Logic to move phone into security-admin mode
* Create notification to display when syncs fail due to security
* Create psuedo-activity (no UI) to manage device admin state transitions
* Clean up and flesh out SecurityPolicy APIs'
* Add placeholders in EasSyncService showing how to react when policies
are not met and sync cannot continue.
Note: There are some STOPSHIP todo's at the top of SecurityPolicy.java.
These should explain any code that you might think is "missing".
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 76ff915..8eaa175 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -115,6 +115,11 @@
android:label="@string/account_settings_action"
>
</activity>
+ <activity
+ android:name=".activity.setup.AccountSecurity"
+ android.label="@string/account_security_title"
+ >
+ </activity>
<activity
android:name=".activity.Debug"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 99d374c..807bb6f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -502,6 +502,19 @@
<string name="account_setup_failed_security_policies_unsupported">
This server requires security features your phone does not support.</string>
+ <!-- Notification ticker when device security required -->
+ <string name="security_notification_ticker_fmt">
+ Account \"<xliff:g id="account">%s</xliff:g>\" requires security settings update.
+ </string>
+ <!-- Notification content title when device security required -->
+ <string name="security_notification_content_title">Update Security Settings</string>
+ <!-- Title of the activity that dispatches changes to device security. Not normally seen. -->
+ <string name="account_security_title">Device Security</string>
+ <!-- Additional diagnostic text when the email app asserts control of the phone. -->
+ <string name="account_security_policy_explanation_fmt">
+ The server <xliff:g id="server">%s</xliff:g> requires that you allow it to remotely control
+ some security features of your phone.</string>
+
<!-- "Setup could not finish" dialog action button -->
<string name="account_setup_failed_dlg_edit_details_action">Edit details</string>
<!-- On Settings screen, section heading -->
@@ -585,9 +598,9 @@
<string name="system_account_create_failed">The AccountManager could not create the Account; please try again.</string>
<!-- Strings that support the DeviceAdmin / DevicePolicyManager API -->
- <!-- Name of the DeviceAdmin (seen in settings - anywhere else?) -->
- <string name="device_admin_label">Email Device Administrator</string>
- <!-- Long-form description of the DeviceAdmin (seen in settings - anywhere else?) -->
- <string name="device_admin_description">Email Device Administrator - Long Description</string>
-
+ <!-- Name of the DeviceAdmin (seen in settings & in user confirmation screen) -->
+ <string name="device_admin_label">Email</string>
+ <!-- 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>
+
</resources>
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index b15dac7..8766c61 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -17,6 +17,8 @@
package com.android.exchange;
+import com.android.email.SecurityPolicy;
+import com.android.email.SecurityPolicy.PolicySet;
import com.android.email.codec.binary.Base64;
import com.android.email.mail.AuthenticationFailedException;
import com.android.email.mail.MessagingException;
@@ -964,25 +966,40 @@
}
while (!mStop) {
- userLog("Sending Account syncKey: ", mAccount.mSyncKey);
- Serializer s = new Serializer();
- s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY)
- .text(mAccount.mSyncKey).end().end().done();
- HttpResponse resp = sendHttpClientPost("FolderSync", s.toByteArray());
- if (mStop) break;
- int code = resp.getStatusLine().getStatusCode();
- if (code == HttpStatus.SC_OK) {
- HttpEntity entity = resp.getEntity();
- int len = (int)entity.getContentLength();
- if (len != 0) {
- InputStream is = entity.getContent();
- // Returns true if we need to sync again
- if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this))
- .parse()) {
- continue;
- }
- }
- } else if (isAuthError(code)) {
+ userLog("Sending Account syncKey: ", mAccount.mSyncKey);
+ Serializer s = new Serializer();
+ s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY)
+ .text(mAccount.mSyncKey).end().end().done();
+ HttpResponse resp = sendHttpClientPost("FolderSync", s.toByteArray());
+ if (mStop) break;
+ int code = resp.getStatusLine().getStatusCode();
+ if (code == HttpStatus.SC_OK) {
+ HttpEntity entity = resp.getEntity();
+ int len = (int)entity.getContentLength();
+ if (len != 0) {
+ InputStream is = entity.getContent();
+ // Returns true if we need to sync again
+ if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this))
+ .parse()) {
+ continue;
+ }
+ }
+ // // EVERYTHING IN THE code==403 BLOCK IS PLACEHOLDER/SAMPLE CODE
+ } else if (code == 403) { // security error
+ // Reality: Find out from server what policies are required
+ // Fake: Hardcode the policies
+ SecurityPolicy sp = SecurityPolicy.getInstance(mContext);
+ PolicySet ps = new PolicySet(4, PolicySet.PASSWORD_MODE_SIMPLE, 0, 0, true);
+ // Update the account
+ if (ps.writeAccount(mAccount, "securitySyncKey", true, mContext)) {
+ sp.updatePolicies(mAccount.mId);
+ }
+ // Notify that we are blocked because of policies
+ sp.policiesRequired(mAccount.mId);
+ // and exit (don't sync in this condition)
+ mExitStatus = EXIT_LOGIN_FAILURE;
+ // END PLACEHOLDER CODE
+ } else if (isAuthError(code)) {
mExitStatus = EXIT_LOGIN_FAILURE;
} else {
userLog("FolderSync response error: ", code);