1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.settings.homepage.contextualcards;
18 
19 
20 import android.content.Context;
21 import android.content.DialogInterface;
22 import android.content.Intent;
23 import android.hardware.face.Face;
24 import android.hardware.face.FaceManager;
25 import android.os.Bundle;
26 import android.provider.Settings;
27 import android.util.Log;
28 
29 import com.android.internal.app.AlertActivity;
30 import com.android.internal.app.AlertController;
31 import com.android.settings.R;
32 import com.android.settings.Utils;
33 import com.android.settings.homepage.contextualcards.slices.FaceSetupSlice;
34 
35 /**
36  * This class is used to show a popup dialog for {@link FaceSetupSlice}.
37  */
38 public class FaceReEnrollDialog extends AlertActivity implements
39         DialogInterface.OnClickListener {
40 
41     private static final String TAG = "FaceReEnrollDialog";
42 
43     private static final String BIOMETRIC_ENROLL_ACTION = "android.settings.BIOMETRIC_ENROLL";
44 
45     private FaceManager mFaceManager;
46     /**
47      * The type of re-enrollment that has been requested,
48      * see {@link Settings.Secure#FACE_UNLOCK_RE_ENROLL} for more details.
49      */
50     private int mReEnrollType;
51 
52     @Override
onCreate(Bundle savedInstanceState)53     protected void onCreate(Bundle savedInstanceState) {
54         super.onCreate(savedInstanceState);
55 
56         final AlertController.AlertParams alertParams = mAlertParams;
57         alertParams.mTitle = getText(
58                 R.string.security_settings_face_enroll_improve_face_alert_title);
59         alertParams.mMessage = getText(
60                 R.string.security_settings_face_enroll_improve_face_alert_body);
61         alertParams.mPositiveButtonText = getText(R.string.storage_menu_set_up);
62         alertParams.mNegativeButtonText = getText(R.string.cancel);
63         alertParams.mPositiveButtonListener = this;
64 
65         mFaceManager = Utils.getFaceManagerOrNull(getApplicationContext());
66 
67         final Context context = getApplicationContext();
68         mReEnrollType = FaceSetupSlice.getReEnrollSetting(context, getUserId());
69 
70         Log.d(TAG, "ReEnroll Type : " + mReEnrollType);
71         if (mReEnrollType == FaceSetupSlice.FACE_RE_ENROLL_SUGGESTED) {
72             // setupAlert will actually display the popup dialog.
73             setupAlert();
74         } else if (mReEnrollType == FaceSetupSlice.FACE_RE_ENROLL_REQUIRED) {
75             // in this case we are skipping the popup dialog and directly going to the
76             // re enrollment flow. A grey overlay will appear to indicate that we are
77             // transitioning.
78             removeFaceAndReEnroll();
79         } else {
80             Log.d(TAG, "Error unsupported flow for : " + mReEnrollType);
81             dismiss();
82         }
83     }
84 
85     @Override
onClick(DialogInterface dialog, int which)86     public void onClick(DialogInterface dialog, int which) {
87         removeFaceAndReEnroll();
88     }
89 
removeFaceAndReEnroll()90     public void removeFaceAndReEnroll() {
91         final int userId = getUserId();
92         if (mFaceManager == null || !mFaceManager.hasEnrolledTemplates(userId)) {
93             finish();
94         }
95         mFaceManager.remove(new Face("", 0, 0), userId, new FaceManager.RemovalCallback() {
96             @Override
97             public void onRemovalError(Face face, int errMsgId, CharSequence errString) {
98                 super.onRemovalError(face, errMsgId, errString);
99                 finish();
100             }
101 
102             @Override
103             public void onRemovalSucceeded(Face face, int remaining) {
104                 super.onRemovalSucceeded(face, remaining);
105                 if (remaining != 0) {
106                     return;
107                 }
108                 // Send user to the enroll flow.
109                 final Intent reEnroll = new Intent(BIOMETRIC_ENROLL_ACTION);
110                 final Context context = getApplicationContext();
111 
112                 try {
113                     startActivity(reEnroll);
114                 } catch (Exception e) {
115                     Log.e(TAG, "Failed to startActivity");
116                 }
117 
118                 finish();
119             }
120         });
121     }
122 }
123