Added different flow for re-enrollment
am: bba7632f28
Change-Id: Ie5174848a3a35df197177b0aa2cf6c324813b8dd
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.homepage.contextualcards;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.app.AlertActivity;
|
||||
import com.android.internal.app.AlertController;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.homepage.contextualcards.slices.FaceSetupSlice;
|
||||
|
||||
/**
|
||||
* This class is used to show a popup dialog for {@link FaceSetupSlice}.
|
||||
*/
|
||||
public class FaceReEnrollDialog extends AlertActivity implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
private static final String TAG = "FaceReEnrollDialog";
|
||||
|
||||
private static final String BIOMETRIC_ENROLL_ACTION = "android.settings.BIOMETRIC_ENROLL";
|
||||
|
||||
private FaceManager mFaceManager;
|
||||
/**
|
||||
* The type of re-enrollment that has been requested,
|
||||
* see {@link Settings.Secure#FACE_UNLOCK_RE_ENROLL} for more details.
|
||||
*/
|
||||
private int mReEnrollType;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final AlertController.AlertParams alertParams = mAlertParams;
|
||||
alertParams.mTitle = getText(
|
||||
R.string.security_settings_face_enroll_improve_face_alert_title);
|
||||
alertParams.mMessage = getText(
|
||||
R.string.security_settings_face_enroll_improve_face_alert_body);
|
||||
alertParams.mPositiveButtonText = getText(R.string.storage_menu_set_up);
|
||||
alertParams.mNegativeButtonText = getText(R.string.cancel);
|
||||
alertParams.mPositiveButtonListener = this;
|
||||
|
||||
mFaceManager = Utils.getFaceManagerOrNull(getApplicationContext());
|
||||
|
||||
final Context context = getApplicationContext();
|
||||
mReEnrollType = FaceSetupSlice.getReEnrollSetting(context, getUserId());
|
||||
|
||||
Log.d(TAG, "ReEnroll Type : " + mReEnrollType);
|
||||
if (mReEnrollType == FaceSetupSlice.FACE_RE_ENROLL_SUGGESTED) {
|
||||
// setupAlert will actually display the popup dialog.
|
||||
setupAlert();
|
||||
} else if (mReEnrollType == FaceSetupSlice.FACE_RE_ENROLL_REQUIRED) {
|
||||
// in this case we are skipping the popup dialog and directly going to the
|
||||
// re enrollment flow. A grey overlay will appear to indicate that we are
|
||||
// transitioning.
|
||||
removeFaceAndReEnroll();
|
||||
} else {
|
||||
Log.d(TAG, "Error unsupported flow for : " + mReEnrollType);
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
removeFaceAndReEnroll();
|
||||
}
|
||||
|
||||
public void removeFaceAndReEnroll() {
|
||||
final int userId = getUserId();
|
||||
if (mFaceManager == null || !mFaceManager.hasEnrolledTemplates(userId)) {
|
||||
finish();
|
||||
}
|
||||
mFaceManager.remove(new Face("", 0, 0), userId, new FaceManager.RemovalCallback() {
|
||||
@Override
|
||||
public void onRemovalError(Face face, int errMsgId, CharSequence errString) {
|
||||
super.onRemovalError(face, errMsgId, errString);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemovalSucceeded(Face face, int remaining) {
|
||||
super.onRemovalSucceeded(face, remaining);
|
||||
if (remaining != 0) {
|
||||
return;
|
||||
}
|
||||
// Send user to the enroll flow.
|
||||
final Intent reEnroll = new Intent(BIOMETRIC_ENROLL_ACTION);
|
||||
final Context context = getApplicationContext();
|
||||
|
||||
try {
|
||||
startActivity(reEnroll);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to startActivity");
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -17,17 +17,14 @@
|
||||
package com.android.settings.homepage.contextualcards.slices;
|
||||
|
||||
|
||||
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_SUCCESS;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.slice.Slice;
|
||||
@@ -39,14 +36,40 @@ import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.face.FaceStatusPreferenceController;
|
||||
import com.android.settings.homepage.contextualcards.FaceReEnrollDialog;
|
||||
import com.android.settings.security.SecuritySettings;
|
||||
import com.android.settings.slices.CustomSliceRegistry;
|
||||
import com.android.settings.slices.CustomSliceable;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
|
||||
/**
|
||||
* This class is used for showing re-enroll suggestions in the Settings page. By either having an
|
||||
* un-enrolled user or setting {@link Settings.Secure#FACE_UNLOCK_RE_ENROLL} to one of the
|
||||
* states listed in {@link Settings.Secure} the slice will change its text and potentially show
|
||||
* a {@link FaceReEnrollDialog}.
|
||||
*/
|
||||
public class FaceSetupSlice implements CustomSliceable {
|
||||
|
||||
private final Context mContext;
|
||||
/**
|
||||
* If a user currently is not enrolled then this class will show a recommendation to
|
||||
* enroll their face.
|
||||
*/
|
||||
private FaceManager mFaceManager;
|
||||
|
||||
/**
|
||||
* Various states the {@link FaceSetupSlice} can be in,
|
||||
* See {@link Settings.Secure#FACE_UNLOCK_RE_ENROLL} for more details.
|
||||
*/
|
||||
|
||||
// No re-enrollment.
|
||||
public static final int FACE_NO_RE_ENROLL_REQUIRED = 0;
|
||||
// Re enrollment is suggested.
|
||||
public static final int FACE_RE_ENROLL_SUGGESTED = 1;
|
||||
// Re enrollment is required after a set time period.
|
||||
public static final int FACE_RE_ENROLL_AFTER_TIMEOUT = 2;
|
||||
// Re enrollment is required immediately.
|
||||
public static final int FACE_RE_ENROLL_REQUIRED = 3;
|
||||
|
||||
public FaceSetupSlice(Context context) {
|
||||
mContext = context;
|
||||
@@ -54,21 +77,45 @@ public class FaceSetupSlice implements CustomSliceable {
|
||||
|
||||
@Override
|
||||
public Slice getSlice() {
|
||||
final FaceManager faceManager = Utils.getFaceManagerOrNull(mContext);
|
||||
if (faceManager == null || faceManager.hasEnrolledTemplates(UserHandle.myUserId())) {
|
||||
return null;
|
||||
mFaceManager = Utils.getFaceManagerOrNull(mContext);
|
||||
if (mFaceManager == null) {
|
||||
return new ListBuilder(mContext, CustomSliceRegistry.FACE_ENROLL_SLICE_URI,
|
||||
ListBuilder.INFINITY).setIsError(true).build();
|
||||
}
|
||||
|
||||
final int userId = UserHandle.myUserId();
|
||||
final boolean hasEnrolledTemplates = mFaceManager.hasEnrolledTemplates(userId);
|
||||
final int shouldReEnroll = FaceSetupSlice.getReEnrollSetting(mContext, userId);
|
||||
|
||||
CharSequence title = "";
|
||||
CharSequence subtitle = "";
|
||||
|
||||
// Set the title and subtitle according to the different states, the icon and layout will
|
||||
// stay the same.
|
||||
if (!hasEnrolledTemplates) {
|
||||
title = mContext.getText(R.string.security_settings_face_settings_enroll);
|
||||
subtitle = mContext.getText(
|
||||
R.string.security_settings_face_settings_context_subtitle);
|
||||
} else if (shouldReEnroll == FACE_RE_ENROLL_SUGGESTED) {
|
||||
title = mContext.getText(
|
||||
R.string.security_settings_face_enroll_should_re_enroll_title);
|
||||
subtitle = mContext.getText(
|
||||
R.string.security_settings_face_enroll_should_re_enroll_subtitle);
|
||||
} else if (shouldReEnroll == FACE_RE_ENROLL_REQUIRED) {
|
||||
title = mContext.getText(
|
||||
R.string.security_settings_face_enroll_must_re_enroll_title);
|
||||
subtitle = mContext.getText(
|
||||
R.string.security_settings_face_enroll_must_re_enroll_subtitle);
|
||||
} else {
|
||||
return new ListBuilder(mContext, CustomSliceRegistry.FACE_ENROLL_SLICE_URI,
|
||||
ListBuilder.INFINITY).setIsError(true).build();
|
||||
}
|
||||
|
||||
final CharSequence title = mContext.getText(
|
||||
R.string.security_settings_face_settings_enroll);
|
||||
final ListBuilder listBuilder = new ListBuilder(mContext,
|
||||
CustomSliceRegistry.FACE_ENROLL_SLICE_URI, ListBuilder.INFINITY)
|
||||
.setAccentColor(Utils.getColorAccentDefaultColor(mContext));
|
||||
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.ic_face_24dp);
|
||||
return listBuilder
|
||||
.addRow(buildRowBuilder(title,
|
||||
mContext.getText(R.string.security_settings_face_settings_context_subtitle),
|
||||
icon, mContext, getIntent()))
|
||||
return listBuilder.addRow(buildRowBuilder(title, subtitle, icon, mContext, getIntent()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -79,12 +126,18 @@ public class FaceSetupSlice implements CustomSliceable {
|
||||
|
||||
@Override
|
||||
public Intent getIntent() {
|
||||
return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
|
||||
SecuritySettings.class.getName(),
|
||||
FaceStatusPreferenceController.KEY_FACE_SETTINGS,
|
||||
mContext.getText(R.string.security_settings_face_settings_enroll).toString(),
|
||||
SettingsEnums.SLICE)
|
||||
.setClassName(mContext.getPackageName(), SubSettings.class.getName());
|
||||
final boolean hasEnrolledTemplates = mFaceManager.hasEnrolledTemplates(
|
||||
UserHandle.myUserId());
|
||||
if (!hasEnrolledTemplates) {
|
||||
return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
|
||||
SecuritySettings.class.getName(),
|
||||
FaceStatusPreferenceController.KEY_FACE_SETTINGS,
|
||||
mContext.getText(R.string.security_settings_face_settings_enroll).toString(),
|
||||
SettingsEnums.SLICE)
|
||||
.setClassName(mContext.getPackageName(), SubSettings.class.getName());
|
||||
} else {
|
||||
return new Intent(mContext, FaceReEnrollDialog.class);
|
||||
}
|
||||
}
|
||||
|
||||
private static RowBuilder buildRowBuilder(CharSequence title, CharSequence subTitle,
|
||||
@@ -98,4 +151,10 @@ public class FaceSetupSlice implements CustomSliceable {
|
||||
.setSubtitle(subTitle)
|
||||
.setPrimaryAction(primarySliceAction);
|
||||
}
|
||||
|
||||
public static int getReEnrollSetting(Context context, int userId) {
|
||||
return Settings.Secure.getIntForUser(context.getContentResolver(),
|
||||
Settings.Secure.FACE_UNLOCK_RE_ENROLL, FACE_NO_RE_ENROLL_REQUIRED, userId);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user