1 /* 2 * Copyright (C) 2018 The Android Open Source Project 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 #ifndef THERMAL_UTILS_THERMAL_WATCHER_H_ 17 #define THERMAL_UTILS_THERMAL_WATCHER_H_ 18 19 #include <chrono> 20 #include <condition_variable> 21 #include <future> 22 #include <list> 23 #include <mutex> 24 #include <set> 25 #include <string> 26 #include <thread> 27 #include <unordered_map> 28 #include <vector> 29 30 #include <android-base/chrono_utils.h> 31 #include <android-base/unique_fd.h> 32 #include <utils/Looper.h> 33 #include <utils/Thread.h> 34 35 namespace android { 36 namespace hardware { 37 namespace thermal { 38 namespace V2_0 { 39 namespace implementation { 40 41 using android::base::boot_clock; 42 using android::base::unique_fd; 43 using WatcherCallback = std::function<bool(const std::set<std::string> &name)>; 44 45 // A helper class for monitoring thermal files changes. 46 class ThermalWatcher : public ::android::Thread { 47 public: ThermalWatcher(const WatcherCallback & cb)48 ThermalWatcher(const WatcherCallback &cb) 49 : Thread(false), cb_(cb), looper_(new Looper(true)) {} 50 ~ThermalWatcher() = default; 51 52 // Disallow copy and assign. 53 ThermalWatcher(const ThermalWatcher &) = delete; 54 void operator=(const ThermalWatcher &) = delete; 55 56 // Start the thread and return true if it succeeds. 57 bool startWatchingDeviceFiles(); 58 // Give the file watcher a list of files to start watching. This helper 59 // class will by default wait for modifications to the file with a looper. 60 // This should be called before starting watcher thread. 61 void registerFilesToWatch(const std::set<std::string> &sensors_to_watch, bool uevent_monitor); 62 // Wake up the looper thus the worker thread, immediately. This can be called 63 // in any thread. 64 void wake(); 65 66 private: 67 // The work done by the watcher thread. This will use inotify to check for 68 // modifications to the files to watch. If any modification is seen this 69 // will callback the registered function with the new data read from the 70 // modified file. 71 bool threadLoop() override; 72 73 // Parse uevent message 74 void parseUevent(std::set<std::string> *sensor_name); 75 76 // Maps watcher filer descriptor to watched file path. 77 std::unordered_map<int, std::string> watch_to_file_path_map_; 78 79 // The callback function. Called whenever thermal uevent is seen. 80 // The function passed in should expect a string in the form (type). 81 // Where type is the name of the thermal zone that trigger a uevent notification. 82 // Callback will return thermal trigger status for next polling decision. 83 const WatcherCallback cb_; 84 85 sp<Looper> looper_; 86 87 // For uevent socket registration. 88 android::base::unique_fd uevent_fd_; 89 // Sensor list which monitor flag is enabled. 90 std::set<std::string> monitored_sensors_; 91 // Flag to point out if any sensor across the first threshold. 92 bool thermal_triggered_; 93 // Flag to point out if device can support uevent notify. 94 bool is_polling_; 95 // Timestamp for last thermal update 96 boot_clock::time_point last_update_time_; 97 }; 98 99 } // namespace implementation 100 } // namespace V2_0 101 } // namespace thermal 102 } // namespace hardware 103 } // namespace android 104 105 #endif // THERMAL_UTILS_THERMAL_WATCHER_H_ 106