Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6794,6 +6794,7 @@ package android.app.admin { method @WorkerThread public int setGlobalPrivateDnsModeSpecifiedHost(@NonNull android.content.ComponentName, @NonNull String); method public void setGlobalSetting(@NonNull android.content.ComponentName, String, String); method public void setKeepUninstalledPackages(@Nullable android.content.ComponentName, @NonNull java.util.List<java.lang.String>); method public boolean setKeyGrantForApp(@Nullable android.content.ComponentName, @NonNull String, @NonNull String, boolean); method public boolean setKeyPairCertificate(@Nullable android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.security.cert.Certificate>, boolean); method public boolean setKeyguardDisabled(@NonNull android.content.ComponentName, boolean); method public void setKeyguardDisabledFeatures(@NonNull android.content.ComponentName, int); core/java/android/app/admin/DevicePolicyManager.java +36 −0 Original line number Diff line number Diff line Loading @@ -4981,6 +4981,42 @@ public class DevicePolicyManager { return null; } /** * Called by a device or profile owner, or delegated certificate chooser (an app that has been * delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to grant an application access * to an already-installed (or generated) KeyChain key. * This is useful (in combination with {@link #installKeyPair} or {@link #generateKeyPair}) to * let an application call {@link android.security.KeyChain#getPrivateKey} without having to * call {@link android.security.KeyChain#choosePrivateKeyAlias} first. * * The grantee app will receive the {@link android.security.KeyChain#ACTION_KEY_ACCESS_CHANGED} * broadcast when access to a key is granted or revoked. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if calling from a delegated certificate installer. * @param alias The alias of the key to grant access to. * @param packageName The name of the (already installed) package to grant access to. * @param hasGrant Whether to grant access to the alias or revoke it. * @return {@code true} if the grant was set successfully, {@code false} otherwise. * * @throws SecurityException if the caller is not a device owner, a profile owner or * delegated certificate chooser. * @throws IllegalArgumentException if {@code packageName} or {@code alias} are empty, or if * {@code packageName} is not a name of an installed package. */ public boolean setKeyGrantForApp(@Nullable ComponentName admin, @NonNull String alias, @NonNull String packageName, boolean hasGrant) { throwIfParentInstance("addKeyGrant"); try { return mService.setKeyGrantForApp( admin, mContext.getPackageName(), alias, packageName, hasGrant); } catch (RemoteException e) { e.rethrowFromSystemServer(); } return false; } /** * Returns {@code true} if the device supports attestation of device identifiers in addition * to key attestation. Loading core/java/android/app/admin/IDevicePolicyManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -436,4 +436,6 @@ interface IDevicePolicyManager { boolean isUnattendedManagedKiosk(); boolean startViewCalendarEventInManagedProfile(String packageName, long eventId, long start, long end, boolean allDay, int flags); boolean setKeyGrantForApp(in ComponentName admin, String callerPackage, String alias, String packageName, boolean hasGrant); } services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.devicepolicy; import android.app.admin.IDevicePolicyManager; import android.content.ComponentName; import com.android.server.SystemService; Loading Loading @@ -56,4 +57,9 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { public void clearSystemUpdatePolicyFreezePeriodRecord() { } public boolean setKeyGrantForApp(ComponentName admin, String callerPackage, String alias, String packageName, boolean hasGrant) { return false; } } services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +53 −0 Original line number Diff line number Diff line Loading @@ -5727,6 +5727,59 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } @Override public boolean setKeyGrantForApp( ComponentName who, String callerPackage, String alias, String packageName, boolean hasGrant) { enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, DELEGATION_CERT_SELECTION); if (TextUtils.isEmpty(alias)) { throw new IllegalArgumentException("Alias to grant cannot be empty."); } if (TextUtils.isEmpty(packageName)) { throw new IllegalArgumentException("Package to grant to cannot be empty."); } final int userId = mInjector.userHandleGetCallingUserId(); final int granteeUid; try { ApplicationInfo ai = mInjector.getIPackageManager().getApplicationInfo( packageName, 0, userId); if (ai == null) { throw new IllegalArgumentException( String.format("Provided package %s is not installed", packageName)); } granteeUid = ai.uid; } catch (RemoteException e) { throw new IllegalStateException("Failure getting grantee uid", e); } final int callingUid = mInjector.binderGetCallingUid(); final long id = mInjector.binderClearCallingIdentity(); try { final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, UserHandle.getUserHandleForUid(callingUid)); try { IKeyChainService keyChain = keyChainConnection.getService(); keyChain.setGrant(granteeUid, alias, hasGrant); return true; } catch (RemoteException e) { Log.e(LOG_TAG, "Setting grant for package.", e); return false; } finally { keyChainConnection.close(); } } catch (InterruptedException e) { Log.w(LOG_TAG, "Interrupted while setting key grant", e); Thread.currentThread().interrupt(); } finally { mInjector.binderRestoreCallingIdentity(id); } return false; } /** * Enforce one the following conditions are met: * (1) The device has a Device Owner, and one of the following holds: Loading Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6794,6 +6794,7 @@ package android.app.admin { method @WorkerThread public int setGlobalPrivateDnsModeSpecifiedHost(@NonNull android.content.ComponentName, @NonNull String); method public void setGlobalSetting(@NonNull android.content.ComponentName, String, String); method public void setKeepUninstalledPackages(@Nullable android.content.ComponentName, @NonNull java.util.List<java.lang.String>); method public boolean setKeyGrantForApp(@Nullable android.content.ComponentName, @NonNull String, @NonNull String, boolean); method public boolean setKeyPairCertificate(@Nullable android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.security.cert.Certificate>, boolean); method public boolean setKeyguardDisabled(@NonNull android.content.ComponentName, boolean); method public void setKeyguardDisabledFeatures(@NonNull android.content.ComponentName, int);
core/java/android/app/admin/DevicePolicyManager.java +36 −0 Original line number Diff line number Diff line Loading @@ -4981,6 +4981,42 @@ public class DevicePolicyManager { return null; } /** * Called by a device or profile owner, or delegated certificate chooser (an app that has been * delegated the {@link #DELEGATION_CERT_SELECTION} privilege), to grant an application access * to an already-installed (or generated) KeyChain key. * This is useful (in combination with {@link #installKeyPair} or {@link #generateKeyPair}) to * let an application call {@link android.security.KeyChain#getPrivateKey} without having to * call {@link android.security.KeyChain#choosePrivateKeyAlias} first. * * The grantee app will receive the {@link android.security.KeyChain#ACTION_KEY_ACCESS_CHANGED} * broadcast when access to a key is granted or revoked. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if calling from a delegated certificate installer. * @param alias The alias of the key to grant access to. * @param packageName The name of the (already installed) package to grant access to. * @param hasGrant Whether to grant access to the alias or revoke it. * @return {@code true} if the grant was set successfully, {@code false} otherwise. * * @throws SecurityException if the caller is not a device owner, a profile owner or * delegated certificate chooser. * @throws IllegalArgumentException if {@code packageName} or {@code alias} are empty, or if * {@code packageName} is not a name of an installed package. */ public boolean setKeyGrantForApp(@Nullable ComponentName admin, @NonNull String alias, @NonNull String packageName, boolean hasGrant) { throwIfParentInstance("addKeyGrant"); try { return mService.setKeyGrantForApp( admin, mContext.getPackageName(), alias, packageName, hasGrant); } catch (RemoteException e) { e.rethrowFromSystemServer(); } return false; } /** * Returns {@code true} if the device supports attestation of device identifiers in addition * to key attestation. Loading
core/java/android/app/admin/IDevicePolicyManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -436,4 +436,6 @@ interface IDevicePolicyManager { boolean isUnattendedManagedKiosk(); boolean startViewCalendarEventInManagedProfile(String packageName, long eventId, long start, long end, boolean allDay, int flags); boolean setKeyGrantForApp(in ComponentName admin, String callerPackage, String alias, String packageName, boolean hasGrant); }
services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.devicepolicy; import android.app.admin.IDevicePolicyManager; import android.content.ComponentName; import com.android.server.SystemService; Loading Loading @@ -56,4 +57,9 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { public void clearSystemUpdatePolicyFreezePeriodRecord() { } public boolean setKeyGrantForApp(ComponentName admin, String callerPackage, String alias, String packageName, boolean hasGrant) { return false; } }
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +53 −0 Original line number Diff line number Diff line Loading @@ -5727,6 +5727,59 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } @Override public boolean setKeyGrantForApp( ComponentName who, String callerPackage, String alias, String packageName, boolean hasGrant) { enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, DELEGATION_CERT_SELECTION); if (TextUtils.isEmpty(alias)) { throw new IllegalArgumentException("Alias to grant cannot be empty."); } if (TextUtils.isEmpty(packageName)) { throw new IllegalArgumentException("Package to grant to cannot be empty."); } final int userId = mInjector.userHandleGetCallingUserId(); final int granteeUid; try { ApplicationInfo ai = mInjector.getIPackageManager().getApplicationInfo( packageName, 0, userId); if (ai == null) { throw new IllegalArgumentException( String.format("Provided package %s is not installed", packageName)); } granteeUid = ai.uid; } catch (RemoteException e) { throw new IllegalStateException("Failure getting grantee uid", e); } final int callingUid = mInjector.binderGetCallingUid(); final long id = mInjector.binderClearCallingIdentity(); try { final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, UserHandle.getUserHandleForUid(callingUid)); try { IKeyChainService keyChain = keyChainConnection.getService(); keyChain.setGrant(granteeUid, alias, hasGrant); return true; } catch (RemoteException e) { Log.e(LOG_TAG, "Setting grant for package.", e); return false; } finally { keyChainConnection.close(); } } catch (InterruptedException e) { Log.w(LOG_TAG, "Interrupted while setting key grant", e); Thread.currentThread().interrupt(); } finally { mInjector.binderRestoreCallingIdentity(id); } return false; } /** * Enforce one the following conditions are met: * (1) The device has a Device Owner, and one of the following holds: Loading