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