From 572c06f91be8c809b8978d985259564f88c6f212 Mon Sep 17 00:00:00 2001 From: Andrew Stadler Date: Fri, 11 Jun 2010 11:21:41 -0700 Subject: [PATCH] DO NOT MERGE - Revert workaround for KeyguardLock problem This reverts commit 3ee0cad5f5e21a24dbe43d21afaac1dd76a2059b. Because commit 284b62e1b8c3419bfd02c6fea5ba0a68146c06f8 fixes the underlying conflict between DeviceAdmin policies and apps attempting to disable the Keyguard Lock, this patch is no longer required. Accounts with a server policy requiring a device PIN or Password will now work properly. Bug: 2737842 Change-Id: I533c27a01a8a331dc11a0cb84bcc78f48edf621c --- AndroidManifest.xml | 7 -- res/values/strings.xml | 6 -- src/com/android/email/Email.java | 6 -- src/com/android/email/SecurityPolicy.java | 66 -------------- .../email/activity/setup/AccountSecurity.java | 86 ++----------------- .../activity/setup/AccountSetupNames.java | 23 +---- .../android/email/service/BootReceiver.java | 14 +-- 7 files changed, 15 insertions(+), 193 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 19dea82de..a21a23d45 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -235,13 +235,6 @@ - - - - - - - diff --git a/res/values/strings.xml b/res/values/strings.xml index 0d651d49b..95b4e9ee5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -681,12 +681,6 @@ Email Enables server-specified security policies - - Screen lock disabled - - This account cannot be used while the - application \"%s\" is installed, because it - interferes with the operation of the screen lock. diff --git a/src/com/android/email/Email.java b/src/com/android/email/Email.java index b43cf94ea..3c5bcb963 100644 --- a/src/com/android/email/Email.java +++ b/src/com/android/email/Email.java @@ -250,12 +250,6 @@ public class Email extends Application { */ MailService.actionReschedule(context); } - // If enabling, clear the cached test for keyguard-disabling apps; This is because - // we may have missed package install/replace/remove broadcasts while we had no accounts - // and the BootReceiver was disabled. - if (enabled) { - SecurityPolicy.getInstance(context.getApplicationContext()).invalidateKeyguardCache(); - } } @Override diff --git a/src/com/android/email/SecurityPolicy.java b/src/com/android/email/SecurityPolicy.java index 335aa75f7..5dc9c14e5 100644 --- a/src/com/android/email/SecurityPolicy.java +++ b/src/com/android/email/SecurityPolicy.java @@ -33,16 +33,11 @@ import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; import android.database.Cursor; import android.media.AudioManager; import android.net.Uri; import android.util.Log; -import java.util.List; - /** * Utility functions to support reading and writing security policies, and handshaking the device * into and out of various security states. @@ -54,10 +49,6 @@ public class SecurityPolicy { private DevicePolicyManager mDPM; private ComponentName mAdminName; private PolicySet mAggregatePolicy; - // false = unknown, true = mKeyguardDisablePackageName is valid (or null) - private boolean mKeyguardDisableChecked; - // null = no apps disabling, non-null = one or more apps disabling - private String mKeyguardDisablePackageName; /* package */ static final PolicySet NO_POLICY_SET = new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false); @@ -110,7 +101,6 @@ public class SecurityPolicy { mDPM = null; mAdminName = new ComponentName(context, PolicyAdmin.class); mAggregatePolicy = null; - mKeyguardDisableChecked = false; } /** @@ -275,13 +265,6 @@ public class SecurityPolicy { } } if (policies.mPasswordMode > 0) { - // If the server requests a password policy of any kind (PIN, password, etc) - // and the user has a keyguard-disable package, then we cannot support the - // policy. In a rare case of a server that doesn't enforce PIN/Password, we - // won't do this test. - if (getKeyguardDisablePackage() != null) { - return false; - } if (dpm.getPasswordQuality(mAdminName) < policies.getDPManagerPasswordQuality()) { return false; } @@ -627,55 +610,6 @@ public class SecurityPolicy { return dpm.isAdminActive(mAdminName); } - /** - * Invalidate the cached result of checking for lock screen disablers. Called by package - * add/replace/delete broadcasts. - */ - public synchronized void invalidateKeyguardCache() { - mKeyguardDisableChecked = false; - mKeyguardDisablePackageName = null; - } - - /** - * Return the name of any app that is disabling the keyguard (lock screen) - in which case, - * we must treat the device as if required lock screen policies are not met. - * - * @return non-null if any app is disabling the keyguard - */ - public synchronized String getKeyguardDisablePackage() { - if (!mKeyguardDisableChecked) { - mKeyguardDisablePackageName = findKeyguardPermission(); - mKeyguardDisableChecked = true; - } - return mKeyguardDisablePackageName; - } - - /** - * Scan installed packages and look for DISABLE_KEYGUARD permission. Return the first - * installed packages (if any are found). This won't be cheap, so do it as little as possible. - * - * @return the display name of the package, or null if all clear - */ - private String findKeyguardPermission() { - PackageManager pm = mContext.getPackageManager(); - List packages = pm.getInstalledPackages(0); - for (PackageInfo info : packages) { - // skip over system packages; they are allowed to have the permission - if (0 != (info.applicationInfo.flags & - (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP))) { - continue; - } - // all other packages, check for specific permission - int permissionResult = pm.checkPermission(android.Manifest.permission.DISABLE_KEYGUARD, - info.packageName); - if (permissionResult == PackageManager.PERMISSION_GRANTED) { - Log.d(Email.LOG_TAG, "DISABLE_KEYGUARD found in " + info.packageName); - return info.applicationInfo.loadLabel(pm).toString(); - } - } - return null; - } - /** * Report admin component name - for making calls into device policy manager */ diff --git a/src/com/android/email/activity/setup/AccountSecurity.java b/src/com/android/email/activity/setup/AccountSecurity.java index d2b66fd5d..68bdbc498 100644 --- a/src/com/android/email/activity/setup/AccountSecurity.java +++ b/src/com/android/email/activity/setup/AccountSecurity.java @@ -21,11 +21,8 @@ import com.android.email.SecurityPolicy; import com.android.email.provider.EmailContent.Account; import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; import android.app.admin.DevicePolicyManager; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; @@ -43,12 +40,8 @@ public class AccountSecurity extends Activity { private static final String EXTRA_ACCOUNT_ID = "com.android.email.activity.setup.ACCOUNT_ID"; - private static final int DIALOG_KEYGUARD_DISABLED = 1; - private static final int REQUEST_ENABLE = 1; - private String mKeyguardBlockerName; - /** * Used for generating intent for this activity (which is intended to be launched * from a notification.) @@ -66,11 +59,6 @@ public class AccountSecurity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - boolean finishNow = true; - // Return RESULT_OK in all cases unless explicitly changed (see below). This is ignored - // when we're launched from notification, but it's checked when we're launched from - // (and return to) AccountSetupNames. - setResult(Activity.RESULT_OK); Intent i = getIntent(); long accountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1); @@ -80,8 +68,7 @@ public class AccountSecurity extends Activity { // TODO: spin up a thread to do this in the background, because of DB ops Account account = Account.restoreAccountWithId(this, accountId); if (account != null) { - if ((account.mSecurityFlags != 0) || - (0 != (account.mFlags & Account.FLAGS_SECURITY_HOLD))) { + if (account.mSecurityFlags != 0) { // This account wants to control security if (!security.isActiveAdmin()) { // try to become active - must happen here in this activity, to get result @@ -96,14 +83,12 @@ public class AccountSecurity extends Activity { return; } else { // already active - try to set actual policies, finish, and return - finishNow = setActivePolicies(); + setActivePolicies(); } } } } - if (finishNow) { - finish(); - } + finish(); } /** @@ -111,12 +96,11 @@ public class AccountSecurity extends Activity { */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - boolean finishNow = true; switch (requestCode) { case REQUEST_ENABLE: if (resultCode == Activity.RESULT_OK) { // now active - try to set actual policies - finishNow = setActivePolicies(); + setActivePolicies(); } else { // failed - repost notification, and exit final long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1); @@ -131,85 +115,31 @@ public class AccountSecurity extends Activity { } } } - // This activity has no layout and in most cases serves only as a dispatcher for - // checking and adjusting device security policies. However, in a few cases, it - // presents an error dialog. In those cases, setActivePolicies() will return false, and - // we don't call finish() so the dialog is able to display. - if (finishNow) { - finish(); - } + finish(); super.onActivityResult(requestCode, resultCode, data); } /** * Now that we are connected as an active device admin, try to set the device to the * correct security level, and ask for a password if necessary. - * - * @return true if OK to finish the activity (false if we posted a dialog) */ - private boolean setActivePolicies() { + private void setActivePolicies() { SecurityPolicy sp = SecurityPolicy.getInstance(this); // check current security level - if sufficient, we're done! if (sp.isActive(null)) { sp.clearAccountHoldFlags(); - return true; + return; } // set current security level sp.setActivePolicies(); // check current security level - if sufficient, we're done! if (sp.isActive(null)) { sp.clearAccountHoldFlags(); - return true; - } - // if the problem is an app blocking the lock screen, notify the user - String keyguardBlocker = sp.getKeyguardDisablePackage(); - if (keyguardBlocker != null) { - mKeyguardBlockerName = keyguardBlocker; - showDialog(DIALOG_KEYGUARD_DISABLED); - // Set activity to return RESULT_CANCELED (after dialog) to notify caller that we - // didn't configure policies completely. - setResult(Activity.RESULT_CANCELED); - return false; + return; } // if not sufficient, launch the activity to have the user set a new password. Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); startActivity(intent); - // TODO: use startActivityForResult, and when we see the result, recheck to see - // if the user actually entered a sufficient password. If not, repost the notification. - return true; } - @Override - public Dialog onCreateDialog(int id) { - switch (id) { - case DIALOG_KEYGUARD_DISABLED: - return new AlertDialog.Builder(this) - .setIcon(android.R.drawable.ic_dialog_alert) - .setTitle(R.string.keyguard_disabled_dlg_title) - .setMessage(getString(R.string.keyguard_disabled_dlg_message_fmt, - mKeyguardBlockerName)) - .setNeutralButton(R.string.okay_action, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - dismissDialog(DIALOG_KEYGUARD_DISABLED); - finish(); - } - }) - .setCancelable(false) - .create(); - } - return super.onCreateDialog(id); - } - - /** - * Update a cached dialog with current values (e.g. account name) - */ - @Override - public void onPrepareDialog(int id, Dialog dialog) { - switch (id) { - case DIALOG_KEYGUARD_DISABLED: - AlertDialog alert = (AlertDialog) dialog; - alert.setMessage(getString(R.string.keyguard_disabled_dlg_message_fmt, - mKeyguardBlockerName)); - } - } } diff --git a/src/com/android/email/activity/setup/AccountSetupNames.java b/src/com/android/email/activity/setup/AccountSetupNames.java index c8885543d..1b148c5c6 100644 --- a/src/com/android/email/activity/setup/AccountSetupNames.java +++ b/src/com/android/email/activity/setup/AccountSetupNames.java @@ -19,7 +19,6 @@ package com.android.email.activity.setup; import com.android.email.AccountBackupRestore; import com.android.email.R; import com.android.email.Utility; -import com.android.email.activity.AccountFolderList; import com.android.email.activity.Welcome; import com.android.email.provider.EmailContent; import com.android.email.provider.EmailContent.Account; @@ -147,25 +146,12 @@ public class AccountSetupNames extends Activity implements OnClickListener { @Override public void onBackPressed() { - onBackPressed(true); // OK to "proceed" to next step (the account has been created) - } - - private void onBackPressed(boolean okToProceed) { boolean easFlowMode = getIntent().getBooleanExtra(EXTRA_EAS_FLOW, false); if (easFlowMode) { AccountSetupBasics.actionAccountCreateFinishedEas(this); } else { if (mAccount != null) { - if (okToProceed) { - AccountSetupBasics.actionAccountCreateFinished(this, mAccount.mId); - } else { - // This is what we do if the account was created, but somebody called - // onBackPressed(false), indicating that the new account's inbox should not be - // entered. In this case, we'll just go back to the accounts list. - // We don't use the typical "Welcome" activity because if there is only one - // account, it will also try to visit the inbox of that account. - AccountFolderList.actionShowAccounts(this); - } + AccountSetupBasics.actionAccountCreateFinished(this, mAccount.mId); } else { // Safety check here; If mAccount is null (due to external issues or bugs) // just rewind back to Welcome, which can handle any configuration of accounts @@ -263,15 +249,14 @@ public class AccountSetupNames extends Activity implements OnClickListener { /** * 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: - // If we get RESULT_CANCEL, we tell onBackPressed that there was an error, - // and it won't try to take us to the MessageList of the new account. - onBackPressed(resultCode == Activity.RESULT_OK); - break; + onBackPressed(); } super.onActivityResult(requestCode, resultCode, data); } diff --git a/src/com/android/email/service/BootReceiver.java b/src/com/android/email/service/BootReceiver.java index 8793e1b1a..880773c2b 100644 --- a/src/com/android/email/service/BootReceiver.java +++ b/src/com/android/email/service/BootReceiver.java @@ -18,7 +18,6 @@ package com.android.email.service; import com.android.email.AccountBackupRestore; import com.android.email.Email; -import com.android.email.SecurityPolicy; import android.content.BroadcastReceiver; import android.content.Context; @@ -30,24 +29,17 @@ public class BootReceiver extends BroadcastReceiver { // Restore accounts, if it has not happened already AccountBackupRestore.restoreAccountsIfNeeded(context); - String intentAction = intent.getAction(); - - if (Intent.ACTION_BOOT_COMPLETED.equals(intentAction)) { + if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { // Returns true if there are any accounts if (Email.setServicesEnabled(context)) { MailService.actionReschedule(context); } } - else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(intentAction)) { + else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(intent.getAction())) { MailService.actionCancel(context); } - else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(intentAction)) { + else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(intent.getAction())) { MailService.actionReschedule(context); } - else if (Intent.ACTION_PACKAGE_ADDED.equals(intentAction) || - Intent.ACTION_PACKAGE_REPLACED.equals(intentAction) || - Intent.ACTION_PACKAGE_REMOVED.equals(intentAction)) { - SecurityPolicy.getInstance(context.getApplicationContext()).invalidateKeyguardCache(); - } } }