1 /*
2  * Copyright (C) 2020 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 package com.android.server.pm.verify.domain.models;
18 
19 import android.annotation.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.util.ArrayMap;
23 import android.util.Slog;
24 
25 import com.android.internal.annotations.VisibleForTesting;
26 
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.List;
30 import java.util.UUID;
31 
32 /**
33  * A feature specific implementation of a multi-key map, since lookups by both a {@link String}
34  * package name and {@link UUID} domain set ID should be supported.
35  *
36  * @param <ValueType> stored object type
37  */
38 public class DomainVerificationStateMap<ValueType> {
39 
40     private static final String TAG = "DomainVerificationStateMap";
41 
42     @NonNull
43     private final ArrayMap<String, ValueType> mPackageNameMap = new ArrayMap<>();
44 
45     @NonNull
46     private final ArrayMap<UUID, ValueType> mDomainSetIdMap = new ArrayMap<>();
47 
size()48     public int size() {
49         return mPackageNameMap.size();
50     }
51 
52     @NonNull
valueAt(@ntRangefrom = 0) int index)53     public ValueType valueAt(@IntRange(from = 0) int index) {
54         return mPackageNameMap.valueAt(index);
55     }
56 
57     @Nullable
get(@onNull String packageName)58     public ValueType get(@NonNull String packageName) {
59         return mPackageNameMap.get(packageName);
60     }
61 
62     @Nullable
get(@onNull UUID domainSetId)63     public ValueType get(@NonNull UUID domainSetId) {
64         return mDomainSetIdMap.get(domainSetId);
65     }
66 
put(@onNull String packageName, @NonNull UUID domainSetId, @NonNull ValueType valueType)67     public void put(@NonNull String packageName, @NonNull UUID domainSetId,
68             @NonNull ValueType valueType) {
69         if (mPackageNameMap.containsKey(packageName)) {
70             remove(packageName);
71         }
72 
73         mPackageNameMap.put(packageName, valueType);
74         mDomainSetIdMap.put(domainSetId, valueType);
75     }
76 
77     @Nullable
remove(@onNull String packageName)78     public ValueType remove(@NonNull String packageName) {
79         ValueType valueRemoved = mPackageNameMap.remove(packageName);
80         if (valueRemoved != null) {
81             int index = mDomainSetIdMap.indexOfValue(valueRemoved);
82             if (index >= 0) {
83                 mDomainSetIdMap.removeAt(index);
84             }
85         }
86         return valueRemoved;
87     }
88 
89     @Nullable
remove(@onNull UUID domainSetId)90     public ValueType remove(@NonNull UUID domainSetId) {
91         ValueType valueRemoved = mDomainSetIdMap.remove(domainSetId);
92         if (valueRemoved != null) {
93             int index = mPackageNameMap.indexOfValue(valueRemoved);
94             if (index >= 0) {
95                 mPackageNameMap.removeAt(index);
96             }
97         }
98         return valueRemoved;
99     }
100 
101     @NonNull
getPackageNames()102     public List<String> getPackageNames() {
103         return new ArrayList<>(mPackageNameMap.keySet());
104     }
105 
106     /**
107      * Exposes the backing values collection of the one of the internal maps. Should only be used
108      * for test assertions.
109      */
110     @VisibleForTesting
values()111     public Collection<ValueType> values() {
112         return new ArrayList<>(mPackageNameMap.values());
113     }
114 
115     @Override
toString()116     public String toString() {
117         return "DomainVerificationStateMap{"
118                 + "packageNameMap=" + mPackageNameMap
119                 + ", domainSetIdMap=" + mDomainSetIdMap
120                 + '}';
121     }
122 }
123