Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a650c2c4 authored by Xiaowen Lei's avatar Xiaowen Lei Committed by Bryce Lee
Browse files

Add role guarded APIs for subscribing to keyguard locked state in KeyguardManager.

Bug: 216630470
CTS-Coverage-Bug: 220371902
Test: manual
Test: atest CtsAppTestCases:KeyguardLockedStateApiTest
Ignore-AOSP-First: (for packages/Shell/AndroidManifest.xml) Permission
not yet publicly announced.

Change-Id: I1f44ec6799b0f74791613389ce28aadf84c9fe5c
parent c80e1dab
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ package android {
    field public static final String START_VIEW_APP_FEATURES = "android.permission.START_VIEW_APP_FEATURES";
    field public static final String START_VIEW_PERMISSION_USAGE = "android.permission.START_VIEW_PERMISSION_USAGE";
    field public static final String STATUS_BAR = "android.permission.STATUS_BAR";
    field public static final String SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE = "android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE";
    field public static final String SYSTEM_ALERT_WINDOW = "android.permission.SYSTEM_ALERT_WINDOW";
    field public static final String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
    field public static final String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
@@ -5677,6 +5678,7 @@ package android.app {
  }
  public class KeyguardManager {
    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);
    method @Deprecated public boolean inKeyguardRestrictedInputMode();
@@ -5685,6 +5687,7 @@ package android.app {
    method public boolean isKeyguardLocked();
    method public boolean isKeyguardSecure();
    method @Deprecated public android.app.KeyguardManager.KeyguardLock newKeyguardLock(String);
    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);
  }
@@ -5700,6 +5703,10 @@ package android.app {
    method @Deprecated @RequiresPermission(android.Manifest.permission.DISABLE_KEYGUARD) public void reenableKeyguard();
  }
  @java.lang.FunctionalInterface public static interface KeyguardManager.KeyguardLockedStateListener {
    method public void onKeyguardLockedStateChanged(boolean);
  }
  @Deprecated public static interface KeyguardManager.OnKeyguardExitResult {
    method @Deprecated public void onKeyguardExitResult(boolean);
  }
+73 −11
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;

import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardLockedStateListener;
import com.android.internal.util.Preconditions;
import com.android.internal.widget.IWeakEscrowTokenActivatedListener;
import com.android.internal.widget.IWeakEscrowTokenRemovedListener;
@@ -183,6 +184,10 @@ public class KeyguardManager {
    })
    @interface LockTypes {}

    // TODO(b/220379118): register only one binder listener and keep a map of listener to executor.
    private final ArrayMap<KeyguardLockedStateListener, IKeyguardLockedStateListener>
            mKeyguardLockedStateListeners = 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
@@ -534,7 +539,7 @@ public class KeyguardManager {
    /**
     * Return whether the keyguard is currently locked.
     *
     * @return true if keyguard is locked.
     * @return {@code true} if the keyguard is locked.
     */
    public boolean isKeyguardLocked() {
        try {
@@ -550,7 +555,7 @@ public class KeyguardManager {
     *
     * <p>See also {@link #isDeviceSecure()} which ignores SIM locked states.
     *
     * @return true if a PIN, pattern or password is set or a SIM card is locked.
     * @return {@code true} if a PIN, pattern or password is set or a SIM card is locked.
     */
    public boolean isKeyguardSecure() {
        try {
@@ -565,7 +570,7 @@ public class KeyguardManager {
     * keyguard password emergency screen). When in such mode, certain keys,
     * such as the Home key and the right soft keys, don't work.
     *
     * @return true if in keyguard restricted input mode.
     * @return {@code true} if in keyguard restricted input mode.
     * @deprecated Use {@link #isKeyguardLocked()} instead.
     */
    public boolean inKeyguardRestrictedInputMode() {
@@ -576,7 +581,7 @@ public class KeyguardManager {
     * Returns whether the device is currently locked and requires a PIN, pattern or
     * password to unlock.
     *
     * @return true if unlocking the device currently requires a PIN, pattern or
     * @return {@code true} if unlocking the device currently requires a PIN, pattern or
     * password.
     */
    public boolean isDeviceLocked() {
@@ -603,7 +608,7 @@ public class KeyguardManager {
     *
     * <p>See also {@link #isKeyguardSecure} which treats SIM locked states as secure.
     *
     * @return true if a PIN, pattern or password was set.
     * @return {@code true} if a PIN, pattern or password was set.
     */
    public boolean isDeviceSecure() {
        return isDeviceSecure(mContext.getUserId());
@@ -762,7 +767,7 @@ public class KeyguardManager {
    *        as the output of String#getBytes
    * @param complexity - complexity level imposed by the requester
    *        as defined in {@code DevicePolicyManager.PasswordComplexity}
    * @return true if the password is valid, false otherwise
    * @return {@code true} if the password is valid, false otherwise
    * @hide
    */
    @RequiresPermission(Manifest.permission.SET_INITIAL_LOCK)
@@ -821,7 +826,7 @@ public class KeyguardManager {
    *        as the output of String#getBytes
    * @param complexity - complexity level imposed by the requester
    *        as defined in {@code DevicePolicyManager.PasswordComplexity}
    * @return true if the lock is successfully set, false otherwise
    * @return {@code true} if the lock is successfully set, false otherwise
    * @hide
    */
    @RequiresPermission(Manifest.permission.SET_INITIAL_LOCK)
@@ -903,8 +908,8 @@ public class KeyguardManager {
    /**
     * 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.
     * @return {@code 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)
@@ -944,7 +949,7 @@ public class KeyguardManager {
    /**
     * Register the given WeakEscrowTokenRemovedListener.
     *
     * @return true if the listener is registered successfully, return false otherwise.
     * @return {@code true} if the listener is registered successfully, return false otherwise.
     * @hide
     */
    @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
@@ -982,7 +987,7 @@ public class KeyguardManager {
    /**
     * Unregister the given WeakEscrowTokenRemovedListener.
     *
     * @return true if the listener is unregistered successfully, return false otherwise.
     * @return {@code true} if the listener is unregistered successfully, return false otherwise.
     * @hide
     */
    @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
@@ -1076,4 +1081,61 @@ public class KeyguardManager {
                throw new IllegalArgumentException("Unknown lock type " + lockType);
        }
    }

    /**
     * Listener for keyguard locked state changes.
     */
    @FunctionalInterface
    public interface KeyguardLockedStateListener {
        /**
         * Callback function that executes when the keyguard locked state changes.
         */
        void onKeyguardLockedStateChanged(boolean isKeyguardLocked);
    }

    /**
     * Registers a listener to execute when the keyguard visibility changes.
     *
     * @param listener The listener to add to receive keyguard visibility changes.
     */
    @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
    public void addKeyguardLockedStateListener(@NonNull @CallbackExecutor Executor executor,
            @NonNull KeyguardLockedStateListener listener) {
        synchronized (mKeyguardLockedStateListeners) {
            try {
                final IKeyguardLockedStateListener innerListener =
                        new IKeyguardLockedStateListener.Stub() {
                    @Override
                    public void onKeyguardLockedStateChanged(boolean isKeyguardLocked) {
                        executor.execute(
                                () -> listener.onKeyguardLockedStateChanged(isKeyguardLocked));
                    }
                };
                mWM.addKeyguardLockedStateListener(innerListener);
                mKeyguardLockedStateListeners.put(listener, innerListener);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
     * Unregisters a listener that executes when the keyguard visibility changes.
     */
    @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
    public void removeKeyguardLockedStateListener(@NonNull KeyguardLockedStateListener listener) {
        synchronized (mKeyguardLockedStateListeners) {
            IKeyguardLockedStateListener innerListener = mKeyguardLockedStateListeners.get(
                    listener);
            if (innerListener == null) {
                return;
            }
            try {
                mWM.removeKeyguardLockedStateListener(innerListener);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
            mKeyguardLockedStateListeners.remove(listener);
        }
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view;

import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardLockedStateListener;
import com.android.internal.policy.IShortcutService;

import android.app.IAssistDataReceiver;
@@ -199,6 +200,9 @@ interface IWindowManager
    boolean isKeyguardSecure(int userId);
    void dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message);

    void addKeyguardLockedStateListener(in IKeyguardLockedStateListener listener);
    void removeKeyguardLockedStateListener(in IKeyguardLockedStateListener listener);

    // Requires INTERACT_ACROSS_USERS_FULL permission
    void setSwitchingUser(boolean switching);

+21 −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.policy;

oneway interface IKeyguardLockedStateListener {
    void onKeyguardLockedStateChanged(boolean isKeyguardLocked);
}
 No newline at end of file
+7 −0
Original line number Diff line number Diff line
@@ -4119,6 +4119,13 @@
    <permission android:name="android.permission.MANAGE_HOTWORD_DETECTION"
                android:protectionLevel="internal|preinstalled" />

    <!-- Allows an application to subscribe to keyguard locked (i.e., showing) state.
         <p>Protection level: internal|role
         <p>Intended for use by ROLE_ASSISTANT only.
    -->
    <permission android:name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE"
                android:protectionLevel="internal|role"/>

    <!-- Must be required by a {@link android.service.autofill.AutofillService},
         to ensure that only the system can bind to it.
         <p>Protection level: signature
Loading