diff options
-rw-r--r-- | cmds/installd/QuotaUtils.cpp | 2 | ||||
-rw-r--r-- | libs/binder/LazyServiceRegistrar.cpp | 75 | ||||
-rw-r--r-- | libs/binder/Parcel.cpp | 10 | ||||
-rw-r--r-- | libs/binder/ndk/ibinder.cpp | 2 | ||||
-rw-r--r-- | libs/binder/ndk/ibinder_internal.h | 10 | ||||
-rw-r--r-- | libs/binder/ndk/tests/iface.cpp | 12 | ||||
-rw-r--r-- | libs/binder/ndk/tests/include/iface/iface.h | 3 | ||||
-rw-r--r-- | libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp | 20 | ||||
-rw-r--r-- | services/inputflinger/reader/InputDevice.cpp | 6 | ||||
-rw-r--r-- | services/inputflinger/reader/InputReader.cpp | 36 | ||||
-rw-r--r-- | services/inputflinger/reader/include/InputDevice.h | 2 | ||||
-rw-r--r-- | services/inputflinger/reader/include/InputReader.h | 5 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.cpp | 12 |
13 files changed, 116 insertions, 79 deletions
diff --git a/cmds/installd/QuotaUtils.cpp b/cmds/installd/QuotaUtils.cpp index e0802911ca..60271392e9 100644 --- a/cmds/installd/QuotaUtils.cpp +++ b/cmds/installd/QuotaUtils.cpp @@ -35,7 +35,7 @@ std::recursive_mutex mMountsLock; /* Map of all quota mounts from target to source */ std::unordered_map<std::string, std::string> mQuotaReverseMounts; -std::string& FindQuotaDeviceForUuid(const std::string& uuid) { +std::string FindQuotaDeviceForUuid(const std::string& uuid) { std::lock_guard<std::recursive_mutex> lock(mMountsLock); auto path = create_data_path(uuid.empty() ? nullptr : uuid.c_str()); return mQuotaReverseMounts[path]; diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp index 68ea8a6d79..f96b6bb4eb 100644 --- a/libs/binder/LazyServiceRegistrar.cpp +++ b/libs/binder/LazyServiceRegistrar.cpp @@ -48,6 +48,22 @@ protected: Status onClients(const sp<IBinder>& service, bool clients) override; private: + struct Service { + sp<IBinder> service; + bool allowIsolated; + int dumpFlags; + + // whether, based on onClients calls, we know we have a client for this + // service or not + bool clients = false; + bool registered = true; + }; + + /** + * Looks up a service guaranteed to be registered (service from onClients). + */ + std::map<std::string, Service>::iterator assertRegisteredService(const sp<IBinder>& service); + /** * Unregisters all services that we can. If we can't unregister all, re-register other * services. @@ -62,24 +78,13 @@ private: */ void maybeTryShutdown(); - /* - * Counter of the number of services that currently have at least one client. - */ + // count of services with clients size_t mNumConnectedServices; // previous value passed to the active services callback std::optional<bool> mPreviousHasClients; - struct Service { - sp<IBinder> service; - bool allowIsolated; - int dumpFlags; - - bool registered = true; - }; - /** - * Map of registered names and services - */ + // map of registered names and services std::map<std::string, Service> mRegisteredServices; bool mForcePersist; @@ -124,18 +129,34 @@ bool ClientCounterCallbackImpl::registerService(const sp<IBinder>& service, cons } if (!reRegister) { - if (!manager->registerClientCallback(name, service, this).isOk()) { + if(!manager->registerClientCallback(name, service, this).isOk()) { ALOGE("Failed to add client callback for service %s", name.c_str()); return false; } // Only add this when a service is added for the first time, as it is not removed - mRegisteredServices[name] = {service, allowIsolated, dumpFlags}; + mRegisteredServices[name] = { + .service = service, + .allowIsolated = allowIsolated, + .dumpFlags = dumpFlags + }; } return true; } +std::map<std::string, ClientCounterCallbackImpl::Service>::iterator ClientCounterCallbackImpl::assertRegisteredService(const sp<IBinder>& service) { + LOG_ALWAYS_FATAL_IF(service == nullptr, "Got onClients callback for null service"); + for (auto it = mRegisteredServices.begin(); it != mRegisteredServices.end(); ++it) { + auto const& [name, registered] = *it; + (void) name; + if (registered.service != service) continue; + return it; + } + LOG_ALWAYS_FATAL("Got callback on service which we did not register: %s", String8(service->getInterfaceDescriptor()).c_str()); + __builtin_unreachable(); +} + void ClientCounterCallbackImpl::forcePersist(bool persist) { mForcePersist = persist; if (!mForcePersist) { @@ -205,15 +226,25 @@ void ClientCounterCallbackImpl::maybeTryShutdown() { * invocations could occur on different threads however. */ Status ClientCounterCallbackImpl::onClients(const sp<IBinder>& service, bool clients) { - if (clients) { - mNumConnectedServices++; - } else { - mNumConnectedServices--; + auto & [name, registered] = *assertRegisteredService(service); + if (registered.clients == clients) { + LOG_ALWAYS_FATAL("Process already thought %s had clients: %d but servicemanager has " + "notified has clients: %d", name.c_str(), registered.clients, clients); + } + registered.clients = clients; + + // update cache count of clients + { + size_t numWithClients = 0; + for (const auto& [name, registered] : mRegisteredServices) { + (void) name; + if (registered.clients) numWithClients++; + } + mNumConnectedServices = numWithClients; } ALOGI("Process has %zu (of %zu available) client(s) in use after notification %s has clients: %d", - mNumConnectedServices, mRegisteredServices.size(), - String8(service->getInterfaceDescriptor()).string(), clients); + mNumConnectedServices, mRegisteredServices.size(), name.c_str(), clients); maybeTryShutdown(); return Status::ok(); @@ -236,7 +267,7 @@ void ClientCounterCallbackImpl::setActiveServicesCallback(const std::function<bo } ClientCounterCallback::ClientCounterCallback() { - mImpl = new ClientCounterCallbackImpl(); + mImpl = sp<ClientCounterCallbackImpl>::make(); } bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name, diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 8bed621ab4..1a4ede1940 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -1651,7 +1651,10 @@ const char* Parcel::readString8Inplace(size_t* outLen) const *outLen = size; const char* str = (const char*)readInplace(size+1); if (str != nullptr) { - return str; + if (str[size] == '\0') { + return str; + } + android_errorWriteLog(0x534e4554, "172655291"); } } *outLen = 0; @@ -1689,7 +1692,10 @@ const char16_t* Parcel::readString16Inplace(size_t* outLen) const *outLen = size; const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t)); if (str != nullptr) { - return str; + if (str[size] == u'\0') { + return str; + } + android_errorWriteLog(0x534e4554, "172655291"); } } *outLen = 0; diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp index 3c906819ff..0f59de4309 100644 --- a/libs/binder/ndk/ibinder.cpp +++ b/libs/binder/ndk/ibinder.cpp @@ -181,7 +181,7 @@ status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parce binder_status_t status = getClass()->onTransact(this, code, &in, &out); return PruneStatusT(status); - } else if (code == SHELL_COMMAND_TRANSACTION && getClass()->handleShellCommand != nullptr) { + } else if (code == SHELL_COMMAND_TRANSACTION) { int in = data.readFileDescriptor(); int out = data.readFileDescriptor(); int err = data.readFileDescriptor(); diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h index 6824306fbf..22cacb4e08 100644 --- a/libs/binder/ndk/ibinder_internal.h +++ b/libs/binder/ndk/ibinder_internal.h @@ -116,13 +116,13 @@ struct AIBinder_Class { const char* getInterfaceDescriptorUtf8() const { return mInterfaceDescriptor.c_str(); } // required to be non-null, implemented for every class - const AIBinder_Class_onCreate onCreate = nullptr; - const AIBinder_Class_onDestroy onDestroy = nullptr; - const AIBinder_Class_onTransact onTransact = nullptr; + const AIBinder_Class_onCreate onCreate; + const AIBinder_Class_onDestroy onDestroy; + const AIBinder_Class_onTransact onTransact; // optional methods for a class - AIBinder_onDump onDump = nullptr; - AIBinder_handleShellCommand handleShellCommand = nullptr; + AIBinder_onDump onDump; + AIBinder_handleShellCommand handleShellCommand; private: // Copy of the raw char string for when we don't have to return UTF-16 diff --git a/libs/binder/ndk/tests/iface.cpp b/libs/binder/ndk/tests/iface.cpp index 2afe5d2058..53b5c3c320 100644 --- a/libs/binder/ndk/tests/iface.cpp +++ b/libs/binder/ndk/tests/iface.cpp @@ -118,7 +118,7 @@ IFoo::~IFoo() { AIBinder_Weak_delete(mWeakBinder); } -AIBinder* IFoo::getBinder() { +binder_status_t IFoo::addService(const char* instance) { AIBinder* binder = nullptr; if (mWeakBinder != nullptr) { @@ -132,18 +132,8 @@ AIBinder* IFoo::getBinder() { AIBinder_Weak_delete(mWeakBinder); } mWeakBinder = AIBinder_Weak_new(binder); - - // WARNING: it is important that this class does not implement debug or - // shell functions because it does not use special C++ wrapper - // functions, and so this is how we test those functions. } - return binder; -} - -binder_status_t IFoo::addService(const char* instance) { - AIBinder* binder = getBinder(); - binder_status_t status = AServiceManager_addService(binder, instance); // Strong references we care about kept by remote process AIBinder_decStrong(binder); diff --git a/libs/binder/ndk/tests/include/iface/iface.h b/libs/binder/ndk/tests/include/iface/iface.h index 7408d0c5a9..244c9857ac 100644 --- a/libs/binder/ndk/tests/include/iface/iface.h +++ b/libs/binder/ndk/tests/include/iface/iface.h @@ -31,9 +31,6 @@ class IFoo : public virtual ::android::RefBase { static AIBinder_Class* kClass; - // binder representing this interface with one reference count - AIBinder* getBinder(); - // Takes ownership of IFoo binder_status_t addService(const char* instance); static ::android::sp<IFoo> getService(const char* instance, AIBinder** outBinder = nullptr); diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp index de1a48dfd8..7f725e0bfb 100644 --- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp @@ -241,26 +241,6 @@ TEST(NdkBinder, CheckServiceThatDoesExist) { AIBinder_decStrong(binder); } -TEST(NdkBinder, UnimplementedDump) { - sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName); - ASSERT_NE(foo, nullptr); - AIBinder* binder = foo->getBinder(); - EXPECT_EQ(OK, AIBinder_dump(binder, STDOUT_FILENO, nullptr, 0)); - AIBinder_decStrong(binder); -} - -TEST(NdkBinder, UnimplementedShell) { - // libbinder_ndk doesn't support calling shell, so we are calling from the - // libbinder across processes to the NDK service which doesn't implement - // shell - static const sp<android::IServiceManager> sm(android::defaultServiceManager()); - sp<IBinder> testService = sm->getService(String16(IFoo::kSomeInstanceName)); - - Vector<String16> argsVec; - EXPECT_EQ(OK, IBinder::shellCommand(testService, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, - argsVec, nullptr, nullptr)); -} - TEST(NdkBinder, DoubleNumber) { sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName); ASSERT_NE(foo, nullptr); diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp index 4b19e5e353..3347ba6ad7 100644 --- a/services/inputflinger/reader/InputDevice.cpp +++ b/services/inputflinger/reader/InputDevice.cpp @@ -84,12 +84,13 @@ void InputDevice::setEnabled(bool enabled, nsecs_t when) { bumpGeneration(); } -void InputDevice::dump(std::string& dump) { +void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) { InputDeviceInfo deviceInfo; getDeviceInfo(&deviceInfo); dump += StringPrintf(INDENT "Device %d: %s\n", deviceInfo.getId(), deviceInfo.getDisplayName().c_str()); + dump += StringPrintf(INDENT "%s", eventHubDevStr.c_str()); dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration); dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal)); dump += StringPrintf(INDENT2 "AssociatedDisplayPort: "); @@ -101,6 +102,7 @@ void InputDevice::dump(std::string& dump) { dump += StringPrintf(INDENT2 "HasMic: %s\n", toString(mHasMic)); dump += StringPrintf(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources()); dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType()); + dump += StringPrintf(INDENT2 "ControllerNum: %d\n", deviceInfo.getControllerNumber()); const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges(); if (!ranges.empty()) { @@ -200,6 +202,8 @@ void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) { // insert the context into the devices set mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))}); + // Must change generation to flag this device as changed + bumpGeneration(); } void InputDevice::removeEventHubDevice(int32_t eventHubId) { diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index 06e374353c..dff830ca7f 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -206,6 +206,14 @@ void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) { } mDevices.emplace(eventHubId, device); + // Add device to device to EventHub ids map. + const auto mapIt = mDeviceToEventHubIdsMap.find(device); + if (mapIt == mDeviceToEventHubIdsMap.end()) { + std::vector<int32_t> ids = {eventHubId}; + mDeviceToEventHubIdsMap.emplace(device, ids); + } else { + mapIt->second.push_back(eventHubId); + } bumpGenerationLocked(); if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) { @@ -222,6 +230,17 @@ void InputReader::removeDeviceLocked(nsecs_t when, int32_t eventHubId) { std::shared_ptr<InputDevice> device = std::move(deviceIt->second); mDevices.erase(deviceIt); + // Erase device from device to EventHub ids map. + auto mapIt = mDeviceToEventHubIdsMap.find(device); + if (mapIt != mDeviceToEventHubIdsMap.end()) { + std::vector<int32_t>& eventHubIds = mapIt->second; + eventHubIds.erase(std::remove_if(eventHubIds.begin(), eventHubIds.end(), + [eventHubId](int32_t eId) { return eId == eventHubId; }), + eventHubIds.end()); + if (eventHubIds.size() == 0) { + mDeviceToEventHubIdsMap.erase(mapIt); + } + } bumpGenerationLocked(); if (device->isIgnored()) { @@ -450,8 +469,7 @@ void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) { outInputDevices.clear(); - for (auto& devicePair : mDevices) { - std::shared_ptr<InputDevice>& device = devicePair.second; + for (const auto& [device, eventHubIds] : mDeviceToEventHubIdsMap) { if (!device->isIgnored()) { InputDeviceInfo info; device->getDeviceInfo(&info); @@ -622,11 +640,17 @@ void InputReader::dump(std::string& dump) { mEventHub->dump(dump); dump += "\n"; - dump += "Input Reader State:\n"; + dump += StringPrintf("Input Reader State (Nums of device: %zu):\n", + mDeviceToEventHubIdsMap.size()); - for (const auto& devicePair : mDevices) { - const std::shared_ptr<InputDevice>& device = devicePair.second; - device->dump(dump); + for (const auto& devicePair : mDeviceToEventHubIdsMap) { + const std::shared_ptr<InputDevice>& device = devicePair.first; + std::string eventHubDevStr = INDENT "EventHub Devices: [ "; + for (const auto& eId : devicePair.second) { + eventHubDevStr += StringPrintf("%d ", eId); + } + eventHubDevStr += "] \n"; + device->dump(dump, eventHubDevStr); } dump += INDENT "Configuration:\n"; diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h index 7c17102826..d2bb4f4b4c 100644 --- a/services/inputflinger/reader/include/InputDevice.h +++ b/services/inputflinger/reader/include/InputDevice.h @@ -66,7 +66,7 @@ public: bool isEnabled(); void setEnabled(bool enabled, nsecs_t when); - void dump(std::string& dump); + void dump(std::string& dump, const std::string& eventHubDevStr); void addEventHubDevice(int32_t eventHubId, bool populateMappers = true); void removeEventHubDevice(int32_t eventHubId); void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes); diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h index 108b9c236c..2773f709eb 100644 --- a/services/inputflinger/reader/include/InputReader.h +++ b/services/inputflinger/reader/include/InputReader.h @@ -143,6 +143,11 @@ private: // to lookup the input device instance from the EventHub device id. std::unordered_map<int32_t /*eventHubId*/, std::shared_ptr<InputDevice>> mDevices; + // An input device contains one or more eventHubId, this map provides a way to lookup the + // EventHubIds contained in the input device from the input device instance. + std::unordered_map<std::shared_ptr<InputDevice>, std::vector<int32_t> /*eventHubId*/> + mDeviceToEventHubIdsMap; + // low-level input event decoding and device management void processEventsLocked(const RawEvent* rawEvents, size_t count); diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 55d80fb7d9..5d4717200d 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -149,8 +149,8 @@ class CreateInfoWrapper { Hal Hal::hal_; const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{ - "ro.hardware.vulkan", - "ro.board.platform", + "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID, + "ro.board.platform" }}; constexpr int LIB_DL_FLAGS = RTLD_LOCAL | RTLD_NOW; @@ -184,8 +184,9 @@ int LoadDriver(android_namespace_t* library_namespace, if (so) break; } - if (!so) + if (!so) { return -ENOENT; + } auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR)); if (!hmi) { @@ -230,7 +231,6 @@ int LoadUpdatedDriver(const hwvulkan_module_t** module) { bool Hal::Open() { ATRACE_CALL(); - const nsecs_t openTime = systemTime(); ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once"); @@ -248,16 +248,16 @@ bool Hal::Open() { if (result != 0) { android::GraphicsEnv::getInstance().setDriverLoaded( android::GpuStatsInfo::Api::API_VK, false, systemTime() - openTime); - ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result); return true; } - hwvulkan_device_t* device; ATRACE_BEGIN("hwvulkan module open"); result = module->common.methods->open(&module->common, HWVULKAN_DEVICE_0, reinterpret_cast<hw_device_t**>(&device)); + + ATRACE_END(); if (result != 0) { android::GraphicsEnv::getInstance().setDriverLoaded( |