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