1 /*
2  * Copyright (C) 2020 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 
17 #pragma once
18 
19 #include <sys/system_properties.h>
20 
21 #include <atomic>
22 #include <condition_variable>
23 #include <functional>
24 #include <mutex>
25 #include <string>
26 #include <unordered_map>
27 
28 using PropertyMonitorCallback = bool(std::string value);
29 
30 struct PropertyMonitorData {
31     std::function<PropertyMonitorCallback> callback;
32     const prop_info* prop_info;
33     uint32_t serial;
34 };
35 
36 // This class is thread-unsafe: all operations must be guarded by mutexes if they can occur on
37 // different threads.
38 struct PropertyMonitor {
39     PropertyMonitor() = default;
40     ~PropertyMonitor() = default;
41 
42     // Register a callback on a specified property, and immediately invoke it on the current value.
43     // If the property is not defined, the callback will be invoked with the empty string.
44     //
45     // Only one callback can be registered on a property at once: subsequent registrations will
46     // delete the original callback.
47     void Add(std::string property, std::function<PropertyMonitorCallback> callback);
48 
49     // Run the PropertyMonitor indefinitely.
50     //
51     // This will run until a callback returns false. If a callback returns false, this does not
52     // return immediately: it will run the other callbacks for changed properties first.
53     void Run();
54 
55   private:
56     std::unordered_map<std::string, PropertyMonitorData> properties_;
57     uint32_t last_serial_ = 0;
58 };
59