package org.microg.networklocation;
import android.location.Location;
import android.location.LocationListener;
import android.os.SystemClock;
import android.util.Log;
import org.microg.networklocation.data.LocationCalculator;
import org.microg.networklocation.provider.NetworkLocationProvider;
public class NetworkLocationThread extends Thread {
private static final String TAG = "nlp.NetworkLocationThread";
private LocationCalculator calculator;
private long autoTime;
private boolean autoUpdate;
private boolean forceUpdate;
private boolean enabled;
private Location lastLocation;
private NetworkLocationProvider locationProvider;
private long lastTime;
public NetworkLocationThread() {
autoUpdate = false;
autoTime = Long.MAX_VALUE;
lastTime = 0;
enabled = true;
forceUpdate = true;
}
public NetworkLocationThread(LocationCalculator calculator) {
this();
this.calculator = calculator;
}
public NetworkLocationThread(NetworkLocationThread oldThread) {
this();
if (oldThread != null) {
lastLocation = oldThread.lastLocation;
lastTime = oldThread.lastTime;
calculator = oldThread.calculator;
}
}
public void disable() {
enabled = false;
synchronized (this) {
notify();
}
}
public long getLastTime() {
return lastTime;
}
public void setLastTime(final long lastTime) {
this.lastTime = lastTime;
}
public boolean isActive() {
return enabled && autoUpdate && (autoTime < 60000);
}
@Override
public void run() {
while (enabled) {
boolean waited = false;
try {
synchronized (this) {
if (!autoUpdate && !forceUpdate && enabled) {
if (MainService.DEBUG)
Log.d(TAG, "We're not active, wait until we are...");
wait();
waited = true;
}
}
} catch (final InterruptedException e) {
}
long wait;
while ((wait = lastTime + autoTime - SystemClock.elapsedRealtime()) > 0 && autoUpdate && !forceUpdate &&
enabled) {
final float w = wait / 1000F;
if (MainService.DEBUG) {
Log.d(TAG, "lastTime: " + lastTime + " autoTime: " + autoTime + " currentTime: " +
SystemClock.elapsedRealtime());
Log.d(TAG, "waiting " + w + "s to update...");
}
try {
synchronized (this) {
wait(wait);
}
waited = true;
} catch (final InterruptedException e) {
break;
}
}
if (!waited && enabled) {
if (MainService.DEBUG) {
Log.d(TAG, "We did not wait, lastTime: " + lastTime + " autoTime: " + autoTime + " currentTime: " +
SystemClock.elapsedRealtime());
Log.w(TAG, "waiting 5s to prevent mass update...");
}
try {
synchronized (this) {
wait(5000);
}
} catch (final InterruptedException e) {
continue;
}
}
if ((autoUpdate || forceUpdate) && calculator != null && enabled) {
if (forceUpdate) {
if (MainService.DEBUG)
Log.d(TAG, "Update forced because of new incoming request");
forceUpdate = false;
}
lastTime = SystemClock.elapsedRealtime();
if (locationProvider != null) {
if (MainService.DEBUG)
Log.d(TAG, "Now requesting \\o/");
locationProvider.onLocationChanged(calculator.getCurrentLocation());
}
} else {
if (MainService.DEBUG)
Log.d(TAG, "we're not active (or not initialized yet) = do not track!");
}
}
}
public void setAuto(final boolean autoUpdate, final long autoTime) {
synchronized (this) {
if (autoTime < this.autoTime) {
forceUpdate = true;
}
this.autoUpdate = autoUpdate;
this.autoTime = autoTime;
notify();
}
}
public void setCalculator(LocationCalculator calculator) {
this.calculator = calculator;
}
public void setLastLocation(final Location location) {
lastLocation = location;
}
public void setLocationProvider(NetworkLocationProvider locationProvider) {
this.locationProvider = locationProvider;
}
}