• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.internal.infra;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.UserIdInt;
22 import android.content.ComponentName;
23 import android.util.ArraySet;
24 import android.util.SparseArray;
25 
26 import com.android.internal.annotations.GuardedBy;
27 
28 import java.io.PrintWriter;
29 import java.util.List;
30 
31 /**
32  * Helper class used to manage a {@link WhitelistHelper} per user instance when the main service
33  * cannot hold a lock when external entities (typically {@code ActivityManagerService}) needs to
34  * get allowlist info.
35  *
36  * <p>This class is thread safe.
37  */
38 // TODO: add unit tests
39 public class GlobalWhitelistState {
40 
41     // Uses full-name to avoid collision with service-provided mLock
42     protected final Object mGlobalWhitelistStateLock = new Object();
43 
44     // TODO: should not be exposed directly
45     @Nullable
46     @GuardedBy("mGlobalWhitelistStateLock")
47     protected SparseArray<WhitelistHelper> mWhitelisterHelpers;
48 
49     /**
50      * Sets the allowlist for the given user.
51      */
setWhitelist(@serIdInt int userId, @Nullable List<String> packageNames, @Nullable List<ComponentName> components)52     public void setWhitelist(@UserIdInt int userId, @Nullable List<String> packageNames,
53             @Nullable List<ComponentName> components) {
54         synchronized (mGlobalWhitelistStateLock) {
55             if (mWhitelisterHelpers == null) {
56                 mWhitelisterHelpers = new SparseArray<>(1);
57             }
58             WhitelistHelper helper = mWhitelisterHelpers.get(userId);
59             if (helper == null) {
60                 helper = new WhitelistHelper();
61                 mWhitelisterHelpers.put(userId, helper);
62             }
63             helper.setWhitelist(packageNames, components);
64         }
65     }
66 
67     /**
68      * Checks if the given package is allowlisted for the given user.
69      */
isWhitelisted(@serIdInt int userId, @NonNull String packageName)70     public boolean isWhitelisted(@UserIdInt int userId, @NonNull String packageName) {
71         synchronized (mGlobalWhitelistStateLock) {
72             if (mWhitelisterHelpers == null) return false;
73             final WhitelistHelper helper = mWhitelisterHelpers.get(userId);
74             return helper == null ? false : helper.isWhitelisted(packageName);
75         }
76     }
77 
78     /**
79      * Checks if the given component is allowlisted for the given user.
80      */
isWhitelisted(@serIdInt int userId, @NonNull ComponentName componentName)81     public boolean isWhitelisted(@UserIdInt int userId, @NonNull ComponentName componentName) {
82         synchronized (mGlobalWhitelistStateLock) {
83             if (mWhitelisterHelpers == null) return false;
84             final WhitelistHelper helper = mWhitelisterHelpers.get(userId);
85             return helper == null ? false : helper.isWhitelisted(componentName);
86         }
87     }
88 
89     /**
90      * Gets the allowlisted components for the given package and user.
91      */
getWhitelistedComponents(@serIdInt int userId, @NonNull String packageName)92     public ArraySet<ComponentName> getWhitelistedComponents(@UserIdInt int userId,
93             @NonNull String packageName) {
94         synchronized (mGlobalWhitelistStateLock) {
95             if (mWhitelisterHelpers == null) return null;
96             final WhitelistHelper helper = mWhitelisterHelpers.get(userId);
97             return helper == null ? null : helper.getWhitelistedComponents(packageName);
98         }
99     }
100 
101     /**
102      * Gets packages that are either entirely allowlisted or have components that are allowlisted
103      * for the given user.
104      */
getWhitelistedPackages(@serIdInt int userId)105     public ArraySet<String> getWhitelistedPackages(@UserIdInt int userId) {
106         synchronized (mGlobalWhitelistStateLock) {
107             if (mWhitelisterHelpers == null) return null;
108             final WhitelistHelper helper = mWhitelisterHelpers.get(userId);
109             return helper == null ? null : helper.getWhitelistedPackages();
110         }
111     }
112 
113     /**
114      * Resets the allowlist for the given user.
115      */
resetWhitelist(@onNull int userId)116     public void resetWhitelist(@NonNull int userId) {
117         synchronized (mGlobalWhitelistStateLock) {
118             if (mWhitelisterHelpers == null) return;
119             mWhitelisterHelpers.remove(userId);
120             if (mWhitelisterHelpers.size() == 0) {
121                 mWhitelisterHelpers = null;
122             }
123         }
124     }
125 
126     /**
127      * Dumps it!
128      */
dump(@onNull String prefix, @NonNull PrintWriter pw)129     public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
130         pw.print(prefix); pw.print("State: ");
131         synchronized (mGlobalWhitelistStateLock) {
132             if (mWhitelisterHelpers == null) {
133                 pw.println("empty");
134                 return;
135             }
136             pw.print(mWhitelisterHelpers.size()); pw.println(" services");
137             final String prefix2 = prefix + "  ";
138             for (int i = 0; i < mWhitelisterHelpers.size(); i++) {
139                 final int userId  = mWhitelisterHelpers.keyAt(i);
140                 final WhitelistHelper helper = mWhitelisterHelpers.valueAt(i);
141                 helper.dump(prefix2, "Whitelist for userId " + userId, pw);
142             }
143         }
144     }
145 }
146