diff options
20 files changed, 275 insertions, 8 deletions
diff --git a/headers/media_plugin/media/cas/DescramblerAPI.h b/headers/media_plugin/media/cas/DescramblerAPI.h index 033c8ce7f9..c57f606077 100644 --- a/headers/media_plugin/media/cas/DescramblerAPI.h +++ b/headers/media_plugin/media/cas/DescramblerAPI.h @@ -72,12 +72,12 @@ struct DescramblerPlugin { // associated MediaCas session is used to load decryption keys // into the crypto/cas plugin. The keys are then referenced by key-id // in the 'key' parameter to the decrypt() method. - // Should return NO_ERROR on success, ERROR_DRM_SESSION_NOT_OPENED if + // Should return NO_ERROR on success, ERROR_CAS_SESSION_NOT_OPENED if // the session is not opened and a code from MediaErrors.h otherwise. virtual status_t setMediaCasSession(const CasSessionId& sessionId) = 0; // If the error returned falls into the range - // ERROR_DRM_VENDOR_MIN..ERROR_DRM_VENDOR_MAX, errorDetailMsg should be + // ERROR_CAS_VENDOR_MIN..ERROR_CAS_VENDOR_MAX, errorDetailMsg should be // filled in with an appropriate string. // At the java level these special errors will then trigger a // MediaCodec.CryptoException that gives clients access to both diff --git a/include/android/trace.h b/include/android/trace.h index aa24995cae..bb7ff28f79 100644 --- a/include/android/trace.h +++ b/include/android/trace.h @@ -33,6 +33,7 @@ #define ANDROID_NATIVE_TRACE_H #include <stdbool.h> +#include <stdint.h> #include <sys/cdefs.h> #ifdef __cplusplus @@ -73,6 +74,40 @@ void ATrace_endSection() __INTRODUCED_IN(23); #endif /* __ANDROID_API__ >= 23 */ +#if __ANDROID_API__ >= __ANDROID_API_Q__ + +/** + * Writes a trace message to indicate that a given section of code has + * begun. Must be followed by a call to {@link ATrace_endAsyncSection} with the same + * methodName and cookie. Unlike {@link ATrace_beginSection} and {@link ATrace_endSection}, + * asynchronous events do not need to be nested. The name and cookie used to + * begin an event must be used to end it. + * + * \param sectionName The method name to appear in the trace. + * \param cookie Unique identifier for distinguishing simultaneous events + */ +void ATrace_beginAsyncSection(const char* sectionName, int32_t cookie) __INTRODUCED_IN(29); + +/** + * Writes a trace message to indicate that the current method has ended. + * Must be called exactly once for each call to {@link ATrace_beginAsyncSection} + * using the same name and cookie. + * + * \param methodName The method name to appear in the trace. + * \param cookie Unique identifier for distinguishing simultaneous events + */ +void ATrace_endAsyncSection(const char* sectionName, int32_t cookie) __INTRODUCED_IN(29); + +/** + * Writes trace message to indicate the value of a given counter. + * + * \param counterName The counter name to appear in the trace. + * \param counterValue The counter value. + */ +void ATrace_setCounter(const char* counterName, int64_t counterValue) __INTRODUCED_IN(29); + +#endif /* __ANDROID_API__ >= 29 */ + #ifdef __cplusplus }; #endif diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 7d2615166f..f1fefcc14b 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -651,6 +651,49 @@ public: &reply); return result; } + + virtual status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames, + uint64_t timestamp, + DisplayedFrameStats* outStats) const { + if (!outStats) return BAD_VALUE; + + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + data.writeStrongBinder(display); + data.writeUint64(maxFrames); + data.writeUint64(timestamp); + + status_t result = + remote()->transact(BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLE, data, &reply); + + if (result != NO_ERROR) { + return result; + } + + result = reply.readUint64(&outStats->numFrames); + if (result != NO_ERROR) { + return result; + } + + result = reply.readInt64Vector( + reinterpret_cast<std::vector<int64_t>*>(&outStats->component_0_sample)); + if (result != NO_ERROR) { + return result; + } + result = reply.readInt64Vector( + reinterpret_cast<std::vector<int64_t>*>(&outStats->component_1_sample)); + if (result != NO_ERROR) { + return result; + } + result = reply.readInt64Vector( + reinterpret_cast<std::vector<int64_t>*>(&outStats->component_2_sample)); + if (result != NO_ERROR) { + return result; + } + result = reply.readInt64Vector( + reinterpret_cast<std::vector<int64_t>*>(&outStats->component_3_sample)); + return result; + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -1055,6 +1098,40 @@ status_t BnSurfaceComposer::onTransact( return setDisplayContentSamplingEnabled(display, enable, static_cast<uint8_t>(componentMask), maxFrames); } + case GET_DISPLAYED_CONTENT_SAMPLE: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + + sp<IBinder> display = data.readStrongBinder(); + uint64_t maxFrames = 0; + uint64_t timestamp = 0; + + status_t result = data.readUint64(&maxFrames); + if (result != NO_ERROR) { + ALOGE("getDisplayedContentSample failure in reading max frames: %d", result); + return result; + } + + result = data.readUint64(×tamp); + if (result != NO_ERROR) { + ALOGE("getDisplayedContentSample failure in reading timestamp: %d", result); + return result; + } + + DisplayedFrameStats stats; + result = getDisplayedContentSample(display, maxFrames, timestamp, &stats); + if (result == NO_ERROR) { + reply->writeUint64(stats.numFrames); + reply->writeInt64Vector( + *reinterpret_cast<std::vector<int64_t>*>(&stats.component_0_sample)); + reply->writeInt64Vector( + *reinterpret_cast<std::vector<int64_t>*>(&stats.component_1_sample)); + reply->writeInt64Vector( + *reinterpret_cast<std::vector<int64_t>*>(&stats.component_2_sample)); + reply->writeInt64Vector( + *reinterpret_cast<std::vector<int64_t>*>(&stats.component_3_sample)); + } + return result; + } default: { return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 34a7742426..95862199eb 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1120,6 +1120,12 @@ status_t SurfaceComposerClient::setDisplayContentSamplingEnabled(const sp<IBinde maxFrames); } +status_t SurfaceComposerClient::getDisplayedContentSample(const sp<IBinder>& display, + uint64_t maxFrames, uint64_t timestamp, + DisplayedFrameStats* outStats) { + return ComposerService::getComposerService()->getDisplayedContentSample(display, maxFrames, + timestamp, outStats); +} // ---------------------------------------------------------------------------- status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace, diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 41369c855a..3052c0b312 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -27,10 +27,11 @@ #include <binder/IInterface.h> +#include <ui/DisplayedFrameStats.h> #include <ui/FrameStats.h> -#include <ui/PixelFormat.h> #include <ui/GraphicBuffer.h> #include <ui/GraphicTypes.h> +#include <ui/PixelFormat.h> #include <vector> @@ -308,6 +309,14 @@ public: virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable, uint8_t componentMask, uint64_t maxFrames) const = 0; + + /* Returns statistics on the color profile of the last frame displayed for a given display + * + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames, + uint64_t timestamp, + DisplayedFrameStats* outStats) const = 0; }; // ---------------------------------------------------------------------------- @@ -349,6 +358,7 @@ public: GET_COLOR_MANAGEMENT, GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES, SET_DISPLAY_CONTENT_SAMPLING_ENABLED, + GET_DISPLAYED_CONTENT_SAMPLE, }; virtual status_t onTransact(uint32_t code, const Parcel& data, diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 5bbb39933c..8e3ba78108 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -30,6 +30,7 @@ #include <utils/SortedVector.h> #include <utils/threads.h> +#include <ui/DisplayedFrameStats.h> #include <ui/FrameStats.h> #include <ui/GraphicTypes.h> #include <ui/PixelFormat.h> @@ -390,6 +391,9 @@ public: static status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable, uint8_t componentMask, uint64_t maxFrames); + static status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames, + uint64_t timestamp, DisplayedFrameStats* outStats); + private: virtual void onFirstRef(); diff --git a/libs/gui/tests/DisplayedContentSampling_test.cpp b/libs/gui/tests/DisplayedContentSampling_test.cpp index f9d5dd632b..5443812bff 100644 --- a/libs/gui/tests/DisplayedContentSampling_test.cpp +++ b/libs/gui/tests/DisplayedContentSampling_test.cpp @@ -104,4 +104,19 @@ TEST_F(DisplayedContentSamplingTest, SelectivelyDisableComponentOk) { 0); EXPECT_EQ(OK, status); } + +TEST_F(DisplayedContentSamplingTest, SampleCollectionCoherentWithSupportMask) { + if (shouldSkipTest()) return; + + DisplayedFrameStats stats; + status_t status = mComposerClient->getDisplayedContentSample(mDisplayToken, 0, 0, &stats); + EXPECT_EQ(OK, status); + if (stats.numFrames <= 0) return; + + if (componentMask & (0x1 << 0)) EXPECT_NE(0, stats.component_0_sample.size()); + if (componentMask & (0x1 << 1)) EXPECT_NE(0, stats.component_1_sample.size()); + if (componentMask & (0x1 << 2)) EXPECT_NE(0, stats.component_2_sample.size()); + if (componentMask & (0x1 << 3)) EXPECT_NE(0, stats.component_3_sample.size()); +} + } // namespace android diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index cb1756f15b..d37b81096b 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -652,6 +652,11 @@ public: uint64_t /*maxFrames*/) const override { return NO_ERROR; } + status_t getDisplayedContentSample(const sp<IBinder>& /*display*/, uint64_t /*maxFrames*/, + uint64_t /*timestamp*/, + DisplayedFrameStats* /*outStats*/) const override { + return NO_ERROR; + } virtual status_t getColorManagement(bool* /*outGetColorManagement*/) const { return NO_ERROR; } diff --git a/libs/ui/include/ui/DisplayedFrameStats.h b/libs/ui/include/ui/DisplayedFrameStats.h new file mode 100644 index 0000000000..7a70ea1f06 --- /dev/null +++ b/libs/ui/include/ui/DisplayedFrameStats.h @@ -0,0 +1,41 @@ +/* + * Copyright 2018 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 <vector> + +namespace android { + +struct DisplayedFrameStats { + /* The number of frames represented by this sample. */ + uint64_t numFrames = 0; + /* A histogram counting how many times a pixel of a given value was displayed onscreen for + * FORMAT_COMPONENT_0. The buckets of the histogram are evenly weighted, the number of buckets + * is device specific. eg, for RGBA_8888, if sampleComponent0 is {10, 6, 4, 1} this means that + * 10 red pixels were displayed onscreen in range 0x00->0x3F, 6 red pixels + * were displayed onscreen in range 0x40->0x7F, etc. + */ + std::vector<uint64_t> component_0_sample = {}; + /* The same sample definition as sampleComponent0, but for FORMAT_COMPONENT_1. */ + std::vector<uint64_t> component_1_sample = {}; + /* The same sample definition as sampleComponent0, but for FORMAT_COMPONENT_2. */ + std::vector<uint64_t> component_2_sample = {}; + /* The same sample definition as sampleComponent0, but for FORMAT_COMPONENT_3. */ + std::vector<uint64_t> component_3_sample = {}; +}; + +} // namespace android diff --git a/libs/ui/include_vndk/ui/DisplayedFrameStats.h b/libs/ui/include_vndk/ui/DisplayedFrameStats.h new file mode 120000 index 0000000000..6014e1954a --- /dev/null +++ b/libs/ui/include_vndk/ui/DisplayedFrameStats.h @@ -0,0 +1 @@ +../../include/ui/DisplayedFrameStats.h
\ No newline at end of file diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index b83b84a281..48fd47fdbe 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -413,10 +413,9 @@ void DisplayDevice::queueBuffer(HWComposer& hwc) { if (mGraphicBuffer == nullptr) { ALOGE("No buffer is ready for display [%s]", mDisplayName.c_str()); } else { - int fd = mBufferReady.release(); - status_t res = mNativeWindow->queueBuffer(mNativeWindow.get(), - mGraphicBuffer->getNativeBuffer(), fd); + mGraphicBuffer->getNativeBuffer(), + dup(mBufferReady)); if (res != NO_ERROR) { ALOGE("Error when queueing buffer for display [%s]: %d", mDisplayName.c_str(), res); // We risk blocking on dequeueBuffer if the primary display failed @@ -425,9 +424,12 @@ void DisplayDevice::queueBuffer(HWComposer& hwc) { LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", res); } else { mNativeWindow->cancelBuffer(mNativeWindow.get(), - mGraphicBuffer->getNativeBuffer(), fd); + mGraphicBuffer->getNativeBuffer(), + dup(mBufferReady)); } } + + mBufferReady.reset(); mGraphicBuffer = nullptr; } } diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index 3b7ed155ba..d6237cbdfc 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -1079,6 +1079,31 @@ Error Composer::setDisplayContentSamplingEnabled(Display display, bool enabled, maxFrames); } +Error Composer::getDisplayedContentSample(Display display, uint64_t maxFrames, uint64_t timestamp, + DisplayedFrameStats* outStats) { + if (!outStats) { + return Error::BAD_PARAMETER; + } + if (!mClient_2_3) { + return Error::UNSUPPORTED; + } + Error error = kDefaultError; + mClient_2_3->getDisplayedContentSample(display, maxFrames, timestamp, + [&](const auto tmpError, auto tmpNumFrames, + const auto& tmpSamples0, const auto& tmpSamples1, + const auto& tmpSamples2, const auto& tmpSamples3) { + error = tmpError; + if (error == Error::NONE) { + outStats->numFrames = tmpNumFrames; + outStats->component_0_sample = tmpSamples0; + outStats->component_1_sample = tmpSamples1; + outStats->component_2_sample = tmpSamples2; + outStats->component_3_sample = tmpSamples3; + } + }); + return error; +} + CommandReader::~CommandReader() { resetData(); diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 0db12a16cf..38ee7ad545 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -30,6 +30,7 @@ #include <composer-command-buffer/2.3/ComposerCommandBuffer.h> #include <gui/HdrMetadata.h> #include <math/mat4.h> +#include <ui/DisplayedFrameStats.h> #include <ui/GraphicBuffer.h> #include <utils/StrongPointer.h> @@ -194,6 +195,8 @@ public: uint8_t* outComponentMask) = 0; virtual Error setDisplayContentSamplingEnabled(Display display, bool enabled, uint8_t componentMask, uint64_t maxFrames) = 0; + virtual Error getDisplayedContentSample(Display display, uint64_t maxFrames, uint64_t timestamp, + DisplayedFrameStats* outStats) = 0; virtual Error getDisplayCapabilities(Display display, std::vector<DisplayCapability>* outCapabilities) = 0; }; @@ -400,6 +403,8 @@ public: uint8_t* outComponentMask) override; Error setDisplayContentSamplingEnabled(Display display, bool enabled, uint8_t componentMask, uint64_t maxFrames) override; + Error getDisplayedContentSample(Display display, uint64_t maxFrames, uint64_t timestamp, + DisplayedFrameStats* outStats) override; Error getDisplayCapabilities(Display display, std::vector<DisplayCapability>* outCapabilities) override; diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index 733a5dae43..d2aa4ad031 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -562,6 +562,12 @@ Error Display::setDisplayContentSamplingEnabled(bool enabled, uint8_t componentM return static_cast<Error>(intError); } +Error Display::getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp, + android::DisplayedFrameStats* outStats) const { + auto intError = mComposer.getDisplayedContentSample(mId, maxFrames, timestamp, outStats); + return static_cast<Error>(intError); +} + Error Display::getReleaseFences( std::unordered_map<Layer*, sp<Fence>>* outFences) const { diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index 2d65051dff..f5cb97e061 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -40,6 +40,7 @@ #include "PowerAdvisor.h" namespace android { + struct DisplayedFrameStats; class Fence; class FloatRect; class GraphicBuffer; @@ -243,6 +244,8 @@ public: [[clang::warn_unused_result]] Error setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask, uint64_t maxFrames) const; + [[clang::warn_unused_result]] Error getDisplayedContentSample( + uint64_t maxFrames, uint64_t timestamp, android::DisplayedFrameStats* outStats) const; [[clang::warn_unused_result]] Error getReleaseFences( std::unordered_map<Layer*, android::sp<android::Fence>>* outFences) const; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 0aa0dfb5c3..0497571871 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -770,6 +770,16 @@ status_t HWComposer::setDisplayContentSamplingEnabled(DisplayId displayId, bool return NO_ERROR; } +status_t HWComposer::getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames, + uint64_t timestamp, DisplayedFrameStats* outStats) { + RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); + const auto error = + mDisplayData[displayId].hwcDisplay->getDisplayedContentSample(maxFrames, timestamp, + outStats); + RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); + return NO_ERROR; +} + bool HWComposer::isUsingVrComposer() const { return getComposer()->isUsingVrComposer(); } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index aaa6e8c255..d9a0916f85 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -36,6 +36,7 @@ namespace android { +struct DisplayedFrameStats; class GraphicBuffer; class TestableSurfaceFlinger; struct CompositionInfo; @@ -132,6 +133,8 @@ public: uint8_t* outComponentMask); status_t setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled, uint8_t componentMask, uint64_t maxFrames); + status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames, uint64_t timestamp, + DisplayedFrameStats* outStats); // Events handling --------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 43932e093e..a142928153 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1146,6 +1146,19 @@ status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& dis componentMask, maxFrames); } +status_t SurfaceFlinger::getDisplayedContentSample(const sp<IBinder>& displayToken, + uint64_t maxFrames, uint64_t timestamp, + DisplayedFrameStats* outStats) const { + const auto display = getDisplayDevice(displayToken); + if (!display || !display->getId()) { + ALOGE("getDisplayContentSample: Bad display token: %p", displayToken.get()); + return BAD_VALUE; + } + + return getHwComposer().getDisplayedContentSample(*display->getId(), maxFrames, timestamp, + outStats); +} + status_t SurfaceFlinger::enableVSyncInjections(bool enable) { postMessageSync(new LambdaMessage([&] { Mutex::Autolock _l(mStateLock); @@ -4787,7 +4800,8 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case INJECT_VSYNC: case SET_POWER_MODE: case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES: - case SET_DISPLAY_CONTENT_SAMPLING_ENABLED: { + case SET_DISPLAY_CONTENT_SAMPLING_ENABLED: + case GET_DISPLAYED_CONTENT_SAMPLE: { if (!callingThreadHasUnscopedSurfaceFlingerAccess()) { IPCThreadState* ipc = IPCThreadState::self(); ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index bff847e8a0..9f520583fe 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -486,6 +486,9 @@ private: virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable, uint8_t componentMask, uint64_t maxFrames) const override; + virtual status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames, + uint64_t timestamp, + DisplayedFrameStats* outStats) const override; /* ------------------------------------------------------------------------ * DeathRecipient interface diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h index 68fd8b4907..dfdda099b3 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -116,6 +116,8 @@ public: MOCK_METHOD4(getDisplayedContentSamplingAttributes, Error(Display, PixelFormat*, Dataspace*, uint8_t*)); MOCK_METHOD4(setDisplayContentSamplingEnabled, Error(Display, bool, uint8_t, uint64_t)); + MOCK_METHOD4(getDisplayedContentSample, + Error(Display, uint64_t, uint64_t, DisplayedFrameStats*)); MOCK_METHOD2(getDisplayCapabilities, Error(Display, std::vector<DisplayCapability>*)); }; |