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/unique_fd.h> 31 #include <utils/Looper.h> 32 #include <utils/Thread.h> 33 34 namespace android { 35 namespace hardware { 36 namespace thermal { 37 namespace V2_0 { 38 namespace implementation { 39 40 using android::base::unique_fd; 41 using WatcherCallback = std::function<bool(const std::set<std::string> &name)>; 42 43 // A helper class for monitoring thermal files changes. 44 class ThermalWatcher : public ::android::Thread { 45 public: ThermalWatcher(const WatcherCallback & cb)46 ThermalWatcher(const WatcherCallback &cb) 47 : Thread(false), cb_(cb), looper_(new Looper(true)) {} 48 ~ThermalWatcher() = default; 49 50 // Disallow copy and assign. 51 ThermalWatcher(const ThermalWatcher &) = delete; 52 void operator=(const ThermalWatcher &) = delete; 53 54 // Start the thread and return true if it succeeds. 55 bool startWatchingDeviceFiles(); 56 // Give the file watcher a list of files to start watching. This helper 57 // class will by default wait for modifications to the file with a looper. 58 // This should be called before starting watcher thread. 59 void registerFilesToWatch(const std::set<std::string> &sensors_to_watch, 60 const std::set<std::string> &cdev_to_watch, bool uevent_monitor); 61 // Wake up the looper thus the worker thread, immediately. This can be called 62 // in any thread. 63 void wake(); 64 65 private: 66 // The work done by the watcher thread. This will use inotify to check for 67 // modifications to the files to watch. If any modification is seen this 68 // will callback the registered function with the new data read from the 69 // modified file. 70 bool threadLoop() override; 71 72 // Parse uevent message 73 void parseUevent(std::set<std::string> *sensor_name); 74 75 // Maps watcher filer descriptor to watched file path. 76 std::unordered_map<int, std::string> watch_to_file_path_map_; 77 std::vector<android::base::unique_fd> fds_; 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 }; 96 97 } // namespace implementation 98 } // namespace V2_0 99 } // namespace thermal 100 } // namespace hardware 101 } // namespace android 102 103 #endif // THERMAL_UTILS_THERMAL_WATCHER_H_ 104