1d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank/* Copyright (C) 2010 The Android Open Source Project.
2d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank *
3d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * Licensed under the Apache License, Version 2.0 (the "License");
4d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * you may not use this file except in compliance with the License.
5d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * You may obtain a copy of the License at
6d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank *
7d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank *      http://www.apache.org/licenses/LICENSE-2.0
8d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank *
9d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * Unless required by applicable law or agreed to in writing, software
10d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * distributed under the License is distributed on an "AS IS" BASIS,
11d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * See the License for the specific language governing permissions and
13d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * limitations under the License.
14d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank */
15d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
16d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankpackage com.android.exchange.adapter;
17d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
18d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.app.admin.DevicePolicyManager;
19d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.content.Context;
20d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.content.res.Resources;
21d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.os.storage.StorageManager;
22d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.os.storage.StorageVolume;
23d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
24d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.emailcommon.provider.Policy;
25d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.exchange.EasSyncService;
26d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.exchange.R;
27d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
28d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport org.xmlpull.v1.XmlPullParser;
29d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport org.xmlpull.v1.XmlPullParserException;
30d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport org.xmlpull.v1.XmlPullParserFactory;
31d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
32d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport java.io.ByteArrayInputStream;
33d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport java.io.IOException;
34d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport java.io.InputStream;
35d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport java.util.ArrayList;
36d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
37d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank/**
38d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * Parse the result of the Provision command
39d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank */
40d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankpublic class ProvisionParser extends Parser {
41d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private final EasSyncService mService;
42d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private Policy mPolicy = null;
43d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private String mSecuritySyncKey = null;
44d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private boolean mRemoteWipe = false;
45d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private boolean mIsSupportable = true;
46d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private boolean smimeRequired = false;
47d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private final Resources mResources;
48d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
49d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    public ProvisionParser(InputStream in, EasSyncService service) throws IOException {
50d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        super(in);
51d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        mService = service;
52d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        mResources = service.mContext.getResources();
53d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
54d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
55d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    public Policy getPolicy() {
56d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        return mPolicy;
57d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
58d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
59d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    public String getSecuritySyncKey() {
60d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        return mSecuritySyncKey;
61d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
62d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
63d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    public void setSecuritySyncKey(String securitySyncKey) {
64d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        mSecuritySyncKey = securitySyncKey;
65d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
66d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
67d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    public boolean getRemoteWipe() {
68d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        return mRemoteWipe;
69d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
70d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
71d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    public boolean hasSupportablePolicySet() {
72d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        return (mPolicy != null) && mIsSupportable;
73d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
74d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
75d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    public void clearUnsupportablePolicies() {
76d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        mIsSupportable = true;
77d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        mPolicy.mProtocolPoliciesUnsupported = null;
78d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
79d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
80d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void addPolicyString(StringBuilder sb, int res) {
81d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        sb.append(mResources.getString(res));
82d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        sb.append(Policy.POLICY_STRING_DELIMITER);
83d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
84d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
85d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    /**
86d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     * Complete setup of a Policy; we normalize it first (removing inconsistencies, etc.) and then
87d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     * generate the tokenized "protocol policies enforced" string.  Note that unsupported policies
88d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     * must have been added prior to calling this method (this is only a possibility with wbxml
89d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     * policy documents, as all versions of the OS support the policies in xml documents).
90d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     */
91d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void setPolicy(Policy policy) {
92d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        policy.normalize();
93d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        StringBuilder sb = new StringBuilder();
94d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        if (policy.mDontAllowAttachments) {
95d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            addPolicyString(sb, R.string.policy_dont_allow_attachments);
96d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
97d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        if (policy.mRequireManualSyncWhenRoaming) {
98d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            addPolicyString(sb, R.string.policy_require_manual_sync_roaming);
99d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
100d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        policy.mProtocolPoliciesEnforced = sb.toString();
101d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        mPolicy = policy;
102d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
103d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
104d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private boolean deviceSupportsEncryption() {
105d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        DevicePolicyManager dpm = (DevicePolicyManager)
106d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                mService.mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
107d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        int status = dpm.getStorageEncryptionStatus();
108d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        return status != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
109d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
110d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
111d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void parseProvisionDocWbxml() throws IOException {
112d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        Policy policy = new Policy();
113d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        ArrayList<Integer> unsupportedList = new ArrayList<Integer>();
114d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        boolean passwordEnabled = false;
115d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
116d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (nextTag(Tags.PROVISION_EAS_PROVISION_DOC) != END) {
117d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            boolean tagIsSupported = true;
118d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            int res = 0;
119d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            switch (tag) {
120d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_DEVICE_PASSWORD_ENABLED:
121d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (getValueInt() == 1) {
122d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        passwordEnabled = true;
123d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (policy.mPasswordMode == Policy.PASSWORD_MODE_NONE) {
124d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            policy.mPasswordMode = Policy.PASSWORD_MODE_SIMPLE;
125d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
126d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
127d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
128d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_MIN_DEVICE_PASSWORD_LENGTH:
129d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mPasswordMinLength = getValueInt();
130d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
131d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALPHA_DEVICE_PASSWORD_ENABLED:
132d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (getValueInt() == 1) {
133d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        policy.mPasswordMode = Policy.PASSWORD_MODE_STRONG;
134d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
135d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
136d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_MAX_INACTIVITY_TIME_DEVICE_LOCK:
137d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    // EAS gives us seconds, which is, happily, what the PolicySet requires
138d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mMaxScreenLockTime = getValueInt();
139d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
140d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_MAX_DEVICE_PASSWORD_FAILED_ATTEMPTS:
141d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mPasswordMaxFails = getValueInt();
142d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
143d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_DEVICE_PASSWORD_EXPIRATION:
144d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mPasswordExpirationDays = getValueInt();
145d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
146d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_DEVICE_PASSWORD_HISTORY:
147d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mPasswordHistory = getValueInt();
148d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
149d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_CAMERA:
150d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mDontAllowCamera = (getValueInt() == 0);
151d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
152d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_SIMPLE_DEVICE_PASSWORD:
153d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    // Ignore this unless there's any MSFT documentation for what this means
154d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    // Hint: I haven't seen any that's more specific than "simple"
155d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    getValue();
156d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
157d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // The following policies, if false, can't be supported at the moment
158d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_STORAGE_CARD:
159d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_UNSIGNED_APPLICATIONS:
160d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_UNSIGNED_INSTALLATION_PACKAGES:
161d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_WIFI:
162d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_TEXT_MESSAGING:
163d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_POP_IMAP_EMAIL:
164d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_IRDA:
165d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_HTML_EMAIL:
166d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_BROWSER:
167d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_CONSUMER_EMAIL:
168d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_INTERNET_SHARING:
169d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (getValueInt() == 0) {
170d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        tagIsSupported = false;
171d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        switch(tag) {
172d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_STORAGE_CARD:
173d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_storage_cards;
174d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
175d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_UNSIGNED_APPLICATIONS:
176d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_unsigned_apps;
177d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
178d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_UNSIGNED_INSTALLATION_PACKAGES:
179d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_unsigned_installers;
180d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
181d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_WIFI:
182d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_wifi;
183d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
184d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_TEXT_MESSAGING:
185d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_text_messaging;
186d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
187d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_POP_IMAP_EMAIL:
188d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_pop_imap;
189d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
190d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_IRDA:
191d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_irda;
192d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
193d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_HTML_EMAIL:
194d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_html;
195d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                policy.mDontAllowHtml = true;
196d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
197d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_BROWSER:
198d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_browser;
199d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
200d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_CONSUMER_EMAIL:
201d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_consumer_email;
202d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
203d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            case Tags.PROVISION_ALLOW_INTERNET_SHARING:
204d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                res = R.string.policy_dont_allow_internet_sharing;
205d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
206d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
207d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (res > 0) {
208d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            unsupportedList.add(res);
209d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
210d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
211d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
212d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ATTACHMENTS_ENABLED:
213d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mDontAllowAttachments = getValueInt() != 1;
214d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
215d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // Bluetooth: 0 = no bluetooth; 1 = only hands-free; 2 = allowed
216d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_BLUETOOTH:
217d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (getValueInt() != 2) {
218d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        tagIsSupported = false;
219d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        unsupportedList.add(R.string.policy_bluetooth_restricted);
220d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
221d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
222d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // We may now support device (internal) encryption; we'll check this capability
223d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // below with the call to SecurityPolicy.isSupported()
224d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_REQUIRE_DEVICE_ENCRYPTION:
225d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (getValueInt() == 1) {
226d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                         if (!deviceSupportsEncryption()) {
227d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            tagIsSupported = false;
228d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            unsupportedList.add(R.string.policy_require_encryption);
229d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        } else {
230d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            policy.mRequireEncryption = true;
231d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
232d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
233d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
234d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // Note that DEVICE_ENCRYPTION_ENABLED refers to SD card encryption, which the OS
235d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // does not yet support.
236d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_DEVICE_ENCRYPTION_ENABLED:
237d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (getValueInt() == 1) {
238d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        log("Policy requires SD card encryption");
239d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        // Let's see if this can be supported on our device...
240d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (deviceSupportsEncryption()) {
241d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            StorageManager sm = (StorageManager)mService.mContext.getSystemService(
242d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                    Context.STORAGE_SERVICE);
243d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            // NOTE: Private API!
244d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            // Go through volumes; if ANY are removable, we can't support this
245d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            // policy.
246d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            StorageVolume[] volumeList = sm.getVolumeList();
247d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            for (StorageVolume volume: volumeList) {
248d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                if (volume.isRemovable()) {
249d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                    tagIsSupported = false;
250cebad501386e803eaea73f6c4301e370a4d4e222Fabrice Di Meglio                                    log("Removable: " + volume.getDescription(mService.mContext));
251d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                    break;  // Break only from the storage volume loop
252d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                } else {
253cebad501386e803eaea73f6c4301e370a4d4e222Fabrice Di Meglio                                    log("Not Removable: " + volume.getDescription(mService.mContext));
254d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                }
255d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            }
256d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            if (tagIsSupported) {
257d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                // If this policy is requested, we MUST also require encryption
258d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                log("Device supports SD card encryption");
259d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                policy.mRequireEncryption = true;
260d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                break;
261d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            }
262d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        } else {
263d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            log("Device doesn't support encryption; failing");
264d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            tagIsSupported = false;
265d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
266d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        // If we fall through, we can't support the policy
267d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        unsupportedList.add(R.string.policy_require_sd_encryption);
268d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
269d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
270d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    // Note this policy; we enforce it in ExchangeService
271d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_REQUIRE_MANUAL_SYNC_WHEN_ROAMING:
272d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mRequireManualSyncWhenRoaming = getValueInt() == 1;
273d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
274d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // We are allowed to accept policies, regardless of value of this tag
275d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // TODO: When we DO support a recovery password, we need to store the value in
276d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // the account (so we know to utilize it)
277d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_PASSWORD_RECOVERY_ENABLED:
278d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    // Read, but ignore, value
279d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mPasswordRecoveryEnabled = getValueInt() == 1;
280d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
281d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // The following policies, if true, can't be supported at the moment
282d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_REQUIRE_SIGNED_SMIME_MESSAGES:
283d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_REQUIRE_ENCRYPTED_SMIME_MESSAGES:
284d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_REQUIRE_SIGNED_SMIME_ALGORITHM:
285d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_REQUIRE_ENCRYPTION_SMIME_ALGORITHM:
286d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (getValueInt() == 1) {
287d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        tagIsSupported = false;
288d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (!smimeRequired) {
289d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            unsupportedList.add(R.string.policy_require_smime);
290d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            smimeRequired = true;
291d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
292d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
293d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
294d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_MAX_ATTACHMENT_SIZE:
295d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    int max = getValueInt();
296d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (max > 0) {
297d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        policy.mMaxAttachmentSize = max;
298d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
299d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
300d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // Complex characters are supported
301d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_MIN_DEVICE_PASSWORD_COMPLEX_CHARS:
302d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mPasswordComplexChars = getValueInt();
303d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
304d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // The following policies are moot; they allow functionality that we don't support
305d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_DESKTOP_SYNC:
306d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_SMIME_ENCRYPTION_NEGOTIATION:
307d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_SMIME_SOFT_CERTS:
308d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_ALLOW_REMOTE_DESKTOP:
309d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    skipTag();
310d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
311d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // We don't handle approved/unapproved application lists
312d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_UNAPPROVED_IN_ROM_APPLICATION_LIST:
313d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_APPROVED_APPLICATION_LIST:
314d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    // Parse and throw away the content
315d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (specifiesApplications(tag)) {
316d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        tagIsSupported = false;
317d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (tag == Tags.PROVISION_UNAPPROVED_IN_ROM_APPLICATION_LIST) {
318d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            unsupportedList.add(R.string.policy_app_blacklist);
319d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        } else {
320d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            unsupportedList.add(R.string.policy_app_whitelist);
321d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
322d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
323d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
324d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // We accept calendar age, since we never ask for more than two weeks, and that's
325d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // the most restrictive policy
326d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_MAX_CALENDAR_AGE_FILTER:
327d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mMaxCalendarLookback = getValueInt();
328d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
329d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // We handle max email lookback
330d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_MAX_EMAIL_AGE_FILTER:
331d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policy.mMaxEmailLookback = getValueInt();
332d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
333d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                // We currently reject these next two policies
334d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_MAX_EMAIL_BODY_TRUNCATION_SIZE:
335d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_MAX_EMAIL_HTML_BODY_TRUNCATION_SIZE:
336d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    String value = getValue();
337d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    // -1 indicates no required truncation
338d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (!value.equals("-1")) {
339d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        max = Integer.parseInt(value);
340d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (tag == Tags.PROVISION_MAX_EMAIL_BODY_TRUNCATION_SIZE) {
341d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            policy.mMaxTextTruncationSize = max;
342d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            unsupportedList.add(R.string.policy_text_truncation);
343d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        } else {
344d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            policy.mMaxHtmlTruncationSize = max;
345d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            unsupportedList.add(R.string.policy_html_truncation);
346d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
347d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        tagIsSupported = false;
348d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
349d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
350d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                default:
351d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    skipTag();
352d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
353d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
354d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            if (!tagIsSupported) {
355d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                log("Policy not supported: " + tag);
356d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                mIsSupportable = false;
357d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
358d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
359d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
360d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        // Make sure policy settings are valid; password not enabled trumps other password settings
361d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        if (!passwordEnabled) {
362d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            policy.mPasswordMode = Policy.PASSWORD_MODE_NONE;
363d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
364d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
365d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        if (!unsupportedList.isEmpty()) {
366d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            StringBuilder sb = new StringBuilder();
367d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            for (int res: unsupportedList) {
368d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                addPolicyString(sb, res);
369d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
370d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            policy.mProtocolPoliciesUnsupported = sb.toString();
371d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
372d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
373d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        setPolicy(policy);
374d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
375d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
376d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    /**
377d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     * Return whether or not either of the application list tags specifies any applications
378d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     * @param endTag the tag whose children we're walking through
379d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     * @return whether any applications were specified (by name or by hash)
380d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     * @throws IOException
381d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     */
382d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private boolean specifiesApplications(int endTag) throws IOException {
383d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        boolean specifiesApplications = false;
384d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (nextTag(endTag) != END) {
385d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            switch (tag) {
386d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_APPLICATION_NAME:
387d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_HASH:
388d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    specifiesApplications = true;
389d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
390d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                default:
391d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    skipTag();
392d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
393d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
394d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        return specifiesApplications;
395d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
396d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
397d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    /*package*/ void parseProvisionDocXml(String doc) throws IOException {
398d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        Policy policy = new Policy();
399d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
400d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        try {
401d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
402d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            XmlPullParser parser = factory.newPullParser();
403d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            parser.setInput(new ByteArrayInputStream(doc.getBytes()), "UTF-8");
404d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            int type = parser.getEventType();
405d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            if (type == XmlPullParser.START_DOCUMENT) {
406d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                type = parser.next();
407d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                if (type == XmlPullParser.START_TAG) {
408d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    String tagName = parser.getName();
409d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (tagName.equals("wap-provisioningdoc")) {
410d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        parseWapProvisioningDoc(parser, policy);
411d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
412d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                }
413d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
414d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        } catch (XmlPullParserException e) {
415d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank           throw new IOException();
416d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
417d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
418d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        setPolicy(policy);
419d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
420d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
421d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    /**
422d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     * Return true if password is required; otherwise false.
423d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank     */
424d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private boolean parseSecurityPolicy(XmlPullParser parser, Policy policy)
425d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            throws XmlPullParserException, IOException {
426d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        boolean passwordRequired = true;
427d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (true) {
428d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            int type = parser.nextTag();
429d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            if (type == XmlPullParser.END_TAG && parser.getName().equals("characteristic")) {
430d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                break;
431d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            } else if (type == XmlPullParser.START_TAG) {
432d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                String tagName = parser.getName();
433d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                if (tagName.equals("parm")) {
434d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    String name = parser.getAttributeValue(null, "name");
435d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (name.equals("4131")) {
436d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        String value = parser.getAttributeValue(null, "value");
437d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (value.equals("1")) {
438d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            passwordRequired = false;
439d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
440d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
441d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                }
442d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
443d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
444d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        return passwordRequired;
445d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
446d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
447d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void parseCharacteristic(XmlPullParser parser, Policy policy)
448d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            throws XmlPullParserException, IOException {
449d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        boolean enforceInactivityTimer = true;
450d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (true) {
451d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            int type = parser.nextTag();
452d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            if (type == XmlPullParser.END_TAG && parser.getName().equals("characteristic")) {
453d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                break;
454d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            } else if (type == XmlPullParser.START_TAG) {
455d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                if (parser.getName().equals("parm")) {
456d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    String name = parser.getAttributeValue(null, "name");
457d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    String value = parser.getAttributeValue(null, "value");
458d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (name.equals("AEFrequencyValue")) {
459d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (enforceInactivityTimer) {
460d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            if (value.equals("0")) {
461d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                policy.mMaxScreenLockTime = 1;
462d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            } else {
463d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                                policy.mMaxScreenLockTime = 60*Integer.parseInt(value);
464d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            }
465d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
466d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    } else if (name.equals("AEFrequencyType")) {
467d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        // "0" here means we don't enforce an inactivity timeout
468d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (value.equals("0")) {
469d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            enforceInactivityTimer = false;
470d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
471d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    } else if (name.equals("DeviceWipeThreshold")) {
472d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        policy.mPasswordMaxFails = Integer.parseInt(value);
473d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    } else if (name.equals("CodewordFrequency")) {
474d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        // Ignore; has no meaning for us
475d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    } else if (name.equals("MinimumPasswordLength")) {
476d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        policy.mPasswordMinLength = Integer.parseInt(value);
477d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    } else if (name.equals("PasswordComplexity")) {
478d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (value.equals("0")) {
479d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            policy.mPasswordMode = Policy.PASSWORD_MODE_STRONG;
480d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        } else {
481d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            policy.mPasswordMode = Policy.PASSWORD_MODE_SIMPLE;
482d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
483d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
484d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                }
485d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
486d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
487d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
488d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
489d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void parseRegistry(XmlPullParser parser, Policy policy)
490d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            throws XmlPullParserException, IOException {
491d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank      while (true) {
492d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank          int type = parser.nextTag();
493d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank          if (type == XmlPullParser.END_TAG && parser.getName().equals("characteristic")) {
494d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank              break;
495d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank          } else if (type == XmlPullParser.START_TAG) {
496d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank              String name = parser.getName();
497d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank              if (name.equals("characteristic")) {
498d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                  parseCharacteristic(parser, policy);
499d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank              }
500d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank          }
501d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank      }
502d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
503d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
504d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void parseWapProvisioningDoc(XmlPullParser parser, Policy policy)
505d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            throws XmlPullParserException, IOException {
506d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (true) {
507d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            int type = parser.nextTag();
508d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            if (type == XmlPullParser.END_TAG && parser.getName().equals("wap-provisioningdoc")) {
509d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                break;
510d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            } else if (type == XmlPullParser.START_TAG) {
511d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                String name = parser.getName();
512d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                if (name.equals("characteristic")) {
513d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    String atype = parser.getAttributeValue(null, "type");
514d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (atype.equals("SecurityPolicy")) {
515d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        // If a password isn't required, stop here
516d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        if (!parseSecurityPolicy(parser, policy)) {
517d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                            return;
518d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        }
519d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    } else if (atype.equals("Registry")) {
520d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        parseRegistry(parser, policy);
521d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        return;
522d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
523d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                }
524d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
525d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
526d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
527d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
528d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void parseProvisionData() throws IOException {
529d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (nextTag(Tags.PROVISION_DATA) != END) {
530d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            if (tag == Tags.PROVISION_EAS_PROVISION_DOC) {
531d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                parseProvisionDocWbxml();
532d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            } else {
533d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                skipTag();
534d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
535d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
536d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
537d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
538d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void parsePolicy() throws IOException {
539d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        String policyType = null;
540d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (nextTag(Tags.PROVISION_POLICY) != END) {
541d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            switch (tag) {
542d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_POLICY_TYPE:
543d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    policyType = getValue();
544d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    mService.userLog("Policy type: ", policyType);
545d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
546d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_POLICY_KEY:
547d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    mSecuritySyncKey = getValue();
548d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
549d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_STATUS:
550d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    mService.userLog("Policy status: ", getValue());
551d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
552d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_DATA:
553d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    if (policyType.equalsIgnoreCase(EasSyncService.EAS_2_POLICY_TYPE)) {
554d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        // Parse the old style XML document
555d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        parseProvisionDocXml(getValue());
556d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    } else {
557d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        // Parse the newer WBXML data
558d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                        parseProvisionData();
559d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    }
560d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
561d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                default:
562d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    skipTag();
563d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
564d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
565d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
566d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
567d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void parsePolicies() throws IOException {
568d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (nextTag(Tags.PROVISION_POLICIES) != END) {
569d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            if (tag == Tags.PROVISION_POLICY) {
570d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                parsePolicy();
571d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            } else {
572d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                skipTag();
573d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
574d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
575d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
576d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
577d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    private void parseDeviceInformation() throws IOException {
578d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (nextTag(Tags.SETTINGS_DEVICE_INFORMATION) != END) {
579d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            if (tag == Tags.SETTINGS_STATUS) {
580d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                mService.userLog("DeviceInformation status: " + getValue());
581d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            } else {
582d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                skipTag();
583d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
584d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
585d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
586d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank
587d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    @Override
588d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    public boolean parse() throws IOException {
589d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        boolean res = false;
590d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        if (nextTag(START_DOCUMENT) != Tags.PROVISION_PROVISION) {
591d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            throw new IOException();
592d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
593d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
594d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            switch (tag) {
595d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_STATUS:
596d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    int status = getValueInt();
597d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    mService.userLog("Provision status: ", status);
598d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    res = (status == 1);
599d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
600d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.SETTINGS_DEVICE_INFORMATION:
601d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    parseDeviceInformation();
602d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
603d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_POLICIES:
604d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    parsePolicies();
605d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
606d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                case Tags.PROVISION_REMOTE_WIPE:
607d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    // Indicate remote wipe command received
608d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    mRemoteWipe = true;
609d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    break;
610d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                default:
611d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank                    skipTag();
612d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank            }
613d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        }
614d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank        return res;
615d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank    }
616d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank}
617