1/* 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 .Build(), 53 dvr::UsagePolicy{}); 54 mBufferHubProducer = BufferHubProducer::Create(mProducerQueue); 55 } 56 57 ~SurfaceParcelableTestService() = default; 58 59 virtual status_t onTransact(uint32_t code, const Parcel& /*data*/, Parcel* reply, 60 uint32_t /*flags*/ = 0) { 61 switch (code) { 62 case CREATE_BUFFER_QUEUE_SURFACE: { 63 view::Surface surfaceShim; 64 surfaceShim.name = kSurfaceName; 65 surfaceShim.graphicBufferProducer = mBufferQueueProducer; 66 return surfaceShim.writeToParcel(reply); 67 } 68 case CREATE_BUFFER_HUB_SURFACE: { 69 view::Surface surfaceShim; 70 surfaceShim.name = kSurfaceName; 71 surfaceShim.graphicBufferProducer = mBufferHubProducer; 72 return surfaceShim.writeToParcel(reply); 73 } 74 default: 75 return UNKNOWN_TRANSACTION; 76 }; 77 } 78 79protected: 80 sp<IGraphicBufferProducer> mBufferQueueProducer; 81 sp<IGraphicBufferConsumer> mBufferQueueConsumer; 82 83 std::shared_ptr<dvr::ProducerQueue> mProducerQueue; 84 sp<IGraphicBufferProducer> mBufferHubProducer; 85}; 86 87static int runBinderServer() { 88 ProcessState::self()->startThreadPool(); 89 90 sp<IServiceManager> sm = defaultServiceManager(); 91 sp<SurfaceParcelableTestService> service = new SurfaceParcelableTestService; 92 sm->addService(kTestServiceName, service, false); 93 94 ALOGI("Binder server running..."); 95 96 while (true) { 97 int stat, retval; 98 retval = wait(&stat); 99 if (retval == -1 && errno == ECHILD) { 100 break; 101 } 102 } 103 104 ALOGI("Binder server exiting..."); 105 return 0; 106} 107 108class SurfaceParcelableTest : public ::testing::TestWithParam<uint32_t> { 109protected: 110 virtual void SetUp() { 111 mService = defaultServiceManager()->getService(kTestServiceName); 112 if (mService == nullptr) { 113 ALOGE("Failed to connect to the test service."); 114 return; 115 } 116 117 ALOGI("Binder service is ready for client."); 118 } 119 120 status_t GetSurface(view::Surface* surfaceShim) { 121 ALOGI("...Test: %d", GetParam()); 122 123 uint32_t opCode = GetParam(); 124 Parcel data; 125 Parcel reply; 126 status_t error = mService->transact(opCode, data, &reply); 127 if (error != NO_ERROR) { 128 ALOGE("Failed to get surface over binder, error=%d.", error); 129 return error; 130 } 131 132 error = surfaceShim->readFromParcel(&reply); 133 if (error != NO_ERROR) { 134 ALOGE("Failed to get surface from parcel, error=%d.", error); 135 return error; 136 } 137 138 return NO_ERROR; 139 } 140 141private: 142 sp<IBinder> mService; 143}; 144 145TEST_P(SurfaceParcelableTest, SendOverBinder) { 146 view::Surface surfaceShim; 147 EXPECT_EQ(GetSurface(&surfaceShim), NO_ERROR); 148 EXPECT_EQ(surfaceShim.name, kSurfaceName); 149 EXPECT_FALSE(surfaceShim.graphicBufferProducer == nullptr); 150} 151 152INSTANTIATE_TEST_CASE_P(SurfaceBackends, SurfaceParcelableTest, 153 ::testing::Values(CREATE_BUFFER_QUEUE_SURFACE, CREATE_BUFFER_HUB_SURFACE)); 154 155} // namespace android 156 157int main(int argc, char** argv) { 158 pid_t pid = fork(); 159 if (pid == 0) { 160 android::ProcessState::self()->startThreadPool(); 161 ::testing::InitGoogleTest(&argc, argv); 162 return RUN_ALL_TESTS(); 163 164 } else { 165 ALOGI("Test process pid: %d.", pid); 166 return android::runBinderServer(); 167 } 168} 169