Merge "Optimize slice permission checks a bit" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a828705fc9
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user