diff options
| author | Felipe Leme <felipeal@google.com> | 2019-03-27 13:40:40 -0700 |
|---|---|---|
| committer | Felipe Leme <felipeal@google.com> | 2019-03-27 17:11:08 -0700 |
| commit | 9bee9440dbbba689f9d0c1dab3f19698e258d9d4 (patch) | |
| tree | 76bdfcfbe9ba6e1c4197a5d7ed6f1a9c0215d6b6 /core/java | |
| parent | 469e872bf0b38d88aaa6a7e05c9ee0d3f9d5d9d5 (diff) | |
Fixed ContentCapture and AugmentedAutofill methods that should not hold the main lock...
...otherwise they could ANR the ActivityManagerService and crash the system
Test: manual verification
Test: atest AugmentedLoginActivityTest
Test: atest CtsContentCaptureServiceTestCases # sanity check (minus usual flakiness)
Fixes: 129410913
Bug: 126266412
Change-Id: I4b0b0c389dd2c34928c6fffeec2854518a5e7da1
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/com/android/internal/infra/GlobalWhitelistState.java | 131 | ||||
| -rw-r--r-- | core/java/com/android/internal/infra/WhitelistHelper.java | 1 |
2 files changed, 132 insertions, 0 deletions
diff --git a/core/java/com/android/internal/infra/GlobalWhitelistState.java b/core/java/com/android/internal/infra/GlobalWhitelistState.java new file mode 100644 index 000000000000..dfa59b7bd0ac --- /dev/null +++ b/core/java/com/android/internal/infra/GlobalWhitelistState.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.infra; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.UserIdInt; +import android.content.ComponentName; +import android.util.ArraySet; +import android.util.SparseArray; + +import com.android.internal.annotations.GuardedBy; + +import java.io.PrintWriter; +import java.util.List; + +/** + * Helper class used to manage a {@link WhitelistHelper} per user instance when the main service + * cannot hold a lock when external entities (typically {@code ActivityManagerService}) needs to + * get whitelist info. + * + * <p>This class is thread safe. + */ +public class GlobalWhitelistState { + + // Uses full-name to avoid collision with service-provided mLock + protected final Object mGlobalWhitelistStateLock = new Object(); + + @Nullable + @GuardedBy("mGlobalWhitelistStateLock") + protected SparseArray<WhitelistHelper> mWhitelisterHelpers; + + /** + * Sets the whitelist for the given user. + */ + public void setWhitelist(@UserIdInt int userId, @Nullable List<String> packageNames, + @Nullable List<ComponentName> components) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) { + mWhitelisterHelpers = new SparseArray<>(1); + } + WhitelistHelper helper = mWhitelisterHelpers.get(userId); + if (helper == null) { + helper = new WhitelistHelper(); + mWhitelisterHelpers.put(userId, helper); + } + helper.setWhitelist(packageNames, components); + } + } + + /** + * Checks if the given package is whitelisted for the given user. + */ + public boolean isWhitelisted(@UserIdInt int userId, @NonNull String packageName) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) return false; + final WhitelistHelper helper = mWhitelisterHelpers.get(userId); + return helper == null ? false : helper.isWhitelisted(packageName); + } + } + + /** + * Checks if the given component is whitelisted for the given user. + */ + public boolean isWhitelisted(@UserIdInt int userId, @NonNull ComponentName componentName) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) return false; + final WhitelistHelper helper = mWhitelisterHelpers.get(userId); + return helper == null ? false : helper.isWhitelisted(componentName); + } + } + + /** + * Gets the whitelisted components for the given package and user. + */ + public ArraySet<ComponentName> getWhitelistedComponents(@UserIdInt int userId, + @NonNull String packageName) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) return null; + final WhitelistHelper helper = mWhitelisterHelpers.get(userId); + return helper == null ? null : helper.getWhitelistedComponents(packageName); + } + } + + /** + * Resets the whitelist for the given user. + */ + public void resetWhitelist(@NonNull int userId) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) return; + mWhitelisterHelpers.remove(userId); + if (mWhitelisterHelpers.size() == 0) { + mWhitelisterHelpers = null; + } + } + } + + /** + * Dumps it! + */ + public void dump(@NonNull String prefix, @NonNull PrintWriter pw) { + pw.print(prefix); pw.print("State: "); + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) { + pw.println("empty"); + return; + } + pw.print(mWhitelisterHelpers.size()); pw.println(" services"); + final String prefix2 = prefix + " "; + for (int i = 0; i < mWhitelisterHelpers.size(); i++) { + final int userId = mWhitelisterHelpers.keyAt(i); + final WhitelistHelper helper = mWhitelisterHelpers.valueAt(i); + helper.dump(prefix2, "Whitelist for userId " + userId, pw); + } + } + } +} diff --git a/core/java/com/android/internal/infra/WhitelistHelper.java b/core/java/com/android/internal/infra/WhitelistHelper.java index 183b465afbfd..d7753db6b0f7 100644 --- a/core/java/com/android/internal/infra/WhitelistHelper.java +++ b/core/java/com/android/internal/infra/WhitelistHelper.java @@ -31,6 +31,7 @@ import java.util.List; /** * Helper class for keeping track of whitelisted packages/activities. * + * <p><b>NOTE: </b>this class is not thread safe. * @hide */ public final class WhitelistHelper { |
