SecurityPolicyTests.java revision aeee10e57ef4d931e7708fde218d590453a82aea
1345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler/*
2345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * Copyright (C) 2010 The Android Open Source Project
3345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler *
4345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * Licensed under the Apache License, Version 2.0 (the "License");
5345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * you may not use this file except in compliance with the License.
6345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * You may obtain a copy of the License at
7345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler *
8345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler *      http://www.apache.org/licenses/LICENSE-2.0
9345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler *
10345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * Unless required by applicable law or agreed to in writing, software
11345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * distributed under the License is distributed on an "AS IS" BASIS,
12345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * See the License for the specific language governing permissions and
14345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * limitations under the License.
15345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler */
16345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
17345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadlerpackage com.android.email;
18345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
191ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadlerimport com.android.email.provider.ContentCache;
209ba506c4dd498150555f6c59aa758f7467bf9236Marc Blankimport com.android.email.provider.EmailProvider;
219ba506c4dd498150555f6c59aa758f7467bf9236Marc Blankimport com.android.email.provider.ProviderTestUtils;
22a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent;
23a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Account;
24a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Mailbox;
25a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Message;
26aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport com.android.emailcommon.provider.Policy;
27aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blankimport com.android.emailcommon.service.LegacyPolicySet;
28345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
29a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadlerimport android.app.admin.DevicePolicyManager;
30345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadlerimport android.content.Context;
31d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadlerimport android.content.ContextWrapper;
32345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadlerimport android.test.ProviderTestCase2;
33345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadlerimport android.test.suitebuilder.annotation.MediumTest;
34345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadlerimport android.test.suitebuilder.annotation.SmallTest;
35345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
36345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler/**
37345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler * This is a series of unit tests for backup/restore of the SecurityPolicy class.
382b2b3448ec200f3d649e5f57309908d28ce3bfc7Marc Blank *
399b4988de43dbee6c06066caab63806e8c8303d7dMarc Blank * You can run this entire test case with:
409b4988de43dbee6c06066caab63806e8c8303d7dMarc Blank *   runtest -c com.android.email.SecurityPolicyTests email
41345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler */
429b4988de43dbee6c06066caab63806e8c8303d7dMarc Blank
43345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler@MediumTest
44345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadlerpublic class SecurityPolicyTests extends ProviderTestCase2<EmailProvider> {
45345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
46345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    private Context mMockContext;
47aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    private SecurityPolicy mSecurityPolicy;
48d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler
49345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    public SecurityPolicyTests() {
5031d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blank        super(EmailProvider.class, EmailContent.AUTHORITY);
51345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    }
52345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
53aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    private static final Policy EMPTY_POLICY = new Policy();
54aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank
55345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    @Override
56345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    protected void setUp() throws Exception {
57345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        super.setUp();
58aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        mMockContext = new MockContext2(getMockContext(), mContext);
591ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Invalidate all caches, since we reset the database for each test
601ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        ContentCache.invalidateAllCachesForTest();
61345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    }
62345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
63345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    /**
64345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler     * Delete any dummy accounts we set up for this test
65345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler     */
66345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    @Override
67345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    protected void tearDown() throws Exception {
68345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        super.tearDown();
69345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    }
70345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
71345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    /**
720fb092b38912c7cff776a51872840bb2089ebe08Makoto Onuki     * Private context wrapper used to add back getPackageName() for these tests.
730fb092b38912c7cff776a51872840bb2089ebe08Makoto Onuki     *
74a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler     * This class also implements {@link Context} method(s) that are called during tests.
75d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler     */
76d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler    private static class MockContext2 extends ContextWrapper {
77d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler
78d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler        private final Context mRealContext;
79d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler
80d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler        public MockContext2(Context mockContext, Context realContext) {
81d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler            super(mockContext);
82d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler            mRealContext = realContext;
83d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler        }
84d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler
85d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler        @Override
860fb092b38912c7cff776a51872840bb2089ebe08Makoto Onuki        public Context getApplicationContext() {
870fb092b38912c7cff776a51872840bb2089ebe08Makoto Onuki            return this;
880fb092b38912c7cff776a51872840bb2089ebe08Makoto Onuki        }
890fb092b38912c7cff776a51872840bb2089ebe08Makoto Onuki
900fb092b38912c7cff776a51872840bb2089ebe08Makoto Onuki        @Override
91d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler        public String getPackageName() {
92d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler            return mRealContext.getPackageName();
93d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler        }
94a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler
95a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler        @Override
96a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler        public Object getSystemService(String name) {
97a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler            return mRealContext.getSystemService(name);
98a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler        }
99d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler    }
100d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler
101d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler    /**
102aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank     * Create a Policy using the arguments formerly used to create a PolicySet; this minimizes the
103aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank     * changes needed for re-using the PolicySet unit test logic
104345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler     */
105aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    private Policy setupPolicy(int minPasswordLength, int passwordMode, int maxPasswordFails,
106aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            int maxScreenLockTime, boolean requireRemoteWipe, int passwordExpirationDays,
107aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            int passwordHistory, int passwordComplexChars, boolean requireEncryption,
108aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            boolean requireEncryptionExternal) throws IllegalArgumentException {
109aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy policy = new Policy();
110aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mPasswordMinLength = minPasswordLength;
111aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mPasswordMode = passwordMode;
112aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mPasswordMaxFails = maxPasswordFails;
113aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mMaxScreenLockTime = maxScreenLockTime;
114aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mRequireRemoteWipe = requireRemoteWipe;
115aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mPasswordExpirationDays = passwordExpirationDays;
116aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mPasswordHistory = passwordHistory;
117aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mPasswordComplexChars = passwordComplexChars;
118aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mRequireEncryption = requireEncryption;
119aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy.mRequireEncryptionExternal = requireEncryptionExternal;
120aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        return policy;
1211d6dab29562eca7978f179be5f5c75f22f44d734Marc Blank    }
1221d6dab29562eca7978f179be5f5c75f22f44d734Marc Blank
123345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    /**
124345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler     * Test business logic of aggregating accounts with policies
125345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler     */
126345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    public void testAggregator() {
127aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        mSecurityPolicy = SecurityPolicy.getInstance(mMockContext);
128345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
129d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler        // with no accounts, should return empty set
130aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertEquals(EMPTY_POLICY, mSecurityPolicy.computeAggregatePolicy());
131345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
132d62860821c2dbc14ab493b888cb129bd5addd53dAndrew Stadler        // with accounts having no security, empty set
133aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        ProviderTestUtils.setupAccount("no-sec-1", true, mMockContext);
134aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        ProviderTestUtils.setupAccount("no-sec-2", true, mMockContext);
135aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertEquals(EMPTY_POLICY, mSecurityPolicy.computeAggregatePolicy());
136345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
137345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        // with a single account in security mode, should return same security as in account
1383d2b3b3b3554be2ac23d9a49fee00faa9693e857Andrew Stadler        // first test with partially-populated policies
139aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a3 = ProviderTestUtils.setupAccount("sec-3", true, mMockContext);
140aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3ain = setupPolicy(10, Policy.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
1417fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
142aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p3ain.setAccountPolicy(mMockContext, a3, "0");
143aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3aout = mSecurityPolicy.computeAggregatePolicy();
1443d2b3b3b3554be2ac23d9a49fee00faa9693e857Andrew Stadler        assertNotNull(p3aout);
1453d2b3b3b3554be2ac23d9a49fee00faa9693e857Andrew Stadler        assertEquals(p3ain, p3aout);
1463d2b3b3b3554be2ac23d9a49fee00faa9693e857Andrew Stadler
1473d2b3b3b3554be2ac23d9a49fee00faa9693e857Andrew Stadler        // Repeat that test with fully-populated policies
148aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3bin = setupPolicy(10, Policy.PASSWORD_MODE_SIMPLE, 15, 16, false, 6, 2, 3,
1497fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
150aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p3bin.setAccountPolicy(mMockContext, a3, "0");
151aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3bout = mSecurityPolicy.computeAggregatePolicy();
1523d2b3b3b3554be2ac23d9a49fee00faa9693e857Andrew Stadler        assertNotNull(p3bout);
1533d2b3b3b3554be2ac23d9a49fee00faa9693e857Andrew Stadler        assertEquals(p3bin, p3bout);
154345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
155345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        // add another account which mixes it up (some fields will change, others will not)
156345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        // pw length and pw mode - max logic - will change because larger #s here
157345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        // fail count and lock timer - min logic - will *not* change because larger #s here
158345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        // wipe required - OR logic - will *not* change here because false
1591ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // expiration - will not change because 0 (unspecified)
1601ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // max complex chars - max logic - will change
161469f2987dc11d153434e50eb04dd6b83b924d09dAndy Stadler        // encryption required - OR logic - will *not* change here because false
1627fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        // encryption external req'd - OR logic - will *not* change here because false
163aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p4in = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 0, 5, 7,
1647fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
165aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a4 = ProviderTestUtils.setupAccount("sec-4", true, mMockContext);
166aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p4in.setAccountPolicy(mMockContext, a4, "0");
167aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p4out = mSecurityPolicy.computeAggregatePolicy();
168345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        assertNotNull(p4out);
169aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertEquals(20, p4out.mPasswordMinLength);
170aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertEquals(Policy.PASSWORD_MODE_STRONG, p4out.mPasswordMode);
171aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertEquals(15, p4out.mPasswordMaxFails);
172345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        assertEquals(16, p4out.mMaxScreenLockTime);
1731ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(6, p4out.mPasswordExpirationDays);
1749b4988de43dbee6c06066caab63806e8c8303d7dMarc Blank        assertEquals(5, p4out.mPasswordHistory);
1759b4988de43dbee6c06066caab63806e8c8303d7dMarc Blank        assertEquals(7, p4out.mPasswordComplexChars);
176345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        assertFalse(p4out.mRequireRemoteWipe);
177469f2987dc11d153434e50eb04dd6b83b924d09dAndy Stadler        assertFalse(p4out.mRequireEncryption);
1787fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        assertFalse(p4out.mRequireEncryptionExternal);
179345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
180345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        // add another account which mixes it up (the remaining fields will change)
181345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        // pw length and pw mode - max logic - will *not* change because smaller #s here
182345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        // fail count and lock timer - min logic - will change because smaller #s here
183345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        // wipe required - OR logic - will change here because true
1841ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // expiration time - min logic - will change because lower here
1851ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // history & complex chars - will not change because 0 (unspecified)
186469f2987dc11d153434e50eb04dd6b83b924d09dAndy Stadler        // encryption required - OR logic - will change here because true
1877fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        // encryption external req'd - OR logic - will *not* change here because false
188aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p5in = setupPolicy(4, Policy.PASSWORD_MODE_SIMPLE, 5, 6, true, 1, 0, 0,
1897fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                true, false);
190aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a5 = ProviderTestUtils.setupAccount("sec-5", true, mMockContext);
191aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p5in.setAccountPolicy(mMockContext, a5, "0");
192aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p5out = mSecurityPolicy.computeAggregatePolicy();
193345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        assertNotNull(p5out);
194aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertEquals(20, p5out.mPasswordMinLength);
195aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertEquals(Policy.PASSWORD_MODE_STRONG, p5out.mPasswordMode);
196aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertEquals(5, p5out.mPasswordMaxFails);
197345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        assertEquals(6, p5out.mMaxScreenLockTime);
1981ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(1, p5out.mPasswordExpirationDays);
199469f2987dc11d153434e50eb04dd6b83b924d09dAndy Stadler        assertEquals(5, p5out.mPasswordHistory);
200469f2987dc11d153434e50eb04dd6b83b924d09dAndy Stadler        assertEquals(7, p5out.mPasswordComplexChars);
201345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        assertTrue(p5out.mRequireRemoteWipe);
2027fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        assertFalse(p5out.mRequireEncryptionExternal);
2037fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler
2047fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        // add another account that continues to mutate fields
2057fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        // encryption external req'd - OR logic - will change here because true
206aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p6in = setupPolicy(0, Policy.PASSWORD_MODE_NONE, 0, 0, false, 0, 0, 0,
2077fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, true);
208aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a6 = ProviderTestUtils.setupAccount("sec-6", true, mMockContext);
209aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p6in.setAccountPolicy(mMockContext, a6, "0");
210aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p6out = mSecurityPolicy.computeAggregatePolicy();
2117fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        assertNotNull(p6out);
2127fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        assertTrue(p6out.mRequireEncryptionExternal);
213345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    }
214345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
215345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    /**
2169b4988de43dbee6c06066caab63806e8c8303d7dMarc Blank     * Test equality.  Note, the tests for inequality are poor, as each field should
217345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler     * be tested individually.
218345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler     */
219345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    @SmallTest
2209b4988de43dbee6c06066caab63806e8c8303d7dMarc Blank    public void testEquals() {
221aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p1 =
222aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
223aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p2 =
224aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
225aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3 =
226aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            setupPolicy(2, Policy.PASSWORD_MODE_SIMPLE, 5, 6, true, 7, 8, 9, false, false);
227345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        assertTrue(p1.equals(p2));
228345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler        assertFalse(p2.equals(p3));
229345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler    }
230345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler
2312a5eeea9213005060256054ec773e72406415ce4Andrew Stadler    /**
2322a5eeea9213005060256054ec773e72406415ce4Andrew Stadler     * Test the API to set/clear policy hold flags in an account
2332a5eeea9213005060256054ec773e72406415ce4Andrew Stadler     */
2342a5eeea9213005060256054ec773e72406415ce4Andrew Stadler    public void testSetClearHoldFlag() {
2352a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        Account a1 = ProviderTestUtils.setupAccount("holdflag-1", false, mMockContext);
2362a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        a1.mFlags = Account.FLAGS_NOTIFY_NEW_MAIL;
2372a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        a1.save(mMockContext);
2382a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        Account a2 = ProviderTestUtils.setupAccount("holdflag-2", false, mMockContext);
2399e2ddca59d048fc9ac55278b193ee36b330a7981Jim Shuma        a2.mFlags = Account.FLAGS_VIBRATE_ALWAYS | Account.FLAGS_SECURITY_HOLD;
2402a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        a2.save(mMockContext);
2412a5eeea9213005060256054ec773e72406415ce4Andrew Stadler
2422a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        // confirm clear until set
2432a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        Account a1a = Account.restoreAccountWithId(mMockContext, a1.mId);
2442a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        assertEquals(Account.FLAGS_NOTIFY_NEW_MAIL, a1a.mFlags);
245aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        SecurityPolicy.setAccountHoldFlag(mMockContext, a1, true);
2462a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        assertEquals(Account.FLAGS_NOTIFY_NEW_MAIL | Account.FLAGS_SECURITY_HOLD, a1.mFlags);
2472a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        Account a1b = Account.restoreAccountWithId(mMockContext, a1.mId);
2482a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        assertEquals(Account.FLAGS_NOTIFY_NEW_MAIL | Account.FLAGS_SECURITY_HOLD, a1b.mFlags);
2492a5eeea9213005060256054ec773e72406415ce4Andrew Stadler
2502a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        // confirm set until cleared
2512a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        Account a2a = Account.restoreAccountWithId(mMockContext, a2.mId);
2529e2ddca59d048fc9ac55278b193ee36b330a7981Jim Shuma        assertEquals(Account.FLAGS_VIBRATE_ALWAYS | Account.FLAGS_SECURITY_HOLD, a2a.mFlags);
253aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        SecurityPolicy.setAccountHoldFlag(mMockContext, a2, false);
2549e2ddca59d048fc9ac55278b193ee36b330a7981Jim Shuma        assertEquals(Account.FLAGS_VIBRATE_ALWAYS, a2.mFlags);
2552a5eeea9213005060256054ec773e72406415ce4Andrew Stadler        Account a2b = Account.restoreAccountWithId(mMockContext, a2.mId);
2569e2ddca59d048fc9ac55278b193ee36b330a7981Jim Shuma        assertEquals(Account.FLAGS_VIBRATE_ALWAYS, a2b.mFlags);
2572a5eeea9213005060256054ec773e72406415ce4Andrew Stadler    }
2582a5eeea9213005060256054ec773e72406415ce4Andrew Stadler
259aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    private static class MockController extends Controller {
260aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        protected MockController(Context context) {
261aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            super(context);
262aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        }
263aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank
264aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        protected void backupAccounts(Context context) {
265aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            // For testing, we don't want to back up our accounts
266aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        }
267aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    }
26802d59d21949a77c60859b615312f02e6d8003490Marc Blank
2692a5eeea9213005060256054ec773e72406415ce4Andrew Stadler    /**
270af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler     * Test the response to disabling DeviceAdmin status
271af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler     */
272af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler    public void testDisableAdmin() {
273aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a1 = ProviderTestUtils.setupAccount("disable-1", true, mMockContext);
274aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p1 = setupPolicy(10, Policy.PASSWORD_MODE_SIMPLE, 0, 0, false, 0, 0, 0,
2757fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
276aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p1.setAccountPolicy(mMockContext, a1, "security-sync-key-1");
277af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler
278aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a2 = ProviderTestUtils.setupAccount("disable-2", true, mMockContext);
279aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p2 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0,
2807fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
281aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p2.setAccountPolicy(mMockContext, a2, "security-sync-key-2");
282af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler
283aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a3 = ProviderTestUtils.setupAccount("disable-3", true, mMockContext);
284aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy.clearAccountPolicy(mMockContext, a3);
285af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler
286aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        mSecurityPolicy = SecurityPolicy.getInstance(mMockContext);
287af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler
288aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        // Confirm that "enabling" device admin does not change security status (policy & sync key)
289aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy before = mSecurityPolicy.getAggregatePolicy();
290aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        mSecurityPolicy.onAdminEnabled(true);        // "enabled" should not change anything
291aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy after1 = mSecurityPolicy.getAggregatePolicy();
292af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler        assertEquals(before, after1);
293af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler        Account a1a = Account.restoreAccountWithId(mMockContext, a1.mId);
294af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler        assertNotNull(a1a.mSecuritySyncKey);
295aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertTrue(a1a.mPolicyKey > 0);
296af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler        Account a2a = Account.restoreAccountWithId(mMockContext, a2.mId);
297af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler        assertNotNull(a2a.mSecuritySyncKey);
298aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertTrue(a2a.mPolicyKey > 0);
299af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler        Account a3a = Account.restoreAccountWithId(mMockContext, a3.mId);
300af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler        assertNull(a3a.mSecuritySyncKey);
301aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertTrue(a3a.mPolicyKey == 0);
302af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler
30302d59d21949a77c60859b615312f02e6d8003490Marc Blank        // Simulate revoke of device admin; directly call deleteSecuredAccounts, which is normally
30402d59d21949a77c60859b615312f02e6d8003490Marc Blank        // called from a background thread
305aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        MockController mockController = new MockController(mMockContext);
306aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Controller.injectMockControllerForTest(mockController);
307aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        try {
308aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mSecurityPolicy.deleteSecuredAccounts(mMockContext);
309aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            Policy after2 = mSecurityPolicy.getAggregatePolicy();
310aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            assertEquals(EMPTY_POLICY, after2);
311aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            Account a1b = Account.restoreAccountWithId(mMockContext, a1.mId);
312aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            assertNull(a1b);
313aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            Account a2b = Account.restoreAccountWithId(mMockContext, a2.mId);
314aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            assertNull(a2b);
315aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            Account a3b = Account.restoreAccountWithId(mMockContext, a3.mId);
316aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            assertNull(a3b.mSecuritySyncKey);
317aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        } finally {
318aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            Controller.injectMockControllerForTest(null);
319aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        }
3201ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler    }
3211ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3221ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler    /**
3231ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler     * Test the scanner that finds expiring accounts
3241ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler     */
3251ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler    public void testFindExpiringAccount() {
326aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        ProviderTestUtils.setupAccount("expiring-1", true, mMockContext);
3271ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3281ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // With no expiring accounts, this should return null.
3297fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        long nextExpiringAccountId = SecurityPolicy.findShortestExpiration(mMockContext);
3301ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(-1, nextExpiringAccountId);
3311ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3321ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Add a single expiring account
333aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a2 =
334aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            ProviderTestUtils.setupAccount("expiring-2", true, mMockContext);
335aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p2 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0,
3367fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
337aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p2.setAccountPolicy(mMockContext, a2, "0");
3381ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3391ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // The expiring account should be returned
3407fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        nextExpiringAccountId = SecurityPolicy.findShortestExpiration(mMockContext);
3411ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(a2.mId, nextExpiringAccountId);
3421ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3431ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Add an account with a longer expiration
344aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a3 = ProviderTestUtils.setupAccount("expiring-3", true, mMockContext);
345aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 60, 0, 0,
3467fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
347aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p3.setAccountPolicy(mMockContext, a3, "0");
3481ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3491ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // The original expiring account (a2) should be returned
3507fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        nextExpiringAccountId = SecurityPolicy.findShortestExpiration(mMockContext);
3511ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(a2.mId, nextExpiringAccountId);
3521ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3531ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Add an account with a shorter expiration
354aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a4 = ProviderTestUtils.setupAccount("expiring-4", true, mMockContext);
355aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p4 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 15, 0, 0,
3567fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
357aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p4.setAccountPolicy(mMockContext, a4, "0");
3581ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3591ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // The new expiring account (a4) should be returned
3607fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        nextExpiringAccountId = SecurityPolicy.findShortestExpiration(mMockContext);
3611ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(a4.mId, nextExpiringAccountId);
3621ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler    }
3631ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3641ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler    /**
3651ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler     * Lightweight subclass of the Controller class allows injection of mock context
3661ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler     */
3671ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler    public static class TestController extends Controller {
3681ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3691ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        protected TestController(Context providerContext, Context systemContext) {
3701ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler            super(systemContext);
3711ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler            setProviderContext(providerContext);
37202d59d21949a77c60859b615312f02e6d8003490Marc Blank        }
373af55e3e436991fde91cdc80efe2786eb8f509d15Andrew Stadler    }
3741ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3751ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler    /**
3761ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler     * Test the scanner that wipes expiring accounts
3771ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler     */
3781ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler    public void testWipeExpiringAccounts() {
379aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        mSecurityPolicy = SecurityPolicy.getInstance(mMockContext);
3801ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        TestController testController = new TestController(mMockContext, getContext());
3811ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3821ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Two accounts - a1 is normal, a2 has security (but no expiration)
3831ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        Account a1 = ProviderTestUtils.setupAccount("expired-1", true, mMockContext);
384aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a2 = ProviderTestUtils.setupAccount("expired-2", true, mMockContext);
385aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p2 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 0, 0, 0,
3867fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
387aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p2.setAccountPolicy(mMockContext, a2, "0");
3881ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
3891ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Add a mailbox & messages to each account
3901ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        long account1Id = a1.mId;
3911ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        long account2Id = a2.mId;
3921ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
3931ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        long box1Id = box1.mId;
3941ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false, true, mMockContext);
3951ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false, true, mMockContext);
3961ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account2Id, true, mMockContext);
3971ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        long box2Id = box2.mId;
3981ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        ProviderTestUtils.setupMessage("message3", account2Id, box2Id, false, true, mMockContext);
3991ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        ProviderTestUtils.setupMessage("message4", account2Id, box2Id, false, true, mMockContext);
4001ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
4011ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Run the expiration code - should do nothing
402aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        boolean wiped = SecurityPolicy.wipeExpiredAccounts(mMockContext, testController);
4031ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertFalse(wiped);
4041ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // check mailboxes & messages not wiped
4051ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(2, EmailContent.count(mMockContext, Account.CONTENT_URI));
4061ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(2, EmailContent.count(mMockContext, Mailbox.CONTENT_URI));
4071ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(4, EmailContent.count(mMockContext, Message.CONTENT_URI));
4081ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
4091ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Add 3rd account that really expires
410aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Account a3 = ProviderTestUtils.setupAccount("expired-3", true, mMockContext);
411aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3 = setupPolicy(20, Policy.PASSWORD_MODE_STRONG, 25, 26, false, 30, 0, 0,
4127fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler                false, false);
413aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        p3.setAccountPolicy(mMockContext, a3, "0");
4141ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
4151ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Add mailbox & messages to 3rd account
4161ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        long account3Id = a3.mId;
4171ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        Mailbox box3 = ProviderTestUtils.setupMailbox("box3", account3Id, true, mMockContext);
4181ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        long box3Id = box3.mId;
4191ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        ProviderTestUtils.setupMessage("message5", account3Id, box3Id, false, true, mMockContext);
4201ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        ProviderTestUtils.setupMessage("message6", account3Id, box3Id, false, true, mMockContext);
4211ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
4221ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // check new counts
4231ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(3, EmailContent.count(mMockContext, Account.CONTENT_URI));
4241ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(3, EmailContent.count(mMockContext, Mailbox.CONTENT_URI));
4251ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(6, EmailContent.count(mMockContext, Message.CONTENT_URI));
4261ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
4271ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Run the expiration code - wipe acct #3
428aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        wiped = SecurityPolicy.wipeExpiredAccounts(mMockContext, testController);
4291ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertTrue(wiped);
4301ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // check new counts - account survives but data is wiped
4311ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(3, EmailContent.count(mMockContext, Account.CONTENT_URI));
4321ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(2, EmailContent.count(mMockContext, Mailbox.CONTENT_URI));
4331ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(4, EmailContent.count(mMockContext, Message.CONTENT_URI));
4341ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler
4351ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        // Check security hold states - only #3 should be in hold
4361ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        Account account = Account.restoreAccountWithId(mMockContext, account1Id);
4371ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(0, account.mFlags & Account.FLAGS_SECURITY_HOLD);
4381ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        account = Account.restoreAccountWithId(mMockContext, account2Id);
4391ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(0, account.mFlags & Account.FLAGS_SECURITY_HOLD);
4401ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        account = Account.restoreAccountWithId(mMockContext, account3Id);
4411ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler        assertEquals(Account.FLAGS_SECURITY_HOLD, account.mFlags & Account.FLAGS_SECURITY_HOLD);
4421ca111c19c83d54ad23bd8615d9c648e09ec3366Andy Stadler    }
443a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler
444a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler    /**
445a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler     * Test the code that clears unsupported policies
446a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler     * TODO inject a mock DPM so we can directly control & test all cases, no matter what device
447a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler     */
448a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler    public void testClearUnsupportedPolicies() {
449aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p1 =
450aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, false);
451aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p2 =
452aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, true, false);
453aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3 =
454aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false, true);
455aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank
456aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        mSecurityPolicy = SecurityPolicy.getInstance(mMockContext);
457aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        DevicePolicyManager dpm = mSecurityPolicy.getDPM();
458a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler        boolean hasEncryption =
459a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler            dpm.getStorageEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
460a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler
461aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p1Result = mSecurityPolicy.clearUnsupportedPolicies(p1);
462aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p2Result = mSecurityPolicy.clearUnsupportedPolicies(p2);
463aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3Result = mSecurityPolicy.clearUnsupportedPolicies(p3);
464a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler
4657fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler        // No changes expected when encryptionRequested bits were false
466a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler        assertEquals(p1, p1Result);
467a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler        if (hasEncryption) {
468a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler            // No changes expected
4697fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler            // NOTE:  TODO: Modify to check for external encryption cleared on devices that
4707fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler            // won't support it (e.g. having only unencrypted, removable storage.)
471a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler            assertEquals(p2, p2Result);
4727fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler            assertEquals(p3, p3Result);
473a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler        } else {
4747fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler            // If encryption is unsupported, encryption policy bits are cleared
475aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            Policy policyExpect =
476aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank                setupPolicy(1, Policy.PASSWORD_MODE_STRONG, 3, 4, true, 7, 8, 9, false,
477aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank                        false);
4787fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler            assertEquals(policyExpect, p2Result);
4797fd14be80447de15bd5360321fa80e34f60fa251Andy Stadler            assertEquals(policyExpect, p3Result);
480a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler        }
481a0d080558ff06f88f000cf424803c8241dd8d2ebAndy Stadler    }
48222759bacd95385d95d3d9321f490763df1aba89dAndy Stadler
48322759bacd95385d95d3d9321f490763df1aba89dAndy Stadler    /**
48422759bacd95385d95d3d9321f490763df1aba89dAndy Stadler     * Test the code that converts from exchange-style quality to DPM/Lockscreen style quality.
48522759bacd95385d95d3d9321f490763df1aba89dAndy Stadler     */
48622759bacd95385d95d3d9321f490763df1aba89dAndy Stadler    public void testGetDPManagerPasswordQuality() {
487aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        // Policy.PASSWORD_MODE_NONE -> DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
488aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p1 = setupPolicy(0, Policy.PASSWORD_MODE_NONE,
48922759bacd95385d95d3d9321f490763df1aba89dAndy Stadler                0, 0, false, 0, 0, 0, false, false);
49022759bacd95385d95d3d9321f490763df1aba89dAndy Stadler        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
49122759bacd95385d95d3d9321f490763df1aba89dAndy Stadler                p1.getDPManagerPasswordQuality());
49222759bacd95385d95d3d9321f490763df1aba89dAndy Stadler
49322759bacd95385d95d3d9321f490763df1aba89dAndy Stadler        // PASSWORD_MODE_SIMPLE -> PASSWORD_QUALITY_NUMERIC
494aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p2 = setupPolicy(4, Policy.PASSWORD_MODE_SIMPLE,
49522759bacd95385d95d3d9321f490763df1aba89dAndy Stadler                0, 0, false, 0, 0, 0, false, false);
49622759bacd95385d95d3d9321f490763df1aba89dAndy Stadler        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
49722759bacd95385d95d3d9321f490763df1aba89dAndy Stadler                p2.getDPManagerPasswordQuality());
49822759bacd95385d95d3d9321f490763df1aba89dAndy Stadler
49922759bacd95385d95d3d9321f490763df1aba89dAndy Stadler        // PASSWORD_MODE_STRONG -> PASSWORD_QUALITY_ALPHANUMERIC
500aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p3 = setupPolicy(4, Policy.PASSWORD_MODE_STRONG,
50122759bacd95385d95d3d9321f490763df1aba89dAndy Stadler                0, 0, false, 0, 0, 0, false, false);
50222759bacd95385d95d3d9321f490763df1aba89dAndy Stadler        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
50322759bacd95385d95d3d9321f490763df1aba89dAndy Stadler                p3.getDPManagerPasswordQuality());
50422759bacd95385d95d3d9321f490763df1aba89dAndy Stadler
50522759bacd95385d95d3d9321f490763df1aba89dAndy Stadler        // PASSWORD_MODE_STRONG + complex chars -> PASSWORD_QUALITY_COMPLEX
506aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy p4 = setupPolicy(4, Policy.PASSWORD_MODE_STRONG,
50722759bacd95385d95d3d9321f490763df1aba89dAndy Stadler                0, 0, false, 0, 0 , 2, false, false);
50822759bacd95385d95d3d9321f490763df1aba89dAndy Stadler        assertEquals(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX,
50922759bacd95385d95d3d9321f490763df1aba89dAndy Stadler                p4.getDPManagerPasswordQuality());
51022759bacd95385d95d3d9321f490763df1aba89dAndy Stadler    }
511aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank
512aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    private boolean policySetEqualsPolicy(PolicySet ps, Policy policy) {
513aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if ((ps.mPasswordMode >> LegacyPolicySet.PASSWORD_MODE_SHIFT) != policy.mPasswordMode) {
514aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            return false;
515aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        }
516aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if (ps.mMinPasswordLength != policy.mPasswordMinLength) return false;
517aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if (ps.mPasswordComplexChars != policy.mPasswordComplexChars) return false;
518aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if (ps.mPasswordHistory != policy.mPasswordHistory) return false;
519aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if (ps.mPasswordExpirationDays != policy.mPasswordExpirationDays) return false;
520aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if (ps.mMaxPasswordFails != policy.mPasswordMaxFails) return false;
521aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if (ps.mMaxScreenLockTime != policy.mMaxScreenLockTime) return false;
522aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if (ps.mRequireRemoteWipe != policy.mRequireRemoteWipe) return false;
523aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if (ps.mRequireEncryption != policy.mRequireEncryption) return false;
524aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        if (ps.mRequireEncryptionExternal != policy.mRequireEncryptionExternal) return false;
525aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        return true;
526aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    }
527aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank
528aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    public void testPolicyFlagsToPolicy() {
529aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        // Policy flags; the three sets included here correspond to policies for three test
530aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        // accounts that, between them, use all of the possible policies
531aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        long flags = 67096612L;
532aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        PolicySet ps = new PolicySet(flags);
533aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        Policy policy = LegacyPolicySet.flagsToPolicy(flags);
534aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertTrue(policySetEqualsPolicy(ps, policy));
535aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        flags = 52776591691846L;
536aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        ps = new PolicySet(flags);
537aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy = LegacyPolicySet.flagsToPolicy(flags);
538aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertTrue(policySetEqualsPolicy(ps, policy));
539aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        flags = 1689605957029924L;
540aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        ps = new PolicySet(flags);
541aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        policy = LegacyPolicySet.flagsToPolicy(flags);
542aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        assertTrue(policySetEqualsPolicy(ps, policy));
543aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    }
544aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank
545aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    /**
546aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank     * The old PolicySet class fields and constructor; we use this to test conversion to the
547aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank     * new Policy table scheme
548aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank     */
549aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    private static class PolicySet {
550aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final int mMinPasswordLength;
551aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final int mPasswordMode;
552aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final int mMaxPasswordFails;
553aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final int mMaxScreenLockTime;
554aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final boolean mRequireRemoteWipe;
555aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final int mPasswordExpirationDays;
556aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final int mPasswordHistory;
557aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final int mPasswordComplexChars;
558aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final boolean mRequireEncryption;
559aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private final boolean mRequireEncryptionExternal;
560aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank
561aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        /**
562aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank         * Create from values encoded in an account flags int
563aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank         */
564aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        private PolicySet(long flags) {
565aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mMinPasswordLength = (int) ((flags & LegacyPolicySet.PASSWORD_LENGTH_MASK)
566aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank                    >> LegacyPolicySet.PASSWORD_LENGTH_SHIFT);
567aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mPasswordMode =
568aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank                (int) (flags & LegacyPolicySet.PASSWORD_MODE_MASK);
569aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mMaxPasswordFails = (int) ((flags & LegacyPolicySet.PASSWORD_MAX_FAILS_MASK)
570aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank                    >> LegacyPolicySet.PASSWORD_MAX_FAILS_SHIFT);
571aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mMaxScreenLockTime = (int) ((flags & LegacyPolicySet.SCREEN_LOCK_TIME_MASK)
572aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank                    >> LegacyPolicySet.SCREEN_LOCK_TIME_SHIFT);
573aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mRequireRemoteWipe = 0 != (flags & LegacyPolicySet.REQUIRE_REMOTE_WIPE);
574aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mPasswordExpirationDays = (int) ((flags & LegacyPolicySet.PASSWORD_EXPIRATION_MASK)
575aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank                    >> LegacyPolicySet.PASSWORD_EXPIRATION_SHIFT);
576aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mPasswordHistory = (int) ((flags & LegacyPolicySet.PASSWORD_HISTORY_MASK)
577aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank                    >> LegacyPolicySet.PASSWORD_HISTORY_SHIFT);
578aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mPasswordComplexChars = (int) ((flags & LegacyPolicySet.PASSWORD_COMPLEX_CHARS_MASK)
579aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank                    >> LegacyPolicySet.PASSWORD_COMPLEX_CHARS_SHIFT);
580aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mRequireEncryption = 0 != (flags & LegacyPolicySet.REQUIRE_ENCRYPTION);
581aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank            mRequireEncryptionExternal = 0 != (flags & LegacyPolicySet.REQUIRE_ENCRYPTION_EXTERNAL);
582aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank        }
583aeee10e57ef4d931e7708fde218d590453a82aeaMarc Blank    }
584345fb8b737c1632fb2a7e69ac44b8612be6237edAndrew Stadler}
585