blob: 183b465afbfd487bfd7e1993cebae5408396fff2 [file] [log] [blame]
Adam He6240eab2019-02-25 13:34:45 -08001/*
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
17package com.android.internal.infra;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.content.ComponentName;
22import android.util.ArrayMap;
23import android.util.ArraySet;
24import android.util.Log;
25
26import com.android.internal.util.Preconditions;
27
28import java.io.PrintWriter;
Felipe Leme0f0b1d32019-03-06 11:40:39 -080029import java.util.List;
Adam He6240eab2019-02-25 13:34:45 -080030
31/**
32 * Helper class for keeping track of whitelisted packages/activities.
33 *
34 * @hide
35 */
36public final class WhitelistHelper {
37
38 private static final String TAG = "WhitelistHelper";
39
40 /**
41 * Map of whitelisted packages/activities. The whole package is whitelisted if its
42 * corresponding value is {@code null}.
43 */
44 @Nullable
45 private ArrayMap<String, ArraySet<ComponentName>> mWhitelistedPackages;
46
47 /**
48 * Sets the whitelist with the given packages and activities. The list is cleared if both
49 * packageNames and components are {@code null}.
50 *
51 * @param packageNames packages to be whitelisted.
52 * @param components activities to be whitelisted.
Adam He70ebc5a2019-03-05 14:20:44 -080053 *
54 * @throws IllegalArgumentException if packages or components are empty.
Adam He6240eab2019-02-25 13:34:45 -080055 */
56 public void setWhitelist(@Nullable ArraySet<String> packageNames,
57 @Nullable ArraySet<ComponentName> components) {
58 mWhitelistedPackages = null;
59 if (packageNames == null && components == null) return;
60
Adam He70ebc5a2019-03-05 14:20:44 -080061 if ((packageNames != null && packageNames.isEmpty())
62 || (components != null && components.isEmpty())) {
63 throw new IllegalArgumentException("Packages or Components cannot be empty.");
64 }
65
Adam He6240eab2019-02-25 13:34:45 -080066 mWhitelistedPackages = new ArrayMap<>();
67
68 if (packageNames != null) {
69 for (int i = 0; i < packageNames.size(); i++) {
70 mWhitelistedPackages.put(packageNames.valueAt(i), null);
71 }
72 }
73
74 if (components != null) {
75 for (int i = 0; i < components.size(); i++) {
76 final ComponentName component = components.valueAt(i);
77 if (component == null) {
78 Log.w(TAG, "setWhitelist(): component is null");
79 continue;
80 }
81
82 final String packageName = component.getPackageName();
83 ArraySet<ComponentName> set = mWhitelistedPackages.get(packageName);
84 if (set == null) {
85 set = new ArraySet<>();
86 mWhitelistedPackages.put(packageName, set);
87 }
88 set.add(component);
89 }
90 }
91 }
92
93 /**
Felipe Leme0f0b1d32019-03-06 11:40:39 -080094 * Helper to use {@link #setWhitelist(ArraySet, ArraySet)} with {@link List Lists}.
95 */
96 public void setWhitelist(@Nullable List<String> packageNames,
97 @Nullable List<ComponentName> components) {
98 final ArraySet<String> packageNamesSet = packageNames == null ? null
99 : new ArraySet<>(packageNames);
100 final ArraySet<ComponentName> componentssSet = components == null ? null
101 : new ArraySet<>(components);
102 setWhitelist(packageNamesSet, componentssSet);
103 }
104
105 /**
Adam He6240eab2019-02-25 13:34:45 -0800106 * Returns {@code true} if the entire package is whitelisted.
107 */
108 public boolean isWhitelisted(@NonNull String packageName) {
109 Preconditions.checkNotNull(packageName);
110
111 if (mWhitelistedPackages == null) return false;
112
113 return mWhitelistedPackages.containsKey(packageName)
114 && mWhitelistedPackages.get(packageName) == null;
115 }
116
117 /**
118 * Returns {@code true} if the specified activity is whitelisted.
119 */
120 public boolean isWhitelisted(@NonNull ComponentName componentName) {
121 Preconditions.checkNotNull(componentName);
122
123 final String packageName = componentName.getPackageName();
124 final ArraySet<ComponentName> whitelistedComponents = getWhitelistedComponents(packageName);
125 if (whitelistedComponents != null) {
126 return whitelistedComponents.contains(componentName);
127 }
128
129 return isWhitelisted(packageName);
130 }
131
132 /**
133 * Returns a set of whitelisted components with the given package, or null if nothing is
134 * whitelisted.
135 */
136 @Nullable
137 public ArraySet<ComponentName> getWhitelistedComponents(@NonNull String packageName) {
138 Preconditions.checkNotNull(packageName);
139
140 return mWhitelistedPackages == null ? null : mWhitelistedPackages.get(packageName);
141 }
142
143 @Override
144 public String toString() {
145 return "WhitelistHelper[" + mWhitelistedPackages + ']';
146 }
147
148 /**
149 * Dumps it!
150 */
151 public void dump(@NonNull String prefix, @NonNull String message, @NonNull PrintWriter pw) {
152 if (mWhitelistedPackages == null || mWhitelistedPackages.size() == 0) {
153 pw.print(prefix); pw.print(message); pw.println(": (no whitelisted packages)");
154 return;
155 }
156
Felipe Leme0f0b1d32019-03-06 11:40:39 -0800157 final String prefix2 = prefix + " ";
Adam He6240eab2019-02-25 13:34:45 -0800158 final int size = mWhitelistedPackages.size();
159 pw.print(prefix); pw.print(message); pw.print(": "); pw.print(size);
160 pw.println(" packages");
161 for (int i = 0; i < mWhitelistedPackages.size(); i++) {
162 final String packageName = mWhitelistedPackages.keyAt(i);
163 final ArraySet<ComponentName> components = mWhitelistedPackages.valueAt(i);
Felipe Leme0f0b1d32019-03-06 11:40:39 -0800164 pw.print(prefix2); pw.print(i); pw.print("."); pw.print(packageName); pw.print(": ");
Adam He6240eab2019-02-25 13:34:45 -0800165 if (components == null) {
166 pw.println("(whole package)");
167 continue;
168 }
169
170 pw.print("["); pw.print(components.valueAt(0));
171 for (int j = 1; j < components.size(); j++) {
172 pw.print(", "); pw.print(components.valueAt(i));
173 }
174 pw.println("]");
175 }
176 }
177}