<commit_before>package com.mapswithme.maps.location;

import android.content.Context;
import android.hardware.GeomagneticField;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.Surface;

import com.mapswithme.maps.MWMApplication;
import com.mapswithme.util.ConnectionState;
import com.mapswithme.util.LocationUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;


public class LocationService implements LocationListener, SensorEventListener, WifiLocation.Listener
{
  private static final String TAG = "LocationService";

  /// These constants should correspond to values defined in platform/location.hpp
  /// Leave 0-value as no any error.
  public static final int ERROR_NOT_SUPPORTED = 1;
  public static final int ERROR_DENIED = 2;
  public static final int ERROR_GPS_OFF = 3;

  public interface Listener
  {
    public void onLocationUpdated(long time, double lat, double lon, float accuracy);
    public void onCompassUpdated(long time, double magneticNorth, double trueNorth, double accuracy);
    public void onLocationError(int errorCode);
  };

  private HashSet<Listener> m_observers = new HashSet<Listener>(10);

  /// Used to filter locations from different providers
  private Location m_lastLocation = null;
  private long m_lastTime = 0;
  private double m_drivingHeading = -1.0;

  private WifiLocation m_wifiScanner = null;

  private LocationManager m_locationManager;

  private SensorManager m_sensorManager;
  private Sensor m_accelerometer = null;
  private Sensor m_magnetometer = null;
  /// To calculate true north for compass
  private GeomagneticField m_magneticField = null;

  /// true when LocationService is on
  private boolean m_isActive = false;

  private MWMApplication m_application = null;

  public LocationService(MWMApplication application)
  {
    m_application = application;

    m_locationManager = (LocationManager) m_application.getSystemService(Context.LOCATION_SERVICE);
    m_sensorManager = (SensorManager) m_application.getSystemService(Context.SENSOR_SERVICE);

    if (m_sensorManager != null)
    {
      m_accelerometer = m_sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
      m_magnetometer = m_sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }
  }

  public Location getLastKnown() { return m_lastLocation; }

  /*
  private void notifyOnError(int errorCode)
  {
    Iterator<Listener> it = m_observers.iterator();
    while (it.hasNext())
      it.next().onLocationError(errorCode);
  }
   */

  private void notifyLocationUpdated(long time, double lat, double lon, float accuracy)
  {
    Iterator<Listener> it = m_observers.iterator();
    while (it.hasNext())
      it.next().onLocationUpdated(time, lat, lon, accuracy);
  }

  private void notifyCompassUpdated(long time, double magneticNorth, double trueNorth, double accuracy)
  {
    Iterator<Listener> it = m_observers.iterator();
    while (it.hasNext())
      it.next().onCompassUpdated(time, magneticNorth, trueNorth, accuracy);
  }

  /*
  private void printLocation(Location l)
  {
    final String p = l.getProvider();
    Log.d(TAG, "Lat = " + l.getLatitude() +
          "; Lon = " + l.getLongitude() +
          "; Time = " + l.getTime() +
          "; Acc = " + l.getAccuracy() +
          "; Provider = " + (p != null ? p : ""));
  }
   */

  public void startUpdate(Listener observer)
  {
    m_observers.add(observer);

    if (!m_isActive)
    {
      m_isGPSOff = false;

      List<String> providers = getFilteredProviders();
      Log.d(TAG, "Enabled providers count = " + providers.size());

      if (providers.size() == 0)
        handleEmptyProvidersList(observer);
      else
      {
        m_isActive = true;

        for (String provider : providers)
        {
          Log.d(TAG, "Connected to provider = " + provider);
          // Half of a second is more than enough, I think ...
          m_locationManager.requestLocationUpdates(provider, 500, 0, this);
        }
        registerSensorListeners();


        List<Location> notExpiredLocations = getAllNotExpiredLocations(providers);
        Location lastKnownLocation = null;
        if (notExpiredLocations.size() > 0)
        {
           final Location newestLocation = LocationUtils.getNewestLocation(notExpiredLocations);
           final Location mostAccurateLocation = LocationUtils.getMostAccurateLocation(notExpiredLocations);

           if (LocationUtils.isFirstOneBetterLocation(newestLocation, mostAccurateLocation))
             lastKnownLocation = newestLocation;
           else
             lastKnownLocation = mostAccurateLocation;

        }

        if (!LocationUtils.isFirstOneBetterLocation(lastKnownLocation, m_lastLocation))
          lastKnownLocation = m_lastLocation;

        // Pass last known location only in the end of all registerListener
        // in case, when we want to disconnect in listener.
        if (lastKnownLocation != null)
          emitLocation(lastKnownLocation, System.currentTimeMillis());
      }

      if (m_isGPSOff)<commit_msg>[android] Nullpointer crash on resume fixed.<commit_after>package com.mapswithme.maps.location;

import android.content.Context;
import android.hardware.GeomagneticField;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.Surface;

import com.mapswithme.maps.MWMApplication;
import com.mapswithme.util.ConnectionState;
import com.mapswithme.util.LocationUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;


public class LocationService implements LocationListener, SensorEventListener, WifiLocation.Listener
{
  private static final String TAG = "LocationService";

  /// These constants should correspond to values defined in platform/location.hpp
  /// Leave 0-value as no any error.
  public static final int ERROR_NOT_SUPPORTED = 1;
  public static final int ERROR_DENIED = 2;
  public static final int ERROR_GPS_OFF = 3;

  public interface Listener
  {
    public void onLocationUpdated(long time, double lat, double lon, float accuracy);
    public void onCompassUpdated(long time, double magneticNorth, double trueNorth, double accuracy);
    public void onLocationError(int errorCode);
  };

  private HashSet<Listener> m_observers = new HashSet<Listener>(10);

  /// Used to filter locations from different providers
  private Location m_lastLocation = null;
  private long m_lastTime = 0;
  private double m_drivingHeading = -1.0;

  private WifiLocation m_wifiScanner = null;

  private LocationManager m_locationManager;

  private SensorManager m_sensorManager;
  private Sensor m_accelerometer = null;
  private Sensor m_magnetometer = null;
  /// To calculate true north for compass
  private GeomagneticField m_magneticField = null;

  /// true when LocationService is on
  private boolean m_isActive = false;

  private MWMApplication m_application = null;

  public LocationService(MWMApplication application)
  {
    m_application = application;

    m_locationManager = (LocationManager) m_application.getSystemService(Context.LOCATION_SERVICE);
    m_sensorManager = (SensorManager) m_application.getSystemService(Context.SENSOR_SERVICE);

    if (m_sensorManager != null)
    {
      m_accelerometer = m_sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
      m_magnetometer = m_sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }
  }

  public Location getLastKnown() { return m_lastLocation; }

  /*
  private void notifyOnError(int errorCode)
  {
    Iterator<Listener> it = m_observers.iterator();
    while (it.hasNext())
      it.next().onLocationError(errorCode);
  }
   */

  private void notifyLocationUpdated(long time, double lat, double lon, float accuracy)
  {
    Iterator<Listener> it = m_observers.iterator();
    while (it.hasNext())
      it.next().onLocationUpdated(time, lat, lon, accuracy);
  }

  private void notifyCompassUpdated(long time, double magneticNorth, double trueNorth, double accuracy)
  {
    Iterator<Listener> it = m_observers.iterator();
    while (it.hasNext())
      it.next().onCompassUpdated(time, magneticNorth, trueNorth, accuracy);
  }

  /*
  private void printLocation(Location l)
  {
    final String p = l.getProvider();
    Log.d(TAG, "Lat = " + l.getLatitude() +
          "; Lon = " + l.getLongitude() +
          "; Time = " + l.getTime() +
          "; Acc = " + l.getAccuracy() +
          "; Provider = " + (p != null ? p : ""));
  }
   */

  public void startUpdate(Listener observer)
  {
    m_observers.add(observer);

    if (!m_isActive)
    {
      m_isGPSOff = false;

      List<String> providers = getFilteredProviders();
      Log.d(TAG, "Enabled providers count = " + providers.size());

      if (providers.size() == 0)
        handleEmptyProvidersList(observer);
      else
      {
        m_isActive = true;

        for (String provider : providers)
        {
          Log.d(TAG, "Connected to provider = " + provider);
          // Half of a second is more than enough, I think ...
          m_locationManager.requestLocationUpdates(provider, 500, 0, this);
        }
        registerSensorListeners();

        // Choose best location from available
        List<Location> notExpiredLocations = getAllNotExpiredLocations(providers);
        Location lastKnownLocation = null;
        
        if (notExpiredLocations.size() > 0)
        {
           final Location newestLocation = LocationUtils.getNewestLocation(notExpiredLocations);
           final Location mostAccurateLocation = LocationUtils.getMostAccurateLocation(notExpiredLocations);

           if (LocationUtils.isFirstOneBetterLocation(newestLocation, mostAccurateLocation))
             lastKnownLocation = newestLocation;
           else
             lastKnownLocation = mostAccurateLocation;
        }

        if (m_lastLocation != null && LocationUtils.isFirstOneBetterLocation(m_lastLocation, lastKnownLocation))
          lastKnownLocation = m_lastLocation;
        // ### location chosen

        // Pass last known location only in the end of all registerListener
        // in case, when we want to disconnect in listener.
        if (lastKnownLocation != null)
          emitLocation(lastKnownLocation, System.currentTimeMillis());
      }

      if (m_isGPSOff)
{'fraction_non_alphanumeric': 0.0901989281496957, 'fraction_numerical': 0.0027250431465164864, 'mean_word_length': 3.5875, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '826761', 'n_tokens_mistral': 3196, 'n_tokens_neox': 3058, 'n_words': 771}