diff options
23 files changed, 384 insertions, 108 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index cbb74b34f2..afa0b4de70 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -2864,31 +2864,23 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, // duration is logged into MYLOG instead. PrintHeader(); - // TODO(b/158737089) reduce code repetition in if branches + bool is_dumpstate_restricted = options_->telephony_only + || options_->wifi_only + || options_->limited_only; + if (!is_dumpstate_restricted) { + // Invoke critical dumpsys first to preserve system state, before doing anything else. + RunDumpsysCritical(); + } + MaybeTakeEarlyScreenshot(); + onUiIntensiveBugreportDumpsFinished(calling_uid); + MaybeCheckUserConsent(calling_uid, calling_package); if (options_->telephony_only) { - MaybeTakeEarlyScreenshot(); - onUiIntensiveBugreportDumpsFinished(calling_uid); - MaybeCheckUserConsent(calling_uid, calling_package); DumpstateTelephonyOnly(calling_package); } else if (options_->wifi_only) { - MaybeTakeEarlyScreenshot(); - onUiIntensiveBugreportDumpsFinished(calling_uid); - MaybeCheckUserConsent(calling_uid, calling_package); DumpstateWifiOnly(); } else if (options_->limited_only) { - MaybeTakeEarlyScreenshot(); - onUiIntensiveBugreportDumpsFinished(calling_uid); - MaybeCheckUserConsent(calling_uid, calling_package); DumpstateLimitedOnly(); } else { - // Invoke critical dumpsys first to preserve system state, before doing anything else. - RunDumpsysCritical(); - - // Take screenshot and get consent only after critical dumpsys has finished. - MaybeTakeEarlyScreenshot(); - onUiIntensiveBugreportDumpsFinished(calling_uid); - MaybeCheckUserConsent(calling_uid, calling_package); - // Dump state for the default case. This also drops root. RunStatus s = DumpstateDefaultAfterCritical(); if (s != RunStatus::OK) { diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index b821578dd3..818804ac14 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -398,6 +398,10 @@ static bool prepare_app_profile_dir(const std::string& packageName, int32_t appI PLOG(ERROR) << "Failed to prepare " << profile_dir; return false; } + if (selinux_android_restorecon(profile_dir.c_str(), 0)) { + PLOG(ERROR) << "Failed to restorecon " << profile_dir; + return false; + } const std::string ref_profile_path = create_primary_reference_profile_package_dir_path(packageName); diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp index 594880ac60..65fc46ecaf 100644 --- a/cmds/installd/dexopt.cpp +++ b/cmds/installd/dexopt.cpp @@ -1818,10 +1818,13 @@ int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* ins pid_t pid = fork(); if (pid == 0) { + // Need to set schedpolicy before dropping privileges + // for cgroup migration. See details at b/175178520. + SetDex2OatScheduling(boot_complete); + /* child -- drop privileges before continuing */ drop_capabilities(uid); - SetDex2OatScheduling(boot_complete); if (flock(out_oat.fd(), LOCK_EX | LOCK_NB) != 0) { PLOG(ERROR) << "flock(" << out_oat.path() << ") failed"; _exit(DexoptReturnCodes::kFlock); diff --git a/data/etc/android.software.opengles.deqp.level-2020-03-01.xml b/data/etc/android.software.opengles.deqp.level-2020-03-01.xml new file mode 100644 index 0000000000..f11e0bb6e7 --- /dev/null +++ b/data/etc/android.software.opengles.deqp.level-2020-03-01.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 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. +--> + +<!-- This is the standard feature indicating that the device passes OpenGL ES + dEQP tests associated with date 2020-03-01 (0x07E40301). --> +<permissions> + <feature name="android.software.opengles.deqp.level" version="132383489" /> +</permissions> diff --git a/data/etc/android.software.opengles.deqp.level-2021-03-01.xml b/data/etc/android.software.opengles.deqp.level-2021-03-01.xml new file mode 100644 index 0000000000..b60697d619 --- /dev/null +++ b/data/etc/android.software.opengles.deqp.level-2021-03-01.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 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. +--> + +<!-- This is the standard feature indicating that the device passes OpenGL ES + dEQP tests associated with date 2021-03-01 (0x07E50301). --> +<permissions> + <feature name="android.software.opengles.deqp.level" version="132449025" /> +</permissions> diff --git a/data/etc/android.software.vulkan.deqp.level-2019-03-01.xml b/data/etc/android.software.vulkan.deqp.level-2019-03-01.xml index 9c67d4abb7..d3ad45aa4e 100644 --- a/data/etc/android.software.vulkan.deqp.level-2019-03-01.xml +++ b/data/etc/android.software.vulkan.deqp.level-2019-03-01.xml @@ -14,7 +14,7 @@ limitations under the License. --> -<!-- This is the standard feature indicating that the device passes Vulkan deQP +<!-- This is the standard feature indicating that the device passes Vulkan dEQP tests associated with date 2019-03-01 (0x07E30301). --> <permissions> <feature name="android.software.vulkan.deqp.level" version="132317953" /> diff --git a/data/etc/android.software.vulkan.deqp.level-2020-03-01.xml b/data/etc/android.software.vulkan.deqp.level-2020-03-01.xml index 19b269b607..84ba389459 100644 --- a/data/etc/android.software.vulkan.deqp.level-2020-03-01.xml +++ b/data/etc/android.software.vulkan.deqp.level-2020-03-01.xml @@ -14,7 +14,7 @@ limitations under the License. --> -<!-- This is the standard feature indicating that the device passes Vulkan deQP +<!-- This is the standard feature indicating that the device passes Vulkan dEQP tests associated with date 2020-03-01 (0x07E40301). --> <permissions> <feature name="android.software.vulkan.deqp.level" version="132383489" /> diff --git a/data/etc/android.software.vulkan.deqp.level-2021-03-01.xml b/data/etc/android.software.vulkan.deqp.level-2021-03-01.xml new file mode 100644 index 0000000000..ae26269b7d --- /dev/null +++ b/data/etc/android.software.vulkan.deqp.level-2021-03-01.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 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. +--> + +<!-- This is the standard feature indicating that the device passes Vulkan dEQP + tests associated with date 2021-03-01 (0x07E50301). --> +<permissions> + <feature name="android.software.vulkan.deqp.level" version="132449025" /> +</permissions> diff --git a/include/input/DisplayViewport.h b/include/input/DisplayViewport.h index b90d57eb25..5e40ca7ece 100644 --- a/include/input/DisplayViewport.h +++ b/include/input/DisplayViewport.h @@ -119,7 +119,7 @@ struct DisplayViewport { physicalBottom = height; deviceWidth = width; deviceHeight = height; - isActive = false; + isActive = true; uniqueId.clear(); physicalPort = std::nullopt; type = ViewportType::INTERNAL; diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index d4c7acfdfd..7d01e0b1c3 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -1248,10 +1248,22 @@ status_t IPCThreadState::executeCommand(int32_t cmd) constexpr uint32_t kForwardReplyFlags = TF_CLEAR_BUF; sendReply(reply, (tr.flags & kForwardReplyFlags)); } else { - if (error != OK || reply.dataSize() != 0) { - alog << "oneway function results will be dropped but finished with status " - << statusToString(error) - << " and parcel size " << reply.dataSize() << endl; + if (error != OK) { + alog << "oneway function results for code " << tr.code + << " on binder at " + << reinterpret_cast<void*>(tr.target.ptr) + << " will be dropped but finished with status " + << statusToString(error); + + // ideally we could log this even when error == OK, but it + // causes too much logspam because some manually-written + // interfaces have clients that call methods which always + // write results, sometimes as oneway methods. + if (reply.dataSize() != 0) { + alog << " and reply parcel size " << reply.dataSize(); + } + + alog << endl; } LOG_ONEWAY("NOT sending reply to %d!", mCallingPid); } diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp index 0f7d15989a..a5261e59bf 100644 --- a/libs/binder/tests/binderLibTest.cpp +++ b/libs/binder/tests/binderLibTest.cpp @@ -404,6 +404,13 @@ TEST_F(BinderLibTest, NopTransaction) { EXPECT_EQ(NO_ERROR, ret); } +TEST_F(BinderLibTest, NopTransactionOneway) { + status_t ret; + Parcel data, reply; + ret = m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply, TF_ONE_WAY); + EXPECT_EQ(NO_ERROR, ret); +} + TEST_F(BinderLibTest, NopTransactionClear) { status_t ret; Parcel data, reply; @@ -1182,9 +1189,6 @@ class BinderLibTestService : public BBinder virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) { - //printf("%s: code %d\n", __func__, code); - (void)flags; - if (getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) { return PERMISSION_DENIED; } @@ -1258,8 +1262,12 @@ class BinderLibTestService : public BBinder return NO_ERROR; case BINDER_LIB_TEST_NOP_TRANSACTION_WAIT: usleep(5000); - return NO_ERROR; + [[fallthrough]]; case BINDER_LIB_TEST_NOP_TRANSACTION: + // oneway error codes should be ignored + if (flags & TF_ONE_WAY) { + return UNKNOWN_ERROR; + } return NO_ERROR; case BINDER_LIB_TEST_DELAYED_CALL_BACK: { // Note: this transaction is only designed for use with a diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index b9ab5613c6..bf0386f006 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -42,6 +42,10 @@ namespace android { // Macros to include adapter info in log messages #define BQA_LOGV(x, ...) \ ALOGV("[%s](f:%u,a:%u) " x, mName.c_str(), mNumFrameAvailable, mNumAcquired, ##__VA_ARGS__) +// enable logs for a single layer +//#define BQA_LOGV(x, ...) \ +// ALOGV_IF((strstr(mName.c_str(), "SurfaceView") != nullptr), "[%s](f:%u,a:%u) " x, \ +// mName.c_str(), mNumFrameAvailable, mNumAcquired, ##__VA_ARGS__) #define BQA_LOGE(x, ...) \ ALOGE("[%s](f:%u,a:%u) " x, mName.c_str(), mNumFrameAvailable, mNumAcquired, ##__VA_ARGS__) @@ -123,7 +127,7 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceCont mProducer->setMaxDequeuedBufferCount(2); } mBufferItemConsumer = - new BLASTBufferItemConsumer(mConsumer, GraphicBuffer::USAGE_HW_COMPOSER, 1, true); + new BLASTBufferItemConsumer(mConsumer, GraphicBuffer::USAGE_HW_COMPOSER, 1, false); static int32_t id = 0; auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id); id++; @@ -248,7 +252,8 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { BufferItem bufferItem; - status_t status = mBufferItemConsumer->acquireBuffer(&bufferItem, -1, false); + status_t status = + mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false); if (status != OK) { BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str()); return; @@ -289,6 +294,9 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { mLastBufferScalingMode = bufferItem.mScalingMode; t->setBuffer(mSurfaceControl, buffer); + t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace)); + t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata); + t->setSurfaceDamageRegion(mSurfaceControl, bufferItem.mSurfaceDamage); t->setAcquireFence(mSurfaceControl, bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE); t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast<void*>(this)); diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index c39b0b5ee6..c75c46c516 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -95,6 +95,15 @@ public: return std::make_unique<InputSurface>(surfaceControl, width, height); } + static std::unique_ptr<InputSurface> makeBlastInputSurface(const sp<SurfaceComposerClient> &scc, + int width, int height) { + sp<SurfaceControl> surfaceControl = + scc->createSurface(String8("Test Buffer Surface"), width, height, + PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceBufferState); + return std::make_unique<InputSurface>(surfaceControl, width, height); + } + static std::unique_ptr<InputSurface> makeContainerInputSurface( const sp<SurfaceComposerClient> &scc, int width, int height) { sp<SurfaceControl> surfaceControl = @@ -180,13 +189,13 @@ public: t.apply(true); } - void showAt(int x, int y) { + void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) { SurfaceComposerClient::Transaction t; t.show(mSurfaceControl); t.setInputWindowInfo(mSurfaceControl, mInputInfo); t.setLayer(mSurfaceControl, LAYER_BASE); t.setPosition(mSurfaceControl, x, y); - t.setCrop_legacy(mSurfaceControl, Rect(0, 0, 100, 100)); + t.setCrop_legacy(mSurfaceControl, crop); t.setAlpha(mSurfaceControl, 1); t.apply(true); } @@ -684,4 +693,34 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) { surface->expectTap(1, 10); } +TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) { + std::unique_ptr<InputSurface> surface = makeSurface(100, 100); + + std::unique_ptr<InputSurface> bufferSurface = + InputSurface::makeBufferInputSurface(mComposerClient, 0, 0); + bufferSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE; + bufferSurface->mInputInfo.ownerUid = 22222; + + surface->showAt(10, 10); + bufferSurface->showAt(50, 50, Rect::EMPTY_RECT); + + injectTap(11, 11); + surface->expectTap(1, 1); +} + +TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) { + std::unique_ptr<InputSurface> surface = makeSurface(100, 100); + + std::unique_ptr<InputSurface> bufferSurface = + InputSurface::makeBlastInputSurface(mComposerClient, 0, 0); + bufferSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE; + bufferSurface->mInputInfo.ownerUid = 22222; + + surface->showAt(10, 10); + bufferSurface->showAt(50, 50, Rect::EMPTY_RECT); + + injectTap(11, 11); + surface->expectTap(1, 1); +} + } // namespace android::test diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp index 4e9c5afce0..ee0a70ad74 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp @@ -587,6 +587,10 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, if (!texMatrix.invert(&matrix)) { matrix = texMatrix; } + // The shader does not respect the translation, so we add it to the texture + // transform for the SkImage. This will make sure that the correct layer contents + // are drawn in the correct part of the screen. + matrix.postTranslate(layer->geometry.boundaries.left, layer->geometry.boundaries.top); sk_sp<SkShader> shader; @@ -596,7 +600,7 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, {SkFilterMode::kLinear, SkMipmapMode::kNone}), &matrix); } else { - shader = image->makeShader(matrix); + shader = image->makeShader(SkSamplingOptions(), matrix); } if (mUseColorManagement && @@ -649,12 +653,11 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, drawShadow(canvas, rect, layer->geometry.roundedCornersRadius, layer->shadow); } + // Push the clipRRect onto the clip stack. Draw the image. Pop the clip. if (layer->geometry.roundedCornersRadius > 0) { - canvas->drawRRect(getRoundedRect(layer), paint); - } else { - canvas->drawRect(dest, paint); + canvas->clipRRect(getRoundedRect(layer), true); } - + canvas->drawRect(dest, paint); canvas->restore(); } canvas->restore(); @@ -698,7 +701,7 @@ inline SkRect SkiaGLRenderEngine::getSkRect(const Rect& rect) { } inline SkRRect SkiaGLRenderEngine::getRoundedRect(const LayerSettings* layer) { - const auto rect = getSkRect(layer->geometry.boundaries); + const auto rect = getSkRect(layer->geometry.roundedCornersCrop); const auto cornerRadius = layer->geometry.roundedCornersRadius; return SkRRect::MakeRectXY(rect, cornerRadius, cornerRadius); } diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp index e8257424a0..712e5e2dd3 100644 --- a/libs/renderengine/tests/RenderEngineTest.cpp +++ b/libs/renderengine/tests/RenderEngineTest.cpp @@ -1735,6 +1735,56 @@ TEST_P(RenderEngineTest, cleanupPostRender_whenCleaningAll_replacesTextureMemory EXPECT_TRUE(mRE->isTextureNameKnownForTesting(texName)); } +TEST_P(RenderEngineTest, testRoundedCornersCrop) { + const auto& renderEngineFactory = GetParam(); + mRE = renderEngineFactory->createRenderEngine(); + + renderengine::DisplaySettings settings; + settings.physicalDisplay = fullscreenRect(); + settings.clip = fullscreenRect(); + settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; + + std::vector<const renderengine::LayerSettings*> layers; + + renderengine::LayerSettings redLayer; + redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; + redLayer.geometry.boundaries = fullscreenRect().toFloatRect(); + redLayer.geometry.roundedCornersRadius = 5.0f; + redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect(); + // Red background. + redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f); + redLayer.alpha = 1.0f; + + layers.push_back(&redLayer); + + // Green layer with 1/3 size. + renderengine::LayerSettings greenLayer; + greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; + greenLayer.geometry.boundaries = fullscreenRect().toFloatRect(); + greenLayer.geometry.roundedCornersRadius = 5.0f; + // Bottom right corner is not going to be rounded. + greenLayer.geometry.roundedCornersCrop = + Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT, + DEFAULT_DISPLAY_HEIGHT) + .toFloatRect(); + greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f); + greenLayer.alpha = 1.0f; + + layers.push_back(&greenLayer); + + invokeDraw(settings, layers, mBuffer); + + // Corners should be ignored... + // Screen size: width is 128, height is 256. + expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0); + expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0); + expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0); + // Bottom right corner is kept out of the clipping, and it's green. + expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1, + DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), + 0, 255, 0, 255); +} + } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/libs/sensorprivacy/OWNERS b/libs/sensorprivacy/OWNERS new file mode 100644 index 0000000000..be955f5865 --- /dev/null +++ b/libs/sensorprivacy/OWNERS @@ -0,0 +1,3 @@ +cbrubaker@google.com +evanseverson@google.com +mpgroover@google.com diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index b620e2d214..ce12c27470 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -647,6 +647,13 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) { return; } + if (!newViewport->isActive) { + ALOGI("Disabling %s (device %i) because the associated viewport is not active", + getDeviceName().c_str(), getDeviceId()); + mDeviceMode = DeviceMode::DISABLED; + return; + } + // Raw width and height in the natural orientation. int32_t rawWidth = mRawPointerAxes.getRawWidth(); int32_t rawHeight = mRawPointerAxes.getRawHeight(); diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index cd61750971..c26a389342 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -224,10 +224,11 @@ public: } void addDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation, - const std::string& uniqueId, std::optional<uint8_t> physicalPort, - ViewportType viewportType) { - const DisplayViewport viewport = createDisplayViewport(displayId, width, height, - orientation, uniqueId, physicalPort, viewportType); + bool isActive, const std::string& uniqueId, + std::optional<uint8_t> physicalPort, ViewportType viewportType) { + const DisplayViewport viewport = + createDisplayViewport(displayId, width, height, orientation, isActive, uniqueId, + physicalPort, viewportType); mViewports.push_back(viewport); mConfig.setDisplayViewports(mViewports); } @@ -295,8 +296,9 @@ public: private: DisplayViewport createDisplayViewport(int32_t displayId, int32_t width, int32_t height, - int32_t orientation, const std::string& uniqueId, std::optional<uint8_t> physicalPort, - ViewportType type) { + int32_t orientation, bool isActive, + const std::string& uniqueId, + std::optional<uint8_t> physicalPort, ViewportType type) { bool isRotated = (orientation == DISPLAY_ORIENTATION_90 || orientation == DISPLAY_ORIENTATION_270); DisplayViewport v; @@ -312,6 +314,7 @@ private: v.physicalBottom = isRotated ? width : height; v.deviceWidth = isRotated ? height : width; v.deviceHeight = isRotated ? width : height; + v.isActive = isActive; v.uniqueId = uniqueId; v.physicalPort = physicalPort; v.type = type; @@ -1117,7 +1120,7 @@ TEST_F(InputReaderPolicyTest, Viewports_GetCleared) { // Add an internal viewport, then clear it mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, uniqueId, NO_PORT, + DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId, NO_PORT, ViewportType::INTERNAL); // Check matching by uniqueId @@ -1148,20 +1151,20 @@ TEST_F(InputReaderPolicyTest, Viewports_GetByType) { // Add an internal viewport mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, internalUniqueId, NO_PORT, - ViewportType::INTERNAL); + DISPLAY_ORIENTATION_0, true /*isActive*/, internalUniqueId, + NO_PORT, ViewportType::INTERNAL); // Add an external viewport mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, externalUniqueId, NO_PORT, - ViewportType::EXTERNAL); + DISPLAY_ORIENTATION_0, true /*isActive*/, externalUniqueId, + NO_PORT, ViewportType::EXTERNAL); // Add an virtual viewport mFakePolicy->addDisplayViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, virtualUniqueId1, NO_PORT, - ViewportType::VIRTUAL); + DISPLAY_ORIENTATION_0, true /*isActive*/, virtualUniqueId1, + NO_PORT, ViewportType::VIRTUAL); // Add another virtual viewport mFakePolicy->addDisplayViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, virtualUniqueId2, NO_PORT, - ViewportType::VIRTUAL); + DISPLAY_ORIENTATION_0, true /*isActive*/, virtualUniqueId2, + NO_PORT, ViewportType::VIRTUAL); // Check matching by type for internal std::optional<DisplayViewport> internalViewport = @@ -1210,10 +1213,12 @@ TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) { mFakePolicy->clearViewports(); // Add a viewport mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, uniqueId1, NO_PORT, type); + DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, + NO_PORT, type); // Add another viewport mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, uniqueId2, NO_PORT, type); + DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, + NO_PORT, type); // Check that correct display viewport was returned by comparing the display IDs. std::optional<DisplayViewport> viewport1 = @@ -1253,10 +1258,10 @@ TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) { // Add the default display first and ensure it gets returned. mFakePolicy->clearViewports(); mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, uniqueId1, NO_PORT, + DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, NO_PORT, ViewportType::INTERNAL); mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, uniqueId2, NO_PORT, + DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, NO_PORT, ViewportType::INTERNAL); std::optional<DisplayViewport> viewport = @@ -1268,10 +1273,10 @@ TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) { // Add the default display second to make sure order doesn't matter. mFakePolicy->clearViewports(); mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, uniqueId2, NO_PORT, + DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, NO_PORT, ViewportType::INTERNAL); mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, uniqueId1, NO_PORT, + DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, NO_PORT, ViewportType::INTERNAL); viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL); @@ -1296,10 +1301,12 @@ TEST_F(InputReaderPolicyTest, Viewports_GetByPort) { mFakePolicy->clearViewports(); // Add a viewport that's associated with some display port that's not of interest. mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, uniqueId1, hdmi3, type); + DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, hdmi3, + type); // Add another viewport, connected to HDMI1 port mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, uniqueId2, hdmi1, type); + DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, hdmi1, + type); // Check that correct display viewport was returned by comparing the display ports. std::optional<DisplayViewport> hdmi1Viewport = mFakePolicy->getDisplayViewportByPort(hdmi1); @@ -1703,10 +1710,10 @@ TEST_F(InputReaderTest, Device_CanDispatchToDisplay) { // Add default and second display. mFakePolicy->clearViewports(); mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, "local:0", NO_PORT, + DISPLAY_ORIENTATION_0, true /*isActive*/, "local:0", NO_PORT, ViewportType::INTERNAL); mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, "local:1", hdmi1, + DISPLAY_ORIENTATION_0, true /*isActive*/, "local:1", hdmi1, ViewportType::EXTERNAL); mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO); mReader->loopOnce(); @@ -2000,8 +2007,8 @@ protected: int32_t orientation, const std::string& uniqueId, std::optional<uint8_t> physicalPort, ViewportType viewportType) { - mFakePolicy->addDisplayViewport(displayId, width, height, orientation, uniqueId, - physicalPort, viewportType); + mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/, + uniqueId, physicalPort, viewportType); mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO); } @@ -2331,7 +2338,8 @@ TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) { // Prepare displays. mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, - DISPLAY_ORIENTATION_0, UNIQUE_ID, hdmi, ViewportType::INTERNAL); + DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, hdmi, + ViewportType::INTERNAL); mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), InputReaderConfiguration::CHANGE_DISPLAY_INFO); ASSERT_TRUE(mDevice->isEnabled()); @@ -2421,8 +2429,8 @@ protected: void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height, int32_t orientation, const std::string& uniqueId, std::optional<uint8_t> physicalPort, ViewportType viewportType) { - mFakePolicy->addDisplayViewport( - displayId, width, height, orientation, uniqueId, physicalPort, viewportType); + mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/, + uniqueId, physicalPort, viewportType); configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); } @@ -4057,7 +4065,8 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) { constexpr int32_t SECOND_DISPLAY_ID = 1; const std::string SECOND_DISPLAY_UNIQUE_ID = "local:1"; mFakePolicy->addDisplayViewport(SECOND_DISPLAY_ID, 800, 480, DISPLAY_ORIENTATION_0, - SECOND_DISPLAY_UNIQUE_ID, NO_PORT, ViewportType::EXTERNAL); + true /*isActive*/, SECOND_DISPLAY_UNIQUE_ID, NO_PORT, + ViewportType::EXTERNAL); mFakePolicy->setDefaultPointerDisplayId(SECOND_DISPLAY_ID); configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); @@ -7108,6 +7117,26 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) { ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId); } +/** + * When the viewport is not active (isActive=false), the touch mapper should be disabled and the + * events should not be delivered to the listener. + */ +TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) { + addConfigurationProperty("touch.deviceType", "touchScreen"); + mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, + DISPLAY_ORIENTATION_0, false /*isActive*/, UNIQUE_ID, NO_PORT, + ViewportType::INTERNAL); + configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); + prepareAxes(POSITION); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); + + NotifyMotionArgs motionArgs; + processPosition(mapper, 100, 100); + processSync(mapper); + + mFakeListener->assertNotifyMotionWasNotCalled(); +} + TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) { // Setup the first touch screen device. prepareAxes(POSITION | ID | SLOT); @@ -7708,8 +7737,8 @@ protected: configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); } - void processPositionAndVerify(MultiTouchInputMapper& mapper, int32_t xInside, int32_t yInside, - int32_t xOutside, int32_t yOutside, int32_t xExpected, + void processPositionAndVerify(MultiTouchInputMapper& mapper, int32_t xOutside, int32_t yOutside, + int32_t xInside, int32_t yInside, int32_t xExpected, int32_t yExpected) { // touch on outside area should not work. processPosition(mapper, toRawX(xOutside), toRawY(yOutside)); diff --git a/services/inputflinger/tests/TestInputListener.cpp b/services/inputflinger/tests/TestInputListener.cpp index 352995c600..1050ab8601 100644 --- a/services/inputflinger/tests/TestInputListener.cpp +++ b/services/inputflinger/tests/TestInputListener.cpp @@ -14,11 +14,10 @@ * limitations under the License. */ +#include "TestInputListener.h" #include <gtest/gtest.h> -#include "TestInputListener.h" - namespace android { // --- TestInputListener --- @@ -28,7 +27,7 @@ TestInputListener::TestInputListener(std::chrono::milliseconds eventHappenedTime : mEventHappenedTimeout(eventHappenedTimeout), mEventDidNotHappenTimeout(eventDidNotHappenTimeout) {} -TestInputListener::~TestInputListener() { } +TestInputListener::~TestInputListener() {} void TestInputListener::assertNotifyConfigurationChangedWasCalled( NotifyConfigurationChangedArgs* outEventArgs) { @@ -43,8 +42,7 @@ void TestInputListener::assertNotifyConfigurationChangedWasNotCalled() { "notifyConfigurationChanged() should not be called.")); } -void TestInputListener::assertNotifyDeviceResetWasCalled( - NotifyDeviceResetArgs* outEventArgs) { +void TestInputListener::assertNotifyDeviceResetWasCalled(NotifyDeviceResetArgs* outEventArgs) { ASSERT_NO_FATAL_FAILURE( assertCalled< NotifyDeviceResetArgs>(outEventArgs, @@ -73,7 +71,7 @@ void TestInputListener::assertNotifyMotionWasCalled(NotifyMotionArgs* outEventAr void TestInputListener::assertNotifyMotionWasNotCalled() { ASSERT_NO_FATAL_FAILURE( - assertNotCalled<NotifySwitchArgs>("notifySwitch() should not be called.")); + assertNotCalled<NotifyMotionArgs>("notifyMotion() should not be called.")); } void TestInputListener::assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs) { diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 5cf046033d..b6c59cde03 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -479,6 +479,10 @@ Rect BufferStateLayer::getBufferSize(const State& s) const { return Rect(getActiveWidth(s), getActiveHeight(s)); } + if (mBufferInfo.mBuffer == nullptr) { + return Rect::INVALID_RECT; + } + // if the display frame is not defined, use the parent bounds as the buffer size. const auto& p = mDrawingParent.promote(); if (p != nullptr) { diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index b273712e34..d5b599add7 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -819,7 +819,8 @@ void Layer::pushPendingState() { // to be applied as per normal (no synchronization). mCurrentState.barrierLayer_legacy = nullptr; } else { - auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.barrierFrameNumber, this); + auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.barrierFrameNumber, this, + barrierLayer); if (barrierLayer->addSyncPoint(syncPoint)) { std::stringstream ss; ss << "Adding sync point " << mCurrentState.barrierFrameNumber; @@ -844,7 +845,7 @@ void Layer::popPendingState(State* stateToCommit) { ATRACE_CALL(); *stateToCommit = mPendingStates[0]; - mPendingStates.removeAt(0); + mPendingStates.pop_front(); ATRACE_INT(mTransactionName.c_str(), mPendingStates.size()); } @@ -883,6 +884,7 @@ bool Layer::applyPendingStates(State* stateToCommit) { mRemoteSyncPoints.pop_front(); } else { ATRACE_NAME("!frameIsAvailable"); + mRemoteSyncPoints.front()->checkTimeoutAndLog(); break; } } else { @@ -2432,27 +2434,7 @@ bool Layer::isRemovedFromCurrentState() const { return mRemovedFromCurrentState; } -InputWindowInfo Layer::fillInputInfo() { - if (!hasInputInfo()) { - mDrawingState.inputInfo.name = getName(); - mDrawingState.inputInfo.ownerUid = mOwnerUid; - mDrawingState.inputInfo.ownerPid = mOwnerPid; - mDrawingState.inputInfo.inputFeatures = InputWindowInfo::Feature::NO_INPUT_CHANNEL; - mDrawingState.inputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL; - mDrawingState.inputInfo.displayId = getLayerStack(); - } - - InputWindowInfo info = mDrawingState.inputInfo; - info.id = sequence; - - if (info.displayId == ADISPLAY_ID_NONE) { - info.displayId = getLayerStack(); - } - - ui::Transform t = getTransform(); - int32_t xSurfaceInset = info.surfaceInset; - int32_t ySurfaceInset = info.surfaceInset; - +void Layer::fillInputFrameInfo(InputWindowInfo& info) { // Transform layer size to screen space and inset it by surface insets. // If this is a portal window, set the touchableRegion to the layerBounds. Rect layerBounds = info.portalToDisplayId == ADISPLAY_ID_NONE @@ -2462,6 +2444,20 @@ InputWindowInfo Layer::fillInputInfo() { layerBounds = getCroppedBufferSize(getDrawingState()); } + if (!layerBounds.isValid()) { + // If the layer bounds is empty, set the frame to empty and clear the transform + info.frameLeft = 0; + info.frameTop = 0; + info.frameRight = 0; + info.frameBottom = 0; + info.transform.reset(); + return; + } + + ui::Transform t = getTransform(); + int32_t xSurfaceInset = info.surfaceInset; + int32_t ySurfaceInset = info.surfaceInset; + const float xScale = t.getScaleX(); const float yScale = t.getScaleY(); if (xScale != 1.0f || yScale != 1.0f) { @@ -2528,6 +2524,27 @@ InputWindowInfo Layer::fillInputInfo() { // Position the touchable region relative to frame screen location and restrict it to frame // bounds. info.touchableRegion = inputTransform.transform(info.touchableRegion); +} + +InputWindowInfo Layer::fillInputInfo() { + if (!hasInputInfo()) { + mDrawingState.inputInfo.name = getName(); + mDrawingState.inputInfo.ownerUid = mOwnerUid; + mDrawingState.inputInfo.ownerPid = mOwnerPid; + mDrawingState.inputInfo.inputFeatures = InputWindowInfo::Feature::NO_INPUT_CHANNEL; + mDrawingState.inputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL; + mDrawingState.inputInfo.displayId = getLayerStack(); + } + + InputWindowInfo info = mDrawingState.inputInfo; + info.id = sequence; + + if (info.displayId == ADISPLAY_ID_NONE) { + info.displayId = getLayerStack(); + } + + fillInputFrameInfo(info); + // For compatibility reasons we let layers which can receive input // receive input before they have actually submitted a buffer. Because // of this we use canReceiveInput instead of isVisible to check the diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index cc47d126ad..2cfdba3e50 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -36,6 +36,7 @@ #include <utils/RefBase.h> #include <utils/Timers.h> +#include <chrono> #include <cstdint> #include <list> #include <optional> @@ -902,12 +903,13 @@ public: protected: class SyncPoint { public: - explicit SyncPoint(uint64_t frameNumber, wp<Layer> requestedSyncLayer) + explicit SyncPoint(uint64_t frameNumber, wp<Layer> requestedSyncLayer, + wp<Layer> barrierLayer_legacy) : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false), - mRequestedSyncLayer(requestedSyncLayer) {} - + mRequestedSyncLayer(requestedSyncLayer), + mBarrierLayer_legacy(barrierLayer_legacy) {} uint64_t getFrameNumber() const { return mFrameNumber; } bool frameIsAvailable() const { return mFrameIsAvailable; } @@ -920,11 +922,42 @@ protected: sp<Layer> getRequestedSyncLayer() { return mRequestedSyncLayer.promote(); } + sp<Layer> getBarrierLayer() const { return mBarrierLayer_legacy.promote(); } + + bool isTimeout() const { + using namespace std::chrono_literals; + static constexpr std::chrono::nanoseconds TIMEOUT_THRESHOLD = 1s; + + return std::chrono::steady_clock::now() - mCreateTimeStamp > TIMEOUT_THRESHOLD; + } + + void checkTimeoutAndLog() { + using namespace std::chrono_literals; + static constexpr std::chrono::nanoseconds LOG_PERIOD = 1s; + + if (!frameIsAvailable() && isTimeout()) { + const auto now = std::chrono::steady_clock::now(); + if (now - mLastLogTime > LOG_PERIOD) { + mLastLogTime = now; + sp<Layer> requestedSyncLayer = getRequestedSyncLayer(); + sp<Layer> barrierLayer = getBarrierLayer(); + ALOGW("[%s] sync point %" PRIu64 " wait timeout %lld for %s", + requestedSyncLayer ? requestedSyncLayer->getDebugName() : "Removed", + mFrameNumber, (now - mCreateTimeStamp).count(), + barrierLayer ? barrierLayer->getDebugName() : "Removed"); + } + } + } + private: const uint64_t mFrameNumber; std::atomic<bool> mFrameIsAvailable; std::atomic<bool> mTransactionIsApplied; wp<Layer> mRequestedSyncLayer; + wp<Layer> mBarrierLayer_legacy; + const std::chrono::time_point<std::chrono::steady_clock> mCreateTimeStamp = + std::chrono::steady_clock::now(); + std::chrono::time_point<std::chrono::steady_clock> mLastLogTime; }; friend class impl::SurfaceInterceptor; @@ -1011,12 +1044,12 @@ protected: State mDrawingState; // Store a copy of the pending state so that the drawing thread can access the // states without a lock. - Vector<State> mPendingStatesSnapshot; + std::deque<State> mPendingStatesSnapshot; // these are protected by an external lock (mStateLock) State mCurrentState; std::atomic<uint32_t> mTransactionFlags{0}; - Vector<State> mPendingStates; + std::deque<State> mPendingStates; // Timestamp history for UIAutomation. Thread safe. FrameTracker mFrameTracker; @@ -1114,6 +1147,9 @@ private: // null. sp<Layer> getRootLayer(); + // Fills in the frame and transform info for the InputWindowInfo + void fillInputFrameInfo(InputWindowInfo& info); + // Cached properties computed from drawing state // Effective transform taking into account parent transforms and any parent scaling, which is // a transform from the current layer coordinate space to display(screen) coordinate space. diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h index 576bba72ad..497ebd3c50 100644 --- a/services/surfaceflinger/SurfaceTracing.h +++ b/services/surfaceflinger/SurfaceTracing.h @@ -85,7 +85,7 @@ private: std::unique_ptr<Runner> runner; struct Config { - uint32_t flags = TRACE_CRITICAL | TRACE_INPUT; + uint32_t flags = TRACE_CRITICAL | TRACE_INPUT | TRACE_SYNC; size_t bufferSize = DEFAULT_BUFFER_SIZE; } mConfig; |