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