Merge "Remote authenticator enrollment finish layout." into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
524643a6c8
48
res/layout/remote_auth_enroll_finish.xml
Normal file
48
res/layout/remote_auth_enroll_finish.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2023 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.setupdesign.GlifLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/setup_wizard_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:icon="@drawable/ic_lock"
|
||||
app:sucHeaderText="@string/security_settings_remoteauth_enroll_finish_title"
|
||||
app:sudDescriptionText="@string/security_settings_remoteauth_enroll_finish_description">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
style="@style/SudContentFrame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="@dimen/remoteauth_fragment_padding_horizontal">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/enroll_finish_animation"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:lottie_rawRes="@raw/remoteauth_enroll_finish_animation"
|
||||
app:lottie_loop="true"
|
||||
app:lottie_autoPlay="true" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.setupdesign.GlifLayout>
|
1
res/raw/remoteauth_enroll_finish_animation.json
Normal file
1
res/raw/remoteauth_enroll_finish_animation.json
Normal file
File diff suppressed because one or more lines are too long
@@ -169,6 +169,9 @@
|
||||
<item name="face_preview_scale" format="float" type="dimen">1.0</item>
|
||||
<dimen name="face_enroll_intro_illustration_margin_bottom">0dp</dimen>
|
||||
|
||||
<!-- RemoteAuth-->
|
||||
<dimen name="remoteauth_fragment_padding_horizontal">40dp</dimen>
|
||||
|
||||
<!-- Lock pattern view size, align sysui biometric_auth_pattern_view_size -->
|
||||
<dimen name="biometric_auth_pattern_view_size">348dp</dimen>
|
||||
<dimen name="biometric_auth_pattern_view_max_size">@dimen/biometric_auth_pattern_view_size</dimen>
|
||||
|
@@ -884,6 +884,20 @@
|
||||
<!-- Message showing that multiple fingerprints, face, and the current watch is set up. Shown for a menu item that launches fingerprint, face, and active unlock settings or enrollment. [CHAR LIMIT=80]-->
|
||||
<string name="security_settings_fingerprint_multiple_face_watch_preference_summary">Face, fingerprints, and <xliff:g id="watch" example="Dani's Watch">%s</xliff:g> added</string>
|
||||
|
||||
<!-- RemoteAuth unlock enrollment and settings --><skip />
|
||||
<!-- Strings for RemoteAuth enroll finish page -->
|
||||
<!-- Title of the dialog that shows when a paired watch has been set up successfully and can be used to unlock the phone [CHAR_LIMIT=45] -->
|
||||
<string name="security_settings_remoteauth_enroll_finish_title">
|
||||
You\'re all set!
|
||||
</string>
|
||||
<!-- Explains when a paired watch can be used to unlock the phone after it has been set up successfully [CHAR_LIMIT=NONE] -->
|
||||
<string name="security_settings_remoteauth_enroll_finish_description">
|
||||
You can now use your watch to unlock this phone when you swipe up on the lock screen or tap a notification
|
||||
</string>
|
||||
<!-- Button text to finish enrollment [CHAR LIMIT=30] -->
|
||||
<string name="security_settings_remoteauth_enroll_finish_btn_next">Done</string>
|
||||
|
||||
|
||||
<!-- Biometric settings --><skip />
|
||||
<!-- Title shown for menu item that launches biometric settings. [CHAR LIMIT=66] -->
|
||||
<string name="security_settings_biometric_preference_title">Fingerprint & Face Unlock</string>
|
||||
|
83
src/com/android/settings/remoteauth/RemoteAuthEnrollBase.kt
Normal file
83
src/com/android/settings/remoteauth/RemoteAuthEnrollBase.kt
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.remoteauth
|
||||
|
||||
import android.R
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
import com.android.settings.Utils
|
||||
import com.google.android.setupcompat.template.FooterBarMixin
|
||||
import com.google.android.setupcompat.template.FooterButton
|
||||
import com.google.android.setupdesign.GlifLayout
|
||||
|
||||
/**
|
||||
* Displays a content view with a sticky footer in the SetupDesign style. Implementations
|
||||
* must define a primary button, and an optional secondary button.
|
||||
*
|
||||
* A layout with a [GlifLayout] must be provided, along with the id of the [GlifLayout].
|
||||
*/
|
||||
abstract class RemoteAuthEnrollBase(
|
||||
@LayoutRes val layoutResId: Int,
|
||||
@IdRes private val glifLayoutId: Int
|
||||
) : Fragment(layoutResId) {
|
||||
protected val primaryFooterButton by lazy { initializePrimaryFooterButton() }
|
||||
protected val secondaryFooterButton by lazy { initializeSecondaryFooterButton() }
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
viewGroup: ViewGroup?,
|
||||
savedInstanceArgs: Bundle?
|
||||
) =
|
||||
super.onCreateView(inflater, viewGroup, savedInstanceArgs)!!.also { view ->
|
||||
initializeFooterbarMixin(view)
|
||||
}
|
||||
|
||||
protected fun getGlifLayout(view: View) = view.findViewById<GlifLayout>(glifLayoutId)
|
||||
|
||||
/**
|
||||
* Return a button will be used as the primary footer button.
|
||||
*/
|
||||
abstract fun initializePrimaryFooterButton(): FooterButton
|
||||
|
||||
/** If non-null, returned button will be used as the secondary footer button. */
|
||||
abstract fun initializeSecondaryFooterButton(): FooterButton?
|
||||
|
||||
private fun initializeFooterbarMixin(view: View) {
|
||||
val footerBarMixin = getGlifLayout(view).getMixin(FooterBarMixin::class.java)
|
||||
primaryFooterButton.also { footerBarMixin.primaryButton = it }
|
||||
secondaryFooterButton?.also { footerBarMixin.secondaryButton = it }
|
||||
footerBarMixin.getButtonContainer().setBackgroundColor(getBackgroundColor())
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
private fun getBackgroundColor(): Int {
|
||||
val stateList = Utils.getColorAttr(context, R.attr.windowBackground)
|
||||
return stateList?.defaultColor ?: Color.TRANSPARENT
|
||||
}
|
||||
|
||||
private companion object{
|
||||
const val TAG = "RemoteAuthEnrollBase"
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.remoteauth.finish
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
||||
import com.android.settings.R
|
||||
import com.android.settings.remoteauth.RemoteAuthEnrollBase
|
||||
import com.android.settingslib.widget.LottieColorUtils
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.google.android.setupcompat.template.FooterButton
|
||||
|
||||
/**
|
||||
* Displays the enrollment finish view.
|
||||
*/
|
||||
class RemoteAuthEnrollFinish :
|
||||
RemoteAuthEnrollBase(
|
||||
layoutResId = R.layout.remote_auth_enroll_finish,
|
||||
glifLayoutId = R.id.setup_wizard_layout,
|
||||
) {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
LottieColorUtils.applyDynamicColors(requireContext(), view.findViewById<LottieAnimationView>(R.id.enroll_finish_animation))
|
||||
}
|
||||
|
||||
override fun initializePrimaryFooterButton(): FooterButton {
|
||||
return FooterButton.Builder(requireContext())
|
||||
.setText(R.string.security_settings_remoteauth_enroll_finish_btn_next)
|
||||
.setListener(this::onPrimaryFooterButtonClick)
|
||||
.setButtonType(FooterButton.ButtonType.NEXT)
|
||||
.setTheme(R.style.SudGlifButton_Primary)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun initializeSecondaryFooterButton(): FooterButton? = null
|
||||
|
||||
fun onPrimaryFooterButtonClick(view: View) {
|
||||
// TODO(b/293906345): Wire up navigation
|
||||
}
|
||||
|
||||
private companion object{
|
||||
const val TAG = "RemoteAuthEnrollFinish"
|
||||
}
|
||||
}
|
@@ -32,6 +32,7 @@ android_app {
|
||||
"androidx.core_core",
|
||||
"androidx.appcompat_appcompat",
|
||||
"androidx.cardview_cardview",
|
||||
"androidx.fragment_fragment-testing",
|
||||
"androidx.preference_preference",
|
||||
"androidx.recyclerview_recyclerview",
|
||||
"androidx.window_window",
|
||||
@@ -47,7 +48,7 @@ android_app {
|
||||
"jsr305",
|
||||
"settings-contextual-card-protos-lite",
|
||||
"settings-log-bridge-protos-lite",
|
||||
"settings-telephony-protos-lite",
|
||||
"settings-telephony-protos-lite",
|
||||
"contextualcards",
|
||||
"settings-logtags",
|
||||
"zxing-core-1.7",
|
||||
|
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.remoteauth.finish
|
||||
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.testing.launchFragmentInContainer
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.settings.R
|
||||
import com.google.android.setupdesign.GlifLayout
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class RemoteAuthEnrollFinishTest {
|
||||
private var mContext: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
@Test
|
||||
fun testRemoteAuthenticatorEnrollFinish_hasHeader() {
|
||||
launchFragmentInContainer<RemoteAuthEnrollFinish>(Bundle(), R.style.SudThemeGlif)
|
||||
.onFragment {
|
||||
assertThat((it.view as GlifLayout).headerText)
|
||||
.isEqualTo(mContext.getString(
|
||||
R.string.security_settings_remoteauth_enroll_finish_title))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRemoteAuthenticatorEnrollFinish_hasDescription() {
|
||||
launchFragmentInContainer<RemoteAuthEnrollFinish>(Bundle(), R.style.SudThemeGlif)
|
||||
.onFragment {
|
||||
assertThat((it.view as GlifLayout).descriptionText)
|
||||
.isEqualTo(mContext.getString(
|
||||
R.string.security_settings_remoteauth_enroll_finish_description))
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user