/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include namespace android { class SurfaceTest : public ::testing::Test { protected: SurfaceTest() { ProcessState::self()->startThreadPool(); } virtual void SetUp() { mComposerClient = new SurfaceComposerClient; ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); mSurfaceControl = mComposerClient->createSurface( String8("Test Surface"), 32, 32, PIXEL_FORMAT_RGBA_8888, 0); ASSERT_TRUE(mSurfaceControl != NULL); ASSERT_TRUE(mSurfaceControl->isValid()); SurfaceComposerClient::openGlobalTransaction(); ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7fffffff)); ASSERT_EQ(NO_ERROR, mSurfaceControl->show()); SurfaceComposerClient::closeGlobalTransaction(); mSurface = mSurfaceControl->getSurface(); ASSERT_TRUE(mSurface != NULL); } virtual void TearDown() { mComposerClient->dispose(); } sp mSurface; sp mComposerClient; sp mSurfaceControl; }; TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenVisible) { sp anw(mSurface); int result = -123; int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &result); EXPECT_EQ(NO_ERROR, err); EXPECT_EQ(1, result); } TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenPurgatorized) { mSurfaceControl.clear(); sp anw(mSurface); int result = -123; int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &result); EXPECT_EQ(NO_ERROR, err); EXPECT_EQ(1, result); } // This test probably doesn't belong here. TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) { sp anw(mSurface); // Verify the screenshot works with no protected buffers. sp producer; sp consumer; BufferQueue::createBufferQueue(&producer, &consumer); sp cpuConsumer = new CpuConsumer(consumer, 1); sp sf(ComposerService::getComposerService()); sp display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(), 64, 64, 0, 0x7fffffff, false)); // Set the PROTECTED usage bit and verify that the screenshot fails. Note // that we need to dequeue a buffer in order for it to actually get // allocated in SurfaceFlinger. ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), GRALLOC_USAGE_PROTECTED)); ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3)); ANativeWindowBuffer* buf = 0; status_t err = native_window_dequeue_buffer_and_wait(anw.get(), &buf); if (err) { // we could fail if GRALLOC_USAGE_PROTECTED is not supported. // that's okay as long as this is the reason for the failure. // try again without the GRALLOC_USAGE_PROTECTED bit. ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0)); ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(), &buf)); return; } ASSERT_EQ(NO_ERROR, anw->cancelBuffer(anw.get(), buf, -1)); for (int i = 0; i < 4; i++) { // Loop to make sure SurfaceFlinger has retired a protected buffer. ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(), &buf)); ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1)); } ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(), 64, 64, 0, 0x7fffffff, false)); } TEST_F(SurfaceTest, ConcreteTypeIsSurface) { sp anw(mSurface); int result = -123; int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result); EXPECT_EQ(NO_ERROR, err); EXPECT_EQ(NATIVE_WINDOW_SURFACE, result); } TEST_F(SurfaceTest, QueryConsumerUsage) { const int TEST_USAGE_FLAGS = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER; sp producer; sp consumer; BufferQueue::createBufferQueue(&producer, &consumer); sp c = new BufferItemConsumer(consumer, TEST_USAGE_FLAGS); sp s = new Surface(producer); sp anw(s); int flags = -1; int err = anw->query(anw.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &flags); ASSERT_EQ(NO_ERROR, err); ASSERT_EQ(TEST_USAGE_FLAGS, flags); } TEST_F(SurfaceTest, QueryDefaultBuffersDataSpace) { const android_dataspace TEST_DATASPACE = HAL_DATASPACE_SRGB; sp producer; sp consumer; BufferQueue::createBufferQueue(&producer, &consumer); sp cpuConsumer = new CpuConsumer(consumer, 1); cpuConsumer->setDefaultBufferDataSpace(TEST_DATASPACE); sp s = new Surface(producer); sp anw(s); android_dataspace dataSpace; int err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, reinterpret_cast(&dataSpace)); ASSERT_EQ(NO_ERROR, err); ASSERT_EQ(TEST_DATASPACE, dataSpace); } TEST_F(SurfaceTest, SettingGenerationNumber) { sp producer; sp consumer; BufferQueue::createBufferQueue(&producer, &consumer); sp cpuConsumer = new CpuConsumer(consumer, 1); sp surface = new Surface(producer); sp window(surface); // Allocate a buffer with a generation number of 0 ANativeWindowBuffer* buffer; int fenceFd; ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fenceFd)); ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, fenceFd)); // Detach the buffer and check its generation number sp graphicBuffer; sp fence; ASSERT_EQ(NO_ERROR, surface->detachNextBuffer(&graphicBuffer, &fence)); ASSERT_EQ(0U, graphicBuffer->getGenerationNumber()); ASSERT_EQ(NO_ERROR, surface->setGenerationNumber(1)); buffer = static_cast(graphicBuffer.get()); // This should change the generation number of the GraphicBuffer ASSERT_EQ(NO_ERROR, surface->attachBuffer(buffer)); // Check that the new generation number sticks with the buffer ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, -1)); ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fenceFd)); graphicBuffer = static_cast(buffer); ASSERT_EQ(1U, graphicBuffer->getGenerationNumber()); } }