• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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.car.settings.system;
18 
19 import static android.app.Activity.RESULT_OK;
20 
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.view.View;
24 import android.view.ViewTreeObserver;
25 
26 import androidx.annotation.NonNull;
27 import androidx.annotation.Nullable;
28 import androidx.annotation.VisibleForTesting;
29 import androidx.annotation.XmlRes;
30 
31 import com.android.car.settings.R;
32 import com.android.car.settings.common.ActivityResultCallback;
33 import com.android.car.settings.common.Logger;
34 import com.android.car.settings.common.SettingsFragment;
35 import com.android.car.settings.security.CheckLockActivity;
36 import com.android.car.ui.recyclerview.CarUiRecyclerView;
37 import com.android.car.ui.toolbar.MenuItem;
38 
39 import java.util.Collections;
40 import java.util.List;
41 
42 /**
43  * Presents the user with the option to reset the head unit to its default "factory" state. If a
44  * user confirms, the user is first required to authenticate and then presented with a secondary
45  * confirmation: {@link FactoryResetConfirmFragment}. The user must scroll to the bottom of the page
46  * before proceeding.
47  */
48 public class FactoryResetFragment extends SettingsFragment implements ActivityResultCallback {
49 
50     private static final Logger LOG = new Logger(FactoryResetFragment.class);
51     // Arbitrary request code for starting CheckLockActivity when the reset button is clicked.
52     @VisibleForTesting
53     static final int CHECK_LOCK_REQUEST_CODE = 88;
54 
55     private MenuItem mFactoryResetButton;
56 
57     @Override
getToolbarMenuItems()58     public List<MenuItem> getToolbarMenuItems() {
59         return Collections.singletonList(mFactoryResetButton);
60     }
61 
62     @Override
onCreate(Bundle savedInstanceState)63     public void onCreate(Bundle savedInstanceState) {
64         super.onCreate(savedInstanceState);
65 
66         mFactoryResetButton = new MenuItem.Builder(getContext())
67                 .setTitle(R.string.factory_reset_button_text)
68                 .setEnabled(false)
69                 .setOnClickListener(i ->
70                         startActivityForResult(new Intent(getContext(), CheckLockActivity.class),
71                                 CHECK_LOCK_REQUEST_CODE, /* callback= */ FactoryResetFragment.this))
72                 .build();
73     }
74 
75     @Override
76     @XmlRes
getPreferenceScreenResId()77     protected int getPreferenceScreenResId() {
78         return R.xml.factory_reset_fragment;
79     }
80 
81     @Override
onViewCreated(@onNull View view, @Nullable Bundle savedInstanceState)82     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
83         super.onViewCreated(view, savedInstanceState);
84 
85         CarUiRecyclerView recyclerView = view.findViewById(R.id.settings_recycler_view);
86         if (recyclerView != null) {
87             recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(
88                     new ViewTreeObserver.OnGlobalLayoutListener() {
89                         @Override
90                         public void onGlobalLayout() {
91                             mFactoryResetButton.setEnabled(isAtEnd(recyclerView));
92                             recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
93                         }
94                     });
95             recyclerView.addOnScrollListener(
96                     new CarUiRecyclerView.OnScrollListener() {
97                         @Override
98                         public void onScrolled(CarUiRecyclerView recyclerView, int dx, int dy) {
99                             if (isAtEnd(recyclerView)) {
100                                 mFactoryResetButton.setEnabled(true);
101                             }
102                         }
103 
104                         @Override
105                         public void onScrollStateChanged(CarUiRecyclerView recyclerView,
106                                 int newState) {
107                             // no-op
108                         }
109                     });
110         } else {
111             LOG.e("No RecyclerView found");
112             requireActivity().onBackPressed();
113         }
114     }
115 
116     @Override
processActivityResult(int requestCode, int resultCode, @Nullable Intent data)117     public void processActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
118         if (requestCode == CHECK_LOCK_REQUEST_CODE && resultCode == RESULT_OK) {
119             launchFragment(new FactoryResetConfirmFragment());
120         }
121     }
122 
123     /** Returns {@code true} if the RecyclerView is completely displaying the last item. */
isAtEnd(CarUiRecyclerView recyclerView)124     private boolean isAtEnd(CarUiRecyclerView recyclerView) {
125         if (recyclerView.getAdapter().getItemCount() == 0) {
126             return true;
127         }
128 
129         return recyclerView.findLastCompletelyVisibleItemPosition()
130                 == recyclerView.getAdapter().getItemCount() - 1;
131     }
132 }
133