DO NOT MERGE Workaround for KeyguardLock problem
* The device policies that enforce the use of a device PIN or password can be sidestepped by apps that implement KeyguardManager.KeyguardLock * This renders the policies unuseable * To prevent this, the email app now scans for any packages holding the DISABLE_KEYGUARD permission. The existence of any non-system app with this permission will put all security-enabled EAS accounts into a security hold, and post a dialog describing the problem. * The user must uninstall any such app(s) in order to sync their EAS data. Bug: 2737842 Change-Id: I4c96d76b12d9242b5c755dd60d7578a825fae597
This commit is contained in:
parent
27e75533e9
commit
3ee0cad5f5
@ -235,6 +235,13 @@
|
|||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.DEVICE_STORAGE_OK" />
|
<action android:name="android.intent.action.DEVICE_STORAGE_OK" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.PACKAGE_ADDED" />
|
||||||
|
<action android:name="android.intent.action.PACKAGE_CHANGED" />
|
||||||
|
<action android:name="android.intent.action.PACKAGE_REMOVED" />
|
||||||
|
<data android:scheme="package" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<!-- Support for DeviceAdmin / DevicePolicyManager. See SecurityPolicy class for impl. -->
|
<!-- Support for DeviceAdmin / DevicePolicyManager. See SecurityPolicy class for impl. -->
|
||||||
|
@ -681,6 +681,12 @@
|
|||||||
<string name="device_admin_label">Email</string>
|
<string name="device_admin_label">Email</string>
|
||||||
<!-- Long-form description of the DeviceAdmin (2nd line in settings & in user conf. screen) -->
|
<!-- Long-form description of the DeviceAdmin (2nd line in settings & in user conf. screen) -->
|
||||||
<string name="device_admin_description">Enables server-specified security policies</string>
|
<string name="device_admin_description">Enables server-specified security policies</string>
|
||||||
|
<!-- Title of keyguard-lock-disabled dialog box -->
|
||||||
|
<string name="keyguard_disabled_dlg_title">Screen lock disabled</string>
|
||||||
|
<!-- Message of keyguard-lock-disabled dialog box -->
|
||||||
|
<string name="keyguard_disabled_dlg_message_fmt">This account cannot be used while the
|
||||||
|
application \"<xliff:g id="application">%s</xliff:g>\" is installed, because it
|
||||||
|
interferes with the operation of the screen lock.</string>
|
||||||
|
|
||||||
<!-- Notification message in notifications window when calendar sync is
|
<!-- Notification message in notifications window when calendar sync is
|
||||||
automatically enabled for pre-existing Exchange accounts on upgrade -->
|
automatically enabled for pre-existing Exchange accounts on upgrade -->
|
||||||
|
@ -250,6 +250,12 @@ public class Email extends Application {
|
|||||||
*/
|
*/
|
||||||
MailService.actionReschedule(context);
|
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
|
@Override
|
||||||
|
@ -33,11 +33,16 @@ import android.content.ContentUris;
|
|||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
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.database.Cursor;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility functions to support reading and writing security policies, and handshaking the device
|
* Utility functions to support reading and writing security policies, and handshaking the device
|
||||||
* into and out of various security states.
|
* into and out of various security states.
|
||||||
@ -49,6 +54,10 @@ public class SecurityPolicy {
|
|||||||
private DevicePolicyManager mDPM;
|
private DevicePolicyManager mDPM;
|
||||||
private ComponentName mAdminName;
|
private ComponentName mAdminName;
|
||||||
private PolicySet mAggregatePolicy;
|
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 =
|
/* package */ static final PolicySet NO_POLICY_SET =
|
||||||
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false);
|
new PolicySet(0, PolicySet.PASSWORD_MODE_NONE, 0, 0, false);
|
||||||
@ -101,6 +110,7 @@ public class SecurityPolicy {
|
|||||||
mDPM = null;
|
mDPM = null;
|
||||||
mAdminName = new ComponentName(context, PolicyAdmin.class);
|
mAdminName = new ComponentName(context, PolicyAdmin.class);
|
||||||
mAggregatePolicy = null;
|
mAggregatePolicy = null;
|
||||||
|
mKeyguardDisableChecked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,6 +275,13 @@ public class SecurityPolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (policies.mPasswordMode > 0) {
|
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()) {
|
if (dpm.getPasswordQuality(mAdminName) < policies.getDPManagerPasswordQuality()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -610,6 +627,55 @@ public class SecurityPolicy {
|
|||||||
return dpm.isAdminActive(mAdminName);
|
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<PackageInfo> 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
|
* Report admin component name - for making calls into device policy manager
|
||||||
*/
|
*/
|
||||||
|
@ -21,8 +21,11 @@ import com.android.email.SecurityPolicy;
|
|||||||
import com.android.email.provider.EmailContent.Account;
|
import com.android.email.provider.EmailContent.Account;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
@ -40,8 +43,12 @@ public class AccountSecurity extends Activity {
|
|||||||
|
|
||||||
private static final String EXTRA_ACCOUNT_ID = "com.android.email.activity.setup.ACCOUNT_ID";
|
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 static final int REQUEST_ENABLE = 1;
|
||||||
|
|
||||||
|
private String mKeyguardBlockerName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for generating intent for this activity (which is intended to be launched
|
* Used for generating intent for this activity (which is intended to be launched
|
||||||
* from a notification.)
|
* from a notification.)
|
||||||
@ -59,6 +66,11 @@ public class AccountSecurity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(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();
|
Intent i = getIntent();
|
||||||
long accountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1);
|
long accountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1);
|
||||||
@ -68,7 +80,8 @@ public class AccountSecurity extends Activity {
|
|||||||
// TODO: spin up a thread to do this in the background, because of DB ops
|
// TODO: spin up a thread to do this in the background, because of DB ops
|
||||||
Account account = Account.restoreAccountWithId(this, accountId);
|
Account account = Account.restoreAccountWithId(this, accountId);
|
||||||
if (account != null) {
|
if (account != null) {
|
||||||
if (account.mSecurityFlags != 0) {
|
if ((account.mSecurityFlags != 0) ||
|
||||||
|
(0 != (account.mFlags & Account.FLAGS_SECURITY_HOLD))) {
|
||||||
// This account wants to control security
|
// This account wants to control security
|
||||||
if (!security.isActiveAdmin()) {
|
if (!security.isActiveAdmin()) {
|
||||||
// try to become active - must happen here in this activity, to get result
|
// try to become active - must happen here in this activity, to get result
|
||||||
@ -83,12 +96,14 @@ public class AccountSecurity extends Activity {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// already active - try to set actual policies, finish, and return
|
// already active - try to set actual policies, finish, and return
|
||||||
setActivePolicies();
|
finishNow = setActivePolicies();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finish();
|
if (finishNow) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,11 +111,12 @@ public class AccountSecurity extends Activity {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
boolean finishNow = true;
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case REQUEST_ENABLE:
|
case REQUEST_ENABLE:
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
// now active - try to set actual policies
|
// now active - try to set actual policies
|
||||||
setActivePolicies();
|
finishNow = setActivePolicies();
|
||||||
} else {
|
} else {
|
||||||
// failed - repost notification, and exit
|
// failed - repost notification, and exit
|
||||||
final long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
|
final long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1);
|
||||||
@ -115,31 +131,85 @@ public class AccountSecurity extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finish();
|
// 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();
|
||||||
|
}
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Now that we are connected as an active device admin, try to set the device to the
|
* 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.
|
* 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 void setActivePolicies() {
|
private boolean setActivePolicies() {
|
||||||
SecurityPolicy sp = SecurityPolicy.getInstance(this);
|
SecurityPolicy sp = SecurityPolicy.getInstance(this);
|
||||||
// check current security level - if sufficient, we're done!
|
// check current security level - if sufficient, we're done!
|
||||||
if (sp.isActive(null)) {
|
if (sp.isActive(null)) {
|
||||||
sp.clearAccountHoldFlags();
|
sp.clearAccountHoldFlags();
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
// set current security level
|
// set current security level
|
||||||
sp.setActivePolicies();
|
sp.setActivePolicies();
|
||||||
// check current security level - if sufficient, we're done!
|
// check current security level - if sufficient, we're done!
|
||||||
if (sp.isActive(null)) {
|
if (sp.isActive(null)) {
|
||||||
sp.clearAccountHoldFlags();
|
sp.clearAccountHoldFlags();
|
||||||
return;
|
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;
|
||||||
}
|
}
|
||||||
// if not sufficient, launch the activity to have the user set a new password.
|
// if not sufficient, launch the activity to have the user set a new password.
|
||||||
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
|
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
|
||||||
startActivity(intent);
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package com.android.email.activity.setup;
|
|||||||
import com.android.email.AccountBackupRestore;
|
import com.android.email.AccountBackupRestore;
|
||||||
import com.android.email.R;
|
import com.android.email.R;
|
||||||
import com.android.email.Utility;
|
import com.android.email.Utility;
|
||||||
|
import com.android.email.activity.AccountFolderList;
|
||||||
import com.android.email.activity.Welcome;
|
import com.android.email.activity.Welcome;
|
||||||
import com.android.email.provider.EmailContent;
|
import com.android.email.provider.EmailContent;
|
||||||
import com.android.email.provider.EmailContent.Account;
|
import com.android.email.provider.EmailContent.Account;
|
||||||
@ -146,12 +147,25 @@ public class AccountSetupNames extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
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);
|
boolean easFlowMode = getIntent().getBooleanExtra(EXTRA_EAS_FLOW, false);
|
||||||
if (easFlowMode) {
|
if (easFlowMode) {
|
||||||
AccountSetupBasics.actionAccountCreateFinishedEas(this);
|
AccountSetupBasics.actionAccountCreateFinishedEas(this);
|
||||||
} else {
|
} else {
|
||||||
if (mAccount != null) {
|
if (mAccount != null) {
|
||||||
AccountSetupBasics.actionAccountCreateFinished(this, mAccount.mId);
|
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);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Safety check here; If mAccount is null (due to external issues or bugs)
|
// 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
|
// just rewind back to Welcome, which can handle any configuration of accounts
|
||||||
@ -249,14 +263,15 @@ public class AccountSetupNames extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the eventual result from the security update activity
|
* 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
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case REQUEST_SECURITY:
|
case REQUEST_SECURITY:
|
||||||
onBackPressed();
|
// 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;
|
||||||
}
|
}
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package com.android.email.service;
|
|||||||
|
|
||||||
import com.android.email.AccountBackupRestore;
|
import com.android.email.AccountBackupRestore;
|
||||||
import com.android.email.Email;
|
import com.android.email.Email;
|
||||||
|
import com.android.email.SecurityPolicy;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -29,17 +30,24 @@ public class BootReceiver extends BroadcastReceiver {
|
|||||||
// Restore accounts, if it has not happened already
|
// Restore accounts, if it has not happened already
|
||||||
AccountBackupRestore.restoreAccountsIfNeeded(context);
|
AccountBackupRestore.restoreAccountsIfNeeded(context);
|
||||||
|
|
||||||
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
|
String intentAction = intent.getAction();
|
||||||
|
|
||||||
|
if (Intent.ACTION_BOOT_COMPLETED.equals(intentAction)) {
|
||||||
// Returns true if there are any accounts
|
// Returns true if there are any accounts
|
||||||
if (Email.setServicesEnabled(context)) {
|
if (Email.setServicesEnabled(context)) {
|
||||||
MailService.actionReschedule(context);
|
MailService.actionReschedule(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(intent.getAction())) {
|
else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(intentAction)) {
|
||||||
MailService.actionCancel(context);
|
MailService.actionCancel(context);
|
||||||
}
|
}
|
||||||
else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(intent.getAction())) {
|
else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(intentAction)) {
|
||||||
MailService.actionReschedule(context);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user