diff --git a/src/com/android/settings/biometrics2/data/repository/PackageManagerRepository.java b/src/com/android/settings/biometrics2/data/repository/PackageManagerRepository.java new file mode 100644 index 00000000000..ae00221a138 --- /dev/null +++ b/src/com/android/settings/biometrics2/data/repository/PackageManagerRepository.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 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.biometrics2.data.repository; + +import android.annotation.NonNull; +import android.content.ComponentName; +import android.content.pm.PackageManager; + +/** + * This repository is used to call all APIs in {@link PackageManager} + */ +public class PackageManagerRepository { + + private final PackageManager mPackageManager; + + public PackageManagerRepository(PackageManager packageManager) { + mPackageManager = packageManager; + } + + /** + * Set the enabled setting for a package component (activity, receiver, service, provider). + * This setting will override any enabled state which may have been set by the component in its + * manifest. + */ + public void setComponentEnabledSetting(@NonNull ComponentName componentName, + @PackageManager.EnabledState int newState, @PackageManager.EnabledFlags int flags) { + mPackageManager.setComponentEnabledSetting(componentName, newState, flags); + } +} diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollFinishFragment.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollFinishFragment.java new file mode 100644 index 00000000000..02aa5f280ca --- /dev/null +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollFinishFragment.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2023 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.biometrics2.ui.view; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.ViewModelProvider; + +import com.android.settings.R; +import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel; + +import com.google.android.setupcompat.template.FooterBarMixin; +import com.google.android.setupcompat.template.FooterButton; +import com.google.android.setupdesign.GlifLayout; + + +/** + * Fragment which concludes fingerprint enrollment. + */ +public class FingerprintEnrollFinishFragment extends Fragment { + + private static final String TAG = FingerprintEnrollFinishFragment.class.getSimpleName(); + + private FingerprintEnrollFinishViewModel mFingerprintEnrollFinishViewModel; + private boolean mCanAssumeSfps; + + private View mView; + private FooterBarMixin mFooterBarMixin; + + private final View.OnClickListener mAddButtonClickListener = + (v) -> mFingerprintEnrollFinishViewModel.onAddButtonClick(); + private final View.OnClickListener mNextButtonClickListener = + (v) -> mFingerprintEnrollFinishViewModel.onNextButtonClick(); + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + final FragmentActivity activity = getActivity(); + final ViewModelProvider provider = new ViewModelProvider(activity); + mFingerprintEnrollFinishViewModel = provider.get(FingerprintEnrollFinishViewModel.class); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mCanAssumeSfps = mFingerprintEnrollFinishViewModel.canAssumeSfps(); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + + if (mCanAssumeSfps) { + mView = inflater.inflate(R.layout.sfps_enroll_finish, container, false); + } else { + mView = inflater.inflate(R.layout.fingerprint_enroll_finish, container, false); + } + + final Activity activity = getActivity(); + final GlifLayoutHelper glifLayoutHelper = new GlifLayoutHelper(activity, + (GlifLayout) mView); + + glifLayoutHelper.setHeaderText(R.string.security_settings_fingerprint_enroll_finish_title); + glifLayoutHelper.setDescriptionText( + R.string.security_settings_fingerprint_enroll_finish_v2_message); + + final int maxEnrollments = mFingerprintEnrollFinishViewModel.getMaxFingerprints(); + final int enrolled = mFingerprintEnrollFinishViewModel.getNumOfEnrolledFingerprintsSize(); + if (mCanAssumeSfps) { + if (enrolled < maxEnrollments) { + glifLayoutHelper.setDescriptionText(R.string + .security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message); + } + } + + mFooterBarMixin = ((GlifLayout) mView).getMixin(FooterBarMixin.class); + mFooterBarMixin.setSecondaryButton( + new FooterButton.Builder(getActivity()) + .setText(R.string.fingerprint_enroll_button_add) + .setButtonType(FooterButton.ButtonType.SKIP) + .setTheme(R.style.SudGlifButton_Secondary) + .build() + ); + + mFooterBarMixin.setPrimaryButton( + new FooterButton.Builder(getActivity()) + .setText(R.string.security_settings_fingerprint_enroll_done) + .setListener(mNextButtonClickListener) + .setButtonType(FooterButton.ButtonType.NEXT) + .setTheme(R.style.SudGlifButton_Primary) + .build() + ); + + FooterButton addButton = mFooterBarMixin.getSecondaryButton(); + if (enrolled >= maxEnrollments) { + addButton.setVisibility(View.INVISIBLE); + } else { + addButton.setOnClickListener(mAddButtonClickListener); + } + + return mView; + } + +} diff --git a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFinishViewModel.java b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFinishViewModel.java new file mode 100644 index 00000000000..2cf0b4780cd --- /dev/null +++ b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFinishViewModel.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2023 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.biometrics2.ui.viewmodel; + + +import android.app.Application; +import android.content.ComponentName; +import android.content.pm.PackageManager; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.MutableLiveData; + +import com.android.settings.biometrics2.data.repository.FingerprintRepository; +import com.android.settings.biometrics2.data.repository.PackageManagerRepository; + +/** + * Finish ViewModel handles the state of the fingerprint renroll final stage + */ +public class FingerprintEnrollFinishViewModel extends AndroidViewModel { + + private static final String TAG = FingerprintEnrollFinishViewModel.class.getSimpleName(); + + private static final String FINGERPRINT_SUGGESTION_ACTIVITY = + "com.android.settings.SetupFingerprintSuggestionActivity"; + + private static final int ACTION_NONE = -1; + private static final int ACTION_ADD_BUTTON_CLICK = 0; + private static final int ACTION_NEXT_BUTTON_CLICK = 1; + + private final FingerprintRepository mFingerprintRepository; + private final PackageManagerRepository mPackageManagerRepository; + private final int mUserId; + + private final MutableLiveData mActionLiveData = new MutableLiveData<>(); + + public FingerprintEnrollFinishViewModel(@NonNull Application application, + FingerprintRepository fingerprintRepository, + PackageManagerRepository packageManagerRepository, + int userId) { + super(application); + mFingerprintRepository = fingerprintRepository; + mPackageManagerRepository = packageManagerRepository; + mUserId = userId; + mActionLiveData.setValue(ACTION_NONE); + } + + /** + * The first sensor type is Side fps sensor or not + */ + public boolean canAssumeSfps() { + return mFingerprintRepository.canAssumeSfps(); + } + + /** + * Get number of fingerprints that this user enrolled. + */ + public int getNumOfEnrolledFingerprintsSize() { + return mFingerprintRepository.getNumOfEnrolledFingerprintsSize(mUserId); + } + + /** + * Get max possible number of fingerprints for a user + */ + public int getMaxFingerprints() { + return mFingerprintRepository.getMaxFingerprints(); + } + + /** + * Clear life data + */ + public void clearLiveData() { + mActionLiveData.setValue(ACTION_NONE); + } + + /** + * Handle add button Click + */ + public void onAddButtonClick() { + mActionLiveData.postValue(ACTION_ADD_BUTTON_CLICK); + } + + /** + * Handle next button Click + */ + public void onNextButtonClick() { + updateFingerprintSuggestionEnableState(); + mActionLiveData.postValue(ACTION_NEXT_BUTTON_CLICK); + } + + /** + * Handle back key pressed + */ + public void onBackKeyPressed() { + updateFingerprintSuggestionEnableState(); + } + + private void updateFingerprintSuggestionEnableState() { + final int enrollNum = mFingerprintRepository.getNumOfEnrolledFingerprintsSize(mUserId); + final int flag = (enrollNum == 1) ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + + ComponentName componentName = new ComponentName(getApplication(), + FINGERPRINT_SUGGESTION_ACTIVITY); + + mPackageManagerRepository.setComponentEnabledSetting(componentName, flag, + PackageManager.DONT_KILL_APP); + } +}