Merge "[Biometric Onboarding & Edu] Update Set up Face Unlock page" into main
This commit is contained in:
@@ -2830,6 +2830,12 @@
|
|||||||
android:screenOrientation="portrait"/>
|
android:screenOrientation="portrait"/>
|
||||||
|
|
||||||
<activity android:name=".biometrics.face.FaceEnrollIntroduction"
|
<activity android:name=".biometrics.face.FaceEnrollIntroduction"
|
||||||
|
android:exported="false"
|
||||||
|
android:theme="@style/GlifV4Theme.DayNight"
|
||||||
|
android:screenOrientation="nosensor">
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name=".biometrics.face.FaceEnroll"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@style/GlifV4Theme.DayNight"
|
android:theme="@style/GlifV4Theme.DayNight"
|
||||||
android:screenOrientation="nosensor">
|
android:screenOrientation="nosensor">
|
||||||
|
@@ -38,7 +38,7 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.Settings;
|
import com.android.settings.Settings;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.SubSettings;
|
import com.android.settings.SubSettings;
|
||||||
import com.android.settings.biometrics.face.FaceEnrollIntroduction;
|
import com.android.settings.biometrics.face.FaceEnrollActivityClassProvider;
|
||||||
import com.android.settings.biometrics.face.FaceEnrollIntroductionInternal;
|
import com.android.settings.biometrics.face.FaceEnrollIntroductionInternal;
|
||||||
import com.android.settings.biometrics.fingerprint.FingerprintEnrollActivityClassProvider;
|
import com.android.settings.biometrics.fingerprint.FingerprintEnrollActivityClassProvider;
|
||||||
import com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling;
|
import com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling;
|
||||||
@@ -254,6 +254,11 @@ public class ActivityEmbeddingRulesController {
|
|||||||
.buildSearchIntent(mContext, SettingsEnums.SETTINGS_HOMEPAGE);
|
.buildSearchIntent(mContext, SettingsEnums.SETTINGS_HOMEPAGE);
|
||||||
addActivityFilter(activityFilters, searchIntent);
|
addActivityFilter(activityFilters, searchIntent);
|
||||||
}
|
}
|
||||||
|
final FaceEnrollActivityClassProvider faceClassProvider = FeatureFactory
|
||||||
|
.getFeatureFactory()
|
||||||
|
.getFaceFeatureProvider()
|
||||||
|
.getEnrollActivityClassProvider();
|
||||||
|
addActivityFilter(activityFilters, faceClassProvider.getNext());
|
||||||
final FingerprintEnrollActivityClassProvider fpClassProvider = FeatureFactory
|
final FingerprintEnrollActivityClassProvider fpClassProvider = FeatureFactory
|
||||||
.getFeatureFactory()
|
.getFeatureFactory()
|
||||||
.getFingerprintFeatureProvider()
|
.getFingerprintFeatureProvider()
|
||||||
@@ -263,7 +268,6 @@ public class ActivityEmbeddingRulesController {
|
|||||||
addActivityFilter(activityFilters, fpClassProvider.getAddAnother());
|
addActivityFilter(activityFilters, fpClassProvider.getAddAnother());
|
||||||
addActivityFilter(activityFilters, FingerprintEnrollEnrolling.class);
|
addActivityFilter(activityFilters, FingerprintEnrollEnrolling.class);
|
||||||
addActivityFilter(activityFilters, FaceEnrollIntroductionInternal.class);
|
addActivityFilter(activityFilters, FaceEnrollIntroductionInternal.class);
|
||||||
addActivityFilter(activityFilters, FaceEnrollIntroduction.class);
|
|
||||||
addActivityFilter(activityFilters, RemoteAuthActivity.class);
|
addActivityFilter(activityFilters, RemoteAuthActivity.class);
|
||||||
addActivityFilter(activityFilters, RemoteAuthActivityInternal.class);
|
addActivityFilter(activityFilters, RemoteAuthActivityInternal.class);
|
||||||
addActivityFilter(activityFilters, ChooseLockPattern.class);
|
addActivityFilter(activityFilters, ChooseLockPattern.class);
|
||||||
|
@@ -71,7 +71,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
|||||||
private boolean mParentalConsentRequired;
|
private boolean mParentalConsentRequired;
|
||||||
private boolean mHasScrolledToBottom = false;
|
private boolean mHasScrolledToBottom = false;
|
||||||
|
|
||||||
@Nullable private PorterDuffColorFilter mIconColorFilter;
|
@Nullable protected PorterDuffColorFilter mIconColorFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the biometric is disabled by a device administrator
|
* @return true if the biometric is disabled by a device administrator
|
||||||
|
@@ -43,7 +43,6 @@ import com.android.internal.widget.LockPatternUtils;
|
|||||||
import com.android.internal.widget.VerifyCredentialResponse;
|
import com.android.internal.widget.VerifyCredentialResponse;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SetupWizardUtils;
|
import com.android.settings.SetupWizardUtils;
|
||||||
import com.android.settings.biometrics.face.FaceEnrollIntroduction;
|
|
||||||
import com.android.settings.biometrics.fingerprint.FingerprintEnroll;
|
import com.android.settings.biometrics.fingerprint.FingerprintEnroll;
|
||||||
import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor;
|
import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor;
|
||||||
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollFindSensor;
|
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollFindSensor;
|
||||||
@@ -281,7 +280,9 @@ public class BiometricUtils {
|
|||||||
*/
|
*/
|
||||||
public static Intent getFaceIntroIntent(@NonNull Context context,
|
public static Intent getFaceIntroIntent(@NonNull Context context,
|
||||||
@NonNull Intent activityIntent) {
|
@NonNull Intent activityIntent) {
|
||||||
final Intent intent = new Intent(context, FaceEnrollIntroduction.class);
|
final Intent intent = new Intent(context,
|
||||||
|
FeatureFactory.getFeatureFactory().getFaceFeatureProvider()
|
||||||
|
.getEnrollActivityClassProvider().getNext());
|
||||||
WizardManagerHelper.copyWizardManagerExtras(activityIntent, intent);
|
WizardManagerHelper.copyWizardManagerExtras(activityIntent, intent);
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
54
src/com/android/settings/biometrics/face/FaceEnroll.kt
Normal file
54
src/com/android/settings/biometrics/face/FaceEnroll.kt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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.face
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|
||||||
|
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
|
||||||
|
|
||||||
|
class FaceEnroll: AppCompatActivity() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class of the next activity to launch. This is open to allow subclasses to provide their
|
||||||
|
* own behavior. Defaults to the default activity class provided by the
|
||||||
|
* enrollActivityClassProvider.
|
||||||
|
*/
|
||||||
|
private val nextActivityClass: Class<*>
|
||||||
|
get() = enrollActivityProvider.next
|
||||||
|
|
||||||
|
private val enrollActivityProvider: FaceEnrollActivityClassProvider
|
||||||
|
get() = featureFactory.faceFeatureProvider.enrollActivityClassProvider
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the next activity to be launched, creates an intent for that activity,
|
||||||
|
* adds flags to forward the result, includes any existing extras from the current intent,
|
||||||
|
* starts the new activity and then finishes the current one
|
||||||
|
*/
|
||||||
|
Log.d("FaceEnroll", "forward to $nextActivityClass")
|
||||||
|
val nextIntent = Intent(this, nextActivityClass)
|
||||||
|
nextIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
|
||||||
|
nextIntent.putExtras(intent)
|
||||||
|
startActivity(nextIntent)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* 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.face
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
|
||||||
|
open class FaceEnrollActivityClassProvider {
|
||||||
|
open val next: Class<out Activity>
|
||||||
|
get() = FaceEnrollIntroduction::class.java
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
val instance = FaceEnrollActivityClassProvider()
|
||||||
|
}
|
||||||
|
}
|
@@ -625,7 +625,7 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
|
|||||||
updateDescriptionText();
|
updateDescriptionText();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPrivateProfile() {
|
protected boolean isPrivateProfile() {
|
||||||
return Utils.isPrivateProfile(mUserId, getApplicationContext());
|
return Utils.isPrivateProfile(mUserId, getApplicationContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,13 +16,13 @@
|
|||||||
|
|
||||||
package com.android.settings.biometrics.face;
|
package com.android.settings.biometrics.face;
|
||||||
|
|
||||||
import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper of {@link FaceEnrollIntroduction} to use with a pre-defined task affinity.
|
* Wrapper of {@link FaceEnrollIntroduction} to use with a pre-defined task affinity.
|
||||||
*
|
*
|
||||||
@@ -42,7 +42,9 @@ public class FaceEnrollIntroductionInternal extends FragmentActivity {
|
|||||||
trampoline.setFlags(0);
|
trampoline.setFlags(0);
|
||||||
|
|
||||||
// Trampoline to the intended activity, and finish
|
// Trampoline to the intended activity, and finish
|
||||||
trampoline.setClassName(SETTINGS_PACKAGE_NAME, FaceEnrollIntroduction.class.getName());
|
trampoline.setClass(getApplicationContext(),
|
||||||
|
FeatureFactory.getFeatureFactory().getFaceFeatureProvider()
|
||||||
|
.getEnrollActivityClassProvider().getNext());
|
||||||
startActivity(trampoline);
|
startActivity(trampoline);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ package com.android.settings.biometrics.face;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
/** Feature provider for face unlock */
|
/** Feature provider for face unlock */
|
||||||
@@ -32,4 +33,13 @@ public interface FaceFeatureProvider {
|
|||||||
|
|
||||||
/** Returns true if setup wizard supported face enrollment. */
|
/** Returns true if setup wizard supported face enrollment. */
|
||||||
boolean isSetupWizardSupported(Context context);
|
boolean isSetupWizardSupported(Context context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the provider for current face enrollment activity classes
|
||||||
|
* @return the provider
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
default FaceEnrollActivityClassProvider getEnrollActivityClassProvider() {
|
||||||
|
return FaceEnrollActivityClassProvider.getInstance();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.settings.biometrics.face;
|
package com.android.settings.biometrics.face;
|
||||||
|
|
||||||
import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
|
|
||||||
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -28,6 +26,7 @@ import androidx.preference.Preference;
|
|||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||||
import com.android.settingslib.widget.LayoutPreference;
|
import com.android.settingslib.widget.LayoutPreference;
|
||||||
@@ -83,7 +82,8 @@ public class FaceSettingsEnrollButtonPreferenceController extends BasePreference
|
|||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
mIsClicked = true;
|
mIsClicked = true;
|
||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent();
|
||||||
intent.setClassName(SETTINGS_PACKAGE_NAME, FaceEnrollIntroduction.class.getName());
|
intent.setClass(mContext, FeatureFactory.getFeatureFactory().getFaceFeatureProvider()
|
||||||
|
.getEnrollActivityClassProvider().getNext());
|
||||||
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
|
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
|
||||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
|
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
|
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2025 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.face
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
|
import com.android.settings.overlay.FeatureFactory
|
||||||
|
import com.android.settings.testutils.FakeFeatureFactory
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import com.google.common.truth.Truth
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.Mockito
|
||||||
|
import org.robolectric.Robolectric
|
||||||
|
import org.robolectric.RobolectricTestRunner
|
||||||
|
import org.robolectric.Shadows
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner::class)
|
||||||
|
class FaceEnrollTest {
|
||||||
|
private lateinit var featureFactory: FeatureFactory
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val INTENT_KEY = "testKey"
|
||||||
|
const val INTENT_VALUE = "testValue"
|
||||||
|
val INTENT = Intent().apply {
|
||||||
|
putExtra(INTENT_KEY, INTENT_VALUE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val activityProvider = FaceEnrollActivityClassProvider()
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
featureFactory = FakeFeatureFactory.setupForTest()
|
||||||
|
Mockito.`when`(featureFactory.faceFeatureProvider.enrollActivityClassProvider)
|
||||||
|
.thenReturn(activityProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupActivity(activityClass: Class<out FaceEnroll>): FaceEnroll {
|
||||||
|
return Robolectric.buildActivity(activityClass, INTENT).create().get()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFinishAndLaunchDefaultActivity() {
|
||||||
|
// Run
|
||||||
|
val activity = setupActivity(FaceEnroll::class.java)
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
verifyLaunchNextActivity(activity, activityProvider.next)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun verifyLaunchNextActivity(
|
||||||
|
currentActivityInstance : FaceEnroll,
|
||||||
|
nextActivityClass: Class<out Activity>
|
||||||
|
) {
|
||||||
|
Truth.assertThat(currentActivityInstance.isFinishing).isTrue()
|
||||||
|
val nextActivityIntent = Shadows.shadowOf(currentActivityInstance).nextStartedActivity
|
||||||
|
assertThat(nextActivityIntent.component!!.className).isEqualTo(nextActivityClass.name)
|
||||||
|
assertThat(nextActivityIntent.extras!!.size()).isEqualTo(1)
|
||||||
|
assertThat(nextActivityIntent.getStringExtra(INTENT_KEY)).isEqualTo(INTENT_VALUE)
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user