1 /*
2  * Copyright (C) 2023 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.remoteauth.enrolling
18 
19 import android.os.Bundle
20 import android.view.View
21 import android.widget.ProgressBar
22 import android.widget.TextView
23 import androidx.fragment.app.viewModels
24 import androidx.lifecycle.Lifecycle
25 import androidx.lifecycle.lifecycleScope
26 import androidx.lifecycle.repeatOnLifecycle
27 
28 
29 import androidx.navigation.fragment.NavHostFragment.Companion.findNavController
30 import androidx.recyclerview.widget.LinearLayoutManager
31 import androidx.recyclerview.widget.RecyclerView
32 
33 import com.android.settings.R
34 import com.android.settings.remoteauth.RemoteAuthEnrollBase
35 
36 import com.google.android.setupcompat.template.FooterButton
37 import kotlinx.coroutines.launch
38 
39 class RemoteAuthEnrollEnrolling :
40     RemoteAuthEnrollBase(
41         layoutResId = R.layout.remote_auth_enroll_enrolling,
42         glifLayoutId = R.id.setup_wizard_layout,
43     ) {
44     private val viewModel: RemoteAuthEnrollEnrollingViewModel by viewModels()
<lambda>null45     private val navController by lazy { findNavController(this) }
46     private val adapter = RemoteAuthEnrollEnrollingRecyclerViewAdapter()
<lambda>null47     private val progressBar by lazy {
48         view!!.requireViewById<ProgressBar>(R.id.enrolling_list_progress_bar)
49     }
<lambda>null50     private val errorText by lazy { view!!.requireViewById<TextView>(R.id.error_text) }
<lambda>null51     private val recyclerView by lazy {
52         view!!.requireViewById<RecyclerView>(R.id.discovered_authenticator_list)
53     }
54 
onViewCreatednull55     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
56         super.onViewCreated(view, savedInstanceState)
57         // Set up adapter
58         recyclerView.layoutManager = LinearLayoutManager(context)
59         recyclerView.adapter = adapter
60 
61         // Collect UIState and update UI on changes.
62         lifecycleScope.launch {
63             repeatOnLifecycle(Lifecycle.State.STARTED) {
64                 viewModel.uiState.collect {
65                     updateUi(it)
66                 }
67             }
68         }
69     }
70 
onStartnull71     override fun onStart() {
72         super.onStart()
73         // Get list of discovered devices from viewModel.
74         viewModel.discoverDevices()
75     }
76 
initializePrimaryFooterButtonnull77     override fun initializePrimaryFooterButton(): FooterButton {
78         return FooterButton.Builder(requireContext())
79             .setText(R.string.security_settings_remoteauth_enroll_enrolling_agree)
80             .setListener(this::onPrimaryFooterButtonClick)
81             .setButtonType(FooterButton.ButtonType.NEXT)
82             .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary)
83             .build()
84     }
85 
initializeSecondaryFooterButtonnull86     override fun initializeSecondaryFooterButton(): FooterButton? {
87         return FooterButton.Builder(requireContext())
88             .setText(R.string.security_settings_remoteauth_enroll_enrolling_disagree)
89             .setListener(this::onSecondaryFooterButtonClick)
90             .setButtonType(FooterButton.ButtonType.SKIP)
91             .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Secondary)
92             .build()
93     }
94 
onPrimaryFooterButtonClicknull95     private fun onPrimaryFooterButtonClick(view: View) {
96         viewModel.registerAuthenticator()
97     }
98 
onSecondaryFooterButtonClicknull99     private fun onSecondaryFooterButtonClick(view: View) {
100         navController.navigateUp()
101     }
102 
updateUinull103     private fun updateUi(uiState: RemoteAuthEnrollEnrollingUiState) {
104         progressBar.visibility = View.INVISIBLE
105         primaryFooterButton.isEnabled = false
106         // TODO(b/290769765): Add unit tests for all this states.
107         when (uiState.enrollmentUiState) {
108             EnrollmentUiState.NONE -> {
109                 adapter.uiStates = uiState.discoveredDeviceUiStates
110                 primaryFooterButton.isEnabled = viewModel.isDeviceSelected()
111             }
112 
113             EnrollmentUiState.FINDING_DEVICES -> {
114                 progressBar.visibility = View.VISIBLE
115             }
116 
117             EnrollmentUiState.ENROLLING -> {}
118             EnrollmentUiState.SUCCESS -> {
119                 navController.navigate(R.id.action_enrolling_to_finish)
120             }
121         }
122         if (uiState.errorMsg != null) {
123             errorText.visibility = View.VISIBLE
124             errorText.text = uiState.errorMsg
125         } else {
126             errorText.visibility = View.INVISIBLE
127             errorText.text = ""
128         }
129     }
130 }
131