Move withPackageSettingsSnapshot methods into PackageManagerInternal

For consumers who don't care about blocking package data updates and
only need data at a specific snapshot in time, these methods would
avoid locking PMS during the iteration process.

Bug: 183643808

Test: atest com.android.server.pm.test.verify.domain

Change-Id: Ia951381798d75f77c4ad5fc010a469b69992f074
This commit is contained in:
Winson
2021-04-01 14:24:35 -07:00
parent 8d3b16568a
commit a74c1f3c69
7 changed files with 295 additions and 181 deletions

View File

@@ -247,6 +247,48 @@ public class FunctionalUtils {
}
}
/**
* A {@link Consumer} that allows the caller to specify a custom checked {@link Exception} that
* can be thrown by the implementer. This is usually used when proxying/wrapping calls between
* different classes.
*
* @param <Input> Method parameter type
* @param <ExceptionType> Checked exception type
*/
@FunctionalInterface
public interface ThrowingCheckedConsumer<Input, ExceptionType extends Exception> {
void accept(Input input) throws ExceptionType;
}
/**
* A {@link Consumer} that allows the caller to specify 2 different custom checked
* {@link Exception}s that can be thrown by the implementer. This is usually used when
* proxying/wrapping calls between different classes.
*
* @param <Input> Method parameter type
* @param <ExceptionOne> First checked exception type
* @param <ExceptionTwo> Second checked exception type
*/
@FunctionalInterface
public interface ThrowingChecked2Consumer<Input, ExceptionOne extends Exception,
ExceptionTwo extends Exception> {
void accept(Input input) throws ExceptionOne, ExceptionTwo;
}
/**
* A {@link Function} that allows the caller to specify a custom checked {@link Exception} that
* can be thrown by the implementer. This is usually used when proxying/wrapping calls between
* different classes.
*
* @param <Input> Method parameter type
* @param <Output> Method return type
* @param <ExceptionType> Checked exception type
*/
@FunctionalInterface
public interface ThrowingCheckedFunction<Input, Output, ExceptionType extends Exception> {
Output apply(Input input) throws ExceptionType;
}
// TODO: add unit test
/**
* Gets a user-friendly name for a lambda function.

View File

@@ -60,7 +60,7 @@ import java.util.function.Consumer;
*
* @hide Only for use within the system server.
*/
public abstract class PackageManagerInternal {
public abstract class PackageManagerInternal implements PackageSettingsSnapshotProvider {
@IntDef(prefix = "PACKAGE_", value = {
PACKAGE_SYSTEM,
PACKAGE_SETUP_WIZARD,
@@ -795,6 +795,9 @@ public abstract class PackageManagerInternal {
* Perform the given action for each package.
* Note that packages lock will be held while performing the actions.
*
* If the caller does not need all packages, prefer the potentially non-locking
* {@link #withPackageSettingsSnapshot(Consumer)}.
*
* @param actionLocked action to be performed
*/
public abstract void forEachPackage(Consumer<AndroidPackage> actionLocked);
@@ -803,6 +806,9 @@ public abstract class PackageManagerInternal {
* Perform the given action for each {@link PackageSetting}.
* Note that packages lock will be held while performing the actions.
*
* If the caller does not need all packages, prefer the potentially non-locking
* {@link #withPackageSettingsSnapshot(Consumer)}.
*
* @param actionLocked action to be performed
*/
public abstract void forEachPackageSetting(Consumer<PackageSetting> actionLocked);

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2021 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 android.content.pm;
import android.annotation.NonNull;
import com.android.internal.util.FunctionalUtils;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.PackageSetting;
import java.util.function.Consumer;
import java.util.function.Function;
/** @hide */
public interface PackageSettingsSnapshotProvider {
/**
* Run a function block that requires access to {@link PackageSetting} data. This will
* ensure the {@link PackageManagerService} lock is taken before any caller's internal lock
* to avoid deadlock. Note that this method may or may not lock. If a snapshot is available
* and valid, it will iterate the snapshot set of data.
*/
void withPackageSettingsSnapshot(
@NonNull Consumer<Function<String, PackageSetting>> block);
/**
* Variant which returns a value to the caller.
* @see #withPackageSettingsSnapshot(Consumer)
*/
<Output> Output withPackageSettingsSnapshotReturning(
@NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
block);
/**
* Variant which throws.
* @see #withPackageSettingsSnapshot(Consumer)
*/
<ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
@NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>,
ExceptionType> block) throws ExceptionType;
/**
* Variant which throws 2 exceptions.
* @see #withPackageSettingsSnapshot(Consumer)
*/
<ExceptionOne extends Exception, ExceptionTwo extends Exception> void
withPackageSettingsSnapshotThrowing2(
@NonNull FunctionalUtils.ThrowingChecked2Consumer<
Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)
throws ExceptionOne, ExceptionTwo;
/**
* Variant which returns a value to the caller and throws.
* @see #withPackageSettingsSnapshot(Consumer)
*/
<Output, ExceptionType extends Exception> Output
withPackageSettingsSnapshotReturningThrowing(
@NonNull FunctionalUtils.ThrowingCheckedFunction<
Function<String, PackageSetting>, Output, ExceptionType> block)
throws ExceptionType;
}

View File

@@ -1731,91 +1731,6 @@ public class PackageManagerService extends IPackageManager.Stub
return PackageManagerService.this.getPackage(packageName);
}
@NonNull
@Override
public void withPackageSettings(@NonNull Consumer<Function<String, PackageSetting>> block) {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
block.accept(snapshot::getPackageSetting);
}
} else {
block.accept(snapshot::getPackageSetting);
}
}
@Override
public <Output> Output withPackageSettingsReturning(
@NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
block) {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
return block.apply(snapshot::getPackageSetting);
}
} else {
return block.apply(snapshot::getPackageSetting);
}
}
@Override
public <ExceptionType extends Exception> void withPackageSettingsThrowing(
@NonNull ThrowingConsumer<Function<String, PackageSetting>, ExceptionType> block)
throws ExceptionType {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
block.accept(snapshot::getPackageSetting);
}
} else {
block.accept(snapshot::getPackageSetting);
}
}
@Override
public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
withPackageSettingsThrowing2(
@NonNull Throwing2Consumer<Function<String, PackageSetting>, ExceptionOne,
ExceptionTwo> block) throws ExceptionOne, ExceptionTwo {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
block.accept(snapshot::getPackageSetting);
}
} else {
block.accept(snapshot::getPackageSetting);
}
}
@Override
public <Output, ExceptionType extends Exception> Output
withPackageSettingsReturningThrowing(@NonNull ThrowingFunction<Function<String,
PackageSetting>, Output, ExceptionType> block) throws ExceptionType {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
return block.apply(snapshot::getPackageSetting);
}
} else {
return block.apply(snapshot::getPackageSetting);
}
}
@Override
public boolean filterAppAccess(String packageName, int callingUid, int userId) {
return mPmInternal.filterAppAccess(packageName, callingUid, userId);
@@ -1830,6 +1745,44 @@ public class PackageManagerService extends IPackageManager.Stub
public boolean doesUserExist(@UserIdInt int userId) {
return mUserManager.exists(userId);
}
@Override
public void withPackageSettingsSnapshot(
@NonNull Consumer<Function<String, PackageSetting>> block) {
mPmInternal.withPackageSettingsSnapshot(block);
}
@Override
public <Output> Output withPackageSettingsSnapshotReturning(
@NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
block) {
return mPmInternal.withPackageSettingsSnapshotReturning(block);
}
@Override
public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
@NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>,
ExceptionType> block) throws ExceptionType {
mPmInternal.withPackageSettingsSnapshotThrowing(block);
}
@Override
public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
withPackageSettingsSnapshotThrowing2(
@NonNull FunctionalUtils.ThrowingChecked2Consumer<
Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)
throws ExceptionOne, ExceptionTwo {
mPmInternal.withPackageSettingsSnapshotThrowing2(block);
}
@Override
public <Output, ExceptionType extends Exception> Output
withPackageSettingsSnapshotReturningThrowing(
@NonNull FunctionalUtils.ThrowingCheckedFunction<
Function<String, PackageSetting>, Output, ExceptionType> block)
throws ExceptionType {
return mPmInternal.withPackageSettingsSnapshotReturningThrowing(block);
}
}
/**
@@ -1843,7 +1796,7 @@ public class PackageManagerService extends IPackageManager.Stub
private final Watcher mWatcher = new Watcher() {
@Override
public void onChange(@Nullable Watchable what) {
public void onChange(@Nullable Watchable what) {
PackageManagerService.this.onChange(what);
}
};
@@ -27290,6 +27243,94 @@ public class PackageManagerService extends IPackageManager.Stub
public void deleteOatArtifactsOfPackage(String packageName) {
PackageManagerService.this.deleteOatArtifactsOfPackage(packageName);
}
@Override
public void withPackageSettingsSnapshot(
@NonNull Consumer<Function<String, PackageSetting>> block) {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
block.accept(snapshot::getPackageSetting);
}
} else {
block.accept(snapshot::getPackageSetting);
}
}
@Override
public <Output> Output withPackageSettingsSnapshotReturning(
@NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
block) {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
return block.apply(snapshot::getPackageSetting);
}
} else {
return block.apply(snapshot::getPackageSetting);
}
}
@Override
public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
@NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>,
ExceptionType> block) throws ExceptionType {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
block.accept(snapshot::getPackageSetting);
}
} else {
block.accept(snapshot::getPackageSetting);
}
}
@Override
public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
withPackageSettingsSnapshotThrowing2(
@NonNull FunctionalUtils.ThrowingChecked2Consumer<
Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)
throws ExceptionOne, ExceptionTwo {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
block.accept(snapshot::getPackageSetting);
}
} else {
block.accept(snapshot::getPackageSetting);
}
}
@Override
public <Output, ExceptionType extends Exception> Output
withPackageSettingsSnapshotReturningThrowing(
@NonNull FunctionalUtils.ThrowingCheckedFunction<
Function<String, PackageSetting>, Output, ExceptionType> block)
throws ExceptionType {
final Computer snapshot = snapshotComputer();
// This method needs to either lock or not lock consistently throughout the method,
// so if the live computer is returned, force a wrapping sync block.
if (snapshot == mLiveComputer) {
synchronized (mLock) {
return block.apply(snapshot::getPackageSetting);
}
} else {
return block.apply(snapshot::getPackageSetting);
}
}
}
@GuardedBy("mLock")

View File

@@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageSettingsSnapshotProvider;
import android.content.pm.ResolveInfo;
import android.content.pm.verify.domain.DomainVerificationInfo;
import android.content.pm.verify.domain.DomainVerificationManager;
@@ -36,7 +37,6 @@ import android.util.Pair;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import com.android.internal.util.FunctionalUtils;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.PackageSetting;
import com.android.server.pm.Settings;
@@ -49,7 +49,6 @@ import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;
public interface DomainVerificationManagerInternal {
@@ -406,7 +405,8 @@ public interface DomainVerificationManagerInternal {
@NonNull Set<String> domains, int state) throws NameNotFoundException;
interface Connection extends DomainVerificationEnforcer.Callback {
interface Connection extends DomainVerificationEnforcer.Callback,
PackageSettingsSnapshotProvider {
/**
* Notify that a settings change has been made and that eventually
@@ -430,60 +430,7 @@ public interface DomainVerificationManagerInternal {
*/
void schedule(int code, @Nullable Object object);
/**
* Run a function block that requires access to {@link PackageSetting} data. This will
* ensure the {@link PackageManagerService} is taken before
* {@link DomainVerificationManagerInternal}'s lock is taken to avoid deadlock.
*/
void withPackageSettings(@NonNull Consumer<Function<String, PackageSetting>> block);
/**
* Variant which returns a value to the caller.
* @see #withPackageSettings(Consumer)
*/
<Output> Output withPackageSettingsReturning(
@NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
block);
/**
* Variant which throws.
* @see #withPackageSettings(Consumer)
*/
<ExceptionType extends Exception> void withPackageSettingsThrowing(
@NonNull ThrowingConsumer<Function<String, PackageSetting>, ExceptionType> block)
throws ExceptionType;
/**
* Variant which throws 2 exceptions.
* @see #withPackageSettings(Consumer)
*/
<ExceptionOne extends Exception, ExceptionTwo extends Exception> void
withPackageSettingsThrowing2(
@NonNull Throwing2Consumer<Function<String, PackageSetting>, ExceptionOne,
ExceptionTwo> block) throws ExceptionOne, ExceptionTwo;
/**
* Variant which returns a value to the caller and throws.
* @see #withPackageSettings(Consumer)
*/
<Output, ExceptionType extends Exception> Output withPackageSettingsReturningThrowing(
@NonNull ThrowingFunction<Function<String, PackageSetting>, Output, ExceptionType>
block) throws ExceptionType;
@UserIdInt
int[] getAllUserIds();
interface ThrowingConsumer<Input, ExceptionType extends Exception> {
void accept(Input input) throws ExceptionType;
}
interface Throwing2Consumer<Input, ExceptionOne extends Exception,
ExceptionTwo extends Exception> {
void accept(Input input) throws ExceptionOne, ExceptionTwo;
}
interface ThrowingFunction<Input, Output, ExceptionType extends Exception> {
Output apply(Input input) throws ExceptionType;
}
}
}

View File

@@ -260,7 +260,7 @@ public class DomainVerificationService extends SystemService
public DomainVerificationInfo getDomainVerificationInfo(@NonNull String packageName)
throws NameNotFoundException {
mEnforcer.assertApprovedQuerent(mConnection.getCallingUid(), mProxy);
return mConnection.withPackageSettingsReturningThrowing(pkgSettings -> {
return mConnection.withPackageSettingsSnapshotReturningThrowing(pkgSettings -> {
synchronized (mLock) {
PackageSetting pkgSetting = pkgSettings.apply(packageName);
AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
@@ -320,7 +320,7 @@ public class DomainVerificationService extends SystemService
@NonNull Set<String> domains, int state)
throws NameNotFoundException {
mEnforcer.assertApprovedVerifier(callingUid, mProxy);
return mConnection.withPackageSettingsReturningThrowing(pkgSettings -> {
return mConnection.withPackageSettingsSnapshotReturningThrowing(pkgSettings -> {
synchronized (mLock) {
List<String> verifiedDomains = new ArrayList<>();
@@ -376,7 +376,7 @@ public class DomainVerificationService extends SystemService
ArraySet<String> verifiedDomains = new ArraySet<>();
if (packageName == null) {
mConnection.withPackageSettings(pkgSettings -> {
mConnection.withPackageSettingsSnapshot(pkgSettings -> {
synchronized (mLock) {
ArraySet<String> validDomains = new ArraySet<>();
@@ -411,7 +411,7 @@ public class DomainVerificationService extends SystemService
}
});
} else {
mConnection.withPackageSettingsThrowing(pkgSettings -> {
mConnection.withPackageSettingsSnapshotThrowing(pkgSettings -> {
synchronized (mLock) {
DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
if (pkgState == null) {
@@ -548,7 +548,7 @@ public class DomainVerificationService extends SystemService
return DomainVerificationManager.ERROR_DOMAIN_SET_ID_INVALID;
}
return mConnection.withPackageSettingsReturningThrowing(pkgSettings -> {
return mConnection.withPackageSettingsSnapshotReturningThrowing(pkgSettings -> {
synchronized (mLock) {
GetAttachedResult result = getAndValidateAttachedLocked(domainSetId, domains,
false /* forAutoVerify */, callingUid, userId, pkgSettings);
@@ -588,7 +588,7 @@ public class DomainVerificationService extends SystemService
@NonNull String packageName, boolean enabled, @Nullable ArraySet<String> domains)
throws NameNotFoundException {
mEnforcer.assertInternal(mConnection.getCallingUid());
mConnection.withPackageSettingsThrowing(pkgSettings -> {
mConnection.withPackageSettingsSnapshotThrowing(pkgSettings -> {
synchronized (mLock) {
DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
if (pkgState == null) {
@@ -694,7 +694,7 @@ public class DomainVerificationService extends SystemService
throw DomainVerificationUtils.throwPackageUnavailable(packageName);
}
return mConnection.withPackageSettingsReturningThrowing(pkgSettings -> {
return mConnection.withPackageSettingsSnapshotReturningThrowing(pkgSettings -> {
synchronized (mLock) {
PackageSetting pkgSetting = pkgSettings.apply(packageName);
AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
@@ -747,7 +747,7 @@ public class DomainVerificationService extends SystemService
mEnforcer.assertOwnerQuerent(mConnection.getCallingUid(), mConnection.getCallingUserId(),
userId);
return mConnection.withPackageSettingsReturningThrowing(pkgSettings -> {
return mConnection.withPackageSettingsSnapshotReturningThrowing(pkgSettings -> {
SparseArray<List<String>> levelToPackages = getOwnersForDomainInternal(domain, false,
userId, pkgSettings);
if (levelToPackages.size() == 0) {
@@ -1048,7 +1048,7 @@ public class DomainVerificationService extends SystemService
public void writeSettings(@NonNull TypedXmlSerializer serializer, boolean includeSignatures,
@UserIdInt int userId)
throws IOException {
mConnection.withPackageSettingsThrowing(pkgSettings -> {
mConnection.withPackageSettingsSnapshotThrowing(pkgSettings -> {
synchronized (mLock) {
Function<String, String> pkgNameToSignature = null;
if (includeSignatures) {
@@ -1077,7 +1077,7 @@ public class DomainVerificationService extends SystemService
@Override
public void readSettings(@NonNull TypedXmlPullParser parser) throws IOException,
XmlPullParserException {
mConnection.<IOException, XmlPullParserException>withPackageSettingsThrowing2(
mConnection.<IOException, XmlPullParserException>withPackageSettingsSnapshotThrowing2(
pkgSettings -> {
synchronized (mLock) {
mSettings.readSettings(parser, mAttachedPkgStates, pkgSettings);
@@ -1094,7 +1094,7 @@ public class DomainVerificationService extends SystemService
@Override
public void restoreSettings(@NonNull TypedXmlPullParser parser)
throws IOException, XmlPullParserException {
mConnection.<IOException, XmlPullParserException>withPackageSettingsThrowing2(
mConnection.<IOException, XmlPullParserException>withPackageSettingsSnapshotThrowing2(
pkgSettings -> {
synchronized (mLock) {
mSettings.restoreSettings(parser, mAttachedPkgStates, pkgSettings);
@@ -1175,7 +1175,7 @@ public class DomainVerificationService extends SystemService
@Override
public void printState(@NonNull IndentingPrintWriter writer, @Nullable String packageName,
@Nullable Integer userId) throws NameNotFoundException {
mConnection.withPackageSettingsThrowing(
mConnection.withPackageSettingsSnapshotThrowing(
pkgSettings -> printState(writer, packageName, userId, pkgSettings));
}
@@ -1193,7 +1193,7 @@ public class DomainVerificationService extends SystemService
public void printOwnersForPackage(@NonNull IndentingPrintWriter writer,
@Nullable String packageName, @Nullable @UserIdInt Integer userId)
throws NameNotFoundException {
mConnection.withPackageSettingsThrowing(pkgSettings -> {
mConnection.withPackageSettingsSnapshotThrowing(pkgSettings -> {
synchronized (mLock) {
if (packageName == null) {
int size = mAttachedPkgStates.size();
@@ -1242,7 +1242,7 @@ public class DomainVerificationService extends SystemService
@Override
public void printOwnersForDomains(@NonNull IndentingPrintWriter writer,
@NonNull List<String> domains, @Nullable @UserIdInt Integer userId) {
mConnection.withPackageSettings(pkgSettings -> {
mConnection.withPackageSettingsSnapshot(pkgSettings -> {
synchronized (mLock) {
int size = domains.size();
for (int index = 0; index < size; index++) {
@@ -1421,7 +1421,7 @@ public class DomainVerificationService extends SystemService
@Override
public void clearDomainVerificationState(@Nullable List<String> packageNames) {
mEnforcer.assertInternal(mConnection.getCallingUid());
mConnection.withPackageSettings(pkgSettings -> {
mConnection.withPackageSettingsSnapshot(pkgSettings -> {
synchronized (mLock) {
if (packageNames == null) {
int size = mAttachedPkgStates.size();
@@ -2022,43 +2022,46 @@ public class DomainVerificationService extends SystemService
}
@Override
public void withPackageSettings(
public void withPackageSettingsSnapshot(
@NonNull Consumer<Function<String, PackageSetting>> block) {
enforceLocking();
mConnection.withPackageSettings(block);
mConnection.withPackageSettingsSnapshot(block);
}
@Override
public <Output> Output withPackageSettingsReturning(
public <Output> Output withPackageSettingsSnapshotReturning(
@NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
block) {
enforceLocking();
return mConnection.withPackageSettingsReturning(block);
return mConnection.withPackageSettingsSnapshotReturning(block);
}
@Override
public <ExceptionType extends Exception> void withPackageSettingsThrowing(
@NonNull ThrowingConsumer<Function<String, PackageSetting>, ExceptionType> block)
throws ExceptionType {
public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
@NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>,
ExceptionType> block) throws ExceptionType {
enforceLocking();
mConnection.withPackageSettingsThrowing(block);
mConnection.withPackageSettingsSnapshotThrowing(block);
}
@Override
public <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
withPackageSettingsThrowing2(
@NonNull Throwing2Consumer<Function<String, PackageSetting>, ExceptionOne,
ExceptionTwo> block) throws ExceptionOne, ExceptionTwo {
withPackageSettingsSnapshotThrowing2(
@NonNull FunctionalUtils.ThrowingChecked2Consumer<
Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)
throws ExceptionOne, ExceptionTwo {
enforceLocking();
mConnection.withPackageSettingsThrowing2(block);
mConnection.withPackageSettingsSnapshotThrowing2(block);
}
@Override
public <Output, ExceptionType extends Exception> Output
withPackageSettingsReturningThrowing(@NonNull ThrowingFunction<Function<String,
PackageSetting>, Output, ExceptionType> block) throws ExceptionType {
withPackageSettingsSnapshotReturningThrowing(
@NonNull FunctionalUtils.ThrowingCheckedFunction<
Function<String, PackageSetting>, Output, ExceptionType> block)
throws ExceptionType {
enforceLocking();
return mConnection.withPackageSettingsReturningThrowing(block);
return mConnection.withPackageSettingsSnapshotReturningThrowing(block);
}
@Override

View File

@@ -30,25 +30,25 @@ internal object DomainVerificationTestUtils {
fun DomainVerificationManagerInternal.Connection.mockPackageSettings(
block: (String) -> PackageSetting?
) {
whenever(withPackageSettings(any())) {
whenever(withPackageSettingsSnapshot(any())) {
(arguments[0] as Consumer<Function<String, PackageSetting?>>).accept { block(it) }
}
whenever(withPackageSettingsReturning<Any>(any())) {
whenever(withPackageSettingsSnapshotReturning<Any>(any())) {
(arguments[0] as FunctionalUtils.ThrowingFunction<Function<String, PackageSetting?>, *>)
.apply { block(it) }
}
whenever(withPackageSettingsThrowing<Exception>(any())) {
(arguments[0] as DomainVerificationManagerInternal.Connection.ThrowingConsumer<
whenever(withPackageSettingsSnapshotThrowing<Exception>(any())) {
(arguments[0] as FunctionalUtils.ThrowingCheckedConsumer<
Function<String, PackageSetting?>, *>)
.accept { block(it) }
}
whenever(withPackageSettingsThrowing2<Exception, Exception>(any())) {
(arguments[0] as DomainVerificationManagerInternal.Connection.Throwing2Consumer<
whenever(withPackageSettingsSnapshotThrowing2<Exception, Exception>(any())) {
(arguments[0] as FunctionalUtils.ThrowingChecked2Consumer<
Function<String, PackageSetting?>, *, *>)
.accept { block(it) }
}
whenever(withPackageSettingsReturningThrowing<Any, Exception>(any())) {
(arguments[0] as DomainVerificationManagerInternal.Connection.ThrowingFunction<
whenever(withPackageSettingsSnapshotReturningThrowing<Any, Exception>(any())) {
(arguments[0] as FunctionalUtils.ThrowingCheckedFunction<
Function<String, PackageSetting?>, *, *>)
.apply { block(it) }
}