• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <inttypes.h>
21 
22 #include "android/view/LayerMetadataKey.h"
23 
24 using android::base::StringPrintf;
25 
26 namespace android {
27 
28 LayerMetadata::LayerMetadata() = default;
29 
LayerMetadata(std::unordered_map<uint32_t,std::vector<uint8_t>> map)30 LayerMetadata::LayerMetadata(std::unordered_map<uint32_t, std::vector<uint8_t>> map)
31       : mMap(std::move(map)) {}
32 
33 LayerMetadata::LayerMetadata(const LayerMetadata& other) = default;
34 
35 LayerMetadata::LayerMetadata(LayerMetadata&& other) = default;
36 
merge(const LayerMetadata & other,bool eraseEmpty)37 bool LayerMetadata::merge(const LayerMetadata& other, bool eraseEmpty) {
38     bool changed = false;
39     for (const auto& entry : other.mMap) {
40         auto it = mMap.find(entry.first);
41         if (it != mMap.cend() && it->second != entry.second) {
42             if (eraseEmpty && entry.second.empty()) {
43                 mMap.erase(it);
44             } else {
45                 it->second = entry.second;
46             }
47             changed = true;
48         } else if (it == mMap.cend() && !entry.second.empty()) {
49             mMap[entry.first] = entry.second;
50             changed = true;
51         }
52     }
53     return changed;
54 }
55 
writeToParcel(Parcel * parcel) const56 status_t LayerMetadata::writeToParcel(Parcel* parcel) const {
57     parcel->writeInt32(static_cast<int>(mMap.size()));
58     status_t status = OK;
59     for (const auto& entry : mMap) {
60         status = parcel->writeUint32(entry.first);
61         if (status != OK) {
62             break;
63         }
64         status = parcel->writeByteVector(entry.second);
65         if (status != OK) {
66             break;
67         }
68     }
69     return status;
70 }
71 
readFromParcel(const Parcel * parcel)72 status_t LayerMetadata::readFromParcel(const Parcel* parcel) {
73     int size = parcel->readInt32();
74     status_t status = OK;
75     mMap.clear();
76     for (int i = 0; i < size; ++i) {
77         uint32_t key = parcel->readUint32();
78         status = parcel->readByteVector(&mMap[key]);
79         if (status != OK) {
80             break;
81         }
82     }
83     return status;
84 }
85 
operator =(const LayerMetadata & other)86 LayerMetadata& LayerMetadata::operator=(const LayerMetadata& other) {
87     mMap = other.mMap;
88     return *this;
89 }
90 
operator =(LayerMetadata && other)91 LayerMetadata& LayerMetadata::operator=(LayerMetadata&& other) {
92     mMap = std::move(other.mMap);
93     return *this;
94 }
95 
has(uint32_t key) const96 bool LayerMetadata::has(uint32_t key) const {
97     return mMap.count(key);
98 }
99 
getInt32(uint32_t key,int32_t fallback) const100 int32_t LayerMetadata::getInt32(uint32_t key, int32_t fallback) const {
101     if (!has(key)) return fallback;
102     const std::vector<uint8_t>& data = mMap.at(key);
103     if (data.size() < sizeof(uint32_t)) return fallback;
104     Parcel p;
105     p.setData(data.data(), data.size());
106     return p.readInt32();
107 }
108 
setInt32(uint32_t key,int32_t value)109 void LayerMetadata::setInt32(uint32_t key, int32_t value) {
110     std::vector<uint8_t>& data = mMap[key];
111     Parcel p;
112     p.writeInt32(value);
113     data.resize(p.dataSize());
114     memcpy(data.data(), p.data(), p.dataSize());
115 }
116 
getInt64(uint32_t key) const117 std::optional<int64_t> LayerMetadata::getInt64(uint32_t key) const {
118     if (!has(key)) return std::nullopt;
119     const std::vector<uint8_t>& data = mMap.at(key);
120     if (data.size() < sizeof(int64_t)) return std::nullopt;
121     Parcel p;
122     p.setData(data.data(), data.size());
123     return p.readInt64();
124 }
125 
itemToString(uint32_t key,const char * separator) const126 std::string LayerMetadata::itemToString(uint32_t key, const char* separator) const {
127     if (!has(key)) return std::string();
128     switch (static_cast<view::LayerMetadataKey>(key)) {
129         case view::LayerMetadataKey::METADATA_OWNER_UID:
130             return StringPrintf("ownerUID%s%d", separator, getInt32(key, 0));
131         case view::LayerMetadataKey::METADATA_WINDOW_TYPE:
132             return StringPrintf("windowType%s%d", separator, getInt32(key, 0));
133         case view::LayerMetadataKey::METADATA_TASK_ID:
134             return StringPrintf("taskId%s%d", separator, getInt32(key, 0));
135         case view::LayerMetadataKey::METADATA_OWNER_PID:
136             return StringPrintf("ownerPID%s%d", separator, getInt32(key, 0));
137         case view::LayerMetadataKey::METADATA_DEQUEUE_TIME:
138             return StringPrintf("dequeueTime%s%" PRId64, separator, *getInt64(key));
139         case view::LayerMetadataKey::METADATA_GAME_MODE:
140             return StringPrintf("gameMode%s%d", separator, getInt32(key, 0));
141         default:
142             return StringPrintf("%d%s%dbytes", key, separator,
143                                 static_cast<int>(mMap.at(key).size()));
144     }
145 }
146 
147 } // namespace android
148