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

Commit de709166 authored by Grace Cheng's avatar Grace Cheng Committed by Automerger Merge Worker
Browse files

Merge "Configures SideFpsEventHandler to handle PhoneWindowManager behavior in...

Merge "Configures SideFpsEventHandler to handle PhoneWindowManager behavior in response to side fingerprint sensor state changes" into sc-dev am: 610ec381

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14278615

Change-Id: I783a9a3abef98f1ed059f2ab7d6b55625915efc1
parents 8a94f6b5 610ec381
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -3390,6 +3390,23 @@
    <!-- [CHAR LIMIT=NONE] Message to show in upgrading dialog when the bulk of the upgrade work is done. -->
    <string name="android_upgrading_complete">Finishing boot.</string>

    <!-- [CHAR LIMIT=40] Title of dialog shown to confirm device going to sleep if the power button
    is pressed during fingerprint enrollment. -->
    <string name="fp_enrollment_powerbutton_intent_title">Turn off screen?</string>

    <!-- [CHAR LIMIT=NONE] Message of dialog shown to confirm device going to sleep if the power
    button is pressed during fingerprint enrollment. -->
    <string name="fp_enrollment_powerbutton_intent_message">While setting up your fingerprint, you
        pressed the Power button.\n\nThis usually turns off your screen.</string>

    <!-- [CHAR LIMIT=20] Positive button of dialog shown to confirm device going to sleep if the
    power button is pressed during fingerprint enrollment. -->
    <string name="fp_enrollment_powerbutton_intent_positive_button">Turn off</string>

    <!-- [CHAR LIMIT=20] Negative button of dialog shown to confirm device going to sleep if the
    power button is pressed during fingerprint enrollment. -->
    <string name="fp_enrollment_powerbutton_intent_negative_button">Cancel</string>

    <!-- Notification text to tell the user that a heavy-weight application is running. -->
    <string name="heavy_weight_notification"><xliff:g id="app">%1$s</xliff:g> running</string>

+4 −0
Original line number Diff line number Diff line
@@ -1814,6 +1814,10 @@
  <java-symbol type="string" name="bugreport_status" />
  <java-symbol type="string" name="bugreport_title" />
  <java-symbol type="string" name="faceunlock_multiple_failures" />
  <java-symbol type="string" name="fp_enrollment_powerbutton_intent_title" />
  <java-symbol type="string" name="fp_enrollment_powerbutton_intent_message" />
  <java-symbol type="string" name="fp_enrollment_powerbutton_intent_positive_button" />
  <java-symbol type="string" name="fp_enrollment_powerbutton_intent_negative_button" />
  <java-symbol type="string" name="global_actions" />
  <java-symbol type="string" name="global_action_power_off" />
  <java-symbol type="string" name="global_action_power_options" />
+8 −0
Original line number Diff line number Diff line
@@ -379,6 +379,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private DisplayFoldController mDisplayFoldController;
    AppOpsManager mAppOpsManager;
    PackageManager mPackageManager;
    SideFpsEventHandler mSideFpsEventHandler;
    private boolean mHasFeatureAuto;
    private boolean mHasFeatureWatch;
    private boolean mHasFeatureLeanback;
@@ -928,6 +929,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        } else if (count == 3) {
            powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
        } else if (interactive && !beganFromNonInteractive) {
            if (mSideFpsEventHandler.onSinglePressDetected(eventTime)) {
                Slog.i(TAG, "Suppressing power key because the user is interacting with the "
                        + "fingerprint sensor");
                return;
            }
            switch (mShortPressOnPowerBehavior) {
                case SHORT_PRESS_POWER_NOTHING:
                    break;
@@ -1803,6 +1809,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                });
        initKeyCombinationRules();
        initSingleKeyGestureRules();
        mSideFpsEventHandler = new SideFpsEventHandler(mContext, mHandler, mPowerManager);
    }

    private void initKeyCombinationRules() {
@@ -4668,6 +4675,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                mKeyguardDelegate.onBootCompleted();
            }
        }
        mSideFpsEventHandler.onFingerprintSensorReady();
        startedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
        finishedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);

+142 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.policy;

import static android.hardware.fingerprint.FingerprintStateListener.STATE_ENROLLING;
import static android.hardware.fingerprint.FingerprintStateListener.STATE_IDLE;

import android.annotation.NonNull;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintStateListener;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.os.Handler;
import android.os.PowerManager;
import android.view.WindowManager;

import com.android.internal.R;

import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Defines behavior for handling interactions between power button events and
 * fingerprint-related operations, for devices where the fingerprint sensor (side fps)
 * lives on the power button.
 */
public class SideFpsEventHandler {
    @NonNull private final Context mContext;
    @NonNull private final Handler mHandler;
    @NonNull private final PowerManager mPowerManager;
    @NonNull private final AtomicBoolean mIsSideFps;
    @NonNull private final AtomicBoolean mSideFpsEventHandlerReady;

    private @FingerprintStateListener.State int mFingerprintState;

    SideFpsEventHandler(Context context, Handler handler, PowerManager powerManager) {
        mContext = context;
        mHandler = handler;
        mPowerManager = powerManager;
        mFingerprintState = STATE_IDLE;
        mIsSideFps = new AtomicBoolean(false);
        mSideFpsEventHandlerReady = new AtomicBoolean(false);
    }

    /**
     * Called from {@link PhoneWindowManager} after power button is pressed. Checks fingerprint
     * sensor state and if mFingerprintState = STATE_ENROLLING, displays a dialog confirming intent
     * to turn screen off. If confirmed, the device goes to sleep, and if canceled, the dialog is
     * dismissed.
     * @param eventTime powerPress event time
     * @return true if powerPress was consumed, false otherwise
     */
    public boolean onSinglePressDetected(long eventTime) {
        if (!mSideFpsEventHandlerReady.get() || !mIsSideFps.get()
                || mFingerprintState != STATE_ENROLLING) {
            return false;
        }
        mHandler.post(() -> {
            Dialog confirmScreenOffDialog = new AlertDialog.Builder(mContext)
                    .setTitle(R.string.fp_enrollment_powerbutton_intent_title)
                    .setMessage(R.string.fp_enrollment_powerbutton_intent_message)
                    .setPositiveButton(
                            R.string.fp_enrollment_powerbutton_intent_positive_button,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    mPowerManager.goToSleep(
                                            eventTime,
                                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
                                            0 /* flags */
                                    );
                                }
                            })
                    .setNegativeButton(
                            R.string.fp_enrollment_powerbutton_intent_negative_button,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            })
                    .setCancelable(false)
                    .create();
            confirmScreenOffDialog.getWindow().setType(
                    WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
            confirmScreenOffDialog.show();
        });
        return true;
    }

    /**
     * Awaits notification from PhoneWindowManager that fingerprint service is ready
     * to send updates about power button fps sensor state. Then configures a
     * FingerprintStateListener to receive and record updates to fps state, and
     * registers the FingerprintStateListener in FingerprintManager.
     */
    public void onFingerprintSensorReady() {
        final PackageManager pm = mContext.getPackageManager();
        if (!pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) return;
        FingerprintManager fingerprintManager =
                mContext.getSystemService(FingerprintManager.class);
        fingerprintManager.addAuthenticatorsRegisteredCallback(
                new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
                    @Override
                    public void onAllAuthenticatorsRegistered(
                            List<FingerprintSensorPropertiesInternal> sensors) {
                        mIsSideFps.set(fingerprintManager.isPowerbuttonFps());
                        FingerprintStateListener fingerprintStateListener =
                                new FingerprintStateListener() {
                            @Override
                            public void onStateChanged(
                                    @FingerprintStateListener.State int newState) {
                                mFingerprintState = newState;
                            }
                        };
                        fingerprintManager.registerFingerprintStateListener(
                                fingerprintStateListener);
                        mSideFpsEventHandlerReady.set(true);
                    }
                });
    }
}