1 /*
2  * Copyright (C) 2022 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.am;
18 
19 import android.util.ArrayMap;
20 import android.util.SparseArray;
21 
22 /**
23  * Utility class to track mappings between (UID, name) and E.
24  *
25  * @param <E> The type of the values in this map.
26  */
27 public class UidProcessMap<E> {
28     final SparseArray<ArrayMap<String, E>> mMap = new SparseArray<>();
29 
30     /**
31      * Retrieve a value from the map.
32      */
get(int uid, String name)33     public E get(int uid, String name) {
34         final ArrayMap<String, E> names = mMap.get(uid);
35         if (names == null) {
36             return null;
37         }
38         return names.get(name);
39     }
40 
41     /**
42      * Add a new value to the array map.
43      */
put(int uid, String name, E value)44     public E put(int uid, String name, E value) {
45         ArrayMap<String, E> names = mMap.get(uid);
46         if (names == null) {
47             names = new ArrayMap<String, E>(2);
48             mMap.put(uid, names);
49         }
50         names.put(name, value);
51         return value;
52     }
53 
54     /**
55      * Remove an existing key (uid, name) from the array map.
56      */
remove(int uid, String name)57     public E remove(int uid, String name) {
58         final int index = mMap.indexOfKey(uid);
59         if (index < 0) {
60             return null;
61         }
62         final ArrayMap<String, E> names = mMap.valueAt(index);
63         if (names != null) {
64             final E old = names.remove(name);
65             if (names.isEmpty()) {
66                 mMap.removeAt(index);
67             }
68             return old;
69         }
70         return null;
71     }
72 
73     /**
74      * Return the underneath map.
75      */
getMap()76     public SparseArray<ArrayMap<String, E>> getMap() {
77         return mMap;
78     }
79 
80     /**
81      * Return the number of items in this map.
82      */
size()83     public int size() {
84         return mMap.size();
85     }
86 
87     /**
88      * Make the map empty. All storage is released.
89      */
clear()90     public void clear() {
91         mMap.clear();
92     }
93 
94     /**
95      * Perform a {@link #put} of all key/value pairs in other.
96      */
putAll(UidProcessMap<E> other)97     public void putAll(UidProcessMap<E> other) {
98         for (int i = other.mMap.size() - 1; i >= 0; i--) {
99             final int uid = other.mMap.keyAt(i);
100             final ArrayMap<String, E> names = mMap.get(uid);
101             if (names != null) {
102                 names.putAll(other.mMap.valueAt(i));
103             } else {
104                 mMap.put(uid, new ArrayMap<String, E>(other.mMap.valueAt(i)));
105             }
106         }
107     }
108 }
109