Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 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.email.activity.setup; |
| 18 | |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 19 | import android.app.Activity; |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 20 | import android.app.AlertDialog; |
| 21 | import android.app.Dialog; |
| 22 | import android.app.DialogFragment; |
| 23 | import android.app.FragmentManager; |
Dianne Hackborn | 6d00162 | 2010-02-26 17:26:45 -0800 | [diff] [blame] | 24 | import android.app.admin.DevicePolicyManager; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 25 | import android.content.Context; |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 26 | import android.content.DialogInterface; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 27 | import android.content.Intent; |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 28 | import android.content.res.Resources; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 29 | import android.os.Bundle; |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 30 | import android.util.Log; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 31 | |
Marc Blank | e2d28a0 | 2011-07-17 15:46:03 -0700 | [diff] [blame] | 32 | import com.android.email.Email; |
| 33 | import com.android.email.R; |
| 34 | import com.android.email.SecurityPolicy; |
| 35 | import com.android.email.activity.ActivityHelper; |
| 36 | import com.android.emailcommon.provider.Account; |
| 37 | import com.android.emailcommon.provider.HostAuth; |
| 38 | import com.android.emailcommon.utility.Utility; |
| 39 | |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 40 | /** |
| 41 | * Psuedo-activity (no UI) to bootstrap the user up to a higher desired security level. This |
| 42 | * bootstrap requires the following steps. |
| 43 | * |
| 44 | * 1. Confirm the account of interest has any security policies defined - exit early if not |
| 45 | * 2. If not actively administrating the device, ask Device Policy Manager to start that |
| 46 | * 3. When we are actively administrating, check current policies and see if they're sufficient |
| 47 | * 4. If not, set policies |
| 48 | * 5. If necessary, request for user to update device password |
Andy Stadler | 469f298 | 2011-01-13 13:12:55 -0800 | [diff] [blame] | 49 | * 6. If necessary, request for user to activate device encryption |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 50 | */ |
| 51 | public class AccountSecurity extends Activity { |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 52 | private static final String TAG = "Email/AccountSecurity"; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 53 | |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 54 | private static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID"; |
| 55 | private static final String EXTRA_SHOW_DIALOG = "SHOW_DIALOG"; |
| 56 | private static final String EXTRA_PASSWORD_EXPIRING = "EXPIRING"; |
| 57 | private static final String EXTRA_PASSWORD_EXPIRED = "EXPIRED"; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 58 | |
| 59 | private static final int REQUEST_ENABLE = 1; |
Andy Stadler | 469f298 | 2011-01-13 13:12:55 -0800 | [diff] [blame] | 60 | private static final int REQUEST_PASSWORD = 2; |
| 61 | private static final int REQUEST_ENCRYPTION = 3; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 62 | |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 63 | private boolean mTriedAddAdministrator = false; |
| 64 | private boolean mTriedSetPassword = false; |
| 65 | private boolean mTriedSetEncryption = false; |
| 66 | private Account mAccount; |
| 67 | |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 68 | /** |
| 69 | * Used for generating intent for this activity (which is intended to be launched |
| 70 | * from a notification.) |
| 71 | * |
| 72 | * @param context Calling context for building the intent |
| 73 | * @param accountId The account of interest |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 74 | * @param showDialog If true, a simple warning dialog will be shown before kicking off |
| 75 | * the necessary system settings. Should be true anywhere the context of the security settings |
| 76 | * is not clear (e.g. any time after the account has been set up). |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 77 | * @return an Intent which can be used to view that account |
| 78 | */ |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 79 | public static Intent actionUpdateSecurityIntent(Context context, long accountId, |
| 80 | boolean showDialog) { |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 81 | Intent intent = new Intent(context, AccountSecurity.class); |
| 82 | intent.putExtra(EXTRA_ACCOUNT_ID, accountId); |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 83 | intent.putExtra(EXTRA_SHOW_DIALOG, showDialog); |
| 84 | return intent; |
| 85 | } |
| 86 | |
| 87 | /** |
| 88 | * Used for generating intent for this activity (which is intended to be launched |
| 89 | * from a notification.) This is a special mode of this activity which exists only |
| 90 | * to give the user a dialog (for context) about a device pin/password expiration event. |
| 91 | */ |
| 92 | public static Intent actionDevicePasswordExpirationIntent(Context context, long accountId, |
| 93 | boolean expired) { |
| 94 | Intent intent = new Intent(context, AccountSecurity.class); |
| 95 | intent.putExtra(EXTRA_ACCOUNT_ID, accountId); |
| 96 | intent.putExtra(expired ? EXTRA_PASSWORD_EXPIRED : EXTRA_PASSWORD_EXPIRING, true); |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 97 | return intent; |
| 98 | } |
| 99 | |
| 100 | @Override |
| 101 | public void onCreate(Bundle savedInstanceState) { |
| 102 | super.onCreate(savedInstanceState); |
Andrew Stadler | cd09545 | 2010-11-01 16:15:15 -0700 | [diff] [blame] | 103 | ActivityHelper.debugSetWindowFlags(this); |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 104 | |
| 105 | Intent i = getIntent(); |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 106 | final long accountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1); |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 107 | final boolean showDialog = i.getBooleanExtra(EXTRA_SHOW_DIALOG, false); |
| 108 | final boolean passwordExpiring = i.getBooleanExtra(EXTRA_PASSWORD_EXPIRING, false); |
| 109 | final boolean passwordExpired = i.getBooleanExtra(EXTRA_PASSWORD_EXPIRED, false); |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 110 | SecurityPolicy security = SecurityPolicy.getInstance(this); |
Marc Blank | c6df1d6 | 2011-07-19 14:09:11 -0700 | [diff] [blame] | 111 | security.clearNotification(); |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 112 | if (accountId == -1) { |
| 113 | finish(); |
| 114 | return; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 115 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 116 | |
Marc Blank | c6df1d6 | 2011-07-19 14:09:11 -0700 | [diff] [blame] | 117 | mAccount = Account.restoreAccountWithId(AccountSecurity.this, accountId); |
| 118 | if (mAccount == null) { |
| 119 | finish(); |
| 120 | return; |
| 121 | } |
Marc Blank | 2736c1a | 2011-10-20 10:13:02 -0700 | [diff] [blame] | 122 | |
Marc Blank | c6df1d6 | 2011-07-19 14:09:11 -0700 | [diff] [blame] | 123 | // Special handling for password expiration events |
| 124 | if (passwordExpiring || passwordExpired) { |
| 125 | FragmentManager fm = getFragmentManager(); |
| 126 | if (fm.findFragmentByTag("password_expiration") == null) { |
| 127 | PasswordExpirationDialog dialog = |
| 128 | PasswordExpirationDialog.newInstance(mAccount.getDisplayName(), |
| 129 | passwordExpired); |
| 130 | dialog.show(fm, "password_expiration"); |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 131 | } |
Marc Blank | c6df1d6 | 2011-07-19 14:09:11 -0700 | [diff] [blame] | 132 | return; |
| 133 | } |
| 134 | // Otherwise, handle normal security settings flow |
| 135 | if (mAccount.mPolicyKey != 0) { |
| 136 | // This account wants to control security |
| 137 | if (showDialog) { |
| 138 | // Show dialog first, unless already showing (e.g. after rotation) |
| 139 | FragmentManager fm = getFragmentManager(); |
| 140 | if (fm.findFragmentByTag("security_needed") == null) { |
| 141 | SecurityNeededDialog dialog = |
| 142 | SecurityNeededDialog.newInstance(mAccount.getDisplayName()); |
| 143 | dialog.show(fm, "security_needed"); |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 144 | } |
Marc Blank | c6df1d6 | 2011-07-19 14:09:11 -0700 | [diff] [blame] | 145 | } else { |
| 146 | // Go directly to security settings |
| 147 | tryAdvanceSecurity(mAccount); |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 148 | } |
Marc Blank | c6df1d6 | 2011-07-19 14:09:11 -0700 | [diff] [blame] | 149 | return; |
| 150 | } |
| 151 | finish(); |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 152 | } |
| 153 | |
| 154 | /** |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 155 | * After any of the activities return, try to advance to the "next step" |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 156 | */ |
| 157 | @Override |
| 158 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 159 | tryAdvanceSecurity(mAccount); |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 160 | super.onActivityResult(requestCode, resultCode, data); |
| 161 | } |
| 162 | |
| 163 | /** |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 164 | * Walk the user through the required steps to become an active administrator and with |
| 165 | * the requisite security settings for the given account. |
| 166 | * |
| 167 | * These steps will be repeated each time we return from a given attempt (e.g. asking the |
| 168 | * user to choose a device pin/password). In a typical activation, we may repeat these |
| 169 | * steps a few times. It may go as far as step 5 (password) or step 6 (encryption), but it |
| 170 | * will terminate when step 2 (isActive()) succeeds. |
| 171 | * |
| 172 | * If at any point we do not advance beyond a given user step, (e.g. the user cancels |
| 173 | * instead of setting a password) we simply repost the security notification, and exit. |
| 174 | * We never want to loop here. |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 175 | */ |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 176 | private void tryAdvanceSecurity(Account account) { |
| 177 | SecurityPolicy security = SecurityPolicy.getInstance(this); |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 178 | // Step 1. Check if we are an active device administrator, and stop here to activate |
| 179 | if (!security.isActiveAdmin()) { |
| 180 | if (mTriedAddAdministrator) { |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 181 | if (Email.DEBUG) { |
| 182 | Log.d(TAG, "Not active admin: repost notification"); |
| 183 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 184 | repostNotification(account, security); |
| 185 | finish(); |
| 186 | } else { |
| 187 | mTriedAddAdministrator = true; |
| 188 | // retrieve name of server for the format string |
| 189 | HostAuth hostAuth = HostAuth.restoreHostAuthWithId(this, account.mHostAuthKeyRecv); |
| 190 | if (hostAuth == null) { |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 191 | if (Email.DEBUG) { |
| 192 | Log.d(TAG, "No HostAuth: repost notification"); |
| 193 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 194 | repostNotification(account, security); |
| 195 | finish(); |
| 196 | } else { |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 197 | if (Email.DEBUG) { |
| 198 | Log.d(TAG, "Not active admin: post initial notification"); |
| 199 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 200 | // try to become active - must happen here in activity, to get result |
| 201 | Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); |
| 202 | intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, |
| 203 | security.getAdminComponent()); |
| 204 | intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, |
| 205 | this.getString(R.string.account_security_policy_explanation_fmt, |
| 206 | hostAuth.mAddress)); |
| 207 | startActivityForResult(intent, REQUEST_ENABLE); |
| 208 | } |
| 209 | } |
| 210 | return; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 211 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 212 | |
| 213 | // Step 2. Check if the current aggregate security policy is being satisfied by the |
| 214 | // DevicePolicyManager (the current system security level). |
| 215 | if (security.isActive(null)) { |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 216 | if (Email.DEBUG) { |
| 217 | Log.d(TAG, "Security active; clear holds"); |
| 218 | } |
Makoto Onuki | bcf3232 | 2010-07-27 12:52:46 -0700 | [diff] [blame] | 219 | Account.clearSecurityHoldOnAllAccounts(this); |
Marc Blank | c6df1d6 | 2011-07-19 14:09:11 -0700 | [diff] [blame] | 220 | security.clearNotification(); |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 221 | finish(); |
| 222 | return; |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 223 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 224 | |
| 225 | // Step 3. Try to assert the current aggregate security requirements with the system. |
| 226 | security.setActivePolicies(); |
| 227 | |
| 228 | // Step 4. Recheck the security policy, and determine what changes are needed (if any) |
| 229 | // to satisfy the requirements. |
| 230 | int inactiveReasons = security.getInactiveReasons(null); |
| 231 | |
| 232 | // Step 5. If password is needed, try to have the user set it |
Andy Stadler | 469f298 | 2011-01-13 13:12:55 -0800 | [diff] [blame] | 233 | if ((inactiveReasons & SecurityPolicy.INACTIVE_NEED_PASSWORD) != 0) { |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 234 | if (mTriedSetPassword) { |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 235 | if (Email.DEBUG) { |
| 236 | Log.d(TAG, "Password needed; repost notification"); |
| 237 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 238 | repostNotification(account, security); |
| 239 | finish(); |
| 240 | } else { |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 241 | if (Email.DEBUG) { |
| 242 | Log.d(TAG, "Password needed; request it via DPM"); |
| 243 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 244 | mTriedSetPassword = true; |
| 245 | // launch the activity to have the user set a new password. |
| 246 | Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); |
| 247 | startActivityForResult(intent, REQUEST_PASSWORD); |
| 248 | } |
| 249 | return; |
Andy Stadler | 469f298 | 2011-01-13 13:12:55 -0800 | [diff] [blame] | 250 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 251 | |
| 252 | // Step 6. If encryption is needed, try to have the user set it |
| 253 | if ((inactiveReasons & SecurityPolicy.INACTIVE_NEED_ENCRYPTION) != 0) { |
| 254 | if (mTriedSetEncryption) { |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 255 | if (Email.DEBUG) { |
| 256 | Log.d(TAG, "Encryption needed; repost notification"); |
| 257 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 258 | repostNotification(account, security); |
| 259 | finish(); |
| 260 | } else { |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 261 | if (Email.DEBUG) { |
| 262 | Log.d(TAG, "Encryption needed; request it via DPM"); |
| 263 | } |
Ben Komalo | d09cff0 | 2011-05-06 14:57:47 -0700 | [diff] [blame] | 264 | mTriedSetEncryption = true; |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 265 | // launch the activity to start up encryption. |
| 266 | Intent intent = new Intent(DevicePolicyManager.ACTION_START_ENCRYPTION); |
| 267 | startActivityForResult(intent, REQUEST_ENCRYPTION); |
| 268 | } |
| 269 | return; |
| 270 | } |
| 271 | |
| 272 | // Step 7. No problems were found, so clear holds and exit |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 273 | if (Email.DEBUG) { |
| 274 | Log.d(TAG, "Policies enforced; clear holds"); |
| 275 | } |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 276 | Account.clearSecurityHoldOnAllAccounts(this); |
Marc Blank | c6df1d6 | 2011-07-19 14:09:11 -0700 | [diff] [blame] | 277 | security.clearNotification(); |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 278 | finish(); |
| 279 | } |
| 280 | |
| 281 | /** |
| 282 | * Mark an account as not-ready-for-sync and post a notification to bring the user back here |
| 283 | * eventually. |
| 284 | */ |
| 285 | private void repostNotification(final Account account, final SecurityPolicy security) { |
Marc Blank | c6df1d6 | 2011-07-19 14:09:11 -0700 | [diff] [blame] | 286 | if (account == null) return; |
Andy Stadler | 45bfac0 | 2011-01-24 11:08:31 -0800 | [diff] [blame] | 287 | Utility.runAsync(new Runnable() { |
| 288 | @Override |
| 289 | public void run() { |
| 290 | security.policiesRequired(account.mId); |
| 291 | } |
| 292 | }); |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 293 | } |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 294 | |
| 295 | /** |
| 296 | * Dialog briefly shown in some cases, to indicate the user that a security update is needed. |
| 297 | * If the user clicks OK, we proceed into the "tryAdvanceSecurity" flow. If the user cancels, |
| 298 | * we repost the notification and finish() the activity. |
| 299 | */ |
| 300 | public static class SecurityNeededDialog extends DialogFragment |
| 301 | implements DialogInterface.OnClickListener { |
| 302 | private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name"; |
| 303 | |
| 304 | /** |
| 305 | * Create a new dialog. |
| 306 | */ |
| 307 | public static SecurityNeededDialog newInstance(String accountName) { |
| 308 | final SecurityNeededDialog dialog = new SecurityNeededDialog(); |
| 309 | Bundle b = new Bundle(); |
| 310 | b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName); |
| 311 | dialog.setArguments(b); |
| 312 | return dialog; |
| 313 | } |
| 314 | |
| 315 | @Override |
| 316 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
| 317 | final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME); |
| 318 | |
| 319 | final Context context = getActivity(); |
| 320 | final Resources res = context.getResources(); |
| 321 | final AlertDialog.Builder b = new AlertDialog.Builder(context); |
| 322 | b.setTitle(R.string.account_security_dialog_title); |
| 323 | b.setIconAttribute(android.R.attr.alertDialogIcon); |
| 324 | b.setMessage(res.getString(R.string.account_security_dialog_content_fmt, accountName)); |
| 325 | b.setPositiveButton(R.string.okay_action, this); |
| 326 | b.setNegativeButton(R.string.cancel_action, this); |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 327 | if (Email.DEBUG) { |
| 328 | Log.d(TAG, "Posting security needed dialog"); |
| 329 | } |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 330 | return b.create(); |
| 331 | } |
| 332 | |
| 333 | @Override |
| 334 | public void onClick(DialogInterface dialog, int which) { |
| 335 | dismiss(); |
| 336 | AccountSecurity activity = (AccountSecurity) getActivity(); |
| 337 | if (activity.mAccount == null) { |
| 338 | // Clicked before activity fully restored - probably just monkey - exit quickly |
| 339 | activity.finish(); |
| 340 | return; |
| 341 | } |
| 342 | switch (which) { |
| 343 | case DialogInterface.BUTTON_POSITIVE: |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 344 | if (Email.DEBUG) { |
| 345 | Log.d(TAG, "User accepts; advance to next step"); |
| 346 | } |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 347 | activity.tryAdvanceSecurity(activity.mAccount); |
| 348 | break; |
| 349 | case DialogInterface.BUTTON_NEGATIVE: |
Marc Blank | aeee10e | 2011-04-27 17:12:06 -0700 | [diff] [blame] | 350 | if (Email.DEBUG) { |
| 351 | Log.d(TAG, "User declines; repost notification"); |
| 352 | } |
Andy Stadler | f489413 | 2011-02-18 18:23:18 -0800 | [diff] [blame] | 353 | activity.repostNotification( |
| 354 | activity.mAccount, SecurityPolicy.getInstance(activity)); |
| 355 | activity.finish(); |
| 356 | break; |
| 357 | } |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | /** |
| 362 | * Dialog briefly shown in some cases, to indicate the user that the PIN/Password is expiring |
| 363 | * or has expired. If the user clicks OK, we launch the password settings screen. |
| 364 | */ |
| 365 | public static class PasswordExpirationDialog extends DialogFragment |
| 366 | implements DialogInterface.OnClickListener { |
| 367 | private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name"; |
| 368 | private static final String BUNDLE_KEY_EXPIRED = "expired"; |
| 369 | |
| 370 | /** |
| 371 | * Create a new dialog. |
| 372 | */ |
| 373 | public static PasswordExpirationDialog newInstance(String accountName, boolean expired) { |
| 374 | final PasswordExpirationDialog dialog = new PasswordExpirationDialog(); |
| 375 | Bundle b = new Bundle(); |
| 376 | b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName); |
| 377 | b.putBoolean(BUNDLE_KEY_EXPIRED, expired); |
| 378 | dialog.setArguments(b); |
| 379 | return dialog; |
| 380 | } |
| 381 | |
| 382 | /** |
| 383 | * Note, this actually creates two slightly different dialogs (for expiring vs. expired) |
| 384 | */ |
| 385 | @Override |
| 386 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
| 387 | final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME); |
| 388 | final boolean expired = getArguments().getBoolean(BUNDLE_KEY_EXPIRED); |
| 389 | final int titleId = expired |
| 390 | ? R.string.password_expired_dialog_title |
| 391 | : R.string.password_expire_warning_dialog_title; |
| 392 | final int contentId = expired |
| 393 | ? R.string.password_expired_dialog_content_fmt |
| 394 | : R.string.password_expire_warning_dialog_content_fmt; |
| 395 | |
| 396 | final Context context = getActivity(); |
| 397 | final Resources res = context.getResources(); |
| 398 | final AlertDialog.Builder b = new AlertDialog.Builder(context); |
| 399 | b.setTitle(titleId); |
| 400 | b.setIconAttribute(android.R.attr.alertDialogIcon); |
| 401 | b.setMessage(res.getString(contentId, accountName)); |
| 402 | b.setPositiveButton(R.string.okay_action, this); |
| 403 | b.setNegativeButton(R.string.cancel_action, this); |
| 404 | return b.create(); |
| 405 | } |
| 406 | |
| 407 | @Override |
| 408 | public void onClick(DialogInterface dialog, int which) { |
| 409 | dismiss(); |
| 410 | AccountSecurity activity = (AccountSecurity) getActivity(); |
| 411 | if (which == DialogInterface.BUTTON_POSITIVE) { |
| 412 | Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); |
| 413 | activity.startActivity(intent); |
| 414 | } |
| 415 | activity.finish(); |
| 416 | } |
| 417 | } |
Andrew Stadler | 3d2b3b3 | 2010-02-05 11:10:39 -0800 | [diff] [blame] | 418 | } |