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 com.android.internal.logging.MetricsLogger; 20 import com.android.internal.widget.LockPatternUtils; 21 import com.android.settings.R; 22 import com.android.settings.SettingsActivity; 23 import com.android.settings.SettingsPreferenceFragment; 24 25 import java.util.List; 26 27 import android.accessibilityservice.AccessibilityServiceInfo; 28 import android.app.AlertDialog; 29 import android.app.Dialog; 30 import android.app.admin.DevicePolicyManager; 31 import android.content.Context; 32 import android.content.DialogInterface; 33 import android.content.DialogInterface.OnClickListener; 34 import android.content.Intent; 35 import android.os.Bundle; 36 import android.os.UserHandle; 37 import android.view.LayoutInflater; 38 import android.view.View; 39 import android.view.ViewGroup; 40 import android.view.accessibility.AccessibilityManager; 41 import android.widget.RadioButton; 42 import android.widget.TextView; 43 44 public class EncryptionInterstitial extends SettingsActivity { 45 46 protected static final String EXTRA_PASSWORD_QUALITY = "extra_password_quality"; 47 public static final String EXTRA_REQUIRE_PASSWORD = "extra_require_password"; 48 49 @Override 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 57 protected boolean isValidFragment(String fragmentName) { 58 return EncryptionInterstitialFragment.class.getName().equals(fragmentName); 59 } 60 61 public static Intent createStartIntent(Context ctx, int quality, 62 boolean requirePasswordDefault) { 63 return new Intent(ctx, EncryptionInterstitial.class) 64 .putExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, true) 65 .putExtra(EXTRA_PREFS_SET_BACK_TEXT, (String) null) 66 .putExtra(EXTRA_PREFS_SET_NEXT_TEXT, ctx.getString( 67 R.string.encryption_continue_button)) 68 .putExtra(EXTRA_PASSWORD_QUALITY, quality) 69 .putExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.encryption_interstitial_header) 70 .putExtra(EXTRA_REQUIRE_PASSWORD, requirePasswordDefault); 71 } 72 73 public static class EncryptionInterstitialFragment extends SettingsPreferenceFragment 74 implements View.OnClickListener, OnClickListener { 75 76 private static final int ACCESSIBILITY_WARNING_DIALOG = 1; 77 private RadioButton mRequirePasswordToDecryptButton; 78 private RadioButton mDontRequirePasswordToDecryptButton; 79 private TextView mEncryptionMessage; 80 private boolean mPasswordRequired; 81 82 @Override 83 protected int getMetricsCategory() { 84 return MetricsLogger.ENCRYPTION; 85 } 86 87 @Override 88 public View onCreateView(LayoutInflater inflater, ViewGroup container, 89 Bundle savedInstanceState) { 90 return inflater.inflate(R.layout.encryption_interstitial, container, false); 91 } 92 93 @Override 94 public void onViewCreated(View view, Bundle savedInstanceState) { 95 super.onViewCreated(view, savedInstanceState); 96 mRequirePasswordToDecryptButton = 97 (RadioButton) view.findViewById(R.id.encrypt_require_password); 98 mDontRequirePasswordToDecryptButton = 99 (RadioButton) view.findViewById(R.id.encrypt_dont_require_password); 100 mEncryptionMessage = 101 (TextView) view.findViewById(R.id.encryption_message); 102 boolean forFingerprint = getActivity().getIntent().getBooleanExtra( 103 ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); 104 int quality = getActivity().getIntent().getIntExtra(EXTRA_PASSWORD_QUALITY, 0); 105 final int msgId; 106 final int enableId; 107 final int disableId; 108 switch (quality) { 109 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 110 msgId = forFingerprint ? 111 R.string.encryption_interstitial_message_pattern_for_fingerprint : 112 R.string.encryption_interstitial_message_pattern; 113 enableId = R.string.encrypt_require_pattern; 114 disableId = R.string.encrypt_dont_require_pattern; 115 break; 116 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 117 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: 118 msgId = forFingerprint ? 119 R.string.encryption_interstitial_message_pin_for_fingerprint : 120 R.string.encryption_interstitial_message_pin; 121 enableId = R.string.encrypt_require_pin; 122 disableId = R.string.encrypt_dont_require_pin; 123 break; 124 default: 125 msgId = forFingerprint ? 126 R.string.encryption_interstitial_message_password_for_fingerprint : 127 R.string.encryption_interstitial_message_password; 128 enableId = R.string.encrypt_require_password; 129 disableId = R.string.encrypt_dont_require_password; 130 break; 131 } 132 mEncryptionMessage.setText(msgId); 133 134 mRequirePasswordToDecryptButton.setOnClickListener(this); 135 mRequirePasswordToDecryptButton.setText(enableId); 136 137 mDontRequirePasswordToDecryptButton.setOnClickListener(this); 138 mDontRequirePasswordToDecryptButton.setText(disableId); 139 140 setRequirePasswordState(getActivity().getIntent().getBooleanExtra( 141 EXTRA_REQUIRE_PASSWORD, true)); 142 } 143 144 @Override 145 public void onClick(View v) { 146 if (v == mRequirePasswordToDecryptButton) { 147 final boolean accEn = AccessibilityManager.getInstance(getActivity()).isEnabled(); 148 if (accEn && !mPasswordRequired) { 149 setRequirePasswordState(false); // clear the UI state 150 showDialog(ACCESSIBILITY_WARNING_DIALOG); 151 } else { 152 setRequirePasswordState(true); 153 } 154 } else { 155 setRequirePasswordState(false); 156 } 157 } 158 159 @Override 160 public Dialog onCreateDialog(int dialogId) { 161 switch(dialogId) { 162 case ACCESSIBILITY_WARNING_DIALOG: { 163 final int quality = new LockPatternUtils(getActivity()) 164 .getKeyguardStoredPasswordQuality(UserHandle.myUserId()); 165 final int titleId; 166 final int messageId; 167 switch (quality) { 168 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 169 titleId = R.string.encrypt_talkback_dialog_require_pattern; 170 messageId = R.string.encrypt_talkback_dialog_message_pattern; 171 break; 172 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 173 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: 174 titleId = R.string.encrypt_talkback_dialog_require_pin; 175 messageId = R.string.encrypt_talkback_dialog_message_pin; 176 break; 177 default: 178 titleId = R.string.encrypt_talkback_dialog_require_password; 179 messageId = R.string.encrypt_talkback_dialog_message_password; 180 break; 181 } 182 183 184 List<AccessibilityServiceInfo> list = 185 AccessibilityManager.getInstance(getActivity()) 186 .getEnabledAccessibilityServiceList( 187 AccessibilityServiceInfo.FEEDBACK_ALL_MASK); 188 final CharSequence exampleAccessibility; 189 if (list.isEmpty()) { 190 // This should never happen. But we shouldn't crash 191 exampleAccessibility = ""; 192 } else { 193 exampleAccessibility = list.get(0).getResolveInfo() 194 .loadLabel(getPackageManager()); 195 } 196 return new AlertDialog.Builder(getActivity()) 197 .setTitle(titleId) 198 .setMessage(getString(messageId, exampleAccessibility)) 199 .setCancelable(true) 200 .setPositiveButton(android.R.string.ok, this) 201 .setNegativeButton(android.R.string.cancel, this) 202 .create(); 203 } 204 default: throw new IllegalArgumentException(); 205 } 206 } 207 208 private void setRequirePasswordState(boolean required) { 209 mPasswordRequired = required; 210 mRequirePasswordToDecryptButton.setChecked(required); 211 mDontRequirePasswordToDecryptButton.setChecked(!required); 212 213 // Updates value returned by SettingsActivity.onActivityResult(). 214 SettingsActivity sa = (SettingsActivity)getActivity(); 215 Intent resultIntentData = sa.getResultIntentData(); 216 if (resultIntentData == null) { 217 resultIntentData = new Intent(); 218 sa.setResultIntentData(resultIntentData); 219 } 220 resultIntentData.putExtra(EXTRA_REQUIRE_PASSWORD, mPasswordRequired); 221 } 222 223 @Override 224 public void onClick(DialogInterface dialog, int which) { 225 if (which == DialogInterface.BUTTON_POSITIVE) { 226 setRequirePasswordState(true); 227 } else if (which == DialogInterface.BUTTON_NEGATIVE) { 228 setRequirePasswordState(false); 229 } 230 } 231 } 232 } 233