Loading cmds/atrace/atrace.cpp +71 −38 Original line number Diff line number Diff line Loading @@ -774,22 +774,10 @@ static bool setCategoriesEnableFromFile(const char* categories_file) return ok; } // Set all the kernel tracing settings to the desired state for this trace // capture. static bool setUpTrace() static bool setUpUserspaceTracing() { bool ok = true; // Set up the tracing options. ok &= setCategoriesEnableFromFile(g_categoriesFile); ok &= setTraceOverwriteEnable(g_traceOverwrite); ok &= setTraceBufferSizeKB(g_traceBufferSizeKB); // TODO: Re-enable after stabilization //ok &= setCmdlineSize(); ok &= setClock(); ok &= setPrintTgidEnableIfPresent(true); ok &= setKernelTraceFuncs(g_kernelTraceFuncs); // Set up the tags property. uint64_t tags = 0; for (size_t i = 0; i < arraysize(k_categories); i++) { Loading Loading @@ -827,6 +815,37 @@ static bool setUpTrace() ok &= ServiceUtility::PokeServices(); } return ok; } static void cleanUpUserspaceTracing() { setTagsProperty(0); clearAppProperties(); pokeBinderServices(); if (g_tracePdx) { ServiceUtility::PokeServices(); } } // Set all the kernel tracing settings to the desired state for this trace // capture. static bool setUpKernelTracing() { bool ok = true; // Set up the tracing options. ok &= setCategoriesEnableFromFile(g_categoriesFile); ok &= setTraceOverwriteEnable(g_traceOverwrite); ok &= setTraceBufferSizeKB(g_traceBufferSizeKB); // TODO: Re-enable after stabilization //ok &= setCmdlineSize(); ok &= setClock(); ok &= setPrintTgidEnableIfPresent(true); ok &= setKernelTraceFuncs(g_kernelTraceFuncs); // Disable all the sysfs enables. This is done as a separate loop from // the enables to allow the same enable to exist in multiple categories. ok &= disableKernelTraceEvents(); Loading Loading @@ -854,20 +873,11 @@ static bool setUpTrace() } // Reset all the kernel tracing settings to their default state. static void cleanUpTrace() static void cleanUpKernelTracing() { // Disable all tracing that we're able to. disableKernelTraceEvents(); // Reset the system properties. setTagsProperty(0); clearAppProperties(); pokeBinderServices(); if (g_tracePdx) { ServiceUtility::PokeServices(); } // Set the options back to their defaults. setTraceOverwriteEnable(true); setTraceBufferSizeKB(1); Loading @@ -875,7 +885,6 @@ static void cleanUpTrace() setKernelTraceFuncs(NULL); } // Enable tracing in the kernel. static bool startTrace() { Loading Loading @@ -1107,6 +1116,7 @@ int main(int argc, char **argv) bool traceStop = true; bool traceDump = true; bool traceStream = false; bool onlyUserspace = false; if (argc == 2 && 0 == strcmp(argv[1], "--help")) { showHelp(argv[0]); Loading @@ -1125,6 +1135,7 @@ int main(int argc, char **argv) {"async_start", no_argument, 0, 0 }, {"async_stop", no_argument, 0, 0 }, {"async_dump", no_argument, 0, 0 }, {"only_userspace", no_argument, 0, 0 }, {"list_categories", no_argument, 0, 0 }, {"stream", no_argument, 0, 0 }, { 0, 0, 0, 0 } Loading Loading @@ -1197,6 +1208,8 @@ int main(int argc, char **argv) async = true; traceStart = false; traceStop = false; } else if (!strcmp(long_options[option_index].name, "only_userspace")) { onlyUserspace = true; } else if (!strcmp(long_options[option_index].name, "stream")) { traceStream = true; traceDump = false; Loading @@ -1214,6 +1227,14 @@ int main(int argc, char **argv) } } if (onlyUserspace) { if (!async || !(traceStart || traceStop)) { fprintf(stderr, "--only_userspace can only be used with " "--async_start or --async_stop\n"); exit(1); } } registerSigHandler(); if (g_initialSleepSecs > 0) { Loading @@ -1221,13 +1242,19 @@ int main(int argc, char **argv) } bool ok = true; if (traceStart) { ok &= setUpTrace(); ok &= setUpUserspaceTracing(); } if (ok && traceStart && !onlyUserspace) { ok &= setUpKernelTracing(); ok &= startTrace(); } if (ok && traceStart) { if (!traceStream) { if (!traceStream && !onlyUserspace) { printf("capturing trace..."); fflush(stdout); } Loading @@ -1237,9 +1264,12 @@ int main(int argc, char **argv) // contain entries from only one CPU can cause "begin" entries without a // matching "end" entry to show up if a task gets migrated from one CPU to // another. if (!onlyUserspace) ok = clearTrace(); if (!onlyUserspace) writeClockSyncMarker(); if (ok && !async && !traceStream) { // Sleep to allow the trace to be captured. struct timespec timeLeft; Loading @@ -1258,10 +1288,10 @@ int main(int argc, char **argv) } // Stop the trace and restore the default settings. if (traceStop) if (traceStop && !onlyUserspace) stopTrace(); if (ok && traceDump) { if (ok && traceDump && !onlyUserspace) { if (!g_traceAborted) { printf(" done\n"); fflush(stdout); Loading @@ -1288,8 +1318,11 @@ int main(int argc, char **argv) } // Reset the trace buffer size to 1. if (traceStop) cleanUpTrace(); if (traceStop) { cleanUpUserspaceTracing(); if (!onlyUserspace) cleanUpKernelTracing(); } return g_traceAborted ? 1 : 0; } headers/media_plugin/media/openmax/OMX_VideoExt.h +15 −14 Original line number Diff line number Diff line Loading @@ -427,14 +427,15 @@ typedef struct OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE { * use cases, corresponding to index OMX_IndexParamVideoAndroidImageGrid. * * OMX_VIDEO_CodingImageHEIC encoders must handle this param type. When this param is set * on the component with bEnabled set to true, nGrid* indicates the desired grid config * by the client. The component can use this as a heuristic, but is free to choose any * suitable grid configs, and the client shall always get the actual from the component * after the param is set. Encoder will receive each input image in full, and shall encode * it into tiles in row-major, top-row first, left-to-right order, and send each encoded * tile in a separate output buffer. All output buffers for the same input buffer shall * carry the same timestamp as the input buffer. If the input buffer is marked EOS, * the EOS should only appear on the last output buffer for that input buffer. * on the component with bEnabled set to true, nTileWidth, nTileHeight, nGridRows, * nGridCols indicates the desired grid config by the client. The component can use this * as a heuristic, and is free to choose any suitable grid configs. The client shall * always get the actual from the component after the param is set. Encoder will receive * each input image in full, and shall encode it into tiles in row-major, top-row first, * left-to-right order, and send each encoded tile in a separate output buffer. All output * buffers for the same input buffer shall carry the same timestamp as the input buffer. * If the input buffer is marked EOS, the EOS should only appear on the last output buffer * for that input buffer. * * OMX_VIDEO_CodingHEVC encoders might also receive this param when it's used for image * encoding, although in this case the param only serves as a hint. The encoder will Loading @@ -446,10 +447,10 @@ typedef struct OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE { * nSize : Size of the structure in bytes * nVersion : OMX specification version information * nPortIndex : Port that this structure applies to (output port for encoders) * bEnabled : Whether grid is enabled. If true, nGrid* specifies the grid * config; otherwise nGrid* shall be ignored. * nGridWidth : Width of each tile. * nGridHeight : Height of each tile. * bEnabled : Whether grid is enabled. If true, the other parameters * specifies the grid config; otherwise they shall be ignored. * nTileWidth : Width of each tile. * nTileHeight : Height of each tile. * nGridRows : Number of rows in the grid. * nGridCols : Number of cols in the grid. */ Loading @@ -458,8 +459,8 @@ typedef struct OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE { OMX_VERSIONTYPE nVersion; OMX_U32 nPortIndex; OMX_BOOL bEnabled; OMX_U32 nGridWidth; OMX_U32 nGridHeight; OMX_U32 nTileWidth; OMX_U32 nTileHeight; OMX_U32 nGridRows; OMX_U32 nGridCols; } OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE; Loading libs/gui/SurfaceComposerClient.cpp +21 −3 Original line number Diff line number Diff line Loading @@ -611,8 +611,26 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface( SurfaceControl* parent, uint32_t windowType, uint32_t ownerUid) { sp<SurfaceControl> s; createSurfaceChecked(name, w, h, format, &s, flags, parent, windowType, ownerUid); return s; } status_t SurfaceComposerClient::createSurfaceChecked( const String8& name, uint32_t w, uint32_t h, PixelFormat format, sp<SurfaceControl>* outSurface, uint32_t flags, SurfaceControl* parent, uint32_t windowType, uint32_t ownerUid) { sp<SurfaceControl> sur; status_t err = NO_ERROR; if (mStatus == NO_ERROR) { sp<IBinder> handle; sp<IBinder> parentHandle; Loading @@ -621,14 +639,14 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface( if (parent != nullptr) { parentHandle = parent->getHandle(); } status_t err = mClient->createSurface(name, w, h, format, flags, parentHandle, err = mClient->createSurface(name, w, h, format, flags, parentHandle, windowType, ownerUid, &handle, &gbp); ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); if (err == NO_ERROR) { sur = new SurfaceControl(this, handle, gbp, true /* owned */); *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */); } } return sur; return err; } status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) { Loading libs/gui/include/gui/SurfaceComposerClient.h +12 −0 Original line number Diff line number Diff line Loading @@ -115,6 +115,18 @@ public: uint32_t ownerUid = 0 // UID of the task ); status_t createSurfaceChecked( const String8& name,// name of the surface uint32_t w, // width in pixel uint32_t h, // height in pixel PixelFormat format, // pixel-format desired sp<SurfaceControl>* outSurface, uint32_t flags = 0, // usage flags SurfaceControl* parent = nullptr, // parent uint32_t windowType = 0, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.) uint32_t ownerUid = 0 // UID of the task ); //! Create a virtual display static sp<IBinder> createDisplay(const String8& displayName, bool secure); Loading libs/vr/libbufferhub/buffer_hub-test.cpp +58 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ using android::dvr::BufferHubDefs::IsBufferPosted; using android::dvr::BufferHubDefs::IsBufferAcquired; using android::dvr::BufferHubDefs::IsBufferReleased; using android::dvr::BufferProducer; using android::pdx::LocalChannelHandle; using android::pdx::LocalHandle; using android::pdx::Status; const int kWidth = 640; const int kHeight = 480; Loading Loading @@ -717,3 +719,59 @@ TEST_F(LibBufferHubTest, TestOrphanedAcquire) { // Producer should be able to gain no matter what. EXPECT_EQ(0, p->GainAsync(&meta, &fence)); } TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) { std::unique_ptr<BufferProducer> p = BufferProducer::Create( kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); std::unique_ptr<BufferConsumer> c = BufferConsumer::Import(p->CreateConsumer()); ASSERT_TRUE(p.get() != nullptr); ASSERT_TRUE(c.get() != nullptr); DvrNativeBufferMetadata metadata; LocalHandle invalid_fence; // Detach in posted state should fail. EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0); auto s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in acquired state should fail. EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in released state should fail. EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence)); EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0); s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in gained state should succeed. EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence)); s1 = p->Detach(); EXPECT_TRUE(s1); LocalChannelHandle detached_buffer = s1.take(); EXPECT_TRUE(detached_buffer.valid()); // Both producer and consumer should have hangup. EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0); auto s2 = p->GetEventMask(POLLHUP); EXPECT_TRUE(s2); EXPECT_EQ(s2.get(), POLLHUP); EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0); s2 = p->GetEventMask(POLLHUP); EXPECT_TRUE(s2); EXPECT_EQ(s2.get(), POLLHUP); auto s3 = p->CreateConsumer(); EXPECT_FALSE(s3); EXPECT_EQ(s3.error(), EOPNOTSUPP); s3 = c->CreateConsumer(); EXPECT_FALSE(s3); EXPECT_EQ(s3.error(), EOPNOTSUPP); } Loading
cmds/atrace/atrace.cpp +71 −38 Original line number Diff line number Diff line Loading @@ -774,22 +774,10 @@ static bool setCategoriesEnableFromFile(const char* categories_file) return ok; } // Set all the kernel tracing settings to the desired state for this trace // capture. static bool setUpTrace() static bool setUpUserspaceTracing() { bool ok = true; // Set up the tracing options. ok &= setCategoriesEnableFromFile(g_categoriesFile); ok &= setTraceOverwriteEnable(g_traceOverwrite); ok &= setTraceBufferSizeKB(g_traceBufferSizeKB); // TODO: Re-enable after stabilization //ok &= setCmdlineSize(); ok &= setClock(); ok &= setPrintTgidEnableIfPresent(true); ok &= setKernelTraceFuncs(g_kernelTraceFuncs); // Set up the tags property. uint64_t tags = 0; for (size_t i = 0; i < arraysize(k_categories); i++) { Loading Loading @@ -827,6 +815,37 @@ static bool setUpTrace() ok &= ServiceUtility::PokeServices(); } return ok; } static void cleanUpUserspaceTracing() { setTagsProperty(0); clearAppProperties(); pokeBinderServices(); if (g_tracePdx) { ServiceUtility::PokeServices(); } } // Set all the kernel tracing settings to the desired state for this trace // capture. static bool setUpKernelTracing() { bool ok = true; // Set up the tracing options. ok &= setCategoriesEnableFromFile(g_categoriesFile); ok &= setTraceOverwriteEnable(g_traceOverwrite); ok &= setTraceBufferSizeKB(g_traceBufferSizeKB); // TODO: Re-enable after stabilization //ok &= setCmdlineSize(); ok &= setClock(); ok &= setPrintTgidEnableIfPresent(true); ok &= setKernelTraceFuncs(g_kernelTraceFuncs); // Disable all the sysfs enables. This is done as a separate loop from // the enables to allow the same enable to exist in multiple categories. ok &= disableKernelTraceEvents(); Loading Loading @@ -854,20 +873,11 @@ static bool setUpTrace() } // Reset all the kernel tracing settings to their default state. static void cleanUpTrace() static void cleanUpKernelTracing() { // Disable all tracing that we're able to. disableKernelTraceEvents(); // Reset the system properties. setTagsProperty(0); clearAppProperties(); pokeBinderServices(); if (g_tracePdx) { ServiceUtility::PokeServices(); } // Set the options back to their defaults. setTraceOverwriteEnable(true); setTraceBufferSizeKB(1); Loading @@ -875,7 +885,6 @@ static void cleanUpTrace() setKernelTraceFuncs(NULL); } // Enable tracing in the kernel. static bool startTrace() { Loading Loading @@ -1107,6 +1116,7 @@ int main(int argc, char **argv) bool traceStop = true; bool traceDump = true; bool traceStream = false; bool onlyUserspace = false; if (argc == 2 && 0 == strcmp(argv[1], "--help")) { showHelp(argv[0]); Loading @@ -1125,6 +1135,7 @@ int main(int argc, char **argv) {"async_start", no_argument, 0, 0 }, {"async_stop", no_argument, 0, 0 }, {"async_dump", no_argument, 0, 0 }, {"only_userspace", no_argument, 0, 0 }, {"list_categories", no_argument, 0, 0 }, {"stream", no_argument, 0, 0 }, { 0, 0, 0, 0 } Loading Loading @@ -1197,6 +1208,8 @@ int main(int argc, char **argv) async = true; traceStart = false; traceStop = false; } else if (!strcmp(long_options[option_index].name, "only_userspace")) { onlyUserspace = true; } else if (!strcmp(long_options[option_index].name, "stream")) { traceStream = true; traceDump = false; Loading @@ -1214,6 +1227,14 @@ int main(int argc, char **argv) } } if (onlyUserspace) { if (!async || !(traceStart || traceStop)) { fprintf(stderr, "--only_userspace can only be used with " "--async_start or --async_stop\n"); exit(1); } } registerSigHandler(); if (g_initialSleepSecs > 0) { Loading @@ -1221,13 +1242,19 @@ int main(int argc, char **argv) } bool ok = true; if (traceStart) { ok &= setUpTrace(); ok &= setUpUserspaceTracing(); } if (ok && traceStart && !onlyUserspace) { ok &= setUpKernelTracing(); ok &= startTrace(); } if (ok && traceStart) { if (!traceStream) { if (!traceStream && !onlyUserspace) { printf("capturing trace..."); fflush(stdout); } Loading @@ -1237,9 +1264,12 @@ int main(int argc, char **argv) // contain entries from only one CPU can cause "begin" entries without a // matching "end" entry to show up if a task gets migrated from one CPU to // another. if (!onlyUserspace) ok = clearTrace(); if (!onlyUserspace) writeClockSyncMarker(); if (ok && !async && !traceStream) { // Sleep to allow the trace to be captured. struct timespec timeLeft; Loading @@ -1258,10 +1288,10 @@ int main(int argc, char **argv) } // Stop the trace and restore the default settings. if (traceStop) if (traceStop && !onlyUserspace) stopTrace(); if (ok && traceDump) { if (ok && traceDump && !onlyUserspace) { if (!g_traceAborted) { printf(" done\n"); fflush(stdout); Loading @@ -1288,8 +1318,11 @@ int main(int argc, char **argv) } // Reset the trace buffer size to 1. if (traceStop) cleanUpTrace(); if (traceStop) { cleanUpUserspaceTracing(); if (!onlyUserspace) cleanUpKernelTracing(); } return g_traceAborted ? 1 : 0; }
headers/media_plugin/media/openmax/OMX_VideoExt.h +15 −14 Original line number Diff line number Diff line Loading @@ -427,14 +427,15 @@ typedef struct OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE { * use cases, corresponding to index OMX_IndexParamVideoAndroidImageGrid. * * OMX_VIDEO_CodingImageHEIC encoders must handle this param type. When this param is set * on the component with bEnabled set to true, nGrid* indicates the desired grid config * by the client. The component can use this as a heuristic, but is free to choose any * suitable grid configs, and the client shall always get the actual from the component * after the param is set. Encoder will receive each input image in full, and shall encode * it into tiles in row-major, top-row first, left-to-right order, and send each encoded * tile in a separate output buffer. All output buffers for the same input buffer shall * carry the same timestamp as the input buffer. If the input buffer is marked EOS, * the EOS should only appear on the last output buffer for that input buffer. * on the component with bEnabled set to true, nTileWidth, nTileHeight, nGridRows, * nGridCols indicates the desired grid config by the client. The component can use this * as a heuristic, and is free to choose any suitable grid configs. The client shall * always get the actual from the component after the param is set. Encoder will receive * each input image in full, and shall encode it into tiles in row-major, top-row first, * left-to-right order, and send each encoded tile in a separate output buffer. All output * buffers for the same input buffer shall carry the same timestamp as the input buffer. * If the input buffer is marked EOS, the EOS should only appear on the last output buffer * for that input buffer. * * OMX_VIDEO_CodingHEVC encoders might also receive this param when it's used for image * encoding, although in this case the param only serves as a hint. The encoder will Loading @@ -446,10 +447,10 @@ typedef struct OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE { * nSize : Size of the structure in bytes * nVersion : OMX specification version information * nPortIndex : Port that this structure applies to (output port for encoders) * bEnabled : Whether grid is enabled. If true, nGrid* specifies the grid * config; otherwise nGrid* shall be ignored. * nGridWidth : Width of each tile. * nGridHeight : Height of each tile. * bEnabled : Whether grid is enabled. If true, the other parameters * specifies the grid config; otherwise they shall be ignored. * nTileWidth : Width of each tile. * nTileHeight : Height of each tile. * nGridRows : Number of rows in the grid. * nGridCols : Number of cols in the grid. */ Loading @@ -458,8 +459,8 @@ typedef struct OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE { OMX_VERSIONTYPE nVersion; OMX_U32 nPortIndex; OMX_BOOL bEnabled; OMX_U32 nGridWidth; OMX_U32 nGridHeight; OMX_U32 nTileWidth; OMX_U32 nTileHeight; OMX_U32 nGridRows; OMX_U32 nGridCols; } OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE; Loading
libs/gui/SurfaceComposerClient.cpp +21 −3 Original line number Diff line number Diff line Loading @@ -611,8 +611,26 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface( SurfaceControl* parent, uint32_t windowType, uint32_t ownerUid) { sp<SurfaceControl> s; createSurfaceChecked(name, w, h, format, &s, flags, parent, windowType, ownerUid); return s; } status_t SurfaceComposerClient::createSurfaceChecked( const String8& name, uint32_t w, uint32_t h, PixelFormat format, sp<SurfaceControl>* outSurface, uint32_t flags, SurfaceControl* parent, uint32_t windowType, uint32_t ownerUid) { sp<SurfaceControl> sur; status_t err = NO_ERROR; if (mStatus == NO_ERROR) { sp<IBinder> handle; sp<IBinder> parentHandle; Loading @@ -621,14 +639,14 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface( if (parent != nullptr) { parentHandle = parent->getHandle(); } status_t err = mClient->createSurface(name, w, h, format, flags, parentHandle, err = mClient->createSurface(name, w, h, format, flags, parentHandle, windowType, ownerUid, &handle, &gbp); ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); if (err == NO_ERROR) { sur = new SurfaceControl(this, handle, gbp, true /* owned */); *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */); } } return sur; return err; } status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) { Loading
libs/gui/include/gui/SurfaceComposerClient.h +12 −0 Original line number Diff line number Diff line Loading @@ -115,6 +115,18 @@ public: uint32_t ownerUid = 0 // UID of the task ); status_t createSurfaceChecked( const String8& name,// name of the surface uint32_t w, // width in pixel uint32_t h, // height in pixel PixelFormat format, // pixel-format desired sp<SurfaceControl>* outSurface, uint32_t flags = 0, // usage flags SurfaceControl* parent = nullptr, // parent uint32_t windowType = 0, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.) uint32_t ownerUid = 0 // UID of the task ); //! Create a virtual display static sp<IBinder> createDisplay(const String8& displayName, bool secure); Loading
libs/vr/libbufferhub/buffer_hub-test.cpp +58 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ using android::dvr::BufferHubDefs::IsBufferPosted; using android::dvr::BufferHubDefs::IsBufferAcquired; using android::dvr::BufferHubDefs::IsBufferReleased; using android::dvr::BufferProducer; using android::pdx::LocalChannelHandle; using android::pdx::LocalHandle; using android::pdx::Status; const int kWidth = 640; const int kHeight = 480; Loading Loading @@ -717,3 +719,59 @@ TEST_F(LibBufferHubTest, TestOrphanedAcquire) { // Producer should be able to gain no matter what. EXPECT_EQ(0, p->GainAsync(&meta, &fence)); } TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) { std::unique_ptr<BufferProducer> p = BufferProducer::Create( kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); std::unique_ptr<BufferConsumer> c = BufferConsumer::Import(p->CreateConsumer()); ASSERT_TRUE(p.get() != nullptr); ASSERT_TRUE(c.get() != nullptr); DvrNativeBufferMetadata metadata; LocalHandle invalid_fence; // Detach in posted state should fail. EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0); auto s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in acquired state should fail. EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in released state should fail. EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence)); EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0); s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in gained state should succeed. EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence)); s1 = p->Detach(); EXPECT_TRUE(s1); LocalChannelHandle detached_buffer = s1.take(); EXPECT_TRUE(detached_buffer.valid()); // Both producer and consumer should have hangup. EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0); auto s2 = p->GetEventMask(POLLHUP); EXPECT_TRUE(s2); EXPECT_EQ(s2.get(), POLLHUP); EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0); s2 = p->GetEventMask(POLLHUP); EXPECT_TRUE(s2); EXPECT_EQ(s2.get(), POLLHUP); auto s3 = p->CreateConsumer(); EXPECT_FALSE(s3); EXPECT_EQ(s3.error(), EOPNOTSUPP); s3 = c->CreateConsumer(); EXPECT_FALSE(s3); EXPECT_EQ(s3.error(), EOPNOTSUPP); }