• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 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 #pragma once
18 
19 #include <log/log.h>
20 #include <set>
21 #include <unordered_map>
22 #include <unordered_set>
23 
24 namespace android::adpf {
25 
26 class SessionLayerMap {
27 public:
28     // Inform the SessionLayerMap about dead sessions
29     void notifySessionsDied(std::vector<int32_t>& sessionIds);
30     // Inform the SessionLayerMap about dead layers
31     void notifyLayersDied(std::vector<int32_t>& layers);
32     // Associate a session with a specific set of layer ids
33     bool bindSessionIDToLayers(int sessionId, const std::vector<int32_t>& layerIds);
34     // Get the set of sessions that are mapped to a specific layer id
35     void getAssociatedSessions(int32_t layerId, std::vector<int32_t>& sessionIdsOut);
36     // Get the set of layers that are currently being tracked
37     void getCurrentlyRelevantLayers(std::unordered_set<int32_t>& currentlyRelevantLayers);
38 
39 private:
40     struct MappedType {
MappedTypeMappedType41         MappedType(int32_t id, std::unordered_map<int32_t, MappedType>& otherList)
42               : mId(id), mOtherList(otherList) {};
43         MappedType() = delete;
~MappedTypeMappedType44         ~MappedType() { swapLinks({}); }
45 
46         // Replace the set of associated IDs for this mapped type with a different set of IDs,
47         // updating only associations which have changed between the two sets
swapLinksMappedType48         void swapLinks(std::set<int32_t>&& incoming) {
49             auto&& oldIter = mLinks.begin();
50             auto&& newIter = incoming.begin();
51 
52             // Dump all outdated values and insert new ones
53             while (oldIter != mLinks.end() || newIter != incoming.end()) {
54                 // If there is a value in the new set but not the old set
55                 // We should have already ensured what we're linking to exists
56                 if (oldIter == mLinks.end() || (newIter != incoming.end() && *newIter < *oldIter)) {
57                     addRemoteAssociation(*newIter);
58                     ++newIter;
59                     continue;
60                 }
61 
62                 // If there is a value in the old set but not the new set
63                 if (newIter == incoming.end() || (oldIter != mLinks.end() && *oldIter < *newIter)) {
64                     dropRemoteAssociation(*oldIter);
65                     ++oldIter;
66                     continue;
67                 }
68 
69                 // If they're the same, skip
70                 if (*oldIter == *newIter) {
71                     ++oldIter;
72                     ++newIter;
73                     continue;
74                 }
75             }
76 
77             mLinks.swap(incoming);
78         }
79 
addRemoteAssociationMappedType80         void addRemoteAssociation(int32_t other) {
81             auto&& iter = mOtherList.find(other);
82             if (iter != mOtherList.end()) {
83                 iter->second.mLinks.insert(mId);
84             } else {
85                 ALOGE("Existing entry in SessionLayerMap, link failed");
86             }
87         }
88 
dropRemoteAssociationMappedType89         void dropRemoteAssociation(int32_t other) {
90             auto&& iter = mOtherList.find(other);
91             if (iter != mOtherList.end()) {
92                 iter->second.mLinks.erase(mId);
93                 if (iter->second.mLinks.empty()) {
94                     // This only erases them from the map, not from general tracking
95                     mOtherList.erase(iter);
96                 }
97             } else {
98                 ALOGE("Missing entry in SessionLayerMap, unlinking failed");
99             }
100         }
101 
102         int32_t mId;
103         std::set<int> mLinks;
104         std::unordered_map<int32_t, MappedType>& mOtherList;
105     };
106 
107     std::unordered_map<int32_t, MappedType> mSessions;
108     std::unordered_map<int32_t, MappedType> mLayers;
109 };
110 
111 } // namespace android::adpf
112