• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.password;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.os.AsyncTask;
22 import android.os.Bundle;
23 import android.os.UserHandle;
24 import android.os.UserManager;
25 import android.util.Pair;
26 import android.widget.Toast;
27 
28 import androidx.fragment.app.Fragment;
29 
30 import com.android.internal.widget.LockPatternUtils;
31 import com.android.internal.widget.LockscreenCredential;
32 import com.android.settings.R;
33 
34 /**
35  * An invisible retained worker fragment to track the AsyncWork that saves (and optionally
36  * verifies if a challenge is given) the chosen lock credential (pattern/pin/password).
37  */
38 abstract class SaveChosenLockWorkerBase extends Fragment {
39 
40     private Listener mListener;
41     private boolean mFinished;
42     private Intent mResultData;
43 
44     protected LockPatternUtils mUtils;
45     protected boolean mRequestGatekeeperPassword;
46     protected boolean mWasSecureBefore;
47     protected int mUserId;
48     protected int mUnificationProfileId = UserHandle.USER_NULL;
49     protected LockscreenCredential mUnificationProfileCredential;
50 
51     private boolean mBlocking;
52 
53     @Override
onCreate(Bundle savedInstanceState)54     public void onCreate(Bundle savedInstanceState) {
55         super.onCreate(savedInstanceState);
56         setRetainInstance(true);
57     }
58 
setListener(Listener listener)59     public void setListener(Listener listener) {
60         if (mListener == listener) {
61             return;
62         }
63 
64         mListener = listener;
65         if (mFinished && mListener != null) {
66             mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData);
67         }
68     }
69 
prepare(LockPatternUtils utils, boolean credentialRequired, boolean requestGatekeeperPassword, int userId)70     protected void prepare(LockPatternUtils utils, boolean credentialRequired,
71             boolean requestGatekeeperPassword, int userId) {
72         mUtils = utils;
73         mUserId = userId;
74         mRequestGatekeeperPassword = requestGatekeeperPassword;
75         // This will be a no-op for non managed profiles.
76         mWasSecureBefore = mUtils.isSecure(mUserId);
77 
78         Context context = getContext();
79         // If context is null, we're being invoked to change the setCredentialRequiredToDecrypt,
80         // and we made sure that this is the primary user already.
81         if (context == null || UserManager.get(context).getUserInfo(mUserId).isPrimary()) {
82             mUtils.setCredentialRequiredToDecrypt(credentialRequired);
83         }
84 
85         mFinished = false;
86         mResultData = null;
87     }
88 
start()89     protected void start() {
90         if (mBlocking) {
91             finish(saveAndVerifyInBackground().second);
92         } else {
93             new Task().execute();
94         }
95     }
96 
97     /**
98      * Executes the save and verify work in background.
99      * @return pair where the first is a boolean confirming whether the change was successful or not
100      * and second is the Intent which has the challenge token or is null.
101      */
saveAndVerifyInBackground()102     protected abstract Pair<Boolean, Intent> saveAndVerifyInBackground();
103 
finish(Intent resultData)104     protected void finish(Intent resultData) {
105         mFinished = true;
106         mResultData = resultData;
107         if (mListener != null) {
108             mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData);
109         }
110         if (mUnificationProfileCredential != null) {
111             mUnificationProfileCredential.zeroize();
112         }
113     }
114 
setBlocking(boolean blocking)115     public void setBlocking(boolean blocking) {
116         mBlocking = blocking;
117     }
118 
setProfileToUnify(int profileId, LockscreenCredential credential)119     public void setProfileToUnify(int profileId, LockscreenCredential credential) {
120         mUnificationProfileId = profileId;
121         mUnificationProfileCredential = credential.duplicate();
122     }
123 
unifyProfileCredentialIfRequested()124     protected void unifyProfileCredentialIfRequested() {
125         if (mUnificationProfileId != UserHandle.USER_NULL) {
126             mUtils.setSeparateProfileChallengeEnabled(mUnificationProfileId, false,
127                     mUnificationProfileCredential);
128         }
129     }
130 
131     private class Task extends AsyncTask<Void, Void, Pair<Boolean, Intent>> {
132 
133         @Override
doInBackground(Void... params)134         protected Pair<Boolean, Intent> doInBackground(Void... params){
135             return saveAndVerifyInBackground();
136         }
137 
138         @Override
onPostExecute(Pair<Boolean, Intent> resultData)139         protected void onPostExecute(Pair<Boolean, Intent> resultData) {
140             if (!resultData.first) {
141                 Toast.makeText(getContext(), R.string.lockpassword_credential_changed,
142                         Toast.LENGTH_LONG).show();
143             }
144             finish(resultData.second);
145         }
146     }
147 
148     interface Listener {
onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData)149         void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData);
150     }
151 }
152