X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/11b88e0fccfdc94dd30f44b70361219d759648ac..5dc43aab3cc1243f9989dd6a0c7dd3350c3f709b:/src/com/owncloud/android/operations/RemoteOperation.java diff --git a/src/com/owncloud/android/operations/RemoteOperation.java b/src/com/owncloud/android/operations/RemoteOperation.java index b4f04be2..711a72b0 100644 --- a/src/com/owncloud/android/operations/RemoteOperation.java +++ b/src/com/owncloud/android/operations/RemoteOperation.java @@ -1,10 +1,9 @@ /* ownCloud Android client application - * Copyright (C) 2011 Bartek Przybylski + * Copyright (C) 2012-2013 ownCloud Inc. * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -19,15 +18,20 @@ package com.owncloud.android.operations; import java.io.IOException; +import org.apache.commons.httpclient.Credentials; + +import com.owncloud.android.Log_OC; +import com.owncloud.android.authentication.AccountAuthenticator; +import com.owncloud.android.network.BearerCredentials; import com.owncloud.android.network.OwnCloudClientUtils; +import com.owncloud.android.operations.RemoteOperationResult.ResultCode; import android.accounts.Account; +import android.accounts.AccountManager; import android.accounts.AccountsException; -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; +import android.app.Activity; import android.content.Context; import android.os.Handler; -import android.util.Log; import eu.alefzero.webdav.WebdavClient; @@ -57,6 +61,9 @@ public abstract class RemoteOperation implements Runnable { /** Handler to the thread where mListener methods will be called */ private Handler mListenerHandler = null; + /** Activity */ + private Activity mCallerActivity; + /** * Abstract method to implement the operation in derived classes. @@ -85,7 +92,7 @@ public abstract class RemoteOperation implements Runnable { try { mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext); } catch (Exception e) { - Log.e(TAG, "Error while trying to access to " + mAccount.name, e); + Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e); return new RemoteOperationResult(e); } return run(mClient); @@ -119,13 +126,14 @@ public abstract class RemoteOperation implements Runnable { * @param listenerHandler Handler associated to the thread where the methods of the listener objects must be called. * @return Thread were the remote operation is executed. */ - public final Thread execute(Account account, Context context, OnRemoteOperationListener listener, Handler listenerHandler) { + public final Thread execute(Account account, Context context, OnRemoteOperationListener listener, Handler listenerHandler, Activity callerActivity) { if (account == null) throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Account"); if (context == null) throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Context"); mAccount = account; mContext = context.getApplicationContext(); + mCallerActivity = callerActivity; mClient = null; // the client instance will be created from mAccount and mContext in the runnerThread to create below if (listener == null) { @@ -200,29 +208,55 @@ public abstract class RemoteOperation implements Runnable { * Asynchronous execution of the operation * started by {@link RemoteOperation#execute(WebdavClient, OnRemoteOperationListener, Handler)}, * and result posting. + * + * TODO refactor && clean the code; now it's a mess */ @Override public final void run() { RemoteOperationResult result = null; - try{ - if (mClient == null) { - if (mAccount != null && mContext != null) { - mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext); - } else { - throw new IllegalStateException("Trying to run a remote operation asynchronously with no client instance or account"); + boolean repeat = false; + do { + try{ + if (mClient == null) { + if (mAccount != null && mContext != null) { + if (mCallerActivity != null) { + mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext, mCallerActivity); + } else { + mClient = OwnCloudClientUtils.createOwnCloudClient(mAccount, mContext); + } + } else { + throw new IllegalStateException("Trying to run a remote operation asynchronously with no client instance or account"); + } } - } - result = run(mClient); - } catch (IOException e) { - Log.e(TAG, "Error while trying to access to " + mAccount.name, e); - result = new RemoteOperationResult(e); + } catch (IOException e) { + Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, new AccountsException("I/O exception while trying to authorize the account", e)); + result = new RemoteOperationResult(e); - } catch (AccountsException e) { - Log.e(TAG, "Error while trying to access to " + mAccount.name, e); - result = new RemoteOperationResult(e); - } + } catch (AccountsException e) { + Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e); + result = new RemoteOperationResult(e); + } + if (result == null) + result = run(mClient); + + repeat = false; + if (mCallerActivity != null && mAccount != null && mContext != null && !result.isSuccess() && result.getCode() == ResultCode.UNAUTHORIZED) { + /// fail due to lack of authorization in an operation performed in foreground + AccountManager am = AccountManager.get(mContext); + Credentials cred = mClient.getCredentials(); + if (cred instanceof BearerCredentials) { + am.invalidateAuthToken(AccountAuthenticator.ACCOUNT_TYPE, ((BearerCredentials)cred).getAccessToken()); + } else { + am.clearPassword(mAccount); + } + mClient = null; + repeat = true; // when repeated, the creation of a new OwnCloudClient after erasing the saved credentials will trigger the login activity + result = null; + } + } while (repeat); + final RemoteOperationResult resultToSend = result; if (mListenerHandler != null && mListener != null) { mListenerHandler.post(new Runnable() { @@ -233,6 +267,15 @@ public abstract class RemoteOperation implements Runnable { }); } } - - + + + /** + * Returns the current client instance to access the remote server. + * + * @return Current client instance to access the remote server. + */ + public final WebdavClient getClient() { + return mClient; + } + }