diff options
28 files changed, 723 insertions, 250 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index b012243c8b..4758607122 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -4656,7 +4656,7 @@ void Dumpstate::UpdateProgress(int32_t delta_sec) { void Dumpstate::TakeScreenshot(const std::string& path) { const std::string& real_path = path.empty() ? screenshot_path_ : path; int status = - RunCommand("", {"/system/bin/screencap", "-p", real_path}, + RunCommand("", {"screencap", "-p", real_path}, CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build()); if (status == 0) { MYLOGD("Screenshot saved on %s\n", real_path.c_str()); diff --git a/include/android/keycodes.h b/include/android/keycodes.h index 79cdbcaf7b..495e0bdb1f 100644 --- a/include/android/keycodes.h +++ b/include/android/keycodes.h @@ -843,6 +843,44 @@ enum { AKEYCODE_EMOJI_PICKER = 317, /** Take Screenshot */ AKEYCODE_SCREENSHOT = 318, + /** To start dictate to an input field */ + AKEYCODE_DICTATE = 319, + /** AC New */ + AKEYCODE_NEW = 320, + /** AC Close */ + AKEYCODE_CLOSE = 321, + /** To toggle 'Do Not Disturb' mode */ + AKEYCODE_DO_NOT_DISTURB = 322, + /** To Print */ + AKEYCODE_PRINT = 323, + /** To Lock the screen */ + AKEYCODE_LOCK = 324, + /** To toggle fullscreen mode (on the current application) */ + AKEYCODE_FULLSCREEN = 325, + /** F13 key */ + AKEYCODE_F13 = 326, + /** F14 key */ + AKEYCODE_F14 = 327, + /** F15 key */ + AKEYCODE_F15 = 328, + /** F16 key */ + AKEYCODE_F16 = 329, + /** F17 key */ + AKEYCODE_F17 = 330, + /** F18 key */ + AKEYCODE_F18 = 331, + /** F19 key */ + AKEYCODE_F19 = 332, + /** F20 key */ + AKEYCODE_F20 = 333, + /** F21 key */ + AKEYCODE_F21 = 334, + /** F22 key */ + AKEYCODE_F22 = 335, + /** F23 key */ + AKEYCODE_F23 = 336, + /** F24 key */ + AKEYCODE_F24 = 337, // NOTE: If you add a new keycode here you must also add it to several other files. // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 80e148be9f..1e33abbdea 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -274,6 +274,7 @@ filegroup { "LayerMetadata.cpp", "LayerStatePermissions.cpp", "LayerState.cpp", + "DisplayLuts.cpp", "OccupancyTracker.cpp", "StreamSplitter.cpp", "ScreenCaptureResults.cpp", diff --git a/libs/gui/DisplayLuts.cpp b/libs/gui/DisplayLuts.cpp new file mode 100644 index 0000000000..80429765be --- /dev/null +++ b/libs/gui/DisplayLuts.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2024 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/gui/DisplayLuts.h" +#include <gui/DisplayLuts.h> +#include <private/gui/ParcelUtils.h> + +namespace android::gui { + +status_t DisplayLuts::Entry::readFromParcel(const android::Parcel* parcel) { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + + SAFE_PARCEL(parcel->readInt32, &dimension); + SAFE_PARCEL(parcel->readInt32, &size); + SAFE_PARCEL(parcel->readInt32, &samplingKey); + + return OK; +} + +status_t DisplayLuts::Entry::writeToParcel(android::Parcel* parcel) const { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + + SAFE_PARCEL(parcel->writeInt32, dimension); + SAFE_PARCEL(parcel->writeInt32, size); + SAFE_PARCEL(parcel->writeInt32, samplingKey); + + return OK; +} + +status_t DisplayLuts::readFromParcel(const android::Parcel* parcel) { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + + SAFE_PARCEL(parcel->readUniqueFileDescriptor, &fd); + SAFE_PARCEL(parcel->readInt32Vector, &offsets); + int32_t numLutProperties; + SAFE_PARCEL(parcel->readInt32, &numLutProperties); + lutProperties.reserve(numLutProperties); + for (int32_t i = 0; i < numLutProperties; i++) { + lutProperties.push_back({}); + SAFE_PARCEL(lutProperties.back().readFromParcel, parcel); + } + return OK; +} + +status_t DisplayLuts::writeToParcel(android::Parcel* parcel) const { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + + SAFE_PARCEL(parcel->writeUniqueFileDescriptor, fd); + SAFE_PARCEL(parcel->writeInt32Vector, offsets); + SAFE_PARCEL(parcel->writeInt32, static_cast<int32_t>(lutProperties.size())); + for (auto& entry : lutProperties) { + SAFE_PARCEL(entry.writeToParcel, parcel); + } + return OK; +} +} // namespace android::gui
\ No newline at end of file diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 1c527d23b6..c1a03fcfea 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -210,6 +210,12 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeInt32, appContentPriority); #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS_APPLY_PICTURE_PROFILES + const bool hasLuts = (luts != nullptr); + SAFE_PARCEL(output.writeBool, hasLuts); + if (hasLuts) { + SAFE_PARCEL(output.writeParcelable, *luts); + } + return NO_ERROR; } @@ -371,6 +377,15 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readInt32, &appContentPriority); #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS_APPLY_PICTURE_PROFILES + bool hasLuts; + SAFE_PARCEL(input.readBool, &hasLuts); + if (hasLuts) { + luts = std::make_shared<gui::DisplayLuts>(); + SAFE_PARCEL(input.readParcelable, luts.get()); + } else { + luts = nullptr; + } + return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index ebed5767a4..61aabaa7f6 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1970,9 +1970,13 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLuts( return *this; } - s->luts = std::make_shared<gui::DisplayLuts>(base::unique_fd(dup(lutFd.get())), offsets, - dimensions, sizes, samplingKeys); s->what |= layer_state_t::eLutsChanged; + if (lutFd.ok()) { + s->luts = std::make_shared<gui::DisplayLuts>(base::unique_fd(dup(lutFd.get())), offsets, + dimensions, sizes, samplingKeys); + } else { + s->luts = nullptr; + } registerSurfaceControlForCallback(sc); return *this; @@ -2128,13 +2132,13 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::notifyPr } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo( - const sp<SurfaceControl>& sc, const WindowInfo& info) { + const sp<SurfaceControl>& sc, sp<WindowInfoHandle> info) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } - s->windowInfoHandle = new WindowInfoHandle(info); + s->windowInfoHandle = std::move(info); s->what |= layer_state_t::eInputInfoChanged; return *this; } diff --git a/libs/gui/include/gui/DisplayLuts.h b/libs/gui/include/gui/DisplayLuts.h index 16a360dcee..ab86ac4af8 100644 --- a/libs/gui/include/gui/DisplayLuts.h +++ b/libs/gui/include/gui/DisplayLuts.h @@ -16,16 +16,24 @@ #pragma once #include <android-base/unique_fd.h> +#include <binder/Parcel.h> +#include <binder/Parcelable.h> #include <vector> namespace android::gui { -struct DisplayLuts { +struct DisplayLuts : public Parcelable { public: - struct Entry { + struct Entry : public Parcelable { + Entry() {}; + Entry(int32_t lutDimension, int32_t lutSize, int32_t lutSamplingKey) + : dimension(lutDimension), size(lutSize), samplingKey(lutSamplingKey) {} int32_t dimension; int32_t size; int32_t samplingKey; + + status_t writeToParcel(android::Parcel* parcel) const override; + status_t readFromParcel(const android::Parcel* parcel) override; }; DisplayLuts() {} @@ -42,7 +50,10 @@ public: } } - base::unique_fd& getLutFileDescriptor() { return fd; } + status_t writeToParcel(android::Parcel* parcel) const override; + status_t readFromParcel(const android::Parcel* parcel) override; + + const base::unique_fd& getLutFileDescriptor() const { return fd; } std::vector<Entry> lutProperties; std::vector<int32_t> offsets; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 6968d252e8..0d7f8c2824 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -688,7 +688,8 @@ public: // ONLY FOR BLAST ADAPTER Transaction& notifyProducerDisconnect(const sp<SurfaceControl>& sc); - Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const gui::WindowInfo& info); + Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, + sp<gui::WindowInfoHandle> info); Transaction& setFocusedWindow(const gui::FocusRequest& request); Transaction& addWindowInfosReportedListener( diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 17630e304f..0e84d68eec 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -112,7 +112,7 @@ public: mInputFlinger = getInputFlinger(); if (noInputChannel) { - mInputInfo.setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, true); + mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, true); } else { android::os::InputChannelCore tempChannel; android::binder::Status result = @@ -121,21 +121,21 @@ public: ADD_FAILURE() << "binder call to createInputChannel failed"; } mClientChannel = InputChannel::create(std::move(tempChannel)); - mInputInfo.token = mClientChannel->getConnectionToken(); + mInputInfo->editInfo()->token = mClientChannel->getConnectionToken(); mInputConsumer = new InputConsumer(mClientChannel); } - mInputInfo.name = "Test info"; - mInputInfo.dispatchingTimeout = 5s; - mInputInfo.globalScaleFactor = 1.0; - mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height)); + mInputInfo->editInfo()->name = "Test info"; + mInputInfo->editInfo()->dispatchingTimeout = 5s; + mInputInfo->editInfo()->globalScaleFactor = 1.0; + mInputInfo->editInfo()->touchableRegion.orSelf(Rect(0, 0, width, height)); InputApplicationInfo aInfo; aInfo.token = new BBinder(); aInfo.name = "Test app info"; aInfo.dispatchingTimeoutMillis = std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count(); - mInputInfo.applicationInfo = aInfo; + mInputInfo->editInfo()->applicationInfo = aInfo; } static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient>& scc, @@ -183,20 +183,6 @@ public: return std::make_unique<InputSurface>(surfaceControl, width, height); } - InputEvent* consumeEvent(std::chrono::milliseconds timeout = 3000ms) { - mClientChannel->waitForMessage(timeout); - - InputEvent* ev; - uint32_t seqId; - status_t consumed = mInputConsumer->consume(&mInputEventFactory, true, -1, &seqId, &ev); - if (consumed != OK) { - return nullptr; - } - status_t status = mInputConsumer->sendFinishedSignal(seqId, true); - EXPECT_EQ(OK, status) << "Could not send finished signal"; - return ev; - } - void assertFocusChange(bool hasFocus) { InputEvent* ev = consumeEvent(); ASSERT_NE(ev, nullptr); @@ -314,8 +300,8 @@ public: void requestFocus(ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT) { SurfaceComposerClient::Transaction t; FocusRequest request; - request.token = mInputInfo.token; - request.windowName = mInputInfo.name; + request.token = mInputInfo->getInfo()->token; + request.windowName = mInputInfo->getInfo()->name; request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC); request.displayId = displayId.val(); t.setFocusedWindow(request); @@ -323,14 +309,30 @@ public: } public: + // But should be private + sp<gui::WindowInfoHandle> mInputInfo = sp<gui::WindowInfoHandle>::make(); sp<SurfaceControl> mSurfaceControl; + +private: std::shared_ptr<InputChannel> mClientChannel; sp<IInputFlinger> mInputFlinger; - WindowInfo mInputInfo; - PreallocatedInputEventFactory mInputEventFactory; InputConsumer* mInputConsumer; + + InputEvent* consumeEvent(std::chrono::milliseconds timeout = 3000ms) { + mClientChannel->waitForMessage(timeout); + + InputEvent* ev; + uint32_t seqId; + status_t consumed = mInputConsumer->consume(&mInputEventFactory, true, -1, &seqId, &ev); + if (consumed != OK) { + return nullptr; + } + status_t status = mInputConsumer->sendFinishedSignal(seqId, true); + EXPECT_EQ(OK, status) << "Could not send finished signal"; + return ev; + } }; class BlastInputSurface : public InputSurface { @@ -458,7 +460,7 @@ TEST_F(InputSurfacesTest, can_receive_input) { injectTap(101, 101); - EXPECT_NE(surface->consumeEvent(), nullptr); + surface->expectTap(1, 1); } /** @@ -521,7 +523,7 @@ TEST_F(InputSurfacesTest, input_respects_surface_insets) { std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); bgSurface->showAt(100, 100); - fgSurface->mInputInfo.surfaceInset = 5; + fgSurface->mInputInfo->editInfo()->surfaceInset = 5; fgSurface->showAt(100, 100); injectTap(106, 106); @@ -536,8 +538,8 @@ TEST_F(InputSurfacesTest, input_respects_surface_insets_with_replaceTouchableReg std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); bgSurface->showAt(100, 100); - fgSurface->mInputInfo.surfaceInset = 5; - fgSurface->mInputInfo.replaceTouchableRegionWithCrop = true; + fgSurface->mInputInfo->editInfo()->surfaceInset = 5; + fgSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true; fgSurface->showAt(100, 100); injectTap(106, 106); @@ -553,7 +555,7 @@ TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) { std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100); parentSurface->showAt(100, 100); - childSurface->mInputInfo.surfaceInset = 10; + childSurface->mInputInfo->editInfo()->surfaceInset = 10; childSurface->showAt(100, 100); childSurface->doTransaction([&](auto& t, auto& sc) { @@ -574,7 +576,7 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) { std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); bgSurface->showAt(100, 100); - fgSurface->mInputInfo.surfaceInset = 5; + fgSurface->mInputInfo->editInfo()->surfaceInset = 5; fgSurface->showAt(100, 100); fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); }); @@ -593,7 +595,7 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) { bgSurface->showAt(100, 100); // In case we pass the very big inset without any checking. - fgSurface->mInputInfo.surfaceInset = INT32_MAX; + fgSurface->mInputInfo->editInfo()->surfaceInset = INT32_MAX; fgSurface->showAt(100, 100); fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); }); @@ -606,13 +608,13 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) { TEST_F(InputSurfacesTest, touchable_region) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); - surface->mInputInfo.touchableRegion.set(Rect{19, 29, 21, 31}); + surface->mInputInfo->editInfo()->touchableRegion.set(Rect{19, 29, 21, 31}); surface->showAt(11, 22); // A tap within the surface but outside the touchable region should not be sent to the surface. injectTap(20, 30); - EXPECT_EQ(surface->consumeEvent(/*timeout=*/200ms), nullptr); + surface->assertNoEvent(); injectTap(31, 52); surface->expectTap(20, 30); @@ -627,7 +629,8 @@ TEST_F(InputSurfacesTest, input_respects_touchable_region_offset_overflow) { // Since the surface is offset from the origin, the touchable region will be transformed into // display space, which would trigger an overflow or an underflow. Ensure that we are protected // against such a situation. - fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX}); + fgSurface->mInputInfo->editInfo()->touchableRegion.orSelf( + Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX}); fgSurface->showAt(100, 100); @@ -642,7 +645,8 @@ TEST_F(InputSurfacesTest, input_respects_scaled_touchable_region_overflow) { std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); bgSurface->showAt(0, 0); - fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX}); + fgSurface->mInputInfo->editInfo()->touchableRegion.orSelf( + Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX}); fgSurface->showAt(0, 0); fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); }); @@ -812,7 +816,7 @@ TEST_F(InputSurfacesTest, rotate_surface_with_scale) { TEST_F(InputSurfacesTest, rotate_surface_with_scale_and_insets) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); - surface->mInputInfo.surfaceInset = 5; + surface->mInputInfo->editInfo()->surfaceInset = 5; surface->showAt(100, 100); surface->doTransaction([](auto& t, auto& sc) { @@ -841,11 +845,12 @@ TEST_F(InputSurfacesTest, touch_flag_obscured) { // Add non touchable window to fully cover touchable window. Window behind gets touch, but // with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100); - nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); - nonTouchableSurface->mInputInfo.ownerUid = gui::Uid{22222}; + nonTouchableSurface->mInputInfo->editInfo() + ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); + nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222}; // Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by // the default obscured/untrusted touch filter introduced in S. - nonTouchableSurface->mInputInfo.touchOcclusionMode = TouchOcclusionMode::ALLOW; + nonTouchableSurface->mInputInfo->editInfo()->touchOcclusionMode = TouchOcclusionMode::ALLOW; nonTouchableSurface->showAt(100, 100); injectTap(190, 199); @@ -861,10 +866,12 @@ TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) { // AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100); std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100); - nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); - parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); - nonTouchableSurface->mInputInfo.ownerUid = gui::Uid{22222}; - parentSurface->mInputInfo.ownerUid = gui::Uid{22222}; + nonTouchableSurface->mInputInfo->editInfo() + ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); + parentSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, + true); + nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222}; + parentSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222}; nonTouchableSurface->showAt(0, 0); parentSurface->showAt(100, 100); @@ -885,10 +892,12 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) { // the touchable window. Window behind gets touch with no obscured flags. std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100); std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100); - nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); - parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); - nonTouchableSurface->mInputInfo.ownerUid = gui::Uid{22222}; - parentSurface->mInputInfo.ownerUid = gui::Uid{22222}; + nonTouchableSurface->mInputInfo->editInfo() + ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); + parentSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, + true); + nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222}; + parentSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222}; nonTouchableSurface->showAt(0, 0); parentSurface->showAt(50, 50); @@ -906,8 +915,9 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) { std::unique_ptr<InputSurface> bufferSurface = InputSurface::makeBufferInputSurface(mComposerClient, 0, 0); - bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); - bufferSurface->mInputInfo.ownerUid = gui::Uid{22222}; + bufferSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, + true); + bufferSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222}; surface->showAt(10, 10); bufferSurface->showAt(50, 50, Rect::EMPTY_RECT); @@ -921,8 +931,9 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) { std::unique_ptr<BlastInputSurface> bufferSurface = BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0); - bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); - bufferSurface->mInputInfo.ownerUid = gui::Uid{22222}; + bufferSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, + true); + bufferSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222}; surface->showAt(10, 10); bufferSurface->showAt(50, 50, Rect::EMPTY_RECT); @@ -965,13 +976,14 @@ TEST_F(InputSurfacesTest, strict_unobscured_input_scaled_without_crop_window) { TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); - surface->mInputInfo.ownerUid = gui::Uid{11111}; + surface->mInputInfo->editInfo()->ownerUid = gui::Uid{11111}; surface->doTransaction( [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); }); surface->showAt(100, 100); std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100); - obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); - obscuringSurface->mInputInfo.ownerUid = gui::Uid{22222}; + obscuringSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, + true); + obscuringSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222}; obscuringSurface->showAt(100, 100); injectTap(101, 101); surface->assertNoEvent(); @@ -984,13 +996,14 @@ TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) { TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); - surface->mInputInfo.ownerUid = gui::Uid{11111}; + surface->mInputInfo->editInfo()->ownerUid = gui::Uid{11111}; surface->doTransaction( [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); }); surface->showAt(100, 100); std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100); - obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true); - obscuringSurface->mInputInfo.ownerUid = gui::Uid{22222}; + obscuringSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, + true); + obscuringSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222}; obscuringSurface->showAt(190, 190); injectTap(101, 101); @@ -1054,7 +1067,7 @@ TEST_F(InputSurfacesTest, ignore_touch_region_with_zero_sized_blast) { BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0); surface->showAt(100, 100); - bufferSurface->mInputInfo.touchableRegion.orSelf(Rect(0, 0, 200, 200)); + bufferSurface->mInputInfo->editInfo()->touchableRegion.orSelf(Rect(0, 0, 200, 200)); bufferSurface->showAt(100, 100, Rect::EMPTY_RECT); injectTap(101, 101); @@ -1097,8 +1110,8 @@ TEST_F(InputSurfacesTest, cropped_container_replaces_touchable_region_with_null_ InputSurface::makeContainerInputSurface(mComposerClient, 100, 100); containerSurface->doTransaction( [&](auto& t, auto& sc) { t.reparent(sc, parentContainer->mSurfaceControl); }); - containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true; - containerSurface->mInputInfo.touchableRegionCropHandle = nullptr; + containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true; + containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle = nullptr; parentContainer->showAt(10, 10, Rect(0, 0, 20, 20)); containerSurface->showAt(10, 10, Rect(0, 0, 5, 5)); @@ -1124,8 +1137,8 @@ TEST_F(InputSurfacesTest, uncropped_container_replaces_touchable_region_with_nul InputSurface::makeContainerInputSurface(mComposerClient, 100, 100); containerSurface->doTransaction( [&](auto& t, auto& sc) { t.reparent(sc, parentContainer->mSurfaceControl); }); - containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true; - containerSurface->mInputInfo.touchableRegionCropHandle = nullptr; + containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true; + containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle = nullptr; parentContainer->doTransaction( [&](auto& t, auto& sc) { t.reparent(sc, bgContainer->mSurfaceControl); }); bgContainer->showAt(0, 0, Rect(0, 0, 100, 100)); @@ -1152,8 +1165,8 @@ TEST_F(InputSurfacesTest, replace_touchable_region_with_crop) { std::unique_ptr<InputSurface> containerSurface = InputSurface::makeContainerInputSurface(mComposerClient, 100, 100); - containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true; - containerSurface->mInputInfo.touchableRegionCropHandle = + containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true; + containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle = cropLayer->mSurfaceControl->getHandle(); containerSurface->showAt(10, 10, Rect::INVALID_RECT); diff --git a/libs/input/InputEventLabels.cpp b/libs/input/InputEventLabels.cpp index 8db0ca588b..b537feb68f 100644 --- a/libs/input/InputEventLabels.cpp +++ b/libs/input/InputEventLabels.cpp @@ -350,7 +350,26 @@ namespace android { DEFINE_KEYCODE(MACRO_3), \ DEFINE_KEYCODE(MACRO_4), \ DEFINE_KEYCODE(EMOJI_PICKER), \ - DEFINE_KEYCODE(SCREENSHOT) + DEFINE_KEYCODE(SCREENSHOT), \ + DEFINE_KEYCODE(DICTATE), \ + DEFINE_KEYCODE(NEW), \ + DEFINE_KEYCODE(CLOSE), \ + DEFINE_KEYCODE(DO_NOT_DISTURB), \ + DEFINE_KEYCODE(PRINT), \ + DEFINE_KEYCODE(LOCK), \ + DEFINE_KEYCODE(FULLSCREEN), \ + DEFINE_KEYCODE(F13), \ + DEFINE_KEYCODE(F14), \ + DEFINE_KEYCODE(F15), \ + DEFINE_KEYCODE(F16), \ + DEFINE_KEYCODE(F17), \ + DEFINE_KEYCODE(F18), \ + DEFINE_KEYCODE(F19),\ + DEFINE_KEYCODE(F20), \ + DEFINE_KEYCODE(F21), \ + DEFINE_KEYCODE(F22), \ + DEFINE_KEYCODE(F23), \ + DEFINE_KEYCODE(F24) // NOTE: If you add a new axis here you must also add it to several other files. // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list. diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp index d248ea0b84..7f207f0670 100644 --- a/libs/renderengine/Android.bp +++ b/libs/renderengine/Android.bp @@ -105,6 +105,7 @@ filegroup { "skia/filters/KawaseBlurDualFilter.cpp", "skia/filters/KawaseBlurFilter.cpp", "skia/filters/LinearEffect.cpp", + "skia/filters/LutShader.cpp", "skia/filters/MouriMap.cpp", "skia/filters/StretchShaderFactory.cpp", "skia/filters/EdgeExtensionShaderFactory.cpp", diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp index ec9d3efb88..5c46c9168d 100644 --- a/libs/renderengine/skia/SkiaRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaRenderEngine.cpp @@ -543,6 +543,10 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader( } } + if (graphicBuffer && parameters.layer.luts) { + shader = mLutShader.lutShader(shader, parameters.layer.luts); + } + if (parameters.requiresLinearEffect) { const auto format = targetBuffer != nullptr ? std::optional<ui::PixelFormat>( diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h index b5f8898263..7be4c253e7 100644 --- a/libs/renderengine/skia/SkiaRenderEngine.h +++ b/libs/renderengine/skia/SkiaRenderEngine.h @@ -39,6 +39,7 @@ #include "filters/BlurFilter.h" #include "filters/EdgeExtensionShaderFactory.h" #include "filters/LinearEffect.h" +#include "filters/LutShader.h" #include "filters/StretchShaderFactory.h" class SkData; @@ -184,6 +185,7 @@ private: StretchShaderFactory mStretchShaderFactory; EdgeExtensionShaderFactory mEdgeExtensionShaderFactory; + LutShader mLutShader; sp<Fence> mLastDrawFence; BlurFilter* mBlurFilter = nullptr; diff --git a/libs/renderengine/skia/filters/LutShader.cpp b/libs/renderengine/skia/filters/LutShader.cpp new file mode 100644 index 0000000000..cea46ef40e --- /dev/null +++ b/libs/renderengine/skia/filters/LutShader.cpp @@ -0,0 +1,242 @@ +/* + * Copyright 2024 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 "LutShader.h" + +#include <SkTileMode.h> +#include <common/trace.h> +#include <cutils/ashmem.h> +#include <math/half.h> +#include <sys/mman.h> + +#include "include/core/SkColorSpace.h" +#include "src/core/SkColorFilterPriv.h" + +using aidl::android::hardware::graphics::composer3::LutProperties; + +namespace android { +namespace renderengine { +namespace skia { + +static const SkString kShader = SkString(R"( + uniform shader image; + uniform shader lut; + uniform int size; + uniform int key; + uniform int dimension; + vec4 main(vec2 xy) { + float4 rgba = image.eval(xy); + float3 linear = toLinearSrgb(rgba.rgb); + if (dimension == 1) { + // RGB + if (key == 0) { + float indexR = linear.r * float(size - 1); + float indexG = linear.g * float(size - 1); + float indexB = linear.b * float(size - 1); + float gainR = lut.eval(vec2(indexR, 0.0) + 0.5).r; + float gainG = lut.eval(vec2(indexG, 0.0) + 0.5).r; + float gainB = lut.eval(vec2(indexB, 0.0) + 0.5).r; + return float4(linear.r * gainR, linear.g * gainG, linear.b * gainB, rgba.a); + // MAX_RGB + } else if (key == 1) { + float4 rgba = image.eval(xy); + float3 linear = toLinearSrgb(rgba.rgb); + float maxRGB = max(linear.r, max(linear.g, linear.b)); + float index = maxRGB * float(size - 1); + float gain = lut.eval(vec2(index, 0.0) + 0.5).r; + return float4(linear * gain, rgba.a); + } + } else if (dimension == 3) { + if (key == 0) { + float tx = linear.r * float(size - 1); + float ty = linear.g * float(size - 1); + float tz = linear.b * float(size - 1); + + // calculate lower and upper bounds for each dimension + int x = int(tx); + int y = int(ty); + int z = int(tz); + + int i000 = x + y * size + z * size * size; + int i100 = i000 + 1; + int i010 = i000 + size; + int i110 = i000 + size + 1; + int i001 = i000 + size * size; + int i101 = i000 + size * size + 1; + int i011 = i000 + size * size + size; + int i111 = i000 + size * size + size + 1; + + // get 1d normalized indices + float c000 = float(i000) / float(size * size * size); + float c100 = float(i100) / float(size * size * size); + float c010 = float(i010) / float(size * size * size); + float c110 = float(i110) / float(size * size * size); + float c001 = float(i001) / float(size * size * size); + float c101 = float(i101) / float(size * size * size); + float c011 = float(i011) / float(size * size * size); + float c111 = float(i111) / float(size * size * size); + + //TODO(b/377984618): support Tetrahedral interpolation + // perform trilinear interpolation + float3 c00 = mix(lut.eval(vec2(c000, 0.0) + 0.5).rgb, + lut.eval(vec2(c100, 0.0) + 0.5).rgb, linear.r); + float3 c01 = mix(lut.eval(vec2(c001, 0.0) + 0.5).rgb, + lut.eval(vec2(c101, 0.0) + 0.5).rgb, linear.r); + float3 c10 = mix(lut.eval(vec2(c010, 0.0) + 0.5).rgb, + lut.eval(vec2(c110, 0.0) + 0.5).rgb, linear.r); + float3 c11 = mix(lut.eval(vec2(c011, 0.0) + 0.5).rgb, + lut.eval(vec2(c111, 0.0) + 0.5).rgb, linear.r); + + float3 c0 = mix(c00, c10, linear.g); + float3 c1 = mix(c01, c11, linear.g); + + float3 val = mix(c0, c1, linear.b); + + return float4(val, rgba.a); + } + } + return rgba; + })"); + +sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input, + const std::vector<float>& buffers, + const int32_t offset, const int32_t length, + const int32_t dimension, const int32_t size, + const int32_t samplingKey) { + SFTRACE_NAME("lut shader"); + std::vector<half> buffer(length * 4); // 4 is for RGBA + auto d = static_cast<LutProperties::Dimension>(dimension); + if (d == LutProperties::Dimension::ONE_D) { + auto it = buffers.begin() + offset; + std::generate(buffer.begin(), buffer.end(), [it, i = 0]() mutable { + float val = (i++ % 4 == 0) ? *it++ : 0.0f; + return half(val); + }); + } else { + for (int i = 0; i < length; i++) { + buffer[i * 4] = half(buffers[offset + i]); + buffer[i * 4 + 1] = half(buffers[offset + length + i]); + buffer[i * 4 + 2] = half(buffers[offset + length * 2 + i]); + buffer[i * 4 + 3] = half(0); + } + } + /** + * 1D Lut(rgba) + * (R0, 0, 0, 0) + * (R1, 0, 0, 0) + * ... + * + * 3D Lut + * (R0, G0, B0, 0) + * (R1, G1, B1, 0) + * ... + */ + SkImageInfo info = SkImageInfo::Make(length /* the number of rgba */ * 4, 1, + kRGBA_F16_SkColorType, kPremul_SkAlphaType); + SkBitmap bitmap; + bitmap.allocPixels(info); + if (!bitmap.installPixels(info, buffer.data(), info.minRowBytes())) { + LOG_ALWAYS_FATAL("unable to install pixels"); + } + + sk_sp<SkImage> lutImage = SkImages::RasterFromBitmap(bitmap); + mBuilder->child("image") = input; + mBuilder->child("lut") = + lutImage->makeRawShader(SkTileMode::kClamp, SkTileMode::kClamp, + d == LutProperties::Dimension::ONE_D + ? SkSamplingOptions(SkFilterMode::kLinear) + : SkSamplingOptions()); + + const int uSize = static_cast<int>(size); + const int uKey = static_cast<int>(samplingKey); + const int uDimension = static_cast<int>(dimension); + mBuilder->uniform("size") = uSize; + mBuilder->uniform("key") = uKey; + mBuilder->uniform("dimension") = uDimension; + return mBuilder->makeShader(); +} + +sk_sp<SkShader> LutShader::lutShader(sk_sp<SkShader>& input, + std::shared_ptr<gui::DisplayLuts> displayLuts) { + if (mBuilder == nullptr) { + const static SkRuntimeEffect::Result instance = SkRuntimeEffect::MakeForShader(kShader); + mBuilder = std::make_unique<SkRuntimeShaderBuilder>(instance.effect); + } + + auto& fd = displayLuts->getLutFileDescriptor(); + if (fd.ok()) { + // de-gamma the image without changing the primaries + SkImage* baseImage = input->isAImage((SkMatrix*)nullptr, (SkTileMode*)nullptr); + if (baseImage) { + sk_sp<SkColorSpace> baseColorSpace = + baseImage->colorSpace() ? baseImage->refColorSpace() : SkColorSpace::MakeSRGB(); + sk_sp<SkColorSpace> gainmapMathColorSpace = baseColorSpace->makeLinearGamma(); + auto colorXformSdrToGainmap = + SkColorFilterPriv::MakeColorSpaceXform(baseColorSpace, gainmapMathColorSpace); + input = input->makeWithColorFilter(colorXformSdrToGainmap); + } + + auto& offsets = displayLuts->offsets; + auto& lutProperties = displayLuts->lutProperties; + std::vector<float> buffers; + int fullLength = offsets[lutProperties.size() - 1]; + if (lutProperties[lutProperties.size() - 1].dimension == 1) { + fullLength += lutProperties[lutProperties.size() - 1].size; + } else { + fullLength += (lutProperties[lutProperties.size() - 1].size * + lutProperties[lutProperties.size() - 1].size * + lutProperties[lutProperties.size() - 1].size * 3); + } + size_t bufferSize = fullLength * sizeof(float); + + // decode the shared memory of luts + float* ptr = + (float*)mmap(NULL, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0); + if (ptr == MAP_FAILED) { + LOG_ALWAYS_FATAL("mmap failed"); + } + buffers = std::vector<float>(ptr, ptr + fullLength); + munmap(ptr, bufferSize); + + for (size_t i = 0; i < offsets.size(); i++) { + int bufferSizePerLut = (i == offsets.size() - 1) ? buffers.size() - offsets[i] + : offsets[i + 1] - offsets[i]; + // divide by 3 for 3d Lut because of 3 (RGB) channels + if (static_cast<LutProperties::Dimension>(lutProperties[i].dimension) == + LutProperties::Dimension::THREE_D) { + bufferSizePerLut /= 3; + } + input = generateLutShader(input, buffers, offsets[i], bufferSizePerLut, + lutProperties[i].dimension, lutProperties[i].size, + lutProperties[i].samplingKey); + } + + // re-gamma + baseImage = input->isAImage((SkMatrix*)nullptr, (SkTileMode*)nullptr); + if (baseImage) { + sk_sp<SkColorSpace> baseColorSpace = + baseImage->colorSpace() ? baseImage->refColorSpace() : SkColorSpace::MakeSRGB(); + sk_sp<SkColorSpace> gainmapMathColorSpace = baseColorSpace->makeLinearGamma(); + auto colorXformGainmapToDst = + SkColorFilterPriv::MakeColorSpaceXform(gainmapMathColorSpace, baseColorSpace); + input = input->makeWithColorFilter(colorXformGainmapToDst); + } + } + return input; +} + +} // namespace skia +} // namespace renderengine +} // namespace android
\ No newline at end of file diff --git a/libs/renderengine/skia/filters/LutShader.h b/libs/renderengine/skia/filters/LutShader.h new file mode 100644 index 0000000000..c157904b63 --- /dev/null +++ b/libs/renderengine/skia/filters/LutShader.h @@ -0,0 +1,44 @@ +/* + * Copyright 2024 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. + */ +#pragma once + +#include <SkBitmap.h> +#include <SkImage.h> +#include <SkRuntimeEffect.h> + +#include <aidl/android/hardware/graphics/composer3/LutProperties.h> +#include <gui/DisplayLuts.h> + +namespace android { +namespace renderengine { +namespace skia { + +class LutShader { +public: + sk_sp<SkShader> lutShader(sk_sp<SkShader>& input, + std::shared_ptr<gui::DisplayLuts> displayLuts); + +private: + sk_sp<SkShader> generateLutShader(sk_sp<SkShader> input, const std::vector<float>& buffers, + const int32_t offset, const int32_t length, + const int32_t dimension, const int32_t size, + const int32_t samplingKey); + std::unique_ptr<SkRuntimeShaderBuilder> mBuilder; +}; + +} // namespace skia +} // namespace renderengine +} // namespace android diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp index eddd568fb5..797efbe5df 100644 --- a/libs/sensor/Sensor.cpp +++ b/libs/sensor/Sensor.cpp @@ -306,7 +306,18 @@ Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersi } if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor.requiredPermission) { mRequiredPermission = hwSensor.requiredPermission; - if (!strcmp(mRequiredPermission, SENSOR_PERMISSION_BODY_SENSORS)) { + bool requiresBodySensorPermission = + !strcmp(mRequiredPermission, SENSOR_PERMISSION_BODY_SENSORS); + if (android::permission::flags::replace_body_sensor_permission_enabled()) { + if (requiresBodySensorPermission) { + ALOGE("Sensor %s using deprecated Body Sensor permission", mName.c_str()); + } + + AppOpsManager appOps; + // Lookup to see if an AppOp exists for the permission. If none + // does, the default value of -1 is used. + mRequiredAppOp = appOps.permissionToOpCode(String16(mRequiredPermission)); + } else if (requiresBodySensorPermission) { AppOpsManager appOps; mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS)); } diff --git a/services/inputflinger/tests/InputMapperTest.cpp b/services/inputflinger/tests/InputMapperTest.cpp index 7dff144f87..ca797dce95 100644 --- a/services/inputflinger/tests/InputMapperTest.cpp +++ b/services/inputflinger/tests/InputMapperTest.cpp @@ -53,13 +53,13 @@ void InputMapperUnitTest::SetUpWithBus(int bus) { } void InputMapperUnitTest::setupAxis(int axis, bool valid, int32_t min, int32_t max, - int32_t resolution) { + int32_t resolution, int32_t flat, int32_t fuzz) { EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis)) .WillRepeatedly(Return(valid ? std::optional<RawAbsoluteAxisInfo>{{ .minValue = min, .maxValue = max, - .flat = 0, - .fuzz = 0, + .flat = flat, + .fuzz = fuzz, .resolution = resolution, }} : std::nullopt)); diff --git a/services/inputflinger/tests/InputMapperTest.h b/services/inputflinger/tests/InputMapperTest.h index fc27e4fefd..b6c5812ec5 100644 --- a/services/inputflinger/tests/InputMapperTest.h +++ b/services/inputflinger/tests/InputMapperTest.h @@ -43,7 +43,8 @@ protected: virtual void SetUp() override { SetUpWithBus(0); } virtual void SetUpWithBus(int bus); - void setupAxis(int axis, bool valid, int32_t min, int32_t max, int32_t resolution); + void setupAxis(int axis, bool valid, int32_t min, int32_t max, int32_t resolution, + int32_t flat = 0, int32_t fuzz = 0); void expectScanCodes(bool present, std::set<int> scanCodes); diff --git a/services/inputflinger/tests/SensorInputMapper_test.cpp b/services/inputflinger/tests/SensorInputMapper_test.cpp index 01814a61ec..2c1265378a 100644 --- a/services/inputflinger/tests/SensorInputMapper_test.cpp +++ b/services/inputflinger/tests/SensorInputMapper_test.cpp @@ -16,168 +16,164 @@ #include "SensorInputMapper.h" +#include <cstdint> +#include <list> +#include <optional> +#include <utility> #include <vector> #include <EventHub.h> #include <NotifyArgs.h> +#include <ftl/enum.h> +#include <gmock/gmock.h> #include <gtest/gtest.h> #include <input/Input.h> #include <input/InputDevice.h> +#include <input/PrintTools.h> #include <linux/input-event-codes.h> #include "InputMapperTest.h" +#include "TestEventMatchers.h" namespace android { -class SensorInputMapperTest : public InputMapperTest { -protected: - static const int32_t ACCEL_RAW_MIN; - static const int32_t ACCEL_RAW_MAX; - static const int32_t ACCEL_RAW_FUZZ; - static const int32_t ACCEL_RAW_FLAT; - static const int32_t ACCEL_RAW_RESOLUTION; - - static const int32_t GYRO_RAW_MIN; - static const int32_t GYRO_RAW_MAX; - static const int32_t GYRO_RAW_FUZZ; - static const int32_t GYRO_RAW_FLAT; - static const int32_t GYRO_RAW_RESOLUTION; - - static const float GRAVITY_MS2_UNIT; - static const float DEGREE_RADIAN_UNIT; - - void prepareAccelAxes(); - void prepareGyroAxes(); - void setAccelProperties(); - void setGyroProperties(); - void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::SENSOR); } -}; +using testing::AllOf; +using testing::ElementsAre; +using testing::Return; +using testing::VariantWith; -const int32_t SensorInputMapperTest::ACCEL_RAW_MIN = -32768; -const int32_t SensorInputMapperTest::ACCEL_RAW_MAX = 32768; -const int32_t SensorInputMapperTest::ACCEL_RAW_FUZZ = 16; -const int32_t SensorInputMapperTest::ACCEL_RAW_FLAT = 0; -const int32_t SensorInputMapperTest::ACCEL_RAW_RESOLUTION = 8192; - -const int32_t SensorInputMapperTest::GYRO_RAW_MIN = -2097152; -const int32_t SensorInputMapperTest::GYRO_RAW_MAX = 2097152; -const int32_t SensorInputMapperTest::GYRO_RAW_FUZZ = 16; -const int32_t SensorInputMapperTest::GYRO_RAW_FLAT = 0; -const int32_t SensorInputMapperTest::GYRO_RAW_RESOLUTION = 1024; - -const float SensorInputMapperTest::GRAVITY_MS2_UNIT = 9.80665f; -const float SensorInputMapperTest::DEGREE_RADIAN_UNIT = 0.0174533f; - -void SensorInputMapperTest::prepareAccelAxes() { - mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ, - ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION); - mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ, - ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION); - mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Z, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ, - ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION); -} +namespace { -void SensorInputMapperTest::prepareGyroAxes() { - mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RX, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ, - GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION); - mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RY, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ, - GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION); - mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RZ, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ, - GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION); -} +constexpr int32_t ACCEL_RAW_MIN = -32768; +constexpr int32_t ACCEL_RAW_MAX = 32768; +constexpr int32_t ACCEL_RAW_FUZZ = 16; +constexpr int32_t ACCEL_RAW_FLAT = 0; +constexpr int32_t ACCEL_RAW_RESOLUTION = 8192; -void SensorInputMapperTest::setAccelProperties() { - mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 0, InputDeviceSensorType::ACCELEROMETER, - /* sensorDataIndex */ 0); - mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 1, InputDeviceSensorType::ACCELEROMETER, - /* sensorDataIndex */ 1); - mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 2, InputDeviceSensorType::ACCELEROMETER, - /* sensorDataIndex */ 2); - mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP); - addConfigurationProperty("sensor.accelerometer.reportingMode", "0"); - addConfigurationProperty("sensor.accelerometer.maxDelay", "100000"); - addConfigurationProperty("sensor.accelerometer.minDelay", "5000"); - addConfigurationProperty("sensor.accelerometer.power", "1.5"); -} +constexpr int32_t GYRO_RAW_MIN = -2097152; +constexpr int32_t GYRO_RAW_MAX = 2097152; +constexpr int32_t GYRO_RAW_FUZZ = 16; +constexpr int32_t GYRO_RAW_FLAT = 0; +constexpr int32_t GYRO_RAW_RESOLUTION = 1024; -void SensorInputMapperTest::setGyroProperties() { - mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 3, InputDeviceSensorType::GYROSCOPE, - /* sensorDataIndex */ 0); - mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 4, InputDeviceSensorType::GYROSCOPE, - /* sensorDataIndex */ 1); - mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 5, InputDeviceSensorType::GYROSCOPE, - /* sensorDataIndex */ 2); - mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP); - addConfigurationProperty("sensor.gyroscope.reportingMode", "0"); - addConfigurationProperty("sensor.gyroscope.maxDelay", "100000"); - addConfigurationProperty("sensor.gyroscope.minDelay", "5000"); - addConfigurationProperty("sensor.gyroscope.power", "0.8"); -} +constexpr float GRAVITY_MS2_UNIT = 9.80665f; +constexpr float DEGREE_RADIAN_UNIT = 0.0174533f; + +} // namespace + +class SensorInputMapperTest : public InputMapperUnitTest { +protected: + void SetUp() override { + InputMapperUnitTest::SetUp(); + EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID)) + .WillRepeatedly(Return(InputDeviceClass::SENSOR)); + // The mapper requests info on all ABS axes, including ones which aren't actually used, so + // just return nullopt for all axes we don't explicitly set up. + EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, testing::_)) + .WillRepeatedly(Return(std::nullopt)); + } + + void setupSensor(int32_t absCode, InputDeviceSensorType type, int32_t sensorDataIndex) { + EXPECT_CALL(mMockEventHub, mapSensor(EVENTHUB_ID, absCode)) + .WillRepeatedly(Return(std::make_pair(type, sensorDataIndex))); + } +}; TEST_F(SensorInputMapperTest, GetSources) { - SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>(); + mMapper = createInputMapper<SensorInputMapper>(*mDeviceContext, + mFakePolicy->getReaderConfiguration()); - ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mapper.getSources()); + ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mMapper->getSources()); } TEST_F(SensorInputMapperTest, ProcessAccelerometerSensor) { - setAccelProperties(); - prepareAccelAxes(); - SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>(); - - ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::ACCELEROMETER, - std::chrono::microseconds(10000), - std::chrono::microseconds(0))); - ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID)); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, 20000); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, -20000); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Z, 40000); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0); - - NotifySensorArgs args; + EXPECT_CALL(mMockEventHub, hasMscEvent(EVENTHUB_ID, MSC_TIMESTAMP)) + .WillRepeatedly(Return(true)); + setupSensor(ABS_X, InputDeviceSensorType::ACCELEROMETER, /*sensorDataIndex=*/0); + setupSensor(ABS_Y, InputDeviceSensorType::ACCELEROMETER, /*sensorDataIndex=*/1); + setupSensor(ABS_Z, InputDeviceSensorType::ACCELEROMETER, /*sensorDataIndex=*/2); + setupAxis(ABS_X, /*valid=*/true, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_RESOLUTION, + ACCEL_RAW_FLAT, ACCEL_RAW_FUZZ); + setupAxis(ABS_Y, /*valid=*/true, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_RESOLUTION, + ACCEL_RAW_FLAT, ACCEL_RAW_FUZZ); + setupAxis(ABS_Z, /*valid=*/true, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_RESOLUTION, + ACCEL_RAW_FLAT, ACCEL_RAW_FUZZ); + mPropertyMap.addProperty("sensor.accelerometer.reportingMode", "0"); + mPropertyMap.addProperty("sensor.accelerometer.maxDelay", "100000"); + mPropertyMap.addProperty("sensor.accelerometer.minDelay", "5000"); + mPropertyMap.addProperty("sensor.accelerometer.power", "1.5"); + mMapper = createInputMapper<SensorInputMapper>(*mDeviceContext, + mFakePolicy->getReaderConfiguration()); + + EXPECT_CALL(mMockEventHub, enableDevice(EVENTHUB_ID)); + ASSERT_TRUE(mMapper->enableSensor(InputDeviceSensorType::ACCELEROMETER, + std::chrono::microseconds(10000), + std::chrono::microseconds(0))); + std::list<NotifyArgs> args; + args += process(ARBITRARY_TIME, EV_ABS, ABS_X, 20000); + args += process(ARBITRARY_TIME, EV_ABS, ABS_Y, -20000); + args += process(ARBITRARY_TIME, EV_ABS, ABS_Z, 40000); + args += process(ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, 1000); + args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); + std::vector<float> values = {20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT, -20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT, 40000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT}; - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args)); - ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR); - ASSERT_EQ(args.deviceId, DEVICE_ID); - ASSERT_EQ(args.sensorType, InputDeviceSensorType::ACCELEROMETER); - ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH); - ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME); - ASSERT_EQ(args.values, values); - mapper.flushSensor(InputDeviceSensorType::ACCELEROMETER); + ASSERT_EQ(args.size(), 1u); + const NotifySensorArgs& arg = std::get<NotifySensorArgs>(args.front()); + ASSERT_EQ(arg.source, AINPUT_SOURCE_SENSOR); + ASSERT_EQ(arg.deviceId, DEVICE_ID); + ASSERT_EQ(arg.sensorType, InputDeviceSensorType::ACCELEROMETER); + ASSERT_EQ(arg.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH); + ASSERT_EQ(arg.hwTimestamp, ARBITRARY_TIME); + ASSERT_EQ(arg.values, values); + mMapper->flushSensor(InputDeviceSensorType::ACCELEROMETER); } TEST_F(SensorInputMapperTest, ProcessGyroscopeSensor) { - setGyroProperties(); - prepareGyroAxes(); - SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>(); - - ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::GYROSCOPE, - std::chrono::microseconds(10000), - std::chrono::microseconds(0))); - ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID)); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RX, 20000); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RY, -20000); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RZ, 40000); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000); - process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0); - - NotifySensorArgs args; + EXPECT_CALL(mMockEventHub, hasMscEvent(EVENTHUB_ID, MSC_TIMESTAMP)) + .WillRepeatedly(Return(true)); + setupSensor(ABS_RX, InputDeviceSensorType::GYROSCOPE, /*sensorDataIndex=*/0); + setupSensor(ABS_RY, InputDeviceSensorType::GYROSCOPE, /*sensorDataIndex=*/1); + setupSensor(ABS_RZ, InputDeviceSensorType::GYROSCOPE, /*sensorDataIndex=*/2); + setupAxis(ABS_RX, /*valid=*/true, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_RESOLUTION, + GYRO_RAW_FLAT, GYRO_RAW_FUZZ); + setupAxis(ABS_RY, /*valid=*/true, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_RESOLUTION, + GYRO_RAW_FLAT, GYRO_RAW_FUZZ); + setupAxis(ABS_RZ, /*valid=*/true, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_RESOLUTION, + GYRO_RAW_FLAT, GYRO_RAW_FUZZ); + mPropertyMap.addProperty("sensor.gyroscope.reportingMode", "0"); + mPropertyMap.addProperty("sensor.gyroscope.maxDelay", "100000"); + mPropertyMap.addProperty("sensor.gyroscope.minDelay", "5000"); + mPropertyMap.addProperty("sensor.gyroscope.power", "0.8"); + mMapper = createInputMapper<SensorInputMapper>(*mDeviceContext, + mFakePolicy->getReaderConfiguration()); + + EXPECT_CALL(mMockEventHub, enableDevice(EVENTHUB_ID)); + ASSERT_TRUE(mMapper->enableSensor(InputDeviceSensorType::GYROSCOPE, + std::chrono::microseconds(10000), + std::chrono::microseconds(0))); + std::list<NotifyArgs> args; + args += process(ARBITRARY_TIME, EV_ABS, ABS_RX, 20000); + args += process(ARBITRARY_TIME, EV_ABS, ABS_RY, -20000); + args += process(ARBITRARY_TIME, EV_ABS, ABS_RZ, 40000); + args += process(ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, 1000); + args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); + std::vector<float> values = {20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT, -20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT, 40000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT}; - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args)); - ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR); - ASSERT_EQ(args.deviceId, DEVICE_ID); - ASSERT_EQ(args.sensorType, InputDeviceSensorType::GYROSCOPE); - ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH); - ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME); - ASSERT_EQ(args.values, values); - mapper.flushSensor(InputDeviceSensorType::GYROSCOPE); + ASSERT_EQ(args.size(), 1u); + const NotifySensorArgs& arg = std::get<NotifySensorArgs>(args.front()); + ASSERT_EQ(arg.source, AINPUT_SOURCE_SENSOR); + ASSERT_EQ(arg.deviceId, DEVICE_ID); + ASSERT_EQ(arg.sensorType, InputDeviceSensorType::GYROSCOPE); + ASSERT_EQ(arg.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH); + ASSERT_EQ(arg.hwTimestamp, ARBITRARY_TIME); + ASSERT_EQ(arg.values, values); + mMapper->flushSensor(InputDeviceSensorType::GYROSCOPE); } } // namespace android
\ No newline at end of file diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h index 4e080b356b..a5e9dded8b 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h @@ -148,9 +148,6 @@ public: virtual std::optional<LayerSettings> prepareClientComposition( ClientCompositionTargetSettings&) const = 0; - // Called after the layer is displayed to update the presentation fence - virtual void onLayerDisplayed(ftl::SharedFuture<FenceResult>, ui::LayerStack layerStack) = 0; - // Initializes a promise for a buffer release fence and provides the future for that // fence. This should only be called when a promise has not yet been created, or // after the previous promise has already been fulfilled. Attempting to call this diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h index cc491c2853..712b55123f 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h @@ -105,7 +105,7 @@ private: aidl::android::hardware::graphics::composer3::Composition from, aidl::android::hardware::graphics::composer3::Composition to) const; bool isClientCompositionForced(bool isPeekingThrough) const; - void updateLuts(std::shared_ptr<gui::DisplayLuts> luts, + void updateLuts(const LayerFECompositionState&, const std::optional<std::vector<std::optional<LutProperties>>>& properties); }; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h index 05a5d3838c..c7ff704491 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h @@ -50,9 +50,6 @@ public: std::optional<compositionengine::LayerFE::LayerSettings>( compositionengine::LayerFE::ClientCompositionTargetSettings&)); - MOCK_METHOD(void, onLayerDisplayed, (ftl::SharedFuture<FenceResult>, ui::LayerStack), - (override)); - MOCK_METHOD0(createReleaseFenceFuture, ftl::Future<FenceResult>()); MOCK_METHOD1(setReleaseFence, void(const FenceResult&)); MOCK_METHOD0(getReleaseFencePromiseStatus, LayerFE::ReleaseFencePromiseStatus()); diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp index e31d6848eb..f6d9a1ae6c 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp @@ -288,8 +288,13 @@ uint32_t OutputLayer::calculateOutputRelativeBufferTransform( } void OutputLayer::updateLuts( - std::shared_ptr<gui::DisplayLuts> layerFEStateLut, + const LayerFECompositionState& layerFEState, const std::optional<std::vector<std::optional<LutProperties>>>& properties) { + auto& luts = layerFEState.luts; + if (!luts) { + return; + } + auto& state = editState(); if (!properties) { @@ -305,7 +310,7 @@ void OutputLayer::updateLuts( } } - for (const auto& inputLut : layerFEStateLut->lutProperties) { + for (const auto& inputLut : luts->lutProperties) { bool foundInHwcLuts = false; for (const auto& hwcLut : hwcLutProperties) { if (static_cast<int32_t>(hwcLut.dimension) == @@ -318,7 +323,7 @@ void OutputLayer::updateLuts( break; } } - // if any lut properties of layerFEStateLut can not be found in hwcLutProperties, + // if any lut properties of luts can not be found in hwcLutProperties, // GPU composition instead if (!foundInHwcLuts) { state.forceClientComposition = true; @@ -411,10 +416,7 @@ void OutputLayer::updateCompositionState( state.whitePointNits = layerBrightnessNits; } - const auto& layerFEStateLut = layerFEState->luts; - if (layerFEStateLut) { - updateLuts(layerFEStateLut, properties); - } + updateLuts(*layerFEState, properties); // These are evaluated every frame as they can potentially change at any // time. diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp index 713a5c509e..ee9302b937 100644 --- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp +++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp @@ -163,7 +163,7 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta uint64_t clientChanges = what | layer_state_t::diff(clientState); layer_state_t::merge(clientState); what = clientChanges; - LLOGV(layerId, "requested=%" PRIu64 "flags=%" PRIu64, clientState.what, clientChanges); + LLOGV(layerId, "requested=%" PRIu64 " flags=%" PRIu64 " ", clientState.what, clientChanges); if (clientState.what & layer_state_t::eFlagsChanged) { if ((oldFlags ^ flags) & @@ -633,7 +633,7 @@ bool RequestedLayerState::isSimpleBufferUpdate(const layer_state_t& s) const { layer_state_t::eEdgeExtensionChanged | layer_state_t::eBufferCropChanged | layer_state_t::eDestinationFrameChanged | layer_state_t::eDimmingEnabledChanged | layer_state_t::eExtendedRangeBrightnessChanged | - layer_state_t::eDesiredHdrHeadroomChanged | + layer_state_t::eDesiredHdrHeadroomChanged | layer_state_t::eLutsChanged | (FlagManager::getInstance().latch_unsignaled_with_auto_refresh_changed() ? layer_state_t::eFlagsChanged : 0); diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp index a346981ae6..231b40b0ac 100644 --- a/services/surfaceflinger/LayerFE.cpp +++ b/services/surfaceflinger/LayerFE.cpp @@ -27,7 +27,6 @@ #include "LayerFE.h" #include "SurfaceFlinger.h" #include "ui/FenceResult.h" -#include "ui/LayerStack.h" namespace android { @@ -343,11 +342,6 @@ void LayerFE::prepareShadowClientComposition(LayerFE::LayerSettings& caster, caster.shadow = state; } -void LayerFE::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult, - ui::LayerStack layerStack) { - mCompositionResult.releaseFences.emplace_back(std::move(futureFenceResult), layerStack); -} - CompositionResult&& LayerFE::stealCompositionResult() { return std::move(mCompositionResult); } diff --git a/services/surfaceflinger/LayerFE.h b/services/surfaceflinger/LayerFE.h index 658f949640..5081e102b8 100644 --- a/services/surfaceflinger/LayerFE.h +++ b/services/surfaceflinger/LayerFE.h @@ -22,14 +22,12 @@ #include "compositionengine/LayerFE.h" #include "compositionengine/LayerFECompositionState.h" #include "renderengine/LayerSettings.h" -#include "ui/LayerStack.h" #include <ftl/future.h> namespace android { struct CompositionResult { - std::vector<std::pair<ftl::SharedFuture<FenceResult>, ui::LayerStack>> releaseFences; sp<Fence> lastClientCompositionFence = nullptr; }; @@ -41,7 +39,6 @@ public: // compositionengine::LayerFE overrides const compositionengine::LayerFECompositionState* getCompositionState() const override; bool onPreComposition(bool updatingOutputGeometryThisFrame) override; - void onLayerDisplayed(ftl::SharedFuture<FenceResult>, ui::LayerStack) override; const char* getDebugName() const override; int32_t getSequence() const override; bool hasRoundedCorners() const override; diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp index e6fed63d96..7b6e4bff6a 100644 --- a/services/surfaceflinger/tests/Credentials_test.cpp +++ b/services/surfaceflinger/tests/Credentials_test.cpp @@ -341,9 +341,9 @@ TEST_F(CredentialsTest, TransactionPermissionTest) { WindowInfosListenerUtils windowInfosListenerUtils; std::string name = "Test Layer"; sp<IBinder> token = sp<BBinder>::make(); - WindowInfo windowInfo; - windowInfo.name = name; - windowInfo.token = token; + auto windowInfo = sp<gui::WindowInfoHandle>::make(); + windowInfo->editInfo()->name = name; + windowInfo->editInfo()->token = token; sp<SurfaceControl> surfaceControl = mComposerClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceBufferState); @@ -370,7 +370,8 @@ TEST_F(CredentialsTest, TransactionPermissionTest) { UIDFaker f(AID_SYSTEM); auto windowIsPresentAndNotTrusted = [&](const std::vector<WindowInfo>& windowInfos) { auto foundWindowInfo = - WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos); + WindowInfosListenerUtils::findMatchingWindowInfo(*windowInfo->getInfo(), + windowInfos); if (!foundWindowInfo) { return false; } @@ -386,7 +387,8 @@ TEST_F(CredentialsTest, TransactionPermissionTest) { Transaction().setTrustedOverlay(surfaceControl, true).apply(/*synchronous=*/true); auto windowIsPresentAndTrusted = [&](const std::vector<WindowInfo>& windowInfos) { auto foundWindowInfo = - WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos); + WindowInfosListenerUtils::findMatchingWindowInfo(*windowInfo->getInfo(), + windowInfos); if (!foundWindowInfo) { return false; } diff --git a/services/surfaceflinger/tests/WindowInfosListener_test.cpp b/services/surfaceflinger/tests/WindowInfosListener_test.cpp index ad9a674456..2dd0dd9bd3 100644 --- a/services/surfaceflinger/tests/WindowInfosListener_test.cpp +++ b/services/surfaceflinger/tests/WindowInfosListener_test.cpp @@ -50,9 +50,9 @@ protected: TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { std::string name = "Test Layer"; sp<IBinder> token = sp<BBinder>::make(); - WindowInfo windowInfo; - windowInfo.name = name; - windowInfo.token = token; + auto windowInfo = sp<gui::WindowInfoHandle>::make(); + windowInfo->editInfo()->name = name; + windowInfo->editInfo()->token = token; sp<SurfaceControl> surfaceControl = mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceBufferState); @@ -65,14 +65,14 @@ TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { .apply(); auto windowPresent = [&](const std::vector<WindowInfo>& windowInfos) { - return findMatchingWindowInfo(windowInfo, windowInfos); + return findMatchingWindowInfo(*windowInfo->getInfo(), windowInfos); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowPresent)); Transaction().reparent(surfaceControl, nullptr).apply(); auto windowNotPresent = [&](const std::vector<WindowInfo>& windowInfos) { - return !findMatchingWindowInfo(windowInfo, windowInfos); + return !findMatchingWindowInfo(*windowInfo->getInfo(), windowInfos); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowNotPresent)); } @@ -80,9 +80,9 @@ TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { TEST_F(WindowInfosListenerTest, WindowInfoChanged) { std::string name = "Test Layer"; sp<IBinder> token = sp<BBinder>::make(); - WindowInfo windowInfo; - windowInfo.name = name; - windowInfo.token = token; + auto windowInfo = sp<gui::WindowInfoHandle>::make(); + windowInfo->editInfo()->name = name; + windowInfo->editInfo()->token = token; sp<SurfaceControl> surfaceControl = mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceBufferState); @@ -96,7 +96,7 @@ TEST_F(WindowInfosListenerTest, WindowInfoChanged) { .apply(); auto windowIsPresentAndTouchableRegionEmpty = [&](const std::vector<WindowInfo>& windowInfos) { - auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); + auto foundWindowInfo = findMatchingWindowInfo(*windowInfo->getInfo(), windowInfos); if (!foundWindowInfo) { return false; } @@ -104,19 +104,19 @@ TEST_F(WindowInfosListenerTest, WindowInfoChanged) { }; ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionEmpty)); - windowInfo.addTouchableRegion({0, 0, 50, 50}); + windowInfo->editInfo()->addTouchableRegion({0, 0, 50, 50}); Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply(); auto windowIsPresentAndTouchableRegionMatches = [&](const std::vector<WindowInfo>& windowInfos) { - auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos); + auto foundWindowInfo = findMatchingWindowInfo(*windowInfo->getInfo(), windowInfos); if (!foundWindowInfo) { return false; } auto touchableRegion = foundWindowInfo->transform.transform(foundWindowInfo->touchableRegion); - return touchableRegion.hasSameRects(windowInfo.touchableRegion); + return touchableRegion.hasSameRects(windowInfo->getInfo()->touchableRegion); }; ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionMatches)); } |