• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.security;
18 
19 import android.content.Context;
20 import android.os.Bundle;
21 import android.os.UserHandle;
22 import android.view.View;
23 import android.widget.TextView;
24 
25 import com.android.car.settings.R;
26 import com.android.car.settings.common.BaseFragment;
27 import com.android.internal.widget.LockPatternUtils;
28 import com.android.internal.widget.LockPatternView;
29 
30 import java.util.List;
31 
32 /**
33  * Fragment for confirming existing lock pattern
34  */
35 public class ConfirmLockPatternFragment extends BaseFragment {
36 
37     private static final String FRAGMENT_TAG_CHECK_LOCK_WORKER = "check_lock_worker";
38     // Time we wait before clearing a wrong pattern and the error message.
39     private static final long CLEAR_WRONG_ATTEMPT_TIMEOUT_MS = 2500L;
40 
41     private LockPatternView mLockPatternView;
42     private TextView mMsgView;
43 
44     private LockPatternUtils mLockPatternUtils;
45     private CheckLockWorker mCheckLockWorker;
46     private CheckLockListener mCheckLockListener;
47 
48     private int mUserId;
49     private List<LockPatternView.Cell> mPattern;
50 
51     /**
52      * Factory method for creating ConfirmLockPatternFragment
53      */
newInstance()54     public static ConfirmLockPatternFragment newInstance() {
55         ConfirmLockPatternFragment patternFragment = new ConfirmLockPatternFragment();
56         Bundle bundle = BaseFragment.getBundle();
57         bundle.putInt(EXTRA_TITLE_ID, R.string.security_settings_title);
58         bundle.putInt(EXTRA_ACTION_BAR_LAYOUT, R.layout.action_bar_with_button);
59         bundle.putInt(EXTRA_LAYOUT, R.layout.confirm_lock_pattern_fragment);
60         patternFragment.setArguments(bundle);
61         return patternFragment;
62     }
63 
64     @Override
onAttach(Context context)65     public void onAttach(Context context) {
66         super.onAttach(context);
67         if ((getActivity() instanceof CheckLockListener)) {
68             mCheckLockListener = (CheckLockListener) getActivity();
69         } else {
70             throw new RuntimeException("The activity must implement CheckLockListener");
71         }
72     }
73 
74     @Override
onCreate(Bundle savedInstanceState)75     public void onCreate(Bundle savedInstanceState) {
76         super.onCreate(savedInstanceState);
77         mLockPatternUtils = new LockPatternUtils(getContext());
78         mUserId = UserHandle.myUserId();
79     }
80 
81     @Override
onViewCreated(View view, Bundle savedInstanceState)82     public void onViewCreated(View view, Bundle savedInstanceState) {
83         super.onViewCreated(view, savedInstanceState);
84 
85         mMsgView = (TextView) view.findViewById(R.id.message);
86         mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
87         mLockPatternView.setFadePattern(false);
88         mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(mUserId));
89         mLockPatternView.setOnPatternListener(mLockPatternListener);
90 
91         if (savedInstanceState != null) {
92             mCheckLockWorker = (CheckLockWorker) getFragmentManager().findFragmentByTag(
93                     FRAGMENT_TAG_CHECK_LOCK_WORKER);
94         }
95     }
96 
97     @Override
onStart()98     public void onStart() {
99         super.onStart();
100         if (mCheckLockWorker != null) {
101             mCheckLockWorker.setListener(this::onCheckCompleted);
102         }
103     }
104 
105     @Override
onStop()106     public void onStop() {
107         super.onStop();
108         if (mCheckLockWorker != null) {
109             mCheckLockWorker.setListener(null);
110         }
111     }
112 
113     private Runnable mClearErrorRunnable = () ->  {
114         mLockPatternView.clearPattern();
115         mMsgView.setText("");
116     };
117 
118     private LockPatternView.OnPatternListener mLockPatternListener =
119             new LockPatternView.OnPatternListener() {
120 
121         public void onPatternStart() {
122             mLockPatternView.removeCallbacks(mClearErrorRunnable);
123             mMsgView.setText("");
124         }
125 
126         public void onPatternCleared() {
127             mLockPatternView.removeCallbacks(mClearErrorRunnable);
128         }
129 
130         public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {}
131 
132         public void onPatternDetected(List<LockPatternView.Cell> pattern) {
133             mLockPatternView.setEnabled(false);
134 
135             if (mCheckLockWorker == null) {
136                 mCheckLockWorker = new CheckLockWorker();
137                 mCheckLockWorker.setListener(ConfirmLockPatternFragment.this::onCheckCompleted);
138 
139                 getFragmentManager()
140                         .beginTransaction()
141                         .add(mCheckLockWorker, FRAGMENT_TAG_CHECK_LOCK_WORKER)
142                         .commitNow();
143             }
144 
145             mPattern = pattern;
146             mCheckLockWorker.checkPattern(mUserId, pattern);
147         }
148     };
149 
onCheckCompleted(boolean lockMatched)150     private void onCheckCompleted(boolean lockMatched) {
151         if (lockMatched) {
152             mCheckLockListener.onLockVerified(LockPatternUtils.patternToString(mPattern));
153         } else {
154             mLockPatternView.setEnabled(true);
155             mMsgView.setText(R.string.lockpattern_pattern_wrong);
156 
157             // Set timer to clear wrong pattern
158             mLockPatternView.removeCallbacks(mClearErrorRunnable);
159             mLockPatternView.postDelayed(mClearErrorRunnable, CLEAR_WRONG_ATTEMPT_TIMEOUT_MS);
160         }
161     }
162 }
163