• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.biometrics.fingerprint;
18 
19 import android.content.Context;
20 import android.graphics.Rect;
21 import android.graphics.RectF;
22 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
23 import android.util.AttributeSet;
24 import android.util.Log;
25 import android.util.RotationUtils;
26 import android.view.DisplayInfo;
27 import android.view.MotionEvent;
28 import android.view.Surface;
29 import android.widget.ImageView;
30 import android.widget.RelativeLayout;
31 
32 import androidx.annotation.NonNull;
33 import androidx.annotation.Nullable;
34 
35 import com.android.settings.R;
36 import com.android.systemui.biometrics.UdfpsUtils;
37 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
38 
39 /**
40  * View corresponding with fingerprint_check_enrolled_dialog.xml
41  */
42 public class UdfpsCheckEnrolledView extends RelativeLayout {
43     private static final String TAG = "UdfpsCheckEnrolledView";
44     @NonNull
45     private final UdfpsFingerprintDrawable mFingerprintDrawable;
46     private ImageView mFingerprintView;
47     private UdfpsUtils mUdfpsUtils;
48 
49     private @Nullable Rect mSensorRect;
50     private @Nullable UdfpsOverlayParams mOverlayParams;
51     private @Nullable FingerprintSensorPropertiesInternal mSensorProperties;
52 
53 
UdfpsCheckEnrolledView(@onNull Context context, @Nullable AttributeSet attrs)54     public UdfpsCheckEnrolledView(@NonNull Context context, @Nullable AttributeSet attrs) {
55         super(context, attrs);
56         mFingerprintDrawable = new UdfpsFingerprintDrawable(mContext, attrs);
57         mUdfpsUtils = new UdfpsUtils();
58     }
59 
60     @Override
onFinishInflate()61     protected void onFinishInflate() {
62         super.onFinishInflate();
63         mFingerprintView = findViewById(R.id.udfps_fingerprint_sensor_view);
64         mFingerprintView.setImageDrawable(mFingerprintDrawable);
65         mFingerprintView.setOnTouchListener((v, event) -> {
66             if (event.getAction() == MotionEvent.ACTION_DOWN) {
67                 Log.d(TAG, "Fingerprint view touched!");
68                 return true;
69             }
70             return false;
71         });
72     }
73 
74     /**
75      * setup SensorProperties
76      */
setSensorProperties(@ullable FingerprintSensorPropertiesInternal properties)77     public void setSensorProperties(@Nullable FingerprintSensorPropertiesInternal properties) {
78         mSensorProperties = properties;
79         updateOverlayParams();
80     }
81 
onSensorRectUpdated()82     private void onSensorRectUpdated() {
83         updateDimensions();
84 
85         if (mSensorRect == null || mOverlayParams == null) {
86             Log.e(TAG, "Fail to onSensorRectUpdated, mSensorRect/mOverlayParams null");
87             return;
88         }
89 
90         // Updates sensor rect in relation to the overlay view
91         mSensorRect.set(0, 0,
92                 mOverlayParams.getSensorBounds().width(),
93                 mOverlayParams.getSensorBounds().height());
94         mFingerprintDrawable.onSensorRectUpdated(new RectF(mSensorRect));
95     }
96 
updateDimensions()97     private void updateDimensions() {
98         if (mOverlayParams == null) {
99             Log.e(TAG, "Fail to updateDimensions for " + this + ", mOverlayParams null");
100             return;
101         }
102         // Original sensorBounds assume portrait mode.
103         final Rect rotatedBounds = new Rect(mOverlayParams.getSensorBounds());
104         int rotation = mOverlayParams.getRotation();
105         if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
106             RotationUtils.rotateBounds(
107                     rotatedBounds,
108                     mOverlayParams.getNaturalDisplayWidth(),
109                     mOverlayParams.getNaturalDisplayHeight(),
110                     rotation
111             );
112         }
113 
114         RelativeLayout parent = ((RelativeLayout) getParent());
115         if (parent == null) {
116             Log.e(TAG, "Fail to updateDimensions for " + this + ", parent null");
117             return;
118         }
119         final int[] coords = parent.getLocationOnScreen();
120         final int parentLeft = coords[0];
121         final int parentTop = coords[1];
122         final int parentRight = parentLeft + parent.getWidth();
123 
124         // Update container view LayoutParams
125         RelativeLayout.LayoutParams checkEnrolledViewLp =
126                 new RelativeLayout.LayoutParams(getWidth(), getHeight());
127         checkEnrolledViewLp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
128         if (rotation == Surface.ROTATION_90) {
129             checkEnrolledViewLp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
130             checkEnrolledViewLp.width =
131                     rotatedBounds.width() + 2 * (parentRight - rotatedBounds.right);
132         } else {
133             checkEnrolledViewLp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
134             checkEnrolledViewLp.width = rotatedBounds.width() + 2 * rotatedBounds.left;
135         }
136         setLayoutParams(checkEnrolledViewLp);
137 
138         // Update fingerprint view LayoutParams
139         RelativeLayout.LayoutParams fingerprintViewLp = new RelativeLayout.LayoutParams(
140                 rotatedBounds.width(), rotatedBounds.height());
141         fingerprintViewLp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
142         fingerprintViewLp.topMargin = rotatedBounds.top - parentTop;
143         if (rotation == Surface.ROTATION_90) {
144             fingerprintViewLp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
145             fingerprintViewLp.rightMargin = parentRight - rotatedBounds.right;
146         } else {
147             fingerprintViewLp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
148             fingerprintViewLp.leftMargin = rotatedBounds.left - parentLeft;
149         }
150         mFingerprintView.setLayoutParams(fingerprintViewLp);
151     }
152 
updateOverlayParams()153     private void updateOverlayParams() {
154 
155         if (mSensorProperties == null) {
156             android.util.Log.e(TAG, "There is no sensor info!");
157             return;
158         }
159 
160         DisplayInfo displayInfo = new DisplayInfo();
161         if (getDisplay() == null) {
162             android.util.Log.e(TAG, "Can not get display");
163             return;
164         }
165         getDisplay().getDisplayInfo(displayInfo);
166         Rect udfpsBounds = mSensorProperties.getLocation().getRect();
167         float scaleFactor = mUdfpsUtils.getScaleFactor(displayInfo);
168         udfpsBounds.scale(scaleFactor);
169 
170         final Rect overlayBounds = new Rect(
171                 0, /* left */
172                 displayInfo.getNaturalHeight() / 2, /* top */
173                 displayInfo.getNaturalWidth(), /* right */
174                 displayInfo.getNaturalHeight() /* botom */);
175 
176         mOverlayParams = new UdfpsOverlayParams(
177                 udfpsBounds,
178                 overlayBounds,
179                 displayInfo.getNaturalWidth(),
180                 displayInfo.getNaturalHeight(),
181                 scaleFactor,
182                 displayInfo.rotation,
183                 mSensorProperties.sensorType);
184 
185         post(() -> {
186             if (mOverlayParams == null) {
187                 Log.e(TAG, "Fail to updateOverlayParams, mOverlayParams null");
188                 return;
189             }
190             mSensorRect = new Rect(mOverlayParams.getSensorBounds());
191             onSensorRectUpdated();
192         });
193     }
194 }
195