diff options
| author | 2019-01-25 23:15:35 +0000 | |
|---|---|---|
| committer | 2019-01-25 23:15:35 +0000 | |
| commit | a2e7f7f613358cdbe205586d6151a2056d1c085c (patch) | |
| tree | a88f06b370ae88c0f85b61b34ecf84f43042d454 | |
| parent | 62ecefead236c531663e65937a7eebc1c037f21b (diff) | |
| parent | 15a5d93a759ded0d880a24537961cb062a9c0dda (diff) | |
Merge changes from topics "sf_task_id", "sf_metadata"
* changes:
Add task-id metadata constant
Add metadata store to surfaces
21 files changed, 403 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..745433a605 --- /dev/null +++ b/libs/gui/LayerMetadata.cpp @@ -0,0 +1,116 @@ +/* + * 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)); + case METADATA_TASK_ID: + return StringPrintf("taskId%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..3ae10e461d --- /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, METADATA_TASK_ID = 3 }; + +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 5308302902..e108d1e74d 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); @@ -595,14 +593,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; } } @@ -1311,11 +1311,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) { @@ -2083,8 +2086,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()); @@ -2096,6 +2097,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 afd48ed28d..d30961aab6 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 5a866b2621..34fcbeb185 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3968,6 +3968,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(); @@ -3996,13 +3999,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)); @@ -4058,12 +4058,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 |