1aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank/* 2aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Copyright (C) 2011 The Android Open Source Project 3aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * 4aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Licensed under the Apache License, Version 2.0 (the "License"); 5aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * you may not use this file except in compliance with the License. 6aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * You may obtain a copy of the License at 7aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * 8aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * http://www.apache.org/licenses/LICENSE-2.0 9aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * 10aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Unless required by applicable law or agreed to in writing, software 11aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * distributed under the License is distributed on an "AS IS" BASIS, 12aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * See the License for the specific language governing permissions and 14aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * limitations under the License. 15aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 16aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 17aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankpackage com.android.emailcommon.provider; 18aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.app.admin.DevicePolicyManager; 19aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.content.ContentProviderOperation; 20b2a909598ba78783b05c58508310f864c56c897bMarc Blankimport android.content.ContentResolver; 21aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.content.ContentUris; 22aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.content.ContentValues; 23aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.content.Context; 24aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.content.OperationApplicationException; 25aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.database.Cursor; 26aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.net.Uri; 27aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.os.Parcel; 28aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.os.Parcelable; 29aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.os.RemoteException; 30aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport android.util.Log; 31aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 32505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komaloimport com.android.emailcommon.utility.Utility; 33745b33b8ff55e9a9c4871f07f9d97db893f784b2Makoto Onukiimport com.google.common.annotations.VisibleForTesting; 34505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo 35aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport java.util.ArrayList; 36aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 37aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank/** 38aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * The Policy class represents a set of security requirements that are associated with an Account. 39aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * The requirements may be either device-specific (e.g. password) or application-specific (e.g. 40aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * a limit on the sync window for the Account) 41aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 42aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankpublic final class Policy extends EmailContent implements EmailContent.PolicyColumns, Parcelable { 432bdf7ee0f0f4a2b11b5f7c0f8b193080600fefd8Marc Blank public static final boolean DEBUG_POLICY = false; // DO NOT SUBMIT WITH THIS SET TO TRUE 44aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final String TAG = "Email/Policy"; 45aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 46aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final String TABLE_NAME = "Policy"; 47aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank @SuppressWarnings("hiding") 48aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final Uri CONTENT_URI = Uri.parse(EmailContent.CONTENT_URI + "/policy"); 49aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 50aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /* Convert days to mSec (used for password expiration) */ 51aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank private static final long DAYS_TO_MSEC = 24 * 60 * 60 * 1000; 52aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /* Small offset (2 minutes) added to policy expiration to make user testing easier. */ 53aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank private static final long EXPIRATION_OFFSET_MSEC = 2 * 60 * 1000; 54aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 55aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int PASSWORD_MODE_NONE = 0; 56aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int PASSWORD_MODE_SIMPLE = 1; 57aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int PASSWORD_MODE_STRONG = 2; 58aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 59aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int mPasswordMode; 60aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int mPasswordMinLength; 61aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int mPasswordMaxFails; 62aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int mPasswordExpirationDays; 63aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int mPasswordHistory; 64aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int mPasswordComplexChars; 65aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int mMaxScreenLockTime; 66aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public boolean mRequireRemoteWipe; 67aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public boolean mRequireEncryption; 68aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public boolean mRequireEncryptionExternal; 69f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public boolean mRequireManualSyncWhenRoaming; 70f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public boolean mDontAllowCamera; 71f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public boolean mDontAllowAttachments; 72f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public boolean mDontAllowHtml; 73f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public int mMaxAttachmentSize; 74f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public int mMaxTextTruncationSize; 75f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public int mMaxHtmlTruncationSize; 76f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public int mMaxEmailLookback; 77f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public int mMaxCalendarLookback; 78f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public boolean mPasswordRecoveryEnabled; 79aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 80aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_ID_COLUMN = 0; 81aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_PASSWORD_MODE_COLUMN = 1; 82aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_PASSWORD_MIN_LENGTH_COLUMN = 2; 83aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_PASSWORD_EXPIRATION_DAYS_COLUMN = 3; 84aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_PASSWORD_HISTORY_COLUMN = 4; 85aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_PASSWORD_COMPLEX_CHARS_COLUMN = 5; 86aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_PASSWORD_MAX_FAILS_COLUMN = 6; 87aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_MAX_SCREEN_LOCK_TIME_COLUMN = 7; 88aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_REQUIRE_REMOTE_WIPE_COLUMN = 8; 89aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_REQUIRE_ENCRYPTION_COLUMN = 9; 90aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final int CONTENT_REQUIRE_ENCRYPTION_EXTERNAL_COLUMN = 10; 91f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_REQUIRE_MANUAL_SYNC_WHEN_ROAMING = 11; 92f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_DONT_ALLOW_CAMERA_COLUMN = 12; 93f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_DONT_ALLOW_ATTACHMENTS_COLUMN = 13; 94f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_DONT_ALLOW_HTML_COLUMN = 14; 95f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_MAX_ATTACHMENT_SIZE_COLUMN = 15; 96f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_MAX_TEXT_TRUNCATION_SIZE_COLUMN = 16; 97f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_MAX_HTML_TRUNCATION_SIZE_COLUMN = 17; 98f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_MAX_EMAIL_LOOKBACK_COLUMN = 18; 99f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_MAX_CALENDAR_LOOKBACK_COLUMN = 19; 100f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank public static final int CONTENT_PASSWORD_RECOVERY_ENABLED_COLUMN = 20; 101aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 102aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final String[] CONTENT_PROJECTION = new String[] {RECORD_ID, 103aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank PolicyColumns.PASSWORD_MODE, PolicyColumns.PASSWORD_MIN_LENGTH, 104aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank PolicyColumns.PASSWORD_EXPIRATION_DAYS, PolicyColumns.PASSWORD_HISTORY, 105aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank PolicyColumns.PASSWORD_COMPLEX_CHARS, PolicyColumns.PASSWORD_MAX_FAILS, 106aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank PolicyColumns.MAX_SCREEN_LOCK_TIME, PolicyColumns.REQUIRE_REMOTE_WIPE, 107f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank PolicyColumns.REQUIRE_ENCRYPTION, PolicyColumns.REQUIRE_ENCRYPTION_EXTERNAL, 108f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank PolicyColumns.REQUIRE_MANUAL_SYNC_WHEN_ROAMING, PolicyColumns.DONT_ALLOW_CAMERA, 109f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank PolicyColumns.DONT_ALLOW_ATTACHMENTS, PolicyColumns.DONT_ALLOW_HTML, 110f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank PolicyColumns.MAX_ATTACHMENT_SIZE, PolicyColumns.MAX_TEXT_TRUNCATION_SIZE, 111f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank PolicyColumns.MAX_HTML_TRUNCATION_SIZE, PolicyColumns.MAX_EMAIL_LOOKBACK, 112f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank PolicyColumns.MAX_CALENDAR_LOOKBACK, PolicyColumns.PASSWORD_RECOVERY_ENABLED 113aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank }; 114aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 115aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final Policy NO_POLICY = new Policy(); 116aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 117b2a909598ba78783b05c58508310f864c56c897bMarc Blank private static final String[] ATTACHMENT_RESET_PROJECTION = 118b2a909598ba78783b05c58508310f864c56c897bMarc Blank new String[] {EmailContent.RECORD_ID, AttachmentColumns.SIZE, AttachmentColumns.FLAGS}; 119b2a909598ba78783b05c58508310f864c56c897bMarc Blank private static final int ATTACHMENT_RESET_PROJECTION_ID = 0; 120b2a909598ba78783b05c58508310f864c56c897bMarc Blank private static final int ATTACHMENT_RESET_PROJECTION_SIZE = 1; 121b2a909598ba78783b05c58508310f864c56c897bMarc Blank private static final int ATTACHMENT_RESET_PROJECTION_FLAGS = 2; 122b2a909598ba78783b05c58508310f864c56c897bMarc Blank 123aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public Policy() { 124aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mBaseUri = CONTENT_URI; 125aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // By default, the password mode is "none" 126aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordMode = PASSWORD_MODE_NONE; 127aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // All server policies require the ability to wipe the device 128aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mRequireRemoteWipe = true; 129aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 130aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 131aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static Policy restorePolicyWithId(Context context, long id) { 132aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return EmailContent.restoreContentWithId(context, Policy.class, Policy.CONTENT_URI, 133aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank Policy.CONTENT_PROJECTION, id); 134aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 135aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 136aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static long getAccountIdWithPolicyKey(Context context, long id) { 137aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return Utility.getFirstRowLong(context, Account.CONTENT_URI, Account.ID_PROJECTION, 138aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank AccountColumns.POLICY_KEY + "=?", new String[] {Long.toString(id)}, null, 139505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo Account.ID_PROJECTION_COLUMN, Account.NO_ACCOUNT); 140aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 141aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 142aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // We override this method to insure that we never write invalid policy data to the provider 143d09cff08882e553afce919865a2cc60b657d4659Ben Komalo @Override 144aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public Uri save(Context context) { 145aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank normalize(); 146aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return super.save(context); 147aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 148aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 149505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo public static void clearAccountPolicy(Context context, Account account) { 150fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank setAccountPolicy(context, account, null, null); 151fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank } 152fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank 153aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /** 154505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo * Convenience method for {@link #setAccountPolicy(Context, Account, Policy, String)}. 155505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo */ 156745b33b8ff55e9a9c4871f07f9d97db893f784b2Makoto Onuki @VisibleForTesting 157505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo public static void setAccountPolicy(Context context, long accountId, Policy policy, 158505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo String securitySyncKey) { 159505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo setAccountPolicy(context, Account.restoreAccountWithId(context, accountId), 160505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo policy, securitySyncKey); 161505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo } 162505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo 163505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo /** 164fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank * Set the policy for an account atomically; this also removes any other policy associated with 165fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank * the account and sets the policy key for the account. If policy is null, the policyKey is 166b169192c8a59f8b61b019c80fda2183194ac5c00Marc Blank * set to 0 and the securitySyncKey to null. Also, update the account object to reflect the 167b169192c8a59f8b61b019c80fda2183194ac5c00Marc Blank * current policyKey and securitySyncKey 168aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * @param context the caller's context 169aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * @param account the account whose policy is to be set 170fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank * @param policy the policy to set, or null if we're clearing the policy 171fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank * @param securitySyncKey the security sync key for this account (ignored if policy is null) 172aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 173505ac4b09bbe13ff099e40d94e45963e46a9261fBen Komalo public static void setAccountPolicy(Context context, Account account, Policy policy, 174fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank String securitySyncKey) { 175aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (DEBUG_POLICY) { 176fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank Log.d(TAG, "Set policy for account " + account.mDisplayName + ": " + 177fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank ((policy == null) ? "none" : policy.toString())); 178aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 179aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 180aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 181fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank // Make sure this is a valid policy set 182fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank if (policy != null) { 183fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank policy.normalize(); 184fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank // Add the new policy (no account will yet reference this) 185fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank ops.add(ContentProviderOperation.newInsert( 186fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank Policy.CONTENT_URI).withValues(policy.toContentValues()).build()); 187fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank // Make the policyKey of the account our newly created policy, and set the sync key 188fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank ops.add(ContentProviderOperation.newUpdate( 189fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank ContentUris.withAppendedId(Account.CONTENT_URI, account.mId)) 190fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank .withValueBackReference(AccountColumns.POLICY_KEY, 0) 191fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank .withValue(AccountColumns.SECURITY_SYNC_KEY, securitySyncKey) 192fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank .build()); 193fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank } else { 194fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank ops.add(ContentProviderOperation.newUpdate( 195fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank ContentUris.withAppendedId(Account.CONTENT_URI, account.mId)) 196fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank .withValue(AccountColumns.SECURITY_SYNC_KEY, null) 197fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank .withValue(AccountColumns.POLICY_KEY, 0) 198fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank .build()); 199aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 200fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank 201aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // Delete the previous policy associated with this account, if any 202aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (account.mPolicyKey > 0) { 203aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank ops.add(ContentProviderOperation.newDelete( 204fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank ContentUris.withAppendedId( 205fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank Policy.CONTENT_URI, account.mPolicyKey)).build()); 206aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 207fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank 208aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank try { 209aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank context.getContentResolver().applyBatch(EmailContent.AUTHORITY, ops); 210b169192c8a59f8b61b019c80fda2183194ac5c00Marc Blank account.refresh(context); 211aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } catch (RemoteException e) { 212fae5ebbfd202b930296a1bbc67459152f1a6c6ceMarc Blank // This is fatal to a remote process 213aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank throw new IllegalStateException("Exception setting account policy."); 214aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } catch (OperationApplicationException e) { 215aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // Can't happen; our provider doesn't throw this exception 216aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 217aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 218aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 219b2a909598ba78783b05c58508310f864c56c897bMarc Blank /** 220b2a909598ba78783b05c58508310f864c56c897bMarc Blank * Review all attachment records for this account, and reset the "don't allow download" flag 221b2a909598ba78783b05c58508310f864c56c897bMarc Blank * as required by the account's new security policies 222b2a909598ba78783b05c58508310f864c56c897bMarc Blank * @param context the caller's context 223b2a909598ba78783b05c58508310f864c56c897bMarc Blank * @param account the account whose attachments need to be reviewed 224b2a909598ba78783b05c58508310f864c56c897bMarc Blank * @param policy the new policy for this account 225b2a909598ba78783b05c58508310f864c56c897bMarc Blank */ 226b2a909598ba78783b05c58508310f864c56c897bMarc Blank public static void setAttachmentFlagsForNewPolicy(Context context, Account account, 227b2a909598ba78783b05c58508310f864c56c897bMarc Blank Policy policy) { 228b2a909598ba78783b05c58508310f864c56c897bMarc Blank // A nasty bit of work; start with all attachments for a given account 229b2a909598ba78783b05c58508310f864c56c897bMarc Blank ContentResolver resolver = context.getContentResolver(); 230b2a909598ba78783b05c58508310f864c56c897bMarc Blank Cursor c = resolver.query(Attachment.CONTENT_URI, ATTACHMENT_RESET_PROJECTION, 231b2a909598ba78783b05c58508310f864c56c897bMarc Blank AttachmentColumns.ACCOUNT_KEY + "=?", new String[] {Long.toString(account.mId)}, 232b2a909598ba78783b05c58508310f864c56c897bMarc Blank null); 233b2a909598ba78783b05c58508310f864c56c897bMarc Blank ContentValues cv = new ContentValues(); 234b2a909598ba78783b05c58508310f864c56c897bMarc Blank try { 235b2a909598ba78783b05c58508310f864c56c897bMarc Blank // Get maximum allowed size (0 if we don't allow attachments at all) 236b2a909598ba78783b05c58508310f864c56c897bMarc Blank int policyMax = policy.mDontAllowAttachments ? 0 : (policy.mMaxAttachmentSize > 0) ? 237b2a909598ba78783b05c58508310f864c56c897bMarc Blank policy.mMaxAttachmentSize : Integer.MAX_VALUE; 238b2a909598ba78783b05c58508310f864c56c897bMarc Blank while (c.moveToNext()) { 239b2a909598ba78783b05c58508310f864c56c897bMarc Blank int flags = c.getInt(ATTACHMENT_RESET_PROJECTION_FLAGS); 240b2a909598ba78783b05c58508310f864c56c897bMarc Blank int size = c.getInt(ATTACHMENT_RESET_PROJECTION_SIZE); 241b2a909598ba78783b05c58508310f864c56c897bMarc Blank boolean wasRestricted = (flags & Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD) != 0; 242b2a909598ba78783b05c58508310f864c56c897bMarc Blank boolean isRestricted = size > policyMax; 243b2a909598ba78783b05c58508310f864c56c897bMarc Blank if (isRestricted != wasRestricted) { 244b2a909598ba78783b05c58508310f864c56c897bMarc Blank if (isRestricted) { 245b2a909598ba78783b05c58508310f864c56c897bMarc Blank flags |= Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD; 246b2a909598ba78783b05c58508310f864c56c897bMarc Blank } else { 247b2a909598ba78783b05c58508310f864c56c897bMarc Blank flags &= ~Attachment.FLAG_POLICY_DISALLOWS_DOWNLOAD; 248b2a909598ba78783b05c58508310f864c56c897bMarc Blank } 249b2a909598ba78783b05c58508310f864c56c897bMarc Blank long id = c.getLong(ATTACHMENT_RESET_PROJECTION_ID); 250b2a909598ba78783b05c58508310f864c56c897bMarc Blank cv.put(AttachmentColumns.FLAGS, flags); 251b2a909598ba78783b05c58508310f864c56c897bMarc Blank resolver.update(ContentUris.withAppendedId(Attachment.CONTENT_URI, id), 252b2a909598ba78783b05c58508310f864c56c897bMarc Blank cv, null, null); 253b2a909598ba78783b05c58508310f864c56c897bMarc Blank } 254b2a909598ba78783b05c58508310f864c56c897bMarc Blank } 255b2a909598ba78783b05c58508310f864c56c897bMarc Blank } finally { 256b2a909598ba78783b05c58508310f864c56c897bMarc Blank c.close(); 257b2a909598ba78783b05c58508310f864c56c897bMarc Blank } 258b2a909598ba78783b05c58508310f864c56c897bMarc Blank } 259b2a909598ba78783b05c58508310f864c56c897bMarc Blank 260aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /** 261aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Normalize the Policy. If the password mode is "none", zero out all password-related fields; 262aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * zero out complex characters for simple passwords. 263aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 264aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public void normalize() { 265aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordMode == PASSWORD_MODE_NONE) { 266aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordMaxFails = 0; 267aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mMaxScreenLockTime = 0; 268aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordMinLength = 0; 269aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordComplexChars = 0; 270aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordHistory = 0; 271aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordExpirationDays = 0; 272aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } else { 273aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if ((mPasswordMode != PASSWORD_MODE_SIMPLE) && 274aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank (mPasswordMode != PASSWORD_MODE_STRONG)) { 275aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank throw new IllegalArgumentException("password mode"); 276aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 277aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // If we're only requiring a simple password, set complex chars to zero; note 278aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // that EAS can erroneously send non-zero values in this case 279aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordMode == PASSWORD_MODE_SIMPLE) { 280aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordComplexChars = 0; 281aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 282aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 283aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 284aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 285aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank @Override 286aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public boolean equals(Object other) { 287aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (!(other instanceof Policy)) return false; 288aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank Policy otherPolicy = (Policy)other; 289aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mRequireEncryption != otherPolicy.mRequireEncryption) return false; 290aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mRequireEncryptionExternal != otherPolicy.mRequireEncryptionExternal) return false; 291aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mRequireRemoteWipe != otherPolicy.mRequireRemoteWipe) return false; 292aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mMaxScreenLockTime != otherPolicy.mMaxScreenLockTime) return false; 293aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordComplexChars != otherPolicy.mPasswordComplexChars) return false; 294aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordExpirationDays != otherPolicy.mPasswordExpirationDays) return false; 295aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordHistory != otherPolicy.mPasswordHistory) return false; 296aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordMaxFails != otherPolicy.mPasswordMaxFails) return false; 297aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordMinLength != otherPolicy.mPasswordMinLength) return false; 298aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordMode != otherPolicy.mPasswordMode) return false; 299f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mRequireManualSyncWhenRoaming != otherPolicy.mRequireManualSyncWhenRoaming) { 300f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank return false; 301f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank } 302f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mDontAllowCamera != otherPolicy.mDontAllowCamera) return false; 303f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mDontAllowAttachments != otherPolicy.mDontAllowAttachments) return false; 304f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mDontAllowHtml != otherPolicy.mDontAllowHtml) return false; 305f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mMaxAttachmentSize != otherPolicy.mMaxAttachmentSize) return false; 306f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mMaxTextTruncationSize != otherPolicy.mMaxTextTruncationSize) return false; 307f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mMaxHtmlTruncationSize != otherPolicy.mMaxHtmlTruncationSize) return false; 308f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mMaxEmailLookback != otherPolicy.mMaxEmailLookback) return false; 309f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mMaxCalendarLookback != otherPolicy.mMaxCalendarLookback) return false; 310f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank if (mPasswordRecoveryEnabled != otherPolicy.mPasswordRecoveryEnabled) return false; 311aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return true; 312aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 313aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 314aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank @Override 315aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int hashCode() { 316aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank int code = mRequireEncryption ? 1 : 0; 317aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank code += (mRequireEncryptionExternal ? 1 : 0) << 1; 318aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank code += (mRequireRemoteWipe ? 1 : 0) << 2; 319aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank code += (mMaxScreenLockTime << 3); 320aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank code += (mPasswordComplexChars << 6); 321aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank code += (mPasswordExpirationDays << 12); 322aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank code += (mPasswordHistory << 15); 323aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank code += (mPasswordMaxFails << 18); 324aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank code += (mPasswordMinLength << 22); 325aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank code += (mPasswordMode << 26); 326f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank // Don't need to include the other fields 327aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return code; 328aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 329aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 330aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank @Override 331aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public void restore(Cursor cursor) { 332aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mBaseUri = CONTENT_URI; 333aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mId = cursor.getLong(CONTENT_ID_COLUMN); 334aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordMode = cursor.getInt(CONTENT_PASSWORD_MODE_COLUMN); 335aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordMinLength = cursor.getInt(CONTENT_PASSWORD_MIN_LENGTH_COLUMN); 336aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordMaxFails = cursor.getInt(CONTENT_PASSWORD_MAX_FAILS_COLUMN); 337aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordHistory = cursor.getInt(CONTENT_PASSWORD_HISTORY_COLUMN); 338aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordExpirationDays = cursor.getInt(CONTENT_PASSWORD_EXPIRATION_DAYS_COLUMN); 339aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordComplexChars = cursor.getInt(CONTENT_PASSWORD_COMPLEX_CHARS_COLUMN); 340aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mMaxScreenLockTime = cursor.getInt(CONTENT_MAX_SCREEN_LOCK_TIME_COLUMN); 341aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mRequireRemoteWipe = cursor.getInt(CONTENT_REQUIRE_REMOTE_WIPE_COLUMN) == 1; 342aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mRequireEncryption = cursor.getInt(CONTENT_REQUIRE_ENCRYPTION_COLUMN) == 1; 343aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mRequireEncryptionExternal = 344aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank cursor.getInt(CONTENT_REQUIRE_ENCRYPTION_EXTERNAL_COLUMN) == 1; 345f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mRequireManualSyncWhenRoaming = 346f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank cursor.getInt(CONTENT_REQUIRE_MANUAL_SYNC_WHEN_ROAMING) == 1; 347f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mDontAllowCamera = cursor.getInt(CONTENT_DONT_ALLOW_CAMERA_COLUMN) == 1; 348f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mDontAllowAttachments = cursor.getInt(CONTENT_DONT_ALLOW_ATTACHMENTS_COLUMN) == 1; 349f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mDontAllowHtml = cursor.getInt(CONTENT_DONT_ALLOW_HTML_COLUMN) == 1; 350f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxAttachmentSize = cursor.getInt(CONTENT_MAX_ATTACHMENT_SIZE_COLUMN); 351f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxTextTruncationSize = cursor.getInt(CONTENT_MAX_TEXT_TRUNCATION_SIZE_COLUMN); 352f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxHtmlTruncationSize = cursor.getInt(CONTENT_MAX_HTML_TRUNCATION_SIZE_COLUMN); 353f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxEmailLookback = cursor.getInt(CONTENT_MAX_EMAIL_LOOKBACK_COLUMN); 354f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxCalendarLookback = cursor.getInt(CONTENT_MAX_CALENDAR_LOOKBACK_COLUMN); 355f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mPasswordRecoveryEnabled = cursor.getInt(CONTENT_PASSWORD_RECOVERY_ENABLED_COLUMN) == 1; 356aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 357aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 358aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank @Override 359aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public ContentValues toContentValues() { 360aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank ContentValues values = new ContentValues(); 361aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.PASSWORD_MODE, mPasswordMode); 362aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.PASSWORD_MIN_LENGTH, mPasswordMinLength); 363aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.PASSWORD_MAX_FAILS, mPasswordMaxFails); 364aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.PASSWORD_HISTORY, mPasswordHistory); 365aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.PASSWORD_EXPIRATION_DAYS, mPasswordExpirationDays); 366aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.PASSWORD_COMPLEX_CHARS, mPasswordComplexChars); 367aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.MAX_SCREEN_LOCK_TIME, mMaxScreenLockTime); 368aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.REQUIRE_REMOTE_WIPE, mRequireRemoteWipe); 369aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.REQUIRE_ENCRYPTION, mRequireEncryption); 370aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank values.put(PolicyColumns.REQUIRE_ENCRYPTION_EXTERNAL, mRequireEncryptionExternal); 371f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.REQUIRE_MANUAL_SYNC_WHEN_ROAMING, mRequireManualSyncWhenRoaming); 372f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.DONT_ALLOW_CAMERA, mDontAllowCamera); 373f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.DONT_ALLOW_ATTACHMENTS, mDontAllowAttachments); 374f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.DONT_ALLOW_HTML, mDontAllowHtml); 375f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.MAX_ATTACHMENT_SIZE, mMaxAttachmentSize); 376f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.MAX_TEXT_TRUNCATION_SIZE, mMaxTextTruncationSize); 377f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.MAX_HTML_TRUNCATION_SIZE, mMaxHtmlTruncationSize); 378f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.MAX_EMAIL_LOOKBACK, mMaxEmailLookback); 379f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.MAX_CALENDAR_LOOKBACK, mMaxCalendarLookback); 380f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank values.put(PolicyColumns.PASSWORD_RECOVERY_ENABLED, mPasswordRecoveryEnabled); 381aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return values; 382aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 383aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 384aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /** 385aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Helper to map our internal encoding to DevicePolicyManager password modes. 386aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 387aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int getDPManagerPasswordQuality() { 388aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank switch (mPasswordMode) { 389aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank case PASSWORD_MODE_SIMPLE: 390aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; 391aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank case PASSWORD_MODE_STRONG: 392aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordComplexChars == 0) { 393aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; 394aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } else { 395aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; 396aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 397aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank default: 398aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return DevicePolicyManager .PASSWORD_QUALITY_UNSPECIFIED; 399aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 400aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 401aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 402aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /** 403aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Helper to map expiration times to the millisecond values used by DevicePolicyManager. 404aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 405aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public long getDPManagerPasswordExpirationTimeout() { 406aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank long result = mPasswordExpirationDays * DAYS_TO_MSEC; 407aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // Add a small offset to the password expiration. This makes it easier to test 408aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // by changing (for example) 1 day to 1 day + 5 minutes. If you set an expiration 409aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // that is within the warning period, you should get a warning fairly quickly. 410aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (result > 0) { 411aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank result += EXPIRATION_OFFSET_MSEC; 412aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 413aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return result; 414aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 415aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 416aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank private void appendPolicy(StringBuilder sb, String code, int value) { 417aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank sb.append(code); 418aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank sb.append(":"); 419aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank sb.append(value); 420aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank sb.append(" "); 421aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 422aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 423d09cff08882e553afce919865a2cc60b657d4659Ben Komalo @Override 424aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public String toString() { 425aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank StringBuilder sb = new StringBuilder("["); 426d09cff08882e553afce919865a2cc60b657d4659Ben Komalo if (equals(NO_POLICY)) { 427aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank sb.append("No policies]"); 428aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } else { 429aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank if (mPasswordMode == PASSWORD_MODE_NONE) { 43071c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank sb.append("Pwd none "); 431aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } else { 432aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank appendPolicy(sb, "Pwd strong", mPasswordMode == PASSWORD_MODE_STRONG ? 1 : 0); 433aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank appendPolicy(sb, "len", mPasswordMinLength); 434aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank appendPolicy(sb, "cmpx", mPasswordComplexChars); 435aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank appendPolicy(sb, "expy", mPasswordExpirationDays); 436aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank appendPolicy(sb, "hist", mPasswordHistory); 437aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank appendPolicy(sb, "fail", mPasswordMaxFails); 438aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank appendPolicy(sb, "idle", mMaxScreenLockTime); 439aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 44071c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank if (mRequireEncryption) { 44171c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank sb.append("encrypt "); 44271c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank } 44371c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank if (mRequireEncryptionExternal) { 44471c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank sb.append("encryptsd "); 44571c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank } 44671c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank if (mDontAllowCamera) { 44771c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank sb.append("nocamera "); 44871c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank } 44971c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank if (mDontAllowAttachments) { 45071c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank sb.append("noatts "); 45171c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank } 45271c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank if (mRequireManualSyncWhenRoaming) { 45371c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank sb.append("nopushroam "); 45471c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank } 45571c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank if (mMaxAttachmentSize > 0) { 45671c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank appendPolicy(sb, "attmax", mMaxAttachmentSize); 45771c9683087c348a117a6dd9c6f6eab96cbc46139Marc Blank } 458aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank sb.append("]"); 459aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 460aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return sb.toString(); 461aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 462aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 463aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /** 464aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Supports Parcelable 465aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 466aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank @Override 467aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public int describeContents() { 468aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return 0; 469aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 470aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 471aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /** 472aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Supports Parcelable 473aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 474aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() { 475aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public Policy createFromParcel(Parcel in) { 476aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return new Policy(in); 477aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 478aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 479aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public Policy[] newArray(int size) { 480aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank return new Policy[size]; 481aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 482aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank }; 483aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 484aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /** 485aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Supports Parcelable 486aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 487aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank @Override 488aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public void writeToParcel(Parcel dest, int flags) { 489aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank // mBaseUri is not parceled 490aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeLong(mId); 491aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mPasswordMode); 492aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mPasswordMinLength); 493aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mPasswordMaxFails); 494aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mPasswordHistory); 495aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mPasswordExpirationDays); 496aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mPasswordComplexChars); 497aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mMaxScreenLockTime); 498aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mRequireRemoteWipe ? 1 : 0); 499aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mRequireEncryption ? 1 : 0); 500aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank dest.writeInt(mRequireEncryptionExternal ? 1 : 0); 501f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mRequireManualSyncWhenRoaming ? 1 : 0); 502f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mDontAllowCamera ? 1 : 0); 503f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mDontAllowAttachments ? 1 : 0); 504f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mDontAllowHtml ? 1 : 0); 505f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mMaxAttachmentSize); 506f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mMaxTextTruncationSize); 507f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mMaxHtmlTruncationSize); 508f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mMaxEmailLookback); 509f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mMaxCalendarLookback); 510f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank dest.writeInt(mPasswordRecoveryEnabled ? 1 : 0); 511aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 512aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank 513aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank /** 514aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank * Supports Parcelable 515aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank */ 516aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank public Policy(Parcel in) { 517aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mBaseUri = CONTENT_URI; 518aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mId = in.readLong(); 519aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordMode = in.readInt(); 520aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordMinLength = in.readInt(); 521aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordMaxFails = in.readInt(); 522aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordHistory = in.readInt(); 523aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordExpirationDays = in.readInt(); 524aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mPasswordComplexChars = in.readInt(); 525aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mMaxScreenLockTime = in.readInt(); 526aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mRequireRemoteWipe = in.readInt() == 1; 527aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mRequireEncryption = in.readInt() == 1; 528aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank mRequireEncryptionExternal = in.readInt() == 1; 529f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mRequireManualSyncWhenRoaming = in.readInt() == 1; 530f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mDontAllowCamera = in.readInt() == 1; 531f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mDontAllowAttachments = in.readInt() == 1; 532f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mDontAllowHtml = in.readInt() == 1; 533f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxAttachmentSize = in.readInt(); 534f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxTextTruncationSize = in.readInt(); 535f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxHtmlTruncationSize = in.readInt(); 536f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxEmailLookback = in.readInt(); 537f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mMaxCalendarLookback = in.readInt(); 538f91a03f5203bb64ae0726596d65ac90c35088666Marc Blank mPasswordRecoveryEnabled = in.readInt() == 1; 539aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank } 540aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank}