Loading core/java/com/android/internal/util/FunctionalUtils.java +42 −0 Original line number Diff line number Diff line Loading @@ -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. Loading services/core/java/android/content/pm/PackageManagerInternal.java +7 −1 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading @@ -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); Loading services/core/java/android/content/pm/PackageSettingsSnapshotProvider.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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; } services/core/java/com/android/server/pm/PackageManagerService.java +118 −77 Original line number Diff line number Diff line Loading @@ -1731,104 +1731,57 @@ 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); } public boolean filterAppAccess(String packageName, int callingUid, int userId) { return mPmInternal.filterAppAccess(packageName, callingUid, userId); } @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); } public int[] getAllUserIds() { return mUserManager.getUserIds(); } @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); } public boolean doesUserExist(@UserIdInt int userId) { return mUserManager.exists(userId); } @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); } public void withPackageSettingsSnapshot( @NonNull Consumer<Function<String, PackageSetting>> block) { mPmInternal.withPackageSettingsSnapshot(block); } @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); } public <Output> Output withPackageSettingsSnapshotReturning( @NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output> block) { return mPmInternal.withPackageSettingsSnapshotReturning(block); } @Override public boolean filterAppAccess(String packageName, int callingUid, int userId) { return mPmInternal.filterAppAccess(packageName, callingUid, userId); public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing( @NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>, ExceptionType> block) throws ExceptionType { mPmInternal.withPackageSettingsSnapshotThrowing(block); } @Override public int[] getAllUserIds() { return mUserManager.getUserIds(); 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 boolean doesUserExist(@UserIdInt int userId) { return mUserManager.exists(userId); public <Output, ExceptionType extends Exception> Output withPackageSettingsSnapshotReturningThrowing( @NonNull FunctionalUtils.ThrowingCheckedFunction< Function<String, PackageSetting>, Output, ExceptionType> block) throws ExceptionType { return mPmInternal.withPackageSettingsSnapshotReturningThrowing(block); } } Loading Loading @@ -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") services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java +3 −56 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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 Loading @@ -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; } } } Loading
core/java/com/android/internal/util/FunctionalUtils.java +42 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
services/core/java/android/content/pm/PackageManagerInternal.java +7 −1 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading @@ -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); Loading
services/core/java/android/content/pm/PackageSettingsSnapshotProvider.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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; }
services/core/java/com/android/server/pm/PackageManagerService.java +118 −77 Original line number Diff line number Diff line Loading @@ -1731,104 +1731,57 @@ 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); } public boolean filterAppAccess(String packageName, int callingUid, int userId) { return mPmInternal.filterAppAccess(packageName, callingUid, userId); } @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); } public int[] getAllUserIds() { return mUserManager.getUserIds(); } @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); } public boolean doesUserExist(@UserIdInt int userId) { return mUserManager.exists(userId); } @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); } public void withPackageSettingsSnapshot( @NonNull Consumer<Function<String, PackageSetting>> block) { mPmInternal.withPackageSettingsSnapshot(block); } @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); } public <Output> Output withPackageSettingsSnapshotReturning( @NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output> block) { return mPmInternal.withPackageSettingsSnapshotReturning(block); } @Override public boolean filterAppAccess(String packageName, int callingUid, int userId) { return mPmInternal.filterAppAccess(packageName, callingUid, userId); public <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing( @NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>, ExceptionType> block) throws ExceptionType { mPmInternal.withPackageSettingsSnapshotThrowing(block); } @Override public int[] getAllUserIds() { return mUserManager.getUserIds(); 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 boolean doesUserExist(@UserIdInt int userId) { return mUserManager.exists(userId); public <Output, ExceptionType extends Exception> Output withPackageSettingsSnapshotReturningThrowing( @NonNull FunctionalUtils.ThrowingCheckedFunction< Function<String, PackageSetting>, Output, ExceptionType> block) throws ExceptionType { return mPmInternal.withPackageSettingsSnapshotReturningThrowing(block); } } Loading Loading @@ -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")
services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java +3 −56 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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 Loading @@ -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; } } }