diff options
author | 2018-12-06 10:47:26 -0800 | |
---|---|---|
committer | 2019-01-25 09:26:29 -0800 | |
commit | 1f6d6d5db93ef4c3bbaeb5241eede30635fa5ff1 (patch) | |
tree | cc086700fc2736de362636bfc5f918f947fa06bd | |
parent | 57ba2f1942f1fae1bd195b8c0f7fda8adbf9c41e (diff) |
Add metadata store to surfaces
This adds a key/value metadata storage mechanism to
surfaces that allows the windowmanager to pass information
to the surfaceflinger frontend.
This then moves the existing metadata (window type and
ownerUID) into this metadata structure.
Bug: 122925737
Test: Phone boots and surfaces fling. Some unittests
Change-Id: I72c574737b7f75be2311a341812b15d385f507ed
21 files changed, 401 insertions, 128 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 3521e89ae6..b148015c14 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -108,6 +108,7 @@ cc_library_shared { "ISurfaceComposerClient.cpp", "ITransactionCompletedListener.cpp", "LayerDebugInfo.cpp", + "LayerMetadata.cpp", "LayerState.cpp", "OccupancyTracker.cpp", "StreamSplitter.cpp", diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp index 928ef95aa8..129558bd15 100644 --- a/libs/gui/ISurfaceComposerClient.cpp +++ b/libs/gui/ISurfaceComposerClient.cpp @@ -47,26 +47,26 @@ public: ~BpSurfaceComposerClient() override; status_t createSurface(const String8& name, uint32_t width, uint32_t height, PixelFormat format, - uint32_t flags, const sp<IBinder>& parent, int32_t windowType, - int32_t ownerUid, sp<IBinder>* handle, - sp<IGraphicBufferProducer>* gbp) override { + uint32_t flags, const sp<IBinder>& parent, LayerMetadata metadata, + sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) override { return callRemote<decltype(&ISurfaceComposerClient::createSurface)>(Tag::CREATE_SURFACE, name, width, height, format, flags, parent, - windowType, ownerUid, + std::move(metadata), handle, gbp); } status_t createWithSurfaceParent(const String8& name, uint32_t width, uint32_t height, PixelFormat format, uint32_t flags, - const sp<IGraphicBufferProducer>& parent, int32_t windowType, - int32_t ownerUid, sp<IBinder>* handle, + const sp<IGraphicBufferProducer>& parent, + LayerMetadata metadata, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) override { return callRemote<decltype( &ISurfaceComposerClient::createWithSurfaceParent)>(Tag::CREATE_WITH_SURFACE_PARENT, name, width, height, format, - flags, parent, windowType, - ownerUid, handle, gbp); + flags, parent, + std::move(metadata), handle, + gbp); } status_t clearLayerFrameStats(const sp<IBinder>& handle) const override { diff --git a/libs/gui/LayerMetadata.cpp b/libs/gui/LayerMetadata.cpp new file mode 100644 index 0000000000..c8a2b0754b --- /dev/null +++ b/libs/gui/LayerMetadata.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2019 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 <android-base/stringprintf.h> +#include <binder/Parcel.h> +#include <gui/LayerMetadata.h> + +using android::base::StringPrintf; + +namespace android { + +LayerMetadata::LayerMetadata() = default; + +LayerMetadata::LayerMetadata(std::unordered_map<uint32_t, std::vector<uint8_t>> map) + : mMap(std::move(map)) {} + +LayerMetadata::LayerMetadata(const LayerMetadata& other) = default; + +LayerMetadata::LayerMetadata(LayerMetadata&& other) = default; + +void LayerMetadata::merge(const LayerMetadata& other) { + for (const auto& entry : other.mMap) { + mMap[entry.first] = entry.second; + } +} + +status_t LayerMetadata::writeToParcel(Parcel* parcel) const { + parcel->writeInt32(static_cast<int>(mMap.size())); + status_t status = OK; + for (const auto& entry : mMap) { + status = parcel->writeUint32(entry.first); + if (status != OK) { + break; + } + status = parcel->writeByteVector(entry.second); + if (status != OK) { + break; + } + } + return status; +} + +status_t LayerMetadata::readFromParcel(const Parcel* parcel) { + int size = parcel->readInt32(); + status_t status = OK; + mMap.clear(); + for (int i = 0; i < size; ++i) { + uint32_t key = parcel->readUint32(); + status = parcel->readByteVector(&mMap[key]); + if (status != OK) { + break; + } + } + return status; +} + +LayerMetadata& LayerMetadata::operator=(const LayerMetadata& other) { + mMap = other.mMap; + return *this; +} + +LayerMetadata& LayerMetadata::operator=(LayerMetadata&& other) { + mMap = std::move(other.mMap); + return *this; +} + +bool LayerMetadata::has(uint32_t key) const { + return mMap.count(key); +} + +int32_t LayerMetadata::getInt32(uint32_t key, int32_t fallback) const { + if (!has(key)) return fallback; + const std::vector<uint8_t>& data = mMap.at(key); + if (data.size() < sizeof(uint32_t)) return fallback; + Parcel p; + p.setData(data.data(), data.size()); + return p.readInt32(); +} + +void LayerMetadata::setInt32(uint32_t key, int32_t value) { + std::vector<uint8_t>& data = mMap[key]; + Parcel p; + p.writeInt32(value); + data.resize(p.dataSize()); + memcpy(data.data(), p.data(), p.dataSize()); +} + +std::string LayerMetadata::itemToString(uint32_t key, const char* separator) const { + if (!has(key)) return std::string(); + switch (key) { + case METADATA_OWNER_UID: + return StringPrintf("ownerUID%s%d", separator, getInt32(key, 0)); + case METADATA_WINDOW_TYPE: + return StringPrintf("windowType%s%d", separator, getInt32(key, 0)); + default: + return StringPrintf("%d%s%dbytes", key, separator, + static_cast<int>(mMap.at(key).size())); + } +} + +} // namespace android diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index ab929731f3..6091d3f08a 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -96,6 +96,7 @@ status_t layer_state_t::write(Parcel& output) const output.writeStrongBinder(cachedBuffer.token); output.writeInt32(cachedBuffer.bufferId); + output.writeParcelable(metadata); output.writeFloat(colorAlpha); output.writeUint32(static_cast<uint32_t>(colorDataspace)); @@ -172,6 +173,7 @@ status_t layer_state_t::read(const Parcel& input) cachedBuffer.token = input.readStrongBinder(); cachedBuffer.bufferId = input.readInt32(); + input.readParcelable(&metadata); colorAlpha = input.readFloat(); colorDataspace = static_cast<ui::Dataspace>(input.readUint32()); @@ -396,6 +398,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eColorDataspaceChanged; colorDataspace = other.colorDataspace; } + if (other.what & eMetadataChanged) { + what |= eMetadataChanged; + metadata.merge(other.metadata); + } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " "other.what=0x%" PRIu64 " what=0x%" PRIu64, diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 6c1c52e1bd..67d936100e 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -539,6 +539,20 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setMetadata( + const sp<SurfaceControl>& sc, uint32_t key, std::vector<uint8_t> data) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eMetadataChanged; + s->metadata.mMap[key] = std::move(data); + + registerSurfaceControlForCallback(sc); + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setMatrix( const sp<SurfaceControl>& sc, float dsdx, float dtdx, float dtdy, float dsdy) { @@ -1141,26 +1155,19 @@ void SurfaceComposerClient::dispose() { mStatus = NO_INIT; } -sp<SurfaceControl> SurfaceComposerClient::createSurface( - const String8& name, - uint32_t w, - uint32_t h, - PixelFormat format, - uint32_t flags, - SurfaceControl* parent, - int32_t windowType, - int32_t ownerUid) -{ +sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h, + PixelFormat format, uint32_t flags, + SurfaceControl* parent, + LayerMetadata metadata) { sp<SurfaceControl> s; - createSurfaceChecked(name, w, h, format, &s, flags, parent, windowType, ownerUid); + createSurfaceChecked(name, w, h, format, &s, flags, parent, std::move(metadata)); return s; } sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, Surface* parent, - int32_t windowType, - int32_t ownerUid) { + LayerMetadata metadata) { sp<SurfaceControl> sur; status_t err = mStatus; @@ -1169,8 +1176,8 @@ sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& sp<IGraphicBufferProducer> parentGbp = parent->getIGraphicBufferProducer(); sp<IGraphicBufferProducer> gbp; - err = mClient->createWithSurfaceParent(name, w, h, format, flags, parentGbp, windowType, - ownerUid, &handle, &gbp); + err = mClient->createWithSurfaceParent(name, w, h, format, flags, parentGbp, + std::move(metadata), &handle, &gbp); ALOGE_IF(err, "SurfaceComposerClient::createWithSurfaceParent error %s", strerror(-err)); if (err == NO_ERROR) { return new SurfaceControl(this, handle, gbp, true /* owned */); @@ -1179,17 +1186,11 @@ sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& return nullptr; } -status_t SurfaceComposerClient::createSurfaceChecked( - const String8& name, - uint32_t w, - uint32_t h, - PixelFormat format, - sp<SurfaceControl>* outSurface, - uint32_t flags, - SurfaceControl* parent, - int32_t windowType, - int32_t ownerUid) -{ +status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h, + PixelFormat format, + sp<SurfaceControl>* outSurface, uint32_t flags, + SurfaceControl* parent, + LayerMetadata metadata) { sp<SurfaceControl> sur; status_t err = mStatus; @@ -1201,8 +1202,9 @@ status_t SurfaceComposerClient::createSurfaceChecked( if (parent != nullptr) { parentHandle = parent->getHandle(); } - err = mClient->createSurface(name, w, h, format, flags, parentHandle, - windowType, ownerUid, &handle, &gbp); + + err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata), + &handle, &gbp); ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); if (err == NO_ERROR) { *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */); diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h index f443df8533..32ac9e8928 100644 --- a/libs/gui/include/gui/ISurfaceComposerClient.h +++ b/libs/gui/include/gui/ISurfaceComposerClient.h @@ -18,8 +18,11 @@ #include <binder/IInterface.h> #include <binder/SafeInterface.h> +#include <gui/LayerMetadata.h> #include <ui/PixelFormat.h> +#include <unordered_map> + namespace android { class FrameStats; @@ -51,8 +54,8 @@ public: * Requires ACCESS_SURFACE_FLINGER permission */ virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags, const sp<IBinder>& parent, int32_t windowType, - int32_t ownerUid, sp<IBinder>* handle, + uint32_t flags, const sp<IBinder>& parent, + LayerMetadata metadata, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) = 0; /* @@ -61,8 +64,7 @@ public: virtual status_t createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, const sp<IGraphicBufferProducer>& parent, - int32_t windowType, int32_t ownerUid, - sp<IBinder>* handle, + LayerMetadata metadata, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) = 0; /* diff --git a/libs/gui/include/gui/LayerMetadata.h b/libs/gui/include/gui/LayerMetadata.h new file mode 100644 index 0000000000..50121817d5 --- /dev/null +++ b/libs/gui/include/gui/LayerMetadata.h @@ -0,0 +1,49 @@ +/* + * Copyright 2019 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 <binder/Parcelable.h> + +#include <unordered_map> + +namespace android { + +enum { METADATA_OWNER_UID = 1, METADATA_WINDOW_TYPE = 2 }; + +struct LayerMetadata : public Parcelable { + std::unordered_map<uint32_t, std::vector<uint8_t>> mMap; + + LayerMetadata(); + LayerMetadata(const LayerMetadata& other); + LayerMetadata(LayerMetadata&& other); + explicit LayerMetadata(std::unordered_map<uint32_t, std::vector<uint8_t>> map); + LayerMetadata& operator=(const LayerMetadata& other); + LayerMetadata& operator=(LayerMetadata&& other); + + void merge(const LayerMetadata& other); + + status_t writeToParcel(Parcel* parcel) const override; + status_t readFromParcel(const Parcel* parcel) override; + + bool has(uint32_t key) const; + int32_t getInt32(uint32_t key, int32_t fallback) const; + void setInt32(uint32_t key, int32_t value); + + std::string itemToString(uint32_t key, const char* separator) const; +}; + +} // namespace android diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 9063e7fbb4..afd843f09e 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -30,6 +30,7 @@ #include <input/InputWindow.h> #endif +#include <gui/LayerMetadata.h> #include <math/vec3.h> #include <ui/GraphicTypes.h> #include <ui/Rect.h> @@ -87,6 +88,7 @@ struct layer_state_t { eCachedBufferChanged = 0x2'00000000, eColorAlphaChanged = 0x4'00000000, eColorDataspaceChanged = 0x8'00000000, + eMetadataChanged = 0x10'00000000, }; layer_state_t() @@ -187,6 +189,8 @@ struct layer_state_t { float colorAlpha; ui::Dataspace colorDataspace; + + LayerMetadata metadata; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 24b656b543..bffe3f98e0 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -159,39 +159,33 @@ public: static sp<SurfaceComposerClient> getDefault(); //! Create a surface - sp<SurfaceControl> createSurface( - const String8& name,// name of the surface - uint32_t w, // width in pixel - uint32_t h, // height in pixel - PixelFormat format, // pixel-format desired - uint32_t flags = 0, // usage flags - SurfaceControl* parent = nullptr, // parent - int32_t windowType = -1, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.) - int32_t ownerUid = -1 // UID of the task + sp<SurfaceControl> createSurface(const String8& name, // name of the surface + uint32_t w, // width in pixel + uint32_t h, // height in pixel + PixelFormat format, // pixel-format desired + uint32_t flags = 0, // usage flags + SurfaceControl* parent = nullptr, // parent + LayerMetadata metadata = LayerMetadata() // metadata ); - status_t createSurfaceChecked( - const String8& name, // name of the surface - uint32_t w, // width in pixel - uint32_t h, // height in pixel - PixelFormat format, // pixel-format desired - sp<SurfaceControl>* outSurface, - uint32_t flags = 0, // usage flags - SurfaceControl* parent = nullptr, // parent - int32_t windowType = -1, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.) - int32_t ownerUid = -1 // UID of the task + status_t createSurfaceChecked(const String8& name, // name of the surface + uint32_t w, // width in pixel + uint32_t h, // height in pixel + PixelFormat format, // pixel-format desired + sp<SurfaceControl>* outSurface, + uint32_t flags = 0, // usage flags + SurfaceControl* parent = nullptr, // parent + LayerMetadata metadata = LayerMetadata() // metadata ); //! Create a surface - sp<SurfaceControl> createWithSurfaceParent( - const String8& name, // name of the surface - uint32_t w, // width in pixel - uint32_t h, // height in pixel - PixelFormat format, // pixel-format desired - uint32_t flags = 0, // usage flags - Surface* parent = nullptr, // parent - int32_t windowType = -1, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.) - int32_t ownerUid = -1 // UID of the task + sp<SurfaceControl> createWithSurfaceParent(const String8& name, // name of the surface + uint32_t w, // width in pixel + uint32_t h, // height in pixel + PixelFormat format, // pixel-format desired + uint32_t flags = 0, // usage flags + Surface* parent = nullptr, // parent + LayerMetadata metadata = LayerMetadata() // metadata ); //! Create a virtual display @@ -302,6 +296,8 @@ public: Transaction& setCrop_legacy(const sp<SurfaceControl>& sc, const Rect& crop); Transaction& setCornerRadius(const sp<SurfaceControl>& sc, float cornerRadius); Transaction& setLayerStack(const sp<SurfaceControl>& sc, uint32_t layerStack); + Transaction& setMetadata(const sp<SurfaceControl>& sc, uint32_t key, + std::vector<uint8_t> data); // Defers applying any changes made in this transaction until the Layer // identified by handle reaches the given frameNumber. If the Layer identified // by handle is removed, then we will apply this transaction regardless of diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 0e447d87f2..0ca3759f07 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -73,14 +73,10 @@ sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const return lbc; } - -status_t Client::createSurface( - const String8& name, - uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, - const sp<IBinder>& parentHandle, int32_t windowType, int32_t ownerUid, - sp<IBinder>* handle, - sp<IGraphicBufferProducer>* gbp) -{ +status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format, + uint32_t flags, const sp<IBinder>& parentHandle, + LayerMetadata metadata, sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp) { sp<Layer> parent = nullptr; if (parentHandle != nullptr) { auto layerHandle = reinterpret_cast<Layer::Handle*>(parentHandle.get()); @@ -91,14 +87,14 @@ status_t Client::createSurface( } // We rely on createLayer to check permissions. - return mFlinger->createLayer(name, this, w, h, format, flags, windowType, - ownerUid, handle, gbp, &parent); + return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp, + &parent); } status_t Client::createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, const sp<IGraphicBufferProducer>& parent, - int32_t windowType, int32_t ownerUid, sp<IBinder>* handle, + LayerMetadata metadata, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) { if (mFlinger->authenticateSurfaceTexture(parent) == false) { return BAD_VALUE; @@ -111,8 +107,7 @@ status_t Client::createWithSurfaceParent(const String8& name, uint32_t w, uint32 sp<IBinder> parentHandle = layer->getHandle(); - return createSurface(name, w, h, format, flags, parentHandle, windowType, ownerUid, handle, - gbp); + return createSurface(name, w, h, format, flags, parentHandle, std::move(metadata), handle, gbp); } status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const { diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h index 0f5ee4c85c..74e48188d6 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -51,18 +51,16 @@ public: private: // ISurfaceComposerClient interface - virtual status_t createSurface( - const String8& name, - uint32_t w, uint32_t h,PixelFormat format, uint32_t flags, - const sp<IBinder>& parent, int32_t windowType, int32_t ownerUid, - sp<IBinder>* handle, - sp<IGraphicBufferProducer>* gbp); + virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format, + uint32_t flags, const sp<IBinder>& parent, + LayerMetadata metadata, sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp); virtual status_t createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, const sp<IGraphicBufferProducer>& parent, - int32_t windowType, int32_t ownerUid, - sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp); + LayerMetadata metadata, sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp); virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index ef77590761..272793a7b1 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -94,8 +94,6 @@ Layer::Layer(const LayerCreationArgs& args) mCurrentState.layerStack = 0; mCurrentState.sequence = 0; mCurrentState.requested_legacy = mCurrentState.active_legacy; - mCurrentState.appId = 0; - mCurrentState.type = 0; mCurrentState.active.w = UINT32_MAX; mCurrentState.active.h = UINT32_MAX; mCurrentState.active.transform.set(0, 0); @@ -600,14 +598,16 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { to_string(error).c_str(), static_cast<int32_t>(error)); getBE().compositionInfo.hwc.z = z; - int type = s.type; - int appId = s.appId; + int type = s.metadata.getInt32(METADATA_WINDOW_TYPE, 0); + int appId = s.metadata.getInt32(METADATA_OWNER_UID, 0); sp<Layer> parent = mDrawingParent.promote(); if (parent.get()) { auto& parentState = parent->getDrawingState(); - if (parentState.type >= 0 || parentState.appId >= 0) { - type = parentState.type; - appId = parentState.appId; + const int parentType = parentState.metadata.getInt32(METADATA_WINDOW_TYPE, 0); + const int parentAppId = parentState.metadata.getInt32(METADATA_OWNER_UID, 0); + if (parentType >= 0 || parentAppId >= 0) { + type = parentType; + appId = parentAppId; } } @@ -1316,11 +1316,14 @@ bool Layer::setOverrideScalingMode(int32_t scalingMode) { return true; } -void Layer::setInfo(int32_t type, int32_t appId) { - mCurrentState.appId = appId; - mCurrentState.type = type; +bool Layer::setMetadata(LayerMetadata data) { + bool changed = data.mMap != mCurrentState.metadata.mMap; + if (!changed) return false; + mCurrentState.metadata = std::move(data); + mCurrentState.sequence++; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); + return true; } bool Layer::setLayerStack(uint32_t layerStack) { @@ -2088,8 +2091,6 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) layerInfo->set_queued_frames(getQueuedFrameCount()); layerInfo->set_refresh_pending(isBufferLatched()); - layerInfo->set_window_type(state.type); - layerInfo->set_app_id(state.appId); layerInfo->set_curr_frame(mCurrentFrameNumber); layerInfo->set_effective_scaling_mode(getEffectiveScalingMode()); @@ -2101,6 +2102,11 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) barrierLayerProto->set_frame_number(pendingState.frameNumber_legacy); } } + + auto protoMap = layerInfo->mutable_metadata(); + for (const auto& entry : state.metadata.mMap) { + (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend()); + } } void Layer::writeToProto(LayerProto* layerInfo, DisplayId displayId) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 685f419d4a..b0efb54f97 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -167,8 +167,7 @@ public: Region activeTransparentRegion_legacy; Region requestedTransparentRegion_legacy; - int32_t appId; - int32_t type; + LayerMetadata metadata; // If non-null, a Surface this Surface's Z-order is interpreted relative to. wp<Layer> zOrderRelativeOf; @@ -284,7 +283,7 @@ public: uint64_t frameNumber); virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber); virtual bool setOverrideScalingMode(int32_t overrideScalingMode); - virtual void setInfo(int32_t type, int32_t appId); + virtual bool setMetadata(LayerMetadata data); virtual bool reparentChildren(const sp<IBinder>& layer); virtual void setChildrenDrawingParent(const sp<Layer>& layer); virtual bool reparent(const sp<IBinder>& newParentHandle); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 299499da12..04c1ba0ade 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3983,6 +3983,9 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState ALOGE("Attempt to update InputWindowInfo without permission ACCESS_SURFACE_FLINGER"); } } + if (what & layer_state_t::eMetadataChanged) { + if (layer->setMetadata(s.metadata)) flags |= eTraversalNeeded; + } std::vector<sp<CallbackHandle>> callbackHandles; if ((what & layer_state_t::eListenerCallbacksChanged) && (!s.listenerCallbacks.empty())) { mTransactionCompletedThread.run(); @@ -4011,13 +4014,10 @@ uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& input return flags; } -status_t SurfaceFlinger::createLayer( - const String8& name, - const sp<Client>& client, - uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, - int32_t windowType, int32_t ownerUid, sp<IBinder>* handle, - sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent) -{ +status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w, + uint32_t h, PixelFormat format, uint32_t flags, + LayerMetadata metadata, sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent) { if (int32_t(w|h) < 0) { ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", int(w), int(h)); @@ -4073,12 +4073,15 @@ status_t SurfaceFlinger::createLayer( // window type is WINDOW_TYPE_DONT_SCREENSHOT from SurfaceControl.java // TODO b/64227542 - if (windowType == 441731) { - windowType = 2024; // TYPE_NAVIGATION_BAR_PANEL - layer->setPrimaryDisplayOnly(); + if (metadata.has(METADATA_WINDOW_TYPE)) { + int32_t windowType = metadata.getInt32(METADATA_WINDOW_TYPE, 0); + if (windowType == 441731) { + metadata.setInt32(METADATA_WINDOW_TYPE, 2024); // TYPE_NAVIGATION_BAR_PANEL + layer->setPrimaryDisplayOnly(); + } } - layer->setInfo(windowType, ownerUid); + layer->setMetadata(std::move(metadata)); bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess(); result = addClientLayer(client, *handle, *gbp, layer, *parent, diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 68a602cf61..5219e2fdb8 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -141,7 +141,6 @@ enum class DisplayColorSetting : int32_t { ENHANCED = 2, }; - class SurfaceFlingerBE { public: @@ -556,10 +555,9 @@ private: /* ------------------------------------------------------------------------ * Layer management */ - status_t createLayer(const String8& name, const sp<Client>& client, - uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, - int32_t windowType, int32_t ownerUid, sp<IBinder>* handle, - sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent); + status_t createLayer(const String8& name, const sp<Client>& client, uint32_t w, uint32_t h, + PixelFormat format, uint32_t flags, LayerMetadata metadata, + sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent); status_t createBufferQueueLayer(const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, diff --git a/services/surfaceflinger/layerproto/Android.bp b/services/surfaceflinger/layerproto/Android.bp index ac147fe182..cb368b0886 100644 --- a/services/surfaceflinger/layerproto/Android.bp +++ b/services/surfaceflinger/layerproto/Android.bp @@ -1,6 +1,5 @@ cc_library_shared { name: "liblayers_proto", - vendor_available: true, export_include_dirs: ["include"], srcs: [ @@ -11,6 +10,7 @@ cc_library_shared { shared_libs: [ "android.hardware.graphics.common@1.1", + "libgui", "libui", "libprotobuf-cpp-lite", "libbase", diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp index d020a394ce..5c72fea375 100644 --- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp +++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp @@ -117,11 +117,15 @@ LayerProtoParser::Layer LayerProtoParser::generateLayer(const LayerProto& layerP layer.hwcFrame = generateRect(layerProto.hwc_frame()); layer.hwcCrop = generateFloatRect(layerProto.hwc_crop()); layer.hwcTransform = layerProto.hwc_transform(); - layer.windowType = layerProto.window_type(); - layer.appId = layerProto.app_id(); layer.hwcCompositionType = layerProto.hwc_composition_type(); layer.isProtected = layerProto.is_protected(); layer.cornerRadius = layerProto.corner_radius(); + for (const auto& entry : layerProto.metadata()) { + const std::string& dataStr = entry.second; + std::vector<uint8_t>& outData = layer.metadata.mMap[entry.first]; + outData.resize(dataStr.size()); + memcpy(outData.data(), dataStr.data(), dataStr.size()); + } return layer; } @@ -310,7 +314,14 @@ std::string LayerProtoParser::Layer::to_string() const { StringAppendF(&result, " activeBuffer=%s,", activeBuffer.to_string().c_str()); StringAppendF(&result, " tr=%s", bufferTransform.to_string().c_str()); StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d,", queuedFrames, refreshPending); - StringAppendF(&result, " windowType=%d, appId=%d", windowType, appId); + StringAppendF(&result, " metadata={"); + bool first = true; + for (const auto& entry : metadata.mMap) { + if (!first) result.append(", "); + first = false; + result.append(metadata.itemToString(entry.first, ":")); + } + result.append("}"); return result; } diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h index a794ca57a3..d1b2b1ffed 100644 --- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h +++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h @@ -17,6 +17,7 @@ #include <layerproto/LayerProtoHeader.h> +#include <gui/LayerMetadata.h> #include <math/vec4.h> #include <memory> @@ -110,11 +111,10 @@ public: LayerProtoParser::Rect hwcFrame; LayerProtoParser::FloatRect hwcCrop; int32_t hwcTransform; - int32_t windowType; - int32_t appId; int32_t hwcCompositionType; bool isProtected; float cornerRadius; + LayerMetadata metadata; std::string to_string() const; }; diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto index b10043877c..4c756d93bb 100644 --- a/services/surfaceflinger/layerproto/layers.proto +++ b/services/surfaceflinger/layerproto/layers.proto @@ -74,8 +74,8 @@ message LayerProto { optional FloatRectProto hwc_crop = 31; // The layer's composer backend transform optional int32 hwc_transform = 32; - optional int32 window_type = 33; - optional int32 app_id = 34; + optional int32 window_type = 33 [deprecated=true]; + optional int32 app_id = 34 [deprecated=true]; // The layer's composition type optional int32 hwc_composition_type = 35; // If it's a buffer layer, indicate if the content is protected @@ -89,6 +89,8 @@ message LayerProto { optional int32 effective_scaling_mode = 40; // Layer's corner radius. optional float corner_radius = 41; + // Metadata map. May be empty. + map<int32, bytes> metadata = 42; } message PositionProto { diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index e34e568132..b2bcb45945 100644 --- a/services/surfaceflinger/tests/unittests/Android.bp +++ b/services/surfaceflinger/tests/unittests/Android.bp @@ -42,6 +42,7 @@ cc_test { "EventThreadTest.cpp", "IdleTimerTest.cpp", "LayerHistoryTest.cpp", + "LayerMetadataTest.cpp", "SchedulerTest.cpp", "SchedulerUtilsTest.cpp", "RefreshRateStatsTest.cpp", diff --git a/services/surfaceflinger/tests/unittests/LayerMetadataTest.cpp b/services/surfaceflinger/tests/unittests/LayerMetadataTest.cpp new file mode 100644 index 0000000000..92c9f92bf1 --- /dev/null +++ b/services/surfaceflinger/tests/unittests/LayerMetadataTest.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2019 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. + */ + +#undef LOG_TAG +#define LOG_TAG "LibSurfaceFlingerUnittests" + +#include <binder/Parcel.h> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <gui/LayerMetadata.h> +#include <log/log.h> + +namespace android { +namespace { + +class LayerMetadataTest : public testing::Test { +public: + LayerMetadataTest(); + ~LayerMetadataTest() override; +}; + +LayerMetadataTest::LayerMetadataTest() { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); +} + +LayerMetadataTest::~LayerMetadataTest() { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); +} + +TEST_F(LayerMetadataTest, testLayerMetadata) { + LayerMetadata metadata; + + ASSERT_EQ(0, metadata.mMap.size()); + + // Test non-set + ASSERT_EQ(3, metadata.getInt32(4, 3)); + + // Make sure it's still unset + ASSERT_EQ(5, metadata.getInt32(4, 5)); + + metadata.setInt32(4, 2); + ASSERT_EQ(2, metadata.getInt32(4, 0)); + + // data is too small + metadata.mMap[2] = std::vector<uint8_t>{'a', 'b'}; + ASSERT_EQ(0, metadata.getInt32(2, 0)); + + LayerMetadata second; + std::vector<uint8_t> someData{'c', 'd', '\0'}; + second.mMap[2] = someData; + second.setInt32(6, 5); + metadata.merge(second); + + ASSERT_EQ(3, metadata.mMap.size()); + ASSERT_EQ(someData, second.mMap[2]); + ASSERT_EQ(5, metadata.getInt32(6, 0)); + ASSERT_EQ(2, metadata.getInt32(4, 0)); + + Parcel p; + metadata.writeToParcel(&p); + LayerMetadata reconstructed; + reconstructed.setInt32(3, 1); // to make sure it gets replaced + p.setDataPosition(0); + reconstructed.readFromParcel(&p); + ASSERT_EQ(metadata.mMap, reconstructed.mMap); +} + +} // namespace +} // namespace android |