blob: 99a8a7a5914806da404433c12506d86ed9998a15 [file] [log] [blame]
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -08001/*
2 * Copyright (C) 2018 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 "SurfaceParcelable_test"
18
19#include <gtest/gtest.h>
20
21#include <binder/IServiceManager.h>
22#include <binder/ProcessState.h>
23#include <gui/BufferHubProducer.h>
24#include <gui/BufferQueue.h>
25#include <gui/view/Surface.h>
26#include <utils/Log.h>
27
28namespace android {
29
30static const String16 kTestServiceName = String16("SurfaceParcelableTestService");
31static const String16 kSurfaceName = String16("TEST_SURFACE");
32static const uint32_t kBufferWidth = 100;
33static const uint32_t kBufferHeight = 1;
34static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
35
36enum SurfaceParcelableTestServiceCode {
37 CREATE_BUFFER_QUEUE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
38 CREATE_BUFFER_HUB_SURFACE,
39};
40
41class SurfaceParcelableTestService : public BBinder {
42public:
43 SurfaceParcelableTestService() {
44 // BufferQueue
45 BufferQueue::createBufferQueue(&mBufferQueueProducer, &mBufferQueueConsumer);
46
47 // BufferHub
48 dvr::ProducerQueueConfigBuilder configBuilder;
49 mProducerQueue = dvr::ProducerQueue::Create(configBuilder.SetDefaultWidth(kBufferWidth)
50 .SetDefaultHeight(kBufferHeight)
51 .SetDefaultFormat(kBufferFormat)
52 .SetMetadata<DvrNativeBufferMetadata>()
53 .Build(),
54 dvr::UsagePolicy{});
55 mBufferHubProducer = BufferHubProducer::Create(mProducerQueue);
56 }
57
58 ~SurfaceParcelableTestService() = default;
59
60 virtual status_t onTransact(uint32_t code, const Parcel& /*data*/, Parcel* reply,
61 uint32_t /*flags*/ = 0) {
62 switch (code) {
63 case CREATE_BUFFER_QUEUE_SURFACE: {
64 view::Surface surfaceShim;
65 surfaceShim.name = kSurfaceName;
66 surfaceShim.graphicBufferProducer = mBufferQueueProducer;
67 return surfaceShim.writeToParcel(reply);
68 }
69 case CREATE_BUFFER_HUB_SURFACE: {
70 view::Surface surfaceShim;
71 surfaceShim.name = kSurfaceName;
72 surfaceShim.graphicBufferProducer = mBufferHubProducer;
73 return surfaceShim.writeToParcel(reply);
74 }
75 default:
76 return UNKNOWN_TRANSACTION;
77 };
78 }
79
80protected:
81 sp<IGraphicBufferProducer> mBufferQueueProducer;
82 sp<IGraphicBufferConsumer> mBufferQueueConsumer;
83
84 std::shared_ptr<dvr::ProducerQueue> mProducerQueue;
85 sp<IGraphicBufferProducer> mBufferHubProducer;
86};
87
88static int runBinderServer() {
89 ProcessState::self()->startThreadPool();
90
91 sp<IServiceManager> sm = defaultServiceManager();
92 sp<SurfaceParcelableTestService> service = new SurfaceParcelableTestService;
93 sm->addService(kTestServiceName, service, false);
94
95 ALOGI("Binder server running...");
96
97 while (true) {
98 int stat, retval;
99 retval = wait(&stat);
100 if (retval == -1 && errno == ECHILD) {
101 break;
102 }
103 }
104
105 ALOGI("Binder server exiting...");
106 return 0;
107}
108
109class SurfaceParcelableTest : public ::testing::TestWithParam<uint32_t> {
110protected:
111 virtual void SetUp() {
112 mService = defaultServiceManager()->getService(kTestServiceName);
113 if (mService == nullptr) {
114 ALOGE("Failed to connect to the test service.");
115 return;
116 }
117
118 ALOGI("Binder service is ready for client.");
119 }
120
121 status_t GetSurface(view::Surface* surfaceShim) {
122 ALOGI("...Test: %d", GetParam());
123
124 uint32_t opCode = GetParam();
125 Parcel data;
126 Parcel reply;
127 status_t error = mService->transact(opCode, data, &reply);
128 if (error != NO_ERROR) {
129 ALOGE("Failed to get surface over binder, error=%d.", error);
130 return error;
131 }
132
133 error = surfaceShim->readFromParcel(&reply);
134 if (error != NO_ERROR) {
135 ALOGE("Failed to get surface from parcel, error=%d.", error);
136 return error;
137 }
138
139 return NO_ERROR;
140 }
141
142private:
143 sp<IBinder> mService;
144};
145
146TEST_P(SurfaceParcelableTest, SendOverBinder) {
147 view::Surface surfaceShim;
148 EXPECT_EQ(GetSurface(&surfaceShim), NO_ERROR);
149 EXPECT_EQ(surfaceShim.name, kSurfaceName);
150 EXPECT_FALSE(surfaceShim.graphicBufferProducer == nullptr);
151}
152
153INSTANTIATE_TEST_CASE_P(SurfaceBackends, SurfaceParcelableTest,
154 ::testing::Values(CREATE_BUFFER_QUEUE_SURFACE, CREATE_BUFFER_HUB_SURFACE));
155
156} // namespace android
157
158int main(int argc, char** argv) {
159 pid_t pid = fork();
160 if (pid == 0) {
161 android::ProcessState::self()->startThreadPool();
162 ::testing::InitGoogleTest(&argc, argv);
163 return RUN_ALL_TESTS();
164
165 } else {
166 ALOGI("Test process pid: %d.", pid);
167 return android::runBinderServer();
168 }
169}