DO NOT MERGE - Mark RQ3A.210410.001 as merged
Bug: 190855093
Merged-In: I99b4579d11ae816785ad60eaf5cdb40e3382ee0d
Change-Id: I5872c49ec6d5f23b5465876c12d107bf544766eb
diff --git a/Android.bp b/Android.bp
index e0ca9e2..33ba0e9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,6 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "system_libhidl_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
cc_defaults {
name: "libhidl-defaults",
cflags: [
@@ -69,6 +86,7 @@
native_bridge_supported: true,
recovery_available: true,
vendor_available: true,
+ product_available: true,
apex_available: [
// TODO(b/137948090): not fully supported in APEX for certain usecases
// - large dependency sizes
@@ -110,13 +128,18 @@
}
// WARNING: deprecated
-// This library is no longer required, and dependencies should be taken
-// on libhidlbase instead.
+// This library is no longer required, and dependencies should be taken on libhidlbase instead.
+// This is automatically removed by bpfix. Once there are no makefiles, fixes can be automatically applied, and this can be removed.
cc_library {
name: "libhidltransport",
vendor_available: true,
- visibility: [":__subpackages__"],
+ visibility: [
+ ":__subpackages__",
+ "//hardware:__subpackages__",
+ "//test/sts:__subpackages__",
+ "//vendor:__subpackages__",
+ ],
}
cc_defaults {
@@ -160,6 +183,13 @@
"transport/include",
],
+ header_libs: [
+ "libfmq-base",
+ ],
+ export_header_lib_headers: [
+ "libfmq-base",
+ ],
+
generated_sources: [
"android.hidl.manager@1.0_genc++",
"android.hidl.manager@1.1_genc++",
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 01179d5..22c9d36 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -8,6 +8,9 @@
},
{
"name": "hal_implementation_test"
+ },
+ {
+ "name": "hidl_lazy_test"
}
]
}
diff --git a/adapter/Android.bp b/adapter/Android.bp
index 07faa10..83609ff 100644
--- a/adapter/Android.bp
+++ b/adapter/Android.bp
@@ -12,10 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
cc_library {
name: "libhidladapter",
defaults: ["libhidl-defaults"],
vendor_available: true,
+ product_available: true,
// TODO(b/153609531): remove when no longer needed.
native_bridge_supported: true,
srcs: [
@@ -33,4 +43,3 @@
"libutils",
],
}
-
diff --git a/base/HidlInternal.cpp b/base/HidlInternal.cpp
index e38a664..e5c8f70 100644
--- a/base/HidlInternal.cpp
+++ b/base/HidlInternal.cpp
@@ -18,6 +18,9 @@
#include <hidl/HidlInternal.h>
+#ifdef __ANDROID__
+#include <android/api-level.h>
+#endif
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
@@ -50,9 +53,16 @@
LOG(FATAL) << message;
}
-std::string getVndkVersionStr() {
- static std::string vndkVersion = base::GetProperty("ro.vndk.version", "");
- return vndkVersion;
+std::string getVndkSpHwPath(const char* lib) {
+ static std::string vndk_version = base::GetProperty("ro.vndk.version", "");
+#ifdef __ANDROID__
+ static int api_level = android_get_device_api_level();
+ if (api_level >= __ANDROID_API_R__) {
+ return android::base::StringPrintf("/apex/com.android.vndk.v%s/%s/hw/",
+ vndk_version.c_str(), lib);
+ }
+#endif
+ return android::base::StringPrintf("/system/%s/vndk-sp-%s/hw/", lib, vndk_version.c_str());
}
// ----------------------------------------------------------------------
@@ -133,8 +143,7 @@
if (instrumentationLibPath.size() > 0) {
instrumentationLibPaths.push_back(instrumentationLibPath);
} else {
- static std::string halLibPathVndkSp = android::base::StringPrintf(
- HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, getVndkVersionStr().c_str());
+ static std::string halLibPathVndkSp = getVndkSpHwPath();
#ifndef __ANDROID_VNDK__
instrumentationLibPaths.push_back(HAL_LIBRARY_PATH_SYSTEM);
#endif
diff --git a/base/HidlSupport.cpp b/base/HidlSupport.cpp
index af805b9..78faa2f 100644
--- a/base/HidlSupport.cpp
+++ b/base/HidlSupport.cpp
@@ -217,6 +217,14 @@
if (size >= UINT32_MAX) {
LOG(FATAL) << "string size can't exceed 2^32 bytes: " << size;
}
+
+ if (size == 0) {
+ mBuffer = kEmptyString;
+ mSize = 0;
+ mOwnsBuffer = false;
+ return;
+ }
+
char *buf = (char *)malloc(size + 1);
memcpy(buf, data, size);
buf[size] = '\0';
diff --git a/base/include/hidl/HidlInternal.h b/base/include/hidl/HidlInternal.h
index ee87b87..3d1a444 100644
--- a/base/include/hidl/HidlInternal.h
+++ b/base/include/hidl/HidlInternal.h
@@ -44,8 +44,12 @@
//to avoid creating dependencies on liblog.
void logAlwaysFatal(const char *message);
-// Returns vndk version from "ro.vndk.version"
-std::string getVndkVersionStr();
+// Returns VNDK-SP hw path according to "ro.vndk.version"
+#if defined(__LP64__)
+std::string getVndkSpHwPath(const char* lib = "lib64");
+#else
+std::string getVndkSpHwPath(const char* lib = "lib");
+#endif
// Explicitly invokes the parameterized element's destructor;
// intended to be used alongside the placement new operator.
@@ -114,22 +118,18 @@
};
#define HAL_LIBRARY_PATH_SYSTEM_64BIT "/system/lib64/hw/"
-#define HAL_LIBRARY_PATH_VNDK_SP_64BIT_FOR_VERSION "/apex/com.android.vndk.v%s/lib64/hw/"
#define HAL_LIBRARY_PATH_VENDOR_64BIT "/vendor/lib64/hw/"
#define HAL_LIBRARY_PATH_ODM_64BIT "/odm/lib64/hw/"
#define HAL_LIBRARY_PATH_SYSTEM_32BIT "/system/lib/hw/"
-#define HAL_LIBRARY_PATH_VNDK_SP_32BIT_FOR_VERSION "/apex/com.android.vndk.v%s/lib/hw/"
#define HAL_LIBRARY_PATH_VENDOR_32BIT "/vendor/lib/hw/"
#define HAL_LIBRARY_PATH_ODM_32BIT "/odm/lib/hw/"
#if defined(__LP64__)
#define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_64BIT
-#define HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION HAL_LIBRARY_PATH_VNDK_SP_64BIT_FOR_VERSION
#define HAL_LIBRARY_PATH_VENDOR HAL_LIBRARY_PATH_VENDOR_64BIT
#define HAL_LIBRARY_PATH_ODM HAL_LIBRARY_PATH_ODM_64BIT
#else
#define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_32BIT
-#define HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION HAL_LIBRARY_PATH_VNDK_SP_32BIT_FOR_VERSION
#define HAL_LIBRARY_PATH_VENDOR HAL_LIBRARY_PATH_VENDOR_32BIT
#define HAL_LIBRARY_PATH_ODM HAL_LIBRARY_PATH_ODM_32BIT
#endif
@@ -201,7 +201,10 @@
// A list of registered instrumentation callbacks.
std::vector<InstrumentationCallback> mInstrumentationCallbacks;
// Flag whether to enable instrumentation.
- bool mEnableInstrumentation;
+ union {
+ bool mEnableInstrumentation;
+ void* mReserved0;
+ };
// Prefix to lookup the instrumentation libraries.
std::string mInstrumentationLibPackage;
// Used for dlsym to load the profiling method for given interface.
@@ -209,6 +212,12 @@
};
+#ifdef __LP64__
+static_assert(sizeof(HidlInstrumentor) == 88, "HidlInstrumentor size frozen by prebuilts");
+#else
+static_assert(sizeof(HidlInstrumentor) == 44, "HidlInstrumentor size frozen by prebuilts");
+#endif
+
} // namespace details
} // namespace hardware
} // namespace android
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 1b91c26..1bb38e8 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -342,7 +342,6 @@
memset(mPad, 0, sizeof(mPad));
}
- // Note, does not initialize primitive types.
hidl_vec(size_t size) : hidl_vec() { resize(size); }
hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
@@ -412,7 +411,7 @@
}
T *releaseData() {
- if (!mOwnsBuffer && mSize > 0) {
+ if (!mOwnsBuffer && mBuffer != nullptr) {
resize(mSize);
}
mOwnsBuffer = false;
@@ -507,7 +506,7 @@
return mBuffer[index];
}
- // Does not initialize primitive types if new size > old size.
+ // Copies over old elements fitting in new size. Value initializes the rest.
void resize(size_t size) {
if (size > UINT32_MAX) {
details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
@@ -1044,6 +1043,9 @@
*/
template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
struct hidl_enum_range {
+ // Container-like associated type.
+ using value_type = T;
+
constexpr auto begin() const { return std::begin(details::hidl_enum_values<T>); }
constexpr auto cbegin() const { return begin(); }
constexpr auto rbegin() const { return std::rbegin(details::hidl_enum_values<T>); }
diff --git a/base/include/hidl/MQDescriptor.h b/base/include/hidl/MQDescriptor.h
index 0f61cb5..0429444 100644
--- a/base/include/hidl/MQDescriptor.h
+++ b/base/include/hidl/MQDescriptor.h
@@ -20,43 +20,13 @@
#include <unistd.h>
#include <cutils/native_handle.h>
+#include <fmq/MQDescriptorBase.h>
#include <hidl/HidlInternal.h>
#include <hidl/HidlSupport.h>
namespace android {
namespace hardware {
-typedef uint64_t RingBufferPosition;
-
-struct GrantorDescriptor {
- uint32_t flags __attribute__ ((aligned(4)));
- uint32_t fdIndex __attribute__ ((aligned(4)));
- uint32_t offset __attribute__ ((aligned(4)));
- uint64_t extent __attribute__ ((aligned(8)));
-};
-
-static_assert(offsetof(GrantorDescriptor, flags) == 0, "wrong offset");
-static_assert(offsetof(GrantorDescriptor, fdIndex) == 4, "wrong offset");
-static_assert(offsetof(GrantorDescriptor, offset) == 8, "wrong offset");
-static_assert(offsetof(GrantorDescriptor, extent) == 16, "wrong offset");
-static_assert(sizeof(GrantorDescriptor) == 24, "wrong size");
-static_assert(__alignof(GrantorDescriptor) == 8, "wrong alignment");
-
-enum MQFlavor : uint32_t {
- /*
- * kSynchronizedReadWrite represents the wait-free synchronized flavor of the
- * FMQ. It is intended to be have a single reader and single writer.
- * Attempts to overflow/underflow returns a failure.
- */
- kSynchronizedReadWrite = 0x01,
- /*
- * kUnsynchronizedWrite represents the flavor of FMQ where writes always
- * succeed. This flavor allows one writer and many readers. A read operation
- * can detect an overwrite and reset the read counter.
- */
- kUnsynchronizedWrite = 0x02
-};
-
template <typename T, MQFlavor flavor>
struct MQDescriptor {
// Takes ownership of handle
@@ -87,10 +57,6 @@
return mGrantors;
}
- inline ::android::hardware::hidl_vec<GrantorDescriptor> &grantors() {
- return mGrantors;
- }
-
inline const ::native_handle_t *handle() const {
return mHandle;
}
@@ -101,42 +67,7 @@
static const size_t kOffsetOfGrantors;
static const size_t kOffsetOfHandle;
- enum GrantorType : int { READPTRPOS = 0, WRITEPTRPOS, DATAPTRPOS, EVFLAGWORDPOS };
- /*
- * There should at least be GrantorDescriptors for the read counter, write
- * counter and data buffer. A GrantorDescriptor for an EventFlag word is
- * not required if there is no need for blocking FMQ operations.
- */
- static constexpr int32_t kMinGrantorCount = DATAPTRPOS + 1;
-
- /*
- * Minimum number of GrantorDescriptors required if EventFlag support is
- * needed for blocking FMQ operations.
- */
- static constexpr int32_t kMinGrantorCountForEvFlagSupport = EVFLAGWORDPOS + 1;
-
- //TODO(b/34160777) Identify a better solution that supports remoting.
- static inline size_t alignToWordBoundary(size_t length) {
- constexpr size_t kAlignmentSize = 64;
- if (kAlignmentSize % __WORDSIZE != 0) {
- details::logAlwaysFatal("Incompatible word size");
- }
-
- /*
- * Check if alignment to word boundary would cause an overflow.
- */
- if (length > SIZE_MAX - kAlignmentSize/8 + 1) {
- details::logAlwaysFatal("Queue size too large");
- }
-
- return (length + kAlignmentSize/8 - 1) & ~(kAlignmentSize/8 - 1U);
- }
-
- static inline size_t isAlignedToWordBoundary(size_t offset) {
- constexpr size_t kAlignmentSize = 64;
- return (offset & (kAlignmentSize/8 - 1)) == 0;
- }
private:
::android::hardware::hidl_vec<GrantorDescriptor> mGrantors;
::android::hardware::details::hidl_pointer<native_handle_t> mHandle;
@@ -164,38 +95,34 @@
template<typename T>
using MQDescriptorUnsync = MQDescriptor<T, kUnsynchronizedWrite>;
-template<typename T, MQFlavor flavor>
-MQDescriptor<T, flavor>::MQDescriptor(
- const std::vector<GrantorDescriptor>& grantors,
- native_handle_t* nhandle,
- size_t size)
- : mHandle(nhandle),
- mQuantum(size),
- mFlags(flavor) {
+template <typename T, MQFlavor flavor>
+MQDescriptor<T, flavor>::MQDescriptor(const std::vector<GrantorDescriptor>& grantors,
+ native_handle_t* nhandle, size_t size)
+ : mHandle(nhandle), mQuantum(static_cast<uint32_t>(size)), mFlags(flavor) {
mGrantors.resize(grantors.size());
for (size_t i = 0; i < grantors.size(); ++i) {
- if (isAlignedToWordBoundary(grantors[i].offset) == false) {
- details::logAlwaysFatal("Grantor offsets need to be aligned");
- }
mGrantors[i] = grantors[i];
}
}
-template<typename T, MQFlavor flavor>
-MQDescriptor<T, flavor>::MQDescriptor(size_t bufferSize, native_handle_t *nHandle,
- size_t messageSize, bool configureEventFlag)
- : mHandle(nHandle), mQuantum(messageSize), mFlags(flavor) {
+template <typename T, MQFlavor flavor>
+MQDescriptor<T, flavor>::MQDescriptor(size_t bufferSize, native_handle_t* nHandle,
+ size_t messageSize, bool configureEventFlag)
+ : mHandle(nHandle), mQuantum(static_cast<uint32_t>(messageSize)), mFlags(flavor) {
/*
* If configureEventFlag is true, allocate an additional spot in mGrantor
* for containing the fd and offset for mmapping the EventFlag word.
*/
- mGrantors.resize(configureEventFlag? kMinGrantorCountForEvFlagSupport : kMinGrantorCount);
+ mGrantors.resize(configureEventFlag ? details::kMinGrantorCountForEvFlagSupport
+ : details::kMinGrantorCount);
size_t memSize[] = {
- sizeof(RingBufferPosition), /* memory to be allocated for read pointer counter */
- sizeof(RingBufferPosition), /* memory to be allocated for write pointer counter */
- bufferSize, /* memory to be allocated for data buffer */
- sizeof(std::atomic<uint32_t>)/* memory to be allocated for EventFlag word */
+ sizeof(details::RingBufferPosition), /* memory to be allocated for read pointer counter
+ */
+ sizeof(details::RingBufferPosition), /* memory to be allocated for write pointer counter
+ */
+ bufferSize, /* memory to be allocated for data buffer */
+ sizeof(std::atomic<uint32_t>) /* memory to be allocated for EventFlag word */
};
/*
@@ -206,12 +133,9 @@
for (size_t grantorPos = 0, offset = 0;
grantorPos < mGrantors.size();
offset += memSize[grantorPos++]) {
- mGrantors[grantorPos] = {
- 0 /* grantor flags */,
- 0 /* fdIndex */,
- static_cast<uint32_t>(alignToWordBoundary(offset)),
- memSize[grantorPos]
- };
+ mGrantors[grantorPos] = {0 /* grantor flags */, 0 /* fdIndex */,
+ static_cast<uint32_t>(details::alignToWordBoundary(offset)),
+ memSize[grantorPos]};
}
}
@@ -234,9 +158,8 @@
mHandle->data[i] = dup(other.mHandle->data[i]);
}
- memcpy(&mHandle->data[other.mHandle->numFds],
- &other.mHandle->data[other.mHandle->numFds],
- other.mHandle->numInts * sizeof(int));
+ memcpy(&mHandle->data[other.mHandle->numFds], &other.mHandle->data[other.mHandle->numFds],
+ static_cast<size_t>(other.mHandle->numInts) * sizeof(int));
}
return *this;
@@ -258,7 +181,7 @@
template<typename T, MQFlavor flavor>
size_t MQDescriptor<T, flavor>::getSize() const {
- return mGrantors[DATAPTRPOS].extent;
+ return static_cast<size_t>(mGrantors[details::DATAPTRPOS].extent);
}
template<typename T, MQFlavor flavor>
diff --git a/libhidlmemory/Android.bp b/libhidlmemory/Android.bp
index 41da614..fc5770c 100644
--- a/libhidlmemory/Android.bp
+++ b/libhidlmemory/Android.bp
@@ -12,11 +12,28 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
cc_library {
name: "libhidlmemory",
vendor_available: true,
+ product_available: true,
+ // Host support is needed for testing only
+ host_supported: true,
// TODO(b/153609531): remove when no longer needed.
native_bridge_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
vndk: {
enabled: true,
support_system_process: true,
diff --git a/minijail/Android.bp b/minijail/Android.bp
index e025033..ad12dad 100644
--- a/minijail/Android.bp
+++ b/minijail/Android.bp
@@ -1,6 +1,15 @@
// TODO(b/110363419): remove or make failures harder
// Deprecated: most minijail users should either use libavservices_minijail
// or reinstitute this (w/ fatal checks).
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
cc_library_shared {
name: "libhwminijail",
defaults: ["hidl_defaults"],
@@ -13,5 +22,9 @@
"libbase",
"libminijail",
],
- visibility: [":__subpackages__"],
+ visibility: [
+ ":__subpackages__",
+ "//hardware/interfaces/configstore/1.1/default",
+ "//vendor:__subpackages__",
+ ],
}
diff --git a/test_main.cpp b/test_main.cpp
index e4cdd29..5c6c78e 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -17,7 +17,7 @@
#define LOG_TAG "LibHidlTest"
#pragma clang diagnostic push
-#pragma clang diagnostic fatal "-Wpadded"
+#pragma clang diagnostic error "-Wpadded"
#include <hidl/HidlInternal.h>
#include <hidl/HidlSupport.h>
#pragma clang diagnostic pop
@@ -175,6 +175,20 @@
EXPECT_FALSE(hs2 <= hs1);
}
+// empty string optimization should apply for any constructor
+TEST_F(LibHidlTest, HidlStringEmptyLiteralAllocation) {
+ using android::hardware::hidl_string;
+
+ hidl_string empty1;
+ hidl_string empty2("");
+ hidl_string empty3("foo", 0);
+ hidl_string empty4((std::string()));
+
+ EXPECT_EQ(empty1.c_str(), empty2.c_str());
+ EXPECT_EQ(empty1.c_str(), empty3.c_str());
+ EXPECT_EQ(empty1.c_str(), empty4.c_str());
+}
+
TEST_F(LibHidlTest, MemoryTest) {
using android::hardware::hidl_memory;
@@ -222,6 +236,24 @@
EXPECT_ARRAYEQ(v3, array, v3.size());
}
+TEST_F(LibHidlTest, VecReleaseTest) {
+ // this test indicates an inconsistency of behaviors which is undesirable.
+ // Perhaps hidl-vec should always allocate an empty vector whenever it
+ // exposes its data. Alternatively, perhaps it should always free/reject
+ // empty vectors and always return nullptr for this state. While this second
+ // alternative is faster, it makes client code harder to write, and it would
+ // break existing client code.
+ using android::hardware::hidl_vec;
+
+ hidl_vec<int32_t> empty;
+ EXPECT_EQ(nullptr, empty.releaseData());
+
+ empty.resize(0);
+ int32_t* data = empty.releaseData();
+ EXPECT_NE(nullptr, data);
+ delete data;
+}
+
TEST_F(LibHidlTest, VecIterTest) {
int32_t array[] = {5, 6, 7};
android::hardware::hidl_vec<int32_t> hv1 = std::vector<int32_t>(array, array + 3);
diff --git a/transport/Android.bp b/transport/Android.bp
index 86603ee..10f31a7 100644
--- a/transport/Android.bp
+++ b/transport/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_package_root {
name: "android.hidl",
}
diff --git a/transport/HidlLazyUtils.cpp b/transport/HidlLazyUtils.cpp
index 08ed676..be7470f 100644
--- a/transport/HidlLazyUtils.cpp
+++ b/transport/HidlLazyUtils.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "HidlLazyUtils"
+
#include <hidl/HidlLazyUtils.h>
#include <hidl/HidlTransportSupport.h>
@@ -29,15 +31,35 @@
using ::android::hidl::base::V1_0::IBase;
class ClientCounterCallback : public ::android::hidl::manager::V1_2::IClientCallback {
- public:
- ClientCounterCallback() : mNumConnectedServices(0) {}
+ public:
+ ClientCounterCallback() {}
bool addRegisteredService(const sp<IBase>& service, const std::string& name);
- protected:
+ bool tryUnregister();
+
+ void reRegister();
+
+ void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
+
+ protected:
Return<void> onClients(const sp<IBase>& service, bool clients) override;
- private:
+ private:
+ struct Service {
+ sp<IBase> service;
+ std::string name;
+ bool clients = false;
+ // Used to keep track of unregistered services to allow re-registry
+ bool registered = true;
+ };
+
+ /**
+ * Looks up service that is guaranteed to be registered (service from
+ * onClients).
+ */
+ Service& assertRegisteredService(const sp<IBase>& service);
+
/**
* Registers or re-registers services. Returns whether successful.
*/
@@ -50,28 +72,32 @@
void tryShutdown();
/**
- * Counter of the number of services that currently have at least one client.
- */
- size_t mNumConnectedServices;
-
- struct Service {
- sp<IBase> service;
- std::string name;
- };
- /**
* Number of services that have been registered.
*/
std::vector<Service> mRegisteredServices;
+
+ /**
+ * Callback for reporting the number of services with clients.
+ */
+ std::function<bool(bool)> mActiveServicesCallback;
+
+ /**
+ * Previous value passed to the active services callback.
+ */
+ std::optional<bool> mPreviousHasClients;
};
class LazyServiceRegistrarImpl {
- public:
+ public:
LazyServiceRegistrarImpl() : mClientCallback(new ClientCounterCallback) {}
status_t registerService(const sp<::android::hidl::base::V1_0::IBase>& service,
const std::string& name);
+ bool tryUnregister();
+ void reRegister();
+ void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
- private:
+ private:
sp<ClientCounterCallback> mClientCallback;
};
@@ -86,6 +112,17 @@
return success;
}
+ClientCounterCallback::Service& ClientCounterCallback::assertRegisteredService(
+ const sp<IBase>& service) {
+ for (Service& registered : mRegisteredServices) {
+ if (registered.service != service) continue;
+ return registered;
+ }
+ LOG(FATAL) << "Got callback on service " << getDescriptor(service.get())
+ << " which we did not register.";
+ __builtin_unreachable();
+}
+
bool ClientCounterCallback::registerService(const sp<IBase>& service, const std::string& name) {
auto manager = hardware::defaultServiceManager1_2();
@@ -114,58 +151,96 @@
*/
Return<void> ClientCounterCallback::onClients(const sp<::android::hidl::base::V1_0::IBase>& service,
bool clients) {
- if (clients) {
- mNumConnectedServices++;
- } else {
- mNumConnectedServices--;
+ Service& registered = assertRegisteredService(service);
+ if (registered.clients == clients) {
+ LOG(FATAL) << "Process already thought " << getDescriptor(service.get()) << "/"
+ << registered.name << " had clients: " << registered.clients
+ << " but hwservicemanager has notified has clients: " << clients;
+ }
+ registered.clients = clients;
+
+ size_t numWithClients = 0;
+ for (const Service& registered : mRegisteredServices) {
+ if (registered.clients) numWithClients++;
}
- LOG(INFO) << "Process has " << mNumConnectedServices << " (of " << mRegisteredServices.size()
+ LOG(INFO) << "Process has " << numWithClients << " (of " << mRegisteredServices.size()
<< " available) client(s) in use after notification " << getDescriptor(service.get())
- << " has clients: " << clients;
+ << "/" << registered.name << " has clients: " << clients;
- if (mNumConnectedServices == 0) {
+ bool handledInCallback = false;
+ if (mActiveServicesCallback != nullptr) {
+ bool hasClients = numWithClients != 0;
+ if (hasClients != mPreviousHasClients) {
+ handledInCallback = mActiveServicesCallback(hasClients);
+ mPreviousHasClients = hasClients;
+ }
+ }
+
+ // If there is no callback defined or the callback did not handle this
+ // client count change event, try to shutdown the process if its services
+ // have no clients.
+ if (!handledInCallback && numWithClients == 0) {
tryShutdown();
}
return Status::ok();
}
-void ClientCounterCallback::tryShutdown() {
- LOG(INFO) << "Trying to exit HAL. No clients in use for any service in process.";
-
+bool ClientCounterCallback::tryUnregister() {
auto manager = hardware::defaultServiceManager1_2();
- auto unRegisterIt = mRegisteredServices.begin();
- for (; unRegisterIt != mRegisteredServices.end(); ++unRegisterIt) {
- auto& entry = (*unRegisterIt);
-
+ for (Service& entry : mRegisteredServices) {
const std::string descriptor = getDescriptor(entry.service.get());
bool success = manager->tryUnregister(descriptor, entry.name, entry.service);
if (!success) {
LOG(INFO) << "Failed to unregister HAL " << descriptor << "/" << entry.name;
- break;
+ return false;
}
+
+ // Mark the entry unregistered, but do not remove it (may still be re-registered)
+ entry.registered = false;
}
- if (unRegisterIt == mRegisteredServices.end()) {
- LOG(INFO) << "Unregistered all clients and exiting";
- exit(EXIT_SUCCESS);
- }
+ return true;
+}
- for (auto reRegisterIt = mRegisteredServices.begin(); reRegisterIt != unRegisterIt;
- reRegisterIt++) {
- auto& entry = (*reRegisterIt);
+void ClientCounterCallback::reRegister() {
+ for (Service& entry : mRegisteredServices) {
+ // re-register entry if not already registered
+ if (entry.registered) {
+ continue;
+ }
- // re-register entry
if (!registerService(entry.service, entry.name)) {
// Must restart. Otherwise, clients will never be able to get ahold of this service.
LOG(FATAL) << "Bad state: could not re-register " << getDescriptor(entry.service.get());
}
+
+ entry.registered = true;
}
}
+void ClientCounterCallback::tryShutdown() {
+ LOG(INFO) << "Trying to exit HAL. No clients in use for any service in process.";
+
+ if (tryUnregister()) {
+ LOG(INFO) << "Unregistered all clients and exiting";
+ exit(EXIT_SUCCESS);
+ }
+
+ // At this point, we failed to unregister some of the services, leaving the
+ // server in an inconsistent state. Re-register all services that were
+ // unregistered by tryUnregister().
+ reRegister();
+}
+
+void ClientCounterCallback::setActiveServicesCallback(
+ const std::function<bool(bool)>& activeServicesCallback) {
+ mActiveServicesCallback = activeServicesCallback;
+}
+
status_t LazyServiceRegistrarImpl::registerService(
const sp<::android::hidl::base::V1_0::IBase>& service, const std::string& name) {
if (!mClientCallback->addRegisteredService(service, name)) {
@@ -175,6 +250,19 @@
return ::android::OK;
}
+bool LazyServiceRegistrarImpl::tryUnregister() {
+ return mClientCallback->tryUnregister();
+}
+
+void LazyServiceRegistrarImpl::reRegister() {
+ mClientCallback->reRegister();
+}
+
+void LazyServiceRegistrarImpl::setActiveServicesCallback(
+ const std::function<bool(bool)>& activeServicesCallback) {
+ mClientCallback->setActiveServicesCallback(activeServicesCallback);
+}
+
} // namespace details
LazyServiceRegistrar::LazyServiceRegistrar() {
@@ -191,5 +279,18 @@
return mImpl->registerService(service, name);
}
+bool LazyServiceRegistrar::tryUnregister() {
+ return mImpl->tryUnregister();
+}
+
+void LazyServiceRegistrar::reRegister() {
+ mImpl->reRegister();
+}
+
+void LazyServiceRegistrar::setActiveServicesCallback(
+ const std::function<bool(bool)>& activeServicesCallback) {
+ mImpl->setActiveServicesCallback(activeServicesCallback);
+}
+
} // namespace hardware
} // namespace android
diff --git a/transport/HidlTransportSupport.cpp b/transport/HidlTransportSupport.cpp
index e645cd0..d0ac243 100644
--- a/transport/HidlTransportSupport.cpp
+++ b/transport/HidlTransportSupport.cpp
@@ -128,12 +128,7 @@
namespace details {
int32_t getPidIfSharable() {
-#if LIBHIDL_TARGET_DEBUGGABLE
return getpid();
-#else
- using android::hidl::manager::V1_0::IServiceManager;
- return static_cast<int32_t>(IServiceManager::PidConstant::NO_PID);
-#endif
}
} // namespace details
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index a7e9626..c638279 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -153,11 +153,41 @@
namespace details {
+#ifdef ENFORCE_VINTF_MANIFEST
+static constexpr bool kEnforceVintfManifest = true;
+#else
+static constexpr bool kEnforceVintfManifest = false;
+#endif
+
+static bool* getTrebleTestingOverridePtr() {
+ static bool gTrebleTestingOverride = false;
+ return &gTrebleTestingOverride;
+}
+
+void setTrebleTestingOverride(bool testingOverride) {
+ *getTrebleTestingOverridePtr() = testingOverride;
+}
+
+static bool isDebuggable() {
+ static bool debuggable = base::GetBoolProperty("ro.debuggable", false);
+ return debuggable;
+}
+
+static inline bool isTrebleTestingOverride() {
+ if (kEnforceVintfManifest && !isDebuggable()) {
+ // don't allow testing override in production
+ return false;
+ }
+
+ return *getTrebleTestingOverridePtr();
+}
+
static void onRegistrationImpl(const std::string& descriptor, const std::string& instanceName) {
LOG(INFO) << "Registered " << descriptor << "/" << instanceName;
tryShortenProcessName(descriptor);
}
+// only used by prebuilts - should be able to remove
void onRegistration(const std::string& packageName, const std::string& interfaceName,
const std::string& instanceName) {
return onRegistrationImpl(packageName + "::" + interfaceName, instanceName);
@@ -329,8 +359,7 @@
dlerror(); // clear
- static std::string halLibPathVndkSp = android::base::StringPrintf(
- HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, details::getVndkVersionStr().c_str());
+ static std::string halLibPathVndkSp = details::getVndkSpHwPath();
std::vector<std::string> paths = {
HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, halLibPathVndkSp,
#ifndef __ANDROID_VNDK__
@@ -338,10 +367,7 @@
#endif
};
-#ifdef LIBHIDL_TARGET_DEBUGGABLE
- const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
- const bool trebleTestingOverride = env && !strcmp(env, "true");
- if (trebleTestingOverride) {
+ if (details::isTrebleTestingOverride()) {
// Load HAL implementations that are statically linked
handle = dlopen(nullptr, dlMode);
if (handle == nullptr) {
@@ -352,7 +378,6 @@
return;
}
}
-#endif
for (const std::string& path : paths) {
std::vector<std::string> libs = findFiles(path, prefix, ".so");
@@ -391,18 +416,27 @@
*(void **)(&generator) = dlsym(handle, sym.c_str());
if(!generator) {
const char* error = dlerror();
- LOG(ERROR) << "Passthrough lookup opened " << lib
- << " but could not find symbol " << sym << ": "
- << (error == nullptr ? "unknown error" : error);
- dlclose(handle);
- return true;
+ LOG(ERROR) << "Passthrough lookup opened " << lib << " but could not find symbol "
+ << sym << ": " << (error == nullptr ? "unknown error" : error)
+ << ". Keeping library open.";
+
+ // dlclose too problematic in multi-threaded environment
+ // dlclose(handle);
+
+ return true; // continue
}
ret = (*generator)(name.c_str());
if (ret == nullptr) {
- dlclose(handle);
- return true; // this module doesn't provide this instance name
+ LOG(ERROR) << "Could not find instance '" << name.c_str() << "' in library " << lib
+ << ". Keeping library open.";
+
+ // dlclose too problematic in multi-threaded environment
+ // dlclose(handle);
+
+ // this module doesn't provide this particular instance
+ return true; // continue
}
// Actual fqname might be a subclass.
@@ -451,10 +485,8 @@
Return<void> debugDump(debugDump_cb _hidl_cb) override {
using Arch = ::android::hidl::base::V1_0::DebugInfo::Architecture;
using std::literals::string_literals::operator""s;
- static std::string halLibPathVndkSp64 = android::base::StringPrintf(
- HAL_LIBRARY_PATH_VNDK_SP_64BIT_FOR_VERSION, details::getVndkVersionStr().c_str());
- static std::string halLibPathVndkSp32 = android::base::StringPrintf(
- HAL_LIBRARY_PATH_VNDK_SP_32BIT_FOR_VERSION, details::getVndkVersionStr().c_str());
+ static std::string halLibPathVndkSp64 = details::getVndkSpHwPath("lib64");
+ static std::string halLibPathVndkSp32 = details::getVndkSpHwPath("lib");
static std::vector<std::pair<Arch, std::vector<const char*>>> sAllPaths{
{Arch::IS_64BIT,
{
@@ -703,28 +735,6 @@
return false;
}
-#ifdef ENFORCE_VINTF_MANIFEST
-static constexpr bool kEnforceVintfManifest = true;
-#else
-static constexpr bool kEnforceVintfManifest = false;
-#endif
-
-#ifdef LIBHIDL_TARGET_DEBUGGABLE
-static constexpr bool kDebuggable = true;
-#else
-static constexpr bool kDebuggable = false;
-#endif
-
-static inline bool isTrebleTestingOverride() {
- if (kEnforceVintfManifest && !kDebuggable) {
- // don't allow testing override in production
- return false;
- }
-
- const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
- return env && !strcmp(env, "true");
-}
-
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance,
bool retry, bool getStub) {
@@ -755,7 +765,7 @@
const bool vintfHwbinder = (transport == Transport::HWBINDER);
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
const bool trebleTestingOverride = isTrebleTestingOverride();
- const bool allowLegacy = !kEnforceVintfManifest || (trebleTestingOverride && kDebuggable);
+ const bool allowLegacy = !kEnforceVintfManifest || (trebleTestingOverride && isDebuggable());
const bool vintfLegacy = (transport == Transport::EMPTY) && allowLegacy;
if (!kEnforceVintfManifest) {
@@ -837,7 +847,13 @@
if (kEnforceVintfManifest && !isTrebleTestingOverride()) {
using Transport = IServiceManager1_0::Transport;
- Transport transport = sm->getTransport(descriptor, name);
+ Return<Transport> transport = sm->getTransport(descriptor, name);
+
+ if (!transport.isOk()) {
+ LOG(ERROR) << "Could not get transport for " << descriptor << "/" << name << ": "
+ << transport.description();
+ return UNKNOWN_ERROR;
+ }
if (transport != Transport::HWBINDER) {
LOG(ERROR) << "Service " << descriptor << "/" << name
diff --git a/transport/allocator/1.0/Android.bp b/transport/allocator/1.0/Android.bp
index 6da3793..0cc3b62 100644
--- a/transport/allocator/1.0/Android.bp
+++ b/transport/allocator/1.0/Android.bp
@@ -1,13 +1,19 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.allocator@1.0",
root: "android.hidl",
// TODO(b/153609531): remove when no longer needed.
native_bridge_supported: true,
- vndk: {
- enabled: true,
- },
srcs: [
"IAllocator.hal",
],
@@ -15,4 +21,8 @@
"android.hidl.base@1.0",
],
gen_java: false,
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/transport/allocator/1.0/default/Android.bp b/transport/allocator/1.0/default/Android.bp
index 1116f1d..42abe9c 100644
--- a/transport/allocator/1.0/default/Android.bp
+++ b/transport/allocator/1.0/default/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
cc_binary {
name: "android.hidl.allocator@1.0-service",
relative_install_path: "hw",
diff --git a/transport/allocator/1.0/utils/Android.bp b/transport/allocator/1.0/utils/Android.bp
index b324ef1..f21047d 100644
--- a/transport/allocator/1.0/utils/Android.bp
+++ b/transport/allocator/1.0/utils/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
cc_library {
name: "libhidlallocatorutils",
vendor_available: true,
diff --git a/transport/allocator/1.0/vts/functional/Android.bp b/transport/allocator/1.0/vts/functional/Android.bp
index 31d9821..f53fc4f 100644
--- a/transport/allocator/1.0/vts/functional/Android.bp
+++ b/transport/allocator/1.0/vts/functional/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
cc_test {
name: "VtsHidlAllocatorV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
@@ -26,4 +35,3 @@
],
test_suites: ["general-tests", "vts"],
}
-
diff --git a/transport/base/1.0/Android.bp b/transport/base/1.0/Android.bp
index 8c796b2..461f7e7 100644
--- a/transport/base/1.0/Android.bp
+++ b/transport/base/1.0/Android.bp
@@ -1,16 +1,26 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.base@1.0",
root: "android.hidl",
// TODO(b/153609531): remove when no longer needed.
native_bridge_supported: true,
- vndk: {
- enabled: true,
- },
srcs: [
"types.hal",
"IBase.hal",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/transport/base/1.0/vts/functional/Android.bp b/transport/base/1.0/vts/functional/Android.bp
index 0c814ae..f25aaaa 100644
--- a/transport/base/1.0/vts/functional/Android.bp
+++ b/transport/base/1.0/vts/functional/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
cc_test {
name: "vts_ibase_test",
defaults: ["libinit_test_utils_libraries_defaults"],
diff --git a/transport/base/1.0/vts/functional/Android.mk b/transport/base/1.0/vts/functional/Android.mk
deleted file mode 100644
index 61c6e31..0000000
--- a/transport/base/1.0/vts/functional/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (C) 2017 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := VtsHalBaseV1_0TargetTest
--include test/vts/tools/build/Android.host_config.mk
diff --git a/transport/base/1.0/vts/functional/AndroidTest.xml b/transport/base/1.0/vts/functional/AndroidTest.xml
deleted file mode 100644
index 80154f2..0000000
--- a/transport/base/1.0/vts/functional/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<configuration description="Config for VTS VtsHalBaseV1_0TargetTest test cases">
- <option name="config-descriptor:metadata" key="plan" value="vts-treble" />
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
- <option name="abort-on-push-failure" value="false"/>
- <option name="push-group" value="HalHidlTargetTest.push"/>
- </target_preparer>
- <multi_target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
- <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
- <option name="test-module-name" value="VtsHalBaseV1_0TargetTest"/>
- <option name="binary-test-working-directory" value="_32bit::/data/nativetest/" />
- <option name="binary-test-working-directory" value="_64bit::/data/nativetest64/" />
- <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_ibase_test/vts_ibase_test" />
- <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_ibase_test/vts_ibase_test" />
- <option name="binary-test-type" value="gtest"/>
- <option name="test-timeout" value="5m"/>
- </test>
-</configuration>
diff --git a/transport/include/hidl/HidlLazyUtils.h b/transport/include/hidl/HidlLazyUtils.h
index 6a62c97..427611b 100644
--- a/transport/include/hidl/HidlLazyUtils.h
+++ b/transport/include/hidl/HidlLazyUtils.h
@@ -16,6 +16,8 @@
#pragma once
+#include <functional>
+
#include <android/hidl/base/1.0/IBase.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
@@ -26,12 +28,53 @@
class LazyServiceRegistrarImpl;
} // namespace details
-/** Exits when all HALs registered through this object have 0 clients */
+/**
+ * Exits when all HALs registered through this object have 0 clients
+ *
+ * In order to use this class, it's expected that your service:
+ * - registers all services in the process with this API
+ * - configures services as oneshot + disabled in init .rc files
+ * - uses 'interface' declarations in init .rc files
+ *
+ * For more information on init .rc configuration, see system/core/init/README.md
+ **/
class LazyServiceRegistrar {
public:
static LazyServiceRegistrar& getInstance();
status_t registerService(const sp<::android::hidl::base::V1_0::IBase>& service,
const std::string& name = "default");
+ /**
+ * Set a callback that is invoked when the active HAL count (i.e. HALs with clients)
+ * registered with this process drops to zero (or becomes nonzero).
+ * The callback takes a boolean argument, which is 'true' if there is
+ * at least one HAL with clients.
+ *
+ * Callback return value:
+ * - false: Default behavior for lazy HALs (shut down the process if there
+ * are no clients).
+ * - true: Don't shut down the process even if there are no clients.
+ *
+ * This callback gives a chance to:
+ * 1 - Perform some additional operations before exiting;
+ * 2 - Prevent the process from exiting by returning "true" from the
+ * callback.
+ *
+ * This method should be called before 'registerService' to avoid races.
+ */
+ void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback);
+
+ /**
+ * Try to unregister all services previously registered with 'registerService'.
+ * Returns 'true' if successful.
+ */
+ bool tryUnregister();
+
+ /**
+ * Re-register services that were unregistered by 'tryUnregister'.
+ * This method should be called in the case 'tryUnregister' fails
+ * (and should be called on the same thread).
+ */
+ void reRegister();
private:
std::shared_ptr<details::LazyServiceRegistrarImpl> mImpl;
diff --git a/transport/include/hidl/ServiceManagement.h b/transport/include/hidl/ServiceManagement.h
index 4573a25..886e816 100644
--- a/transport/include/hidl/ServiceManagement.h
+++ b/transport/include/hidl/ServiceManagement.h
@@ -47,10 +47,17 @@
// e.x.: android.hardware.foo@1.0::IFoo, default
void waitForHwService(const std::string &interface, const std::string &instanceName);
+// Only works on userdebug/eng builds. This allows getService to bypass the
+// VINTF manifest for testing only.
+void setTrebleTestingOverride(bool testingOverride);
+
void preloadPassthroughService(const std::string &descriptor);
// Returns a service with the following constraints:
-// - retry => service is waited for and returned if available in this process
+// - retry => service is waited for and returned if it is declared in the
+// manifest AND it is available in this process (if errors indicate an
+// sepolicy denial, then this will return - TODO(b/28321379) more precise
+// errors to handle more cases)
// - getStub => internal only. Forces to get the unwrapped (no BsFoo) if available.
// TODO(b/65843592)
// If the service is a remote service, this function returns BpBase. If the service is
diff --git a/transport/manager/1.0/Android.bp b/transport/manager/1.0/Android.bp
index c91dcd2..4a84b86 100644
--- a/transport/manager/1.0/Android.bp
+++ b/transport/manager/1.0/Android.bp
@@ -1,11 +1,17 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.manager@1.0",
root: "android.hidl",
- vndk: {
- enabled: true,
- },
srcs: [
"IServiceManager.hal",
"IServiceNotification.hal",
@@ -14,4 +20,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/transport/manager/1.1/Android.bp b/transport/manager/1.1/Android.bp
index 82545e5..c9e22c9 100644
--- a/transport/manager/1.1/Android.bp
+++ b/transport/manager/1.1/Android.bp
@@ -1,11 +1,17 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.manager@1.1",
root: "android.hidl",
- vndk: {
- enabled: true,
- },
srcs: [
"IServiceManager.hal",
],
@@ -14,4 +20,8 @@
"android.hidl.manager@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/transport/manager/1.2/Android.bp b/transport/manager/1.2/Android.bp
index e7ee143..a58c12e 100644
--- a/transport/manager/1.2/Android.bp
+++ b/transport/manager/1.2/Android.bp
@@ -1,11 +1,17 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.manager@1.2",
root: "android.hidl",
- vndk: {
- enabled: true,
- },
srcs: [
"IClientCallback.hal",
"IServiceManager.hal",
@@ -16,4 +22,8 @@
"android.hidl.manager@1.1",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/transport/memory/1.0/Android.bp b/transport/memory/1.0/Android.bp
index 9ce04ed..8e066a9 100644
--- a/transport/memory/1.0/Android.bp
+++ b/transport/memory/1.0/Android.bp
@@ -1,5 +1,14 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.memory@1.0",
root: "android.hidl",
@@ -17,4 +26,8 @@
"android.hidl.base@1.0",
],
gen_java: false,
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/transport/memory/1.0/default/Android.bp b/transport/memory/1.0/default/Android.bp
index f56ee95..a44a0db 100644
--- a/transport/memory/1.0/default/Android.bp
+++ b/transport/memory/1.0/default/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
cc_library_shared {
name: "android.hidl.memory@1.0-impl",
vendor_available: true,
diff --git a/transport/memory/block/1.0/Android.bp b/transport/memory/block/1.0/Android.bp
index f26a6d3..bfaf139 100644
--- a/transport/memory/block/1.0/Android.bp
+++ b/transport/memory/block/1.0/Android.bp
@@ -1,11 +1,17 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.memory.block@1.0",
root: "android.hidl",
- vndk: {
- enabled: true,
- },
srcs: [
"types.hal",
],
diff --git a/transport/memory/token/1.0/Android.bp b/transport/memory/token/1.0/Android.bp
index 46c3387..c304284 100644
--- a/transport/memory/token/1.0/Android.bp
+++ b/transport/memory/token/1.0/Android.bp
@@ -1,5 +1,14 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.memory.token@1.0",
root: "android.hidl",
@@ -16,4 +25,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/transport/safe_union/1.0/Android.bp b/transport/safe_union/1.0/Android.bp
index 2760863..cae92dd 100644
--- a/transport/safe_union/1.0/Android.bp
+++ b/transport/safe_union/1.0/Android.bp
@@ -1,5 +1,14 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.safe_union@1.0",
root: "android.hidl",
@@ -11,4 +20,8 @@
"types.hal",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/transport/token/1.0/Android.bp b/transport/token/1.0/Android.bp
index 28f16f7..8bda482 100644
--- a/transport/token/1.0/Android.bp
+++ b/transport/token/1.0/Android.bp
@@ -1,5 +1,14 @@
// This file is autogenerated by hidl-gen -Landroidbp.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
hidl_interface {
name: "android.hidl.token@1.0",
root: "android.hidl",
@@ -13,4 +22,8 @@
"android.hidl.base@1.0",
],
gen_java: true,
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/transport/token/1.0/utils/Android.bp b/transport/token/1.0/utils/Android.bp
index 5ccbe75..84f6f0f 100644
--- a/transport/token/1.0/utils/Android.bp
+++ b/transport/token/1.0/utils/Android.bp
@@ -12,10 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_libhidl_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_libhidl_license"],
+}
+
cc_library {
name: "android.hidl.token@1.0-utils",
defaults: ["libhidl-defaults"],
vendor_available: true,
+ // Host support is needed for testing only
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
vndk: {
enabled: true,
},
@@ -48,4 +64,8 @@
"include",
],
min_sdk_version: "29",
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/vintfdata/Android.mk b/vintfdata/Android.mk
index d873e29..4c5cca5 100644
--- a/vintfdata/Android.mk
+++ b/vintfdata/Android.mk
@@ -48,6 +48,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := vendor_compatibility_matrix.xml
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
LOCAL_MODULE_STEM := compatibility_matrix.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vintf
@@ -69,6 +72,9 @@
# System Manifest
include $(CLEAR_VARS)
LOCAL_MODULE := system_manifest.xml
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
LOCAL_MODULE_STEM := manifest.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
@@ -89,6 +95,9 @@
ifneq ($(PRODUCT_MANIFEST_FILES),)
include $(CLEAR_VARS)
LOCAL_MODULE := product_manifest.xml
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
LOCAL_MODULE_STEM := manifest.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_PRODUCT_MODULE := true
@@ -107,6 +116,9 @@
# System_ext Manifest
include $(CLEAR_VARS)
LOCAL_MODULE := system_ext_manifest.xml
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
LOCAL_MODULE_STEM := manifest.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_SYSTEM_EXT_MODULE := true
@@ -128,3 +140,5 @@
SYSTEM_EXT_MANIFEST_INPUT_FILES :=
DEVICE_MATRIX_INPUT_FILE :=
PRODUCT_MANIFEST_INPUT_FILES :=
+
+VINTF_FRAMEWORK_MANIFEST_FROZEN_DIR := $(LOCAL_PATH)/frozen
diff --git a/vintfdata/README.md b/vintfdata/README.md
new file mode 100644
index 0000000..cfc1da7
--- /dev/null
+++ b/vintfdata/README.md
@@ -0,0 +1,91 @@
+# Updating the latest framework manifest
+
+## Adding new HALs / Major version update
+
+Add a new `<hal>` entry without a `max-level` attribute. The `<hal>` entry can
+be added to the main manifest under `manifest.xml`, or to the manifest
+fragment for the server module specified in `vintf_fragments`.
+
+Introducing new HALs are backwards compatible.
+
+## Minor version update
+
+When a framework HAL updates its minor version, simply update the `<version>` or
+`<fqname>` field to the latest version. This is the same as any other HALs.
+
+For example, when `IServiceManager` updates to 1.2, change its `<fqname>` field
+to `@1.2::IServiceManager/default`.
+
+Because minor version updates are backwards compatible, all devices that require
+a lower minor version of the HAL are still compatible.
+
+Leave `max-level` attribute empty.
+
+## Deprecating HAL
+
+When a framework HAL is deprecated, set `max-level` field of the HAL from empty
+to the last frozen version.
+For example, if IDisplayService is deprecated in Android S, set `max-level` to
+Android R (5):
+
+```xml
+<manifest version="3.0" type="framework">
+ <hal format="hidl" max-level="5"> <!-- Level::R -->
+ <name>android.frameworks.displayservice</name>
+ <transport>hwbinder</transport>
+ <fqname>@1.0::IDisplayService/default</fqname>
+ </hal>
+</manifest>
+```
+
+Note that the `max-level` of the HAL is set to Android R, meaning that the HAL
+is last available in Android R and disabled in Android S.
+
+Deprecating a HAL doesn’t mean dropping support of the HAL, so no devices will
+break.
+
+When setting `max-level` of a HAL:
+- If `optional="false"` in frozen DCMs, the build system checks that adding the
+ attribute does not break backwards compatibility; that is,
+ `max-level > last_frozen_level`.
+- If `optional="true"`, the check is disabled. Care must be taken to ensure
+ `max-level` is set appropriately.
+
+## Removing HAL
+
+When the framework drops support of a certain HAL, the corresponding HAL entry
+is removed from the framework manifest, and code that serves and registers the
+HAL must be removed simultaneously.
+
+Devices that are lower than the `max-level` attribute of the HAL may start to
+break if they require this HAL. Hence, this must only be done when there is
+enough evidence that the devices are not updateable to the latest Android
+release.
+
+# Freezing framework HAL manifest
+
+First, check `libvintf` or `hardware/interfaces/compatibility_matrices` to
+determine the current level.
+
+Execute the following, replacing the argument with the level to freeze:
+
+```shell script
+lunch cf_x86_phone-userdebug # or any generic target
+LEVEL=5
+./freeze.sh ${LEVEL}
+```
+
+A new file, `frozen/${LEVEL}.xml`, will be created after the command is
+executed. Frozen system manifests are stored in compatibility matrices. Then,
+manually inspect the frozen compatibility matrix. Modify the `optional`
+field for certain HALs. See comments in the compatibility matrix of the previous
+level for details.
+
+These compatibility matrices served as a reference for devices at that
+target FCM version. Devices at the given target FCM version should
+reference DCMs in the `frozen/` dir, with some of the HALs marked
+as `optional="true"` or even omitted if unused by device-specific code.
+
+At build time, compatibiltiy is checked between framework manifest and
+the respective frozen DCM. HALs in the framework manifest with `max-level`
+less than the specified level are omitted.
diff --git a/vintfdata/freeze.sh b/vintfdata/freeze.sh
new file mode 100755
index 0000000..a624ee3
--- /dev/null
+++ b/vintfdata/freeze.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+mydir="$(dirname $0)"
+
+function freeze() {
+ [[ $# == 1 ]] || {
+ echo "usage: freeze.sh <level>"
+ echo "e.g. To freeze framework manifest for Android R, run:"
+ echo " freeze.sh 5"
+ return 1
+ }
+ local level="$1"
+ [[ "${ANDROID_BUILD_TOP}" ]] || {
+ echo "ANDROID_BUILD_TOP is not set; did you run envsetup.sh?"
+ return 1
+ }
+ [[ "${ANDROID_HOST_OUT}" ]] || {
+ echo "ANDROID_HOST_OUT is not set; did you run envsetup.sh?"
+ return 1
+ }
+
+ local modules_to_build=check-vintf-all
+ echo "Building ${modules_to_build}"
+ "${ANDROID_BUILD_TOP}/build/soong/soong_ui.bash" --build-mode --all-modules --dir="$(pwd)" ${modules_to_build} || {
+ echo "${modules_to_build} failed. Backwards compatibility might be broken."
+ echo "Check framework manifest changes. If this is intentional, run "
+ echo " \`vintffm --update\` with appropriate options to update frozen files."
+ return 1
+ }
+
+ echo "Updating level ${level}"
+ "${ANDROID_HOST_OUT}/bin/vintffm" --update --level "${level}" --dirmap "/system:${ANDROID_PRODUCT_OUT}/system" "${mydir}/frozen" || return 1
+
+ local files_to_diff="$(printf "${mydir}/frozen/%s\n" $(ls -1 -t -r ${mydir}/frozen | xargs -I{} basename {} | grep -B1 "${level}.xml"))"
+
+ echo
+ echo "Summary of changes:"
+ echo diff ${files_to_diff}
+ diff ${files_to_diff} || true
+}
+
+freeze $@
diff --git a/vintfdata/frozen/5.xml b/vintfdata/frozen/5.xml
new file mode 100644
index 0000000..525829d
--- /dev/null
+++ b/vintfdata/frozen/5.xml
@@ -0,0 +1,110 @@
+<compatibility-matrix version="3.0" type="device">
+ <!--
+ cameraserver is installed for all phones and tablets, but not
+ auto or TV.
+ -->
+ <hal format="hidl" optional="true">
+ <name>android.frameworks.cameraservice.service</name>
+ <version>2.1</version>
+ <interface>
+ <name>ICameraService</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.frameworks.displayservice</name>
+ <version>1.0</version>
+ <interface>
+ <name>IDisplayService</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.frameworks.schedulerservice</name>
+ <version>1.0</version>
+ <interface>
+ <name>ISchedulingPolicyService</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.frameworks.sensorservice</name>
+ <version>1.0</version>
+ <interface>
+ <name>ISensorManager</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.frameworks.stats</name>
+ <version>1.0</version>
+ <interface>
+ <name>IStats</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hardware.media.c2</name>
+ <version>1.1</version>
+ <interface>
+ <name>IComponentStore</name>
+ <instance>software</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hidl.allocator</name>
+ <version>1.0</version>
+ <interface>
+ <name>IAllocator</name>
+ <instance>ashmem</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hidl.manager</name>
+ <version>1.2</version>
+ <interface>
+ <name>IServiceManager</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hidl.memory</name>
+ <version>1.0</version>
+ <interface>
+ <name>IMapper</name>
+ <instance>ashmem</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.hidl.token</name>
+ <version>1.0</version>
+ <interface>
+ <name>ITokenManager</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.system.net.netd</name>
+ <version>1.1</version>
+ <interface>
+ <name>INetd</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.system.suspend</name>
+ <version>1.0</version>
+ <interface>
+ <name>ISystemSuspend</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="false">
+ <name>android.system.wifi.keystore</name>
+ <version>1.0</version>
+ <interface>
+ <name>IKeystore</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</compatibility-matrix>
diff --git a/vintfdata/manifest.xml b/vintfdata/manifest.xml
index e204671..8fd69b9 100644
--- a/vintfdata/manifest.xml
+++ b/vintfdata/manifest.xml
@@ -35,7 +35,12 @@
<instance>default</instance>
</interface>
</hal>
- <hal>
+ <!--
+ Instead of calling this, prefer to set priority in init .rc files via
+ `ioprio <class> <priority>`. For more information, see
+ system/core/init/README.md
+ -->
+ <hal max-level="5">
<name>android.frameworks.schedulerservice</name>
<transport>hwbinder</transport>
<version>1.0</version>