diff --git a/src/com/owncloud/android/lib/common/OwnCloudAccount.java b/src/com/owncloud/android/lib/common/OwnCloudAccount.java new file mode 100644 index 00000000..ff0cf3dd --- /dev/null +++ b/src/com/owncloud/android/lib/common/OwnCloudAccount.java @@ -0,0 +1,95 @@ +/* ownCloud Android client application + * Copyright (C) 2014 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.owncloud.android.lib.common; + + +import java.io.IOException; + +import com.owncloud.android.lib.common.accounts.AccountUtils; +import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; + +import android.accounts.Account; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; +import android.content.Context; +import android.net.Uri; + +/** + * OwnCloud Account + * + * @author David A. Velasco + */ +public class OwnCloudAccount { + + private Uri mBaseUri; + + private OwnCloudCredentials mCredentials; + + private String mSavedAccountName; + + + public OwnCloudAccount(Account savedAccount, Context context) + throws AccountNotFoundException, AuthenticatorException, + IOException, OperationCanceledException { + + if (savedAccount == null) { + throw new IllegalArgumentException("Parameter 'savedAccount' cannot be null"); + } + if (context == null) { + throw new IllegalArgumentException("Parameter 'context' cannot be null"); + } + + mSavedAccountName = savedAccount.name; + mBaseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, savedAccount)); + mCredentials = AccountUtils.getCredentialsForAccount(context, savedAccount); + } + + + public OwnCloudAccount(Uri baseUri, OwnCloudCredentials credentials) { + if (baseUri == null) { + throw new IllegalArgumentException("Parameter 'baseUri' cannot be null"); + } + mSavedAccountName = null; + mBaseUri = baseUri; + mCredentials = credentials != null ? + credentials : OwnCloudCredentialsFactory.getAnonymousCredentials(); + String username = credentials.getUsername(); + if (username != null) { + mSavedAccountName = AccountUtils.buildAccountName(mBaseUri, username); + } + } + + + public boolean isAnonymous() { + return (mCredentials == null); + } + + public Uri getBaseUri() { + return mBaseUri; + } + + public OwnCloudCredentials getCredentials() { + return mCredentials; + } + + public String getName() { + return mSavedAccountName; + } + + +} \ No newline at end of file diff --git a/src/com/owncloud/android/lib/common/OwnCloudBasicCredentials.java b/src/com/owncloud/android/lib/common/OwnCloudBasicCredentials.java index cb30f093..6855cfc4 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudBasicCredentials.java +++ b/src/com/owncloud/android/lib/common/OwnCloudBasicCredentials.java @@ -30,6 +30,11 @@ public class OwnCloudBasicCredentials implements OwnCloudCredentials { ); } + @Override + public String getUsername() { + return mUsername; + } + @Override public String getAuthToken() { return mPassword; diff --git a/src/com/owncloud/android/lib/common/OwnCloudBearerCredentials.java b/src/com/owncloud/android/lib/common/OwnCloudBearerCredentials.java index 2a9f4515..fb6f2018 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudBearerCredentials.java +++ b/src/com/owncloud/android/lib/common/OwnCloudBearerCredentials.java @@ -32,6 +32,12 @@ public class OwnCloudBearerCredentials implements OwnCloudCredentials { ); } + @Override + public String getUsername() { + // its unknown + return null; + } + @Override public String getAuthToken() { return mAccessToken; @@ -41,5 +47,5 @@ public class OwnCloudBearerCredentials implements OwnCloudCredentials { public boolean authTokenExpires() { return true; } - + } diff --git a/src/com/owncloud/android/lib/common/OwnCloudClientManager.java b/src/com/owncloud/android/lib/common/OwnCloudClientManager.java index c2bd0bf5..b0b26c96 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClientManager.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClientManager.java @@ -58,5 +58,7 @@ public interface OwnCloudClientManager { public OwnCloudClient removeClientFor(Account account, Context context) throws AccountNotFoundException, AuthenticatorException, IOException, OperationCanceledException; + + public OwnCloudClient getClientFor(OwnCloudAccount account, Context context); } diff --git a/src/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java b/src/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java index 78b6858e..f8a9a2f3 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClientManagerFactory.java @@ -8,6 +8,8 @@ public class OwnCloudClientManagerFactory { } public final static Policy DEFAULT_POLICY = Policy.ALWAYS_NEW_CLIENT; + + private static OwnCloudClientManager mDefaultSingleton; public static OwnCloudClientManager newDefaultOwnCloudClientManager() { return newOwnCloudClientManager(DEFAULT_POLICY); @@ -16,15 +18,21 @@ public class OwnCloudClientManagerFactory { public static OwnCloudClientManager newOwnCloudClientManager(Policy policy) { switch (policy) { case ALWAYS_NEW_CLIENT: - return new SingleSessionManager(); + return new SimpleFactoryManager(); case SINGLE_SESSION_PER_ACCOUNT: - return new SimpleFactoryManager(); + return new SingleSessionManager(); default: throw new IllegalArgumentException("Unknown policy"); } } - + public static OwnCloudClientManager getDefaultSingleton() { + if (mDefaultSingleton == null) { + mDefaultSingleton = newDefaultOwnCloudClientManager(); + } + return mDefaultSingleton; + } + } diff --git a/src/com/owncloud/android/lib/common/OwnCloudCredentials.java b/src/com/owncloud/android/lib/common/OwnCloudCredentials.java index deba8177..a3fff2eb 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudCredentials.java +++ b/src/com/owncloud/android/lib/common/OwnCloudCredentials.java @@ -21,6 +21,8 @@ public interface OwnCloudCredentials { public void applyTo(OwnCloudClient ownCloudClient); + public String getUsername(); + public String getAuthToken(); public boolean authTokenExpires(); diff --git a/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java b/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java index 45ee53de..951b4ae3 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java +++ b/src/com/owncloud/android/lib/common/OwnCloudCredentialsFactory.java @@ -42,6 +42,12 @@ public class OwnCloudCredentialsFactory { public boolean authTokenExpires() { return false; } + + @Override + public String getUsername() { + // no user name + return null; + } } } diff --git a/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java b/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java index a50d3177..78c96bfa 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java +++ b/src/com/owncloud/android/lib/common/OwnCloudSamlSsoCredentials.java @@ -39,6 +39,12 @@ public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials { } } + @Override + public String getUsername() { + // its unknown + return null; + } + @Override public String getAuthToken() { return mSessionCookie; diff --git a/src/com/owncloud/android/lib/common/SimpleFactoryManager.java b/src/com/owncloud/android/lib/common/SimpleFactoryManager.java index e37ff4c8..012b9303 100644 --- a/src/com/owncloud/android/lib/common/SimpleFactoryManager.java +++ b/src/com/owncloud/android/lib/common/SimpleFactoryManager.java @@ -7,25 +7,46 @@ import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.content.Context; import android.net.Uri; +import android.util.Log; import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; public class SimpleFactoryManager implements OwnCloudClientManager { - + private static final String TAG = OwnCloudClientManager.class.getSimpleName(); + + @Override + public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) { + Log.d(TAG, "getClientFor(OwnCloudAccount ... : "); + OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient( + account.getBaseUri(), + context.getApplicationContext(), + true); + + Log.d(TAG, " new client " + client.hashCode()); + client.setCredentials(account.getCredentials()); + return client; + } + + @Override public OwnCloudClient getClientFor(Account savedAccount, Context context) throws OperationCanceledException, AuthenticatorException, AccountNotFoundException, IOException { - - return OwnCloudClientFactory.createOwnCloudClient( + Log.d(TAG, "getClientFor(Account ... : "); + + OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient( savedAccount, context.getApplicationContext()); + + Log.d(TAG, " new client " + client.hashCode()); + return client; } @Override public OwnCloudClient getClientFor(Uri serverBaseUri, OwnCloudCredentials credentials, Context context) { + Log.d(TAG, "getClientFor(Uri ... : "); OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient( serverBaseUri, @@ -33,6 +54,7 @@ public class SimpleFactoryManager implements OwnCloudClientManager { true); client.setCredentials(credentials); + Log.d(TAG, " new client " + client.hashCode()); return client; } diff --git a/src/com/owncloud/android/lib/common/SingleSessionManager.java b/src/com/owncloud/android/lib/common/SingleSessionManager.java index f8fe97cd..e7ba5e57 100644 --- a/src/com/owncloud/android/lib/common/SingleSessionManager.java +++ b/src/com/owncloud/android/lib/common/SingleSessionManager.java @@ -34,6 +34,7 @@ import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.content.Context; import android.net.Uri; +import android.util.Log; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.OwnCloudClientFactory; @@ -55,19 +56,73 @@ public class SingleSessionManager implements OwnCloudClientManager { //private static final String TAG = SingleSessionManager.class.getSimpleName(); + private static final String TAG = SingleSessionManager.class.getSimpleName(); + private static OwnCloudClientManager mInstance = null; private Map> mClientsPerServer = new HashMap>(); + private Map mClientsWithKnownUsername = + new HashMap(); - public static OwnCloudClientManager getInstance() { - if (mInstance == null) { - mInstance = new SingleSessionManager(); + private Map mClientsWithUnknownUsername = + new HashMap(); + + + @Override + public synchronized OwnCloudClient getClientFor(OwnCloudAccount account, Context context) { + Log.d(TAG, "getClientFor(OwnCloudAccount ... : "); + if (account == null) { + throw new IllegalArgumentException("Cannot get an OwnCloudClient for a null account"); } - return mInstance ; - } + OwnCloudClient client = null; + String accountName = account.getName(); + String sessionName = AccountUtils.buildAccountName( + account.getBaseUri(), + account.getCredentials().getAuthToken()); + + if (accountName != null) { + client = mClientsWithKnownUsername.get(accountName); + } + if (client == null) { + if (accountName != null) { + client = mClientsWithUnknownUsername.remove(sessionName); + if (client != null) { + Log.d(TAG, " reusing client {" + sessionName + ", " + client.hashCode() + "}"); + mClientsWithKnownUsername.put(accountName, client); + Log.d(TAG, " moved client to {" + accountName + ", " + client.hashCode() + "}"); + } + } else { + client = mClientsWithUnknownUsername.get(sessionName); + } + } else { + Log.d(TAG, " reusing client {" + accountName + ", " + client.hashCode() + "}"); + } + + if (client == null) { + // no client to reuse - create a new one + client = OwnCloudClientFactory.createOwnCloudClient( + account.getBaseUri(), + context.getApplicationContext(), + true); + client.setCredentials(account.getCredentials()); + if (accountName != null) { + mClientsWithKnownUsername.put(accountName, client); + Log.d(TAG, " new client {" + accountName + ", " + client.hashCode() + "}"); + + } else { + mClientsWithUnknownUsername.put(sessionName, client); + Log.d(TAG, " new client {" + sessionName + ", " + client.hashCode() + "}"); + } + } else { + Log.d(TAG, " reusing client {" + sessionName + ", " + client.hashCode() + "}"); + } + + return client; + } + @Override public synchronized OwnCloudClient getClientFor(Account savedAccount, Context context) diff --git a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java index 58f422cd..376ec611 100644 --- a/src/com/owncloud/android/lib/common/accounts/AccountUtils.java +++ b/src/com/owncloud/android/lib/common/accounts/AccountUtils.java @@ -37,7 +37,9 @@ import android.accounts.AccountsException; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.content.Context; + import android.util.Log; +import android.net.Uri; public class AccountUtils { public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php"; @@ -186,6 +188,15 @@ public class AccountUtils { return credentials; } + + + public static String buildAccountName(Uri serverBaseUrl, String username) { + String accountName = username + "@" + serverBaseUrl.getHost(); + if (serverBaseUrl.getPort() >= 0) { + accountName += ":" + serverBaseUrl.getPort(); + } + return accountName; + } public static void saveClient(OwnCloudClient client, Account savedAccount, Context context) { diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperation.java b/src/com/owncloud/android/lib/common/operations/RemoteOperation.java index 16d24585..1045d6fd 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperation.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperation.java @@ -28,6 +28,7 @@ import java.io.IOException; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.OwnCloudClientFactory; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; import com.owncloud.android.lib.common.OwnCloudCredentials; import com.owncloud.android.lib.common.SingleSessionManager; import com.owncloud.android.lib.common.accounts.AccountUtils; @@ -105,7 +106,8 @@ public abstract class RemoteOperation implements Runnable { mAccount = account; mContext = context.getApplicationContext(); try { - mClient = SingleSessionManager.getInstance().getClientFor(mAccount, mContext); + mClient = OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(mAccount, mContext); } catch (Exception e) { Log.e(TAG, "Error while trying to access to " + mAccount.name, e); return new RemoteOperationResult(e); @@ -252,7 +254,7 @@ public abstract class RemoteOperation implements Runnable { mAccount, mContext, mCallerActivity); } else { /** EOF DEPRECATED */ - mClient = SingleSessionManager.getInstance(). + mClient = OwnCloudClientManagerFactory.getDefaultSingleton(). getClientFor(mAccount, mContext); } // Save Client Cookies