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

Commit a65ce74e authored by Kevin Chyn's avatar Kevin Chyn
Browse files

Pass detailed reason to UdfpsView, split animation logic

Bug: 177931181

Test: AOD anti-burn-in offsets still applied
Test: Auth on keyguard
Test: Enroll
Test: Auth in settings
Test: atest com.android.server.biometrics
Test: atest com.android.systemui.biometrics

Change-Id: I3638fe02d72caf1911f6b4919b62ca5b25e4b0ea
parent 352d5a43
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ package android.hardware.fingerprint;
oneway interface IUdfpsOverlayController {
    const int REASON_UNKNOWN = 0;
    const int REASON_ENROLL = 1;
    const int REASON_AUTH = 2;
    const int REASON_AUTH_BP = 2; // BiometricPrompt
    const int REASON_AUTH_FPM_KEYGUARD = 3; // FingerprintManager usage from Keyguard
    const int REASON_AUTH_FPM_OTHER = 4; // Other FingerprintManager usage

    // Shows the overlay.
    void showUdfpsOverlay(int sensorId, int reason);
+50 −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.systemui.biometrics;

import android.content.Context;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;

import androidx.annotation.NonNull;

import com.android.systemui.R;

/**
 * Abstract base class for animations that should be drawn when the finger is not touching the
 * sensor area.
 */
public abstract class UdfpsAnimation extends Drawable {
    abstract void updateColor();

    @NonNull protected final Context mContext;
    @NonNull protected final Drawable mFingerprintDrawable;

    public UdfpsAnimation(@NonNull Context context) {
        mContext = context;
        mFingerprintDrawable = context.getResources().getDrawable(R.drawable.ic_fingerprint, null);
    }

    public void onSensorRectUpdated(@NonNull RectF sensorRect) {
        int margin =  (int) (sensorRect.bottom - sensorRect.top) / 5;
        mFingerprintDrawable.setBounds(
                (int) sensorRect.left + margin,
                (int) sensorRect.top + margin,
                (int) sensorRect.right - margin,
                (int) sensorRect.bottom - margin);
    }
}
+88 −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.systemui.biometrics;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.RectF;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.systemui.R;

/**
 * UDFPS animations that should be shown when enrolling.
 */
public class UdfpsAnimationEnroll extends UdfpsAnimation {
    private static final String TAG = "UdfpsAnimationEnroll";

    @Nullable private RectF mSensorRect;
    @NonNull private final Paint mSensorPaint;

    UdfpsAnimationEnroll(@NonNull Context context) {
        super(context);

        mSensorPaint = new Paint(0 /* flags */);
        mSensorPaint.setAntiAlias(true);
        mSensorPaint.setColor(Color.WHITE);
        mSensorPaint.setShadowLayer(UdfpsView.SENSOR_SHADOW_RADIUS, 0, 0, Color.BLACK);
        mSensorPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    void updateColor() {
        mFingerprintDrawable.setTint(mContext.getColor(R.color.udfps_enroll_icon));
    }

    @Override
    public void onSensorRectUpdated(@NonNull RectF sensorRect) {
        super.onSensorRectUpdated(sensorRect);
        mSensorRect = sensorRect;
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        final boolean isNightMode = (mContext.getResources().getConfiguration().uiMode
                & Configuration.UI_MODE_NIGHT_YES) != 0;
        if (!isNightMode) {
            if (mSensorRect != null) {
                canvas.drawOval(mSensorRect, mSensorPaint);
            }
        }
        mFingerprintDrawable.draw(canvas);
    }

    @Override
    public void setAlpha(int alpha) {

    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {

    }

    @Override
    public int getOpacity() {
        return 0;
    }
}
+60 −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.systemui.biometrics;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * UDFPS animations that should be shown when authenticating via FingerprintManager, excluding
 * keyguard.
 */
public class UdfpsAnimationFpmOther extends UdfpsAnimation {

    UdfpsAnimationFpmOther(@NonNull Context context) {
        super(context);
    }

    @Override
    void updateColor() {

    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        mFingerprintDrawable.draw(canvas);
    }

    @Override
    public void setAlpha(int alpha) {

    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {

    }

    @Override
    public int getOpacity() {
        return 0;
    }
}
+124 −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.systemui.biometrics;

import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.util.MathUtils;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.graphics.ColorUtils;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.doze.DozeReceiver;
import com.android.systemui.plugins.statusbar.StatusBarStateController;

/**
 * UDFPS animations that should be shown when authenticating on keyguard.
 */
public class UdfpsAnimationKeyguard extends UdfpsAnimation implements DozeReceiver,
        StatusBarStateController.StateListener {

    private static final String TAG = "UdfpsAnimationKeyguard";

    @NonNull private final View mParent;
    @NonNull private final Context mContext;
    private final int mMaxBurnInOffsetX;
    private final int mMaxBurnInOffsetY;

    // AOD anti-burn-in offsets
    private float mInterpolatedDarkAmount;
    private float mBurnInOffsetX;
    private float mBurnInOffsetY;

    UdfpsAnimationKeyguard(@NonNull View parent, @NonNull Context context,
            @NonNull StatusBarStateController statusBarStateController) {
        super(context);
        mParent = parent;
        mContext = context;

        mMaxBurnInOffsetX = context.getResources()
                .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_x);
        mMaxBurnInOffsetY = context.getResources()
                .getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);

        statusBarStateController.addCallback(this);
    }

    private void updateAodPositionAndColor() {
        mBurnInOffsetX = MathUtils.lerp(0f,
                getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
                        - mMaxBurnInOffsetX,
                mInterpolatedDarkAmount);
        mBurnInOffsetY = MathUtils.lerp(0f,
                getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
                        - 0.5f * mMaxBurnInOffsetY,
                mInterpolatedDarkAmount);
        updateColor();
        mParent.postInvalidate();
    }

    @Override
    public void dozeTimeTick() {
        updateAodPositionAndColor();
    }

    @Override
    public void onDozeAmountChanged(float linear, float eased) {
        mInterpolatedDarkAmount = eased;
        updateAodPositionAndColor();
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        canvas.save();
        canvas.translate(mBurnInOffsetX, mBurnInOffsetY);
        mFingerprintDrawable.draw(canvas);
        canvas.restore();
    }

    @Override
    public void setAlpha(int alpha) {

    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {

    }

    @Override
    public int getOpacity() {
        return 0;
    }

    @Override
    public void updateColor() {
        final int lockScreenIconColor = Utils.getColorAttrDefaultColor(mContext,
                R.attr.wallpaperTextColor);
        final int ambientDisplayIconColor = Color.WHITE;
        mFingerprintDrawable.setTint(ColorUtils.blendARGB(lockScreenIconColor,
                ambientDisplayIconColor, mInterpolatedDarkAmount));
    }
}
Loading