Loading core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -6235,6 +6235,7 @@ package android.app { } public class KeyguardManager { method @FlaggedApi("android.app.device_unlock_listener") @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void addDeviceLockedStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.DeviceLockedStateListener); method @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void addKeyguardLockedStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.KeyguardLockedStateListener); method @Deprecated public android.content.Intent createConfirmDeviceCredentialIntent(CharSequence, CharSequence); method @Deprecated @RequiresPermission(android.Manifest.permission.DISABLE_KEYGUARD) public void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult); Loading @@ -6244,10 +6245,15 @@ package android.app { method public boolean isKeyguardLocked(); method public boolean isKeyguardSecure(); method @Deprecated public android.app.KeyguardManager.KeyguardLock newKeyguardLock(String); method @FlaggedApi("android.app.device_unlock_listener") @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void removeDeviceLockedStateListener(@NonNull android.app.KeyguardManager.DeviceLockedStateListener); method @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void removeKeyguardLockedStateListener(@NonNull android.app.KeyguardManager.KeyguardLockedStateListener); method public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable android.app.KeyguardManager.KeyguardDismissCallback); } @FlaggedApi("android.app.device_unlock_listener") @java.lang.FunctionalInterface public static interface KeyguardManager.DeviceLockedStateListener { method public void onDeviceLockedStateChanged(boolean); } public abstract static class KeyguardManager.KeyguardDismissCallback { ctor public KeyguardManager.KeyguardDismissCallback(); method public void onDismissCancelled(); core/java/android/app/KeyguardManager.java +96 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.app; import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -52,7 +53,9 @@ import android.view.IOnKeyguardExitResult; import android.view.IWindowManager; import android.view.WindowManagerGlobal; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.IDeviceLockedStateListener; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.IKeyguardLockedStateListener; import com.android.internal.util.Preconditions; Loading Loading @@ -253,6 +256,26 @@ public class KeyguardManager { private final ArrayMap<KeyguardLockedStateListener, Executor> mKeyguardLockedStateListeners = new ArrayMap<>(); private final IDeviceLockedStateListener mIDeviceLockedStateListener = new IDeviceLockedStateListener.Stub() { @Override public void onDeviceLockedStateChanged(boolean isDeviceLocked) { if (!Flags.deviceUnlockListener()) { return; } synchronized (mDeviceLockedStateListeners) { mDeviceLockedStateListeners.forEach((listener, executor) -> { executor.execute( () -> listener.onDeviceLockedStateChanged(isDeviceLocked)); }); } } }; @GuardedBy("mDeviceLockedStateListeners") private final ArrayMap<DeviceLockedStateListener, Executor> mDeviceLockedStateListeners = new ArrayMap<>(); /** * Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics * if enrolled) for the current user of the device. The caller is expected to launch this Loading Loading @@ -1370,4 +1393,77 @@ public class KeyguardManager { } } } /** * Listener for device locked state changes. */ @FunctionalInterface @FlaggedApi(Flags.FLAG_DEVICE_UNLOCK_LISTENER) public interface DeviceLockedStateListener { /** * Callback function that executes when the device locked state changes. */ void onDeviceLockedStateChanged(boolean isDeviceLocked); } /** * Registers a listener to execute when the device locked state changes. * * @param executor The {@link Executor} where the {@code listener} will be invoked * @param listener The listener to add to receive device locked state changes. * * @see #isDeviceLocked() * @see #removeDeviceLockedStateListener(DeviceLockedStateListener) */ @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) @FlaggedApi(Flags.FLAG_DEVICE_UNLOCK_LISTENER) public void addDeviceLockedStateListener(@NonNull @CallbackExecutor Executor executor, @NonNull DeviceLockedStateListener listener) { if (!Flags.deviceUnlockListener()) { return; } synchronized (mDeviceLockedStateListeners) { mDeviceLockedStateListeners.put(listener, executor); if (mDeviceLockedStateListeners.size() > 1) { return; } try { mTrustManager.registerDeviceLockedStateListener(mIDeviceLockedStateListener, mContext.getDeviceId()); } catch (RemoteException re) { Log.d(TAG, "TrustManager service died", re); } } } /** * Unregisters a listener that executes when the device locked state changes. * * @param listener The listener to remove. * * @see #isDeviceLocked() * @see #addDeviceLockedStateListener(Executor, DeviceLockedStateListener) */ @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) @FlaggedApi(Flags.FLAG_DEVICE_UNLOCK_LISTENER) public void removeDeviceLockedStateListener(@NonNull DeviceLockedStateListener listener) { if (!Flags.deviceUnlockListener()) { return; } synchronized (mDeviceLockedStateListeners) { mDeviceLockedStateListeners.remove(listener); if (!mDeviceLockedStateListeners.isEmpty()) { return; } try { mTrustManager.unregisterDeviceLockedStateListener(mIDeviceLockedStateListener); } catch (RemoteException re) { Log.d(TAG, "TrustManager service died", re); } } } } core/java/android/app/keyguard.aconfig 0 → 100644 +10 −0 Original line number Diff line number Diff line package: "android.app" container: "system" flag { namespace: "wallet_integration" name: "device_unlock_listener" is_exported: true description: "Enable listener API for device unlock." bug: "296195355" } No newline at end of file core/java/android/app/trust/ITrustManager.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.app.trust; import android.app.trust.ITrustListener; import android.hardware.biometrics.BiometricSourceType; import com.android.internal.policy.IDeviceLockedStateListener; /** * System private API to comunicate with trust service. Loading @@ -43,4 +44,8 @@ interface ITrustManager { boolean isActiveUnlockRunning(int userId); @EnforcePermission("ACCESS_FINE_LOCATION") boolean isInSignificantPlace(); @EnforcePermission("SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE") void registerDeviceLockedStateListener(in IDeviceLockedStateListener listener, int deviceId); @EnforcePermission("SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE") void unregisterDeviceLockedStateListener(in IDeviceLockedStateListener listener); } core/java/android/app/trust/TrustManager.java +31 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.os.Message; import android.os.RemoteException; import android.util.ArrayMap; import com.android.internal.policy.IDeviceLockedStateListener; import java.util.ArrayList; import java.util.List; Loading Loading @@ -258,6 +260,35 @@ public class TrustManager { } } /** * Registers a listener for device lock state events. * * Requires the {@link android.Manifest.permission#SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE} * permission. */ public void registerDeviceLockedStateListener(final IDeviceLockedStateListener listener, int deviceId) { try { mService.registerDeviceLockedStateListener(listener, deviceId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Unregisters a listener for device lock state events. * * Requires the {@link android.Manifest.permission#SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE} * permission. */ public void unregisterDeviceLockedStateListener(final IDeviceLockedStateListener listener) { try { mService.unregisterDeviceLockedStateListener(listener); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * @return whether {@param userId} has enabled and configured trust agents. Ignores short-term * unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}. Loading Loading
core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -6235,6 +6235,7 @@ package android.app { } public class KeyguardManager { method @FlaggedApi("android.app.device_unlock_listener") @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void addDeviceLockedStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.DeviceLockedStateListener); method @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void addKeyguardLockedStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.KeyguardLockedStateListener); method @Deprecated public android.content.Intent createConfirmDeviceCredentialIntent(CharSequence, CharSequence); method @Deprecated @RequiresPermission(android.Manifest.permission.DISABLE_KEYGUARD) public void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult); Loading @@ -6244,10 +6245,15 @@ package android.app { method public boolean isKeyguardLocked(); method public boolean isKeyguardSecure(); method @Deprecated public android.app.KeyguardManager.KeyguardLock newKeyguardLock(String); method @FlaggedApi("android.app.device_unlock_listener") @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void removeDeviceLockedStateListener(@NonNull android.app.KeyguardManager.DeviceLockedStateListener); method @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void removeKeyguardLockedStateListener(@NonNull android.app.KeyguardManager.KeyguardLockedStateListener); method public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable android.app.KeyguardManager.KeyguardDismissCallback); } @FlaggedApi("android.app.device_unlock_listener") @java.lang.FunctionalInterface public static interface KeyguardManager.DeviceLockedStateListener { method public void onDeviceLockedStateChanged(boolean); } public abstract static class KeyguardManager.KeyguardDismissCallback { ctor public KeyguardManager.KeyguardDismissCallback(); method public void onDismissCancelled();
core/java/android/app/KeyguardManager.java +96 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.app; import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -52,7 +53,9 @@ import android.view.IOnKeyguardExitResult; import android.view.IWindowManager; import android.view.WindowManagerGlobal; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.IDeviceLockedStateListener; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.IKeyguardLockedStateListener; import com.android.internal.util.Preconditions; Loading Loading @@ -253,6 +256,26 @@ public class KeyguardManager { private final ArrayMap<KeyguardLockedStateListener, Executor> mKeyguardLockedStateListeners = new ArrayMap<>(); private final IDeviceLockedStateListener mIDeviceLockedStateListener = new IDeviceLockedStateListener.Stub() { @Override public void onDeviceLockedStateChanged(boolean isDeviceLocked) { if (!Flags.deviceUnlockListener()) { return; } synchronized (mDeviceLockedStateListeners) { mDeviceLockedStateListeners.forEach((listener, executor) -> { executor.execute( () -> listener.onDeviceLockedStateChanged(isDeviceLocked)); }); } } }; @GuardedBy("mDeviceLockedStateListeners") private final ArrayMap<DeviceLockedStateListener, Executor> mDeviceLockedStateListeners = new ArrayMap<>(); /** * Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics * if enrolled) for the current user of the device. The caller is expected to launch this Loading Loading @@ -1370,4 +1393,77 @@ public class KeyguardManager { } } } /** * Listener for device locked state changes. */ @FunctionalInterface @FlaggedApi(Flags.FLAG_DEVICE_UNLOCK_LISTENER) public interface DeviceLockedStateListener { /** * Callback function that executes when the device locked state changes. */ void onDeviceLockedStateChanged(boolean isDeviceLocked); } /** * Registers a listener to execute when the device locked state changes. * * @param executor The {@link Executor} where the {@code listener} will be invoked * @param listener The listener to add to receive device locked state changes. * * @see #isDeviceLocked() * @see #removeDeviceLockedStateListener(DeviceLockedStateListener) */ @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) @FlaggedApi(Flags.FLAG_DEVICE_UNLOCK_LISTENER) public void addDeviceLockedStateListener(@NonNull @CallbackExecutor Executor executor, @NonNull DeviceLockedStateListener listener) { if (!Flags.deviceUnlockListener()) { return; } synchronized (mDeviceLockedStateListeners) { mDeviceLockedStateListeners.put(listener, executor); if (mDeviceLockedStateListeners.size() > 1) { return; } try { mTrustManager.registerDeviceLockedStateListener(mIDeviceLockedStateListener, mContext.getDeviceId()); } catch (RemoteException re) { Log.d(TAG, "TrustManager service died", re); } } } /** * Unregisters a listener that executes when the device locked state changes. * * @param listener The listener to remove. * * @see #isDeviceLocked() * @see #addDeviceLockedStateListener(Executor, DeviceLockedStateListener) */ @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) @FlaggedApi(Flags.FLAG_DEVICE_UNLOCK_LISTENER) public void removeDeviceLockedStateListener(@NonNull DeviceLockedStateListener listener) { if (!Flags.deviceUnlockListener()) { return; } synchronized (mDeviceLockedStateListeners) { mDeviceLockedStateListeners.remove(listener); if (!mDeviceLockedStateListeners.isEmpty()) { return; } try { mTrustManager.unregisterDeviceLockedStateListener(mIDeviceLockedStateListener); } catch (RemoteException re) { Log.d(TAG, "TrustManager service died", re); } } } }
core/java/android/app/keyguard.aconfig 0 → 100644 +10 −0 Original line number Diff line number Diff line package: "android.app" container: "system" flag { namespace: "wallet_integration" name: "device_unlock_listener" is_exported: true description: "Enable listener API for device unlock." bug: "296195355" } No newline at end of file
core/java/android/app/trust/ITrustManager.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.app.trust; import android.app.trust.ITrustListener; import android.hardware.biometrics.BiometricSourceType; import com.android.internal.policy.IDeviceLockedStateListener; /** * System private API to comunicate with trust service. Loading @@ -43,4 +44,8 @@ interface ITrustManager { boolean isActiveUnlockRunning(int userId); @EnforcePermission("ACCESS_FINE_LOCATION") boolean isInSignificantPlace(); @EnforcePermission("SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE") void registerDeviceLockedStateListener(in IDeviceLockedStateListener listener, int deviceId); @EnforcePermission("SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE") void unregisterDeviceLockedStateListener(in IDeviceLockedStateListener listener); }
core/java/android/app/trust/TrustManager.java +31 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.os.Message; import android.os.RemoteException; import android.util.ArrayMap; import com.android.internal.policy.IDeviceLockedStateListener; import java.util.ArrayList; import java.util.List; Loading Loading @@ -258,6 +260,35 @@ public class TrustManager { } } /** * Registers a listener for device lock state events. * * Requires the {@link android.Manifest.permission#SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE} * permission. */ public void registerDeviceLockedStateListener(final IDeviceLockedStateListener listener, int deviceId) { try { mService.registerDeviceLockedStateListener(listener, deviceId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Unregisters a listener for device lock state events. * * Requires the {@link android.Manifest.permission#SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE} * permission. */ public void unregisterDeviceLockedStateListener(final IDeviceLockedStateListener listener) { try { mService.unregisterDeviceLockedStateListener(listener); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * @return whether {@param userId} has enabled and configured trust agents. Ignores short-term * unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}. Loading