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