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.content.pm.PackageManager;
24 import android.hardware.face.Face;
25 import android.hardware.face.FaceManager;
26 import android.os.Bundle;
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.biometrics.face.FaceUpdater;
34 import com.android.settings.homepage.contextualcards.slices.FaceSetupSlice;
35 
36 /**
37  * This class is used to show a popup dialog for {@link FaceSetupSlice}.
38  */
39 public class FaceReEnrollDialog extends AlertActivity implements
40         DialogInterface.OnClickListener {
41 
42     private static final String TAG = "FaceReEnrollDialog";
43 
44     private static final String BIOMETRIC_ENROLL_ACTION = "android.settings.BIOMETRIC_ENROLL";
45 
46     private FaceManager mFaceManager;
47     private FaceUpdater mFaceUpdater;
48     /**
49      * The type of re-enrollment that has been requested,
50      * see {@link Settings.Secure#FACE_UNLOCK_RE_ENROLL} for more details.
51      */
52     private int mReEnrollType;
53 
54     @Override
onCreate(Bundle savedInstanceState)55     protected void onCreate(Bundle savedInstanceState) {
56         super.onCreate(savedInstanceState);
57 
58         final PackageManager pm = getApplicationContext().getPackageManager();
59         final int dialogMessageRes = pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
60                 ? R.string.security_settings_face_enroll_improve_face_alert_body_fingerprint
61                 : R.string.security_settings_face_enroll_improve_face_alert_body;
62 
63         final AlertController.AlertParams alertParams = mAlertParams;
64         alertParams.mTitle = getText(
65                 R.string.security_settings_face_enroll_improve_face_alert_title);
66         alertParams.mMessage = getText(dialogMessageRes);
67         alertParams.mPositiveButtonText = getText(R.string.storage_menu_set_up);
68         alertParams.mNegativeButtonText = getText(R.string.cancel);
69         alertParams.mPositiveButtonListener = this;
70 
71         mFaceManager = Utils.getFaceManagerOrNull(getApplicationContext());
72         mFaceUpdater = new FaceUpdater(getApplicationContext(), mFaceManager);
73 
74         final Context context = getApplicationContext();
75         mReEnrollType = FaceSetupSlice.getReEnrollSetting(context, getUserId());
76 
77         Log.d(TAG, "ReEnroll Type : " + mReEnrollType);
78         if (mReEnrollType == FaceSetupSlice.FACE_RE_ENROLL_SUGGESTED) {
79             // setupAlert will actually display the popup dialog.
80             setupAlert();
81         } else if (mReEnrollType == FaceSetupSlice.FACE_RE_ENROLL_REQUIRED) {
82             // in this case we are skipping the popup dialog and directly going to the
83             // re enrollment flow. A grey overlay will appear to indicate that we are
84             // transitioning.
85             removeFaceAndReEnroll();
86         } else {
87             Log.d(TAG, "Error unsupported flow for : " + mReEnrollType);
88             dismiss();
89         }
90     }
91 
92     @Override
onClick(DialogInterface dialog, int which)93     public void onClick(DialogInterface dialog, int which) {
94         removeFaceAndReEnroll();
95     }
96 
removeFaceAndReEnroll()97     public void removeFaceAndReEnroll() {
98         final int userId = getUserId();
99         if (mFaceManager == null || !mFaceManager.hasEnrolledTemplates(userId)) {
100             finish();
101         }
102         mFaceUpdater.remove(new Face("", 0, 0), userId, new FaceManager.RemovalCallback() {
103             @Override
104             public void onRemovalError(Face face, int errMsgId, CharSequence errString) {
105                 super.onRemovalError(face, errMsgId, errString);
106                 finish();
107             }
108 
109             @Override
110             public void onRemovalSucceeded(Face face, int remaining) {
111                 super.onRemovalSucceeded(face, remaining);
112                 if (remaining != 0) {
113                     return;
114                 }
115                 // Send user to the enroll flow.
116                 final Intent reEnroll = new Intent(BIOMETRIC_ENROLL_ACTION)
117                         .setPackage(getPackageName());
118 
119                 try {
120                     startActivity(reEnroll);
121                 } catch (Exception e) {
122                     Log.e(TAG, "Failed to startActivity");
123                 }
124 
125                 finish();
126             }
127         });
128     }
129 }
130