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>