From 2a3cdfed4f51031d6260f4c707c88ef53dc03177 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Fri, 6 Feb 2015 13:00:31 +0100 Subject: [PATCH] Synchronize connections --- .../android/gms/location/LocationClient.java | 8 ++++ src/org/microg/gms/common/GmsClient.java | 40 ++++++++++++------- src/org/microg/gms/common/GmsConnector.java | 2 +- .../api/AbstractPlayServicesClient.java | 4 ++ .../gms/common/api/GoogleApiClientImpl.java | 14 ++++--- 5 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/com/google/android/gms/location/LocationClient.java b/src/com/google/android/gms/location/LocationClient.java index 06b766d1..04190cef 100644 --- a/src/com/google/android/gms/location/LocationClient.java +++ b/src/com/google/android/gms/location/LocationClient.java @@ -31,41 +31,49 @@ public class LocationClient extends AbstractPlayServicesClient { } public Location getLastLocation() { + assertConnected(); return LocationServices.FusedLocationApi.getLastLocation(googleApiClient); } public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener) { + assertConnected(); return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener); } public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener, Looper looper) { + assertConnected(); return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener, looper); } public PendingResult requestLocationUpdates(LocationRequest request, PendingIntent callbackIntent) { + assertConnected(); return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, callbackIntent); } public PendingResult removeLocationUpdates(LocationListener listener) { + assertConnected(); return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, listener); } public PendingResult removeLocationUpdates(PendingIntent callbackIntent) { + assertConnected(); return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, callbackIntent); } public PendingResult setMockMode(boolean isMockMode) { + assertConnected(); return LocationServices.FusedLocationApi.setMockMode(googleApiClient, isMockMode); } public PendingResult setMockLocation(Location mockLocation) { + assertConnected(); return LocationServices.FusedLocationApi.setMockLocation(googleApiClient, mockLocation); } } diff --git a/src/org/microg/gms/common/GmsClient.java b/src/org/microg/gms/common/GmsClient.java index 800b8df8..80bf78cf 100644 --- a/src/org/microg/gms/common/GmsClient.java +++ b/src/org/microg/gms/common/GmsClient.java @@ -43,7 +43,7 @@ public abstract class GmsClient implements ApiConnection { private I serviceInterface; public GmsClient(Context context, GoogleApiClient.ConnectionCallbacks callbacks, - GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { + GoogleApiClient.OnConnectionFailedListener connectionFailedListener) { this.context = context; this.callbacks = callbacks; this.connectionFailedListener = connectionFailedListener; @@ -57,9 +57,11 @@ public abstract class GmsClient implements ApiConnection { protected abstract I interfaceFromBinder(IBinder binder); @Override - public void connect() { + public synchronized void connect() { Log.d(TAG, "connect()"); - if (state == ConnectionState.CONNECTED || state == ConnectionState.CONNECTING) return; + if (state == ConnectionState.CONNECTED || state == ConnectionState.CONNECTING) { + Log.d(TAG, "Already connected/connecting - nothing to do"); + } state = ConnectionState.CONNECTING; if (serviceConnection != null) { MultiConnectionKeeper.getInstance(context) @@ -79,7 +81,7 @@ public abstract class GmsClient implements ApiConnection { } @Override - public void disconnect() { + public synchronized void disconnect() { Log.d(TAG, "disconnect()"); if (state == ConnectionState.DISCONNECTING) return; if (state == ConnectionState.CONNECTING) { @@ -95,16 +97,16 @@ public abstract class GmsClient implements ApiConnection { } @Override - public boolean isConnected() { + public synchronized boolean isConnected() { return state == ConnectionState.CONNECTED || state == ConnectionState.PSEUDO_CONNECTED; } @Override - public boolean isConnecting() { + public synchronized boolean isConnecting() { return state == ConnectionState.CONNECTING; } - public boolean hasError() { + public synchronized boolean hasError() { return state == ConnectionState.ERROR; } @@ -112,7 +114,13 @@ public abstract class GmsClient implements ApiConnection { return context; } - public I getServiceInterface() { + public synchronized I getServiceInterface() { + if (isConnecting()) { + // TODO: wait for connection to be established and return afterwards. + throw new IllegalStateException("Waiting for connection"); + } else if (!isConnected()) { + throw new IllegalStateException("interface only available once connected!"); + } return serviceInterface; } @@ -135,7 +143,9 @@ public abstract class GmsClient implements ApiConnection { @Override public void onServiceDisconnected(ComponentName componentName) { - state = ConnectionState.NOT_CONNECTED; + synchronized (GmsClient.this) { + state = ConnectionState.NOT_CONNECTED; + } } } @@ -144,13 +154,15 @@ public abstract class GmsClient implements ApiConnection { @Override public void onPostInitComplete(int statusCode, IBinder binder, Bundle params) throws RemoteException { - if (state == ConnectionState.DISCONNECTING) { + synchronized (GmsClient.this) { + if (state == ConnectionState.DISCONNECTING) { + state = ConnectionState.CONNECTED; + disconnect(); + return; + } state = ConnectionState.CONNECTED; - disconnect(); - return; + serviceInterface = interfaceFromBinder(binder); } - state = ConnectionState.CONNECTED; - serviceInterface = interfaceFromBinder(binder); Log.d(TAG, "GmsCallbacks : onPostInitComplete(" + serviceInterface + ")"); callbacks.onConnected(params); } diff --git a/src/org/microg/gms/common/GmsConnector.java b/src/org/microg/gms/common/GmsConnector.java index cd23afc7..90712d9a 100644 --- a/src/org/microg/gms/common/GmsConnector.java +++ b/src/org/microg/gms/common/GmsConnector.java @@ -64,7 +64,7 @@ public class GmsConnector result = (AbstractPendingResult) msg.obj; try { result.deliverResult(callback.onClientAvailable((C) apiClient.getApiConnection diff --git a/src/org/microg/gms/common/api/AbstractPlayServicesClient.java b/src/org/microg/gms/common/api/AbstractPlayServicesClient.java index 6ff1be44..0bd98141 100644 --- a/src/org/microg/gms/common/api/AbstractPlayServicesClient.java +++ b/src/org/microg/gms/common/api/AbstractPlayServicesClient.java @@ -30,6 +30,10 @@ public class AbstractPlayServicesClient implements GooglePlayServicesClient { this.googleApiClient = googleApiClient; } + public void assertConnected() { + if (!isConnected()) throw new IllegalStateException("Not connected!"); + } + @Override public void connect() { googleApiClient.connect(); diff --git a/src/org/microg/gms/common/api/GoogleApiClientImpl.java b/src/org/microg/gms/common/api/GoogleApiClientImpl.java index ff2fa9ce..10878613 100644 --- a/src/org/microg/gms/common/api/GoogleApiClientImpl.java +++ b/src/org/microg/gms/common/api/GoogleApiClientImpl.java @@ -120,8 +120,12 @@ public class GoogleApiClientImpl implements GoogleApiClient { } @Override - public void connect() { + public synchronized void connect() { Log.d(TAG, "connect()"); + if (isConnected() || isConnecting()) { + Log.d(TAG, "Already connected/connecting, noting to do"); + return; + } for (ApiConnection connection : apiConnections.values()) { if (!connection.isConnected()) { connection.connect(); @@ -130,7 +134,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { } @Override - public void disconnect() { + public synchronized void disconnect() { Log.d(TAG, "disconnect()"); for (ApiConnection connection : apiConnections.values()) { if (connection.isConnected()) { @@ -140,7 +144,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { } @Override - public boolean isConnected() { + public synchronized boolean isConnected() { for (ApiConnection connection : apiConnections.values()) { if (!connection.isConnected()) return false; } @@ -148,7 +152,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { } @Override - public boolean isConnecting() { + public synchronized boolean isConnecting() { for (ApiConnection connection : apiConnections.values()) { if (connection.isConnecting()) return true; } @@ -167,7 +171,7 @@ public class GoogleApiClientImpl implements GoogleApiClient { } @Override - public void reconnect() { + public synchronized void reconnect() { Log.d(TAG, "reconnect()"); disconnect(); connect();