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 using android::base::StringPrintf;
22
23 namespace android {
24
25 LayerMetadata::LayerMetadata() = default;
26
LayerMetadata(std::unordered_map<uint32_t,std::vector<uint8_t>> map)27 LayerMetadata::LayerMetadata(std::unordered_map<uint32_t, std::vector<uint8_t>> map)
28 : mMap(std::move(map)) {}
29
30 LayerMetadata::LayerMetadata(const LayerMetadata& other) = default;
31
32 LayerMetadata::LayerMetadata(LayerMetadata&& other) = default;
33
merge(const LayerMetadata & other,bool eraseEmpty)34 bool LayerMetadata::merge(const LayerMetadata& other, bool eraseEmpty) {
35 bool changed = false;
36 for (const auto& entry : other.mMap) {
37 auto it = mMap.find(entry.first);
38 if (it != mMap.cend() && it->second != entry.second) {
39 if (eraseEmpty && entry.second.empty()) {
40 mMap.erase(it);
41 } else {
42 it->second = entry.second;
43 }
44 changed = true;
45 } else if (it == mMap.cend() && !entry.second.empty()) {
46 mMap[entry.first] = entry.second;
47 changed = true;
48 }
49 }
50 return changed;
51 }
52
writeToParcel(Parcel * parcel) const53 status_t LayerMetadata::writeToParcel(Parcel* parcel) const {
54 parcel->writeInt32(static_cast<int>(mMap.size()));
55 status_t status = OK;
56 for (const auto& entry : mMap) {
57 status = parcel->writeUint32(entry.first);
58 if (status != OK) {
59 break;
60 }
61 status = parcel->writeByteVector(entry.second);
62 if (status != OK) {
63 break;
64 }
65 }
66 return status;
67 }
68
readFromParcel(const Parcel * parcel)69 status_t LayerMetadata::readFromParcel(const Parcel* parcel) {
70 int size = parcel->readInt32();
71 status_t status = OK;
72 mMap.clear();
73 for (int i = 0; i < size; ++i) {
74 uint32_t key = parcel->readUint32();
75 status = parcel->readByteVector(&mMap[key]);
76 if (status != OK) {
77 break;
78 }
79 }
80 return status;
81 }
82
operator =(const LayerMetadata & other)83 LayerMetadata& LayerMetadata::operator=(const LayerMetadata& other) {
84 mMap = other.mMap;
85 return *this;
86 }
87
operator =(LayerMetadata && other)88 LayerMetadata& LayerMetadata::operator=(LayerMetadata&& other) {
89 mMap = std::move(other.mMap);
90 return *this;
91 }
92
has(uint32_t key) const93 bool LayerMetadata::has(uint32_t key) const {
94 return mMap.count(key);
95 }
96
getInt32(uint32_t key,int32_t fallback) const97 int32_t LayerMetadata::getInt32(uint32_t key, int32_t fallback) const {
98 if (!has(key)) return fallback;
99 const std::vector<uint8_t>& data = mMap.at(key);
100 if (data.size() < sizeof(uint32_t)) return fallback;
101 Parcel p;
102 p.setData(data.data(), data.size());
103 return p.readInt32();
104 }
105
setInt32(uint32_t key,int32_t value)106 void LayerMetadata::setInt32(uint32_t key, int32_t value) {
107 std::vector<uint8_t>& data = mMap[key];
108 Parcel p;
109 p.writeInt32(value);
110 data.resize(p.dataSize());
111 memcpy(data.data(), p.data(), p.dataSize());
112 }
113
itemToString(uint32_t key,const char * separator) const114 std::string LayerMetadata::itemToString(uint32_t key, const char* separator) const {
115 if (!has(key)) return std::string();
116 switch (key) {
117 case METADATA_OWNER_UID:
118 return StringPrintf("ownerUID%s%d", separator, getInt32(key, 0));
119 case METADATA_WINDOW_TYPE:
120 return StringPrintf("windowType%s%d", separator, getInt32(key, 0));
121 case METADATA_TASK_ID:
122 return StringPrintf("taskId%s%d", separator, getInt32(key, 0));
123 default:
124 return StringPrintf("%d%s%dbytes", key, separator,
125 static_cast<int>(mMap.at(key).size()));
126 }
127 }
128
129 } // namespace android
130