package pl.charmas.android.reactivelocation.observables.location;
import android.content.Context;
import android.location.Location;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationServices;
import pl.charmas.android.reactivelocation.observables.BaseLocationObservable;
import pl.charmas.android.reactivelocation.observables.StatusException;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.functions.Action0;
import rx.functions.Action1;
public class MockLocationObservable extends BaseLocationObservable<Status> {
private Observable<Location> locationObservable;
private Subscription mockLocationSubscription;
public static Observable<Status> createObservable(Context context, Observable<Location> locationObservable) {
return Observable.create(new MockLocationObservable(context, locationObservable));
}
protected MockLocationObservable(Context ctx, Observable<Location> locationObservable) {
super(ctx);
this.locationObservable = locationObservable;
}
@Override
protected void onGoogleApiClientReady(final GoogleApiClient apiClient, final Observer<? super Status> observer) {
// this throws SecurityException if permissions are bad or mock locations are not enabled,
// which is passed to observer's onError by BaseObservable
LocationServices.FusedLocationApi.setMockMode(apiClient, true)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
if (status.isSuccess()) {
startLocationMocking(apiClient, observer);
} else {
observer.onError(new StatusException(status));
}
}
});
}
private void startLocationMocking(final GoogleApiClient apiClient, final Observer<? super Status> observer) {
mockLocationSubscription = locationObservable.subscribe(new Action1<Location>() {
@Override
public void call(Location location) {
LocationServices.FusedLocationApi.setMockLocation(apiClient, location)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
if (status.isSuccess()) {
observer.onNext(status);
} else {
observer.onError(new StatusException(status));
}
}
});
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
observer.onError(throwable);
}
}, new Action0() {
@Override
public void call() {
observer.onCompleted();
}
});
}
@Override
protected void onUnsubscribed(GoogleApiClient locationClient) {
if (locationClient.isConnected()) {
try {
LocationServices.FusedLocationApi.setMockMode(locationClient, false);
} catch (SecurityException e) {
// if this happens then we couldn't have switched mock mode on in the first place,
// and the observer's onError will already have been called
}
}
if (mockLocationSubscription != null && !mockLocationSubscription.isUnsubscribed()) {
mockLocationSubscription.unsubscribe();
}
}
}