Home | History | Annotate | Download | only in thermal
      1 /*
      2  * Copyright 2014 Intel Corporation All Rights Reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.intel.thermal;
     18 
     19 import android.app.ActivityManagerNative;
     20 import android.app.IntentService;
     21 import android.app.Service;
     22 import android.content.BroadcastReceiver;
     23 import android.content.ContentResolver;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.IntentFilter;
     27 import android.content.pm.PackageManager;
     28 import android.os.Handler;
     29 import android.os.IBinder;
     30 import android.os.Looper;
     31 import android.os.Message;
     32 import android.os.Process;
     33 import android.os.SystemProperties;
     34 import android.os.UserHandle;
     35 import android.util.Log;
     36 
     37 import java.io.BufferedReader;
     38 import java.io.File;
     39 import java.io.FileNotFoundException;
     40 import java.io.FileReader;
     41 import java.io.IOException;
     42 import java.lang.ClassLoader;
     43 import java.lang.NullPointerException;
     44 import java.lang.reflect.Array;
     45 import java.lang.SecurityException;
     46 import java.util.ArrayList;
     47 import java.util.concurrent.BlockingQueue;
     48 import java.util.concurrent.ArrayBlockingQueue;
     49 import java.util.Iterator;
     50 import java.util.Map;
     51 
     52 import org.xmlpull.v1.XmlPullParser;
     53 import org.xmlpull.v1.XmlPullParserException;
     54 import org.xmlpull.v1.XmlPullParserFactory;
     55 
     56 /**
     57  * The ThermalService monitors the Thermal zones on the platform.
     58  * The number of thermal zones and sensors associated with the zones are
     59  * obtained from the thermal_sensor_config.xml file. When any thermal zone
     60  * crosses the thresholds configured in the xml, a Thermal Intent is sent.
     61  * ACTION_THERMAL_ZONE_STATE_CHANGED
     62  * The Thermal Cooling Manager acts upon this intent and throttles
     63  * the corresponding cooling device.
     64  *
     65  * @hide
     66  */
     67 public class ThermalService extends Service {
     68     private static final String TAG = ThermalService.class.getSimpleName();
     69     private static Context mContext;
     70     private Handler mHandler = new Handler();
     71     static {
     72         System.loadLibrary("thermalJNI");
     73     }
     74     protected enum MetaTag {
     75             ENUM_UNKNOWN,
     76             ENUM_ZONETHRESHOLD,
     77             ENUM_POLLDELAY,
     78             ENUM_MOVINGAVGWINDOW
     79     }
     80 
     81     public class ThermalParser {
     82         // Names of the XML Tags
     83         private static final String PINFO = "PlatformInfo";
     84         private static final String SENSOR_ATTRIB = "SensorAttrib";
     85         private static final String SENSOR = "Sensor";
     86         private static final String ZONE = "Zone";
     87         private static final String THERMAL_CONFIG = "thermalconfig";
     88         private static final String THRESHOLD = "Threshold";
     89         private static final String POLLDELAY = "PollDelay";
     90         private static final String MOVINGAVGWINDOW = "MovingAverageWindow";
     91         private static final String ZONELOGIC = "ZoneLogic";
     92         private static final String WEIGHT = "Weight";
     93         private static final String ORDER = "Order";
     94         private static final String OFFSET = "Offset";
     95         private static final String ZONETHRESHOLD = "ZoneThreshold";
     96         private static final String PROFILE = "Profile";
     97 
     98         private boolean mDone = false;
     99         private ThermalManager.PlatformInfo mPlatformInfo = null;
    100         private ThermalSensor mCurrSensor = null;
    101         private ThermalZone mCurrZone = null;
    102         private ArrayList<ThermalSensorAttrib> mCurrSensorAttribList = null;
    103         private ThermalSensorAttrib mCurrSensorAttrib = null;
    104         private ArrayList<ThermalZone> mThermalZones = null;
    105         private ArrayList<Integer> mPollDelayList = null;
    106         private ArrayList<Integer> mMovingAvgWindowList = null;
    107         private ArrayList<Integer> mWeightList = null;
    108         private ArrayList<Integer> mOrderList = null;
    109         private ArrayList<Integer> mZoneThresholdList = null;
    110         private String mSensorName = null;
    111         XmlPullParserFactory mFactory = null;
    112         XmlPullParser mParser = null;
    113         int mTempZoneId = -1;
    114         int mNumProfiles = 0;
    115         String mTempZoneName = null;
    116         String mCurProfileName = ThermalManager.DEFAULT_PROFILE_NAME;
    117         FileReader mInputStream = null;
    118 
    119         ThermalParser(String fname) {
    120             try {
    121                 mFactory = XmlPullParserFactory.newInstance(System.
    122                         getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
    123                 mFactory.setNamespaceAware(true);
    124                 mParser = mFactory.newPullParser();
    125             } catch (SecurityException e) {
    126                 Log.e(TAG, "SecurityException caught in ThermalParser");
    127             } catch (IllegalArgumentException e) {
    128                 Log.e(TAG, "IllegalArgumentException caught in ThermalParser");
    129             } catch (XmlPullParserException xppe) {
    130                 Log.e(TAG, "XmlPullParserException caught in ThermalParser");
    131             }
    132 
    133             try {
    134                 mInputStream = new FileReader(fname);
    135                 mPlatformInfo = null;
    136                 mCurrSensor = null;
    137                 mCurrZone = null;
    138                 mThermalZones = null;
    139                 if (mInputStream == null) return;
    140                 if (mParser != null) {
    141                     mParser.setInput(mInputStream);
    142                 }
    143             } catch (FileNotFoundException e) {
    144                 Log.e(TAG, "FileNotFoundException Exception in ThermalParser()");
    145             } catch (XmlPullParserException e) {
    146                 Log.e(TAG, "XmlPullParserException Exception in ThermalParser()");
    147             }
    148         }
    149 
    150         ThermalParser() {
    151             mParser = mContext.getResources().
    152                     getXml(ThermalManager.sSensorFileXmlId);
    153         }
    154 
    155         public ThermalManager.PlatformInfo getPlatformInfo() {
    156             return mPlatformInfo;
    157         }
    158 
    159         public boolean parse() {
    160             if (ThermalManager.sIsOverlays == false && mInputStream == null) return false;
    161             /* if mParser is null, close any open stream before exiting */
    162             if (mParser == null) {
    163                 try {
    164                     if (mInputStream != null) {
    165                         mInputStream.close();
    166                     }
    167                 } catch (IOException e) {
    168                     Log.i(TAG, "IOException caught in parse() function");
    169                 }
    170                 return false;
    171             }
    172 
    173             boolean ret = true;
    174             MetaTag tag = MetaTag.ENUM_UNKNOWN;
    175             try {
    176                 int mEventType = mParser.getEventType();
    177                 while (mEventType != XmlPullParser.END_DOCUMENT && !mDone) {
    178                     switch (mEventType) {
    179                         case XmlPullParser.START_DOCUMENT:
    180                             Log.i(TAG, "StartDocument");
    181                             break;
    182                         case XmlPullParser.START_TAG:
    183                             String tagName = mParser.getName();
    184                             boolean isMetaTag = false;
    185                             if (tagName != null && tagName.equalsIgnoreCase(ZONETHRESHOLD)) {
    186                                 tag = MetaTag.ENUM_ZONETHRESHOLD;
    187                                 isMetaTag = true;
    188                             } else if (tagName != null && tagName.equalsIgnoreCase(POLLDELAY)) {
    189                                 tag = MetaTag.ENUM_POLLDELAY;
    190                                 isMetaTag = true;
    191                             } else if (tagName != null
    192                                     && tagName.equalsIgnoreCase(MOVINGAVGWINDOW)) {
    193                                 tag = MetaTag.ENUM_MOVINGAVGWINDOW;
    194                                 isMetaTag = true;
    195                             }
    196                             if (isMetaTag) {
    197                                 ret = processMetaTag(tagName, tag);
    198                             } else {
    199                                 ret = processStartElement(tagName);
    200                             }
    201                             if (!ret) {
    202                                 if (mInputStream != null) mInputStream.close();
    203                                 return false;
    204                             }
    205                             break;
    206                         case XmlPullParser.END_TAG:
    207                             processEndElement(mParser.getName());
    208                             break;
    209                     }
    210                     mEventType = mParser.next();
    211                 }
    212             } catch (XmlPullParserException xppe) {
    213                 Log.i(TAG, "XmlPullParserException caught in parse():" + xppe.getMessage());
    214                 ret = false;
    215             } catch (IOException e) {
    216                 Log.i(TAG, "IOException caught in parse():" + e.getMessage());
    217                 ret = false;
    218             } finally {
    219                 try {
    220                     // end of parsing, close the stream
    221                     // close is moved here, since if there is an exception
    222                     // while parsing doc, input stream needs to be closed
    223                     if (mInputStream != null) mInputStream.close();
    224                 } catch (IOException e) {
    225                     Log.i(TAG, "IOException caught in parse() function");
    226                     ret = false;
    227                 }
    228                 return ret;
    229             }
    230         }
    231 
    232         boolean processMetaTag(String tagName, MetaTag tagId) {
    233             if (mParser == null || tagName == null || mCurrZone == null)  return false;
    234             ArrayList<Integer> tempList;
    235             tempList = new ArrayList<Integer>();
    236             // add the dummy value for TOFF now. update it once meta tag parsed
    237             tempList.add(0);
    238             try {
    239                 int eventType = mParser.next();
    240                 while (true) {
    241                     if (eventType == XmlPullParser.START_TAG) {
    242                         tempList.add(Integer.parseInt(mParser.nextText()));
    243                     } else if (eventType == XmlPullParser.END_TAG &&
    244                             mParser.getName().equalsIgnoreCase(tagName)) {
    245                         break;
    246                     }
    247                     eventType = mParser.next();
    248                 }
    249             } catch (XmlPullParserException xppe) {
    250                 Log.e(TAG, "XmlPullParserException:" + xppe.getMessage());
    251                 return false;
    252             } catch (IOException ioe) {
    253                 Log.e(TAG, "IOException:" + ioe.getMessage());
    254                 return false;
    255             }
    256             // now that all state values are parse, copy the value corresponding to <normal>
    257             // state to TOFF and last state to CRITICAL state.
    258             // now we have reached end of meta tag add this temp list to appropriate list
    259             switch(tagId) {
    260                 case ENUM_POLLDELAY:
    261                     // add TOFF
    262                     tempList.set(0, tempList.get(1));
    263                     // add TCRITICAL
    264                     tempList.add(tempList.get(tempList.size() - 1));
    265                     mCurrZone.setPollDelay(tempList);
    266                     break;
    267                 case ENUM_ZONETHRESHOLD:
    268                     // add TCRITICAL
    269                     tempList.add(tempList.get(tempList.size() - 1));
    270                     mCurrZone.updateMaxStates(tempList.size());
    271                     mCurrZone.setZoneTempThreshold(tempList);
    272                     break;
    273                 case ENUM_MOVINGAVGWINDOW:
    274                     // add TOFF
    275                     tempList.set(0, tempList.get(1));
    276                     // add TCRITICAL
    277                     tempList.add(tempList.get(tempList.size() - 1));
    278                     mCurrZone.setMovingAvgWindow(tempList);
    279                     break;
    280                 case ENUM_UNKNOWN:
    281                 default:
    282                     break;
    283             }
    284             tempList = null;
    285             return true;
    286         }
    287 
    288         boolean processStartElement(String name) {
    289             if (name == null)
    290                 return false;
    291             String zoneName;
    292             boolean ret = true;
    293             try {
    294                 if (name.equalsIgnoreCase(PINFO)) {
    295                     mPlatformInfo = new ThermalManager.PlatformInfo();
    296                     // Default Thermal States
    297                     mPlatformInfo.mMaxThermalStates = 5;
    298                 } else if (name.equalsIgnoreCase(PROFILE)) {
    299                     mNumProfiles++;
    300                 } else if (name.equalsIgnoreCase(SENSOR)) {
    301                     if (mCurrSensor == null) {
    302                         mCurrSensor = new ThermalSensor();
    303                     }
    304                 } else if (name.equalsIgnoreCase(SENSOR_ATTRIB)) {
    305                     if (mCurrSensorAttribList == null) {
    306                         mCurrSensorAttribList = new ArrayList<ThermalSensorAttrib>();
    307                     }
    308                     mCurrSensorAttrib = new ThermalSensorAttrib();
    309                 } else if (name.equalsIgnoreCase(ZONE)) {
    310                     if (mThermalZones == null)
    311                         mThermalZones = new ArrayList<ThermalZone>();
    312                 } else {
    313                     // Retrieve Platform Information
    314                     if (mPlatformInfo != null && name.equalsIgnoreCase("PlatformThermalStates")) {
    315                         mPlatformInfo.mMaxThermalStates = Integer.parseInt(mParser.nextText());
    316                         // Retrieve Zone Information
    317                     } else if (name.equalsIgnoreCase("ZoneName") && mTempZoneId != -1) {
    318                         mTempZoneName = mParser.nextText();
    319                     } else if (name.equalsIgnoreCase("Name")) {
    320                         mCurProfileName = mParser.nextText();
    321                     } else if (name.equalsIgnoreCase(ZONELOGIC) && mTempZoneId != -1
    322                             && mTempZoneName != null) {
    323                         String zoneLogic = mParser.nextText();
    324                         if (zoneLogic.equalsIgnoreCase("VirtualSkin")) {
    325                             mCurrZone = new VirtualThermalZone();
    326                         } else {
    327                             // default zone raw
    328                             mCurrZone = new RawThermalZone();
    329                         }
    330                         if (mCurrZone != null) {
    331                             mCurrZone.setZoneName(mTempZoneName);
    332                             mCurrZone.setZoneId(mTempZoneId);
    333                             mCurrZone.setZoneLogic(zoneLogic);
    334                         }
    335                     } else if (name.equalsIgnoreCase("ZoneID")) {
    336                         mTempZoneId = Integer.parseInt(mParser.nextText());
    337                     } else if (name.equalsIgnoreCase("SupportsUEvent") && mCurrZone != null)
    338                         mCurrZone.setSupportsUEvent(Integer.parseInt(mParser.nextText()));
    339                     else if (name.equalsIgnoreCase("SupportsEmulTemp") && mCurrZone != null)
    340                         mCurrZone.setEmulTempFlag(Integer.parseInt(mParser.nextText()));
    341                     else if (name.equalsIgnoreCase("DebounceInterval") && mCurrZone != null)
    342                         mCurrZone.setDBInterval(Integer.parseInt(mParser.nextText()));
    343                     else if (name.equalsIgnoreCase(POLLDELAY) && mCurrZone != null) {
    344                         mPollDelayList = new ArrayList<Integer>();
    345                     } else if (name.equalsIgnoreCase(OFFSET) && mCurrZone != null) {
    346                         mCurrZone.setOffset(Integer.parseInt(mParser.nextText()));
    347                     }
    348 
    349                     // Retrieve Sensor Information
    350                     else if (name.equalsIgnoreCase("SensorName")) {
    351                         if (mCurrSensorAttrib != null) {
    352                             mCurrSensorAttrib.setSensorName(mParser.nextText());
    353                         } else if (mCurrSensor != null) {
    354                             mCurrSensor.setSensorName(mParser.nextText());
    355                         }
    356                     } else if (name.equalsIgnoreCase("SensorPath") && mCurrSensor != null)
    357                         mCurrSensor.setSensorPath(mParser.nextText());
    358                     else if (name.equalsIgnoreCase("InputTemp") && mCurrSensor != null)
    359                         mCurrSensor.setInputTempPath(mParser.nextText());
    360                     else if (name.equalsIgnoreCase("HighTemp") && mCurrSensor != null)
    361                         mCurrSensor.setHighTempPath(mParser.nextText());
    362                     else if (name.equalsIgnoreCase("LowTemp") && mCurrSensor != null)
    363                         mCurrSensor.setLowTempPath(mParser.nextText());
    364                     else if (name.equalsIgnoreCase("UEventDevPath") && mCurrSensor != null)
    365                         mCurrSensor.setUEventDevPath(mParser.nextText());
    366                     else if (name.equalsIgnoreCase("ErrorCorrection") && mCurrSensor != null)
    367                         mCurrSensor.setErrorCorrectionTemp(Integer.parseInt(mParser.nextText()));
    368                     else if (name.equalsIgnoreCase(WEIGHT) && mCurrSensorAttrib != null) {
    369                         if (mWeightList == null) {
    370                             mWeightList = new ArrayList<Integer>();
    371                         }
    372                         if (mWeightList != null) {
    373                             mWeightList.add(Integer.parseInt(mParser.nextText()));
    374                         }
    375                     } else if (name.equalsIgnoreCase(ORDER) && mCurrSensorAttrib != null) {
    376                         if (mOrderList == null) {
    377                             mOrderList = new ArrayList<Integer>();
    378                         }
    379                         if (mOrderList != null) {
    380                             mOrderList.add(Integer.parseInt(mParser.nextText()));
    381                         }
    382                     }
    383                 }
    384             } catch (XmlPullParserException e) {
    385                 Log.i(TAG, "XmlPullParserException caught in processStartElement()");
    386                 ret = false;
    387             } catch (IOException e) {
    388                 Log.i(TAG, "IOException caught in processStartElement()");
    389                 ret = false;
    390             } finally {
    391                 return ret;
    392             }
    393         }
    394 
    395         void processEndElement(String name) {
    396             if (name.equalsIgnoreCase(SENSOR)) {
    397                 // insert in map, only if no sensor with same name already in map
    398                 if (mCurrSensor == null) return;
    399                 mCurrSensor.setAutoValues();
    400                 if (ThermalManager.getSensor(mCurrSensor.getSensorName()) == null) {
    401                     ThermalManager.sSensorMap.put(mCurrSensor.getSensorName(), mCurrSensor);
    402                 } else {
    403                     Log.i(TAG, "sensor:" + mCurrSensor.getSensorName() + " already present");
    404                 }
    405                 mCurrSensor = null;
    406             } else if (name.equalsIgnoreCase(SENSOR_ATTRIB) && mCurrSensorAttribList != null) {
    407                 if (mCurrSensorAttrib != null) {
    408                     mCurrSensorAttrib.setWeights(mWeightList);
    409                     mCurrSensorAttrib.setOrder(mOrderList);
    410                 }
    411                 mWeightList = null;
    412                 mOrderList = null;
    413                 if (mCurrSensorAttrib != null
    414                         && ThermalManager.getSensor(mCurrSensorAttrib.getSensorName()) != null) {
    415                     // this is valid sensor, so now update the zone sensorattrib list
    416                     // and sensor list.This check is needed to avoid a scenario where
    417                     // a invalid sensor name might be included in sensorattrib list.
    418                     // This check filters out all invalid sensor attrib.
    419                     mCurrSensorAttribList.add(mCurrSensorAttrib);
    420                 }
    421             } else if (name.equalsIgnoreCase(ZONE) && mCurrZone != null
    422                     && mThermalZones != null) {
    423                 mCurrZone.setSensorList(mCurrSensorAttribList);
    424                 mThermalZones.add(mCurrZone);
    425                 mCurrZone = null;
    426                 mTempZoneId = -1;
    427                 mTempZoneName = null;
    428                 mCurrSensorAttribList = null;
    429             } else if (name.equalsIgnoreCase(POLLDELAY) && mCurrZone != null) {
    430                 mCurrZone.setPollDelay(mPollDelayList);
    431                 mPollDelayList = null;
    432             } else if (name.equalsIgnoreCase(MOVINGAVGWINDOW) && mCurrZone != null) {
    433                 mCurrZone.setMovingAvgWindow(mMovingAvgWindowList);
    434                 mMovingAvgWindowList = null;
    435             } else if (name.equalsIgnoreCase(THERMAL_CONFIG)) {
    436                 // This indicates we have not seen any <Profile> tag.
    437                 // Consider it as if we have only one 'Default' Profile.
    438                 if (mNumProfiles == 0) {
    439                     ThermalManager.sProfileZoneMap.put(mCurProfileName, mThermalZones);
    440                 }
    441                 mDone = true;
    442             } else if (name.equalsIgnoreCase(PROFILE)) {
    443                 ThermalManager.sProfileZoneMap.put(mCurProfileName, mThermalZones);
    444                 mThermalZones = null;
    445             } else if (name.equalsIgnoreCase(ZONETHRESHOLD) && mCurrZone != null) {
    446                 mCurrZone.setZoneTempThreshold(mZoneThresholdList);
    447                 mZoneThresholdList = null;
    448             }
    449         }
    450     }
    451 
    452     /* Class to notifying thermal events */
    453     public class Notify implements Runnable {
    454         private final BlockingQueue cQueue;
    455         Notify (BlockingQueue q) {
    456             cQueue = q;
    457         }
    458 
    459         public void run () {
    460             try {
    461                 while (true) { consume((ThermalEvent) cQueue.take()); }
    462             } catch (InterruptedException ex) {
    463                 Log.i(TAG, "caught InterruptedException in run()");
    464             }
    465         }
    466 
    467         /* Method to consume thermal event */
    468         public void consume (ThermalEvent event) {
    469             Intent statusIntent = new Intent();
    470             statusIntent.setAction(ThermalManager.ACTION_THERMAL_ZONE_STATE_CHANGED);
    471 
    472             statusIntent.putExtra(ThermalManager.EXTRA_NAME, event.mZoneName);
    473             statusIntent.putExtra(ThermalManager.EXTRA_PROFILE, event.mProfName);
    474             statusIntent.putExtra(ThermalManager.EXTRA_ZONE, event.mZoneId);
    475             statusIntent.putExtra(ThermalManager.EXTRA_EVENT, event.mEventType);
    476             statusIntent.putExtra(ThermalManager.EXTRA_STATE, event.mThermalLevel);
    477             statusIntent.putExtra(ThermalManager.EXTRA_TEMP, event.mZoneTemp);
    478 
    479             /* Send the Thermal Intent */
    480             mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
    481         }
    482     }
    483 
    484     /* Register for boot complete Intent */
    485     public ThermalService() {
    486         super();
    487     }
    488 
    489     private void configureTurboProperties() {
    490         String prop = SystemProperties.get("persist.thermal.turbo.dynamic");
    491 
    492         if (prop.equals("0")) {
    493             ThermalManager.sIsDynamicTurboEnabled = false;
    494             Log.i(TAG, "Dynamic Turbo disabled through persist.thermal.turbo.dynamic");
    495         } else if (prop.equals("1")) {
    496             ThermalManager.sIsDynamicTurboEnabled = true;
    497             Log.i(TAG, "Dynamic Turbo enabled through persist.thermal.turbo.dynamic");
    498         } else {
    499             // Set it to true so that we don't write ThermalManager.DISABLE_DYNAMIC_TURBO
    500             // into any cooling device based on this.
    501             ThermalManager.sIsDynamicTurboEnabled = true;
    502             Log.i(TAG, "property persist.thermal.turbo.dynamic not present");
    503         }
    504     }
    505 
    506     @Override
    507     public void onDestroy() {
    508         // stop all thread
    509         ThermalManager.stopCurrentProfile();
    510         ThermalManager.sCoolingManager.unregisterReceivers();
    511         // clear all static data
    512         ThermalManager.clearData();
    513         Log.w(TAG, "ituxd destroyed");
    514     }
    515 
    516     @Override
    517     public void onCreate() {
    518         mContext = getApplicationContext();
    519         ThermalManager.setContext(mContext);
    520     }
    521 
    522     @Override
    523     public IBinder onBind(Intent intent) {
    524         return(null);
    525     }
    526 
    527     @Override
    528     public int onStartCommand(Intent intent, int flags, int startid)
    529     {
    530         boolean ret;
    531         ThermalManager.loadiTUXVersion();
    532         /* Check for exitence of config files */
    533         ThermalUtils.initialiseConfigFiles(mContext);
    534         if (!ThermalManager.sIsConfigFiles && !ThermalManager.sIsOverlays) {
    535             Log.i(TAG, "Thermal config files do not exist. Exiting ThermalService");
    536             return START_NOT_STICKY;
    537         }
    538 
    539         /* Set Dynamic Turbo status based on the property */
    540         configureTurboProperties();
    541 
    542         /* Intiliaze DTS TjMax temperature */
    543         ThermalUtils.getTjMax();
    544 
    545         /* Initialize the Thermal Cooling Manager */
    546         ThermalManager.sCoolingManager = new ThermalCooling();
    547         if (ThermalManager.sCoolingManager != null) {
    548             ret = ThermalManager.sCoolingManager.init(mContext);
    549             if (!ret) {
    550                 Log.i(TAG, "CoolingManager is null. Exiting ThermalService");
    551                 return START_NOT_STICKY;
    552             }
    553         }
    554 
    555         /* Parse the thermal configuration file to determine zone/sensor information */
    556         ThermalParser mThermalParser;
    557         if (ThermalManager.sIsConfigFiles) {
    558             mThermalParser = new ThermalParser(ThermalManager.sSensorFilePath);
    559         } else {
    560             mThermalParser = new ThermalParser();
    561         }
    562 
    563         if (mThermalParser != null) {
    564             ret = mThermalParser.parse();
    565             if (!ret) {
    566                 ThermalManager.sCoolingManager.unregisterReceivers();
    567                 Log.i(TAG, "thermal_sensor_config.xml parsing Failed. Exiting ThermalService");
    568                 return START_NOT_STICKY;
    569             }
    570         }
    571 
    572         /* Retrieve the platform information after parsing */
    573         ThermalManager.sPlatformInfo = mThermalParser.getPlatformInfo();
    574 
    575         /* Print thermal_sensor_config.xml information */
    576         Iterator it = ThermalManager.sProfileZoneMap.entrySet().iterator();
    577         while (it.hasNext()) {
    578             Map.Entry entry = (Map.Entry) it.next();
    579             String key = (String) entry.getKey();
    580             ArrayList<ThermalZone> tzList = (ArrayList<ThermalZone>) entry.getValue();
    581             Log.i(TAG, "Zones under Profile: " + key);
    582             for (ThermalZone tz : tzList) tz.printAttrs();
    583         }
    584 
    585         /* read persistent system properties for shutdown notification */
    586         ThermalManager.readShutdownNotiferProperties();
    587         /* initialize the thermal notifier thread */
    588         Notify notifier = new Notify(ThermalManager.sEventQueue);
    589         new Thread(notifier, "ThermalNotifier").start();
    590 
    591         ThermalManager.buildProfileNameList();
    592         ThermalManager.initializeStickyIntent();
    593 
    594         /* Building bucket size for all profiles */
    595         ThermalManager.setBucketSizeForProfiles();
    596 
    597         /* Start monitoring the zones in Default Thermal Profile */
    598         ThermalManager.startDefaultProfile();
    599 
    600         return START_STICKY;
    601     }
    602 }
    603