Merge "Use unique names for InputSurface in e2eNativeInputTest" into main
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index fa7cb64..38a125b 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -396,7 +396,7 @@
SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
- *outBinder = tryGetBinder(name, true);
+ *outBinder = tryGetBinder(name, true).service;
// returns ok regardless of result for legacy reasons
return Status::ok();
}
@@ -430,13 +430,15 @@
return os::Service::make<os::Service::Tag::accessor>(nullptr);
}
return os::Service::make<os::Service::Tag::accessor>(
- tryGetBinder(*accessorName, startIfNotFound));
+ tryGetBinder(*accessorName, startIfNotFound).service);
} else {
- return os::Service::make<os::Service::Tag::binder>(tryGetBinder(name, startIfNotFound));
+ return os::Service::make<os::Service::Tag::serviceWithMetadata>(
+ tryGetBinder(name, startIfNotFound));
}
}
-sp<IBinder> ServiceManager::tryGetBinder(const std::string& name, bool startIfNotFound) {
+os::ServiceWithMetadata ServiceManager::tryGetBinder(const std::string& name,
+ bool startIfNotFound) {
SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
@@ -450,13 +452,13 @@
if (!service->allowIsolated && is_multiuser_uid_isolated(ctx.uid)) {
LOG(WARNING) << "Isolated app with UID " << ctx.uid << " requested '" << name
<< "', but the service is not allowed for isolated apps.";
- return nullptr;
+ return os::ServiceWithMetadata();
}
out = service->binder;
}
if (!mAccess->canFind(ctx, name)) {
- return nullptr;
+ return os::ServiceWithMetadata();
}
if (!out && startIfNotFound) {
@@ -473,8 +475,11 @@
CHECK(handleServiceClientCallback(2 /* sm + transaction */, name, false));
service->guaranteeClient = true;
}
-
- return out;
+ os::ServiceWithMetadata serviceWithMetadata = os::ServiceWithMetadata();
+ serviceWithMetadata.service = out;
+ serviceWithMetadata.isLazyService =
+ service ? service->dumpPriority & FLAG_IS_LAZY_SERVICE : false;
+ return serviceWithMetadata;
}
bool isValidServiceName(const std::string& name) {
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index c92141b..964abee 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -114,7 +114,7 @@
void removeClientCallback(const wp<IBinder>& who, ClientCallbackMap::iterator* it);
os::Service tryGetService(const std::string& name, bool startIfNotFound);
- sp<IBinder> tryGetBinder(const std::string& name, bool startIfNotFound);
+ os::ServiceWithMetadata tryGetBinder(const std::string& name, bool startIfNotFound);
binder::Status canAddService(const Access::CallingContext& ctx, const std::string& name,
std::optional<std::string>* accessor);
binder::Status canFindService(const Access::CallingContext& ctx, const std::string& name,
diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp
index 95f459f..e620770 100644
--- a/cmds/servicemanager/test_sm.cpp
+++ b/cmds/servicemanager/test_sm.cpp
@@ -92,6 +92,11 @@
auto sm = getPermissiveServiceManager();
EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
+
+ EXPECT_TRUE(sm->addService("lazyfoo", getBinder(), false /*allowIsolated*/,
+ IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT |
+ IServiceManager::FLAG_IS_LAZY_SERVICE)
+ .isOk());
}
TEST(AddService, EmptyNameDisallowed) {
@@ -156,7 +161,7 @@
Service outA;
EXPECT_TRUE(sm->getService2("foo", &outA).isOk());
- EXPECT_EQ(serviceA, outA.get<Service::Tag::binder>());
+ EXPECT_EQ(serviceA, outA.get<Service::Tag::serviceWithMetadata>().service);
sp<IBinder> outBinderA;
EXPECT_TRUE(sm->getService("foo", &outBinderA).isOk());
EXPECT_EQ(serviceA, outBinderA);
@@ -168,7 +173,7 @@
Service outB;
EXPECT_TRUE(sm->getService2("foo", &outB).isOk());
- EXPECT_EQ(serviceB, outB.get<Service::Tag::binder>());
+ EXPECT_EQ(serviceB, outB.get<Service::Tag::serviceWithMetadata>().service);
sp<IBinder> outBinderB;
EXPECT_TRUE(sm->getService("foo", &outBinderB).isOk());
EXPECT_EQ(serviceB, outBinderB);
@@ -195,7 +200,7 @@
Service out;
EXPECT_TRUE(sm->getService2("foo", &out).isOk());
- EXPECT_EQ(service, out.get<Service::Tag::binder>());
+ EXPECT_EQ(service, out.get<Service::Tag::serviceWithMetadata>().service);
sp<IBinder> outBinder;
EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
EXPECT_EQ(service, outBinder);
@@ -206,7 +211,7 @@
Service out;
EXPECT_TRUE(sm->getService2("foo", &out).isOk());
- EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
+ EXPECT_EQ(nullptr, out.get<Service::Tag::serviceWithMetadata>().service);
sp<IBinder> outBinder;
EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
EXPECT_EQ(nullptr, outBinder);
@@ -227,7 +232,7 @@
Service out;
// returns nullptr but has OK status for legacy compatibility
EXPECT_TRUE(sm->getService2("foo", &out).isOk());
- EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
+ EXPECT_EQ(nullptr, out.get<Service::Tag::serviceWithMetadata>().service);
sp<IBinder> outBinder;
EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
EXPECT_EQ(nullptr, outBinder);
@@ -257,7 +262,7 @@
Service out;
EXPECT_TRUE(sm->getService2("foo", &out).isOk());
- EXPECT_EQ(service, out.get<Service::Tag::binder>());
+ EXPECT_EQ(service, out.get<Service::Tag::serviceWithMetadata>().service);
sp<IBinder> outBinder;
EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
EXPECT_EQ(service, outBinder);
@@ -289,7 +294,7 @@
Service out;
// returns nullptr but has OK status for legacy compatibility
EXPECT_TRUE(sm->getService2("foo", &out).isOk());
- EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
+ EXPECT_EQ(nullptr, out.get<Service::Tag::serviceWithMetadata>().service);
sp<IBinder> outBinder;
EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
EXPECT_EQ(nullptr, outBinder);
diff --git a/include/android/performance_hint.h b/include/android/performance_hint.h
index ca86c27..2b4a5f5 100644
--- a/include/android/performance_hint.h
+++ b/include/android/performance_hint.h
@@ -359,6 +359,31 @@
bool cpu, bool gpu, const char* _Nonnull debugName) __INTRODUCED_IN(36);
/**
+ * Informs the framework of an upcoming one-off expensive frame for a graphics pipeline
+ * bound to this session. This frame will be treated as not representative of the workload as a
+ * whole, and it will be discarded the purposes of load tracking. The user can specify
+ * whether the workload spike is expected to be on the CPU, GPU, or both.
+ *
+ * Sending hints for both CPU and GPU counts as two separate hints for the purposes of the
+ * rate limiter.
+ *
+ * @param cpu Indicates if the workload spike is expected to affect the CPU.
+ * @param gpu Indicates if the workload spike is expected to affect the GPU.
+ * @param debugName A required string used to identify this specific hint during
+ * tracing. This debug string will only be held for the duration of the
+ * method, and can be safely discarded after.
+ *
+ * @return 0 on success.
+ * EINVAL if no hints were requested.
+ * EBUSY if the hint was rate limited.
+ * EPIPE if communication with the system service has failed.
+ * ENOTSUP if the hint is not supported.
+ */
+int APerformanceHint_notifyWorkloadSpike(
+ APerformanceHintSession* _Nonnull session,
+ bool cpu, bool gpu, const char* _Nonnull debugName) __INTRODUCED_IN(36);
+
+/**
* Associates a session with any {@link ASurfaceControl} or {@link ANativeWindow}
* instances managed by this session.
*
diff --git a/include/input/DisplayTopologyGraph.h b/include/input/DisplayTopologyGraph.h
new file mode 100644
index 0000000..90427bd
--- /dev/null
+++ b/include/input/DisplayTopologyGraph.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 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.
+ */
+
+#pragma once
+
+#include <ftl/enum.h>
+#include <ui/LogicalDisplayId.h>
+
+#include <cinttypes>
+#include <unordered_map>
+#include <vector>
+
+namespace android {
+
+/**
+ * The edge of the current display, where adjacent display is attached to.
+ */
+enum class DisplayTopologyPosition : int32_t {
+ LEFT = 0,
+ TOP = 1,
+ RIGHT = 2,
+ BOTTOM = 3,
+
+ ftl_last = BOTTOM
+};
+
+/**
+ * Directed edge in the graph of adjacent displays.
+ */
+struct DisplayTopologyAdjacentDisplay {
+ ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID;
+ DisplayTopologyPosition position;
+ float offsetPx;
+};
+
+/**
+ * Directed Graph representation of Display Topology.
+ */
+struct DisplayTopologyGraph {
+ ui::LogicalDisplayId primaryDisplayId = ui::LogicalDisplayId::INVALID;
+ std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>> graph;
+};
+
+} // namespace android
diff --git a/include/private/performance_hint_private.h b/include/private/performance_hint_private.h
index f150fb1..e3f98ba 100644
--- a/include/private/performance_hint_private.h
+++ b/include/private/performance_hint_private.h
@@ -74,6 +74,20 @@
* baseline to prepare for an arbitrary load, and must wake up if inactive.
*/
GPU_LOAD_RESET = 7,
+
+ /**
+ * This hint indicates an upcoming CPU workload that is abnormally large and
+ * not representative of the workload. This should be used for rare, one-time
+ * operations and should be ignored by any load tracking or session hysteresis.
+ */
+ CPU_LOAD_SPIKE = 8,
+
+ /**
+ * This hint indicates an upcoming GPU workload that is abnormally large and
+ * not representative of the workload. This should be used for rare, one-time
+ * operations and should be ignored by any load tracking or session hysteresis.
+ */
+ GPU_LOAD_SPIKE = 9,
};
// Allows access to PowerHAL's SessionTags without needing to import its AIDL
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index e10e4dd..aac369d 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -456,6 +456,28 @@
}
soong_config_module_type {
+ name: "libbinder_remove_cache_static_list_config",
+ module_type: "cc_defaults",
+ config_namespace: "libbinder",
+ bool_variables: ["release_libbinder_remove_cache_static_list"],
+ properties: [
+ "cflags",
+ ],
+}
+
+libbinder_remove_cache_static_list_config {
+ name: "libbinder_remove_cache_static_list_flag",
+ soong_config_variables: {
+ release_libbinder_remove_cache_static_list: {
+ cflags: ["-DLIBBINDER_REMOVE_CACHE_STATIC_LIST"],
+ conditions_default: {
+ cflags: ["-DNO_LIBBINDER_REMOVE_CACHE_STATIC_LIST"],
+ },
+ },
+ },
+}
+
+soong_config_module_type {
name: "libbinder_client_cache_config",
module_type: "cc_defaults",
config_namespace: "libbinder",
@@ -504,6 +526,7 @@
defaults: [
"libbinder_client_cache_flag",
"libbinder_addservice_cache_flag",
+ "libbinder_remove_cache_static_list_flag",
],
srcs: [
"BufferedTextOutput.cpp",
@@ -826,6 +849,7 @@
"aidl/android/os/IServiceCallback.aidl",
"aidl/android/os/IServiceManager.aidl",
"aidl/android/os/Service.aidl",
+ "aidl/android/os/ServiceWithMetadata.aidl",
"aidl/android/os/ServiceDebugInfo.aidl",
],
path: "aidl",
diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp
index 123dfd2..03d687a 100644
--- a/libs/binder/BackendUnifiedServiceManager.cpp
+++ b/libs/binder/BackendUnifiedServiceManager.cpp
@@ -16,6 +16,7 @@
#include "BackendUnifiedServiceManager.h"
#include <android/os/IAccessor.h>
+#include <android/os/IServiceManager.h>
#include <binder/RpcSession.h>
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
@@ -36,6 +37,12 @@
constexpr bool kUseCacheInAddService = false;
#endif
+#ifdef LIBBINDER_REMOVE_CACHE_STATIC_LIST
+constexpr bool kRemoveStaticList = true;
+#else
+constexpr bool kRemoveStaticList = false;
+#endif
+
using AidlServiceManager = android::os::IServiceManager;
using android::os::IAccessor;
using binder::Status;
@@ -110,6 +117,13 @@
// go/keep-sorted end
};
+os::ServiceWithMetadata createServiceWithMetadata(const sp<IBinder>& service, bool isLazyService) {
+ os::ServiceWithMetadata out = os::ServiceWithMetadata();
+ out.service = service;
+ out.isLazyService = isLazyService;
+ return out;
+}
+
bool BinderCacheWithInvalidation::isClientSideCachingEnabled(const std::string& serviceName) {
sp<ProcessState> self = ProcessState::selfOrNull();
if (!self || self->getThreadPoolMaxTotalThreadCount() <= 0) {
@@ -132,15 +146,21 @@
return Status::ok();
}
- if (service.getTag() == os::Service::Tag::binder) {
- return updateCache(serviceName, service.get<os::Service::Tag::binder>());
+ if (service.getTag() == os::Service::Tag::serviceWithMetadata) {
+ auto serviceWithMetadata = service.get<os::Service::Tag::serviceWithMetadata>();
+ return updateCache(serviceName, serviceWithMetadata.service,
+ serviceWithMetadata.isLazyService);
}
return Status::ok();
}
Status BackendUnifiedServiceManager::updateCache(const std::string& serviceName,
- const sp<IBinder>& binder) {
+ const sp<IBinder>& binder, bool isServiceLazy) {
std::string traceStr;
+ // Don't cache if service is lazy
+ if (kRemoveStaticList && isServiceLazy) {
+ return Status::ok();
+ }
if (atrace_is_tag_enabled(ATRACE_TAG_AIDL)) {
traceStr = "BinderCacheWithInvalidation::updateCache : " + serviceName;
}
@@ -153,7 +173,9 @@
binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
"BinderCacheWithInvalidation::updateCache failed: "
"isBinderAlive_false");
- } else if (mCacheForGetService->isClientSideCachingEnabled(serviceName)) {
+ }
+ // If we reach here with kRemoveStaticList=true then we know service isn't lazy
+ else if (kRemoveStaticList || mCacheForGetService->isClientSideCachingEnabled(serviceName)) {
binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
"BinderCacheWithInvalidation::updateCache successful");
return mCacheForGetService->setItem(serviceName, binder);
@@ -173,7 +195,7 @@
sp<IBinder> item = mCacheForGetService->getItem(serviceName);
// TODO(b/363177618): Enable caching for binders which are always null.
if (item != nullptr && item->isBinderAlive()) {
- *_out = os::Service::make<os::Service::Tag::binder>(item);
+ *_out = createServiceWithMetadata(item, false);
return true;
}
return false;
@@ -188,7 +210,7 @@
sp<IBinder>* _aidl_return) {
os::Service service;
Status status = getService2(name, &service);
- *_aidl_return = service.get<os::Service::Tag::binder>();
+ *_aidl_return = service.get<os::Service::Tag::serviceWithMetadata>().service;
return status;
}
@@ -227,14 +249,16 @@
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) {
+ case os::Service::Tag::serviceWithMetadata: {
+ auto serviceWithMetadata = in.get<os::Service::Tag::serviceWithMetadata>();
+ if (serviceWithMetadata.service == nullptr) {
// failed to find a service. Check to see if we have any local
// injected Accessors for this service.
os::Service accessor;
Status status = getInjectedAccessor(name, &accessor);
if (!status.isOk()) {
- *_out = os::Service::make<os::Service::Tag::binder>(nullptr);
+ *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(
+ createServiceWithMetadata(nullptr, false));
return status;
}
if (accessor.getTag() == os::Service::Tag::accessor &&
@@ -255,7 +279,8 @@
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);
+ *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(
+ createServiceWithMetadata(nullptr, false));
return Status::ok();
}
auto request = [=] {
@@ -276,7 +301,8 @@
return Status::fromStatusT(status);
}
session->setSessionSpecificRoot(accessorBinder);
- *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject());
+ *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(
+ createServiceWithMetadata(session->getRootObject(), false));
return Status::ok();
}
default: {
@@ -291,7 +317,8 @@
Status status = mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);
// mEnableAddServiceCache is true by default.
if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) {
- return updateCache(name, service);
+ return updateCache(name, service,
+ dumpPriority & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE);
}
return status;
}
diff --git a/libs/binder/BackendUnifiedServiceManager.h b/libs/binder/BackendUnifiedServiceManager.h
index b46bf19..6a0d06a 100644
--- a/libs/binder/BackendUnifiedServiceManager.h
+++ b/libs/binder/BackendUnifiedServiceManager.h
@@ -159,7 +159,8 @@
binder::Status toBinderService(const ::std::string& name, const os::Service& in,
os::Service* _out);
binder::Status updateCache(const std::string& serviceName, const os::Service& service);
- binder::Status updateCache(const std::string& serviceName, const sp<IBinder>& binder);
+ binder::Status updateCache(const std::string& serviceName, const sp<IBinder>& binder,
+ bool isLazyService);
bool returnIfCached(const std::string& serviceName, os::Service* _out);
};
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 61866d7..53435c3 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -152,7 +152,8 @@
virtual Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
Service service;
Status status = mUnifiedServiceManager->getService2(name, &service);
- *_aidl_return = service.get<Service::Tag::binder>();
+ auto serviceWithMetadata = service.get<Service::Tag::serviceWithMetadata>();
+ *_aidl_return = serviceWithMetadata.service;
return status;
}
};
@@ -607,7 +608,7 @@
if (!mUnifiedServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
return nullptr;
}
- return ret.get<Service::Tag::binder>();
+ return ret.get<Service::Tag::serviceWithMetadata>().service;
}
status_t CppBackendShim::addService(const String16& name, const sp<IBinder>& service,
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index 0f0af0b..27cfe0c 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -19,7 +19,6 @@
#include <android/os/BnClientCallback.h>
#include <android/os/IServiceManager.h>
#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
#include <binder/LazyServiceRegistrar.h>
namespace android {
@@ -134,6 +133,12 @@
std::string regStr = (reRegister) ? "Re-registering" : "Registering";
ALOGI("%s service %s", regStr.c_str(), name.c_str());
+ if (dumpFlags & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE) {
+ ALOGW("FLAG_IS_LAZY_SERVICE flag already set. This should only be set by "
+ "ClientCounterCallbackImpl in LazyServiceRegistrar");
+ }
+ dumpFlags |= android::os::IServiceManager::FLAG_IS_LAZY_SERVICE;
+
if (Status status = manager->addService(name.c_str(), service, allowIsolated, dumpFlags);
!status.isOk()) {
ALOGE("Failed to register service %s (%s)", name.c_str(), status.toString8().c_str());
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 1d1f84f..69edef8 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -49,6 +49,8 @@
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
| DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PRIORITY_DEFAULT;
+ const int FLAG_IS_LAZY_SERVICE = 1 << 30;
+
/* Allows services to dump sections in protobuf format. */
const int DUMP_FLAG_PROTO = 1 << 4;
@@ -61,7 +63,8 @@
*
* Returns null if the service does not exist.
*
- * @deprecated TODO(b/355394904): Use getService2 instead.
+ * @deprecated TODO(b/355394904): Use getService2 instead. This does not return metadata
+ * that is included in ServiceWithMetadata
*/
@UnsupportedAppUsage
@nullable IBinder getService(@utf8InCpp String name);
diff --git a/libs/binder/aidl/android/os/Service.aidl b/libs/binder/aidl/android/os/Service.aidl
index 4c52109..3bc6588 100644
--- a/libs/binder/aidl/android/os/Service.aidl
+++ b/libs/binder/aidl/android/os/Service.aidl
@@ -16,6 +16,8 @@
package android.os;
+import android.os.ServiceWithMetadata;
+
/**
* Service is a union of different service types that can be returned
* by the internal {@link ServiceManager#getService(name)} API.
@@ -23,6 +25,6 @@
* @hide
*/
union Service {
- @nullable IBinder binder;
+ ServiceWithMetadata serviceWithMetadata;
@nullable IBinder accessor;
}
\ No newline at end of file
diff --git a/libs/binder/aidl/android/os/ServiceWithMetadata.aidl b/libs/binder/aidl/android/os/ServiceWithMetadata.aidl
new file mode 100644
index 0000000..96f76ff
--- /dev/null
+++ b/libs/binder/aidl/android/os/ServiceWithMetadata.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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 binder with metadata.
+ * @hide
+ */
+parcelable ServiceWithMetadata {
+ /**
+ * IBinder to service
+ */
+ @nullable IBinder service;
+ /**
+ * boolean if the IBinder can be cached by client.
+ */
+ boolean isLazyService;
+}
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index cc4943b..f5df8d5 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -34,6 +34,7 @@
ADD_SERVICE_DUMP_FLAG_PRIORITY_HIGH = 1 << 2,
ADD_SERVICE_DUMP_FLAG_PRIORITY_NORMAL = 1 << 3,
ADD_SERVICE_DUMP_FLAG_PRIORITY_DEFAULT = 1 << 4,
+ // All other bits are reserved for internal usage
};
/**
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 642fbf3..c21d7c6 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -73,6 +73,7 @@
defaults: [
"libbinder_client_cache_flag",
"libbinder_addservice_cache_flag",
+ "libbinder_remove_cache_static_list_flag",
],
test_suites: ["general-tests"],
require_root: true,
diff --git a/libs/binder/tests/binderCacheUnitTest.cpp b/libs/binder/tests/binderCacheUnitTest.cpp
index 3195c55..19395c2 100644
--- a/libs/binder/tests/binderCacheUnitTest.cpp
+++ b/libs/binder/tests/binderCacheUnitTest.cpp
@@ -40,6 +40,12 @@
constexpr bool kUseCacheInAddService = false;
#endif
+#ifdef LIBBINDER_REMOVE_CACHE_STATIC_LIST
+constexpr bool kRemoveStaticList = true;
+#else
+constexpr bool kRemoveStaticList = false;
+#endif
+
// A service name which is in the static list of cachable services
const String16 kCachedServiceName = String16("isub");
@@ -69,8 +75,10 @@
MockAidlServiceManager() : innerSm() {}
binder::Status checkService(const ::std::string& name, os::Service* _out) override {
- sp<IBinder> binder = innerSm.getService(String16(name.c_str()));
- *_out = os::Service::make<os::Service::Tag::binder>(binder);
+ os::ServiceWithMetadata serviceWithMetadata = os::ServiceWithMetadata();
+ serviceWithMetadata.service = innerSm.getService(String16(name.c_str()));
+ serviceWithMetadata.isLazyService = false;
+ *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(serviceWithMetadata);
return binder::Status::ok();
}
@@ -85,6 +93,75 @@
FakeServiceManager innerSm;
};
+// Returns services with isLazyService flag as true.
+class MockAidlServiceManager2 : public os::IServiceManagerDefault {
+public:
+ MockAidlServiceManager2() : innerSm() {}
+
+ binder::Status checkService(const ::std::string& name, os::Service* _out) override {
+ os::ServiceWithMetadata serviceWithMetadata = os::ServiceWithMetadata();
+ serviceWithMetadata.service = innerSm.getService(String16(name.c_str()));
+ serviceWithMetadata.isLazyService = true;
+ *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(serviceWithMetadata);
+ return binder::Status::ok();
+ }
+
+ binder::Status addService(const std::string& name, const sp<IBinder>& service,
+ bool allowIsolated, int32_t dumpPriority) override {
+ return binder::Status::fromStatusT(
+ innerSm.addService(String16(name.c_str()), service, allowIsolated, dumpPriority));
+ }
+
+ void clearServices() { innerSm.clear(); }
+
+ FakeServiceManager innerSm;
+};
+
+class LibbinderCacheRemoveStaticList : public ::testing::Test {
+protected:
+ void SetUp() override {
+ fakeServiceManager = sp<MockAidlServiceManager2>::make();
+ mServiceManager = getServiceManagerShimFromAidlServiceManagerForTests(fakeServiceManager);
+ mServiceManager->enableAddServiceCache(true);
+ }
+ void TearDown() override {}
+
+public:
+ void cacheAddServiceAndConfirmCacheMiss(const sp<IBinder>& binder1) {
+ // Add a service. This shouldn't cache it.
+ EXPECT_EQ(OK,
+ mServiceManager->addService(kCachedServiceName, binder1,
+ /*allowIsolated = */ false,
+ android::os::IServiceManager::FLAG_IS_LAZY_SERVICE));
+ // Try to populate cache. Cache shouldn't be updated.
+ EXPECT_EQ(binder1, mServiceManager->checkService(kCachedServiceName));
+ fakeServiceManager->clearServices();
+ EXPECT_EQ(nullptr, mServiceManager->checkService(kCachedServiceName));
+ }
+
+ sp<MockAidlServiceManager2> fakeServiceManager;
+ sp<android::IServiceManager> mServiceManager;
+};
+
+TEST_F(LibbinderCacheRemoveStaticList, AddLocalServiceAndConfirmCacheMiss) {
+ if (!kRemoveStaticList) {
+ GTEST_SKIP() << "Skipping as feature is not enabled";
+ return;
+ }
+ sp<IBinder> binder1 = sp<BBinder>::make();
+ cacheAddServiceAndConfirmCacheMiss(binder1);
+}
+
+TEST_F(LibbinderCacheRemoveStaticList, AddRemoteServiceAndConfirmCacheMiss) {
+ if (!kRemoveStaticList) {
+ GTEST_SKIP() << "Skipping as feature is not enabled";
+ return;
+ }
+ sp<IBinder> binder1 = defaultServiceManager()->checkService(kServerName);
+ ASSERT_NE(binder1, nullptr);
+ cacheAddServiceAndConfirmCacheMiss(binder1);
+}
+
class LibbinderCacheAddServiceTest : public ::testing::Test {
protected:
void SetUp() override {
@@ -231,7 +308,13 @@
EXPECT_EQ(binder2, result);
}
+// TODO(b/333854840): Remove this test removing the static list
TEST_F(LibbinderCacheTest, DoNotCacheServiceNotInList) {
+ if (kRemoveStaticList) {
+ GTEST_SKIP() << "Skipping test as static list is disabled";
+ return;
+ }
+
sp<IBinder> binder1 = sp<BBinder>::make();
sp<IBinder> binder2 = sp<BBinder>::make();
String16 serviceName = String16("NewLibbinderCacheTest");
diff --git a/libs/gui/tests/FrameRateUtilsTest.cpp b/libs/gui/tests/FrameRateUtilsTest.cpp
index 5d3287d..9ffe91f 100644
--- a/libs/gui/tests/FrameRateUtilsTest.cpp
+++ b/libs/gui/tests/FrameRateUtilsTest.cpp
@@ -62,7 +62,7 @@
// Invalid compatibility.
EXPECT_FALSE(
ValidateFrameRate(60.0f, -1, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
- EXPECT_FALSE(ValidateFrameRate(60.0f, 2, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+ EXPECT_FALSE(ValidateFrameRate(60.0f, 3, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
// Invalid change frame rate strategy.
if (flags::bq_setframerate()) {
diff --git a/services/surfaceflinger/common/Android.bp b/services/surfaceflinger/common/Android.bp
index f9c99bf..8786f6e 100644
--- a/services/surfaceflinger/common/Android.bp
+++ b/services/surfaceflinger/common/Android.bp
@@ -38,6 +38,7 @@
],
static_libs: [
"libsurfaceflingerflags",
+ "aconfig_hardware_flags_c_lib",
"android.os.flags-aconfig-cc",
"android.server.display.flags-aconfig-cc",
"libguiflags_no_apex",
@@ -51,6 +52,7 @@
],
static_libs: [
"libsurfaceflingerflags_test",
+ "aconfig_hardware_flags_c_lib",
"android.os.flags-aconfig-cc-test",
"android.server.display.flags-aconfig-cc",
"libguiflags_no_apex",
@@ -67,6 +69,7 @@
static_libs: [
"libsurfaceflinger_common",
"libsurfaceflingerflags",
+ "aconfig_hardware_flags_c_lib",
"android.os.flags-aconfig-cc",
"android.server.display.flags-aconfig-cc",
"libguiflags_no_apex",
@@ -83,6 +86,7 @@
static_libs: [
"libsurfaceflinger_common_test",
"libsurfaceflingerflags_test",
+ "aconfig_hardware_flags_c_lib",
"android.os.flags-aconfig-cc-test",
"android.server.display.flags-aconfig-cc",
"libguiflags_no_apex",
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index e28a0c1..858f759 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -27,6 +27,7 @@
#include <cinttypes>
#include <android_os.h>
+#include <android_hardware_flags.h>
#include <com_android_graphics_libgui_flags.h>
#include <com_android_graphics_surfaceflinger_flags.h>
#include <com_android_server_display_feature_flags.h>
@@ -279,5 +280,6 @@
FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(adpf_use_fmq_channel_fixed, "", android::os)
FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(trace_frame_rate_override, "",
com::android::graphics::libgui::flags);
-
+FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(luts_api, "",
+ android::hardware::flags);
} // namespace android
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
index 1a857c8..05af721 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -102,6 +102,7 @@
bool deprecate_frame_tracker() const;
bool skip_invisible_windows_in_input() const;
bool begone_bright_hlg() const;
+ bool luts_api() const;
protected:
// overridden for unit tests