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.car.vms;
18 
19 import android.annotation.Nullable;
20 import android.util.ArrayMap;
21 
22 import com.android.internal.annotations.GuardedBy;
23 
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 
27 class VmsProviderInfoStore {
28     private final Object mLock = new Object();
29     @GuardedBy("mLock")
30     private final ArrayMap<InfoWrapper, Integer> mProvidersIds = new ArrayMap<>();
31     @GuardedBy("mLock")
32     private final ArrayList<InfoWrapper> mProvidersInfo = new ArrayList<>();
33 
34     private static class InfoWrapper {
35         private final byte[] mInfo;
36 
InfoWrapper(byte[] info)37         InfoWrapper(byte[] info) {
38             mInfo = info;
39         }
40 
getInfo()41         public byte[] getInfo() {
42             return mInfo.clone();
43         }
44 
45         @Override
equals(Object o)46         public boolean equals(Object o) {
47             if (!(o instanceof InfoWrapper)) {
48                 return false;
49             }
50             InfoWrapper p = (InfoWrapper) o;
51             return Arrays.equals(this.mInfo, p.mInfo);
52         }
53 
54         @Override
hashCode()55         public int hashCode() {
56             return Arrays.hashCode(mInfo);
57         }
58     }
59 
60     /**
61      * Retrieves the provider ID for the given provider information. If the provider information
62      * has not previously been seen, it will be assigned a new provider ID.
63      *
64      * @param providerInfo Provider information to query or register.
65      * @return Provider ID for the given provider information.
66      */
getProviderId(byte[] providerInfo)67     int getProviderId(byte[] providerInfo) {
68         Integer providerId;
69         InfoWrapper wrappedProviderInfo = new InfoWrapper(providerInfo);
70         synchronized (mLock) {
71             // Check if provider is already registered
72             providerId = mProvidersIds.get(wrappedProviderInfo);
73             if (providerId == null) {
74                 // Add the new provider and assign it the next ID
75                 mProvidersInfo.add(wrappedProviderInfo);
76                 providerId = mProvidersInfo.size();
77                 mProvidersIds.put(wrappedProviderInfo, providerId);
78             }
79         }
80         return providerId;
81     }
82 
83     /**
84      * Returns the provider info associated with the given provider ID.
85      * @param providerId Provider ID to query.
86      * @return Provider info associated with the ID, or null if provider ID is unknown.
87      */
88     @Nullable
getProviderInfo(int providerId)89     byte[] getProviderInfo(int providerId) {
90         synchronized (mLock) {
91             return providerId < 1 || providerId > mProvidersInfo.size()
92                     ? null
93                     : mProvidersInfo.get(providerId - 1).getInfo();
94         }
95     }
96 }
97