(1/n) Make the GlifHeader scrollable on FingerprintEnrollEnrolling(
UDPFS) layout page. 1. To override GlifLayout's onInflateTemplate() then embedding a ScrollView on GlifHeader. 2. Remove previous hiding the description text snippet 3. Handling UDFPS enroll lottie position problem. 4. Solve the ProgressBar overlapped with FooterBar problem. Flag: com.android.settings.flags.enroll_layout_truncate_improvement Bug: 359149850 Bug: 367164671 Bug: 362522976 Test: atest UdfpsEnrollEnrollingViewTest Test: Build Forrest ROM then check the UI in different scenarios Change-Id: Iee44cb5815286233f23266e3d86fd8335ab2087d
This commit is contained in:
@@ -15,6 +15,16 @@ flag {
|
||||
bug: "301226085"
|
||||
}
|
||||
|
||||
flag {
|
||||
name: "enroll_layout_truncate_improvement"
|
||||
namespace: "biometrics_integration"
|
||||
description: "This flag controls whether the enroll layout truncate improvement feature should be enabled"
|
||||
bug: "359149850"
|
||||
metadata {
|
||||
purpose: PURPOSE_BUGFIX
|
||||
}
|
||||
}
|
||||
|
||||
flag {
|
||||
name: "screen_off_unlock_power_optimization"
|
||||
namespace: "biometrics_integration"
|
||||
|
26
res/layout/biometrics_glif_compact.xml
Normal file
26
res/layout/biometrics_glif_compact.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2024 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.
|
||||
-->
|
||||
|
||||
<com.google.android.setupcompat.view.StatusBarBackgroundLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/suc_layout_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include layout="@layout/biometrics_glif_content" />
|
||||
|
||||
</com.google.android.setupcompat.view.StatusBarBackgroundLayout>
|
82
res/layout/biometrics_glif_content.xml
Normal file
82
res/layout/biometrics_glif_content.xml
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2024 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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/sud_layout_template_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="true"
|
||||
android:clipToPadding="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/sud_layout_sticky_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.google.android.setupdesign.view.BottomScrollView
|
||||
android:id="@+id/sud_header_scroll_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/biometrics_glif_header_height"
|
||||
android:fillViewport="true"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<include layout="@layout/sud_glif_header" />
|
||||
|
||||
</com.google.android.setupdesign.view.BottomScrollView>
|
||||
|
||||
|
||||
<com.google.android.setupdesign.view.BottomScrollView
|
||||
android:id="@+id/sud_scroll_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:fillViewport="true"
|
||||
android:scrollIndicators="?attr/sudScrollIndicators"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/sud_layout_illustration_progress_stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@+id/sud_layout_progress_illustration"
|
||||
android:layout="@layout/sud_progress_illustration_layout" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/sud_layout_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.setupdesign.view.BottomScrollView>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/suc_layout_footer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
@@ -24,58 +24,66 @@
|
||||
android:layout_height="match_parent"
|
||||
style="?attr/fingerprint_layout_theme">
|
||||
|
||||
<LinearLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
style="@style/SudContentFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:orientation="vertical">
|
||||
android:clipChildren="false">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/illustration_lottie"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
app:layout_constraintTop_toTopOf="@id/udfps_view"
|
||||
android:scaleType="centerInside"
|
||||
android:visibility="gone"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="true"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
app:lottie_speed=".85" />
|
||||
|
||||
<LinearLayout
|
||||
style="@style/SudContentFrame"
|
||||
android:id="@+id/udfps_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center|bottom"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
tools:ignore="Suspicious0dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center|bottom"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Animation res MUST be set in code -->
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/illustration_lottie"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="@dimen/udfps_lottie_translate_y"
|
||||
android:scaleType="centerInside"
|
||||
android:visibility="gone"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="true"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
app:lottie_speed=".85" />
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
tools:ignore="Suspicious0dp">
|
||||
|
||||
<include layout="@layout/udfps_enroll_view" />
|
||||
<include layout="@layout/udfps_enroll_view" />
|
||||
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error_text"
|
||||
style="@style/TextAppearance.ErrorText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:accessibilityLiveRegion="polite"
|
||||
android:gravity="center_horizontal"
|
||||
android:visibility="invisible" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/error_text"
|
||||
style="@style/TextAppearance.ErrorText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:accessibilityLiveRegion="polite"
|
||||
android:gravity="center_horizontal"
|
||||
android:visibility="invisible" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.android.settings.biometrics.fingerprint.UdfpsEnrollEnrollingView>
|
||||
|
81
res/layout/udfps_enroll_enrolling_non_scroll.xml
Normal file
81
res/layout/udfps_enroll_enrolling_non_scroll.xml
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2024 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.
|
||||
-->
|
||||
|
||||
<com.android.settings.biometrics.fingerprint.UdfpsEnrollEnrollingView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/setup_wizard_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
style="?attr/fingerprint_layout_theme">
|
||||
|
||||
<LinearLayout
|
||||
style="@style/SudContentFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center|bottom"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
tools:ignore="Suspicious0dp">
|
||||
|
||||
<!-- Animation res MUST be set in code -->
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/illustration_lottie"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="@dimen/udfps_lottie_translate_y"
|
||||
android:scaleType="centerInside"
|
||||
android:visibility="gone"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="true"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
app:lottie_speed=".85" />
|
||||
|
||||
<include layout="@layout/udfps_enroll_view" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error_text"
|
||||
style="@style/TextAppearance.ErrorText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:accessibilityLiveRegion="polite"
|
||||
android:gravity="center_horizontal"
|
||||
android:visibility="invisible" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.settings.biometrics.fingerprint.UdfpsEnrollEnrollingView>
|
@@ -772,6 +772,9 @@
|
||||
58.0001 29.2229,56.9551 26.8945,55.195
|
||||
</string>
|
||||
|
||||
<!-- Duration in milliseconds of the udfps title/sub-title scrolling once animation. -->
|
||||
<integer name="config_biometrics_header_scroll_duration">1000</integer>
|
||||
|
||||
<!-- Whether auto data switching on secondary SIM enables cross-SIM calling on both SIMs. -->
|
||||
<bool name="config_auto_data_switch_enables_cross_sim_calling">false</bool>
|
||||
|
||||
|
@@ -159,6 +159,10 @@
|
||||
<dimen name="sfps_enroll_finish_icon_margin_top">-24dp</dimen>
|
||||
<dimen name="udfps_lottie_translate_y">0dp</dimen>
|
||||
<dimen name="udfps_lottie_padding_top">20dp</dimen>
|
||||
<dimen name="biometrics_glif_header_height">274dp</dimen>
|
||||
<item name="biometrics_glif_header_height_ratio" format="float" type="dimen">0.27</item>
|
||||
<!-- For showing when Display / Font size set to largest -->
|
||||
<item name="biometrics_glif_header_height_ratio_large" format="float" type="dimen">0.37</item>
|
||||
|
||||
<!-- Face -->
|
||||
<item name="face_preview_translate_y" format="float" type="dimen">0</item>
|
||||
|
@@ -57,6 +57,7 @@ import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.IdRes;
|
||||
@@ -72,6 +73,7 @@ import com.android.settings.biometrics.BiometricsEnrollEnrolling;
|
||||
import com.android.settings.biometrics.BiometricsSplitScreenDialog;
|
||||
import com.android.settings.biometrics.fingerprint.feature.SfpsEnrollmentFeature;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.display.DisplayDensityUtils;
|
||||
import com.android.systemui.unfold.compat.ScreenSizeFoldProvider;
|
||||
@@ -243,16 +245,36 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
mIsAccessibilityEnabled = mAccessibilityManager.isEnabled();
|
||||
|
||||
listenOrientationEvent();
|
||||
|
||||
if (mCanAssumeUdfps) {
|
||||
final int rotation = getApplicationContext().getDisplay().getRotation();
|
||||
final boolean isPortrait = (rotation == Surface.ROTATION_0)
|
||||
|| (rotation == Surface.ROTATION_180);
|
||||
|
||||
final UdfpsEnrollEnrollingView layout =
|
||||
(UdfpsEnrollEnrollingView) getLayoutInflater().inflate(
|
||||
R.layout.udfps_enroll_enrolling, null, false);
|
||||
Flags.enrollLayoutTruncateImprovement()
|
||||
? R.layout.udfps_enroll_enrolling :
|
||||
R.layout.udfps_enroll_enrolling_non_scroll, null, false);
|
||||
setUdfpsEnrollHelper();
|
||||
layout.initView(props.get(0), mUdfpsEnrollHelper, mAccessibilityManager);
|
||||
|
||||
setContentView(layout);
|
||||
setDescriptionText(R.string.security_settings_udfps_enroll_start_message);
|
||||
|
||||
if (Flags.enrollLayoutTruncateImprovement() && isPortrait) {
|
||||
final UdfpsEnrollEnrollingView layoutView = (UdfpsEnrollEnrollingView) getLayout();
|
||||
if (layoutView != null) {
|
||||
final ScrollView headerScrollView = layout.findViewById(
|
||||
R.id.sud_header_scroll_view);
|
||||
if (headerScrollView != null) {
|
||||
final long headerScrollDuration = getResources().getInteger(
|
||||
R.integer.config_biometrics_header_scroll_duration);
|
||||
layoutView.adjustScrollableHeaderHeight(
|
||||
headerScrollView, mShouldShowLottie);
|
||||
layoutView.headerVerticalScrolling(headerScrollView, headerScrollDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (mCanAssumeSfps) {
|
||||
mSfpsEnrollmentFeature = FeatureFactory.getFeatureFactory()
|
||||
.getFingerprintFeatureProvider().getSfpsEnrollmentFeature();
|
||||
@@ -1199,6 +1221,24 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasWindowFocus) {
|
||||
super.onWindowFocusChanged(hasWindowFocus);
|
||||
if (Flags.enrollLayoutTruncateImprovement()) {
|
||||
adjustEnrollViewIfOverlappedWithFooterBar();
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustEnrollViewIfOverlappedWithFooterBar() {
|
||||
if (mCanAssumeUdfps) {
|
||||
final UdfpsEnrollEnrollingView layoutView = (UdfpsEnrollEnrollingView) getLayout();
|
||||
if (layoutView != null) {
|
||||
layoutView.adjustUdfpsVieWithFooterBar();
|
||||
layoutView.onUdfpsSensorRectUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class IconTouchDialog extends InstrumentedDialogFragment {
|
||||
|
||||
@Override
|
||||
|
@@ -16,27 +16,42 @@
|
||||
|
||||
package com.android.settings.biometrics.fingerprint;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.systemui.biometrics.UdfpsUtils;
|
||||
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
|
||||
|
||||
@@ -50,6 +65,7 @@ import java.util.Locale;
|
||||
* View for udfps enrolling.
|
||||
*/
|
||||
public class UdfpsEnrollEnrollingView extends GlifLayout {
|
||||
|
||||
private final UdfpsUtils mUdfpsUtils;
|
||||
private final Context mContext;
|
||||
// We don't need to listen to onConfigurationChanged() for mRotation here because
|
||||
@@ -57,14 +73,19 @@ public class UdfpsEnrollEnrollingView extends GlifLayout {
|
||||
private final int mRotation;
|
||||
private final boolean mIsLandscape;
|
||||
private final boolean mShouldUseReverseLandscape;
|
||||
|
||||
private WindowManager mWindowManager;
|
||||
|
||||
private UdfpsEnrollView mUdfpsEnrollView;
|
||||
private View mHeaderView;
|
||||
private AccessibilityManager mAccessibilityManager;
|
||||
|
||||
private ObjectAnimator mHeaderScrollAnimator;
|
||||
|
||||
public UdfpsEnrollEnrollingView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
mRotation = mContext.getDisplay().getRotation();
|
||||
mIsLandscape = mRotation == Surface.ROTATION_90 || mRotation == Surface.ROTATION_270;
|
||||
final boolean isLayoutRtl = (TextUtils.getLayoutDirectionFromLocale(Locale.getDefault())
|
||||
@@ -82,6 +103,139 @@ public class UdfpsEnrollEnrollingView extends GlifLayout {
|
||||
mUdfpsEnrollView = findViewById(R.id.udfps_animation_view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View onInflateTemplate(LayoutInflater inflater, @LayoutRes int template) {
|
||||
final Configuration config = inflater.getContext().getResources().getConfiguration();
|
||||
if (Flags.enrollLayoutTruncateImprovement()
|
||||
&& config.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
template = R.layout.biometrics_glif_compact;
|
||||
}
|
||||
return super.onInflateTemplate(inflater, template);
|
||||
}
|
||||
|
||||
void setDecreasePadding(int decreasePadding) {
|
||||
if (mUdfpsEnrollView != null) {
|
||||
mUdfpsEnrollView.setDecreasePadding(decreasePadding);
|
||||
}
|
||||
}
|
||||
|
||||
void onUdfpsSensorRectUpdated() {
|
||||
if (mUdfpsEnrollView != null) {
|
||||
mUdfpsEnrollView.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private int getScrollableGlifHeaderHeight(boolean isShouldShowLottie) {
|
||||
final TypedValue tvRatio = new TypedValue();
|
||||
if (isLargeDisplaySizeOrFontSize() && !isShouldShowLottie) {
|
||||
getResources().getValue(
|
||||
R.dimen.biometrics_glif_header_height_ratio_large, tvRatio, true);
|
||||
} else {
|
||||
getResources().getValue(R.dimen.biometrics_glif_header_height_ratio, tvRatio, true);
|
||||
}
|
||||
final float newHeaderHeight = (float) getResources().getDisplayMetrics().heightPixels
|
||||
* tvRatio.getFloat();
|
||||
|
||||
return (int) newHeaderHeight;
|
||||
}
|
||||
|
||||
void adjustScrollableHeaderHeight(ScrollView headerScrollView, boolean isShouldShowLottie) {
|
||||
ViewGroup.LayoutParams params = headerScrollView.getLayoutParams();
|
||||
params.height = getScrollableGlifHeaderHeight(isShouldShowLottie);
|
||||
headerScrollView.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private boolean isLargeDisplaySizeOrFontSize() {
|
||||
final Configuration config = getResources().getConfiguration();
|
||||
if (config.fontScale > 1.3f || getLargeDisplayScale() >= 2.8f) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private float getLargeDisplayScale() {
|
||||
final Display display = mWindowManager.getDefaultDisplay();
|
||||
final DisplayMetrics metrics = new DisplayMetrics();
|
||||
display.getMetrics(metrics);
|
||||
return metrics.scaledDensity;
|
||||
}
|
||||
|
||||
void adjustUdfpsVieWithFooterBar() {
|
||||
final FrameLayout allContent = findViewById(R.id.suc_layout_status);
|
||||
final ImageView udfpsProgressView = findViewById(
|
||||
R.id.udfps_enroll_animation_fp_progress_view);
|
||||
|
||||
final int navigationBarHeight = getNaviBarHeight();
|
||||
final int footerBarHeight = getFooterBarHeight();
|
||||
|
||||
final int udfpsProgressDrawableBottom = getOnScreenPositionTop(udfpsProgressView)
|
||||
+ udfpsProgressView.getDrawable().getBounds().height()
|
||||
- udfpsProgressView.getPaddingBottom() + 2 /* reserved for more space */;
|
||||
final int footerBarTop = getOnScreenPositionTop(allContent) + allContent.getHeight()
|
||||
- (footerBarHeight + navigationBarHeight);
|
||||
|
||||
if (udfpsProgressDrawableBottom > footerBarTop) {
|
||||
int adjustPadding = udfpsProgressDrawableBottom - footerBarTop;
|
||||
setDecreasePadding(adjustPadding);
|
||||
}
|
||||
}
|
||||
|
||||
private int getOnScreenPositionTop(View view) {
|
||||
int [] location = new int[2];
|
||||
view.getLocationOnScreen(location);
|
||||
return location[1];
|
||||
}
|
||||
|
||||
private int getNaviBarHeight() {
|
||||
final Insets inset = mWindowManager.getMaximumWindowMetrics().getWindowInsets().getInsets(
|
||||
WindowInsets.Type.navigationBars());
|
||||
return inset.toRect().height();
|
||||
}
|
||||
|
||||
private int getFooterBarHeight() {
|
||||
TypedArray a = mContext.getTheme().obtainStyledAttributes(new int[] {
|
||||
com.google.android.setupcompat.R.attr.sucFooterBarMinHeight});
|
||||
final int footerBarMinHeight = a.getDimensionPixelSize(0, -1);
|
||||
a.recycle();
|
||||
return footerBarMinHeight;
|
||||
}
|
||||
|
||||
void headerVerticalScrolling(ScrollView headerScrollView, long duration) {
|
||||
headerScrollView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final int maxScroll = headerScrollView.getChildAt(0).getMeasuredHeight()
|
||||
- headerScrollView.getMeasuredHeight();
|
||||
mHeaderScrollAnimator = ObjectAnimator.ofInt(
|
||||
headerScrollView, "scrollY", maxScroll);
|
||||
mHeaderScrollAnimator.setDuration(duration);
|
||||
mHeaderScrollAnimator.addListener(new Animator.AnimatorListener() {
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(@NonNull Animator animation) {}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(@NonNull Animator animation) {
|
||||
mHeaderScrollAnimator.removeAllListeners();
|
||||
headerScrollView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mHeaderScrollAnimator.reverse();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(@NonNull Animator animation) {}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(@NonNull Animator animation) {}
|
||||
});
|
||||
mHeaderScrollAnimator.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void initView(FingerprintSensorPropertiesInternal udfpsProps,
|
||||
UdfpsEnrollHelper udfpsEnrollHelper,
|
||||
AccessibilityManager accessibilityManager) {
|
||||
@@ -93,7 +247,7 @@ public class UdfpsEnrollEnrollingView extends GlifLayout {
|
||||
} else if (mShouldUseReverseLandscape) {
|
||||
swapHeaderAndContent();
|
||||
}
|
||||
mUdfpsEnrollView.setVisibility(View.VISIBLE);
|
||||
mUdfpsEnrollView.setVisibility(View.INVISIBLE);
|
||||
setOnHoverListener();
|
||||
}
|
||||
|
||||
@@ -166,17 +320,6 @@ public class UdfpsEnrollEnrollingView extends GlifLayout {
|
||||
R.id.udfps_enroll_animation_fp_view);
|
||||
fingerprintView.setPadding(0, -layoutLottieAnimationPadding,
|
||||
0, layoutLottieAnimationPadding);
|
||||
|
||||
// TODO(b/260970216) Instead of hiding the description text view, we should
|
||||
// make the header view scrollable if the text is too long.
|
||||
// If description text view has overlap with udfps progress view, hide it.
|
||||
final View descView = getDescriptionTextView();
|
||||
getViewTreeObserver().addOnDrawListener(() -> {
|
||||
if (descView.getVisibility() == View.VISIBLE
|
||||
&& hasOverlap(descView, mUdfpsEnrollView)) {
|
||||
descView.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setOnHoverListener() {
|
||||
|
@@ -133,6 +133,15 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li
|
||||
enrollHelper.setListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust progress bar radius only for decreasing.
|
||||
* @param decreasePadding the decrease padding
|
||||
*/
|
||||
void setDecreasePadding(int decreasePadding) {
|
||||
mProgressBarRadius -= decreasePadding;
|
||||
onSensorRectUpdated();
|
||||
}
|
||||
|
||||
private void onSensorRectUpdated() {
|
||||
updateDimensions();
|
||||
|
||||
|
24
tests/robotests/res/layout/test_udfps_enroll_enrolling.xml
Normal file
24
tests/robotests/res/layout/test_udfps_enroll_enrolling.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2024 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.
|
||||
-->
|
||||
|
||||
<com.android.settings.biometrics.fingerprint.TestUdfpsEnrollEnrollingView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/test_setup_wizard_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.settings.biometrics.fingerprint;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.google.android.setupdesign.GlifLayout;
|
||||
|
||||
public class TestUdfpsEnrollEnrollingView extends GlifLayout {
|
||||
public TestUdfpsEnrollEnrollingView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View onInflateTemplate(LayoutInflater inflater, @LayoutRes int template) {
|
||||
return super.onInflateTemplate(inflater, R.layout.biometrics_glif_compact);
|
||||
}
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.settings.biometrics.fingerprint;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.platform.test.annotations.EnableFlags;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.annotation.LooperMode;
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@LooperMode(LooperMode.Mode.LEGACY)
|
||||
public class UdfpsEnrollEnrollingViewTest {
|
||||
|
||||
private Context mThemeContext;
|
||||
private TestFingerprintEnrollEnrolling mFingerprintEnrollEnrolling;
|
||||
private ActivityController<UdfpsEnrollEnrollingViewTest.TestFingerprintEnrollEnrolling>
|
||||
mController;
|
||||
private AttributeSet mAttributeSet;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mController = Robolectric.buildActivity(TestFingerprintEnrollEnrolling.class);
|
||||
mFingerprintEnrollEnrolling = mController.create().get();
|
||||
mThemeContext = new ContextThemeWrapper(mFingerprintEnrollEnrolling,
|
||||
R.style.SudThemeGlif_Light);
|
||||
mAttributeSet = Robolectric.buildAttributeSet().build();
|
||||
}
|
||||
|
||||
private void assertDefaultTemplate(TestUdfpsEnrollEnrollingView layout) {
|
||||
final View title = layout.findViewById(
|
||||
com.google.android.setupdesign.R.id.suc_layout_title);
|
||||
assertThat(title).isNotNull();
|
||||
|
||||
final View subTitle = layout.findViewById(
|
||||
com.google.android.setupdesign.R.id.sud_layout_subtitle);
|
||||
assertThat(subTitle).isNotNull();
|
||||
|
||||
final View icon = layout.findViewById(com.google.android.setupdesign.R.id.sud_layout_icon);
|
||||
assertThat(icon).isNotNull();
|
||||
|
||||
final View scrollView = layout.findViewById(
|
||||
com.google.android.setupdesign.R.id.sud_scroll_view);
|
||||
assertThat(scrollView).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENROLL_LAYOUT_TRUNCATE_IMPROVEMENT)
|
||||
public void testDefaultTemplate() {
|
||||
TestUdfpsEnrollEnrollingView layout = new TestUdfpsEnrollEnrollingView(mThemeContext,
|
||||
mAttributeSet);
|
||||
assertDefaultTemplate(layout);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENROLL_LAYOUT_TRUNCATE_IMPROVEMENT)
|
||||
public void testGlifHeaderScrollView() {
|
||||
TestUdfpsEnrollEnrollingView layout = new TestUdfpsEnrollEnrollingView(mThemeContext,
|
||||
mAttributeSet);
|
||||
final View headerScrollView = layout.findViewById(
|
||||
R.id.sud_header_scroll_view);
|
||||
|
||||
assertThat(headerScrollView).isNotNull();
|
||||
}
|
||||
|
||||
public static class TestFingerprintEnrollEnrolling extends FingerprintEnrollEnrolling {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
final TestUdfpsEnrollEnrollingView layout =
|
||||
(TestUdfpsEnrollEnrollingView) getLayoutInflater().inflate(
|
||||
R.layout.test_udfps_enroll_enrolling, null, false);
|
||||
setContentView(layout);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user