summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTri Vo <trong@google.com>2019-02-05 13:45:17 -0800
committerandroid-build-merger <android-build-merger@google.com>2019-02-05 13:45:17 -0800
commitdc048f17154e42bb66d1efdecf96315938b8a1d4 (patch)
tree2c4e7b3f0657b43e1b61c9b3e3569f405e4a101a
parent9759c00041f21d4a4c5696f0be1f1b21da4faffe (diff)
parentdf205799f399528a822fefce5ae1e6e46cea5410 (diff)
downloadplatform_system_ashmemd-dc048f17154e42bb66d1efdecf96315938b8a1d4.tar.gz
platform_system_ashmemd-dc048f17154e42bb66d1efdecf96315938b8a1d4.tar.bz2
platform_system_ashmemd-dc048f17154e42bb66d1efdecf96315938b8a1d4.zip
ashmemd: daemon that provides /dev/ashmem fds
am: df205799f3 Change-Id: I45720cf5fd010b0ff654b4cad97f8394a8049e22
-rw-r--r--Android.bp60
-rw-r--r--OWNERS1
-rw-r--r--aidl/android/ashmemd/IAshmemDeviceService.aidl23
-rw-r--r--ashmemd.cpp59
-rw-r--r--ashmemd.rc4
-rw-r--r--ashmemd_client.cpp49
-rw-r--r--tests/ashmemd_test.cpp94
7 files changed, 290 insertions, 0 deletions
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..37699f8
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,60 @@
+// Copyright (C) 2018 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.
+
+aidl_interface {
+ name: "ashmemd_aidl_interface",
+ local_include_dir: "aidl",
+ srcs: [
+ "aidl/android/ashmemd/IAshmemDeviceService.aidl",
+ ],
+}
+
+cc_defaults {
+ name: "ashmemd_defaults",
+ shared_libs: [
+ "ashmemd_aidl_interface-cpp",
+ "libbase",
+ "libbinder",
+ "libutils",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+}
+
+cc_binary {
+ name: "ashmemd",
+ defaults: ["ashmemd_defaults"],
+ srcs: ["ashmemd.cpp"],
+ init_rc: ["ashmemd.rc"],
+}
+
+// This library is used to communicate with ashmemd using dlopen/dlsym. We do
+// this to avoid shared library dependecy cycles.
+cc_library {
+ name: "libashmemd_client",
+ defaults: ["ashmemd_defaults"],
+ srcs: ["ashmemd_client.cpp"],
+ cflags: [
+ "-Wexit-time-destructors",
+ "-fno-c++-static-destructors",
+ ],
+}
+
+cc_test {
+ name: "ashmemd_test",
+ defaults: ["ashmemd_defaults"],
+ srcs: ["tests/ashmemd_test.cpp"],
+}
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..5f8199f
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1 @@
+trong@google.com
diff --git a/aidl/android/ashmemd/IAshmemDeviceService.aidl b/aidl/android/ashmemd/IAshmemDeviceService.aidl
new file mode 100644
index 0000000..283db13
--- /dev/null
+++ b/aidl/android/ashmemd/IAshmemDeviceService.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+package android.ashmemd;
+
+/** {@hide} */
+interface IAshmemDeviceService {
+ /* Opens a file descriptor to /dev/ashmem */
+ ParcelFileDescriptor open();
+}
diff --git a/ashmemd.cpp b/ashmemd.cpp
new file mode 100644
index 0000000..9d12ed3
--- /dev/null
+++ b/ashmemd.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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/unique_fd.h>
+#include <binder/BinderService.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <binder/Status.h>
+#include <utils/String16.h>
+
+#include <android/ashmemd/BnAshmemDeviceService.h>
+
+using android::String16;
+using android::base::unique_fd;
+
+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();
+ }
+};
+
+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
+}
+
+} // namespace ashmemd
+} // namespace android
+
+int main() {
+ android::ashmemd::CreateAndRegisterService();
+ android::ashmemd::JoinThreadPool();
+ std::abort(); // unreachable
+}
diff --git a/ashmemd.rc b/ashmemd.rc
new file mode 100644
index 0000000..ee16d95
--- /dev/null
+++ b/ashmemd.rc
@@ -0,0 +1,4 @@
+service ashmemd /system/bin/ashmemd
+ class core
+ user nobody
+ group nobody
diff --git a/ashmemd_client.cpp b/ashmemd_client.cpp
new file mode 100644
index 0000000..1984358
--- /dev/null
+++ b/ashmemd_client.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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/ashmemd/IAshmemDeviceService.h>
+#include <binder/IServiceManager.h>
+
+using android::IBinder;
+using android::IServiceManager;
+using android::String16;
+using android::ashmemd::IAshmemDeviceService;
+using android::os::ParcelFileDescriptor;
+
+namespace android {
+namespace ashmemd {
+
+sp<IAshmemDeviceService> getAshmemService() {
+ sp<IServiceManager> sm = android::defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("ashmem_device_service"));
+ return interface_cast<IAshmemDeviceService>(binder);
+}
+
+extern "C" int openAshmemdFd() {
+ static sp<IAshmemDeviceService> ashmemService = getAshmemService();
+ if (!ashmemService) return -1;
+
+ ParcelFileDescriptor fd;
+ auto status = ashmemService->open(&fd);
+ if (!status.isOk()) return -1;
+
+ // unique_fd is the underlying type of ParcelFileDescriptor, i.e. fd is
+ // closed when it falls out of scope, so we make a dup.
+ return dup(fd.get());
+}
+
+} // namespace ashmemd
+} // namespace android
diff --git a/tests/ashmemd_test.cpp b/tests/ashmemd_test.cpp
new file mode 100644
index 0000000..ed3cfe3
--- /dev/null
+++ b/tests/ashmemd_test.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 <binder/IServiceManager.h>
+#include <gtest/gtest.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::os::ParcelFileDescriptor;
+
+namespace android {
+namespace ashmemd {
+
+class AshmemdTest : public ::testing::Test {
+ public:
+ virtual 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);
+ }
+
+ void openFd(ParcelFileDescriptor* fd) {
+ auto status = ashmemService->open(fd);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_GE(fd->get(), 0);
+ }
+
+ sp<IAshmemDeviceService> ashmemService;
+};
+
+TEST_F(AshmemdTest, OpenFd) {
+ ParcelFileDescriptor fd;
+ openFd(&fd);
+}
+
+TEST_F(AshmemdTest, OpenMultipleFds) {
+ ParcelFileDescriptor fd1;
+ ParcelFileDescriptor fd2;
+ openFd(&fd1);
+ openFd(&fd2);
+ ASSERT_NE(fd1.get(), fd2.get());
+}
+
+TEST_F(AshmemdTest, MmapFd) {
+ ParcelFileDescriptor pfd;
+ openFd(&pfd);
+ int fd = pfd.get();
+ size_t testSize = 2097152;
+
+ ASSERT_EQ(ioctl(fd, ASHMEM_SET_NAME, "AshmemdTest"), 0);
+ ASSERT_EQ(ioctl(fd, ASHMEM_SET_SIZE, testSize), 0);
+
+ void* data = mmap(NULL, testSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ ASSERT_NE(data, MAP_FAILED) << "Failed to mmap() ashmem fd";
+ ASSERT_EQ(munmap(data, testSize), 0) << "Failed to munmap() ashmem fd";
+}
+
+TEST(LibAshmemdClientTest, OpenFd) {
+ void* handle = dlopen("libashmemd_client.so", RTLD_NOW);
+ ASSERT_NE(handle, nullptr) << "Failed to dlopen() libashmemd_client.so: " << 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