package org.fitchfamily.android.gsmlocation;

import java.util.List;

import android.content.Context;
import android.location.Location;
import android.os.Looper;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.Log;

import org.microg.nlp.api.LocationBackendService;

public class GSMService extends LocationBackendService {

    private TelephonyManager tm;
    private telephonyHelper th;

    protected String TAG = appConstants.TAG_PREFIX+"service";
    private static boolean DEBUG = appConstants.DEBUG;

    protected Thread worker = null;

    private Location lastLocation = null;

    public synchronized void start() {

        if (worker != null && worker.isAlive())
            return;

        if (DEBUG)
            Log.d(TAG, "Starting location backend");

        final Context ctx = getApplicationContext();
        tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
        th = new telephonyHelper(tm);

        try {
            if (worker != null && worker.isAlive()) worker.interrupt();

            worker = new Thread() {

                public void run() {
                    if (DEBUG) Log.d(TAG, "Starting reporter thread");
                    Looper.prepare();

                    final PhoneStateListener listener = new PhoneStateListener() {

                        private boolean sameLoc(Location l1, Location l2) {

                            if ((l1 == null) && (l2 == null))
                                return true;

                            if ((l1 == null) && (l2 != null))
                                return false;

                            return (l1.getLatitude() == l2.getLatitude()) &&
                                   (l1.getLongitude() == l2.getLongitude()) &&
                                   (l1.getAccuracy() == l2.getAccuracy());
                        }

                        private synchronized void doIt(String from) {
                            if (isConnected()) {
                                Location rslt = th.getLocationEstimate();
                                String logString;

                                if (rslt != null)
                                    logString = from + rslt.toString();
                                else
                                    logString = from + " null position";

                                if (DEBUG)
                                    Log.d(TAG, logString);

                                if (!sameLoc(lastLocation, rslt)) {
                                    if (DEBUG)
                                        Log.d(TAG, "Location Changed.");

                                    report(rslt);
                                }
                                lastLocation = rslt;
                            }
                        }

                        public void onServiceStateChanged(ServiceState serviceState) {
                            doIt("onServiceStateChanged: ");
                        }

                        public void onCellLocationChanged(CellLocation location) {
                            doIt("onCellLocationChanged: ");
                        }

                        public void onCellInfoChanged(List<android.telephony.CellInfo> cellInfo) {
                            doIt("onCellInfoChanged: ");
                        }
                    };
                    tm.listen(
                        listener,
                        PhoneStateListener.LISTEN_CELL_INFO |
                        PhoneStateListener.LISTEN_CELL_LOCATION |
                        PhoneStateListener.LISTEN_SERVICE_STATE
                    );
                    Looper.loop();
                }
            };
            worker.start();
        } catch (Exception e) {
            Log.e(TAG, "Start failed: " + e.getMessage());
            e.printStackTrace();
            worker = null;
        }
    }

     @Override
     protected synchronized Location update() {
         return lastLocation;
     }

    @Override
    protected synchronized void onOpen() {
        super.onOpen();

        start();

        if (DEBUG)
            Log.d(TAG, "Binder OPEN called");
    }

    protected synchronized void onClose() {
        if (DEBUG) Log.d(TAG, "Binder CLOSE called");
        super.onClose();

        try {
            if (worker != null && worker.isAlive())
                worker.interrupt();

            if (worker != null)
                worker = null;

        } finally {
            worker = null;
        }
    }

}

@@ -1529,33 +1529,32 @@
              if 
-(
 (l1 == null) && 
@@ -1548,22 +1548,20 @@
  == null
-)
  && 
-(
 l2 == nu
@@ -1559,25 +1559,24 @@
  l2 == null)
-)
 %0A           
@@ -1641,17 +1641,16 @@
      if 
-(
 (l1 == n
@@ -1656,14 +1656,12 @@
 null
-)
  && 
-(
 l2 !
@@ -1667,16 +1667,119 @@
 != null)
+%0A                                return false;%0A%0A                            if(l1 != null && l2 == null
 )%0A      

fix (potential) NPE