1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-06-07 16:06:08 +00:00

Fixed deadlock in main thread due to SingleSessionManager synchronization

This commit is contained in:
David A. Velasco 2015-03-31 09:26:41 +02:00
parent 925227b41b
commit 2b2fc9171f

View File

@ -28,6 +28,8 @@ import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.cookie.CookiePolicy;
@ -36,6 +38,7 @@ import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException; import android.accounts.OperationCanceledException;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.util.Log;
import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
@ -54,19 +57,21 @@ public class SingleSessionManager implements OwnCloudClientManager {
private static final String TAG = SingleSessionManager.class.getSimpleName(); private static final String TAG = SingleSessionManager.class.getSimpleName();
private Map<String, OwnCloudClient> mClientsWithKnownUsername = private ConcurrentMap<String, OwnCloudClient> mClientsWithKnownUsername =
new HashMap<String, OwnCloudClient>(); new ConcurrentHashMap<String, OwnCloudClient>();
private Map<String, OwnCloudClient> mClientsWithUnknownUsername = private ConcurrentMap<String, OwnCloudClient> mClientsWithUnknownUsername =
new HashMap<String, OwnCloudClient>(); new ConcurrentHashMap<String, OwnCloudClient>();
@Override @Override
public synchronized OwnCloudClient getClientFor(OwnCloudAccount account, Context context) public OwnCloudClient getClientFor(OwnCloudAccount account, Context context)
throws AccountNotFoundException, OperationCanceledException, AuthenticatorException, throws AccountNotFoundException, OperationCanceledException, AuthenticatorException,
IOException { IOException {
Log_OC.d(TAG, "getClientFor(OwnCloudAccount ... : "); if (Log.isLoggable(TAG, Log.DEBUG)) {
Log_OC.d(TAG, "getClientFor starting ");
}
if (account == null) { if (account == null) {
throw new IllegalArgumentException("Cannot get an OwnCloudClient for a null account"); throw new IllegalArgumentException("Cannot get an OwnCloudClient for a null account");
} }
@ -88,18 +93,21 @@ public class SingleSessionManager implements OwnCloudClientManager {
if (accountName != null) { if (accountName != null) {
client = mClientsWithUnknownUsername.remove(sessionName); client = mClientsWithUnknownUsername.remove(sessionName);
if (client != null) { if (client != null) {
// TODO REMOVE THIS LOG if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log_OC.d(TAG, " reusing client {" + sessionName + ", " + Log_OC.v(TAG, "reusing client for session " + sessionName);
client.hashCode() + "}"); }
mClientsWithKnownUsername.put(accountName, client); mClientsWithKnownUsername.put(accountName, client);
Log_OC.d(TAG, " moved client to {" + accountName + ", " + if (Log.isLoggable(TAG, Log.VERBOSE)) {
client.hashCode() + "}"); Log_OC.v(TAG, "moved client to account " + accountName);
}
} }
} else { } else {
client = mClientsWithUnknownUsername.get(sessionName); client = mClientsWithUnknownUsername.get(sessionName);
} }
} else { } else {
Log_OC.d(TAG, " reusing client {" + accountName + ", " + client.hashCode() + "}"); if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log_OC.v(TAG, "reusing client for account " + accountName);
}
reusingKnown = true; reusingKnown = true;
} }
@ -118,29 +126,38 @@ public class SingleSessionManager implements OwnCloudClientManager {
client.setCredentials(account.getCredentials()); client.setCredentials(account.getCredentials());
if (accountName != null) { if (accountName != null) {
mClientsWithKnownUsername.put(accountName, client); mClientsWithKnownUsername.put(accountName, client);
Log_OC.d(TAG, " new client {" + accountName + ", " + client.hashCode() + "}"); if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log_OC.v(TAG, "new client for account " + accountName);
}
} else { } else {
mClientsWithUnknownUsername.put(sessionName, client); mClientsWithUnknownUsername.put(sessionName, client);
// TODO REMOVE THIS LOG if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log_OC.d(TAG, " new client {" + sessionName + ", " + client.hashCode() + "}"); Log_OC.v(TAG, "new client for session " + sessionName);
}
} }
} else { } else {
if (!reusingKnown) { if (!reusingKnown && Log.isLoggable(TAG, Log.VERBOSE)) {
// TODO REMOVE THIS LOG Log_OC.v(TAG, "reusing client for session " + sessionName);
Log_OC.d(TAG, " reusing client {" + sessionName + ", " + client.hashCode() + "}");
} }
keepCredentialsUpdated(account, client); keepCredentialsUpdated(account, client);
keepUriUpdated(account, client); keepUriUpdated(account, client);
} }
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log_OC.d(TAG, "getClientFor finishing ");
}
return client; return client;
} }
@Override @Override
public OwnCloudClient removeClientFor(OwnCloudAccount account) { public OwnCloudClient removeClientFor(OwnCloudAccount account) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log_OC.d(TAG, "removeClientFor starting ");
}
if (account == null) { if (account == null) {
return null; return null;
} }
@ -150,25 +167,36 @@ public class SingleSessionManager implements OwnCloudClientManager {
if (accountName != null) { if (accountName != null) {
client = mClientsWithKnownUsername.remove(accountName); client = mClientsWithKnownUsername.remove(accountName);
if (client != null) { if (client != null) {
Log_OC.d(TAG, "Removed client {" + accountName + ", " + client.hashCode() + "}"); if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log_OC.v(TAG, "Removed client for account " + accountName);
}
return client; return client;
} else { } else {
Log_OC.d(TAG, "No client tracked for {" + accountName + "}"); if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log_OC.v(TAG, "No client tracked for account " + accountName);
}
} }
} }
mClientsWithUnknownUsername.clear(); mClientsWithUnknownUsername.clear();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log_OC.d(TAG, "removeClientFor finishing ");
}
return null; return null;
} }
@Override @Override
public synchronized void saveAllClients(Context context, String accountType) public void saveAllClients(Context context, String accountType)
throws AccountNotFoundException, AuthenticatorException, IOException, throws AccountNotFoundException, AuthenticatorException, IOException,
OperationCanceledException { OperationCanceledException {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log_OC.d(TAG, "Saving sessions... ");
}
Iterator<String> accountNames = mClientsWithKnownUsername.keySet().iterator(); Iterator<String> accountNames = mClientsWithKnownUsername.keySet().iterator();
String accountName = null; String accountName = null;
Account account = null; Account account = null;
@ -180,6 +208,10 @@ public class SingleSessionManager implements OwnCloudClientManager {
account, account,
context); context);
} }
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log_OC.d(TAG, "All sessions saved");
}
} }