diff --git a/src/com/owncloud/android/lib/common/OwnCloudClient.java b/src/com/owncloud/android/lib/common/OwnCloudClient.java index fa67fd1f..96bace13 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClient.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClient.java @@ -33,7 +33,6 @@ import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HostConfiguration; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpConnectionManager; -import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpStatus; @@ -41,10 +40,10 @@ import org.apache.commons.httpclient.HttpVersion; import org.apache.commons.httpclient.URI; import org.apache.commons.httpclient.URIException; import org.apache.commons.httpclient.cookie.CookiePolicy; -import org.apache.commons.httpclient.methods.HeadMethod; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.commons.httpclient.params.HttpParams; +import android.content.Context; import android.net.Uri; import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; @@ -52,7 +51,6 @@ import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials; import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.network.RedirectionPath; -import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.status.OwnCloudVersion; @@ -75,6 +73,11 @@ public class OwnCloudClient extends HttpClient { private OwnCloudVersion mVersion = null; + /// next too attributes are a very ugly dependency, added to grant silent retry of OAuth token when needed ; + /// see {} for more details + private Context mContext; + private OwnCloudAccount mAccount; + /** * Constructor */ @@ -448,4 +451,21 @@ public class OwnCloudClient extends HttpClient { public OwnCloudVersion getOwnCloudVersion() { return mVersion; } + + public void setContext(Context context) { + this.mContext = context; + } + + public Context getContext() { + return mContext; + } + + public void setAccount(OwnCloudAccount account) { + this.mAccount = account; + } + + public OwnCloudAccount getAccount() { + return mAccount; + } + } diff --git a/src/com/owncloud/android/lib/common/OwnCloudClientFactory.java b/src/com/owncloud/android/lib/common/OwnCloudClientFactory.java index 8c7a23f8..ff9e32b0 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClientFactory.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClientFactory.java @@ -176,6 +176,7 @@ public class OwnCloudClientFactory { OwnCloudClient client = new OwnCloudClient(uri, NetworkUtils.getMultiThreadedConnManager()); client.setDefaultTimeouts(DEFAULT_DATA_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT); client.setFollowRedirects(followRedirects); + client.setContext(context); return client; } diff --git a/src/com/owncloud/android/lib/common/SimpleFactoryManager.java b/src/com/owncloud/android/lib/common/SimpleFactoryManager.java index 362d2a6e..81abbc78 100644 --- a/src/com/owncloud/android/lib/common/SimpleFactoryManager.java +++ b/src/com/owncloud/android/lib/common/SimpleFactoryManager.java @@ -36,44 +36,45 @@ import com.owncloud.android.lib.common.utils.Log_OC; import java.io.IOException; public class SimpleFactoryManager implements OwnCloudClientManager { - - private static final String TAG = SimpleFactoryManager.class.getSimpleName(); - @Override - public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) - throws AccountNotFoundException, OperationCanceledException, AuthenticatorException, - IOException { + private static final String TAG = SimpleFactoryManager.class.getSimpleName(); - Log_OC.d(TAG, "getClientFor(OwnCloudAccount ... : "); + @Override + public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) + throws AccountNotFoundException, OperationCanceledException, AuthenticatorException, + IOException { - OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient( - account.getBaseUri(), - context.getApplicationContext(), - true); + Log_OC.d(TAG, "getClientFor(OwnCloudAccount ... : "); - Log_OC.v(TAG, " new client {" + - (account.getName() != null ? - account.getName() : - AccountUtils.buildAccountName(account.getBaseUri(), "") + OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient( + account.getBaseUri(), + context.getApplicationContext(), + true); - ) + ", " + client.hashCode() + "}"); + Log_OC.v(TAG, " new client {" + + (account.getName() != null ? + account.getName() : + AccountUtils.buildAccountName(account.getBaseUri(), "") + + ) + ", " + client.hashCode() + "}"); if (account.getCredentials() == null) { account.loadCredentials(context); } client.setCredentials(account.getCredentials()); - return client; - } + client.setAccount(account); + return client; + } - @Override - public OwnCloudClient removeClientFor(OwnCloudAccount account) { - // nothing to do - not taking care of tracking instances! - return null; - } + @Override + public OwnCloudClient removeClientFor(OwnCloudAccount account) { + // nothing to do - not taking care of tracking instances! + return null; + } - @Override - public void saveAllClients(Context context, String accountType) { - // nothing to do - not taking care of tracking instances! - } + @Override + public void saveAllClients(Context context, String accountType) { + // nothing to do - not taking care of tracking instances! + } } diff --git a/src/com/owncloud/android/lib/common/SingleSessionManager.java b/src/com/owncloud/android/lib/common/SingleSessionManager.java index fbc08374..f168837d 100644 --- a/src/com/owncloud/android/lib/common/SingleSessionManager.java +++ b/src/com/owncloud/android/lib/common/SingleSessionManager.java @@ -116,6 +116,7 @@ public class SingleSessionManager implements OwnCloudClientManager { context.getApplicationContext(), true); // TODO remove dependency on OwnCloudClientFactory client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); + client.setAccount(account); // enable cookie tracking AccountUtils.restoreCookies(account.getSavedAccount(), client, context); diff --git a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java index dad8e231..7f91207d 100644 --- a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java +++ b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java @@ -287,7 +287,9 @@ public class AccountUtils { should &= (client.getCredentials() != null && // real credentials !(client.getCredentials() instanceof OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials)); - should &= (account != null && context != null); // have all the needed to effectively invalidate + // test if have all the needed to effectively invalidate ... + should &= ((account != null && context != null) || // ... either directly, or ... + client.getAccount() != null && client.getContext() != null) ; // ... indirectly return should; } @@ -310,16 +312,25 @@ public class AccountUtils { Account account, Context context ) { + Account checkedAccount = (account == null) ? client.getAccount().getSavedAccount() : account; + if (checkedAccount == null) { + throw new IllegalArgumentException("Account cannot be null both in parameter and in client"); + } + Context checkedContext = (context == null) ? client.getContext() : context; + if (checkedContext == null) { + throw new IllegalArgumentException("Context cannot be null both in parameter and in client"); + } + try { - OwnCloudAccount ocAccount = new OwnCloudAccount(account, context); + OwnCloudAccount ocAccount = new OwnCloudAccount(checkedAccount, checkedContext); OwnCloudClientManagerFactory.getDefaultSingleton(). removeClientFor(ocAccount); // to prevent nobody else is provided this client - AccountManager am = AccountManager.get(context); + AccountManager am = AccountManager.get(checkedContext); am.invalidateAuthToken( - account.type, + checkedAccount.type, client.getCredentials().getAuthToken() ); - am.clearPassword(account); // being strict, only needed for Basic Auth credentials + am.clearPassword(checkedAccount); // being strict, only needed for Basic Auth credentials return true; } catch (AccountUtils.AccountNotFoundException e) { diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperation.java b/src/com/owncloud/android/lib/common/operations/RemoteOperation.java index f059bfe5..c2590adb 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperation.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperation.java @@ -90,10 +90,14 @@ public abstract class RemoteOperation implements Runnable { /** * When 'true', the operation tries to silently refresh credentials if fails due to lack of authorization. * - * Valid for 'execute methods' receiving an {@link Account} instance as parameter, but not for those - * receiving an {@link OwnCloudClient}. This is, valid for: + * Valid for 'execute methods' receiving an {@link Account} instance as parameter, out of the box: * -- {@link RemoteOperation#execute(Account, Context)} * -- {@link RemoteOperation#execute(Account, Context, OnRemoteOperationListener, Handler)} + * + * Valid for 'execute methods' receiving an {@link OwnCloudClient}, as long as it returns non null values + * to its methods {@link OwnCloudClient#getContext()} && {@link OwnCloudClient#getAccount()}: + * -- {@link RemoteOperation#execute(OwnCloudClient)} + * -- {@link RemoteOperation#execute(OwnCloudClient, OnRemoteOperationListener, Handler)} */ private boolean mSilentRefreshOfAccountCredentials = false; @@ -160,7 +164,10 @@ public abstract class RemoteOperation implements Runnable { throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + "OwnCloudClient"); mClient = client; - mSilentRefreshOfAccountCredentials = false; + if (client.getAccount() != null) { + mAccount = client.getAccount().getSavedAccount(); + } + mContext = client.getContext(); return runOperation(); } @@ -221,6 +228,10 @@ public abstract class RemoteOperation implements Runnable { ("Trying to execute a remote operation with a NULL OwnCloudClient"); } mClient = client; + if (client.getAccount() != null) { + mAccount = client.getAccount().getSavedAccount(); + } + mContext = client.getContext(); if (listener == null) { throw new IllegalArgumentException @@ -233,8 +244,6 @@ public abstract class RemoteOperation implements Runnable { mListenerHandler = listenerHandler; } - mSilentRefreshOfAccountCredentials = false; - Thread runnerThread = new Thread(this); runnerThread.start(); return runnerThread; @@ -359,7 +368,7 @@ public abstract class RemoteOperation implements Runnable { /** * Enables or disables silent refresh of credentials, if supported by credentials itself. * - * Will have effect if called before: + * Will have effect if called before in all cases: * -- {@link RemoteOperation#execute(Account, Context)} * -- {@link RemoteOperation#execute(Account, Context, OnRemoteOperationListener, Handler)} * @@ -367,7 +376,8 @@ public abstract class RemoteOperation implements Runnable { * -- {@link RemoteOperation#execute(OwnCloudClient)} * -- {@link RemoteOperation#execute(OwnCloudClient, OnRemoteOperationListener, Handler)} * - * @param silentRefreshOfAccountCredentials 'True' enables silent refresh, 'false' disables it. + * ... UNLESS the passed {@link OwnCloudClient} returns non-NULL values for + * {@link OwnCloudClient#getAccount()} && {@link OwnCloudClient#getContext()} */ public void setSilentRefreshOfAccountCredentials(boolean silentRefreshOfAccountCredentials) { mSilentRefreshOfAccountCredentials = silentRefreshOfAccountCredentials;