Loading core/java/android/app/admin/DevicePolicyManager.java +11 −2 Original line number Diff line number Diff line Loading @@ -3985,6 +3985,7 @@ public class DevicePolicyManager { */ public static final String AUTO_TIMEZONE_POLICY = "autoTimezone"; // TODO: Expose this as SystemAPI once we add the query API /** * @hide */ Loading @@ -4011,14 +4012,22 @@ public class DevicePolicyManager { /** * @hide */ public static final String USER_CONTROL_DISABLED_PACKAGES = "userControlDisabledPackages"; public static final String USER_CONTROL_DISABLED_PACKAGES_POLICY = "userControlDisabledPackages"; // TODO: Expose this as SystemAPI once we add the query API /** * @hide */ public static final String PERSISTENT_PREFERRED_ACTIVITY_POLICY = "persistentPreferredActivity"; // TODO: Expose this as SystemAPI once we add the query API /** * @hide */ public static final String PERSISTENT_PREFERRED_ACTIVITY = "persistentPreferredActivity"; public static final String PACKAGE_UNINSTALL_BLOCKED_POLICY = "packageUninstallBlocked"; /** * This object is a single place to tack on invalidation and disable calls. All Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +50 −14 Original line number Diff line number Diff line Loading @@ -12219,11 +12219,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { || isFinancedDeviceOwner(caller))) || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_BLOCK_UNINSTALL))); if (isCoexistenceEnabled(caller)) { // TODO(b/260573124): Add correct enforcing admin when permission changes are // merged, and don't forget to handle delegates! Enterprise admins assume // component name isn't null. EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin( who != null ? who : new ComponentName(callerPackage, "delegate"), caller.getUserId()); mDevicePolicyEngine.setLocalPolicy( PolicyDefinition.PACKAGE_UNINSTALL_BLOCKED(packageName), admin, uninstallBlocked, caller.getUserId()); } else { final int userId = caller.getUserId(); synchronized (getLockObject()) { long id = mInjector.binderClearCallingIdentity(); try { mIPackageManager.setBlockUninstallForUser(packageName, uninstallBlocked, userId); mIPackageManager.setBlockUninstallForUser( packageName, uninstallBlocked, userId); } catch (RemoteException re) { // Shouldn't happen. Slogf.e(LOG_TAG, "Failed to setBlockUninstallForUser", re); Loading @@ -12237,6 +12251,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pmi.removeDistractingPackageRestrictions(packageName, userId); pmi.flushPackageRestrictions(userId); } } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_UNINSTALL_BLOCKED) .setAdmin(caller.getPackageName()) Loading @@ -12245,6 +12261,26 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } static void setUninstallBlockedUnchecked( String packageName, boolean uninstallBlocked, int userId) { Binder.withCleanCallingIdentity(() -> { try { AppGlobals.getPackageManager().setBlockUninstallForUser( packageName, uninstallBlocked, userId); } catch (RemoteException re) { // Shouldn't happen. Slogf.e(LOG_TAG, "Failed to setBlockUninstallForUser", re); } }); if (uninstallBlocked) { final PackageManagerInternal pmi = LocalServices.getService( PackageManagerInternal.class); pmi.removeNonSystemPackageSuspensions(packageName, userId); pmi.removeDistractingPackageRestrictions(packageName, userId); pmi.flushPackageRestrictions(userId); } } @Override public boolean isUninstallBlocked(ComponentName who, String packageName) { // This function should return true if and only if the package is blocked by services/devicepolicy/java/com/android/server/devicepolicy/PackageSpecificPolicyKey.java 0 → 100644 +101 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.devicepolicy; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_PACKAGE_NAME; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_BUNDLE_KEY; import android.annotation.Nullable; import android.os.Bundle; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.Objects; /** * Class used to identify a policy that relates to a certain package in the policy engine's data * structure. */ final class PackageSpecificPolicyKey extends PolicyKey { private static final String ATTR_POLICY_KEY = "policy-key"; private static final String ATTR_PACKAGE_NAME = "package-name"; private static final String ATTR_PERMISSION_NAME = "permission-name"; private final String mPackageName; PackageSpecificPolicyKey(String key, String packageName) { super(key); mPackageName = Objects.requireNonNull((packageName)); } PackageSpecificPolicyKey(String key) { super(key); mPackageName = null; } @Nullable String getPackageName() { return mPackageName; } @Override void saveToXml(TypedXmlSerializer serializer) throws IOException { serializer.attribute(/* namespace= */ null, ATTR_POLICY_KEY, mKey); serializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName); } @Override PackageSpecificPolicyKey readFromXml(TypedXmlPullParser parser) throws XmlPullParserException, IOException { String policyKey = parser.getAttributeValue(/* namespace= */ null, ATTR_POLICY_KEY); String packageName = parser.getAttributeValue(/* namespace= */ null, ATTR_PACKAGE_NAME); String permissionName = parser.getAttributeValue( /* namespace= */ null, ATTR_PERMISSION_NAME); return new PackageSpecificPolicyKey(policyKey, packageName); } @Override void writeToBundle(Bundle bundle) { super.writeToBundle(bundle); Bundle extraPolicyParams = new Bundle(); extraPolicyParams.putString(EXTRA_PACKAGE_NAME, mPackageName); bundle.putBundle(EXTRA_POLICY_BUNDLE_KEY, extraPolicyParams); } @Override public boolean equals(@Nullable Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; PackageSpecificPolicyKey other = (PackageSpecificPolicyKey) o; return Objects.equals(mKey, other.mKey) && Objects.equals(mPackageName, other.mPackageName); } @Override public int hashCode() { return Objects.hash(mKey, mPackageName); } @Override public String toString() { return "mPolicyKey= " + mKey + "; mPackageName= " + mPackageName; } } services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +37 −5 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ final class PolicyDefinition<V> { private static final MostRestrictive<Boolean> FALSE_MORE_RESTRICTIVE = new MostRestrictive<>( List.of(false, true)); private static final MostRestrictive<Boolean> TRUE_MORE_RESTRICTIVE = new MostRestrictive<>( List.of(true, false)); static PolicyDefinition<Boolean> AUTO_TIMEZONE = new PolicyDefinition<>( new DefaultPolicyKey(DevicePolicyManager.AUTO_TIMEZONE_POLICY), // auto timezone is enabled by default, hence disabling it is more restrictive. Loading Loading @@ -102,7 +105,7 @@ final class PolicyDefinition<V> { new LockTaskPolicy.LockTaskPolicySerializer()); static PolicyDefinition<Set<String>> USER_CONTROLLED_DISABLED_PACKAGES = new PolicyDefinition<>( new DefaultPolicyKey(DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES), new DefaultPolicyKey(DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES_POLICY), new SetUnion<>(), (Set<String> value, Context context, Integer userId, PolicyKey policyKey) -> PolicyEnforcerCallbacks.setUserControlDisabledPackages(value, userId), Loading @@ -114,7 +117,7 @@ final class PolicyDefinition<V> { static PolicyDefinition<ComponentName> GENERIC_PERSISTENT_PREFERRED_ACTIVITY = new PolicyDefinition<>( new PersistentPreferredActivityPolicyKey( DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY), DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY), new TopPriority<>(List.of( // TODO(b/258166155): add correct device lock role name EnforcingAdmin.getRoleAuthorityOf("DeviceLock"), Loading @@ -134,15 +137,44 @@ final class PolicyDefinition<V> { } return GENERIC_PERSISTENT_PREFERRED_ACTIVITY.createPolicyDefinition( new PersistentPreferredActivityPolicyKey( DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY, intentFilter)); DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY, intentFilter)); } // This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the // actual uninstall blocked policy with the correct arguments (i.e. packageName) // when reading the policies from xml. static PolicyDefinition<Boolean> GENERIC_PACKAGE_UNINSTALL_BLOCKED = new PolicyDefinition<>( new PackageSpecificPolicyKey( DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY), TRUE_MORE_RESTRICTIVE, POLICY_FLAG_LOCAL_ONLY_POLICY, PolicyEnforcerCallbacks::setUninstallBlocked, new BooleanPolicySerializer()); /** * Passing in {@code null} for {@code packageName} will return * {@link #GENERIC_PACKAGE_UNINSTALL_BLOCKED}. */ static PolicyDefinition<Boolean> PACKAGE_UNINSTALL_BLOCKED( String packageName) { if (packageName == null) { return GENERIC_PACKAGE_UNINSTALL_BLOCKED; } return GENERIC_PACKAGE_UNINSTALL_BLOCKED.createPolicyDefinition( new PackageSpecificPolicyKey( DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY, packageName)); } private static final Map<String, PolicyDefinition<?>> sPolicyDefinitions = Map.of( DevicePolicyManager.AUTO_TIMEZONE_POLICY, AUTO_TIMEZONE, DevicePolicyManager.PERMISSION_GRANT_POLICY_KEY, GENERIC_PERMISSION_GRANT, DevicePolicyManager.LOCK_TASK_POLICY, LOCK_TASK, DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES, USER_CONTROLLED_DISABLED_PACKAGES, DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY, GENERIC_PERSISTENT_PREFERRED_ACTIVITY DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES_POLICY, USER_CONTROLLED_DISABLED_PACKAGES, DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY, GENERIC_PERSISTENT_PREFERRED_ACTIVITY, DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY, GENERIC_PACKAGE_UNINSTALL_BLOCKED ); Loading services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java +18 −0 Original line number Diff line number Diff line Loading @@ -179,4 +179,22 @@ final class PolicyEnforcerCallbacks { }); return true; } static boolean setUninstallBlocked( @Nullable Boolean uninstallBlocked, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { if (!(policyKey instanceof PackageSpecificPolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " + "PackageSpecificPolicyKey"); } PackageSpecificPolicyKey parsedKey = (PackageSpecificPolicyKey) policyKey; String packageName = Objects.requireNonNull(parsedKey.getPackageName()); DevicePolicyManagerService.setUninstallBlockedUnchecked( packageName, uninstallBlocked != null && uninstallBlocked, userId); return true; })); } } Loading
core/java/android/app/admin/DevicePolicyManager.java +11 −2 Original line number Diff line number Diff line Loading @@ -3985,6 +3985,7 @@ public class DevicePolicyManager { */ public static final String AUTO_TIMEZONE_POLICY = "autoTimezone"; // TODO: Expose this as SystemAPI once we add the query API /** * @hide */ Loading @@ -4011,14 +4012,22 @@ public class DevicePolicyManager { /** * @hide */ public static final String USER_CONTROL_DISABLED_PACKAGES = "userControlDisabledPackages"; public static final String USER_CONTROL_DISABLED_PACKAGES_POLICY = "userControlDisabledPackages"; // TODO: Expose this as SystemAPI once we add the query API /** * @hide */ public static final String PERSISTENT_PREFERRED_ACTIVITY_POLICY = "persistentPreferredActivity"; // TODO: Expose this as SystemAPI once we add the query API /** * @hide */ public static final String PERSISTENT_PREFERRED_ACTIVITY = "persistentPreferredActivity"; public static final String PACKAGE_UNINSTALL_BLOCKED_POLICY = "packageUninstallBlocked"; /** * This object is a single place to tack on invalidation and disable calls. All Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +50 −14 Original line number Diff line number Diff line Loading @@ -12219,11 +12219,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { || isFinancedDeviceOwner(caller))) || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_BLOCK_UNINSTALL))); if (isCoexistenceEnabled(caller)) { // TODO(b/260573124): Add correct enforcing admin when permission changes are // merged, and don't forget to handle delegates! Enterprise admins assume // component name isn't null. EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin( who != null ? who : new ComponentName(callerPackage, "delegate"), caller.getUserId()); mDevicePolicyEngine.setLocalPolicy( PolicyDefinition.PACKAGE_UNINSTALL_BLOCKED(packageName), admin, uninstallBlocked, caller.getUserId()); } else { final int userId = caller.getUserId(); synchronized (getLockObject()) { long id = mInjector.binderClearCallingIdentity(); try { mIPackageManager.setBlockUninstallForUser(packageName, uninstallBlocked, userId); mIPackageManager.setBlockUninstallForUser( packageName, uninstallBlocked, userId); } catch (RemoteException re) { // Shouldn't happen. Slogf.e(LOG_TAG, "Failed to setBlockUninstallForUser", re); Loading @@ -12237,6 +12251,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pmi.removeDistractingPackageRestrictions(packageName, userId); pmi.flushPackageRestrictions(userId); } } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_UNINSTALL_BLOCKED) .setAdmin(caller.getPackageName()) Loading @@ -12245,6 +12261,26 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } static void setUninstallBlockedUnchecked( String packageName, boolean uninstallBlocked, int userId) { Binder.withCleanCallingIdentity(() -> { try { AppGlobals.getPackageManager().setBlockUninstallForUser( packageName, uninstallBlocked, userId); } catch (RemoteException re) { // Shouldn't happen. Slogf.e(LOG_TAG, "Failed to setBlockUninstallForUser", re); } }); if (uninstallBlocked) { final PackageManagerInternal pmi = LocalServices.getService( PackageManagerInternal.class); pmi.removeNonSystemPackageSuspensions(packageName, userId); pmi.removeDistractingPackageRestrictions(packageName, userId); pmi.flushPackageRestrictions(userId); } } @Override public boolean isUninstallBlocked(ComponentName who, String packageName) { // This function should return true if and only if the package is blocked by
services/devicepolicy/java/com/android/server/devicepolicy/PackageSpecificPolicyKey.java 0 → 100644 +101 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 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.devicepolicy; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_PACKAGE_NAME; import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_BUNDLE_KEY; import android.annotation.Nullable; import android.os.Bundle; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.Objects; /** * Class used to identify a policy that relates to a certain package in the policy engine's data * structure. */ final class PackageSpecificPolicyKey extends PolicyKey { private static final String ATTR_POLICY_KEY = "policy-key"; private static final String ATTR_PACKAGE_NAME = "package-name"; private static final String ATTR_PERMISSION_NAME = "permission-name"; private final String mPackageName; PackageSpecificPolicyKey(String key, String packageName) { super(key); mPackageName = Objects.requireNonNull((packageName)); } PackageSpecificPolicyKey(String key) { super(key); mPackageName = null; } @Nullable String getPackageName() { return mPackageName; } @Override void saveToXml(TypedXmlSerializer serializer) throws IOException { serializer.attribute(/* namespace= */ null, ATTR_POLICY_KEY, mKey); serializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName); } @Override PackageSpecificPolicyKey readFromXml(TypedXmlPullParser parser) throws XmlPullParserException, IOException { String policyKey = parser.getAttributeValue(/* namespace= */ null, ATTR_POLICY_KEY); String packageName = parser.getAttributeValue(/* namespace= */ null, ATTR_PACKAGE_NAME); String permissionName = parser.getAttributeValue( /* namespace= */ null, ATTR_PERMISSION_NAME); return new PackageSpecificPolicyKey(policyKey, packageName); } @Override void writeToBundle(Bundle bundle) { super.writeToBundle(bundle); Bundle extraPolicyParams = new Bundle(); extraPolicyParams.putString(EXTRA_PACKAGE_NAME, mPackageName); bundle.putBundle(EXTRA_POLICY_BUNDLE_KEY, extraPolicyParams); } @Override public boolean equals(@Nullable Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; PackageSpecificPolicyKey other = (PackageSpecificPolicyKey) o; return Objects.equals(mKey, other.mKey) && Objects.equals(mPackageName, other.mPackageName); } @Override public int hashCode() { return Objects.hash(mKey, mPackageName); } @Override public String toString() { return "mPolicyKey= " + mKey + "; mPackageName= " + mPackageName; } }
services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +37 −5 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ final class PolicyDefinition<V> { private static final MostRestrictive<Boolean> FALSE_MORE_RESTRICTIVE = new MostRestrictive<>( List.of(false, true)); private static final MostRestrictive<Boolean> TRUE_MORE_RESTRICTIVE = new MostRestrictive<>( List.of(true, false)); static PolicyDefinition<Boolean> AUTO_TIMEZONE = new PolicyDefinition<>( new DefaultPolicyKey(DevicePolicyManager.AUTO_TIMEZONE_POLICY), // auto timezone is enabled by default, hence disabling it is more restrictive. Loading Loading @@ -102,7 +105,7 @@ final class PolicyDefinition<V> { new LockTaskPolicy.LockTaskPolicySerializer()); static PolicyDefinition<Set<String>> USER_CONTROLLED_DISABLED_PACKAGES = new PolicyDefinition<>( new DefaultPolicyKey(DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES), new DefaultPolicyKey(DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES_POLICY), new SetUnion<>(), (Set<String> value, Context context, Integer userId, PolicyKey policyKey) -> PolicyEnforcerCallbacks.setUserControlDisabledPackages(value, userId), Loading @@ -114,7 +117,7 @@ final class PolicyDefinition<V> { static PolicyDefinition<ComponentName> GENERIC_PERSISTENT_PREFERRED_ACTIVITY = new PolicyDefinition<>( new PersistentPreferredActivityPolicyKey( DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY), DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY), new TopPriority<>(List.of( // TODO(b/258166155): add correct device lock role name EnforcingAdmin.getRoleAuthorityOf("DeviceLock"), Loading @@ -134,15 +137,44 @@ final class PolicyDefinition<V> { } return GENERIC_PERSISTENT_PREFERRED_ACTIVITY.createPolicyDefinition( new PersistentPreferredActivityPolicyKey( DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY, intentFilter)); DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY, intentFilter)); } // This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the // actual uninstall blocked policy with the correct arguments (i.e. packageName) // when reading the policies from xml. static PolicyDefinition<Boolean> GENERIC_PACKAGE_UNINSTALL_BLOCKED = new PolicyDefinition<>( new PackageSpecificPolicyKey( DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY), TRUE_MORE_RESTRICTIVE, POLICY_FLAG_LOCAL_ONLY_POLICY, PolicyEnforcerCallbacks::setUninstallBlocked, new BooleanPolicySerializer()); /** * Passing in {@code null} for {@code packageName} will return * {@link #GENERIC_PACKAGE_UNINSTALL_BLOCKED}. */ static PolicyDefinition<Boolean> PACKAGE_UNINSTALL_BLOCKED( String packageName) { if (packageName == null) { return GENERIC_PACKAGE_UNINSTALL_BLOCKED; } return GENERIC_PACKAGE_UNINSTALL_BLOCKED.createPolicyDefinition( new PackageSpecificPolicyKey( DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY, packageName)); } private static final Map<String, PolicyDefinition<?>> sPolicyDefinitions = Map.of( DevicePolicyManager.AUTO_TIMEZONE_POLICY, AUTO_TIMEZONE, DevicePolicyManager.PERMISSION_GRANT_POLICY_KEY, GENERIC_PERMISSION_GRANT, DevicePolicyManager.LOCK_TASK_POLICY, LOCK_TASK, DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES, USER_CONTROLLED_DISABLED_PACKAGES, DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY, GENERIC_PERSISTENT_PREFERRED_ACTIVITY DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES_POLICY, USER_CONTROLLED_DISABLED_PACKAGES, DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY, GENERIC_PERSISTENT_PREFERRED_ACTIVITY, DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY, GENERIC_PACKAGE_UNINSTALL_BLOCKED ); Loading
services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java +18 −0 Original line number Diff line number Diff line Loading @@ -179,4 +179,22 @@ final class PolicyEnforcerCallbacks { }); return true; } static boolean setUninstallBlocked( @Nullable Boolean uninstallBlocked, @NonNull Context context, int userId, @NonNull PolicyKey policyKey) { return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { if (!(policyKey instanceof PackageSpecificPolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " + "PackageSpecificPolicyKey"); } PackageSpecificPolicyKey parsedKey = (PackageSpecificPolicyKey) policyKey; String packageName = Objects.requireNonNull(parsedKey.getPackageName()); DevicePolicyManagerService.setUninstallBlockedUnchecked( packageName, uninstallBlocked != null && uninstallBlocked, userId); return true; })); } }