xref: /aosp_15_r20/frameworks/native/libs/gui/LayerMetadata.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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