diff options
| -rw-r--r-- | services/core/java/com/android/server/slice/SliceManagerService.java | 64 | ||||
| -rw-r--r-- | services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java | 75 |
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(); + } +} |