• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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;
18 
19 import android.accessibilityservice.AccessibilityServiceInfo;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.app.admin.DevicePolicyManager;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.content.Intent;
26 import android.os.Bundle;
27 import android.util.Log;
28 import android.view.LayoutInflater;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.view.accessibility.AccessibilityManager;
32 import android.widget.Button;
33 import android.widget.LinearLayout;
34 import android.widget.TextView;
35 
36 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
37 import com.android.setupwizardlib.GlifLayout;
38 
39 import java.util.List;
40 
41 public class EncryptionInterstitial extends SettingsActivity {
42     private static final String TAG = EncryptionInterstitial.class.getSimpleName();
43 
44     protected static final String EXTRA_PASSWORD_QUALITY = "extra_password_quality";
45     protected static final String EXTRA_UNLOCK_METHOD_INTENT = "extra_unlock_method_intent";
46     public static final String EXTRA_REQUIRE_PASSWORD = "extra_require_password";
47     private static final int CHOOSE_LOCK_REQUEST = 100;
48 
49     @Override
getIntent()50     public Intent getIntent() {
51         Intent modIntent = new Intent(super.getIntent());
52         modIntent.putExtra(EXTRA_SHOW_FRAGMENT, EncryptionInterstitialFragment.class.getName());
53         return modIntent;
54     }
55 
56     @Override
isValidFragment(String fragmentName)57     protected boolean isValidFragment(String fragmentName) {
58         return EncryptionInterstitialFragment.class.getName().equals(fragmentName);
59     }
60 
createStartIntent(Context ctx, int quality, boolean requirePasswordDefault, Intent unlockMethodIntent)61     public static Intent createStartIntent(Context ctx, int quality,
62             boolean requirePasswordDefault, Intent unlockMethodIntent) {
63         return new Intent(ctx, EncryptionInterstitial.class)
64                 .putExtra(EXTRA_PASSWORD_QUALITY, quality)
65                 .putExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.encryption_interstitial_header)
66                 .putExtra(EXTRA_REQUIRE_PASSWORD, requirePasswordDefault)
67                 .putExtra(EXTRA_UNLOCK_METHOD_INTENT, unlockMethodIntent);
68     }
69 
70     @Override
onCreate(Bundle savedInstance)71     protected void onCreate(Bundle savedInstance) {
72         super.onCreate(savedInstance);
73         LinearLayout layout = (LinearLayout) findViewById(R.id.content_parent);
74         layout.setFitsSystemWindows(false);
75     }
76 
77     public static class EncryptionInterstitialFragment extends SettingsPreferenceFragment
78             implements View.OnClickListener, DialogInterface.OnClickListener {
79 
80         private static final int ACCESSIBILITY_WARNING_DIALOG = 1;
81 
82         private View mRequirePasswordToDecrypt;
83         private View mDontRequirePasswordToDecrypt;
84         private boolean mPasswordRequired;
85         private Intent mUnlockMethodIntent;
86         private int mRequestedPasswordQuality;
87 
88         @Override
getMetricsCategory()89         public int getMetricsCategory() {
90             return MetricsEvent.ENCRYPTION;
91         }
92 
93         @Override
onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)94         public View onCreateView(
95                 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
96             return inflater.inflate(R.layout.encryption_interstitial, container, false);
97         }
98 
99         @Override
onViewCreated(View view, Bundle savedInstanceState)100         public void onViewCreated(View view, Bundle savedInstanceState) {
101             super.onViewCreated(view, savedInstanceState);
102 
103             mRequirePasswordToDecrypt = view.findViewById(R.id.encrypt_require_password);
104             mDontRequirePasswordToDecrypt = view.findViewById(R.id.encrypt_dont_require_password);
105             boolean forFingerprint = getActivity().getIntent().getBooleanExtra(
106                     ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
107             Intent intent = getActivity().getIntent();
108             mRequestedPasswordQuality = intent.getIntExtra(EXTRA_PASSWORD_QUALITY, 0);
109             mUnlockMethodIntent = intent.getParcelableExtra(EXTRA_UNLOCK_METHOD_INTENT);
110             final int msgId;
111             switch (mRequestedPasswordQuality) {
112                 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
113                     msgId = forFingerprint ?
114                             R.string.encryption_interstitial_message_pattern_for_fingerprint :
115                             R.string.encryption_interstitial_message_pattern;
116                     break;
117                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
118                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
119                     msgId = forFingerprint ?
120                             R.string.encryption_interstitial_message_pin_for_fingerprint :
121                             R.string.encryption_interstitial_message_pin;
122                     break;
123                 default:
124                     msgId = forFingerprint ?
125                             R.string.encryption_interstitial_message_password_for_fingerprint :
126                             R.string.encryption_interstitial_message_password;
127                     break;
128             }
129             TextView message = (TextView) getActivity().findViewById(R.id.encryption_message);
130             message.setText(msgId);
131 
132             mRequirePasswordToDecrypt.setOnClickListener(this);
133             mDontRequirePasswordToDecrypt.setOnClickListener(this);
134 
135             setRequirePasswordState(getActivity().getIntent().getBooleanExtra(
136                     EXTRA_REQUIRE_PASSWORD, true));
137 
138             GlifLayout layout = (GlifLayout) view;
139             layout.setHeaderText(getActivity().getTitle());
140         }
141 
startLockIntent()142         protected void startLockIntent() {
143             if (mUnlockMethodIntent != null) {
144                 mUnlockMethodIntent.putExtra(EXTRA_REQUIRE_PASSWORD, mPasswordRequired);
145                 startActivityForResult(mUnlockMethodIntent, CHOOSE_LOCK_REQUEST);
146             } else {
147                 Log.wtf(TAG, "no unlock intent to start");
148                 finish();
149             }
150         }
151 
152         @Override
onActivityResult(int requestCode, int resultCode, Intent data)153         public void onActivityResult(int requestCode, int resultCode, Intent data) {
154             super.onActivityResult(requestCode, resultCode, data);
155             if (requestCode == CHOOSE_LOCK_REQUEST && resultCode != RESULT_CANCELED) {
156                 getActivity().setResult(resultCode, data);
157                 finish();
158             }
159         }
160 
161         @Override
onClick(View view)162         public void onClick(View view) {
163             if (view == mRequirePasswordToDecrypt) {
164                 final boolean accEn = AccessibilityManager.getInstance(getActivity()).isEnabled();
165                 if (accEn && !mPasswordRequired) {
166                     setRequirePasswordState(false); // clear the UI state
167                     showDialog(ACCESSIBILITY_WARNING_DIALOG);
168                 } else {
169                     setRequirePasswordState(true);
170                     startLockIntent();
171                 }
172             } else {
173                 setRequirePasswordState(false);
174                 startLockIntent();
175             }
176         }
177 
178         @Override
onCreateDialog(int dialogId)179         public Dialog onCreateDialog(int dialogId) {
180             switch(dialogId) {
181                 case ACCESSIBILITY_WARNING_DIALOG: {
182                     final int titleId;
183                     final int messageId;
184                     switch (mRequestedPasswordQuality) {
185                         case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
186                             titleId = R.string.encrypt_talkback_dialog_require_pattern;
187                             messageId = R.string.encrypt_talkback_dialog_message_pattern;
188                             break;
189                         case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
190                         case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
191                             titleId = R.string.encrypt_talkback_dialog_require_pin;
192                             messageId = R.string.encrypt_talkback_dialog_message_pin;
193                             break;
194                         default:
195                             titleId = R.string.encrypt_talkback_dialog_require_password;
196                             messageId = R.string.encrypt_talkback_dialog_message_password;
197                             break;
198                     }
199 
200 
201                     List<AccessibilityServiceInfo> list =
202                             AccessibilityManager.getInstance(getActivity())
203                             .getEnabledAccessibilityServiceList(
204                                     AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
205                     final CharSequence exampleAccessibility;
206                     if (list.isEmpty()) {
207                         // This should never happen.  But we shouldn't crash
208                         exampleAccessibility = "";
209                     } else {
210                         exampleAccessibility = list.get(0).getResolveInfo()
211                                 .loadLabel(getPackageManager());
212                     }
213                     return new AlertDialog.Builder(getActivity())
214                         .setTitle(titleId)
215                         .setMessage(getString(messageId, exampleAccessibility))
216                         .setCancelable(true)
217                         .setPositiveButton(android.R.string.ok, this)
218                         .setNegativeButton(android.R.string.cancel, this)
219                         .create();
220                 }
221                 default: throw new IllegalArgumentException();
222             }
223         }
224 
225         @Override
getDialogMetricsCategory(int dialogId)226         public int getDialogMetricsCategory(int dialogId) {
227             if (dialogId == ACCESSIBILITY_WARNING_DIALOG) {
228                 return MetricsEvent.DIALOG_ENCRYPTION_INTERSTITIAL_ACCESSIBILITY;
229             }
230             return 0;
231         }
232 
setRequirePasswordState(boolean required)233         private void setRequirePasswordState(boolean required) {
234             mPasswordRequired = required;
235         }
236 
237         @Override
onClick(DialogInterface dialog, int which)238         public void onClick(DialogInterface dialog, int which) {
239             if (which == DialogInterface.BUTTON_POSITIVE) {
240                 setRequirePasswordState(true);
241                 startLockIntent();
242             } else if (which == DialogInterface.BUTTON_NEGATIVE) {
243                 setRequirePasswordState(false);
244             }
245         }
246     }
247 }
248