1 /*
2  * Copyright (C) 2015 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.biometrics.fingerprint;
18 
19 import android.app.settings.SettingsEnums;
20 import android.content.ComponentName;
21 import android.content.Intent;
22 import android.content.pm.PackageManager;
23 import android.hardware.fingerprint.FingerprintManager;
24 import android.os.Bundle;
25 import android.util.Log;
26 import android.view.View;
27 
28 import androidx.annotation.VisibleForTesting;
29 
30 import com.android.settings.R;
31 import com.android.settings.Utils;
32 import com.android.settings.biometrics.BiometricEnrollBase;
33 import com.android.settings.password.ChooseLockSettingsHelper;
34 
35 import com.google.android.setupcompat.template.FooterBarMixin;
36 import com.google.android.setupcompat.template.FooterButton;
37 import com.google.android.setupcompat.util.WizardManagerHelper;
38 
39 /**
40  * Activity which concludes fingerprint enrollment.
41  */
42 public class FingerprintEnrollFinish extends BiometricEnrollBase {
43 
44     private static final String TAG = "FingerprintEnrollFinish";
45     private static final String ACTION_FINGERPRINT_SETTINGS =
46             "android.settings.FINGERPRINT_SETTINGS";
47     @VisibleForTesting
48     static final int REQUEST_ADD_ANOTHER = 1;
49     @VisibleForTesting
50     static final String FINGERPRINT_SUGGESTION_ACTIVITY =
51             "com.android.settings.SetupFingerprintSuggestionActivity";
52 
53     @Override
onCreate(Bundle savedInstanceState)54     protected void onCreate(Bundle savedInstanceState) {
55         super.onCreate(savedInstanceState);
56         setContentView(R.layout.fingerprint_enroll_finish);
57         setHeaderText(R.string.security_settings_fingerprint_enroll_finish_title);
58 
59         mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class);
60         mFooterBarMixin.setSecondaryButton(
61                 new FooterButton.Builder(this)
62                         .setText(R.string.fingerprint_enroll_button_add)
63                         .setButtonType(FooterButton.ButtonType.SKIP)
64                         .setTheme(R.style.SudGlifButton_Secondary)
65                         .build()
66         );
67 
68         mFooterBarMixin.setPrimaryButton(
69                 new FooterButton.Builder(this)
70                         .setText(R.string.security_settings_fingerprint_enroll_done)
71                         .setListener(this::onNextButtonClick)
72                         .setButtonType(FooterButton.ButtonType.NEXT)
73                         .setTheme(R.style.SudGlifButton_Primary)
74                         .build()
75         );
76     }
77 
78     @Override
onBackPressed()79     public void onBackPressed() {
80         super.onBackPressed();
81 
82         updateFingerprintSuggestionEnableState();
83     }
84 
85     @Override
onResume()86     protected void onResume() {
87         super.onResume();
88 
89         FooterButton addButton = mFooterBarMixin.getSecondaryButton();
90 
91         final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(this);
92         boolean hideAddAnother = false;
93         if (fpm != null) {
94             int enrolled = fpm.getEnrolledFingerprints(mUserId).size();
95             int max = getResources().getInteger(
96                     com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
97             hideAddAnother = enrolled >= max;
98         }
99         if (hideAddAnother) {
100             // Don't show "Add" button if too many fingerprints already added
101             addButton.setVisibility(View.INVISIBLE);
102         } else {
103             addButton.setOnClickListener(this::onAddAnotherButtonClick);
104         }
105     }
106 
107     @Override
onNextButtonClick(View view)108     protected void onNextButtonClick(View view) {
109         updateFingerprintSuggestionEnableState();
110         setResult(RESULT_FINISHED);
111         if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
112             postEnroll();
113         } else if (mFromSettingsSummary) {
114             // Only launch fingerprint settings if enrollment was triggered through settings summary
115             launchFingerprintSettings();
116         }
117         finish();
118     }
119 
updateFingerprintSuggestionEnableState()120     private void updateFingerprintSuggestionEnableState() {
121         final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(this);
122         if (fpm != null) {
123             int enrolled = fpm.getEnrolledFingerprints(mUserId).size();
124 
125             // Only show "Add another fingerprint" if the user already enrolled one.
126             // "Add fingerprint" will be shown in the main flow if the user hasn't enrolled any
127             // fingerprints. If the user already added more than one fingerprint, they already know
128             // to add multiple fingerprints so we don't show the suggestion.
129             int flag = (enrolled == 1) ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
130                     : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
131 
132             ComponentName componentName = new ComponentName(getApplicationContext(),
133                     FINGERPRINT_SUGGESTION_ACTIVITY);
134             getPackageManager().setComponentEnabledSetting(
135                     componentName, flag, PackageManager.DONT_KILL_APP);
136             Log.d(TAG, FINGERPRINT_SUGGESTION_ACTIVITY + " enabled state = " + (enrolled == 1));
137         }
138     }
139 
postEnroll()140     private void postEnroll() {
141         final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(this);
142         if (fpm != null) {
143             int result = fpm.postEnroll();
144             if (result < 0) {
145                 Log.w(TAG, "postEnroll failed: result = " + result);
146             }
147         }
148     }
149 
launchFingerprintSettings()150     private void launchFingerprintSettings() {
151         final Intent intent = new Intent(ACTION_FINGERPRINT_SETTINGS);
152         intent.setPackage(Utils.SETTINGS_PACKAGE_NAME);
153         intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
154         intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
155         intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
156         startActivity(intent);
157     }
158 
onAddAnotherButtonClick(View view)159     private void onAddAnotherButtonClick(View view) {
160         startActivityForResult(getFingerprintEnrollingIntent(), REQUEST_ADD_ANOTHER);
161     }
162 
163     @Override
onActivityResult(int requestCode, int resultCode, Intent data)164     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
165         updateFingerprintSuggestionEnableState();
166         if (requestCode == REQUEST_ADD_ANOTHER && resultCode != RESULT_CANCELED) {
167             setResult(resultCode, data);
168             finish();
169         } else {
170             super.onActivityResult(requestCode, resultCode, data);
171         }
172     }
173 
174     @Override
getMetricsCategory()175     public int getMetricsCategory() {
176         return SettingsEnums.FINGERPRINT_ENROLL_FINISH;
177     }
178 }
179