1414 * limitations under the License.
1515 */
1616
17+ #include < sys/socket.h>
1718#define LOG_TAG " ServiceManagerCppClient"
1819
1920#include < binder/IServiceManager.h>
2425#include < chrono>
2526#include < condition_variable>
2627
28+ #include < FdTrigger.h>
29+ #include < RpcSocketAddress.h>
2730#include < android-base/properties.h>
31+ #include < android/os/BnAccessor.h>
2832#include < android/os/BnServiceCallback.h>
33+ #include < android/os/BnServiceManager.h>
2934#include < android/os/IAccessor.h>
3035#include < android/os/IServiceManager.h>
3136#include < binder/IPCThreadState.h>
3237#include < binder/Parcel.h>
38+ #include < binder/RpcSession.h>
3339#include < utils/String8.h>
34-
40+ # include < variant >
3541#ifndef __ANDROID_VNDK__
3642#include < binder/IPermissionController.h>
3743#endif
@@ -148,8 +154,141 @@ class CppBackendShim : public IServiceManager {
148154 }
149155};
150156
157+ class AccessorProvider {
158+ public:
159+ AccessorProvider (RpcAccessorProvider&& provider) : mProvider (provider) {}
160+ sp<IBinder> provide (const String16& name) { return mProvider (name); }
161+
162+ private:
163+ AccessorProvider () = delete ;
164+
165+ RpcAccessorProvider mProvider ;
166+ };
167+
168+ class AccessorProviderEntry {
169+ public:
170+ AccessorProviderEntry (std::shared_ptr<AccessorProvider>&& provider) : mProvider (provider) {}
171+ std::shared_ptr<AccessorProvider> mProvider ;
172+
173+ private:
174+ AccessorProviderEntry () = delete ;
175+ };
176+
151177[[clang::no_destroy]] static std::once_flag gSmOnce ;
152178[[clang::no_destroy]] static sp<IServiceManager> gDefaultServiceManager ;
179+ [[clang::no_destroy]] static std::mutex gAccessorProvidersMutex ;
180+ [[clang::no_destroy]] static std::vector<AccessorProviderEntry> gAccessorProviders ;
181+
182+ class LocalAccessor : public android ::os::BnAccessor {
183+ public:
184+ LocalAccessor (const String16& instance, RpcSocketAddressProvider&& connectionInfoProvider)
185+ : mInstance (instance), mConnectionInfoProvider (connectionInfoProvider) {
186+ LOG_ALWAYS_FATAL_IF (!mConnectionInfoProvider ,
187+ " LocalAccessor object needs a valid connection info provider" );
188+ }
189+
190+ ~LocalAccessor () {
191+ if (mOnDelete ) mOnDelete ();
192+ }
193+
194+ ::android::binder::Status addConnection (::android::os::ParcelFileDescriptor* outFd) {
195+ using android::os::IAccessor;
196+ sockaddr_storage addrStorage;
197+ std::unique_ptr<FdTrigger> trigger = FdTrigger::make ();
198+ RpcTransportFd fd;
199+ status_t status =
200+ mConnectionInfoProvider (mInstance , reinterpret_cast <sockaddr*>(&addrStorage),
201+ sizeof (addrStorage));
202+ if (status != OK) {
203+ const std::string error = " The connection info provider was unable to provide "
204+ " connection info for instance " +
205+ std::string (String8 (mInstance ).c_str ()) +
206+ " with status: " + statusToString (status);
207+ ALOGE (" %s" , error.c_str ());
208+ return Status::fromServiceSpecificError (IAccessor::ERROR_CONNECTION_INFO_NOT_FOUND,
209+ error.c_str ());
210+ }
211+ if (addrStorage.ss_family == AF_VSOCK) {
212+ sockaddr_vm* addr = reinterpret_cast <sockaddr_vm*>(&addrStorage);
213+ status = singleSocketConnection (VsockSocketAddress (addr->svm_cid , addr->svm_port ),
214+ trigger, &fd);
215+ } else if (addrStorage.ss_family == AF_UNIX) {
216+ sockaddr_un* addr = reinterpret_cast <sockaddr_un*>(&addrStorage);
217+ status = singleSocketConnection (UnixSocketAddress (addr->sun_path ), trigger, &fd);
218+ } else if (addrStorage.ss_family == AF_INET) {
219+ sockaddr_in* addr = reinterpret_cast <sockaddr_in*>(&addrStorage);
220+ status = singleSocketConnection (InetSocketAddress (reinterpret_cast <sockaddr*>(addr),
221+ sizeof (sockaddr_in),
222+ inet_ntoa (addr->sin_addr ),
223+ ntohs (addr->sin_port )),
224+ trigger, &fd);
225+ } else {
226+ const std::string error =
227+ " Unsupported socket family type or the ConnectionInfoProvider failed to find a "
228+ " valid address. Family type: " +
229+ std::to_string (addrStorage.ss_family );
230+ ALOGE (" %s" , error.c_str ());
231+ return Status::fromServiceSpecificError (IAccessor::ERROR_UNSUPPORTED_SOCKET_FAMILY,
232+ error.c_str ());
233+ }
234+ if (status != OK) {
235+ const std::string error = " Failed to connect to socket for " +
236+ std::string (String8 (mInstance ).c_str ()) +
237+ " with status: " + statusToString (status);
238+ ALOGE (" %s" , error.c_str ());
239+ int err = 0 ;
240+ if (status == -EACCES) {
241+ err = IAccessor::ERROR_FAILED_TO_CONNECT_EACCES;
242+ } else {
243+ err = IAccessor::ERROR_FAILED_TO_CONNECT_TO_SOCKET;
244+ }
245+ return Status::fromServiceSpecificError (err, error.c_str ());
246+ }
247+ *outFd = os::ParcelFileDescriptor (std::move (fd.fd ));
248+ return Status::ok ();
249+ }
250+
251+ ::android::binder::Status getInstanceName (String16* instance) {
252+ *instance = mInstance ;
253+ return Status::ok ();
254+ }
255+
256+ private:
257+ LocalAccessor () = delete ;
258+ String16 mInstance ;
259+ RpcSocketAddressProvider mConnectionInfoProvider ;
260+ std::function<void ()> mOnDelete ;
261+ };
262+
263+ android::binder::Status getInjectedAccessor (const std::string& name,
264+ android::os::Service* service) {
265+ std::vector<AccessorProviderEntry> copiedProviders;
266+ {
267+ std::lock_guard<std::mutex> lock (gAccessorProvidersMutex );
268+ copiedProviders.insert (copiedProviders.begin (), gAccessorProviders .begin (),
269+ gAccessorProviders .end ());
270+ }
271+
272+ // Unlocked to call the providers. This requires the providers to be
273+ // threadsafe and not contain any references to objects that could be
274+ // deleted.
275+ for (const auto & provider : copiedProviders) {
276+ sp<IBinder> binder = provider.mProvider ->provide (String16 (name.c_str ()));
277+ if (binder == nullptr ) continue ;
278+ status_t status = validateAccessor (String16 (name.c_str ()), binder);
279+ if (status != OK) {
280+ ALOGE (" A provider returned a binder that is not an IAccessor for instance %s. Status: "
281+ " %s" ,
282+ name.c_str (), statusToString (status).c_str ());
283+ return android::binder::Status::fromStatusT (android::INVALID_OPERATION);
284+ }
285+ *service = os::Service::make<os::Service::Tag::accessor>(binder);
286+ return android::binder::Status::ok ();
287+ }
288+
289+ *service = os::Service::make<os::Service::Tag::accessor>(nullptr );
290+ return android::binder::Status::ok ();
291+ }
153292
154293sp<IServiceManager> defaultServiceManager ()
155294{
@@ -172,6 +311,75 @@ void setDefaultServiceManager(const sp<IServiceManager>& sm) {
172311 }
173312}
174313
314+ std::weak_ptr<AccessorProvider> addAccessorProvider (RpcAccessorProvider&& providerCallback) {
315+ std::lock_guard<std::mutex> lock (gAccessorProvidersMutex );
316+ std::shared_ptr<AccessorProvider> provider =
317+ std::make_shared<AccessorProvider>(std::move (providerCallback));
318+ gAccessorProviders .push_back (AccessorProviderEntry (std::move (provider)));
319+
320+ return provider;
321+ }
322+
323+ status_t removeAccessorProvider (std::weak_ptr<AccessorProvider> wProvider) {
324+ std::shared_ptr<AccessorProvider> provider = wProvider.lock ();
325+ if (provider == nullptr ) {
326+ ALOGE (" The provider supplied to removeAccessorProvider has already been removed." );
327+ return NAME_NOT_FOUND;
328+ }
329+ std::lock_guard<std::mutex> lock (gAccessorProvidersMutex );
330+ size_t sizeBefore = gAccessorProviders .size ();
331+ gAccessorProviders .erase (std::remove_if (gAccessorProviders .begin (), gAccessorProviders .end (),
332+ [&](AccessorProviderEntry entry) {
333+ return entry.mProvider == provider;
334+ }),
335+ gAccessorProviders .end ());
336+ if (sizeBefore == gAccessorProviders .size ()) {
337+ ALOGE (" Failed to find an AccessorProvider for removeAccessorProvider" );
338+ return NAME_NOT_FOUND;
339+ }
340+
341+ return OK;
342+ }
343+
344+ status_t validateAccessor (const String16& instance, const sp<IBinder>& binder) {
345+ if (binder == nullptr ) {
346+ ALOGE (" Binder is null" );
347+ return BAD_VALUE;
348+ }
349+ sp<IAccessor> accessor = interface_cast<IAccessor>(binder);
350+ if (accessor == nullptr ) {
351+ ALOGE (" This binder for %s is not an IAccessor binder" , String8 (instance).c_str ());
352+ return BAD_TYPE;
353+ }
354+ String16 reportedInstance;
355+ Status status = accessor->getInstanceName (&reportedInstance);
356+ if (!status.isOk ()) {
357+ ALOGE (" Failed to validate the binder being used to create a new ARpc_Accessor for %s with "
358+ " status: %s" ,
359+ String8 (instance).c_str (), status.toString8 ().c_str ());
360+ return NAME_NOT_FOUND;
361+ }
362+ if (reportedInstance != instance) {
363+ ALOGE (" Instance %s doesn't match the Accessor's instance of %s" , String8 (instance).c_str (),
364+ String8 (reportedInstance).c_str ());
365+ return NAME_NOT_FOUND;
366+ }
367+ return OK;
368+ }
369+
370+ sp<IBinder> createAccessor (const String16& instance,
371+ RpcSocketAddressProvider&& connectionInfoProvider) {
372+ // Try to create a new accessor
373+ if (!connectionInfoProvider) {
374+ ALOGE (" Could not find an Accessor for %s and no ConnectionInfoProvider provided to "
375+ " create a new one" ,
376+ String8 (instance).c_str ());
377+ return nullptr ;
378+ }
379+ sp<IBinder> binder = sp<LocalAccessor>::make (instance, std::move (connectionInfoProvider));
380+ return binder;
381+ }
382+
175383#if !defined(__ANDROID_VNDK__)
176384// IPermissionController is not accessible to vendors
177385
0 commit comments