summaryrefslogtreecommitdiffstats
path: root/provider_src/com/android/email/activity/setup/AccountSecurity.java
diff options
context:
space:
mode:
Diffstat (limited to 'provider_src/com/android/email/activity/setup/AccountSecurity.java')
-rw-r--r--provider_src/com/android/email/activity/setup/AccountSecurity.java628
1 files changed, 628 insertions, 0 deletions
diff --git a/provider_src/com/android/email/activity/setup/AccountSecurity.java b/provider_src/com/android/email/activity/setup/AccountSecurity.java
new file mode 100644
index 000000000..c2be45928
--- /dev/null
+++ b/provider_src/com/android/email/activity/setup/AccountSecurity.java
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.email.activity.setup;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.app.LoaderManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.text.TextUtils;
+
+import com.android.email.DebugUtils;
+import com.android.email.R;
+import com.android.email.SecurityPolicy;
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.HostAuth;
+import com.android.emailcommon.provider.Policy;
+import com.android.emailcommon.utility.IntentUtilities;
+import com.android.mail.ui.MailAsyncTaskLoader;
+import com.android.mail.utils.LogUtils;
+
+/**
+ * Psuedo-activity (no UI) to bootstrap the user up to a higher desired security level. This
+ * bootstrap requires the following steps.
+ *
+ * 1. Confirm the account of interest has any security policies defined - exit early if not
+ * 2. If not actively administrating the device, ask Device Policy Manager to start that
+ * 3. When we are actively administrating, check current policies and see if they're sufficient
+ * 4. If not, set policies
+ * 5. If necessary, request for user to update device password
+ * 6. If necessary, request for user to activate device encryption
+ */
+public class AccountSecurity extends Activity {
+ private static final String TAG = "Email/AccountSecurity";
+
+ private static final boolean DEBUG = false; // Don't ship with this set to true
+
+ private static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID";
+ private static final String EXTRA_SHOW_DIALOG = "SHOW_DIALOG";
+ private static final String EXTRA_PASSWORD_EXPIRING = "EXPIRING";
+ private static final String EXTRA_PASSWORD_EXPIRED = "EXPIRED";
+
+ private static final String SAVESTATE_INITIALIZED_TAG = "initialized";
+ private static final String SAVESTATE_TRIED_ADD_ADMINISTRATOR_TAG = "triedAddAdministrator";
+ private static final String SAVESTATE_TRIED_SET_PASSWORD_TAG = "triedSetpassword";
+ private static final String SAVESTATE_TRIED_SET_ENCRYPTION_TAG = "triedSetEncryption";
+ private static final String SAVESTATE_ACCOUNT_TAG = "account";
+
+ private static final int REQUEST_ENABLE = 1;
+ private static final int REQUEST_PASSWORD = 2;
+ private static final int REQUEST_ENCRYPTION = 3;
+
+ private boolean mTriedAddAdministrator;
+ private boolean mTriedSetPassword;
+ private boolean mTriedSetEncryption;
+
+ private Account mAccount;
+
+ protected boolean mInitialized;
+
+ private Handler mHandler;
+ private boolean mActivityResumed;
+
+ private static final int ACCOUNT_POLICY_LOADER_ID = 0;
+ private AccountAndPolicyLoaderCallbacks mAPLoaderCallbacks;
+ private Bundle mAPLoaderArgs;
+
+ public static Uri getUpdateSecurityUri(final long accountId, final boolean showDialog) {
+ final Uri.Builder baseUri = Uri.parse("auth://" + EmailContent.EMAIL_PACKAGE_NAME +
+ ".ACCOUNT_SECURITY/").buildUpon();
+ IntentUtilities.setAccountId(baseUri, accountId);
+ baseUri.appendQueryParameter(EXTRA_SHOW_DIALOG, Boolean.toString(showDialog));
+ return baseUri.build();
+ }
+
+ /**
+ * Used for generating intent for this activity (which is intended to be launched
+ * from a notification.)
+ *
+ * @param context Calling context for building the intent
+ * @param accountId The account of interest
+ * @param showDialog If true, a simple warning dialog will be shown before kicking off
+ * the necessary system settings. Should be true anywhere the context of the security settings
+ * is not clear (e.g. any time after the account has been set up).
+ * @return an Intent which can be used to view that account
+ */
+ public static Intent actionUpdateSecurityIntent(Context context, long accountId,
+ boolean showDialog) {
+ Intent intent = new Intent(context, AccountSecurity.class);
+ intent.putExtra(EXTRA_ACCOUNT_ID, accountId);
+ intent.putExtra(EXTRA_SHOW_DIALOG, showDialog);
+ return intent;
+ }
+
+ /**
+ * Used for generating intent for this activity (which is intended to be launched
+ * from a notification.) This is a special mode of this activity which exists only
+ * to give the user a dialog (for context) about a device pin/password expiration event.
+ */
+ public static Intent actionDevicePasswordExpirationIntent(Context context, long accountId,
+ boolean expired) {
+ Intent intent = new ForwardingIntent(context, AccountSecurity.class);
+ intent.putExtra(EXTRA_ACCOUNT_ID, accountId);
+ intent.putExtra(expired ? EXTRA_PASSWORD_EXPIRED : EXTRA_PASSWORD_EXPIRING, true);
+ return intent;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mHandler = new Handler();
+
+ final Intent i = getIntent();
+ final long accountId;
+ Bundle extras = i.getExtras();
+ if (extras == null) {
+ // We have been invoked via a uri. We need to get our parameters from the URI instead
+ // of looking in the intent extras.
+ extras = new Bundle();
+ accountId = IntentUtilities.getAccountIdFromIntent(i);
+ extras.putLong(EXTRA_ACCOUNT_ID, accountId);
+ boolean showDialog = false;
+ final String value = i.getData().getQueryParameter(EXTRA_SHOW_DIALOG);
+ if (!TextUtils.isEmpty(value)) {
+ showDialog = Boolean.getBoolean(value);
+ }
+ extras.putBoolean(EXTRA_SHOW_DIALOG, showDialog);
+ } else {
+ accountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1);
+ extras = i.getExtras();
+ }
+
+ final SecurityPolicy security = SecurityPolicy.getInstance(this);
+ security.clearNotification();
+ if (accountId == -1) {
+ finish();
+ return;
+ }
+
+ if (savedInstanceState != null) {
+ mInitialized = savedInstanceState.getBoolean(SAVESTATE_INITIALIZED_TAG, false);
+
+ mTriedAddAdministrator =
+ savedInstanceState.getBoolean(SAVESTATE_TRIED_ADD_ADMINISTRATOR_TAG, false);
+ mTriedSetPassword =
+ savedInstanceState.getBoolean(SAVESTATE_TRIED_SET_PASSWORD_TAG, false);
+ mTriedSetEncryption =
+ savedInstanceState.getBoolean(SAVESTATE_TRIED_SET_ENCRYPTION_TAG, false);
+
+ mAccount = savedInstanceState.getParcelable(SAVESTATE_ACCOUNT_TAG);
+ }
+
+ if (!mInitialized) {
+ startAccountAndPolicyLoader(extras);
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(final Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putBoolean(SAVESTATE_INITIALIZED_TAG, mInitialized);
+
+ outState.putBoolean(SAVESTATE_TRIED_ADD_ADMINISTRATOR_TAG, mTriedAddAdministrator);
+ outState.putBoolean(SAVESTATE_TRIED_SET_PASSWORD_TAG, mTriedSetPassword);
+ outState.putBoolean(SAVESTATE_TRIED_SET_ENCRYPTION_TAG, mTriedSetEncryption);
+
+ outState.putParcelable(SAVESTATE_ACCOUNT_TAG, mAccount);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mActivityResumed = false;
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mActivityResumed = true;
+ tickleAccountAndPolicyLoader();
+ }
+
+ protected boolean isActivityResumed() {
+ return mActivityResumed;
+ }
+
+ private void tickleAccountAndPolicyLoader() {
+ // If we're already initialized we don't need to tickle.
+ if (!mInitialized) {
+ getLoaderManager().initLoader(ACCOUNT_POLICY_LOADER_ID, mAPLoaderArgs,
+ mAPLoaderCallbacks);
+ }
+ }
+
+ private void startAccountAndPolicyLoader(final Bundle args) {
+ mAPLoaderArgs = args;
+ mAPLoaderCallbacks = new AccountAndPolicyLoaderCallbacks();
+ tickleAccountAndPolicyLoader();
+ }
+
+ private class AccountAndPolicyLoaderCallbacks
+ implements LoaderManager.LoaderCallbacks<Account> {
+ @Override
+ public Loader<Account> onCreateLoader(final int id, final Bundle args) {
+ final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
+ final boolean showDialog = args.getBoolean(EXTRA_SHOW_DIALOG, false);
+ final boolean passwordExpiring =
+ args.getBoolean(EXTRA_PASSWORD_EXPIRING, false);
+ final boolean passwordExpired =
+ args.getBoolean(EXTRA_PASSWORD_EXPIRED, false);
+
+ return new AccountAndPolicyLoader(getApplicationContext(), accountId,
+ showDialog, passwordExpiring, passwordExpired);
+ }
+
+ @Override
+ public void onLoadFinished(final Loader<Account> loader, final Account account) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ final AccountSecurity activity = AccountSecurity.this;
+ if (!activity.isActivityResumed()) {
+ return;
+ }
+
+ if (account == null || (account.mPolicyKey != 0 && account.mPolicy == null)) {
+ activity.finish();
+ LogUtils.d(TAG, "could not load account or policy in AccountSecurity");
+ return;
+ }
+
+ if (!activity.mInitialized) {
+ activity.mInitialized = true;
+
+ final AccountAndPolicyLoader apLoader = (AccountAndPolicyLoader) loader;
+ activity.completeCreate(account, apLoader.mShowDialog,
+ apLoader.mPasswordExpiring, apLoader.mPasswordExpired);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Account> loader) {}
+ }
+
+ private static class AccountAndPolicyLoader extends MailAsyncTaskLoader<Account> {
+ private final long mAccountId;
+ public final boolean mShowDialog;
+ public final boolean mPasswordExpiring;
+ public final boolean mPasswordExpired;
+
+ private final Context mContext;
+
+ AccountAndPolicyLoader(final Context context, final long accountId,
+ final boolean showDialog, final boolean passwordExpiring,
+ final boolean passwordExpired) {
+ super(context);
+ mContext = context;
+ mAccountId = accountId;
+ mShowDialog = showDialog;
+ mPasswordExpiring = passwordExpiring;
+ mPasswordExpired = passwordExpired;
+ }
+
+ @Override
+ public Account loadInBackground() {
+ final Account account = Account.restoreAccountWithId(mContext, mAccountId);
+ if (account == null) {
+ return null;
+ }
+
+ final long policyId = account.mPolicyKey;
+ if (policyId != 0) {
+ account.mPolicy = Policy.restorePolicyWithId(mContext, policyId);
+ }
+
+ account.getOrCreateHostAuthRecv(mContext);
+
+ return account;
+ }
+
+ @Override
+ protected void onDiscardResult(Account result) {}
+ }
+
+ protected void completeCreate(final Account account, final boolean showDialog,
+ final boolean passwordExpiring, final boolean passwordExpired) {
+ mAccount = account;
+
+ // Special handling for password expiration events
+ if (passwordExpiring || passwordExpired) {
+ FragmentManager fm = getFragmentManager();
+ if (fm.findFragmentByTag("password_expiration") == null) {
+ PasswordExpirationDialog dialog =
+ PasswordExpirationDialog.newInstance(mAccount.getDisplayName(),
+ passwordExpired);
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Showing password expiration dialog");
+ }
+ dialog.show(fm, "password_expiration");
+ }
+ return;
+ }
+ // Otherwise, handle normal security settings flow
+ if (mAccount.mPolicyKey != 0) {
+ // This account wants to control security
+ if (showDialog) {
+ // Show dialog first, unless already showing (e.g. after rotation)
+ FragmentManager fm = getFragmentManager();
+ if (fm.findFragmentByTag("security_needed") == null) {
+ SecurityNeededDialog dialog =
+ SecurityNeededDialog.newInstance(mAccount.getDisplayName());
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Showing security needed dialog");
+ }
+ dialog.show(fm, "security_needed");
+ }
+ } else {
+ // Go directly to security settings
+ tryAdvanceSecurity(mAccount);
+ }
+ return;
+ }
+ finish();
+ }
+
+ /**
+ * After any of the activities return, try to advance to the "next step"
+ */
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ tryAdvanceSecurity(mAccount);
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ /**
+ * Walk the user through the required steps to become an active administrator and with
+ * the requisite security settings for the given account.
+ *
+ * These steps will be repeated each time we return from a given attempt (e.g. asking the
+ * user to choose a device pin/password). In a typical activation, we may repeat these
+ * steps a few times. It may go as far as step 5 (password) or step 6 (encryption), but it
+ * will terminate when step 2 (isActive()) succeeds.
+ *
+ * If at any point we do not advance beyond a given user step, (e.g. the user cancels
+ * instead of setting a password) we simply repost the security notification, and exit.
+ * We never want to loop here.
+ */
+ private void tryAdvanceSecurity(Account account) {
+ SecurityPolicy security = SecurityPolicy.getInstance(this);
+ // Step 1. Check if we are an active device administrator, and stop here to activate
+ if (!security.isActiveAdmin()) {
+ if (mTriedAddAdministrator) {
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Not active admin: repost notification");
+ }
+ repostNotification(account, security);
+ finish();
+ } else {
+ mTriedAddAdministrator = true;
+ // retrieve name of server for the format string
+ final HostAuth hostAuth = account.mHostAuthRecv;
+ if (hostAuth == null) {
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "No HostAuth: repost notification");
+ }
+ repostNotification(account, security);
+ finish();
+ } else {
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Not active admin: post initial notification");
+ }
+ // try to become active - must happen here in activity, to get result
+ Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
+ intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+ security.getAdminComponent());
+ intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
+ this.getString(R.string.account_security_policy_explanation_fmt,
+ hostAuth.mAddress));
+ startActivityForResult(intent, REQUEST_ENABLE);
+ }
+ }
+ return;
+ }
+
+ // Step 2. Check if the current aggregate security policy is being satisfied by the
+ // DevicePolicyManager (the current system security level).
+ if (security.isActive(null)) {
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Security active; clear holds");
+ }
+ Account.clearSecurityHoldOnAllAccounts(this);
+ security.syncAccount(account);
+ security.clearNotification();
+ finish();
+ return;
+ }
+
+ // Step 3. Try to assert the current aggregate security requirements with the system.
+ security.setActivePolicies();
+
+ // Step 4. Recheck the security policy, and determine what changes are needed (if any)
+ // to satisfy the requirements.
+ int inactiveReasons = security.getInactiveReasons(null);
+
+ // Step 5. If password is needed, try to have the user set it
+ if ((inactiveReasons & SecurityPolicy.INACTIVE_NEED_PASSWORD) != 0) {
+ if (mTriedSetPassword) {
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Password needed; repost notification");
+ }
+ repostNotification(account, security);
+ finish();
+ } else {
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Password needed; request it via DPM");
+ }
+ mTriedSetPassword = true;
+ // launch the activity to have the user set a new password.
+ Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+ startActivityForResult(intent, REQUEST_PASSWORD);
+ }
+ return;
+ }
+
+ // Step 6. If encryption is needed, try to have the user set it
+ if ((inactiveReasons & SecurityPolicy.INACTIVE_NEED_ENCRYPTION) != 0) {
+ if (mTriedSetEncryption) {
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Encryption needed; repost notification");
+ }
+ repostNotification(account, security);
+ finish();
+ } else {
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Encryption needed; request it via DPM");
+ }
+ mTriedSetEncryption = true;
+ // launch the activity to start up encryption.
+ Intent intent = new Intent(DevicePolicyManager.ACTION_START_ENCRYPTION);
+ startActivityForResult(intent, REQUEST_ENCRYPTION);
+ }
+ return;
+ }
+
+ // Step 7. No problems were found, so clear holds and exit
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Policies enforced; clear holds");
+ }
+ Account.clearSecurityHoldOnAllAccounts(this);
+ security.syncAccount(account);
+ security.clearNotification();
+ finish();
+ }
+
+ /**
+ * Mark an account as not-ready-for-sync and post a notification to bring the user back here
+ * eventually.
+ */
+ private static void repostNotification(final Account account, final SecurityPolicy security) {
+ if (account == null) return;
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ security.policiesRequired(account.mId);
+ return null;
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ /**
+ * Dialog briefly shown in some cases, to indicate the user that a security update is needed.
+ * If the user clicks OK, we proceed into the "tryAdvanceSecurity" flow. If the user cancels,
+ * we repost the notification and finish() the activity.
+ */
+ public static class SecurityNeededDialog extends DialogFragment
+ implements DialogInterface.OnClickListener {
+ private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name";
+
+ // Public no-args constructor needed for fragment re-instantiation
+ public SecurityNeededDialog() {}
+
+ /**
+ * Create a new dialog.
+ */
+ public static SecurityNeededDialog newInstance(String accountName) {
+ final SecurityNeededDialog dialog = new SecurityNeededDialog();
+ Bundle b = new Bundle();
+ b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName);
+ dialog.setArguments(b);
+ return dialog;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME);
+
+ final Context context = getActivity();
+ final Resources res = context.getResources();
+ final AlertDialog.Builder b = new AlertDialog.Builder(context);
+ b.setTitle(R.string.account_security_dialog_title);
+ b.setIconAttribute(android.R.attr.alertDialogIcon);
+ b.setMessage(res.getString(R.string.account_security_dialog_content_fmt, accountName));
+ b.setPositiveButton(android.R.string.ok, this);
+ b.setNegativeButton(android.R.string.cancel, this);
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "Posting security needed dialog");
+ }
+ return b.create();
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss();
+ AccountSecurity activity = (AccountSecurity) getActivity();
+ if (activity.mAccount == null) {
+ // Clicked before activity fully restored - probably just monkey - exit quickly
+ activity.finish();
+ return;
+ }
+ switch (which) {
+ case DialogInterface.BUTTON_POSITIVE:
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "User accepts; advance to next step");
+ }
+ activity.tryAdvanceSecurity(activity.mAccount);
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ if (DebugUtils.DEBUG || DEBUG) {
+ LogUtils.d(TAG, "User declines; repost notification");
+ }
+ AccountSecurity.repostNotification(
+ activity.mAccount, SecurityPolicy.getInstance(activity));
+ activity.finish();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Dialog briefly shown in some cases, to indicate the user that the PIN/Password is expiring
+ * or has expired. If the user clicks OK, we launch the password settings screen.
+ */
+ public static class PasswordExpirationDialog extends DialogFragment
+ implements DialogInterface.OnClickListener {
+ private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name";
+ private static final String BUNDLE_KEY_EXPIRED = "expired";
+
+ /**
+ * Create a new dialog.
+ */
+ public static PasswordExpirationDialog newInstance(String accountName, boolean expired) {
+ final PasswordExpirationDialog dialog = new PasswordExpirationDialog();
+ Bundle b = new Bundle();
+ b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName);
+ b.putBoolean(BUNDLE_KEY_EXPIRED, expired);
+ dialog.setArguments(b);
+ return dialog;
+ }
+
+ // Public no-args constructor needed for fragment re-instantiation
+ public PasswordExpirationDialog() {}
+
+ /**
+ * Note, this actually creates two slightly different dialogs (for expiring vs. expired)
+ */
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME);
+ final boolean expired = getArguments().getBoolean(BUNDLE_KEY_EXPIRED);
+ final int titleId = expired
+ ? R.string.password_expired_dialog_title
+ : R.string.password_expire_warning_dialog_title;
+ final int contentId = expired
+ ? R.string.password_expired_dialog_content_fmt
+ : R.string.password_expire_warning_dialog_content_fmt;
+
+ final Context context = getActivity();
+ final Resources res = context.getResources();
+ return new AlertDialog.Builder(context)
+ .setTitle(titleId)
+ .setIconAttribute(android.R.attr.alertDialogIcon)
+ .setMessage(res.getString(contentId, accountName))
+ .setPositiveButton(android.R.string.ok, this)
+ .setNegativeButton(android.R.string.cancel, this)
+ .create();
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss();
+ AccountSecurity activity = (AccountSecurity) getActivity();
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+ activity.startActivity(intent);
+ }
+ activity.finish();
+ }
+ }
+}