Loading core/api/system-current.txt +15 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,7 @@ package android { field public static final String MANAGE_USB = "android.permission.MANAGE_USB"; field public static final String MANAGE_USERS = "android.permission.MANAGE_USERS"; field public static final String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE"; field public static final String MANAGE_WEAK_ESCROW_TOKEN = "android.permission.MANAGE_WEAK_ESCROW_TOKEN"; field public static final String MANAGE_WIFI_AUTO_JOIN = "android.permission.MANAGE_WIFI_AUTO_JOIN"; field public static final String MANAGE_WIFI_COUNTRY_CODE = "android.permission.MANAGE_WIFI_COUNTRY_CODE"; field public static final String MARK_DEVICE_ORGANIZATION_OWNED = "android.permission.MARK_DEVICE_ORGANIZATION_OWNED"; Loading Loading @@ -757,18 +758,32 @@ package android.app { } public class KeyguardManager { method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public long addWeakEscrowToken(@NonNull byte[], @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.WeakEscrowTokenActivatedListener); method public android.content.Intent createConfirmFactoryResetCredentialIntent(CharSequence, CharSequence, CharSequence); method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public int getMinLockLength(boolean, int); method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public boolean getPrivateNotificationsAllowed(); method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public boolean isValidLockPasswordComplexity(int, @NonNull byte[], int); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean isWeakEscrowTokenActive(long, @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean isWeakEscrowTokenValid(long, @NonNull byte[], @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean registerWeakEscrowTokenRemovedListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.WeakEscrowTokenRemovedListener); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean removeWeakEscrowToken(long, @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.SHOW_KEYGUARD_MESSAGE) public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable CharSequence, @Nullable android.app.KeyguardManager.KeyguardDismissCallback); method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public boolean setLock(int, @NonNull byte[], int); method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public void setPrivateNotificationsAllowed(boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean unregisterWeakEscrowTokenRemovedListener(@NonNull android.app.KeyguardManager.WeakEscrowTokenRemovedListener); field public static final int PASSWORD = 0; // 0x0 field public static final int PATTERN = 2; // 0x2 field public static final int PIN = 1; // 0x1 } public static interface KeyguardManager.WeakEscrowTokenActivatedListener { method public void onWeakEscrowTokenActivated(long, @NonNull android.os.UserHandle); } public static interface KeyguardManager.WeakEscrowTokenRemovedListener { method public void onWeakEscrowTokenRemoved(long, @NonNull android.os.UserHandle); } public class LocaleManager { method @NonNull @RequiresPermission(android.Manifest.permission.READ_APP_SPECIFIC_LOCALES) public android.os.LocaleList getApplicationLocales(@NonNull String); method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void setApplicationLocales(@NonNull String, @NonNull android.os.LocaleList); core/java/android/app/KeyguardManager.java +192 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app; import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -40,8 +41,10 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.UserHandle; import android.provider.Settings; import android.service.persistentdata.IPersistentDataBlockService; import android.util.ArrayMap; import android.util.Log; import android.view.IOnKeyguardExitResult; import android.view.IWindowManager; Loading @@ -49,6 +52,9 @@ import android.view.WindowManager.LayoutParams; import android.view.WindowManagerGlobal; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.util.Preconditions; import com.android.internal.widget.IWeakEscrowTokenActivatedListener; import com.android.internal.widget.IWeakEscrowTokenRemovedListener; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockscreenCredential; Loading @@ -57,6 +63,8 @@ import com.android.internal.widget.VerifyCredentialResponse; import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; /** * Class that can be used to lock and unlock the keyguard. The Loading @@ -69,10 +77,13 @@ public class KeyguardManager { private static final String TAG = "KeyguardManager"; private final Context mContext; private final LockPatternUtils mLockPatternUtils; private final IWindowManager mWM; private final IActivityManager mAm; private final ITrustManager mTrustManager; private final INotificationManager mNotificationManager; private final ArrayMap<WeakEscrowTokenRemovedListener, IWeakEscrowTokenRemovedListener> mListeners = new ArrayMap<>(); /** * Intent used to prompt user for device credentials. Loading Loading @@ -455,8 +466,42 @@ public class KeyguardManager { public void onDismissCancelled() { } } /** * Callback passed to * {@link KeyguardManager#addWeakEscrowToken} * to notify caller of state change. * @hide */ @SystemApi public interface WeakEscrowTokenActivatedListener { /** * The method to be called when the token is activated. * @param handle 64 bit handle corresponding to the escrow token * @param user user for whom the weak escrow token has been added */ void onWeakEscrowTokenActivated(long handle, @NonNull UserHandle user); } /** * Listener passed to * {@link KeyguardManager#registerWeakEscrowTokenRemovedListener} and * {@link KeyguardManager#unregisterWeakEscrowTokenRemovedListener} * to notify caller of an weak escrow token has been removed. * @hide */ @SystemApi public interface WeakEscrowTokenRemovedListener { /** * The method to be called when the token is removed. * @param handle 64 bit handle corresponding to the escrow token * @param user user for whom the escrow token has been added */ void onWeakEscrowTokenRemoved(long handle, @NonNull UserHandle user); } KeyguardManager(Context context) throws ServiceNotFoundException { mContext = context; mLockPatternUtils = new LockPatternUtils(context); mWM = WindowManagerGlobal.getWindowManagerService(); mAm = ActivityManager.getService(); mTrustManager = ITrustManager.Stub.asInterface( Loading Loading @@ -785,7 +830,6 @@ public class KeyguardManager { return false; } LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); int userId = mContext.getUserId(); if (isDeviceSecure(userId)) { Log.e(TAG, "Password already set, rejecting call to setLock"); Loading @@ -799,7 +843,7 @@ public class KeyguardManager { try { LockscreenCredential credential = createLockscreenCredential( lockType, password); success = lockPatternUtils.setLockCredential( success = mLockPatternUtils.setLockCredential( credential, /* savedPassword= */ LockscreenCredential.createNone(), userId); Loading @@ -812,6 +856,150 @@ public class KeyguardManager { return success; } /** * Create a weak escrow token for the current user, which can later be used to unlock FBE * or change user password. * * After adding, if the user currently has a secure lockscreen, they will need to perform a * confirm credential operation in order to activate the token for future use. If the user * has no secure lockscreen, then the token is activated immediately. * * If the user changes or removes the lockscreen password, any activated weak escrow token will * be removed. * * @return a unique 64-bit token handle which is needed to refer to this token later. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public long addWeakEscrowToken(@NonNull byte[] token, @NonNull UserHandle user, @NonNull @CallbackExecutor Executor executor, @NonNull WeakEscrowTokenActivatedListener listener) { Objects.requireNonNull(token, "Token cannot be null."); Objects.requireNonNull(user, "User cannot be null."); Objects.requireNonNull(executor, "Executor cannot be null."); Objects.requireNonNull(listener, "Listener cannot be null."); int userId = user.getIdentifier(); IWeakEscrowTokenActivatedListener internalListener = new IWeakEscrowTokenActivatedListener.Stub() { @Override public void onWeakEscrowTokenActivated(long handle, int userId) { UserHandle user = UserHandle.of(userId); final long restoreToken = Binder.clearCallingIdentity(); try { executor.execute(() -> listener.onWeakEscrowTokenActivated(handle, user)); } finally { Binder.restoreCallingIdentity(restoreToken); } Log.i(TAG, "Weak escrow token activated."); } }; return mLockPatternUtils.addWeakEscrowToken(token, userId, internalListener); } /** * Remove a weak escrow token. * * @return true if the given handle refers to a valid weak token previously returned from * {@link #addWeakEscrowToken}, whether it's active or not. return false otherwise. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean removeWeakEscrowToken(long handle, @NonNull UserHandle user) { Objects.requireNonNull(user, "User cannot be null."); return mLockPatternUtils.removeWeakEscrowToken(handle, user.getIdentifier()); } /** * Check if the given weak escrow token is active or not. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean isWeakEscrowTokenActive(long handle, @NonNull UserHandle user) { Objects.requireNonNull(user, "User cannot be null."); return mLockPatternUtils.isWeakEscrowTokenActive(handle, user.getIdentifier()); } /** * Check if the given weak escrow token is validate. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean isWeakEscrowTokenValid(long handle, @NonNull byte[] token, @NonNull UserHandle user) { Objects.requireNonNull(token, "Token cannot be null."); Objects.requireNonNull(user, "User cannot be null."); return mLockPatternUtils.isWeakEscrowTokenValid(handle, token, user.getIdentifier()); } /** * Register the given WeakEscrowTokenRemovedListener. * * @return true if the listener is registered successfully, return false otherwise. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean registerWeakEscrowTokenRemovedListener( @NonNull @CallbackExecutor Executor executor, @NonNull WeakEscrowTokenRemovedListener listener) { Objects.requireNonNull(listener, "Listener cannot be null."); Objects.requireNonNull(executor, "Executor cannot be null."); Preconditions.checkArgument(!mListeners.containsKey(listener), "Listener already registered: %s", listener); IWeakEscrowTokenRemovedListener internalListener = new IWeakEscrowTokenRemovedListener.Stub() { @Override public void onWeakEscrowTokenRemoved(long handle, int userId) { UserHandle user = UserHandle.of(userId); final long token = Binder.clearCallingIdentity(); try { executor.execute(() -> listener.onWeakEscrowTokenRemoved(handle, user)); } finally { Binder.restoreCallingIdentity(token); } } }; if (mLockPatternUtils.registerWeakEscrowTokenRemovedListener(internalListener)) { mListeners.put(listener, internalListener); return true; } else { Log.e(TAG, "Listener failed to register"); return false; } } /** * Unregister the given WeakEscrowTokenRemovedListener. * * @return true if the listener is unregistered successfully, return false otherwise. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean unregisterWeakEscrowTokenRemovedListener( @NonNull WeakEscrowTokenRemovedListener listener) { Objects.requireNonNull(listener, "Listener cannot be null."); IWeakEscrowTokenRemovedListener internalListener = mListeners.get(listener); Preconditions.checkArgument(internalListener != null, "Listener was not registered"); if (mLockPatternUtils.unregisterWeakEscrowTokenRemovedListener(internalListener)) { mListeners.remove(listener); return true; } else { Log.e(TAG, "Listener failed to unregister."); return false; } } /** * Set the lockscreen password to {@code newPassword} after validating the current password * against {@code currentPassword}. Loading @@ -832,13 +1020,12 @@ public class KeyguardManager { }) public boolean setLock(@LockTypes int newLockType, @Nullable byte[] newPassword, @LockTypes int currentLockType, @Nullable byte[] currentPassword) { final LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); final int userId = mContext.getUserId(); LockscreenCredential currentCredential = createLockscreenCredential( currentLockType, currentPassword); LockscreenCredential newCredential = createLockscreenCredential( newLockType, newPassword); return lockPatternUtils.setLockCredential(newCredential, currentCredential, userId); return mLockPatternUtils.setLockCredential(newCredential, currentCredential, userId); } /** Loading @@ -857,10 +1044,9 @@ public class KeyguardManager { Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE }) public boolean checkLock(@LockTypes int lockType, @Nullable byte[] password) { final LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); final LockscreenCredential credential = createLockscreenCredential( lockType, password); final VerifyCredentialResponse response = lockPatternUtils.verifyCredential( final VerifyCredentialResponse response = mLockPatternUtils.verifyCredential( credential, mContext.getUserId(), /* flags= */ 0); if (response == null) { return false; Loading core/java/com/android/internal/widget/ILockSettings.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.security.keystore.recovery.KeyChainSnapshot; import android.security.keystore.recovery.KeyChainProtectionParams; import android.security.keystore.recovery.RecoveryCertPath; import com.android.internal.widget.ICheckCredentialProgressCallback; import com.android.internal.widget.IWeakEscrowTokenActivatedListener; import com.android.internal.widget.IWeakEscrowTokenRemovedListener; import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.VerifyCredentialResponse; Loading Loading @@ -96,4 +98,10 @@ interface ILockSettings { boolean tryUnlockWithCachedUnifiedChallenge(int userId); void removeCachedUnifiedChallenge(int userId); void updateEncryptionPassword(int type, in byte[] password); boolean registerWeakEscrowTokenRemovedListener(in IWeakEscrowTokenRemovedListener listener); boolean unregisterWeakEscrowTokenRemovedListener(in IWeakEscrowTokenRemovedListener listener); long addWeakEscrowToken(in byte[] token, int userId, in IWeakEscrowTokenActivatedListener callback); boolean removeWeakEscrowToken(long handle, int userId); boolean isWeakEscrowTokenActive(long handle, int userId); boolean isWeakEscrowTokenValid(long handle, in byte[] token, int userId); } core/java/com/android/internal/widget/IWeakEscrowTokenActivatedListener.aidl 0 → 100644 +22 −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.internal.widget; /** @hide */ oneway interface IWeakEscrowTokenActivatedListener { void onWeakEscrowTokenActivated(long handle, int userId); } core/java/com/android/internal/widget/IWeakEscrowTokenRemovedListener.aidl 0 → 100644 +22 −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.internal.widget; /** @hide */ oneway interface IWeakEscrowTokenRemovedListener { void onWeakEscrowTokenRemoved(long handle, int userId); } Loading
core/api/system-current.txt +15 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,7 @@ package android { field public static final String MANAGE_USB = "android.permission.MANAGE_USB"; field public static final String MANAGE_USERS = "android.permission.MANAGE_USERS"; field public static final String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE"; field public static final String MANAGE_WEAK_ESCROW_TOKEN = "android.permission.MANAGE_WEAK_ESCROW_TOKEN"; field public static final String MANAGE_WIFI_AUTO_JOIN = "android.permission.MANAGE_WIFI_AUTO_JOIN"; field public static final String MANAGE_WIFI_COUNTRY_CODE = "android.permission.MANAGE_WIFI_COUNTRY_CODE"; field public static final String MARK_DEVICE_ORGANIZATION_OWNED = "android.permission.MARK_DEVICE_ORGANIZATION_OWNED"; Loading Loading @@ -757,18 +758,32 @@ package android.app { } public class KeyguardManager { method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public long addWeakEscrowToken(@NonNull byte[], @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.WeakEscrowTokenActivatedListener); method public android.content.Intent createConfirmFactoryResetCredentialIntent(CharSequence, CharSequence, CharSequence); method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public int getMinLockLength(boolean, int); method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public boolean getPrivateNotificationsAllowed(); method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public boolean isValidLockPasswordComplexity(int, @NonNull byte[], int); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean isWeakEscrowTokenActive(long, @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean isWeakEscrowTokenValid(long, @NonNull byte[], @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean registerWeakEscrowTokenRemovedListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.WeakEscrowTokenRemovedListener); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean removeWeakEscrowToken(long, @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.SHOW_KEYGUARD_MESSAGE) public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable CharSequence, @Nullable android.app.KeyguardManager.KeyguardDismissCallback); method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public boolean setLock(int, @NonNull byte[], int); method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public void setPrivateNotificationsAllowed(boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean unregisterWeakEscrowTokenRemovedListener(@NonNull android.app.KeyguardManager.WeakEscrowTokenRemovedListener); field public static final int PASSWORD = 0; // 0x0 field public static final int PATTERN = 2; // 0x2 field public static final int PIN = 1; // 0x1 } public static interface KeyguardManager.WeakEscrowTokenActivatedListener { method public void onWeakEscrowTokenActivated(long, @NonNull android.os.UserHandle); } public static interface KeyguardManager.WeakEscrowTokenRemovedListener { method public void onWeakEscrowTokenRemoved(long, @NonNull android.os.UserHandle); } public class LocaleManager { method @NonNull @RequiresPermission(android.Manifest.permission.READ_APP_SPECIFIC_LOCALES) public android.os.LocaleList getApplicationLocales(@NonNull String); method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void setApplicationLocales(@NonNull String, @NonNull android.os.LocaleList);
core/java/android/app/KeyguardManager.java +192 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app; import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -40,8 +41,10 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.UserHandle; import android.provider.Settings; import android.service.persistentdata.IPersistentDataBlockService; import android.util.ArrayMap; import android.util.Log; import android.view.IOnKeyguardExitResult; import android.view.IWindowManager; Loading @@ -49,6 +52,9 @@ import android.view.WindowManager.LayoutParams; import android.view.WindowManagerGlobal; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.util.Preconditions; import com.android.internal.widget.IWeakEscrowTokenActivatedListener; import com.android.internal.widget.IWeakEscrowTokenRemovedListener; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockscreenCredential; Loading @@ -57,6 +63,8 @@ import com.android.internal.widget.VerifyCredentialResponse; import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; /** * Class that can be used to lock and unlock the keyguard. The Loading @@ -69,10 +77,13 @@ public class KeyguardManager { private static final String TAG = "KeyguardManager"; private final Context mContext; private final LockPatternUtils mLockPatternUtils; private final IWindowManager mWM; private final IActivityManager mAm; private final ITrustManager mTrustManager; private final INotificationManager mNotificationManager; private final ArrayMap<WeakEscrowTokenRemovedListener, IWeakEscrowTokenRemovedListener> mListeners = new ArrayMap<>(); /** * Intent used to prompt user for device credentials. Loading Loading @@ -455,8 +466,42 @@ public class KeyguardManager { public void onDismissCancelled() { } } /** * Callback passed to * {@link KeyguardManager#addWeakEscrowToken} * to notify caller of state change. * @hide */ @SystemApi public interface WeakEscrowTokenActivatedListener { /** * The method to be called when the token is activated. * @param handle 64 bit handle corresponding to the escrow token * @param user user for whom the weak escrow token has been added */ void onWeakEscrowTokenActivated(long handle, @NonNull UserHandle user); } /** * Listener passed to * {@link KeyguardManager#registerWeakEscrowTokenRemovedListener} and * {@link KeyguardManager#unregisterWeakEscrowTokenRemovedListener} * to notify caller of an weak escrow token has been removed. * @hide */ @SystemApi public interface WeakEscrowTokenRemovedListener { /** * The method to be called when the token is removed. * @param handle 64 bit handle corresponding to the escrow token * @param user user for whom the escrow token has been added */ void onWeakEscrowTokenRemoved(long handle, @NonNull UserHandle user); } KeyguardManager(Context context) throws ServiceNotFoundException { mContext = context; mLockPatternUtils = new LockPatternUtils(context); mWM = WindowManagerGlobal.getWindowManagerService(); mAm = ActivityManager.getService(); mTrustManager = ITrustManager.Stub.asInterface( Loading Loading @@ -785,7 +830,6 @@ public class KeyguardManager { return false; } LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); int userId = mContext.getUserId(); if (isDeviceSecure(userId)) { Log.e(TAG, "Password already set, rejecting call to setLock"); Loading @@ -799,7 +843,7 @@ public class KeyguardManager { try { LockscreenCredential credential = createLockscreenCredential( lockType, password); success = lockPatternUtils.setLockCredential( success = mLockPatternUtils.setLockCredential( credential, /* savedPassword= */ LockscreenCredential.createNone(), userId); Loading @@ -812,6 +856,150 @@ public class KeyguardManager { return success; } /** * Create a weak escrow token for the current user, which can later be used to unlock FBE * or change user password. * * After adding, if the user currently has a secure lockscreen, they will need to perform a * confirm credential operation in order to activate the token for future use. If the user * has no secure lockscreen, then the token is activated immediately. * * If the user changes or removes the lockscreen password, any activated weak escrow token will * be removed. * * @return a unique 64-bit token handle which is needed to refer to this token later. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public long addWeakEscrowToken(@NonNull byte[] token, @NonNull UserHandle user, @NonNull @CallbackExecutor Executor executor, @NonNull WeakEscrowTokenActivatedListener listener) { Objects.requireNonNull(token, "Token cannot be null."); Objects.requireNonNull(user, "User cannot be null."); Objects.requireNonNull(executor, "Executor cannot be null."); Objects.requireNonNull(listener, "Listener cannot be null."); int userId = user.getIdentifier(); IWeakEscrowTokenActivatedListener internalListener = new IWeakEscrowTokenActivatedListener.Stub() { @Override public void onWeakEscrowTokenActivated(long handle, int userId) { UserHandle user = UserHandle.of(userId); final long restoreToken = Binder.clearCallingIdentity(); try { executor.execute(() -> listener.onWeakEscrowTokenActivated(handle, user)); } finally { Binder.restoreCallingIdentity(restoreToken); } Log.i(TAG, "Weak escrow token activated."); } }; return mLockPatternUtils.addWeakEscrowToken(token, userId, internalListener); } /** * Remove a weak escrow token. * * @return true if the given handle refers to a valid weak token previously returned from * {@link #addWeakEscrowToken}, whether it's active or not. return false otherwise. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean removeWeakEscrowToken(long handle, @NonNull UserHandle user) { Objects.requireNonNull(user, "User cannot be null."); return mLockPatternUtils.removeWeakEscrowToken(handle, user.getIdentifier()); } /** * Check if the given weak escrow token is active or not. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean isWeakEscrowTokenActive(long handle, @NonNull UserHandle user) { Objects.requireNonNull(user, "User cannot be null."); return mLockPatternUtils.isWeakEscrowTokenActive(handle, user.getIdentifier()); } /** * Check if the given weak escrow token is validate. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean isWeakEscrowTokenValid(long handle, @NonNull byte[] token, @NonNull UserHandle user) { Objects.requireNonNull(token, "Token cannot be null."); Objects.requireNonNull(user, "User cannot be null."); return mLockPatternUtils.isWeakEscrowTokenValid(handle, token, user.getIdentifier()); } /** * Register the given WeakEscrowTokenRemovedListener. * * @return true if the listener is registered successfully, return false otherwise. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean registerWeakEscrowTokenRemovedListener( @NonNull @CallbackExecutor Executor executor, @NonNull WeakEscrowTokenRemovedListener listener) { Objects.requireNonNull(listener, "Listener cannot be null."); Objects.requireNonNull(executor, "Executor cannot be null."); Preconditions.checkArgument(!mListeners.containsKey(listener), "Listener already registered: %s", listener); IWeakEscrowTokenRemovedListener internalListener = new IWeakEscrowTokenRemovedListener.Stub() { @Override public void onWeakEscrowTokenRemoved(long handle, int userId) { UserHandle user = UserHandle.of(userId); final long token = Binder.clearCallingIdentity(); try { executor.execute(() -> listener.onWeakEscrowTokenRemoved(handle, user)); } finally { Binder.restoreCallingIdentity(token); } } }; if (mLockPatternUtils.registerWeakEscrowTokenRemovedListener(internalListener)) { mListeners.put(listener, internalListener); return true; } else { Log.e(TAG, "Listener failed to register"); return false; } } /** * Unregister the given WeakEscrowTokenRemovedListener. * * @return true if the listener is unregistered successfully, return false otherwise. * @hide */ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) @RequiresPermission(Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) @SystemApi public boolean unregisterWeakEscrowTokenRemovedListener( @NonNull WeakEscrowTokenRemovedListener listener) { Objects.requireNonNull(listener, "Listener cannot be null."); IWeakEscrowTokenRemovedListener internalListener = mListeners.get(listener); Preconditions.checkArgument(internalListener != null, "Listener was not registered"); if (mLockPatternUtils.unregisterWeakEscrowTokenRemovedListener(internalListener)) { mListeners.remove(listener); return true; } else { Log.e(TAG, "Listener failed to unregister."); return false; } } /** * Set the lockscreen password to {@code newPassword} after validating the current password * against {@code currentPassword}. Loading @@ -832,13 +1020,12 @@ public class KeyguardManager { }) public boolean setLock(@LockTypes int newLockType, @Nullable byte[] newPassword, @LockTypes int currentLockType, @Nullable byte[] currentPassword) { final LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); final int userId = mContext.getUserId(); LockscreenCredential currentCredential = createLockscreenCredential( currentLockType, currentPassword); LockscreenCredential newCredential = createLockscreenCredential( newLockType, newPassword); return lockPatternUtils.setLockCredential(newCredential, currentCredential, userId); return mLockPatternUtils.setLockCredential(newCredential, currentCredential, userId); } /** Loading @@ -857,10 +1044,9 @@ public class KeyguardManager { Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE }) public boolean checkLock(@LockTypes int lockType, @Nullable byte[] password) { final LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); final LockscreenCredential credential = createLockscreenCredential( lockType, password); final VerifyCredentialResponse response = lockPatternUtils.verifyCredential( final VerifyCredentialResponse response = mLockPatternUtils.verifyCredential( credential, mContext.getUserId(), /* flags= */ 0); if (response == null) { return false; Loading
core/java/com/android/internal/widget/ILockSettings.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.security.keystore.recovery.KeyChainSnapshot; import android.security.keystore.recovery.KeyChainProtectionParams; import android.security.keystore.recovery.RecoveryCertPath; import com.android.internal.widget.ICheckCredentialProgressCallback; import com.android.internal.widget.IWeakEscrowTokenActivatedListener; import com.android.internal.widget.IWeakEscrowTokenRemovedListener; import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.VerifyCredentialResponse; Loading Loading @@ -96,4 +98,10 @@ interface ILockSettings { boolean tryUnlockWithCachedUnifiedChallenge(int userId); void removeCachedUnifiedChallenge(int userId); void updateEncryptionPassword(int type, in byte[] password); boolean registerWeakEscrowTokenRemovedListener(in IWeakEscrowTokenRemovedListener listener); boolean unregisterWeakEscrowTokenRemovedListener(in IWeakEscrowTokenRemovedListener listener); long addWeakEscrowToken(in byte[] token, int userId, in IWeakEscrowTokenActivatedListener callback); boolean removeWeakEscrowToken(long handle, int userId); boolean isWeakEscrowTokenActive(long handle, int userId); boolean isWeakEscrowTokenValid(long handle, in byte[] token, int userId); }
core/java/com/android/internal/widget/IWeakEscrowTokenActivatedListener.aidl 0 → 100644 +22 −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.internal.widget; /** @hide */ oneway interface IWeakEscrowTokenActivatedListener { void onWeakEscrowTokenActivated(long handle, int userId); }
core/java/com/android/internal/widget/IWeakEscrowTokenRemovedListener.aidl 0 → 100644 +22 −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.internal.widget; /** @hide */ oneway interface IWeakEscrowTokenRemovedListener { void onWeakEscrowTokenRemoved(long handle, int userId); }