1328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu/* 2328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * Copyright (C) 2013 The Android Open Source Project 3328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * 4328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * Licensed under the Apache License, Version 2.0 (the "License"); 5328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * you may not use this file except in compliance with the License. 6328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * You may obtain a copy of the License at 7328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * 8328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * http://www.apache.org/licenses/LICENSE-2.0 9328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * 10328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * Unless required by applicable law or agreed to in writing, software 11328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * distributed under the License is distributed on an "AS IS" BASIS, 12328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * See the License for the specific language governing permissions and 14328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * limitations under the License. 15328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu */ 16328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 17328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hupackage com.android.exchange.eas; 18328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 19f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Leeimport android.content.ContentValues; 201df4a493b2efa34fce4bd8a70aca57203b4ed037Yu Ping Huimport android.content.Context; 21328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 226c4254903d2f42836c5b74a934e54441ccee6dbeYu Ping Huimport com.android.emailcommon.provider.Account; 23f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Leeimport com.android.emailcommon.provider.EmailContent; 24328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport com.android.emailcommon.provider.Policy; 25328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport com.android.emailcommon.service.PolicyServiceProxy; 26328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport com.android.exchange.Eas; 27328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport com.android.exchange.EasResponse; 28328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport com.android.exchange.adapter.ProvisionParser; 29328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport com.android.exchange.adapter.Serializer; 30328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport com.android.exchange.adapter.Tags; 311df4a493b2efa34fce4bd8a70aca57203b4ed037Yu Ping Huimport com.android.exchange.service.EasServerConnection; 32328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport com.android.mail.utils.LogUtils; 33328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 34328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport org.apache.http.HttpEntity; 35328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 36328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Huimport java.io.IOException; 37328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 38328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu/** 39328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * Implements the EAS Provision protocol. 40328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * 41328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * Provisioning actually consists of two server interactions: 42328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * 1) Ask the server for the required policies. 43328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * 2) Acknowledge our disposition for enforcing those policies. 44328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * 45328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * The structure of the requests and response are essentially the same for both, so we use the 46328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * same code and vary slightly based on which one we're doing. Also, provisioning responses can tell 47328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * us to wipe the device, so we need to handle that too. 48328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * TODO: Make it possible to ack separately, possibly by splitting into separate operations. 49328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * See http://msdn.microsoft.com/en-us/library/ee203567(v=exchg.80).aspx for more details. 50328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu */ 51328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hupublic class EasProvision extends EasOperation { 52328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 53110837ebff288a75f9bda067c38e2c46797d99b5Alon Albert private static final String LOG_TAG = Eas.LOG_TAG; 54328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 55328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** The policy type for versions of EAS prior to 2007. */ 56be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu public static final String EAS_2_POLICY_TYPE = "MS-WAP-Provisioning-XML"; 57328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** The policy type for versions of EAS starting with 2007. */ 58be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu public static final String EAS_12_POLICY_TYPE = "MS-EAS-Provisioning-WBXML"; 59328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 60328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** The EAS protocol Provision status for "we implement all of the policies" */ 61a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee static final String PROVISION_STATUS_OK = "1"; 62328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** The EAS protocol Provision status meaning "we partially implement the policies" */ 63a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee static final String PROVISION_STATUS_PARTIAL = "2"; 64328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 65328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** Value for {@link #mPhase} indicating we're performing the initial request. */ 66a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee static final int PHASE_INITIAL = 0; 67328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** Value for {@link #mPhase} indicating we're performing the acknowledgement request. */ 68a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee static final int PHASE_ACKNOWLEDGE = 1; 69328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** Value for {@link #mPhase} indicating we're performing the acknowledgement for a wipe. */ 70a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee static final int PHASE_WIPE = 2; 71328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 72328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** 73328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * This operation doesn't use public result codes because ultimately the operation answers 74328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * a yes/no question. These result codes are used internally only to communicate from 75328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * {@link #handleResponse}. 76328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu */ 77328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 78328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** Result code indicating the server's policy can be fully supported. */ 79328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu private static final int RESULT_POLICY_SUPPORTED = 1; 80328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** Result code indicating the server's policy cannot be fully supported. */ 81328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu private static final int RESULT_POLICY_UNSUPPORTED = 2; 82328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** Result code indicating the server sent a remote wipe directive. */ 83328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu private static final int RESULT_REMOTE_WIPE = 3; 84328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 85328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu private Policy mPolicy; 86328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu private String mPolicyKey; 87328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu private String mStatus; 88328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 89328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** 90328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * Because this operation supports variants of the request and parsing, and {@link EasOperation} 91328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * has no way to communicate this into {@link #performOperation}, we use this member variable 92328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * to vary how {@link #getRequestEntity} and {@link #handleResponse} work. 93328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu */ 94328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu private int mPhase; 95328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 966c4254903d2f42836c5b74a934e54441ccee6dbeYu Ping Hu public EasProvision(final Context context, final Account account, 971df4a493b2efa34fce4bd8a70aca57203b4ed037Yu Ping Hu final EasServerConnection connection) { 986c4254903d2f42836c5b74a934e54441ccee6dbeYu Ping Hu super(context, account, connection); 991df4a493b2efa34fce4bd8a70aca57203b4ed037Yu Ping Hu mPolicy = null; 1001df4a493b2efa34fce4bd8a70aca57203b4ed037Yu Ping Hu mPolicyKey = null; 1011df4a493b2efa34fce4bd8a70aca57203b4ed037Yu Ping Hu mStatus = null; 1021df4a493b2efa34fce4bd8a70aca57203b4ed037Yu Ping Hu mPhase = 0; 1031df4a493b2efa34fce4bd8a70aca57203b4ed037Yu Ping Hu } 1041df4a493b2efa34fce4bd8a70aca57203b4ed037Yu Ping Hu 105b6ef78e8c4112d47d965b5b274d52fe8885f58faYu Ping Hu public EasProvision(final EasOperation parentOperation) { 106b6ef78e8c4112d47d965b5b274d52fe8885f58faYu Ping Hu super(parentOperation); 107328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mPolicy = null; 108328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mPolicyKey = null; 109328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mStatus = null; 110328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mPhase = 0; 111328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 112328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 1138c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu private int performInitialRequest() { 114328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mPhase = PHASE_INITIAL; 1158c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu return performOperation(); 116328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 117328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 1188c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu private void performAckRequestForWipe() { 119328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mPhase = PHASE_WIPE; 1208c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu performOperation(); 121328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 122328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 1238c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu private int performAckRequest(final boolean isPartial) { 124328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mPhase = PHASE_ACKNOWLEDGE; 125328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mStatus = isPartial ? PROVISION_STATUS_PARTIAL : PROVISION_STATUS_OK; 1268c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu return performOperation(); 127328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 128328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 129328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** 130328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * Make the provisioning calls to determine if we can handle the required policy. 131b6ef78e8c4112d47d965b5b274d52fe8885f58faYu Ping Hu * @return The {@link Policy} if we support it, or null otherwise. 132328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu */ 133b6ef78e8c4112d47d965b5b274d52fe8885f58faYu Ping Hu public final Policy test() { 1348c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu int result = performInitialRequest(); 135328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu if (result == RESULT_POLICY_UNSUPPORTED) { 136328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // Check if the server will permit partial policies. 1378c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu result = performAckRequest(true); 138328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 139b6ef78e8c4112d47d965b5b274d52fe8885f58faYu Ping Hu if (result == RESULT_POLICY_SUPPORTED) { 140be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu // The server is ok with us not supporting everything, so clear the unsupported ones. 141be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu mPolicy.mProtocolPoliciesUnsupported = null; 142b6ef78e8c4112d47d965b5b274d52fe8885f58faYu Ping Hu } 143be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu return (result == RESULT_POLICY_SUPPORTED || result == RESULT_POLICY_UNSUPPORTED) 144be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu ? mPolicy : null; 145328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 146328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 147328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** 148f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee * Write the max attachment size that came out of the policy to the Account table in the db. 149f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee * Once this value is written, the mapping to Account.Settings.MAX_ATTACHMENT_SIZE was 150f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee * added to point to this column in this table. 151f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee * @param maxAttachmentSize The max attachment size value that we want to write to the db. 152f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee */ 153f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee private void storeMaxAttachmentSize(final int maxAttachmentSize) { 154f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee final ContentValues values = new ContentValues(1); 155f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee values.put(EmailContent.AccountColumns.MAX_ATTACHMENT_SIZE, maxAttachmentSize); 156f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee Account.update(mContext, Account.CONTENT_URI, getAccountId(), values); 157f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee } 158f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee 159f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee /** 160328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * Get the required policy from the server and enforce it. 161328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * @return Whether we succeeded in provisioning this account. 162328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu */ 1638c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu public final boolean provision() { 1648c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu final int result = performInitialRequest(); 1658c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu final long accountId = getAccountId(); 166328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 167328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu if (result < 0) { 168328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return false; 169328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 170328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 171328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu if (result == RESULT_REMOTE_WIPE) { 1728c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu performAckRequestForWipe(); 173328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu LogUtils.i(LOG_TAG, "Executing remote wipe"); 174328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu PolicyServiceProxy.remoteWipe(mContext); 175328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return false; 176328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 177328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 178f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee // Even before the policy is accepted, we can honor this setting since it has nothing 179f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee // to do with the device policy manager and is requested by the Exchange server. 1802408dfa83cea2d31e820a3309fc8627ed065cd12Yu Ping Hu // TODO: This was an error, this is minimum change to disable it. 1812408dfa83cea2d31e820a3309fc8627ed065cd12Yu Ping Hu //storeMaxAttachmentSize(mPolicy.mMaxAttachmentSize); 182f4a8a08aee041db51a8baa9b64a4cffc1c83a6e6Anthony Lee 183328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // Apply the policies (that we support) with the temporary key. 184f4b85896898ab862ea2c94fc147df363a78df14cJay Shrauner if (mPolicy != null) { 185f4b85896898ab862ea2c94fc147df363a78df14cJay Shrauner mPolicy.mProtocolPoliciesUnsupported = null; 186f4b85896898ab862ea2c94fc147df363a78df14cJay Shrauner } 187328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu PolicyServiceProxy.setAccountPolicy(mContext, accountId, mPolicy, null); 188328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu if (!PolicyServiceProxy.isActive(mContext, mPolicy)) { 189328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return false; 190328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 191328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 192328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // Acknowledge to the server and make sure all's well. 1938c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu if (performAckRequest(result == RESULT_POLICY_UNSUPPORTED) == RESULT_POLICY_UNSUPPORTED) { 194328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return false; 195328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 196328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 197328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // Write the final policy key to the Account. 198328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu PolicyServiceProxy.setAccountPolicy(mContext, accountId, mPolicy, mPolicyKey); 199be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu 200be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu // For 12.1 and 14.0, after provisioning we need to also send the device information via 201be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu // the Settings command. 202be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu // See the comments for EasSettings for more details. 203be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu final double version = getProtocolVersion(); 204be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu if (version == Eas.SUPPORTED_PROTOCOL_EX2007_SP1_DOUBLE 205be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu || version == Eas.SUPPORTED_PROTOCOL_EX2010_DOUBLE) { 206be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu final EasSettings settingsOperation = new EasSettings(this); 2078c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu if (!settingsOperation.sendDeviceInformation()) { 2082e8ce13ff0b47f2b0b2f06541a0c155e0727a40dYu Ping Hu // TODO: Do something more useful when the settings command fails. 2092e8ce13ff0b47f2b0b2f06541a0c155e0727a40dYu Ping Hu // The consequence here is that the server will not have device info. 2102e8ce13ff0b47f2b0b2f06541a0c155e0727a40dYu Ping Hu // However, this is NOT a provisioning failure. 211be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu } 212be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu } 213be22ff8b8b3aa6057de165b76da433cabad4dcfdYu Ping Hu 214328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return true; 215328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 216328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 217328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu @Override 218328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu protected String getCommand() { 219328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return "Provision"; 220328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 221328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 222a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee /** 223a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * Add the device information to the current request. 224a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * @param context The {@link Context} for the current device. 225a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * @param userAgent The user agent string that our connection uses. 226a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * @param policyKey EAS specific tag for Provision requests. 227a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * @param policyType EAS specific tag for Provision requests. 228a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * @param status The status value that we are sending to the server in our request. 229a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * @param phase The phase of the provisioning process this requests is built for. 230a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * @param protocolVersion The version of the EAS protocol that we should speak. 231a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * @return The {@link Serializer} containing the payload for this request. 232a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee */ 233a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee protected static Serializer generateRequestEntitySerializer( 234a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee final Context context, final String userAgent, final String policyKey, 235a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee final String policyType, final String status, final int phase, 236a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee final double protocolVersion) throws IOException { 237328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu final Serializer s = new Serializer(); 238328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu s.start(Tags.PROVISION_PROVISION); 239328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 240328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // When requesting the policy in 14.1, we also need to send device information. 241a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee if (phase == PHASE_INITIAL && 242a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee protocolVersion >= Eas.SUPPORTED_PROTOCOL_EX2010_SP1_DOUBLE) { 243a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee // The "inner" version of this function is being used because it is 244a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee // re-entrant and can be unit tested easier. Until we are unit testing 245a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee // everything, the other version of this function still lives so that 246a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee // we are disrupting as little code as possible for now. 247a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee expandedAddDeviceInformationToSerializer(s, context, userAgent); 248328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 249a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee if (phase == PHASE_WIPE) { 250328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu s.start(Tags.PROVISION_REMOTE_WIPE); 251328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu s.data(Tags.PROVISION_STATUS, PROVISION_STATUS_OK); 252a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee s.end(); // PROVISION_REMOTE_WIPE 253a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee } else { 254a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee s.start(Tags.PROVISION_POLICIES); 255a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee s.start(Tags.PROVISION_POLICY); 256a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee s.data(Tags.PROVISION_POLICY_TYPE, policyType); 257a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee // When acknowledging a policy, we tell the server whether we applied the policy. 258a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee if (phase == PHASE_ACKNOWLEDGE) { 259a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee s.data(Tags.PROVISION_POLICY_KEY, policyKey); 260a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee s.data(Tags.PROVISION_STATUS, status); 261a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee } 262a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee s.end().end(); // PROVISION_POLICY, PROVISION_POLICIES, 263328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 264a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee s.end().done(); // PROVISION_PROVISION 265a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee return s; 266a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee } 267328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 268a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee /** 269a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * Generates a request entity based on the type of request and our current context. 270a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee * @return The {@link HttpEntity} that was generated for this request. 271a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee */ 272a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee @Override 273a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee protected HttpEntity getRequestEntity() throws IOException { 274a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee final String policyType = getPolicyType(); 275a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee final String userAgent = getUserAgent(); 276a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee final double protocolVersion = getProtocolVersion(); 277a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee final Serializer s = generateRequestEntitySerializer(mContext, userAgent, mPolicyKey, 278a09e6cc2e8fca144de4d0b69f129b177f4a3219bAnthony Lee policyType, mStatus, mPhase, protocolVersion); 279328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return makeEntity(s); 280328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 281328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 282328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu @Override 2838c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu protected int handleResponse(final EasResponse response) throws IOException { 284328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu final ProvisionParser pp = new ProvisionParser(mContext, response.getInputStream()); 285328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // If this is the response for a remote wipe ack, it doesn't have anything useful in it. 286328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // Just go ahead and return now. 287328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu if (mPhase == PHASE_WIPE) { 288328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return RESULT_REMOTE_WIPE; 289328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 290328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 291328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu if (!pp.parse()) { 292328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu throw new IOException("Error while parsing response"); 293328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 294328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 295328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // What we care about in the response depends on what phase we're in. 296328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu if (mPhase == PHASE_INITIAL) { 297328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu if (pp.getRemoteWipe()) { 298328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return RESULT_REMOTE_WIPE; 299328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 300328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mPolicy = pp.getPolicy(); 301328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mPolicyKey = pp.getSecuritySyncKey(); 302328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 303328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return (pp.hasSupportablePolicySet() 304328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu ? RESULT_POLICY_SUPPORTED : RESULT_POLICY_UNSUPPORTED); 305328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 306328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 307328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu if (mPhase == PHASE_ACKNOWLEDGE) { 308328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu mPolicyKey = pp.getSecuritySyncKey(); 309328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return (mPolicyKey != null ? RESULT_POLICY_SUPPORTED : RESULT_POLICY_UNSUPPORTED); 310328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 311328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 312328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // Note: this should be unreachable, but the compiler doesn't know it. 313328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // If we somehow get here, act like we can't do anything. 314328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return RESULT_POLICY_UNSUPPORTED; 315328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 316328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 317328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu @Override 3188c95506ad96f5990d5e4d4ca86b05ec95dd4b1d6Yu Ping Hu protected boolean handleProvisionError() { 319328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu // If we get a provisioning error while doing provisioning, we should not recurse. 320328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return false; 321328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 322328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu 323328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu /** 324328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu * @return The policy type for this connection. 325328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu */ 326328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu private final String getPolicyType() { 327328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu return (getProtocolVersion() >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) ? 328328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu EAS_12_POLICY_TYPE : EAS_2_POLICY_TYPE; 329328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu } 330328ca0d959f7e729e96f19538c8f3af8fe782a09Yu Ping Hu} 331