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