blob: 93d614124d46a42edc20c350202c7c95a5902203 [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.exchange.eas;
import android.content.Context;
import android.content.SyncResult;
import android.os.Bundle;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.HostAuth;
import com.android.exchange.CommandStatusException;
import com.android.exchange.EasResponse;
import com.android.exchange.adapter.FolderSyncParser;
import com.android.exchange.adapter.Serializer;
import com.android.exchange.adapter.Tags;
import com.android.mail.utils.LogUtils;
import org.apache.http.HttpEntity;
import java.io.IOException;
/**
* Implements the EAS FolderSync command. We use this both to actually do a folder sync, and also
* during account adding flow as a convenient command to validate the account settings (e.g. since
* it needs to login and will tell us about provisioning requirements).
* TODO: Doing validation here is kind of wonky. There must be a better way.
*
* See http://msdn.microsoft.com/en-us/library/ee237648(v=exchg.80).aspx for more details.
*/
public class EasFolderSync extends EasOperation {
/** Result code indicating the sync completed correctly. */
public static final int RESULT_OK = 1;
/**
* Result code indicating that this object was constructed for sync and was asked to validate,
* or vice versa.
*/
public static final int RESULT_WRONG_OPERATION = 2;
// TODO: Eliminate the need for mAccount (requires FolderSyncParser changes).
private final Account mAccount;
/** Indicates whether this object is for validation rather than sync. */
private final boolean mStatusOnly;
/**
* Constructor for actually doing folder sync.
* @param context
* @param account
*/
public EasFolderSync(final Context context, final Account account) {
super(context, account);
mAccount = account;
mStatusOnly = false;
}
/**
* Constructor for account validation.
* @param context
* @param hostAuth
*/
public EasFolderSync(final Context context, final HostAuth hostAuth) {
this(context, new Account(), hostAuth);
}
private EasFolderSync(final Context context, final Account account, final HostAuth hostAuth) {
super(context, account, hostAuth);
mAccount = account;
mAccount.mEmailAddress = hostAuth.mLogin;
mStatusOnly = true;
}
/**
* Perform a folder sync.
* @param syncResult The {@link SyncResult} object for this sync operation.
* @return A result code, either from above or from the base class.
*/
public int doFolderSync(final SyncResult syncResult) {
if (mStatusOnly) {
return RESULT_WRONG_OPERATION;
}
LogUtils.i(LOG_TAG, "Performing sync for account %d", mAccount.mId);
return performOperation(syncResult);
}
/**
* Perform account validation.
* TODO: Implement correctly.
* @param bundle The {@link Bundle} to provide the results of validation to the UI.
* @return A result code, either from above or from the base class.
*/
public int validate(final Bundle bundle) {
if (!mStatusOnly || bundle == null) {
return RESULT_WRONG_OPERATION;
}
LogUtils.i(LOG_TAG, "Performing validation");
final int result = performOperation(null);
return RESULT_OK;
}
@Override
protected String getCommand() {
return "FolderSync";
}
@Override
protected HttpEntity getRequestEntity() throws IOException {
final String syncKey = mAccount.mSyncKey != null ? mAccount.mSyncKey : "0";
final Serializer s = new Serializer();
s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY).text(syncKey)
.end().end().done();
return makeEntity(s);
}
@Override
protected int handleResponse(final EasResponse response, final SyncResult syncResult)
throws IOException {
if (!response.isEmpty()) {
try {
new FolderSyncParser(mContext, mContext.getContentResolver(),
response.getInputStream(), mAccount, mStatusOnly).parse();
} catch (final CommandStatusException e) {
final int status = e.mStatus;
if (CommandStatusException.CommandStatus.isNeedsProvisioning(status)) {
return RESULT_PROVISIONING_ERROR;
}
if (CommandStatusException.CommandStatus.isDeniedAccess(status)) {
return RESULT_FORBIDDEN;
}
return RESULT_OTHER_FAILURE;
}
}
return RESULT_OK;
}
@Override
protected boolean handleForbidden() {
return mStatusOnly;
}
}