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.annotation.WorkerThread;
20 import android.os.AsyncTask;
21 import android.os.Bundle;
22 
23 import androidx.annotation.VisibleForTesting;
24 import androidx.fragment.app.Fragment;
25 
26 import com.android.car.settings.common.Logger;
27 import com.android.internal.widget.LockPatternUtils;
28 
29 /**
30  * An invisible retained worker fragment to track the AsyncWork that saves
31  * the chosen lock credential (pattern/pin/password).
32  */
33 abstract class SaveLockWorkerBase extends Fragment {
34     /**
35      * Callback when lock save has finished
36      */
37     interface Listener {
onChosenLockSaveFinished(boolean isSaveSuccessful)38         void onChosenLockSaveFinished(boolean isSaveSuccessful);
39     }
40 
41     private static final Logger LOG = new Logger(SaveLockWorkerBase.class);
42 
43     private Listener mListener;
44     private boolean mFinished;
45     private boolean mIsSaveSuccessful;
46     private LockPatternUtils mUtils;
47     private int mUserId;
48 
getUtils()49     final LockPatternUtils getUtils() {
50         return mUtils;
51     }
52 
getUserId()53     final int getUserId() {
54         return mUserId;
55     }
56 
isFinished()57     final boolean isFinished() {
58         return mFinished;
59     }
60 
61     @Override
onCreate(Bundle savedInstanceState)62     public void onCreate(Bundle savedInstanceState) {
63         super.onCreate(savedInstanceState);
64         setRetainInstance(true);
65     }
66 
init(int userId)67     final void init(int userId) {
68         mUtils = new LockPatternUtils(getContext());
69         mUserId = userId;
70     }
71 
72     /**
73      * Start executing the async task.
74      */
start()75     final void start() {
76         mFinished = false;
77         new Task().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
78     }
79 
80     /**
81      * Set the listener to get callback when finished saving the chosen lock.
82      */
setListener(Listener listener)83     public void setListener(Listener listener) {
84         if (mListener != listener) {
85             mListener = listener;
86             if (mFinished && mListener != null) {
87                 mListener.onChosenLockSaveFinished(mIsSaveSuccessful);
88             }
89         }
90     }
91 
92     @VisibleForTesting
saveAndVerifyInBackground(Void... params)93     boolean saveAndVerifyInBackground(Void... params) {
94         boolean isSaveSuccessful = true;
95 
96         try {
97             saveLock();
98         } catch (Exception e) {
99             LOG.e("Save lock exception", e);
100             isSaveSuccessful = false;
101         }
102 
103         return isSaveSuccessful;
104     }
105 
finish(boolean isSaveSuccessful)106     private void finish(boolean isSaveSuccessful) {
107         mFinished = true;
108         mIsSaveSuccessful = isSaveSuccessful;
109         if (mListener != null) {
110             mListener.onChosenLockSaveFinished(isSaveSuccessful);
111         }
112     }
113 
114     /**
115      * Executes the save and verify work in background.
116      */
117     @WorkerThread
saveLock()118     abstract void saveLock();
119 
120     // Save chosen lock task.
121     private class Task extends AsyncTask<Void, Void, Boolean> {
122         @Override
doInBackground(Void... params)123         protected Boolean doInBackground(Void... params) {
124             return saveAndVerifyInBackground();
125         }
126 
127         @Override
onPostExecute(Boolean isSaveSuccessful)128         protected void onPostExecute(Boolean isSaveSuccessful) {
129             finish(isSaveSuccessful);
130         }
131     }
132 }
133