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.car.vms.IVmsClientCallback; 20 import android.car.vms.VmsAssociatedLayer; 21 import android.car.vms.VmsLayer; 22 import android.car.vms.VmsLayerDependency; 23 import android.car.vms.VmsLayersOffering; 24 import android.os.IBinder; 25 import android.util.ArraySet; 26 import android.util.SparseArray; 27 import android.util.SparseBooleanArray; 28 29 import com.android.internal.annotations.GuardedBy; 30 31 import java.io.PrintWriter; 32 import java.util.ArrayList; 33 import java.util.Collection; 34 import java.util.Collections; 35 import java.util.List; 36 import java.util.Map; 37 import java.util.Set; 38 import java.util.stream.Collectors; 39 40 /** 41 * Class for tracking Vehicle Map Service client information, offerings, and subscriptions. 42 */ 43 final class VmsClientInfo { 44 private final int mUid; 45 private final String mPackageName; 46 private final IVmsClientCallback mCallback; 47 private final boolean mLegacyClient; 48 private final IBinder.DeathRecipient mDeathRecipient; 49 50 private final Object mLock = new Object(); 51 @GuardedBy("mLock") 52 private final SparseBooleanArray mProviderIds = new SparseBooleanArray(); 53 @GuardedBy("mLock") 54 private final SparseArray<Set<VmsLayerDependency>> mOfferings = new SparseArray<>(); 55 @GuardedBy("mLock") 56 private final SparseArray<Set<VmsLayer>> mPotentialOfferings = new SparseArray<>(); 57 @GuardedBy("mLock") 58 private Set<VmsLayer> mLayerSubscriptions = Collections.emptySet(); 59 @GuardedBy("mLock") 60 private Map<VmsLayer, Set<Integer>> mLayerAndProviderSubscriptions = Collections.emptyMap(); 61 @GuardedBy("mLock") 62 private boolean mMonitoringEnabled; 63 VmsClientInfo(int uid, String packageName, IVmsClientCallback callback, boolean legacyClient, IBinder.DeathRecipient deathRecipient)64 VmsClientInfo(int uid, String packageName, IVmsClientCallback callback, boolean legacyClient, 65 IBinder.DeathRecipient deathRecipient) { 66 mUid = uid; 67 mPackageName = packageName; 68 mCallback = callback; 69 mLegacyClient = legacyClient; 70 mDeathRecipient = deathRecipient; 71 } 72 getUid()73 int getUid() { 74 return mUid; 75 } 76 getPackageName()77 String getPackageName() { 78 return mPackageName; 79 } 80 getCallback()81 IVmsClientCallback getCallback() { 82 return mCallback; 83 } 84 isLegacyClient()85 boolean isLegacyClient() { 86 return mLegacyClient; 87 } 88 getDeathRecipient()89 IBinder.DeathRecipient getDeathRecipient() { 90 return mDeathRecipient; 91 } 92 addProviderId(int providerId)93 void addProviderId(int providerId) { 94 synchronized (mLock) { 95 mProviderIds.put(providerId, true); 96 } 97 } 98 hasProviderId(int providerId)99 boolean hasProviderId(int providerId) { 100 synchronized (mLock) { 101 return mProviderIds.get(providerId); 102 } 103 } 104 setProviderOfferings(int providerId, Collection<VmsLayerDependency> offerings)105 boolean setProviderOfferings(int providerId, Collection<VmsLayerDependency> offerings) { 106 synchronized (mLock) { 107 Set<VmsLayerDependency> providerOfferings = mOfferings.get(providerId); 108 109 // If the offerings are unchanged, do nothing 110 if (providerOfferings != null 111 && providerOfferings.size() == offerings.size() 112 && providerOfferings.containsAll(offerings)) { 113 return false; 114 } 115 116 // Otherwise, update the offerings and return true 117 mOfferings.put(providerId, new ArraySet<>(offerings)); 118 mPotentialOfferings.put(providerId, offerings.stream() 119 .map(VmsLayerDependency::getLayer) 120 .collect(Collectors.toSet())); 121 return true; 122 } 123 } 124 getAllOfferings()125 Collection<VmsLayersOffering> getAllOfferings() { 126 List<VmsLayersOffering> result = new ArrayList<>(mOfferings.size()); 127 synchronized (mLock) { 128 for (int i = 0; i < mOfferings.size(); i++) { 129 int providerId = mOfferings.keyAt(i); 130 Set<VmsLayerDependency> providerOfferings = mOfferings.valueAt(i); 131 result.add(new VmsLayersOffering(new ArraySet<>(providerOfferings), providerId)); 132 } 133 } 134 return result; 135 } 136 hasOffering(int providerId, VmsLayer layer)137 boolean hasOffering(int providerId, VmsLayer layer) { 138 synchronized (mLock) { 139 return mPotentialOfferings.get(providerId, Collections.emptySet()).contains(layer); 140 } 141 } 142 setSubscriptions(List<VmsAssociatedLayer> layers)143 void setSubscriptions(List<VmsAssociatedLayer> layers) { 144 synchronized (mLock) { 145 mLayerSubscriptions = layers.stream() 146 .filter(associatedLayer -> associatedLayer.getProviderIds().isEmpty()) 147 .map(VmsAssociatedLayer::getVmsLayer) 148 .collect(Collectors.toSet()); 149 mLayerAndProviderSubscriptions = layers.stream() 150 .filter(associatedLayer -> !associatedLayer.getProviderIds().isEmpty()) 151 .collect(Collectors.toMap( 152 VmsAssociatedLayer::getVmsLayer, 153 associatedLayer -> new ArraySet<>(associatedLayer.getProviderIds()))); 154 } 155 } 156 getLayerSubscriptions()157 Set<VmsLayer> getLayerSubscriptions() { 158 synchronized (mLock) { 159 return new ArraySet<>(mLayerSubscriptions); 160 } 161 } 162 getLayerAndProviderSubscriptions()163 Map<VmsLayer, Set<Integer>> getLayerAndProviderSubscriptions() { 164 synchronized (mLock) { 165 return deepCopy(mLayerAndProviderSubscriptions); 166 } 167 } 168 setMonitoringEnabled(boolean enabled)169 void setMonitoringEnabled(boolean enabled) { 170 synchronized (mLock) { 171 mMonitoringEnabled = enabled; 172 } 173 } 174 isSubscribed(int providerId, VmsLayer layer)175 boolean isSubscribed(int providerId, VmsLayer layer) { 176 synchronized (mLock) { 177 return mMonitoringEnabled 178 || mLayerSubscriptions.contains(layer) 179 || mLayerAndProviderSubscriptions.getOrDefault(layer, Collections.emptySet()) 180 .contains(providerId); 181 } 182 } 183 dump(PrintWriter writer, String indent)184 void dump(PrintWriter writer, String indent) { 185 synchronized (mLock) { 186 String prefix = indent; 187 writer.println(prefix + "VmsClient [" + mPackageName + "]"); 188 189 prefix = indent + " "; 190 writer.println(prefix + "UID: " + mUid); 191 writer.println(prefix + "Legacy Client: " + mLegacyClient); 192 writer.println(prefix + "Monitoring: " + mMonitoringEnabled); 193 194 if (mProviderIds.size() > 0) { 195 writer.println(prefix + "Offerings:"); 196 for (int i = 0; i < mProviderIds.size(); i++) { 197 prefix = indent + " "; 198 int providerId = mProviderIds.keyAt(i); 199 writer.println(prefix + "Provider [" + providerId + "]"); 200 201 for (VmsLayerDependency layerOffering : mOfferings.get( 202 providerId, Collections.emptySet())) { 203 prefix = indent + " "; 204 writer.println(prefix + layerOffering.getLayer()); 205 if (!layerOffering.getDependencies().isEmpty()) { 206 prefix = indent + " "; 207 writer.println(prefix + "Dependencies: " 208 + layerOffering.getDependencies()); 209 } 210 } 211 } 212 } 213 214 if (!mLayerSubscriptions.isEmpty() || !mLayerAndProviderSubscriptions.isEmpty()) { 215 prefix = indent + " "; 216 writer.println(prefix + "Subscriptions:"); 217 218 prefix = indent + " "; 219 for (VmsLayer layer : mLayerSubscriptions) { 220 writer.println(prefix + layer); 221 } 222 for (Map.Entry<VmsLayer, Set<Integer>> layerEntry : 223 mLayerAndProviderSubscriptions.entrySet()) { 224 writer.println(prefix + layerEntry.getKey() + ": " + layerEntry.getValue()); 225 } 226 } 227 } 228 } 229 deepCopy(Map<K, Set<V>> original)230 private static <K, V> Map<K, Set<V>> deepCopy(Map<K, Set<V>> original) { 231 return original.entrySet().stream().collect(Collectors.toMap( 232 Map.Entry::getKey, 233 entry -> new ArraySet<>(entry.getValue()))); 234 } 235 } 236