(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:
Jason Chang
2024-08-28 18:52:19 +00:00
parent c0c9592660
commit e4623cd2a3
13 changed files with 631 additions and 56 deletions

View File

@@ -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"

View 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>

View 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>

View File

@@ -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>

View 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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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() {

View File

@@ -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();

View 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"/>

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}