Merge "Optimize slice permission checks a bit" into pi-dev
am: a828705fc9
Change-Id: I190ce1596596946f45ead7c8f3b325c1d16eeb3c
This commit is contained in:
@@ -55,6 +55,7 @@ import android.os.ShellCallback;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
import android.util.SparseArray;
|
||||||
import android.util.Xml.Encoding;
|
import android.util.Xml.Encoding;
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
@@ -77,6 +78,7 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class SliceManagerService extends ISliceManager.Stub {
|
public class SliceManagerService extends ISliceManager.Stub {
|
||||||
|
|
||||||
@@ -90,6 +92,10 @@ public class SliceManagerService extends ISliceManager.Stub {
|
|||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final ArrayMap<Uri, PinnedSliceState> mPinnedSlicesByUri = new ArrayMap<>();
|
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 Handler mHandler;
|
||||||
|
|
||||||
private final SlicePermissionManager mPermissions;
|
private final SlicePermissionManager mPermissions;
|
||||||
@@ -453,17 +459,37 @@ public class SliceManagerService extends ISliceManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAssistant(String pkg, int userId) {
|
private boolean isAssistant(String pkg, int userId) {
|
||||||
final ComponentName cn = mAssistUtils.getAssistComponentForUser(userId);
|
return getAssistantMatcher(userId).matches(pkg);
|
||||||
if (cn == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return cn.getPackageName().equals(pkg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDefaultHomeApp(String pkg, int userId) {
|
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.
|
// Based on getDefaultHome in ShortcutService.
|
||||||
@@ -559,6 +585,30 @@ public class SliceManagerService extends ISliceManager.Stub {
|
|||||||
return mPermissions.getAllPackagesGranted(pkg);
|
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 {
|
public static class Lifecycle extends SystemService {
|
||||||
private SliceManagerService mService;
|
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