xref: /aosp_15_r20/system/core/libutils/misc.cpp (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
1*00c7fec1SAndroid Build Coastguard Worker /*
2*00c7fec1SAndroid Build Coastguard Worker  * Copyright (C) 2005 The Android Open Source Project
3*00c7fec1SAndroid Build Coastguard Worker  *
4*00c7fec1SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*00c7fec1SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*00c7fec1SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*00c7fec1SAndroid Build Coastguard Worker  *
8*00c7fec1SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*00c7fec1SAndroid Build Coastguard Worker  *
10*00c7fec1SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*00c7fec1SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*00c7fec1SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*00c7fec1SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*00c7fec1SAndroid Build Coastguard Worker  * limitations under the License.
15*00c7fec1SAndroid Build Coastguard Worker  */
16*00c7fec1SAndroid Build Coastguard Worker 
17*00c7fec1SAndroid Build Coastguard Worker #define LOG_TAG "misc"
18*00c7fec1SAndroid Build Coastguard Worker 
19*00c7fec1SAndroid Build Coastguard Worker #include <utils/misc.h>
20*00c7fec1SAndroid Build Coastguard Worker 
21*00c7fec1SAndroid Build Coastguard Worker #include <pthread.h>
22*00c7fec1SAndroid Build Coastguard Worker 
23*00c7fec1SAndroid Build Coastguard Worker #include <log/log.h>
24*00c7fec1SAndroid Build Coastguard Worker #include <utils/Vector.h>
25*00c7fec1SAndroid Build Coastguard Worker 
26*00c7fec1SAndroid Build Coastguard Worker #if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
27*00c7fec1SAndroid Build Coastguard Worker #include <dlfcn.h>
28*00c7fec1SAndroid Build Coastguard Worker #include <vndksupport/linker.h>
29*00c7fec1SAndroid Build Coastguard Worker #endif
30*00c7fec1SAndroid Build Coastguard Worker 
31*00c7fec1SAndroid Build Coastguard Worker extern "C" void do_report_sysprop_change();
32*00c7fec1SAndroid Build Coastguard Worker 
33*00c7fec1SAndroid Build Coastguard Worker using namespace android;
34*00c7fec1SAndroid Build Coastguard Worker 
35*00c7fec1SAndroid Build Coastguard Worker namespace android {
36*00c7fec1SAndroid Build Coastguard Worker 
37*00c7fec1SAndroid Build Coastguard Worker struct sysprop_change_callback_info {
38*00c7fec1SAndroid Build Coastguard Worker     sysprop_change_callback callback;
39*00c7fec1SAndroid Build Coastguard Worker     int priority;
40*00c7fec1SAndroid Build Coastguard Worker };
41*00c7fec1SAndroid Build Coastguard Worker 
42*00c7fec1SAndroid Build Coastguard Worker #if !defined(_WIN32)
43*00c7fec1SAndroid Build Coastguard Worker static pthread_mutex_t gSyspropMutex = PTHREAD_MUTEX_INITIALIZER;
44*00c7fec1SAndroid Build Coastguard Worker static Vector<sysprop_change_callback_info>* gSyspropList = nullptr;
45*00c7fec1SAndroid Build Coastguard Worker #endif
46*00c7fec1SAndroid Build Coastguard Worker 
47*00c7fec1SAndroid Build Coastguard Worker #if !defined(_WIN32)
add_sysprop_change_callback(sysprop_change_callback cb,int priority)48*00c7fec1SAndroid Build Coastguard Worker void add_sysprop_change_callback(sysprop_change_callback cb, int priority) {
49*00c7fec1SAndroid Build Coastguard Worker     pthread_mutex_lock(&gSyspropMutex);
50*00c7fec1SAndroid Build Coastguard Worker     if (gSyspropList == nullptr) {
51*00c7fec1SAndroid Build Coastguard Worker         gSyspropList = new Vector<sysprop_change_callback_info>();
52*00c7fec1SAndroid Build Coastguard Worker     }
53*00c7fec1SAndroid Build Coastguard Worker     sysprop_change_callback_info info;
54*00c7fec1SAndroid Build Coastguard Worker     info.callback = cb;
55*00c7fec1SAndroid Build Coastguard Worker     info.priority = priority;
56*00c7fec1SAndroid Build Coastguard Worker     bool added = false;
57*00c7fec1SAndroid Build Coastguard Worker     for (size_t i=0; i<gSyspropList->size(); i++) {
58*00c7fec1SAndroid Build Coastguard Worker         if (priority >= gSyspropList->itemAt(i).priority) {
59*00c7fec1SAndroid Build Coastguard Worker             gSyspropList->insertAt(info, i);
60*00c7fec1SAndroid Build Coastguard Worker             added = true;
61*00c7fec1SAndroid Build Coastguard Worker             break;
62*00c7fec1SAndroid Build Coastguard Worker         }
63*00c7fec1SAndroid Build Coastguard Worker     }
64*00c7fec1SAndroid Build Coastguard Worker     if (!added) {
65*00c7fec1SAndroid Build Coastguard Worker         gSyspropList->add(info);
66*00c7fec1SAndroid Build Coastguard Worker     }
67*00c7fec1SAndroid Build Coastguard Worker     pthread_mutex_unlock(&gSyspropMutex);
68*00c7fec1SAndroid Build Coastguard Worker }
69*00c7fec1SAndroid Build Coastguard Worker #else
add_sysprop_change_callback(sysprop_change_callback,int)70*00c7fec1SAndroid Build Coastguard Worker void add_sysprop_change_callback(sysprop_change_callback, int) {}
71*00c7fec1SAndroid Build Coastguard Worker #endif
72*00c7fec1SAndroid Build Coastguard Worker 
73*00c7fec1SAndroid Build Coastguard Worker #if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
get_report_sysprop_change_func()74*00c7fec1SAndroid Build Coastguard Worker void (*get_report_sysprop_change_func())() {
75*00c7fec1SAndroid Build Coastguard Worker     void (*func)() = nullptr;
76*00c7fec1SAndroid Build Coastguard Worker     void* handle = android_load_sphal_library("libutils.so", RTLD_NOW);
77*00c7fec1SAndroid Build Coastguard Worker     if (handle != nullptr) {
78*00c7fec1SAndroid Build Coastguard Worker         func = reinterpret_cast<decltype(func)>(dlsym(handle, "do_report_sysprop_change"));
79*00c7fec1SAndroid Build Coastguard Worker     }
80*00c7fec1SAndroid Build Coastguard Worker 
81*00c7fec1SAndroid Build Coastguard Worker     return func;
82*00c7fec1SAndroid Build Coastguard Worker }
83*00c7fec1SAndroid Build Coastguard Worker #endif
84*00c7fec1SAndroid Build Coastguard Worker 
report_sysprop_change()85*00c7fec1SAndroid Build Coastguard Worker void report_sysprop_change() {
86*00c7fec1SAndroid Build Coastguard Worker     do_report_sysprop_change();
87*00c7fec1SAndroid Build Coastguard Worker 
88*00c7fec1SAndroid Build Coastguard Worker #if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
89*00c7fec1SAndroid Build Coastguard Worker     // libutils.so is double loaded; from the default namespace and from the
90*00c7fec1SAndroid Build Coastguard Worker     // 'sphal' namespace. Redirect the sysprop change event to the other instance
91*00c7fec1SAndroid Build Coastguard Worker     // of libutils.so loaded in the 'sphal' namespace so that listeners attached
92*00c7fec1SAndroid Build Coastguard Worker     // to that instance is also notified with this event.
93*00c7fec1SAndroid Build Coastguard Worker     static auto func = get_report_sysprop_change_func();
94*00c7fec1SAndroid Build Coastguard Worker     if (func != nullptr) {
95*00c7fec1SAndroid Build Coastguard Worker         (*func)();
96*00c7fec1SAndroid Build Coastguard Worker     }
97*00c7fec1SAndroid Build Coastguard Worker #endif
98*00c7fec1SAndroid Build Coastguard Worker }
99*00c7fec1SAndroid Build Coastguard Worker 
100*00c7fec1SAndroid Build Coastguard Worker };  // namespace android
101*00c7fec1SAndroid Build Coastguard Worker 
do_report_sysprop_change()102*00c7fec1SAndroid Build Coastguard Worker void do_report_sysprop_change() {
103*00c7fec1SAndroid Build Coastguard Worker #if !defined(_WIN32)
104*00c7fec1SAndroid Build Coastguard Worker     pthread_mutex_lock(&gSyspropMutex);
105*00c7fec1SAndroid Build Coastguard Worker     Vector<sysprop_change_callback_info> listeners;
106*00c7fec1SAndroid Build Coastguard Worker     if (gSyspropList != nullptr) {
107*00c7fec1SAndroid Build Coastguard Worker         listeners = *gSyspropList;
108*00c7fec1SAndroid Build Coastguard Worker     }
109*00c7fec1SAndroid Build Coastguard Worker     pthread_mutex_unlock(&gSyspropMutex);
110*00c7fec1SAndroid Build Coastguard Worker 
111*00c7fec1SAndroid Build Coastguard Worker     //ALOGI("Reporting sysprop change to %d listeners", listeners.size());
112*00c7fec1SAndroid Build Coastguard Worker     for (size_t i=0; i<listeners.size(); i++) {
113*00c7fec1SAndroid Build Coastguard Worker         listeners[i].callback();
114*00c7fec1SAndroid Build Coastguard Worker     }
115*00c7fec1SAndroid Build Coastguard Worker #endif
116*00c7fec1SAndroid Build Coastguard Worker }
117