1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "VtsHalCarDisplayTest"
18
19 #include <aidl/Gtest.h>
20 #include <aidl/Vintf.h>
21 #include <aidl/android/frameworks/automotive/display/DisplayDesc.h>
22 #include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
23 #include <aidlcommonsupport/NativeHandle.h>
24 #include <android-base/logging.h>
25 #include <android/binder_ibinder.h>
26 #include <android/binder_manager.h>
27 #include <android/binder_process.h>
28 #include <android/binder_status.h>
29 #include <bufferqueueconverter/BufferQueueConverter.h>
30 #include <hidl/ServiceManagement.h>
31
32 namespace {
33
34 using ::aidl::android::frameworks::automotive::display::DisplayDesc;
35 using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
36 using ::aidl::android::hardware::common::NativeHandle;
37
convertNativeHandleToHGBP(const NativeHandle & aidlHandle)38 android::sp<HGraphicBufferProducer> convertNativeHandleToHGBP(const NativeHandle& aidlHandle) {
39 native_handle_t* handle = ::android::dupFromAidl(aidlHandle);
40 if (handle == nullptr || handle->numFds != 0 ||
41 handle->numInts < std::ceil(sizeof(size_t) / sizeof(int))) {
42 LOG(ERROR) << "Invalid native handle";
43 return nullptr;
44 }
45 android::hardware::hidl_vec<uint8_t> halToken;
46 halToken.setToExternal(reinterpret_cast<uint8_t*>(const_cast<int*>(&(handle->data[1]))),
47 handle->data[0]);
48 android::sp<HGraphicBufferProducer> hgbp =
49 HGraphicBufferProducer::castFrom(::android::retrieveHalInterface(halToken));
50 return std::move(hgbp);
51 }
52
53 } // namespace
54
55 // The main test class for Automotive Display Service
56 class CarDisplayAidlTest : public ::testing::TestWithParam<std::string> {
57 public:
SetUp()58 void SetUp() override {
59 // Make sure we can connect to the service
60 std::string serviceName = GetParam();
61 AIBinder* binder = AServiceManager_waitForService(serviceName.data());
62 ASSERT_NE(binder, nullptr);
63 mDisplayProxy = ICarDisplayProxy::fromBinder(ndk::SpAIBinder(binder));
64 ASSERT_NE(mDisplayProxy, nullptr);
65 LOG(INFO) << "Test target service: " << serviceName;
66
67 loadDisplayList();
68 }
69
TearDown()70 void TearDown() override {
71 mDisplayProxy.reset();
72 mDisplayIds.clear();
73 }
74
75 protected:
loadDisplayList()76 void loadDisplayList() {
77 ASSERT_TRUE(mDisplayProxy->getDisplayIdList(&mDisplayIds).isOk());
78 LOG(INFO) << "We have " << mDisplayIds.size() << " displays.";
79 }
80
81 std::shared_ptr<ICarDisplayProxy> mDisplayProxy;
82 std::vector<int64_t> mDisplayIds;
83 };
84
TEST_P(CarDisplayAidlTest,getIGBPObject)85 TEST_P(CarDisplayAidlTest, getIGBPObject) {
86 LOG(INFO) << "Test getHGraphicBufferProducer method";
87
88 if (!android::hardware::isHidlSupported()) {
89 // This test assumes that HIDL is supported on the target device.
90 GTEST_SKIP() << "Assumption failed; HIDL is not supported.";
91 }
92
93 for (const auto& id : mDisplayIds) {
94 // Get a display info.
95 DisplayDesc desc;
96 ASSERT_TRUE(mDisplayProxy->getDisplayInfo(id, &desc).isOk());
97
98 // Get a HGBP object as a native handle object.
99 NativeHandle handle;
100 ASSERT_TRUE(mDisplayProxy->getHGraphicBufferProducer(id, &handle).isOk());
101
102 // Convert a native handle object into a HGBP object.
103 android::sp<android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer>
104 gfxBufferProducer = convertNativeHandleToHGBP(handle);
105 ASSERT_NE(gfxBufferProducer, nullptr);
106
107 // Create a Surface object.
108 android::SurfaceHolderUniquePtr surfaceHolder = getSurfaceFromHGBP(gfxBufferProducer);
109 ASSERT_NE(surfaceHolder, nullptr);
110
111 // Verify the size.
112 ANativeWindow* nativeWindow = getNativeWindow(surfaceHolder.get());
113 ASSERT_EQ(desc.width, ANativeWindow_getWidth(nativeWindow));
114 ASSERT_EQ(desc.height, ANativeWindow_getHeight(nativeWindow));
115 }
116 }
117
TEST_P(CarDisplayAidlTest,showWindow)118 TEST_P(CarDisplayAidlTest, showWindow) {
119 LOG(INFO) << "Test showWindow method";
120 for (const auto& id : mDisplayIds) {
121 // Get a Surface object to register a target device.
122 aidl::android::view::Surface shimSurface;
123 ASSERT_TRUE(mDisplayProxy->getSurface(id, &shimSurface).isOk());
124
125 ASSERT_TRUE(mDisplayProxy->showWindow(id).isOk());
126 }
127 }
128
TEST_P(CarDisplayAidlTest,hideWindow)129 TEST_P(CarDisplayAidlTest, hideWindow) {
130 LOG(INFO) << "Test hideWindow method";
131
132 for (const auto& id : mDisplayIds) {
133 // Get a Surface object to register a target device.
134 aidl::android::view::Surface shimSurface;
135 ASSERT_TRUE(mDisplayProxy->getSurface(id, &shimSurface).isOk());
136
137 ASSERT_TRUE(mDisplayProxy->hideWindow(id).isOk());
138 }
139 }
140
TEST_P(CarDisplayAidlTest,getSurface)141 TEST_P(CarDisplayAidlTest, getSurface) {
142 LOG(INFO) << "Test getSurface method";
143
144 for (const auto& id : mDisplayIds) {
145 // Get a display info.
146 DisplayDesc desc;
147 ASSERT_TRUE(mDisplayProxy->getDisplayInfo(id, &desc).isOk());
148
149 // Get a Surface object.
150 aidl::android::view::Surface shimSurface;
151 ASSERT_TRUE(mDisplayProxy->getSurface(id, &shimSurface).isOk());
152
153 // Verify the size.
154 ANativeWindow* nativeWindow = shimSurface.get();
155 ASSERT_EQ(desc.width, ANativeWindow_getWidth(nativeWindow));
156 ASSERT_EQ(desc.height, ANativeWindow_getHeight(nativeWindow));
157 }
158 }
159
160 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CarDisplayAidlTest);
161 INSTANTIATE_TEST_SUITE_P(
162 PerInstance, CarDisplayAidlTest,
163 testing::ValuesIn(android::getAidlHalInstanceNames(ICarDisplayProxy::descriptor)),
164 android::PrintInstanceNameToString);
165
main(int argc,char ** argv)166 int main(int argc, char** argv) {
167 ::testing::InitGoogleTest(&argc, argv);
168 ABinderProcess_setThreadPoolMaxThreadCount(/* numThreads= */ 1);
169 ABinderProcess_startThreadPool();
170 return RUN_ALL_TESTS();
171 }
172