• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include <android/binder_manager.h>
18 
19 #include "ibinder_internal.h"
20 #include "status_internal.h"
21 
22 #include <android-base/logging.h>
23 #include <binder/IServiceManager.h>
24 #include <binder/LazyServiceRegistrar.h>
25 
26 using ::android::defaultServiceManager;
27 using ::android::IBinder;
28 using ::android::IServiceManager;
29 using ::android::sp;
30 using ::android::status_t;
31 using ::android::statusToString;
32 using ::android::String16;
33 using ::android::String8;
34 
AServiceManager_addService(AIBinder * binder,const char * instance)35 binder_exception_t AServiceManager_addService(AIBinder* binder, const char* instance) {
36     if (binder == nullptr || instance == nullptr) {
37         return EX_ILLEGAL_ARGUMENT;
38     }
39 
40     sp<IServiceManager> sm = defaultServiceManager();
41     status_t exception = sm->addService(String16(instance), binder->getBinder());
42     return PruneException(exception);
43 }
44 
AServiceManager_addServiceWithFlags(AIBinder * binder,const char * instance,const AServiceManager_AddServiceFlag flags)45 binder_exception_t AServiceManager_addServiceWithFlags(AIBinder* binder, const char* instance,
46                                                        const AServiceManager_AddServiceFlag flags) {
47     if (binder == nullptr || instance == nullptr) {
48         return EX_ILLEGAL_ARGUMENT;
49     }
50 
51     sp<IServiceManager> sm = defaultServiceManager();
52 
53     bool allowIsolated = flags & AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED;
54     status_t exception = sm->addService(String16(instance), binder->getBinder(), allowIsolated);
55     return PruneException(exception);
56 }
57 
AServiceManager_checkService(const char * instance)58 AIBinder* AServiceManager_checkService(const char* instance) {
59     if (instance == nullptr) {
60         return nullptr;
61     }
62 
63     sp<IServiceManager> sm = defaultServiceManager();
64     sp<IBinder> binder = sm->checkService(String16(instance));
65 
66     sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(binder);
67     AIBinder_incStrong(ret.get());
68     return ret.get();
69 }
AServiceManager_getService(const char * instance)70 AIBinder* AServiceManager_getService(const char* instance) {
71     if (instance == nullptr) {
72         return nullptr;
73     }
74 
75     sp<IServiceManager> sm = defaultServiceManager();
76     sp<IBinder> binder = sm->getService(String16(instance));
77 
78     sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(binder);
79     AIBinder_incStrong(ret.get());
80     return ret.get();
81 }
AServiceManager_registerLazyService(AIBinder * binder,const char * instance)82 binder_status_t AServiceManager_registerLazyService(AIBinder* binder, const char* instance) {
83     if (binder == nullptr || instance == nullptr) {
84         return STATUS_UNEXPECTED_NULL;
85     }
86 
87     auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
88     status_t status = serviceRegistrar.registerService(binder->getBinder(), instance);
89 
90     return PruneStatusT(status);
91 }
AServiceManager_waitForService(const char * instance)92 AIBinder* AServiceManager_waitForService(const char* instance) {
93     if (instance == nullptr) {
94         return nullptr;
95     }
96 
97     sp<IServiceManager> sm = defaultServiceManager();
98     sp<IBinder> binder = sm->waitForService(String16(instance));
99 
100     sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(binder);
101     AIBinder_incStrong(ret.get());
102     return ret.get();
103 }
104 typedef void (*AServiceManager_onRegister)(const char* instance, AIBinder* registered,
105                                            void* cookie);
106 
107 struct AServiceManager_NotificationRegistration
108     : public IServiceManager::LocalRegistrationCallback {
109     std::mutex m;
110     const char* instance = nullptr;
111     void* cookie = nullptr;
112     AServiceManager_onRegister onRegister = nullptr;
113 
onServiceRegistrationAServiceManager_NotificationRegistration114     virtual void onServiceRegistration(const String16& smInstance, const sp<IBinder>& binder) {
115         std::lock_guard<std::mutex> l(m);
116         if (onRegister == nullptr) return;
117 
118         CHECK_EQ(String8(smInstance), instance);
119 
120         sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(binder);
121         AIBinder_incStrong(ret.get());
122 
123         onRegister(instance, ret.get(), cookie);
124     }
125 
clearAServiceManager_NotificationRegistration126     void clear() {
127         std::lock_guard<std::mutex> l(m);
128         instance = nullptr;
129         cookie = nullptr;
130         onRegister = nullptr;
131     }
132 };
133 
134 __attribute__((warn_unused_result)) AServiceManager_NotificationRegistration*
AServiceManager_registerForServiceNotifications(const char * instance,AServiceManager_onRegister onRegister,void * cookie)135 AServiceManager_registerForServiceNotifications(const char* instance,
136                                                 AServiceManager_onRegister onRegister,
137                                                 void* cookie) {
138     CHECK_NE(instance, nullptr);
139     CHECK_NE(onRegister, nullptr) << instance;
140     // cookie can be nullptr
141 
142     auto cb = sp<AServiceManager_NotificationRegistration>::make();
143     cb->instance = instance;
144     cb->onRegister = onRegister;
145     cb->cookie = cookie;
146 
147     sp<IServiceManager> sm = defaultServiceManager();
148     if (status_t res = sm->registerForNotifications(String16(instance), cb); res != STATUS_OK) {
149         LOG(ERROR) << "Failed to register for service notifications for " << instance << ": "
150                    << statusToString(res);
151         return nullptr;
152     }
153 
154     cb->incStrong(nullptr);
155     return cb.get();
156 }
157 
AServiceManager_NotificationRegistration_delete(AServiceManager_NotificationRegistration * notification)158 void AServiceManager_NotificationRegistration_delete(
159         AServiceManager_NotificationRegistration* notification) {
160     CHECK_NE(notification, nullptr);
161     notification->clear();
162     notification->decStrong(nullptr);
163 }
164 
AServiceManager_isDeclared(const char * instance)165 bool AServiceManager_isDeclared(const char* instance) {
166     if (instance == nullptr) {
167         return false;
168     }
169 
170     sp<IServiceManager> sm = defaultServiceManager();
171     return sm->isDeclared(String16(instance));
172 }
AServiceManager_forEachDeclaredInstance(const char * interface,void * context,void (* callback)(const char *,void *))173 void AServiceManager_forEachDeclaredInstance(const char* interface, void* context,
174                                              void (*callback)(const char*, void*)) {
175     CHECK(interface != nullptr);
176     // context may be nullptr
177     CHECK(callback != nullptr);
178 
179     sp<IServiceManager> sm = defaultServiceManager();
180     for (const String16& instance : sm->getDeclaredInstances(String16(interface))) {
181         callback(String8(instance).c_str(), context);
182     }
183 }
AServiceManager_isUpdatableViaApex(const char * instance)184 bool AServiceManager_isUpdatableViaApex(const char* instance) {
185     if (instance == nullptr) {
186         return false;
187     }
188 
189     sp<IServiceManager> sm = defaultServiceManager();
190     return sm->updatableViaApex(String16(instance)) != std::nullopt;
191 }
AServiceManager_getUpdatableApexName(const char * instance,void * context,void (* callback)(const char *,void *))192 void AServiceManager_getUpdatableApexName(const char* instance, void* context,
193                                           void (*callback)(const char*, void*)) {
194     CHECK_NE(instance, nullptr);
195     // context may be nullptr
196     CHECK_NE(callback, nullptr);
197 
198     sp<IServiceManager> sm = defaultServiceManager();
199     std::optional<String16> updatableViaApex = sm->updatableViaApex(String16(instance));
200     if (updatableViaApex.has_value()) {
201         callback(String8(updatableViaApex.value()).c_str(), context);
202     }
203 }
AServiceManager_forceLazyServicesPersist(bool persist)204 void AServiceManager_forceLazyServicesPersist(bool persist) {
205     auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
206     serviceRegistrar.forcePersist(persist);
207 }
AServiceManager_setActiveServicesCallback(bool (* callback)(bool,void *),void * context)208 void AServiceManager_setActiveServicesCallback(bool (*callback)(bool, void*), void* context) {
209     auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
210     std::function<bool(bool)> fn = [=](bool hasClients) -> bool {
211         return callback(hasClients, context);
212     };
213     serviceRegistrar.setActiveServicesCallback(fn);
214 }
AServiceManager_tryUnregister()215 bool AServiceManager_tryUnregister() {
216     auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
217     return serviceRegistrar.tryUnregister();
218 }
AServiceManager_reRegister()219 void AServiceManager_reRegister() {
220     auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
221     serviceRegistrar.reRegister();
222 }
223