summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-05-22 18:50:24 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-05-22 18:50:24 +0000
commita828705fc90d35d85d8775e4929b4fe2c0dd69c7 (patch)
treede92d29d918984fbde24b2e6ab3363bec4c68238
parent2d6dbbac04a3f47cbdce91476337a8c7d7c0d0eb (diff)
parente009a8ed6ed309d0e75d6fc5739eb67eb174777c (diff)
Merge "Optimize slice permission checks a bit" into pi-dev
-rw-r--r--services/core/java/com/android/server/slice/SliceManagerService.java64
-rw-r--r--services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java75
2 files changed, 132 insertions, 7 deletions
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 2621c50fb2f2..c3b984172802 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -55,6 +55,7 @@ import android.os.ShellCallback;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.Xml.Encoding;
import com.android.internal.annotations.GuardedBy;
@@ -77,6 +78,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.function.Supplier;
public class SliceManagerService extends ISliceManager.Stub {
@@ -90,6 +92,10 @@ public class SliceManagerService extends ISliceManager.Stub {
@GuardedBy("mLock")
private final ArrayMap<Uri, PinnedSliceState> mPinnedSlicesByUri = new ArrayMap<>();
+ @GuardedBy("mLock")
+ private final SparseArray<PackageMatchingCache> mAssistantLookup = new SparseArray<>();
+ @GuardedBy("mLock")
+ private final SparseArray<PackageMatchingCache> mHomeLookup = new SparseArray<>();
private final Handler mHandler;
private final SlicePermissionManager mPermissions;
@@ -453,17 +459,37 @@ public class SliceManagerService extends ISliceManager.Stub {
}
private boolean isAssistant(String pkg, int userId) {
- final ComponentName cn = mAssistUtils.getAssistComponentForUser(userId);
- if (cn == null) {
- return false;
- }
- return cn.getPackageName().equals(pkg);
+ return getAssistantMatcher(userId).matches(pkg);
}
private boolean isDefaultHomeApp(String pkg, int userId) {
- String defaultHome = getDefaultHome(userId);
+ return getHomeMatcher(userId).matches(pkg);
+ }
- return pkg != null && Objects.equals(pkg, defaultHome);
+ private PackageMatchingCache getAssistantMatcher(int userId) {
+ PackageMatchingCache matcher = mAssistantLookup.get(userId);
+ if (matcher == null) {
+ matcher = new PackageMatchingCache(() -> getAssistant(userId));
+ mAssistantLookup.put(userId, matcher);
+ }
+ return matcher;
+ }
+
+ private PackageMatchingCache getHomeMatcher(int userId) {
+ PackageMatchingCache matcher = mHomeLookup.get(userId);
+ if (matcher == null) {
+ matcher = new PackageMatchingCache(() -> getDefaultHome(userId));
+ mHomeLookup.put(userId, matcher);
+ }
+ return matcher;
+ }
+
+ private String getAssistant(int userId) {
+ final ComponentName cn = mAssistUtils.getAssistComponentForUser(userId);
+ if (cn == null) {
+ return null;
+ }
+ return cn.getPackageName();
}
// Based on getDefaultHome in ShortcutService.
@@ -559,6 +585,30 @@ public class SliceManagerService extends ISliceManager.Stub {
return mPermissions.getAllPackagesGranted(pkg);
}
+ /**
+ * Holder that caches a package that has access to a slice.
+ */
+ static class PackageMatchingCache {
+
+ private final Supplier<String> mPkgSource;
+ private String mCurrentPkg;
+
+ public PackageMatchingCache(Supplier<String> pkgSource) {
+ mPkgSource = pkgSource;
+ }
+
+ public boolean matches(String pkgCandidate) {
+ if (pkgCandidate == null) return false;
+
+ if (Objects.equals(pkgCandidate, mCurrentPkg)) {
+ return true;
+ }
+ // Failed on cached value, try updating.
+ mCurrentPkg = mPkgSource.get();
+ return Objects.equals(pkgCandidate, mCurrentPkg);
+ }
+ }
+
public static class Lifecycle extends SystemService {
private SliceManagerService mService;
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java
new file mode 100644
index 000000000000..c6aea882b7ca
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 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.server.slice;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.server.UiServiceTestCase;
+import com.android.server.slice.SliceManagerService.PackageMatchingCache;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.function.Supplier;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class PackageMatchingCacheTest extends UiServiceTestCase {
+
+ private final Supplier<String> supplier = mock(Supplier.class);
+ private final PackageMatchingCache cache = new PackageMatchingCache(supplier);
+
+ @Test
+ public void testNulls() {
+ // Doesn't get for a null input
+ cache.matches(null);
+ verify(supplier, never()).get();
+
+ // Gets once valid input in sent.
+ cache.matches("");
+ verify(supplier).get();
+ }
+
+ @Test
+ public void testCaching() {
+ when(supplier.get()).thenReturn("ret.pkg");
+
+ assertTrue(cache.matches("ret.pkg"));
+ assertTrue(cache.matches("ret.pkg"));
+ assertTrue(cache.matches("ret.pkg"));
+
+ verify(supplier, times(1)).get();
+ }
+
+ @Test
+ public void testGetOnFailure() {
+ when(supplier.get()).thenReturn("ret.pkg");
+ assertTrue(cache.matches("ret.pkg"));
+
+ when(supplier.get()).thenReturn("other.pkg");
+ assertTrue(cache.matches("other.pkg"));
+ verify(supplier, times(2)).get();
+ }
+}