Loading libs/binder/BackendUnifiedServiceManager.cpp +38 −8 Original line number Diff line number Diff line Loading @@ -46,7 +46,9 @@ binder::Status BackendUnifiedServiceManager::getService2(const ::std::string& na os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->getService2(name, &service); toBinderService(service, _out); if (status.isOk()) { return toBinderService(name, service, _out); } return status; } Loading @@ -54,15 +56,38 @@ binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& n os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->checkService(name, &service); toBinderService(service, _out); if (status.isOk()) { return toBinderService(name, service, _out); } return status; } void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Service* _out) { binder::Status BackendUnifiedServiceManager::toBinderService(const ::std::string& name, const os::Service& in, os::Service* _out) { switch (in.getTag()) { case os::Service::Tag::binder: { if (in.get<os::Service::Tag::binder>() == nullptr) { // failed to find a service. Check to see if we have any local // injected Accessors for this service. os::Service accessor; binder::Status status = getInjectedAccessor(name, &accessor); if (!status.isOk()) { *_out = os::Service::make<os::Service::Tag::binder>(nullptr); return status; } if (accessor.getTag() == os::Service::Tag::accessor && accessor.get<os::Service::Tag::accessor>() != nullptr) { ALOGI("Found local injected service for %s, will attempt to create connection", name.c_str()); // Call this again using the accessor Service to get the real // service's binder into _out return toBinderService(name, accessor, _out); } } *_out = in; break; return binder::Status::ok(); } case os::Service::Tag::accessor: { sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>(); Loading @@ -70,7 +95,7 @@ void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Se if (accessor == nullptr) { ALOGE("Service#accessor doesn't have accessor. VM is maybe starting..."); *_out = os::Service::make<os::Service::Tag::binder>(nullptr); break; return binder::Status::ok(); } auto request = [=] { os::ParcelFileDescriptor fd; Loading @@ -83,10 +108,15 @@ void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Se } }; auto session = RpcSession::make(); session->setupPreconnectedClient(base::unique_fd{}, request); status_t status = session->setupPreconnectedClient(base::unique_fd{}, request); if (status != OK) { ALOGE("Failed to set up preconnected binder RPC client: %s", statusToString(status).c_str()); return binder::Status::fromStatusT(status); } session->setSessionSpecificRoot(accessorBinder); *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject()); break; return binder::Status::ok(); } default: { LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag()); Loading libs/binder/BackendUnifiedServiceManager.h +5 −2 Original line number Diff line number Diff line Loading @@ -59,9 +59,12 @@ public: private: sp<os::IServiceManager> mTheRealServiceManager; void toBinderService(const os::Service& in, os::Service* _out); binder::Status toBinderService(const ::std::string& name, const os::Service& in, os::Service* _out); }; sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager(); android::binder::Status getInjectedAccessor(const std::string& name, android::os::Service* service); } // namespace android libs/binder/IServiceManager.cpp +209 −1 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ * limitations under the License. */ #include <sys/socket.h> #define LOG_TAG "ServiceManagerCppClient" #include <binder/IServiceManager.h> Loading @@ -24,14 +25,19 @@ #include <chrono> #include <condition_variable> #include <FdTrigger.h> #include <RpcSocketAddress.h> #include <android-base/properties.h> #include <android/os/BnAccessor.h> #include <android/os/BnServiceCallback.h> #include <android/os/BnServiceManager.h> #include <android/os/IAccessor.h> #include <android/os/IServiceManager.h> #include <binder/IPCThreadState.h> #include <binder/Parcel.h> #include <binder/RpcSession.h> #include <utils/String8.h> #include <variant> #ifndef __ANDROID_VNDK__ #include <binder/IPermissionController.h> #endif Loading Loading @@ -148,8 +154,141 @@ protected: } }; class AccessorProvider { public: AccessorProvider(RpcAccessorProvider&& provider) : mProvider(provider) {} sp<IBinder> provide(const String16& name) { return mProvider(name); } private: AccessorProvider() = delete; RpcAccessorProvider mProvider; }; class AccessorProviderEntry { public: AccessorProviderEntry(std::shared_ptr<AccessorProvider>&& provider) : mProvider(provider) {} std::shared_ptr<AccessorProvider> mProvider; private: AccessorProviderEntry() = delete; }; [[clang::no_destroy]] static std::once_flag gSmOnce; [[clang::no_destroy]] static sp<IServiceManager> gDefaultServiceManager; [[clang::no_destroy]] static std::mutex gAccessorProvidersMutex; [[clang::no_destroy]] static std::vector<AccessorProviderEntry> gAccessorProviders; class LocalAccessor : public android::os::BnAccessor { public: LocalAccessor(const String16& instance, RpcSocketAddressProvider&& connectionInfoProvider) : mInstance(instance), mConnectionInfoProvider(connectionInfoProvider) { LOG_ALWAYS_FATAL_IF(!mConnectionInfoProvider, "LocalAccessor object needs a valid connection info provider"); } ~LocalAccessor() { if (mOnDelete) mOnDelete(); } ::android::binder::Status addConnection(::android::os::ParcelFileDescriptor* outFd) { using android::os::IAccessor; sockaddr_storage addrStorage; std::unique_ptr<FdTrigger> trigger = FdTrigger::make(); RpcTransportFd fd; status_t status = mConnectionInfoProvider(mInstance, reinterpret_cast<sockaddr*>(&addrStorage), sizeof(addrStorage)); if (status != OK) { const std::string error = "The connection info provider was unable to provide " "connection info for instance " + std::string(String8(mInstance).c_str()) + " with status: " + statusToString(status); ALOGE("%s", error.c_str()); return Status::fromServiceSpecificError(IAccessor::ERROR_CONNECTION_INFO_NOT_FOUND, error.c_str()); } if (addrStorage.ss_family == AF_VSOCK) { sockaddr_vm* addr = reinterpret_cast<sockaddr_vm*>(&addrStorage); status = singleSocketConnection(VsockSocketAddress(addr->svm_cid, addr->svm_port), trigger, &fd); } else if (addrStorage.ss_family == AF_UNIX) { sockaddr_un* addr = reinterpret_cast<sockaddr_un*>(&addrStorage); status = singleSocketConnection(UnixSocketAddress(addr->sun_path), trigger, &fd); } else if (addrStorage.ss_family == AF_INET) { sockaddr_in* addr = reinterpret_cast<sockaddr_in*>(&addrStorage); status = singleSocketConnection(InetSocketAddress(reinterpret_cast<sockaddr*>(addr), sizeof(sockaddr_in), inet_ntoa(addr->sin_addr), ntohs(addr->sin_port)), trigger, &fd); } else { const std::string error = "Unsupported socket family type or the ConnectionInfoProvider failed to find a " "valid address. Family type: " + std::to_string(addrStorage.ss_family); ALOGE("%s", error.c_str()); return Status::fromServiceSpecificError(IAccessor::ERROR_UNSUPPORTED_SOCKET_FAMILY, error.c_str()); } if (status != OK) { const std::string error = "Failed to connect to socket for " + std::string(String8(mInstance).c_str()) + " with status: " + statusToString(status); ALOGE("%s", error.c_str()); int err = 0; if (status == -EACCES) { err = IAccessor::ERROR_FAILED_TO_CONNECT_EACCES; } else { err = IAccessor::ERROR_FAILED_TO_CONNECT_TO_SOCKET; } return Status::fromServiceSpecificError(err, error.c_str()); } *outFd = os::ParcelFileDescriptor(std::move(fd.fd)); return Status::ok(); } ::android::binder::Status getInstanceName(String16* instance) { *instance = mInstance; return Status::ok(); } private: LocalAccessor() = delete; String16 mInstance; RpcSocketAddressProvider mConnectionInfoProvider; std::function<void()> mOnDelete; }; android::binder::Status getInjectedAccessor(const std::string& name, android::os::Service* service) { std::vector<AccessorProviderEntry> copiedProviders; { std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); copiedProviders.insert(copiedProviders.begin(), gAccessorProviders.begin(), gAccessorProviders.end()); } // Unlocked to call the providers. This requires the providers to be // threadsafe and not contain any references to objects that could be // deleted. for (const auto& provider : copiedProviders) { sp<IBinder> binder = provider.mProvider->provide(String16(name.c_str())); if (binder == nullptr) continue; status_t status = validateAccessor(String16(name.c_str()), binder); if (status != OK) { ALOGE("A provider returned a binder that is not an IAccessor for instance %s. Status: " "%s", name.c_str(), statusToString(status).c_str()); return android::binder::Status::fromStatusT(android::INVALID_OPERATION); } *service = os::Service::make<os::Service::Tag::accessor>(binder); return android::binder::Status::ok(); } *service = os::Service::make<os::Service::Tag::accessor>(nullptr); return android::binder::Status::ok(); } sp<IServiceManager> defaultServiceManager() { Loading @@ -172,6 +311,75 @@ void setDefaultServiceManager(const sp<IServiceManager>& sm) { } } std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& providerCallback) { std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); std::shared_ptr<AccessorProvider> provider = std::make_shared<AccessorProvider>(std::move(providerCallback)); gAccessorProviders.push_back(AccessorProviderEntry(std::move(provider))); return provider; } status_t removeAccessorProvider(std::weak_ptr<AccessorProvider> wProvider) { std::shared_ptr<AccessorProvider> provider = wProvider.lock(); if (provider == nullptr) { ALOGE("The provider supplied to removeAccessorProvider has already been removed."); return NAME_NOT_FOUND; } std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); size_t sizeBefore = gAccessorProviders.size(); gAccessorProviders.erase(std::remove_if(gAccessorProviders.begin(), gAccessorProviders.end(), [&](AccessorProviderEntry entry) { return entry.mProvider == provider; }), gAccessorProviders.end()); if (sizeBefore == gAccessorProviders.size()) { ALOGE("Failed to find an AccessorProvider for removeAccessorProvider"); return NAME_NOT_FOUND; } return OK; } status_t validateAccessor(const String16& instance, const sp<IBinder>& binder) { if (binder == nullptr) { ALOGE("Binder is null"); return BAD_VALUE; } sp<IAccessor> accessor = interface_cast<IAccessor>(binder); if (accessor == nullptr) { ALOGE("This binder for %s is not an IAccessor binder", String8(instance).c_str()); return BAD_TYPE; } String16 reportedInstance; Status status = accessor->getInstanceName(&reportedInstance); if (!status.isOk()) { ALOGE("Failed to validate the binder being used to create a new ARpc_Accessor for %s with " "status: %s", String8(instance).c_str(), status.toString8().c_str()); return NAME_NOT_FOUND; } if (reportedInstance != instance) { ALOGE("Instance %s doesn't match the Accessor's instance of %s", String8(instance).c_str(), String8(reportedInstance).c_str()); return NAME_NOT_FOUND; } return OK; } sp<IBinder> createAccessor(const String16& instance, RpcSocketAddressProvider&& connectionInfoProvider) { // Try to create a new accessor if (!connectionInfoProvider) { ALOGE("Could not find an Accessor for %s and no ConnectionInfoProvider provided to " "create a new one", String8(instance).c_str()); return nullptr; } sp<IBinder> binder = sp<LocalAccessor>::make(instance, std::move(connectionInfoProvider)); return binder; } #if !defined(__ANDROID_VNDK__) // IPermissionController is not accessible to vendors Loading libs/binder/RpcSession.cpp +18 −2 Original line number Diff line number Diff line Loading @@ -589,6 +589,21 @@ status_t RpcSession::setupSocketClient(const RpcSocketAddress& addr) { status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, const std::vector<uint8_t>& sessionId, bool incoming) { RpcTransportFd transportFd; status_t status = singleSocketConnection(addr, mShutdownTrigger, &transportFd); if (status != OK) return status; return initAndAddConnection(std::move(transportFd), sessionId, incoming); } status_t singleSocketConnection(const RpcSocketAddress& addr, const std::unique_ptr<FdTrigger>& shutdownTrigger, RpcTransportFd* outFd) { LOG_ALWAYS_FATAL_IF(outFd == nullptr, "There is no reason to call this function without an outFd"); LOG_ALWAYS_FATAL_IF(shutdownTrigger == nullptr, "FdTrigger argument is required so we don't get stuck in the connect call " "if the server process shuts down."); for (size_t tries = 0; tries < 5; tries++) { if (tries > 0) usleep(10000); Loading Loading @@ -620,7 +635,7 @@ status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, if (connErrno == EAGAIN || connErrno == EINPROGRESS) { // For non-blocking sockets, connect() may return EAGAIN (for unix domain socket) or // EINPROGRESS (for others). Call poll() and getsockopt() to get the error. status_t pollStatus = mShutdownTrigger->triggerablePoll(transportFd, POLLOUT); status_t pollStatus = shutdownTrigger->triggerablePoll(transportFd, POLLOUT); if (pollStatus != OK) { ALOGE("Could not POLLOUT after connect() on non-blocking socket: %s", statusToString(pollStatus).c_str()); Loading Loading @@ -654,7 +669,8 @@ status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), transportFd.fd.get()); return initAndAddConnection(std::move(transportFd), sessionId, incoming); *outFd = std::move(transportFd); return OK; } ALOGE("Ran out of retries to connect to %s", addr.toString().c_str()); Loading libs/binder/RpcSocketAddress.h +7 −0 Original line number Diff line number Diff line Loading @@ -113,4 +113,11 @@ private: unsigned int mPort; }; /** * Connects to a single socket and produces a RpcTransportFd. */ status_t singleSocketConnection(const RpcSocketAddress& address, const std::unique_ptr<FdTrigger>& shutdownTrigger, RpcTransportFd* outFd); } // namespace android Loading
libs/binder/BackendUnifiedServiceManager.cpp +38 −8 Original line number Diff line number Diff line Loading @@ -46,7 +46,9 @@ binder::Status BackendUnifiedServiceManager::getService2(const ::std::string& na os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->getService2(name, &service); toBinderService(service, _out); if (status.isOk()) { return toBinderService(name, service, _out); } return status; } Loading @@ -54,15 +56,38 @@ binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& n os::Service* _out) { os::Service service; binder::Status status = mTheRealServiceManager->checkService(name, &service); toBinderService(service, _out); if (status.isOk()) { return toBinderService(name, service, _out); } return status; } void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Service* _out) { binder::Status BackendUnifiedServiceManager::toBinderService(const ::std::string& name, const os::Service& in, os::Service* _out) { switch (in.getTag()) { case os::Service::Tag::binder: { if (in.get<os::Service::Tag::binder>() == nullptr) { // failed to find a service. Check to see if we have any local // injected Accessors for this service. os::Service accessor; binder::Status status = getInjectedAccessor(name, &accessor); if (!status.isOk()) { *_out = os::Service::make<os::Service::Tag::binder>(nullptr); return status; } if (accessor.getTag() == os::Service::Tag::accessor && accessor.get<os::Service::Tag::accessor>() != nullptr) { ALOGI("Found local injected service for %s, will attempt to create connection", name.c_str()); // Call this again using the accessor Service to get the real // service's binder into _out return toBinderService(name, accessor, _out); } } *_out = in; break; return binder::Status::ok(); } case os::Service::Tag::accessor: { sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>(); Loading @@ -70,7 +95,7 @@ void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Se if (accessor == nullptr) { ALOGE("Service#accessor doesn't have accessor. VM is maybe starting..."); *_out = os::Service::make<os::Service::Tag::binder>(nullptr); break; return binder::Status::ok(); } auto request = [=] { os::ParcelFileDescriptor fd; Loading @@ -83,10 +108,15 @@ void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Se } }; auto session = RpcSession::make(); session->setupPreconnectedClient(base::unique_fd{}, request); status_t status = session->setupPreconnectedClient(base::unique_fd{}, request); if (status != OK) { ALOGE("Failed to set up preconnected binder RPC client: %s", statusToString(status).c_str()); return binder::Status::fromStatusT(status); } session->setSessionSpecificRoot(accessorBinder); *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject()); break; return binder::Status::ok(); } default: { LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag()); Loading
libs/binder/BackendUnifiedServiceManager.h +5 −2 Original line number Diff line number Diff line Loading @@ -59,9 +59,12 @@ public: private: sp<os::IServiceManager> mTheRealServiceManager; void toBinderService(const os::Service& in, os::Service* _out); binder::Status toBinderService(const ::std::string& name, const os::Service& in, os::Service* _out); }; sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager(); android::binder::Status getInjectedAccessor(const std::string& name, android::os::Service* service); } // namespace android
libs/binder/IServiceManager.cpp +209 −1 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ * limitations under the License. */ #include <sys/socket.h> #define LOG_TAG "ServiceManagerCppClient" #include <binder/IServiceManager.h> Loading @@ -24,14 +25,19 @@ #include <chrono> #include <condition_variable> #include <FdTrigger.h> #include <RpcSocketAddress.h> #include <android-base/properties.h> #include <android/os/BnAccessor.h> #include <android/os/BnServiceCallback.h> #include <android/os/BnServiceManager.h> #include <android/os/IAccessor.h> #include <android/os/IServiceManager.h> #include <binder/IPCThreadState.h> #include <binder/Parcel.h> #include <binder/RpcSession.h> #include <utils/String8.h> #include <variant> #ifndef __ANDROID_VNDK__ #include <binder/IPermissionController.h> #endif Loading Loading @@ -148,8 +154,141 @@ protected: } }; class AccessorProvider { public: AccessorProvider(RpcAccessorProvider&& provider) : mProvider(provider) {} sp<IBinder> provide(const String16& name) { return mProvider(name); } private: AccessorProvider() = delete; RpcAccessorProvider mProvider; }; class AccessorProviderEntry { public: AccessorProviderEntry(std::shared_ptr<AccessorProvider>&& provider) : mProvider(provider) {} std::shared_ptr<AccessorProvider> mProvider; private: AccessorProviderEntry() = delete; }; [[clang::no_destroy]] static std::once_flag gSmOnce; [[clang::no_destroy]] static sp<IServiceManager> gDefaultServiceManager; [[clang::no_destroy]] static std::mutex gAccessorProvidersMutex; [[clang::no_destroy]] static std::vector<AccessorProviderEntry> gAccessorProviders; class LocalAccessor : public android::os::BnAccessor { public: LocalAccessor(const String16& instance, RpcSocketAddressProvider&& connectionInfoProvider) : mInstance(instance), mConnectionInfoProvider(connectionInfoProvider) { LOG_ALWAYS_FATAL_IF(!mConnectionInfoProvider, "LocalAccessor object needs a valid connection info provider"); } ~LocalAccessor() { if (mOnDelete) mOnDelete(); } ::android::binder::Status addConnection(::android::os::ParcelFileDescriptor* outFd) { using android::os::IAccessor; sockaddr_storage addrStorage; std::unique_ptr<FdTrigger> trigger = FdTrigger::make(); RpcTransportFd fd; status_t status = mConnectionInfoProvider(mInstance, reinterpret_cast<sockaddr*>(&addrStorage), sizeof(addrStorage)); if (status != OK) { const std::string error = "The connection info provider was unable to provide " "connection info for instance " + std::string(String8(mInstance).c_str()) + " with status: " + statusToString(status); ALOGE("%s", error.c_str()); return Status::fromServiceSpecificError(IAccessor::ERROR_CONNECTION_INFO_NOT_FOUND, error.c_str()); } if (addrStorage.ss_family == AF_VSOCK) { sockaddr_vm* addr = reinterpret_cast<sockaddr_vm*>(&addrStorage); status = singleSocketConnection(VsockSocketAddress(addr->svm_cid, addr->svm_port), trigger, &fd); } else if (addrStorage.ss_family == AF_UNIX) { sockaddr_un* addr = reinterpret_cast<sockaddr_un*>(&addrStorage); status = singleSocketConnection(UnixSocketAddress(addr->sun_path), trigger, &fd); } else if (addrStorage.ss_family == AF_INET) { sockaddr_in* addr = reinterpret_cast<sockaddr_in*>(&addrStorage); status = singleSocketConnection(InetSocketAddress(reinterpret_cast<sockaddr*>(addr), sizeof(sockaddr_in), inet_ntoa(addr->sin_addr), ntohs(addr->sin_port)), trigger, &fd); } else { const std::string error = "Unsupported socket family type or the ConnectionInfoProvider failed to find a " "valid address. Family type: " + std::to_string(addrStorage.ss_family); ALOGE("%s", error.c_str()); return Status::fromServiceSpecificError(IAccessor::ERROR_UNSUPPORTED_SOCKET_FAMILY, error.c_str()); } if (status != OK) { const std::string error = "Failed to connect to socket for " + std::string(String8(mInstance).c_str()) + " with status: " + statusToString(status); ALOGE("%s", error.c_str()); int err = 0; if (status == -EACCES) { err = IAccessor::ERROR_FAILED_TO_CONNECT_EACCES; } else { err = IAccessor::ERROR_FAILED_TO_CONNECT_TO_SOCKET; } return Status::fromServiceSpecificError(err, error.c_str()); } *outFd = os::ParcelFileDescriptor(std::move(fd.fd)); return Status::ok(); } ::android::binder::Status getInstanceName(String16* instance) { *instance = mInstance; return Status::ok(); } private: LocalAccessor() = delete; String16 mInstance; RpcSocketAddressProvider mConnectionInfoProvider; std::function<void()> mOnDelete; }; android::binder::Status getInjectedAccessor(const std::string& name, android::os::Service* service) { std::vector<AccessorProviderEntry> copiedProviders; { std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); copiedProviders.insert(copiedProviders.begin(), gAccessorProviders.begin(), gAccessorProviders.end()); } // Unlocked to call the providers. This requires the providers to be // threadsafe and not contain any references to objects that could be // deleted. for (const auto& provider : copiedProviders) { sp<IBinder> binder = provider.mProvider->provide(String16(name.c_str())); if (binder == nullptr) continue; status_t status = validateAccessor(String16(name.c_str()), binder); if (status != OK) { ALOGE("A provider returned a binder that is not an IAccessor for instance %s. Status: " "%s", name.c_str(), statusToString(status).c_str()); return android::binder::Status::fromStatusT(android::INVALID_OPERATION); } *service = os::Service::make<os::Service::Tag::accessor>(binder); return android::binder::Status::ok(); } *service = os::Service::make<os::Service::Tag::accessor>(nullptr); return android::binder::Status::ok(); } sp<IServiceManager> defaultServiceManager() { Loading @@ -172,6 +311,75 @@ void setDefaultServiceManager(const sp<IServiceManager>& sm) { } } std::weak_ptr<AccessorProvider> addAccessorProvider(RpcAccessorProvider&& providerCallback) { std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); std::shared_ptr<AccessorProvider> provider = std::make_shared<AccessorProvider>(std::move(providerCallback)); gAccessorProviders.push_back(AccessorProviderEntry(std::move(provider))); return provider; } status_t removeAccessorProvider(std::weak_ptr<AccessorProvider> wProvider) { std::shared_ptr<AccessorProvider> provider = wProvider.lock(); if (provider == nullptr) { ALOGE("The provider supplied to removeAccessorProvider has already been removed."); return NAME_NOT_FOUND; } std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); size_t sizeBefore = gAccessorProviders.size(); gAccessorProviders.erase(std::remove_if(gAccessorProviders.begin(), gAccessorProviders.end(), [&](AccessorProviderEntry entry) { return entry.mProvider == provider; }), gAccessorProviders.end()); if (sizeBefore == gAccessorProviders.size()) { ALOGE("Failed to find an AccessorProvider for removeAccessorProvider"); return NAME_NOT_FOUND; } return OK; } status_t validateAccessor(const String16& instance, const sp<IBinder>& binder) { if (binder == nullptr) { ALOGE("Binder is null"); return BAD_VALUE; } sp<IAccessor> accessor = interface_cast<IAccessor>(binder); if (accessor == nullptr) { ALOGE("This binder for %s is not an IAccessor binder", String8(instance).c_str()); return BAD_TYPE; } String16 reportedInstance; Status status = accessor->getInstanceName(&reportedInstance); if (!status.isOk()) { ALOGE("Failed to validate the binder being used to create a new ARpc_Accessor for %s with " "status: %s", String8(instance).c_str(), status.toString8().c_str()); return NAME_NOT_FOUND; } if (reportedInstance != instance) { ALOGE("Instance %s doesn't match the Accessor's instance of %s", String8(instance).c_str(), String8(reportedInstance).c_str()); return NAME_NOT_FOUND; } return OK; } sp<IBinder> createAccessor(const String16& instance, RpcSocketAddressProvider&& connectionInfoProvider) { // Try to create a new accessor if (!connectionInfoProvider) { ALOGE("Could not find an Accessor for %s and no ConnectionInfoProvider provided to " "create a new one", String8(instance).c_str()); return nullptr; } sp<IBinder> binder = sp<LocalAccessor>::make(instance, std::move(connectionInfoProvider)); return binder; } #if !defined(__ANDROID_VNDK__) // IPermissionController is not accessible to vendors Loading
libs/binder/RpcSession.cpp +18 −2 Original line number Diff line number Diff line Loading @@ -589,6 +589,21 @@ status_t RpcSession::setupSocketClient(const RpcSocketAddress& addr) { status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, const std::vector<uint8_t>& sessionId, bool incoming) { RpcTransportFd transportFd; status_t status = singleSocketConnection(addr, mShutdownTrigger, &transportFd); if (status != OK) return status; return initAndAddConnection(std::move(transportFd), sessionId, incoming); } status_t singleSocketConnection(const RpcSocketAddress& addr, const std::unique_ptr<FdTrigger>& shutdownTrigger, RpcTransportFd* outFd) { LOG_ALWAYS_FATAL_IF(outFd == nullptr, "There is no reason to call this function without an outFd"); LOG_ALWAYS_FATAL_IF(shutdownTrigger == nullptr, "FdTrigger argument is required so we don't get stuck in the connect call " "if the server process shuts down."); for (size_t tries = 0; tries < 5; tries++) { if (tries > 0) usleep(10000); Loading Loading @@ -620,7 +635,7 @@ status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, if (connErrno == EAGAIN || connErrno == EINPROGRESS) { // For non-blocking sockets, connect() may return EAGAIN (for unix domain socket) or // EINPROGRESS (for others). Call poll() and getsockopt() to get the error. status_t pollStatus = mShutdownTrigger->triggerablePoll(transportFd, POLLOUT); status_t pollStatus = shutdownTrigger->triggerablePoll(transportFd, POLLOUT); if (pollStatus != OK) { ALOGE("Could not POLLOUT after connect() on non-blocking socket: %s", statusToString(pollStatus).c_str()); Loading Loading @@ -654,7 +669,8 @@ status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), transportFd.fd.get()); return initAndAddConnection(std::move(transportFd), sessionId, incoming); *outFd = std::move(transportFd); return OK; } ALOGE("Ran out of retries to connect to %s", addr.toString().c_str()); Loading
libs/binder/RpcSocketAddress.h +7 −0 Original line number Diff line number Diff line Loading @@ -113,4 +113,11 @@ private: unsigned int mPort; }; /** * Connects to a single socket and produces a RpcTransportFd. */ status_t singleSocketConnection(const RpcSocketAddress& address, const std::unique_ptr<FdTrigger>& shutdownTrigger, RpcTransportFd* outFd); } // namespace android