/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.mozstumbler.client.mapview;
import android.location.Location;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.mozstumbler.service.Prefs;
import org.mozilla.mozstumbler.service.core.http.ILocationService;
import org.mozilla.mozstumbler.service.core.http.IResponse;
import org.mozilla.mozstumbler.service.core.offline.IOfflineLocationService;
import org.mozilla.mozstumbler.service.utils.LocationAdapter;
import org.mozilla.mozstumbler.svclocator.ServiceLocator;
import org.mozilla.mozstumbler.svclocator.services.log.LoggerUtil;
import java.util.concurrent.atomic.AtomicInteger;
/*
An asynchronous task to fetch MLS locations.
*/
public class AsyncGeolocate extends AsyncTask<String, Void, Location> {
private static final String LOG_TAG = LoggerUtil.makeLogTag(AsyncGeolocate.class);
private static AtomicInteger sRequestCounter = new AtomicInteger(0);
private final int MAX_REQUESTS = 10;
private MLSLocationGetterCallback mCallback;
JSONObject mlsGeolocateObj;
private boolean mIsBadRequest;
public AsyncGeolocate(MLSLocationGetterCallback callback, JSONObject mlsQueryObj) {
mCallback = callback;
mlsGeolocateObj = mlsQueryObj;
}
@Override
public Location doInBackground(String... params) {
JSONObject response = null;
ILocationService mls = null;
int requests = sRequestCounter.incrementAndGet();
if (requests > MAX_REQUESTS) {
return null;
}
if (Prefs.getInstanceWithoutContext().useOfflineGeo()) {
Log.i(LOG_TAG, "Using offline location fixing!");
mls = (ILocationService)
ServiceLocator.getInstance()
.getService(IOfflineLocationService.class);
} else {
Log.i(LOG_TAG, "Using MLS online location fixing!");
mls = (ILocationService)
ServiceLocator.getInstance()
.getService(ILocationService.class);
}
// TODO: the ILocationService shouldn't be returning raw HTTP responses.
// We should either get a Location or a null.
IResponse resp = mls.search(mlsGeolocateObj, null, false);
if (resp == null) {
Log.i(LOG_TAG, "Error processing search request");
return null;
}
if (resp.isErrorCode4xx()) {
mIsBadRequest = true;
return null;
}
try {
response = new JSONObject(resp.body());
} catch (JSONException e) {
Log.e(LOG_TAG, "Error deserializing JSON. " + e.toString(), e);
return null;
}
return LocationAdapter.fromJSON(response);
}
@Override
protected void onPostExecute(Location location) {
sRequestCounter.decrementAndGet();
if (location == null) {
mCallback.errorMLSResponse(mIsBadRequest);
} else {
mCallback.setMLSResponseLocation(location);
}
}
public interface MLSLocationGetterCallback {
void setMLSResponseLocation(Location loc);
void errorMLSResponse(boolean stopRequesting);
}
}