Merge "Error fix from enabling Clang thread-safety checks." into main
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 1333599..d85182d 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -112,13 +112,15 @@
std::string iface;
std::string instance;
- static bool fill(const std::string& name, AidlName* aname) {
+ static bool fill(const std::string& name, AidlName* aname, bool logError) {
size_t firstSlash = name.find('/');
size_t lastDot = name.rfind('.', firstSlash);
if (firstSlash == std::string::npos || lastDot == std::string::npos) {
- ALOGE("VINTF HALs require names in the format type/instance (e.g. "
- "some.package.foo.IFoo/default) but got: %s",
- name.c_str());
+ if (logError) {
+ ALOGE("VINTF HALs require names in the format type/instance (e.g. "
+ "some.package.foo.IFoo/default) but got: %s",
+ name.c_str());
+ }
return false;
}
aname->package = name.substr(0, lastDot);
@@ -151,7 +153,7 @@
}
AidlName aname;
- if (!AidlName::fill(name, &aname)) return false;
+ if (!AidlName::fill(name, &aname, true)) return false;
bool found = forEachManifest([&](const ManifestWithDescription& mwd) {
if (mwd.manifest->hasAidlInstance(aname.package, aname.iface, aname.instance)) {
@@ -209,7 +211,7 @@
}
AidlName aname;
- if (!AidlName::fill(name, &aname)) return std::nullopt;
+ if (!AidlName::fill(name, &aname, true)) return std::nullopt;
std::optional<std::string> updatableViaApex;
@@ -249,9 +251,28 @@
return names;
}
+static std::optional<std::string> getVintfAccessorName(const std::string& name) {
+ AidlName aname;
+ if (!AidlName::fill(name, &aname, false)) return std::nullopt;
+
+ std::optional<std::string> accessor;
+ forEachManifest([&](const ManifestWithDescription& mwd) {
+ mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
+ if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
+ if (manifestInstance.package() != aname.package) return true;
+ if (manifestInstance.interface() != aname.iface) return true;
+ if (manifestInstance.instance() != aname.instance) return true;
+ accessor = manifestInstance.accessor();
+ return false; // break (libvintf uses opposite convention)
+ });
+ return false; // continue
+ });
+ return accessor;
+}
+
static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
AidlName aname;
- if (!AidlName::fill(name, &aname)) return std::nullopt;
+ if (!AidlName::fill(name, &aname, true)) return std::nullopt;
std::optional<std::string> ip;
std::optional<uint64_t> port;
@@ -364,23 +385,40 @@
}
}
-Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
+Status ServiceManager::getService(const std::string& name, os::Service* outService) {
SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
- *outBinder = tryGetService(name, true);
+ *outService = tryGetService(name, true);
// returns ok regardless of result for legacy reasons
return Status::ok();
}
-Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
+Status ServiceManager::checkService(const std::string& name, os::Service* outService) {
SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
- *outBinder = tryGetService(name, false);
+ *outService = tryGetService(name, false);
// returns ok regardless of result for legacy reasons
return Status::ok();
}
-sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
+os::Service ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
+ std::optional<std::string> accessorName;
+#ifndef VENDORSERVICEMANAGER
+ accessorName = getVintfAccessorName(name);
+#endif
+ if (accessorName.has_value()) {
+ auto ctx = mAccess->getCallingContext();
+ if (!mAccess->canFind(ctx, name)) {
+ return os::Service::make<os::Service::Tag::accessor>(nullptr);
+ }
+ return os::Service::make<os::Service::Tag::accessor>(
+ tryGetBinder(*accessorName, startIfNotFound));
+ } else {
+ return os::Service::make<os::Service::Tag::binder>(tryGetBinder(name, startIfNotFound));
+ }
+}
+
+sp<IBinder> ServiceManager::tryGetBinder(const std::string& name, bool startIfNotFound) {
SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
auto ctx = mAccess->getCallingContext();
@@ -565,8 +603,11 @@
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux");
+ // TODO(b/338541373): Implement the notification mechanism for services accessed via
+ // IAccessor.
+ std::optional<std::string> accessorName;
+ if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) {
+ return status;
}
// note - we could allow isolated apps to get notifications if we
@@ -613,8 +654,9 @@
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+ std::optional<std::string> accessorName;
+ if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) {
+ return status;
}
bool found = false;
@@ -638,8 +680,9 @@
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+ std::optional<std::string> accessorName;
+ if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) {
+ return status;
}
*outReturn = false;
@@ -662,8 +705,10 @@
outReturn->clear();
+ std::optional<std::string> _accessorName;
for (const std::string& instance : allInstances) {
- if (mAccess->canFind(ctx, interface + "/" + instance)) {
+ if (auto status = canFindService(ctx, interface + "/" + instance, &_accessorName);
+ status.isOk()) {
outReturn->push_back(instance);
}
}
@@ -681,8 +726,9 @@
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+ std::optional<std::string> _accessorName;
+ if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) {
+ return status;
}
*outReturn = std::nullopt;
@@ -706,8 +752,9 @@
outReturn->clear();
+ std::optional<std::string> _accessorName;
for (const std::string& name : apexUpdatableNames) {
- if (mAccess->canFind(ctx, name)) {
+ if (auto status = canFindService(ctx, name, &_accessorName); status.isOk()) {
outReturn->push_back(name);
}
}
@@ -724,8 +771,9 @@
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+ std::optional<std::string> _accessorName;
+ if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) {
+ return status;
}
*outReturn = std::nullopt;
@@ -1032,6 +1080,23 @@
return Status::ok();
}
+Status ServiceManager::canFindService(const Access::CallingContext& ctx, const std::string& name,
+ std::optional<std::string>* accessor) {
+ if (!mAccess->canFind(ctx, name)) {
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied for service.");
+ }
+#ifndef VENDORSERVICEMANAGER
+ *accessor = getVintfAccessorName(name);
+#endif
+ if (accessor->has_value()) {
+ if (!mAccess->canFind(ctx, accessor->value())) {
+ return Status::fromExceptionCode(Status::EX_SECURITY,
+ "SELinux denied for the accessor of the service.");
+ }
+ }
+ return Status::ok();
+}
+
Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
SM_PERFETTO_TRACE_FUNC();
if (!mAccess->canList(mAccess->getCallingContext())) {
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 1536014..18bae68 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -44,8 +44,8 @@
~ServiceManager();
// getService will try to start any services it cannot find
- binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override;
- binder::Status checkService(const std::string& name, sp<IBinder>* outBinder) override;
+ binder::Status getService(const std::string& name, os::Service* outService) override;
+ binder::Status checkService(const std::string& name, os::Service* outService) override;
binder::Status addService(const std::string& name, const sp<IBinder>& binder,
bool allowIsolated, int32_t dumpPriority) override;
binder::Status listServices(int32_t dumpPriority, std::vector<std::string>* outList) override;
@@ -112,7 +112,10 @@
// this updates the iterator to the next location
void removeClientCallback(const wp<IBinder>& who, ClientCallbackMap::iterator* it);
- sp<IBinder> tryGetService(const std::string& name, bool startIfNotFound);
+ os::Service tryGetService(const std::string& name, bool startIfNotFound);
+ sp<IBinder> tryGetBinder(const std::string& name, bool startIfNotFound);
+ binder::Status canFindService(const Access::CallingContext& ctx, const std::string& name,
+ std::optional<std::string>* accessor);
ServiceMap mNameToService;
ServiceCallbackMap mNameToRegistrationCallback;
diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp
index b575053..9d22641 100644
--- a/cmds/servicemanager/test_sm.cpp
+++ b/cmds/servicemanager/test_sm.cpp
@@ -38,6 +38,7 @@
using android::binder::Status;
using android::os::BnServiceCallback;
using android::os::IServiceManager;
+using android::os::Service;
using testing::_;
using testing::ElementsAre;
using testing::NiceMock;
@@ -153,18 +154,18 @@
EXPECT_TRUE(sm->addService("foo", serviceA, false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> outA;
+ Service outA;
EXPECT_TRUE(sm->getService("foo", &outA).isOk());
- EXPECT_EQ(serviceA, outA);
+ EXPECT_EQ(serviceA, outA.get<Service::Tag::binder>());
// serviceA should be overwritten by serviceB
sp<IBinder> serviceB = getBinder();
EXPECT_TRUE(sm->addService("foo", serviceB, false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> outB;
+ Service outB;
EXPECT_TRUE(sm->getService("foo", &outB).isOk());
- EXPECT_EQ(serviceB, outB);
+ EXPECT_EQ(serviceB, outB.get<Service::Tag::binder>());
}
TEST(AddService, NoPermissions) {
@@ -186,17 +187,17 @@
EXPECT_TRUE(sm->addService("foo", service, false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> out;
+ Service out;
EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(service, out);
+ EXPECT_EQ(service, out.get<Service::Tag::binder>());
}
TEST(GetService, NonExistant) {
auto sm = getPermissiveServiceManager();
- sp<IBinder> out;
+ Service out;
EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(nullptr, out.get());
+ EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
}
TEST(GetService, NoPermissionsForGettingService) {
@@ -211,10 +212,10 @@
EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> out;
+ Service out;
// returns nullptr but has OK status for legacy compatibility
EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(nullptr, out.get());
+ EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
}
TEST(GetService, AllowedFromIsolated) {
@@ -236,9 +237,9 @@
EXPECT_TRUE(sm->addService("foo", service, true /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> out;
+ Service out;
EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(service, out.get());
+ EXPECT_EQ(service, out.get<Service::Tag::binder>());
}
TEST(GetService, NotAllowedFromIsolated) {
@@ -261,10 +262,10 @@
EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> out;
+ Service out;
// returns nullptr but has OK status for legacy compatibility
EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(nullptr, out.get());
+ EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
}
TEST(ListServices, NoPermissions) {
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index cdc7166..de331b7 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -450,8 +450,31 @@
],
}
+soong_config_module_type {
+ name: "libbinder_client_cache_config",
+ module_type: "cc_defaults",
+ config_namespace: "libbinder",
+ bool_variables: ["release_libbinder_client_cache"],
+ properties: [
+ "cflags",
+ ],
+}
+
+libbinder_client_cache_config {
+ name: "libbinder_client_cache_flag",
+ soong_config_variables: {
+ release_libbinder_client_cache: {
+ cflags: ["-DLIBBINDER_CLIENT_CACHE"],
+ conditions_default: {
+ cflags: ["-DNO_LIBBINDER_CLIENT_CACHE"],
+ },
+ },
+ },
+}
+
cc_defaults {
name: "libbinder_kernel_defaults",
+ defaults: ["libbinder_client_cache_flag"],
srcs: [
"BufferedTextOutput.cpp",
"BackendUnifiedServiceManager.cpp",
@@ -771,11 +794,41 @@
"aidl/android/os/IClientCallback.aidl",
"aidl/android/os/IServiceCallback.aidl",
"aidl/android/os/IServiceManager.aidl",
+ "aidl/android/os/Service.aidl",
"aidl/android/os/ServiceDebugInfo.aidl",
+ ":libbinder_accessor_aidl",
],
path: "aidl",
}
+filegroup {
+ name: "libbinder_accessor_aidl",
+ srcs: [
+ "aidl/android/os/IAccessor.aidl",
+ ],
+ path: "aidl",
+}
+
+// TODO(b/353492849): Make this interface private to libbinder.
+aidl_interface {
+ name: "android.os.accessor",
+ srcs: [":libbinder_accessor_aidl"],
+ unstable: true,
+ backend: {
+ rust: {
+ enabled: true,
+ apex_available: [
+ "com.android.virt",
+ ],
+ },
+ },
+ visibility: [
+ ":__subpackages__",
+ "//system/tools/aidl:__subpackages__",
+ "//packages/modules/Virtualization:__subpackages__",
+ ],
+}
+
aidl_interface {
name: "packagemanager_aidl",
unstable: true,
diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp
index b0d3048..0bf3cad 100644
--- a/libs/binder/BackendUnifiedServiceManager.cpp
+++ b/libs/binder/BackendUnifiedServiceManager.cpp
@@ -15,6 +15,9 @@
*/
#include "BackendUnifiedServiceManager.h"
+#include <android/os/IAccessor.h>
+#include <binder/RpcSession.h>
+
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
#include <android-base/properties.h>
#endif
@@ -22,6 +25,7 @@
namespace android {
using AidlServiceManager = android::os::IServiceManager;
+using IAccessor = android::os::IAccessor;
BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl)
: mTheRealServiceManager(impl) {}
@@ -30,13 +34,57 @@
return mTheRealServiceManager;
}
binder::Status BackendUnifiedServiceManager::getService(const ::std::string& name,
- sp<IBinder>* _aidl_return) {
- return mTheRealServiceManager->getService(name, _aidl_return);
+ os::Service* _out) {
+ os::Service service;
+ binder::Status status = mTheRealServiceManager->getService(name, &service);
+ toBinderService(service, _out);
+ return status;
}
+
binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& name,
- sp<IBinder>* _aidl_return) {
- return mTheRealServiceManager->checkService(name, _aidl_return);
+ os::Service* _out) {
+ os::Service service;
+ binder::Status status = mTheRealServiceManager->checkService(name, &service);
+ toBinderService(service, _out);
+ return status;
}
+
+void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Service* _out) {
+ switch (in.getTag()) {
+ case os::Service::Tag::binder: {
+ *_out = in;
+ break;
+ }
+ case os::Service::Tag::accessor: {
+ sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>();
+ sp<IAccessor> accessor = interface_cast<IAccessor>(accessorBinder);
+ if (accessor == nullptr) {
+ ALOGE("Service#accessor doesn't have accessor. VM is maybe starting...");
+ *_out = os::Service::make<os::Service::Tag::binder>(nullptr);
+ break;
+ }
+ auto request = [=] {
+ os::ParcelFileDescriptor fd;
+ binder::Status ret = accessor->addConnection(&fd);
+ if (ret.isOk()) {
+ return base::unique_fd(fd.release());
+ } else {
+ ALOGE("Failed to connect to RpcSession: %s", ret.toString8().c_str());
+ return base::unique_fd(-1);
+ }
+ };
+ auto session = RpcSession::make();
+ session->setupPreconnectedClient(base::unique_fd{}, request);
+ session->setSessionSpecificRoot(accessorBinder);
+ *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject());
+ break;
+ }
+ default: {
+ LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag());
+ }
+ }
+}
+
binder::Status BackendUnifiedServiceManager::addService(const ::std::string& name,
const sp<IBinder>& service,
bool allowIsolated, int32_t dumpPriority) {
diff --git a/libs/binder/BackendUnifiedServiceManager.h b/libs/binder/BackendUnifiedServiceManager.h
index d72b5bb..4715be4 100644
--- a/libs/binder/BackendUnifiedServiceManager.h
+++ b/libs/binder/BackendUnifiedServiceManager.h
@@ -26,8 +26,8 @@
explicit BackendUnifiedServiceManager(const sp<os::IServiceManager>& impl);
sp<os::IServiceManager> getImpl();
- binder::Status getService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
- binder::Status checkService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
+ binder::Status getService(const ::std::string& name, os::Service* out) override;
+ binder::Status checkService(const ::std::string& name, os::Service* out) override;
binder::Status addService(const ::std::string& name, const sp<IBinder>& service,
bool allowIsolated, int32_t dumpPriority) override;
binder::Status listServices(int32_t dumpPriority,
@@ -60,6 +60,7 @@
private:
sp<os::IServiceManager> mTheRealServiceManager;
+ void toBinderService(const os::Service& in, os::Service* _out);
};
sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager();
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 17e522d..12a18f2 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -26,6 +26,7 @@
#include <android-base/properties.h>
#include <android/os/BnServiceCallback.h>
+#include <android/os/IAccessor.h>
#include <android/os/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
@@ -57,6 +58,8 @@
using AidlServiceManager = android::os::IServiceManager;
using android::binder::Status;
+using android::os::IAccessor;
+using android::os::Service;
// libbinder's IServiceManager.h can't rely on the values generated by AIDL
// because many places use its headers via include_dirs (meaning, without
@@ -139,7 +142,10 @@
// When implementing ServiceManagerShim, use realGetService instead of
// mUnifiedServiceManager->getService so that it can be overridden in ServiceManagerHostShim.
virtual Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
- return mUnifiedServiceManager->getService(name, _aidl_return);
+ Service service;
+ Status status = mUnifiedServiceManager->getService(name, &service);
+ *_aidl_return = service.get<Service::Tag::binder>();
+ return status;
}
};
@@ -327,11 +333,11 @@
sp<IBinder> ServiceManagerShim::checkService(const String16& name) const
{
- sp<IBinder> ret;
+ Service ret;
if (!mUnifiedServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
return nullptr;
}
- return ret;
+ return ret.get<Service::Tag::binder>();
}
status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 16a7f9f..49def82 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -801,6 +801,14 @@
return true;
}
+void RpcSession::setSessionSpecificRoot(const sp<IBinder>& sessionSpecificRoot) {
+ LOG_ALWAYS_FATAL_IF(mSessionSpecificRootObject != nullptr,
+ "Session specific root object already set");
+ LOG_ALWAYS_FATAL_IF(mForServer != nullptr,
+ "Session specific root object cannot be set for a server");
+ mSessionSpecificRootObject = sessionSpecificRoot;
+}
+
sp<RpcSession::RpcConnection> RpcSession::assignIncomingConnectionToThisThread(
std::unique_ptr<RpcTransport> rpcTransport) {
RpcMutexLockGuard _l(mMutex);
diff --git a/libs/binder/aidl/android/os/IAccessor.aidl b/libs/binder/aidl/android/os/IAccessor.aidl
new file mode 100644
index 0000000..a3134a3
--- /dev/null
+++ b/libs/binder/aidl/android/os/IAccessor.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Interface for accessing the RPC server of a service.
+ *
+ * @hide
+ */
+interface IAccessor {
+ /**
+ * Adds a connection to the RPC server of the service managed by the IAccessor.
+ *
+ * This method can be called multiple times to establish multiple distinct
+ * connections to the same RPC server.
+ *
+ * @return A file descriptor connected to the RPC session of the service managed
+ * by IAccessor.
+ */
+ ParcelFileDescriptor addConnection();
+
+ // TODO(b/350941051): Add API for debugging.
+}
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 0fb1615..ac95188 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -18,6 +18,7 @@
import android.os.IClientCallback;
import android.os.IServiceCallback;
+import android.os.Service;
import android.os.ServiceDebugInfo;
import android.os.ConnectionInfo;
@@ -61,7 +62,7 @@
* Returns null if the service does not exist.
*/
@UnsupportedAppUsage
- @nullable IBinder getService(@utf8InCpp String name);
+ Service getService(@utf8InCpp String name);
/**
* Retrieve an existing service called @a name from the service
@@ -69,7 +70,7 @@
* exist.
*/
@UnsupportedAppUsage
- @nullable IBinder checkService(@utf8InCpp String name);
+ Service checkService(@utf8InCpp String name);
/**
* Place a new @a service called @a name into the service
diff --git a/libs/binder/aidl/android/os/Service.aidl b/libs/binder/aidl/android/os/Service.aidl
new file mode 100644
index 0000000..4c52109
--- /dev/null
+++ b/libs/binder/aidl/android/os/Service.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/**
+ * Service is a union of different service types that can be returned
+ * by the internal {@link ServiceManager#getService(name)} API.
+ *
+ * @hide
+ */
+union Service {
+ @nullable IBinder binder;
+ @nullable IBinder accessor;
+}
\ No newline at end of file
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index 40102bb..af37bf2 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -220,6 +220,12 @@
// internal only
LIBBINDER_EXPORTED const std::unique_ptr<RpcState>& state() { return mRpcBinderState; }
+ /**
+ * Sets the session-specific root object. This is the object that will be used to attach
+ * the IAccessor binder to the RpcSession when a binder is set up via accessor.
+ */
+ LIBBINDER_EXPORTED void setSessionSpecificRoot(const sp<IBinder>& sessionSpecificRoot);
+
private:
friend sp<RpcSession>;
friend RpcServer;
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 18b178b..201dfbc 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -118,13 +118,11 @@
class ServiceManagerProxyToNative : public android::os::BnServiceManager {
public:
ServiceManagerProxyToNative(const sp<android::os::IServiceManager>& impl) : mImpl(impl) {}
- android::binder::Status getService(const std::string&,
- android::sp<android::IBinder>*) override {
+ android::binder::Status getService(const std::string&, android::os::Service*) override {
// We can't send BpBinder for regular binder over RPC.
return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
}
- android::binder::Status checkService(const std::string&,
- android::sp<android::IBinder>*) override {
+ android::binder::Status checkService(const std::string&, android::os::Service*) override {
// We can't send BpBinder for regular binder over RPC.
return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
}
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index f4cf11e..a9bd11e 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <set>
+#include <utility>
#include <android-base/file.h>
#include <android-base/parseint.h>
@@ -115,7 +116,7 @@
/* list of extra hal interfaces to dump containing process during native dumps */
// This is filled when dumpstate is called.
-static std::set<const std::string> extra_hal_interfaces_to_dump;
+static std::set<std::string> extra_hal_interfaces_to_dump;
static void read_extra_hals_to_dump_from_property() {
// extra hals to dump are already filled
@@ -129,7 +130,7 @@
if (trimmed_token.length() == 0) {
continue;
}
- extra_hal_interfaces_to_dump.insert(trimmed_token);
+ extra_hal_interfaces_to_dump.insert(std::move(trimmed_token));
}
}
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 6fcb3a4..d05ff34 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -326,7 +326,7 @@
* COMPOSER_OVERLAY, the system will try to prioritize the buffer receiving
* an overlay plane & avoid caching it in intermediate composition buffers.
*/
- AHARDWAREBUFFER_USAGE_FRONT_BUFFER = 1UL << 32,
+ AHARDWAREBUFFER_USAGE_FRONT_BUFFER = 1ULL << 32,
AHARDWAREBUFFER_USAGE_VENDOR_0 = 1ULL << 28,
AHARDWAREBUFFER_USAGE_VENDOR_1 = 1ULL << 29,
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index abe0d9b..7b3b176 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -718,8 +718,7 @@
const auto externalTexture =
std::make_shared<impl::ExternalTexture>(externalBuffer, *renderengine,
impl::ExternalTexture::Usage::READABLE);
- std::vector<const std::shared_ptr<ExternalTexture>> textures =
- {srcTexture, externalTexture};
+ std::vector<std::shared_ptr<ExternalTexture>> textures = {srcTexture, externalTexture};
// Another external texture with a different pixel format triggers useIsOpaqueWorkaround.
// It doesn't have to be f16, but it can't be the usual 8888.
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index c91ba38..2fd1763 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2624,6 +2624,9 @@
if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
continue;
}
+ if (!touchedWindow.hasTouchingPointers(entry.deviceId)) {
+ continue;
+ }
touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
}
}
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 168e74c..dc13fed 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -1340,6 +1340,13 @@
WithFlags(expectedFlags)));
}
+ inline void consumeMotionPointerDown(int32_t pointerIdx,
+ const ::testing::Matcher<MotionEvent>& matcher) {
+ const int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN |
+ (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+ consumeMotionEvent(testing::AllOf(WithMotionAction(action), matcher));
+ }
+
void consumeMotionPointerUp(int32_t pointerIdx, int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
int32_t expectedFlags = 0) {
const int32_t action = AMOTION_EVENT_ACTION_POINTER_UP |
@@ -1348,6 +1355,13 @@
WithFlags(expectedFlags)));
}
+ inline void consumeMotionPointerUp(int32_t pointerIdx,
+ const ::testing::Matcher<MotionEvent>& matcher) {
+ const int32_t action = AMOTION_EVENT_ACTION_POINTER_UP |
+ (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+ consumeMotionEvent(testing::AllOf(WithMotionAction(action), matcher));
+ }
+
void consumeMotionUp(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
int32_t expectedFlags = 0) {
consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDisplayId(expectedDisplayId),
@@ -4771,6 +4785,72 @@
rightWindow->assertNoEvents();
}
+/**
+ * Two windows: left and right. The left window has PREVENT_SPLITTING input config. Device A sends a
+ * down event to the right window. Device B sends a down event to the left window, and then a
+ * POINTER_DOWN event to the right window. However, since the left window prevents splitting, the
+ * POINTER_DOWN event should only go to the left window, and not to the right window.
+ * This test attempts to reproduce a crash.
+ */
+TEST_F(InputDispatcherTest, MultiDeviceTwoWindowsPreventSplitting) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> leftWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Left window (prevent splitting)",
+ ADISPLAY_ID_DEFAULT);
+ leftWindow->setFrame(Rect(0, 0, 100, 100));
+ leftWindow->setPreventSplitting(true);
+
+ sp<FakeWindowHandle> rightWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Right window",
+ ADISPLAY_ID_DEFAULT);
+ rightWindow->setFrame(Rect(100, 0, 200, 100));
+
+ mDispatcher->onWindowInfosChanged(
+ {{*leftWindow->getInfo(), *rightWindow->getInfo()}, {}, 0, 0});
+
+ const DeviceId deviceA = 9;
+ const DeviceId deviceB = 3;
+ // Touch the right window with device A
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
+ .deviceId(deviceA)
+ .build());
+ rightWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceA)));
+ // Touch the left window with device B
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .deviceId(deviceB)
+ .build());
+ leftWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceB)));
+ // Send a second pointer from device B to the right window. It shouldn't go to the right window
+ // because the left window prevents splitting.
+ mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .deviceId(deviceB)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120))
+ .build());
+ leftWindow->consumeMotionPointerDown(1, WithDeviceId(deviceB));
+
+ // Finish the gesture for both devices
+ mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .deviceId(deviceB)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120))
+ .build());
+ leftWindow->consumeMotionPointerUp(1, WithDeviceId(deviceB));
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .deviceId(deviceB)
+ .build());
+ leftWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceB), WithPointerId(0, 0)));
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
+ .deviceId(deviceA)
+ .build());
+ rightWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceA)));
+}
+
TEST_F(InputDispatcherTest, TouchpadThreeFingerSwipeOnlySentToTrustedOverlays) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h
index a3e8eaf..76170eb 100644
--- a/services/inputflinger/tests/TestEventMatchers.h
+++ b/services/inputflinger/tests/TestEventMatchers.h
@@ -609,10 +609,33 @@
return arg.getRepeatCount() == repeatCount;
}
-MATCHER_P2(WithPointerId, index, id, "MotionEvent with specified pointer ID for pointer index") {
- const auto argPointerId = arg.pointerProperties[index].id;
- *result_listener << "expected pointer with index " << index << " to have ID " << argPointerId;
- return argPointerId == id;
+class WithPointerIdMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithPointerIdMatcher(size_t index, int32_t pointerId)
+ : mIndex(index), mPointerId(pointerId) {}
+
+ bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+ return args.pointerProperties[mIndex].id == mPointerId;
+ }
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
+ return event.getPointerId(mIndex) == mPointerId;
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "with pointer[" << mIndex << "] id = " << mPointerId;
+ }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointerId"; }
+
+private:
+ const size_t mIndex;
+ const int32_t mPointerId;
+};
+
+inline WithPointerIdMatcher WithPointerId(size_t index, int32_t pointerId) {
+ return WithPointerIdMatcher(index, pointerId);
}
MATCHER_P2(WithCursorPosition, x, y, "InputEvent with specified cursor position") {
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
index 6be6735..9c0e072 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
@@ -92,15 +92,15 @@
}
private:
- std::vector<const LayerState> copyLayers(const std::vector<const LayerState*>& layers) {
- std::vector<const LayerState> copiedLayers;
+ std::vector<LayerState> copyLayers(const std::vector<const LayerState*>& layers) {
+ std::vector<LayerState> copiedLayers;
copiedLayers.reserve(layers.size());
std::transform(layers.cbegin(), layers.cend(), std::back_inserter(copiedLayers),
[](const LayerState* layerState) { return *layerState; });
return copiedLayers;
}
- std::vector<const LayerState> mLayers;
+ std::vector<LayerState> mLayers;
// TODO(b/180976743): Tune kMaxDifferingFields
constexpr static int kMaxDifferingFields = 6;