diff --git a/src/com/google/android/gms/location/FusedLocationProviderApi.java b/src/com/google/android/gms/location/FusedLocationProviderApi.java index 5d5ba084..c736e6ce 100644 --- a/src/com/google/android/gms/location/FusedLocationProviderApi.java +++ b/src/com/google/android/gms/location/FusedLocationProviderApi.java @@ -8,8 +8,8 @@ import com.google.android.gms.common.api.PendingResult; import org.microg.gms.Constants; public interface FusedLocationProviderApi { - String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION"; - String KEY_MOCK_LOCATION = Constants.KEY_MOCK_LOCATION; + public static final String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION"; + public static final String KEY_MOCK_LOCATION = Constants.KEY_MOCK_LOCATION; public Location getLastLocation(GoogleApiClient client); diff --git a/src/com/google/android/gms/location/LocationClient.java b/src/com/google/android/gms/location/LocationClient.java index b3072880..a8b79b0b 100644 --- a/src/com/google/android/gms/location/LocationClient.java +++ b/src/com/google/android/gms/location/LocationClient.java @@ -1,78 +1,63 @@ package com.google.android.gms.location; +import android.app.PendingIntent; import android.content.Context; +import android.location.Location; +import android.os.Looper; +import android.os.RemoteException; + import com.google.android.gms.common.GooglePlayServicesClient; import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.PendingResult; + import org.microg.gms.common.ForwardConnectionCallbacks; import org.microg.gms.common.ForwardConnectionFailedListener; +import org.microg.gms.common.api.AbstractPlayServicesClient; +import org.microg.gms.common.api.GoogleApiClientImpl; +import org.microg.gms.location.LocationClientImpl; @Deprecated -public class LocationClient implements GooglePlayServicesClient { - private GoogleApiClient googleApiClient; - - public LocationClient(Context context, ConnectionCallbacks callbacks) { - googleApiClient = new GoogleApiClient.Builder(context) +public class LocationClient extends AbstractPlayServicesClient { + public static final String KEY_LOCATION_CHANGED = "com.google.android.location.LOCATION"; + + public LocationClient(Context context, ConnectionCallbacks callbacks, + OnConnectionFailedListener connectionFailedListener) { + super(new GoogleApiClient.Builder(context) .addApi(LocationServices.API) .addConnectionCallbacks(new ForwardConnectionCallbacks(callbacks)) - .build(); + .addOnConnectionFailedListener(new ForwardConnectionFailedListener(connectionFailedListener)) + .build()); } - @Override - public void connect() { - googleApiClient.connect(); + public Location getLastLocation() { + return LocationServices.FusedLocationApi.getLastLocation(googleApiClient); } - @Override - public void disconnect() { - googleApiClient.disconnect(); + public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener) { + return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener); } - @Override - public boolean isConnected() { - return googleApiClient.isConnected(); + public PendingResult requestLocationUpdates(LocationRequest request, LocationListener listener, Looper looper) { + return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, listener, looper); } - @Override - public boolean isConnecting() { - return googleApiClient.isConnecting(); + public PendingResult requestLocationUpdates(LocationRequest request, PendingIntent callbackIntent) { + return LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, callbackIntent); } - @Override - public void registerConnectionCallbacks(final ConnectionCallbacks listener) { - googleApiClient.registerConnectionCallbacks(new ForwardConnectionCallbacks(listener)); + public PendingResult removeLocationUpdates(LocationListener listener) { + return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, listener); } - @Override - public boolean isConnectionCallbacksRegistered(ConnectionCallbacks listener) { - return googleApiClient - .isConnectionCallbacksRegistered(new ForwardConnectionCallbacks(listener)); + public PendingResult removeLocationUpdates(PendingIntent callbackIntent) { + return LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, callbackIntent); } - @Override - public void unregisterConnectionCallbacks( - ConnectionCallbacks listener) { - googleApiClient.unregisterConnectionCallbacks(new ForwardConnectionCallbacks(listener)); + public PendingResult setMockMode(boolean isMockMode) { + return LocationServices.FusedLocationApi.setMockMode(googleApiClient, isMockMode); } - @Override - public void registerConnectionFailedListener( - OnConnectionFailedListener listener) { - googleApiClient.registerConnectionFailedListener( - new ForwardConnectionFailedListener(listener)); + public PendingResult setMockLocation(Location mockLocation) { + return LocationServices.FusedLocationApi.setMockLocation(googleApiClient, mockLocation); } - - @Override - public boolean isConnectionFailedListenerRegistered( - OnConnectionFailedListener listener) { - return googleApiClient.isConnectionFailedListenerRegistered( - new ForwardConnectionFailedListener(listener)); - } - - @Override - public void unregisterConnectionFailedListener( - OnConnectionFailedListener listener) { - googleApiClient.unregisterConnectionFailedListener( - new ForwardConnectionFailedListener(listener)); - } - } diff --git a/src/com/google/android/gms/location/LocationListener.java b/src/com/google/android/gms/location/LocationListener.java index 63603d67..86fedc42 100644 --- a/src/com/google/android/gms/location/LocationListener.java +++ b/src/com/google/android/gms/location/LocationListener.java @@ -1,4 +1,18 @@ package com.google.android.gms.location; +import android.location.Location; + +/** + * Used for receiving notifications from the {@link FusedLocationProviderApi} when the location has + * changed. The methods are called if the LocationListener has been registered with the location + * client. + */ public interface LocationListener { + + /** + * Called when the location has changed. + * + * @param location The updated location. + */ + public void onLocationChanged(Location location); } diff --git a/src/main/res/values/version.xml b/src/main/res/values/version.xml new file mode 100644 index 00000000..096db2c0 --- /dev/null +++ b/src/main/res/values/version.xml @@ -0,0 +1,20 @@ + + + + + 6599436 + diff --git a/src/org/microg/gms/common/GmsConnector.java b/src/org/microg/gms/common/GmsConnector.java index af3c8699..c222aad2 100644 --- a/src/org/microg/gms/common/GmsConnector.java +++ b/src/org/microg/gms/common/GmsConnector.java @@ -30,14 +30,24 @@ import com.google.android.gms.common.api.Result; import org.microg.gms.common.api.GoogleApiClientImpl; -public class GmsConnector { - public static - AbstractPendingResult connect(GoogleApiClient apiClient, Api api, Callback callback) { +public class GmsConnector { + private final GoogleApiClientImpl apiClient; + private final Api api; + private final Callback callback; + + public GmsConnector(GoogleApiClient apiClient, Api api, Callback callback) { + this.apiClient = (GoogleApiClientImpl) apiClient; + this.api = api; + this.callback = callback; + } + + + public AbstractPendingResult connect() { Looper looper = ((GoogleApiClientImpl) apiClient).getLooper(); final AbstractPendingResult result = new AbstractPendingResult<>(looper); Message msg = new Message(); - msg.obj = new ConnectRequest((GoogleApiClientImpl) apiClient, api, result, callback); - new Handler(looper).sendMessage(msg); + msg.obj = result; + new Handler(looper).sendMessage(msg); return result; } @@ -45,35 +55,21 @@ public class GmsConnector { public R onClientAvailable(C client) throws RemoteException; } - private static class Handler extends android.os.Handler { + private class Handler extends android.os.Handler { private Handler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { - ConnectRequest request = (ConnectRequest) msg.obj; - ApiConnection apiConnection = request.apiClient.getApiConnection(request.api); + AbstractPendingResult result = (AbstractPendingResult) msg.obj; + ApiConnection apiConnection = apiClient.getApiConnection(api); apiConnection.connect(); try { - request.result.setResult(request.callback.onClientAvailable((C) apiConnection)); + result.setResult(callback.onClientAvailable((C) apiConnection)); } catch (RemoteException ignored) { } } } - - private static class ConnectRequest { - GoogleApiClientImpl apiClient; - Api api; - AbstractPendingResult result; - Callback callback; - - private ConnectRequest(GoogleApiClientImpl apiClient, Api api, AbstractPendingResult result, Callback callback) { - this.apiClient = apiClient; - this.api = api; - this.result = result; - this.callback = callback; - } - } } diff --git a/src/org/microg/gms/common/api/AbstractPlayServicesClient.java b/src/org/microg/gms/common/api/AbstractPlayServicesClient.java new file mode 100644 index 00000000..6ff1be44 --- /dev/null +++ b/src/org/microg/gms/common/api/AbstractPlayServicesClient.java @@ -0,0 +1,90 @@ +/* + * Copyright 2014-2015 µg Project Team + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.microg.gms.common.api; + +import com.google.android.gms.common.GooglePlayServicesClient; +import com.google.android.gms.common.api.GoogleApiClient; + +import org.microg.gms.common.ForwardConnectionCallbacks; +import org.microg.gms.common.ForwardConnectionFailedListener; + +public class AbstractPlayServicesClient implements GooglePlayServicesClient { + + protected final GoogleApiClient googleApiClient; + + public AbstractPlayServicesClient(GoogleApiClient googleApiClient) { + this.googleApiClient = googleApiClient; + } + + @Override + public void connect() { + googleApiClient.connect(); + } + + @Override + public void disconnect() { + googleApiClient.disconnect(); + } + + @Override + public boolean isConnected() { + return googleApiClient.isConnected(); + } + + @Override + public boolean isConnecting() { + return googleApiClient.isConnecting(); + } + + @Override + public void registerConnectionCallbacks(final ConnectionCallbacks listener) { + googleApiClient.registerConnectionCallbacks(new ForwardConnectionCallbacks(listener)); + } + + @Override + public boolean isConnectionCallbacksRegistered(ConnectionCallbacks listener) { + return googleApiClient + .isConnectionCallbacksRegistered(new ForwardConnectionCallbacks(listener)); + } + + @Override + public void unregisterConnectionCallbacks( + ConnectionCallbacks listener) { + googleApiClient.unregisterConnectionCallbacks(new ForwardConnectionCallbacks(listener)); + } + + @Override + public void registerConnectionFailedListener( + OnConnectionFailedListener listener) { + googleApiClient.registerConnectionFailedListener( + new ForwardConnectionFailedListener(listener)); + } + + @Override + public boolean isConnectionFailedListenerRegistered( + OnConnectionFailedListener listener) { + return googleApiClient.isConnectionFailedListenerRegistered( + new ForwardConnectionFailedListener(listener)); + } + + @Override + public void unregisterConnectionFailedListener( + OnConnectionFailedListener listener) { + googleApiClient.unregisterConnectionFailedListener( + new ForwardConnectionFailedListener(listener)); + } +} diff --git a/src/org/microg/gms/location/FusedLocationProviderApiImpl.java b/src/org/microg/gms/location/FusedLocationProviderApiImpl.java index 169b9788..c3f5f36f 100644 --- a/src/org/microg/gms/location/FusedLocationProviderApiImpl.java +++ b/src/org/microg/gms/location/FusedLocationProviderApiImpl.java @@ -5,17 +5,22 @@ import android.location.Location; import android.os.Looper; import android.os.RemoteException; import android.util.Log; + import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; +import com.google.android.gms.common.api.Result; +import com.google.android.gms.common.api.Status; import com.google.android.gms.location.FusedLocationProviderApi; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; +import com.google.android.gms.location.LocationServices; import org.microg.gms.common.GmsConnector; +import org.microg.gms.common.api.ApiConnection; public class FusedLocationProviderApiImpl implements FusedLocationProviderApi { private static final String TAG = "GmsFusedApiImpl"; - + @Override public Location getLastLocation(GoogleApiClient client) { try { @@ -27,49 +32,98 @@ public class FusedLocationProviderApiImpl implements FusedLocationProviderApi { } @Override - public PendingResult requestLocationUpdates(GoogleApiClient client, LocationRequest request, - LocationListener listener) { - - //LocationClientImpl.get(client).requestLocationUpdates(request, listener); - return null; + public PendingResult requestLocationUpdates(GoogleApiClient client, + final LocationRequest request, + final LocationListener listener) { + return callVoid(client, new Runnable() { + @Override + public void run(LocationClientImpl client) throws RemoteException { + client.requestLocationUpdates(request, listener); + } + }); } @Override - public PendingResult requestLocationUpdates(GoogleApiClient client, LocationRequest request, - LocationListener listener, Looper looper) { - //LocationClientImpl.get(client).requestLocationUpdates(request, listener, looper); - return null; + public PendingResult requestLocationUpdates(GoogleApiClient client, + final LocationRequest request, + final LocationListener listener, + final Looper looper) { + return callVoid(client, new Runnable() { + @Override + public void run(LocationClientImpl client) throws RemoteException { + client.requestLocationUpdates(request, listener, looper); + } + }); } @Override - public PendingResult requestLocationUpdates(GoogleApiClient client, LocationRequest request, - PendingIntent callbackIntent) { - //LocationClientImpl.get(client).requestLocationUpdates(request, callbackIntent); - return null; - } - - @Override - public PendingResult removeLocationUpdates(GoogleApiClient client, LocationListener listener) { - //LocationClientImpl.get(client).removeLocationUpdates(listener); - return null; + public PendingResult requestLocationUpdates(GoogleApiClient client, + final LocationRequest request, + final PendingIntent callbackIntent) { + return callVoid(client, new Runnable() { + @Override + public void run(LocationClientImpl client) throws RemoteException { + client.requestLocationUpdates(request, callbackIntent); + } + }); } @Override public PendingResult removeLocationUpdates(GoogleApiClient client, - PendingIntent callbackIntent) { - //LocationClientImpl.get(client).removeLocationUpdates(callbackIntent); - return null; + final LocationListener listener) { + return callVoid(client, new Runnable() { + @Override + public void run(LocationClientImpl client) throws RemoteException { + client.removeLocationUpdates(listener); + } + }); } @Override - public PendingResult setMockMode(GoogleApiClient client, boolean isMockMode) { - //LocationClientImpl.get(client).setMockMode(isMockMode); - return null; + public PendingResult removeLocationUpdates(GoogleApiClient client, + final PendingIntent callbackIntent) { + return callVoid(client, new Runnable() { + @Override + public void run(LocationClientImpl client) throws RemoteException { + client.removeLocationUpdates(callbackIntent); + } + }); } @Override - public PendingResult setMockLocation(GoogleApiClient client, Location mockLocation) { - //LocationClientImpl.get(client).setMockLocation(mockLocation); - return null; + public PendingResult setMockMode(GoogleApiClient client, final boolean isMockMode) { + return callVoid(client, new Runnable() { + @Override + public void run(LocationClientImpl client) throws RemoteException { + client.setMockMode(isMockMode); + } + }); } + + @Override + public PendingResult setMockLocation(GoogleApiClient client, final Location mockLocation) { + return callVoid(client, new Runnable() { + @Override + public void run(LocationClientImpl client) throws RemoteException { + client.setMockLocation(mockLocation); + } + }); + } + + private PendingResult callVoid(GoogleApiClient client, final Runnable runnable) { + return new GmsConnector<>(client, LocationServices.API, + new GmsConnector.Callback() { + @Override + public Result onClientAvailable(LocationClientImpl client) throws + RemoteException { + runnable.run(client); + return Status.SUCCESS; + } + }).connect(); + } + + private interface Runnable { + public void run(LocationClientImpl client) throws RemoteException; + } + } diff --git a/src/org/microg/gms/location/LocationClientImpl.java b/src/org/microg/gms/location/LocationClientImpl.java index e523c14c..1bb56a9a 100644 --- a/src/org/microg/gms/location/LocationClientImpl.java +++ b/src/org/microg/gms/location/LocationClientImpl.java @@ -5,12 +5,18 @@ import android.content.Context; import android.location.Location; import android.os.Looper; import android.os.RemoteException; + import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.location.ILocationListener; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; + import org.microg.gms.common.api.GoogleApiClientImpl; +import java.util.HashMap; +import java.util.Map; + public class LocationClientImpl extends GoogleLocationManagerClient { public LocationClientImpl(Context context) { super(context); @@ -24,38 +30,49 @@ public class LocationClientImpl extends GoogleLocationManagerClient { return null; } + private Map listenerMap = new HashMap<>(); + public Location getLastLocation() throws RemoteException { return getServiceInterface().getLastLocation(); } - public void requestLocationUpdates(LocationRequest request, LocationListener listener) + public void requestLocationUpdates(LocationRequest request, final LocationListener listener) throws RemoteException { - + ILocationListener iLocationListener = new ILocationListener.Stub() { + @Override + public void onLocationChanged(Location location) throws RemoteException { + listener.onLocationChanged(location); + } + }; + listenerMap.put(listener, iLocationListener); + getServiceInterface().requestLocationUpdatesWithPackage(request, + iLocationListener, getContext().getPackageName()); } public void requestLocationUpdates(LocationRequest request, PendingIntent pendingIntent) throws RemoteException { - + getServiceInterface().requestLocationUpdatesWithIntent(request, pendingIntent); } public void requestLocationUpdates(LocationRequest request, LocationListener listener, - Looper looper) throws RemoteException { - + Looper looper) throws RemoteException { + requestLocationUpdates(request, listener); // TODO } public void removeLocationUpdates(LocationListener listener) throws RemoteException { - + getServiceInterface().removeLocationUpdatesWithListener(listenerMap.get(listener)); + listenerMap.remove(listener); } public void removeLocationUpdates(PendingIntent pendingIntent) throws RemoteException { - + getServiceInterface().removeLocationUpdatesWithIntent(pendingIntent); } public void setMockMode(boolean isMockMode) throws RemoteException { - + getServiceInterface().setMockMode(isMockMode); } public void setMockLocation(Location mockLocation) throws RemoteException { - + getServiceInterface().setMockLocation(mockLocation); } }