1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <android-base/stringprintf.h>
18 #include <binder/Parcel.h>
19 #include <gui/LayerMetadata.h>
20
21 #include "android/view/LayerMetadataKey.h"
22
23 using android::base::StringPrintf;
24
25 namespace android {
26
27 LayerMetadata::LayerMetadata() = default;
28
LayerMetadata(std::unordered_map<uint32_t,std::vector<uint8_t>> map)29 LayerMetadata::LayerMetadata(std::unordered_map<uint32_t, std::vector<uint8_t>> map)
30 : mMap(std::move(map)) {}
31
32 LayerMetadata::LayerMetadata(const LayerMetadata& other) = default;
33
34 LayerMetadata::LayerMetadata(LayerMetadata&& other) = default;
35
merge(const LayerMetadata & other,bool eraseEmpty)36 bool LayerMetadata::merge(const LayerMetadata& other, bool eraseEmpty) {
37 bool changed = false;
38 for (const auto& entry : other.mMap) {
39 auto it = mMap.find(entry.first);
40 if (it != mMap.cend() && it->second != entry.second) {
41 if (eraseEmpty && entry.second.empty()) {
42 mMap.erase(it);
43 } else {
44 it->second = entry.second;
45 }
46 changed = true;
47 } else if (it == mMap.cend() && !entry.second.empty()) {
48 mMap[entry.first] = entry.second;
49 changed = true;
50 }
51 }
52 return changed;
53 }
54
writeToParcel(Parcel * parcel) const55 status_t LayerMetadata::writeToParcel(Parcel* parcel) const {
56 parcel->writeInt32(static_cast<int>(mMap.size()));
57 status_t status = OK;
58 for (const auto& entry : mMap) {
59 status = parcel->writeUint32(entry.first);
60 if (status != OK) {
61 break;
62 }
63 status = parcel->writeByteVector(entry.second);
64 if (status != OK) {
65 break;
66 }
67 }
68 return status;
69 }
70
readFromParcel(const Parcel * parcel)71 status_t LayerMetadata::readFromParcel(const Parcel* parcel) {
72 int size = parcel->readInt32();
73 status_t status = OK;
74 mMap.clear();
75 for (int i = 0; i < size; ++i) {
76 uint32_t key = parcel->readUint32();
77 status = parcel->readByteVector(&mMap[key]);
78 if (status != OK) {
79 break;
80 }
81 }
82 return status;
83 }
84
operator =(const LayerMetadata & other)85 LayerMetadata& LayerMetadata::operator=(const LayerMetadata& other) {
86 mMap = other.mMap;
87 return *this;
88 }
89
operator =(LayerMetadata && other)90 LayerMetadata& LayerMetadata::operator=(LayerMetadata&& other) {
91 mMap = std::move(other.mMap);
92 return *this;
93 }
94
has(uint32_t key) const95 bool LayerMetadata::has(uint32_t key) const {
96 return mMap.count(key);
97 }
98
getInt32(uint32_t key,int32_t fallback) const99 int32_t LayerMetadata::getInt32(uint32_t key, int32_t fallback) const {
100 if (!has(key)) return fallback;
101 const std::vector<uint8_t>& data = mMap.at(key);
102 if (data.size() < sizeof(uint32_t)) return fallback;
103 Parcel p;
104 p.setData(data.data(), data.size());
105 return p.readInt32();
106 }
107
setInt32(uint32_t key,int32_t value)108 void LayerMetadata::setInt32(uint32_t key, int32_t value) {
109 std::vector<uint8_t>& data = mMap[key];
110 Parcel p;
111 p.writeInt32(value);
112 data.resize(p.dataSize());
113 memcpy(data.data(), p.data(), p.dataSize());
114 }
115
itemToString(uint32_t key,const char * separator) const116 std::string LayerMetadata::itemToString(uint32_t key, const char* separator) const {
117 if (!has(key)) return std::string();
118 switch (static_cast<view::LayerMetadataKey>(key)) {
119 case view::LayerMetadataKey::METADATA_OWNER_UID:
120 return StringPrintf("ownerUID%s%d", separator, getInt32(key, 0));
121 case view::LayerMetadataKey::METADATA_WINDOW_TYPE:
122 return StringPrintf("windowType%s%d", separator, getInt32(key, 0));
123 case view::LayerMetadataKey::METADATA_TASK_ID:
124 return StringPrintf("taskId%s%d", separator, getInt32(key, 0));
125 default:
126 return StringPrintf("%d%s%dbytes", key, separator,
127 static_cast<int>(mMap.at(key).size()));
128 }
129 }
130
131 } // namespace android
132