Snap for 5735642 from 48a484c8db1c3cff3d90bd8e047408c8e55f944b to sdk-release
Change-Id: Ia07c65fa527969dcf0b263e3740c18ef75a768e8
diff --git a/Android.bp b/Android.bp
index b30ca23..1cb86b7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,10 +23,12 @@
cc_defaults {
name: "ashmemd_defaults",
shared_libs: [
- "ashmemd_aidl_interface-cpp",
"libbase",
"libbinder",
+ "libcutils",
"libutils",
+ "libhidlbase",
+ "libhidltransport",
],
cflags: [
"-Wall",
@@ -38,15 +40,37 @@
name: "ashmemd",
defaults: ["ashmemd_defaults"],
srcs: ["ashmemd.cpp"],
+ shared_libs: [
+ "android.system.ashmem@1.0",
+ "ashmemd_aidl_interface-cpp",
+ ],
init_rc: ["ashmemd.rc"],
+ vintf_fragments: ["android.system.ashmem@1.0.xml"],
}
// This library is used to communicate with ashmemd using dlopen/dlsym. We do
-// this to avoid shared library dependecy cycles.
+// this to avoid shared library dependency cycles.
cc_library {
name: "libashmemd_client",
defaults: ["ashmemd_defaults"],
srcs: ["ashmemd_client.cpp"],
+ shared_libs: ["ashmemd_aidl_interface-cpp"],
+ cflags: [
+ "-Wexit-time-destructors",
+ "-fno-c++-static-destructors",
+ ],
+}
+
+// This library is used to communicate with ashmemd using dlopen/dlsym. We do
+// this to avoid shared library dependency cycles.
+cc_library {
+ name: "libashmemd_hidl_client",
+ vendor: true,
+ defaults: ["ashmemd_defaults"],
+ srcs: ["ashmemd_hidl_client.cpp"],
+ shared_libs: [
+ "android.system.ashmem@1.0",
+ ],
cflags: [
"-Wexit-time-destructors",
"-fno-c++-static-destructors",
@@ -57,5 +81,18 @@
name: "ashmemd_test",
defaults: ["ashmemd_defaults"],
srcs: ["tests/ashmemd_test.cpp"],
+ shared_libs: [
+ "android.system.ashmem@1.0",
+ "ashmemd_aidl_interface-cpp",
+ ],
+ test_suites: ["device-tests"],
+}
+
+cc_test {
+ name: "ashmemd_hidl_client_test",
+ vendor: true,
+ defaults: ["ashmemd_defaults"],
+ srcs: ["tests/ashmemd_hidl_client_test.cpp"],
+ shared_libs: ["android.system.ashmem@1.0"],
test_suites: ["device-tests"],
}
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
new file mode 100644
index 0000000..18b0a1b
--- /dev/null
+++ b/PREUPLOAD.cfg
@@ -0,0 +1,6 @@
+[Options]
+ignore_merged_commits = true
+
+[Builtin Hooks]
+clang_format = true
+bpfmt = true
diff --git a/android.system.ashmem@1.0.xml b/android.system.ashmem@1.0.xml
new file mode 100644
index 0000000..48c7e47
--- /dev/null
+++ b/android.system.ashmem@1.0.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="framework">
+ <hal>
+ <name>android.system.ashmem</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IAshmem</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/ashmemd.cpp b/ashmemd.cpp
index 9d12ed3..67f407b 100644
--- a/ashmemd.cpp
+++ b/ashmemd.cpp
@@ -14,46 +14,89 @@
* limitations under the License.
*/
+#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <binder/BinderService.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/Status.h>
+#include <cutils/native_handle.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Status.h>
#include <utils/String16.h>
#include <android/ashmemd/BnAshmemDeviceService.h>
+#include <android/system/ashmem/1.0/IAshmem.h>
+using android::sp;
using android::String16;
using android::base::unique_fd;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::system::ashmem::V1_0::IAshmem;
namespace android {
namespace ashmemd {
-class AshmemDeviceService : public BnAshmemDeviceService {
- public:
- binder::Status open(os::ParcelFileDescriptor* ashmemFd) override {
- ashmemFd->reset(unique_fd(TEMP_FAILURE_RETRY(::open("/dev/ashmem", O_RDWR | O_CLOEXEC))));
- return binder::Status::ok();
- }
+inline unique_fd openDevAshmem() {
+ int fd = TEMP_FAILURE_RETRY(::open("/dev/ashmem", O_RDWR | O_CLOEXEC));
+ return unique_fd(fd);
+}
+
+class AshmemAidlService : public BnAshmemDeviceService {
+public:
+ binder::Status open(os::ParcelFileDescriptor *ashmemFd) override {
+ ashmemFd->reset(openDevAshmem());
+ return binder::Status::ok();
+ }
};
-void CreateAndRegisterService() {
- sp<AshmemDeviceService> ashmemService = new AshmemDeviceService();
- defaultServiceManager()->addService(String16("ashmem_device_service"), ashmemService,
- true /* allowIsolated */);
-}
-
-void JoinThreadPool() {
- sp<ProcessState> ps = ProcessState::self();
- IPCThreadState::self()->joinThreadPool(); // should not return
-}
+class AshmemHidlService : public IAshmem {
+public:
+ Return<void> open(open_cb _hidl_cb) override {
+ unique_fd fd = openDevAshmem();
+ if (fd == -1) {
+ _hidl_cb(nullptr);
+ } else {
+ native_handle_t *native_handle =
+ native_handle_create(1 /* num_fds */, 0 /* num_ints */);
+ native_handle->data[0] = fd.get();
+ _hidl_cb(native_handle);
+ // unique_fd, fd, will close when it falls out of scope, no need to
+ // call native_handle_close.
+ native_handle_delete(native_handle);
+ }
+ return Void();
+ }
+};
} // namespace ashmemd
} // namespace android
+using android::ashmemd::AshmemAidlService;
+using android::ashmemd::AshmemHidlService;
+
int main() {
- android::ashmemd::CreateAndRegisterService();
- android::ashmemd::JoinThreadPool();
- std::abort(); // unreachable
+ configureRpcThreadpool(1, true /* callerWillJoin */);
+
+ sp<AshmemAidlService> ashmemAidlService = new AshmemAidlService();
+ android::defaultServiceManager()->addService(
+ String16("ashmem_device_service"), ashmemAidlService,
+ true /* allowIsolated */);
+
+ sp<AshmemHidlService> ashmemHidlService = new AshmemHidlService();
+ auto status = ashmemHidlService->registerAsService();
+ if (status != android::OK) {
+ LOG(FATAL) << "Unable to register ashmem hidl service: " << status;
+ }
+
+ // Create non-HW binder threadpool for Aidl Service
+ sp<android::ProcessState> ps{android::ProcessState::self()};
+ ps->startThreadPool();
+
+ joinRpcThreadpool();
+ std::abort(); // unreachable
}
diff --git a/ashmemd_hidl_client.cpp b/ashmemd_hidl_client.cpp
new file mode 100644
index 0000000..9b8219f
--- /dev/null
+++ b/ashmemd_hidl_client.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <android-base/logging.h>
+#include <android/system/ashmem/1.0/IAshmem.h>
+
+using android::sp;
+using android::hardware::hidl_handle;
+using android::system::ashmem::V1_0::IAshmem;
+
+namespace android {
+namespace ashmemd {
+
+extern "C" int openAshmemdFd() {
+ static sp<IAshmem> ashmemService = IAshmem::getService();
+ if (!ashmemService) {
+ LOG(ERROR) << "Failed to get IAshmem service.";
+ return -1;
+ }
+ int fd = -1;
+ ashmemService->open([&fd](hidl_handle handle) {
+ if (handle == nullptr || handle->numFds < 1 || handle->data[0] < 0) {
+ LOG(ERROR) << "IAshmem.open() failed";
+ } else {
+ fd = dup(handle->data[0]);
+ }
+ });
+ return fd;
+}
+
+} // namespace ashmemd
+} // namespace android
diff --git a/tests/ashmemd_hidl_client_test.cpp b/tests/ashmemd_hidl_client_test.cpp
new file mode 100644
index 0000000..e5155ce
--- /dev/null
+++ b/tests/ashmemd_hidl_client_test.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include <dlfcn.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace ashmemd {
+
+TEST(AshmemdHidlClientTest, OpenFd) {
+ const char *clientLib = "libashmemd_hidl_client.so";
+
+ void *handle = dlopen(clientLib, RTLD_NOW);
+ ASSERT_NE(handle, nullptr) << "Failed to dlopen() " << clientLib << ": " << dlerror();
+
+ auto function = (int (*)())dlsym(handle, "openAshmemdFd");
+ ASSERT_NE(function, nullptr) << "Failed to dlsym() openAshmemdFd() function: " << dlerror();
+
+ int fd = function();
+ ASSERT_GE(fd, 0) << "Failed to open /dev/ashmem";
+}
+
+} // namespace ashmemd
+} // namespace android
diff --git a/tests/ashmemd_test.cpp b/tests/ashmemd_test.cpp
index ed3cfe3..0d57b0f 100644
--- a/tests/ashmemd_test.cpp
+++ b/tests/ashmemd_test.cpp
@@ -14,71 +14,114 @@
* limitations under the License.
*/
-#include <dlfcn.h>
-
+#include <android-base/unique_fd.h>
+#include <android/ashmemd/IAshmemDeviceService.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <android/system/ashmem/1.0/IAshmem.h>
#include <binder/IServiceManager.h>
+#include <dlfcn.h>
#include <gtest/gtest.h>
+#include <hidl/ServiceManagement.h>
#include <linux/ashmem.h>
#include <sys/mman.h>
-#include <android/ashmemd/IAshmemDeviceService.h>
-
using android::IBinder;
using android::IServiceManager;
using android::String16;
using android::ashmemd::IAshmemDeviceService;
+using android::base::unique_fd;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
using android::os::ParcelFileDescriptor;
+using android::system::ashmem::V1_0::IAshmem;
namespace android {
namespace ashmemd {
-class AshmemdTest : public ::testing::Test {
+enum class Interface { AIDL, HIDL };
+
+class AshmemdTest : public ::testing::TestWithParam<Interface> {
public:
- virtual void SetUp() override {
+ void SetUp() override {
sp<IServiceManager> sm = android::defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("ashmem_device_service"));
ASSERT_NE(binder, nullptr);
- ashmemService = android::interface_cast<IAshmemDeviceService>(binder);
- ASSERT_NE(ashmemService, nullptr);
+ ashmemAidlService = android::interface_cast<IAshmemDeviceService>(binder);
+ ASSERT_NE(ashmemAidlService, nullptr);
+
+ ashmemHidlService = IAshmem::getService();
+ ASSERT_NE(ashmemHidlService, nullptr) << "failed to get ashmem hidl service";
}
- void openFd(ParcelFileDescriptor* fd) {
- auto status = ashmemService->open(fd);
- ASSERT_TRUE(status.isOk());
- ASSERT_GE(fd->get(), 0);
+ unique_fd openFd(Interface interface) {
+ switch (interface) {
+ case Interface::AIDL: {
+ ParcelFileDescriptor fd;
+ ashmemAidlService->open(&fd);
+ return unique_fd(dup(fd.get()));
+ }
+ case Interface::HIDL: {
+ unique_fd fd;
+ ashmemHidlService->open([&fd](hidl_handle handle) {
+ ASSERT_NE(handle, nullptr)
+ << "failed to open /dev/ashmem from IAshmem.";
+ fd = unique_fd(dup(handle->data[0]));
+ });
+ return fd;
+ }
+ default:
+ return unique_fd(-1);
+ }
}
- sp<IAshmemDeviceService> ashmemService;
+ sp<IAshmemDeviceService> ashmemAidlService;
+ sp<IAshmem> ashmemHidlService;
};
-TEST_F(AshmemdTest, OpenFd) {
- ParcelFileDescriptor fd;
- openFd(&fd);
+TEST_P(AshmemdTest, OpenFd) {
+ unique_fd fd = openFd(GetParam());
+ ASSERT_GE(fd.get(), 0);
}
-TEST_F(AshmemdTest, OpenMultipleFds) {
- ParcelFileDescriptor fd1;
- ParcelFileDescriptor fd2;
- openFd(&fd1);
- openFd(&fd2);
+TEST_P(AshmemdTest, OpenMultipleFds) {
+ unique_fd fd1 = openFd(GetParam());
+ unique_fd fd2 = openFd(GetParam());
ASSERT_NE(fd1.get(), fd2.get());
}
-TEST_F(AshmemdTest, MmapFd) {
- ParcelFileDescriptor pfd;
- openFd(&pfd);
- int fd = pfd.get();
+TEST_P(AshmemdTest, MmapFd) {
+ unique_fd fd = openFd(GetParam());
size_t testSize = 2097152;
- ASSERT_EQ(ioctl(fd, ASHMEM_SET_NAME, "AshmemdTest"), 0);
- ASSERT_EQ(ioctl(fd, ASHMEM_SET_SIZE, testSize), 0);
+ ASSERT_EQ(ioctl(fd.get(), ASHMEM_SET_NAME, "AshmemdTest"), 0);
+ ASSERT_EQ(ioctl(fd.get(), ASHMEM_SET_SIZE, testSize), 0);
- void* data = mmap(NULL, testSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ void* data = mmap(NULL, testSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
ASSERT_NE(data, MAP_FAILED) << "Failed to mmap() ashmem fd";
ASSERT_EQ(munmap(data, testSize), 0) << "Failed to munmap() ashmem fd";
}
+INSTANTIATE_TEST_SUITE_P(AshmemdTestSuite, AshmemdTest,
+ ::testing::Values(Interface::AIDL, Interface::HIDL));
+
+TEST(IAshmemTest, OnlyOneInstance) {
+ using ::android::hidl::manager::V1_2::IServiceManager;
+ sp<IServiceManager> manager = android::hardware::defaultServiceManager1_2();
+ ASSERT_NE(manager, nullptr) << "Unable to open defaultServiceManager";
+
+ manager->listManifestByInterface(
+ IAshmem::descriptor, [](const hidl_vec<hidl_string>& names) {
+ int instances = 0;
+ for (const auto& name : names) {
+ ASSERT_EQ(name, std::string("default"));
+ instances += 1;
+ }
+ ASSERT_EQ(instances, 1);
+ });
+}
+
TEST(LibAshmemdClientTest, OpenFd) {
void* handle = dlopen("libashmemd_client.so", RTLD_NOW);
ASSERT_NE(handle, nullptr) << "Failed to dlopen() libashmemd_client.so: " << dlerror();
diff --git a/tests/vts/Android.bp b/tests/vts/Android.bp
new file mode 100644
index 0000000..dca934d
--- /dev/null
+++ b/tests/vts/Android.bp
@@ -0,0 +1,18 @@
+// Copyright (C) 2019 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.
+//
+
+vts_config {
+ name: "VtsAshmemV1_0Test",
+}
diff --git a/tests/vts/AndroidTest.xml b/tests/vts/AndroidTest.xml
new file mode 100644
index 0000000..06db098
--- /dev/null
+++ b/tests/vts/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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 VtsAshmemV1_0Test test cases">
+ <option name="config-descriptor:metadata" key="plan" value="vts-hal" />
+ <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>
+ <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+ <option name="test-module-name" value="VtsAshmemV1_0Test"/>
+ <option name="binary-test-source" value="_32bit::DATA/nativetest/ashmemd_test/ashmemd_test"/>
+ <option name="binary-test-source" value="_64bit::DATA/nativetest64/ashmemd_test/ashmemd_test"/>
+ <option name="binary-test-type" value="hal_hidl_gtest"/>
+ <option name="binary-test-disable-framework" value="true"/>
+ <option name="test-timeout" value="5m"/>
+ </test>
+</configuration>