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