1 /*
2 * Copyright (C) 2019 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 "GraphicBufferOverBinder_test"
18
19 #include <binder/IServiceManager.h>
20 #include <binder/Parcel.h>
21 #include <binder/ProcessState.h>
22 #include <gtest/gtest.h>
23 #include <gui/BufferQueue.h>
24 #include <gui/IGraphicBufferConsumer.h>
25 #include <gui/IGraphicBufferProducer.h>
26 #include <ui/GraphicBuffer.h>
27 #include <utils/Log.h>
28
29 namespace android {
30
31 constexpr uint32_t kTestWidth = 1024;
32 constexpr uint32_t kTestHeight = 1;
33 constexpr uint32_t kTestFormat = HAL_PIXEL_FORMAT_BLOB;
34 constexpr uint32_t kTestLayerCount = 1;
35 constexpr uint64_t kTestUsage = GraphicBuffer::USAGE_SW_WRITE_OFTEN;
36 static const String16 kTestServiceName = String16("GraphicBufferOverBinderTestService");
37 enum GraphicBufferOverBinderTestServiceCode {
38 GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
39 };
40
41 class GraphicBufferOverBinderTestService : public BBinder {
42 public:
GraphicBufferOverBinderTestService()43 GraphicBufferOverBinderTestService() {
44 // GraphicBuffer
45 mGraphicBuffer = new GraphicBuffer(kTestWidth, kTestHeight, kTestFormat, kTestLayerCount,
46 kTestUsage);
47 }
48
49 ~GraphicBufferOverBinderTestService() = default;
50
onTransact(uint32_t code,const Parcel &,Parcel * reply,uint32_t=0)51 virtual status_t onTransact(uint32_t code, const Parcel& /*data*/, Parcel* reply,
52 uint32_t /*flags*/ = 0) {
53 switch (code) {
54 case GRAPHIC_BUFFER: {
55 return reply->write(*mGraphicBuffer);
56 }
57 default:
58 return UNKNOWN_TRANSACTION;
59 };
60 }
61
62 protected:
63 sp<GraphicBuffer> mGraphicBuffer;
64 };
65
runBinderServer()66 static int runBinderServer() {
67 ProcessState::self()->startThreadPool();
68
69 sp<IServiceManager> sm = defaultServiceManager();
70 sp<GraphicBufferOverBinderTestService> service = new GraphicBufferOverBinderTestService;
71 sm->addService(kTestServiceName, service, false);
72
73 ALOGI("Binder server running...");
74
75 while (true) {
76 int stat, retval;
77 retval = wait(&stat);
78 if (retval == -1 && errno == ECHILD) {
79 break;
80 }
81 }
82
83 ALOGI("Binder server exiting...");
84 return 0;
85 }
86
87 class GraphicBufferOverBinderTest : public ::testing::TestWithParam<uint32_t> {
88 protected:
SetUp()89 virtual void SetUp() {
90 mService = defaultServiceManager()->getService(kTestServiceName);
91 if (mService == nullptr) {
92 ALOGE("Failed to connect to the test service.");
93 return;
94 }
95
96 ALOGI("Binder service is ready for client.");
97 }
98
GetGraphicBuffer(sp<GraphicBuffer> * outBuf,uint32_t opCode)99 status_t GetGraphicBuffer(sp<GraphicBuffer>* outBuf, uint32_t opCode) {
100 Parcel data;
101 Parcel reply;
102 status_t error = mService->transact(opCode, data, &reply);
103 if (error != NO_ERROR) {
104 ALOGE("Failed to get graphic buffer over binder, error=%d.", error);
105 return error;
106 }
107
108 *outBuf = new GraphicBuffer();
109 return reply.read(**outBuf);
110 }
111
112 private:
113 sp<IBinder> mService;
114 };
115
TEST_F(GraphicBufferOverBinderTest,SendGraphicBufferOverBinder)116 TEST_F(GraphicBufferOverBinderTest, SendGraphicBufferOverBinder) {
117 sp<GraphicBuffer> gb;
118 EXPECT_EQ(GetGraphicBuffer(&gb, GRAPHIC_BUFFER), OK);
119 EXPECT_NE(gb, nullptr);
120 void* vaddr;
121 EXPECT_EQ(gb->lock(kTestUsage, &vaddr), OK);
122 EXPECT_EQ(gb->unlock(), OK);
123 }
124
125 } // namespace android
126
main(int argc,char ** argv)127 int main(int argc, char** argv) {
128 pid_t pid = fork();
129 if (pid == 0) {
130 android::ProcessState::self()->startThreadPool();
131 ::testing::InitGoogleTest(&argc, argv);
132 return RUN_ALL_TESTS();
133
134 } else {
135 ALOGI("Test process pid: %d.", pid);
136 return android::runBinderServer();
137 }
138 }
139