Force security activation after new account create

On new accounts, we can accelerate the process of setting up security
by explicitly checking (at the end of the security process).  The user
is not required to "answer" the asynchronous notification.

This is an imperfect solution, as a slow initial sync could leave the
user in a non-synced Inbox (with a notification waiting for them), but
we can come back to this after we evaluate real-world performance.

Bug: 2387961
This commit is contained in:
Andrew Stadler 2010-02-09 17:24:55 -08:00
parent 50d1610c43
commit d71d0b223a
3 changed files with 100 additions and 16 deletions

View File

@ -38,20 +38,11 @@ import android.net.Uri;
import android.util.Log;
/**
* Utility functions to support reading and writing security policies
*
* STOPSHIP - these TODO items are all part of finishing the feature
* TODO: When accounts are deleted, reduce policy and/or give up admin status
* TODO: Provide a way to check for policy issues at synchronous times such as entering
* message list or folder list.
* Utility functions to support reading and writing security policies, and handshaking the device
* into and out of various security states.
*/
public class SecurityPolicy {
/** STOPSHIP - ok to check in true for now, but must be false for shipping */
/** DO NOT CHECK IN WHILE 'true' */
// Until everything is connected, allow syncs to work
private static final boolean DEBUG_ALWAYS_ACTIVE = false;
private static SecurityPolicy sInstance = null;
private Context mContext;
private DevicePolicyManager mDPM;
@ -295,8 +286,8 @@ public class SecurityPolicy {
// making it this far means we passed!
return true;
}
// return false, not active - unless debugging enabled
return DEBUG_ALWAYS_ACTIVE;
// return false, not active
return false;
}
/**

View File

@ -25,7 +25,6 @@ import android.app.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
/**
* Psuedo-activity (no UI) to bootstrap the user up to a higher desired security level. This

View File

@ -20,11 +20,15 @@ import com.android.email.AccountBackupRestore;
import com.android.email.R;
import com.android.email.Utility;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.AccountColumns;
import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
@ -38,12 +42,20 @@ import android.widget.EditText;
public class AccountSetupNames extends Activity implements OnClickListener {
private static final String EXTRA_ACCOUNT_ID = "accountId";
private static final String EXTRA_EAS_FLOW = "easFlow";
private static final int REQUEST_SECURITY = 0;
private EditText mDescription;
private EditText mName;
private EmailContent.Account mAccount;
private Account mAccount;
private Button mDoneButton;
private CheckAccountStateTask mCheckAccountStateTask;
private static final int ACCOUNT_INFO_COLUMN_FLAGS = 0;
private static final int ACCOUNT_INFO_COLUMN_SECURITY_FLAGS = 1;
private static final String[] ACCOUNT_INFO_PROJECTION = new String[] {
AccountColumns.FLAGS, AccountColumns.SECURITY_FLAGS };
public static void actionSetNames(Activity fromActivity, long accountId, boolean easFlowMode) {
Intent i = new Intent(fromActivity, AccountSetupNames.class);
i.putExtra(EXTRA_ACCOUNT_ID, accountId);
@ -92,6 +104,17 @@ public class AccountSetupNames extends Activity implements OnClickListener {
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mCheckAccountStateTask != null &&
mCheckAccountStateTask.getStatus() != CheckAccountStateTask.Status.FINISHED) {
mCheckAccountStateTask.cancel(true);
mCheckAccountStateTask = null;
}
}
/**
* TODO: Validator should also trim the name string before checking it.
*/
@ -130,7 +153,11 @@ public class AccountSetupNames extends Activity implements OnClickListener {
mAccount.update(this, cv);
// Update the backup (side copy) of the accounts
AccountBackupRestore.backupAccounts(this);
onBackPressed();
// Before proceeding, launch an AsyncTask to test the account for any syncing problems,
// and if there's a problem, bring up the UI to update the security level.
mCheckAccountStateTask = new CheckAccountStateTask(mAccount.mId);
mCheckAccountStateTask.execute();
}
public void onClick(View v) {
@ -140,4 +167,71 @@ public class AccountSetupNames extends Activity implements OnClickListener {
break;
}
}
/**
* This async task is launched just before exiting. It's a last chance test, before leaving
* this activity, for the account being in a "hold" state, and gives the user a chance to
* update security, enter a device PIN, etc. for a more seamless account setup experience.
*
* TODO: If there was *any* indication that security might be required, we could at least
* force the DeviceAdmin activation step, without waiting for the initial sync/handshake
* to fail.
* TODO: If the user doesn't update the security, don't go to the MessageList.
*/
private class CheckAccountStateTask extends AsyncTask<Void, Void, Boolean> {
private long mAccountId;
public CheckAccountStateTask(long accountId) {
mAccountId = accountId;
}
@Override
protected Boolean doInBackground(Void... params) {
Cursor c = AccountSetupNames.this.getContentResolver().query(
ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId),
ACCOUNT_INFO_PROJECTION, null, null, null);
try {
if (c.moveToFirst()) {
int flags = c.getInt(ACCOUNT_INFO_COLUMN_FLAGS);
int securityFlags = c.getInt(ACCOUNT_INFO_COLUMN_SECURITY_FLAGS);
if ((flags & Account.FLAGS_SECURITY_HOLD) != 0) {
return Boolean.TRUE;
}
}
} finally {
c.close();
}
return Boolean.FALSE;
}
@Override
protected void onPostExecute(Boolean isSecurityHold) {
if (!isCancelled()) {
if (isSecurityHold) {
Intent i = AccountSecurity.actionUpdateSecurityIntent(
AccountSetupNames.this, mAccountId);
AccountSetupNames.this.startActivityForResult(i, REQUEST_SECURITY);
} else {
onBackPressed();
}
}
}
}
/**
* Handle the eventual result from the security update activity
*
* TODO: If the user doesn't update the security, don't go to the MessageList.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_SECURITY:
onBackPressed();
}
super.onActivityResult(requestCode, resultCode, data);
}
}