Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a550bdc8 authored by Daisuke Miyakawa's avatar Daisuke Miyakawa
Browse files

Use passive provider for location based country detection

Bug: 4345419
Change-Id: Ia3e071b97c6971538ea994fdee6029db928201d6
parent 9a51519d
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import java.util.TimerTask;
public class ComprehensiveCountryDetector extends CountryDetectorBase {

    private final static String TAG = "ComprehensiveCountryDetector";
    /* package */ static final boolean DEBUG = false;

    /**
     * The refresh interval when the location based country was used
@@ -90,7 +91,9 @@ public class ComprehensiveCountryDetector extends CountryDetectorBase {
     * The listener for receiving the notification from LocationBasedCountryDetector.
     */
    private CountryListener mLocationBasedCountryDetectionListener = new CountryListener() {
        @Override
        public void onCountryDetected(Country country) {
            if (DEBUG) Slog.d(TAG, "Country detected via LocationBasedCountryDetector");
            mCountryFromLocation = country;
            // Don't start the LocationBasedCountryDetector.
            detectCountry(true, false);
@@ -206,6 +209,7 @@ public class ComprehensiveCountryDetector extends CountryDetectorBase {
    protected void runAfterDetectionAsync(final Country country, final Country detectedCountry,
            final boolean notifyChange, final boolean startLocationBasedDetection) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                runAfterDetection(
                        country, detectedCountry, notifyChange, startLocationBasedDetection);
@@ -233,9 +237,20 @@ public class ComprehensiveCountryDetector extends CountryDetectorBase {
        if (notifyChange) {
            notifyIfCountryChanged(country, detectedCountry);
        }
        if (DEBUG) {
            Slog.d(TAG, "startLocationBasedDetection=" + startLocationBasedDetection
                    + " detectCountry=" + (detectedCountry == null ? null :
                        "(source: " + detectedCountry.getSource()
                        + ", countryISO: " + detectedCountry.getCountryIso() + ")")
                    + " isAirplaneModeOff()=" + isAirplaneModeOff()
                    + " mListener=" + mListener
                    + " isGeoCoderImplemnted()=" + isGeoCoderImplemented());
        }

        if (startLocationBasedDetection && (detectedCountry == null
                || detectedCountry.getSource() > Country.COUNTRY_SOURCE_LOCATION)
                && isAirplaneModeOff() && mListener != null && isGeoCoderImplemented()) {
            if (DEBUG) Slog.d(TAG, "run startLocationBasedDetector()");
            // Start finding location when the source is less reliable than the
            // location and the airplane mode is off (as geocoder will not
            // work).
@@ -266,12 +281,20 @@ public class ComprehensiveCountryDetector extends CountryDetectorBase {
        if (mLocationBasedCountryDetector != null) {
            return;
        }
        if (DEBUG) {
            Slog.d(TAG, "starts LocationBasedDetector to detect Country code via Location info "
                    + "(e.g. GPS)");
        }
        mLocationBasedCountryDetector = createLocationBasedCountryDetector();
        mLocationBasedCountryDetector.setCountryListener(listener);
        mLocationBasedCountryDetector.detectCountry();
    }

    private synchronized void stopLocationBasedDetector() {
        if (DEBUG) {
            Slog.d(TAG, "tries to stop LocationBasedDetector "
                    + "(current detector: " + mLocationBasedCountryDetector + ")");
        }
        if (mLocationBasedCountryDetector != null) {
            mLocationBasedCountryDetector.stop();
            mLocationBasedCountryDetector = null;
@@ -305,10 +328,17 @@ public class ComprehensiveCountryDetector extends CountryDetectorBase {
     */
    private synchronized void scheduleLocationRefresh() {
        if (mLocationRefreshTimer != null) return;
        if (DEBUG) {
            Slog.d(TAG, "start periodic location refresh timer. Interval: "
                    + LOCATION_REFRESH_INTERVAL);
        }
        mLocationRefreshTimer = new Timer();
        mLocationRefreshTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (DEBUG) {
                    Slog.d(TAG, "periodic location refresh event. Starts detecting Country code");
                }
                mLocationRefreshTimer = null;
                detectCountry(false, true);
            }
+48 −40
Original line number Diff line number Diff line
@@ -16,12 +16,6 @@

package com.android.server.location;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.location.Address;
import android.location.Country;
@@ -32,6 +26,12 @@ import android.location.LocationManager;
import android.os.Bundle;
import android.util.Slog;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * This class detects which country the user currently is in through the enabled
 * location providers and the GeoCoder
@@ -86,25 +86,24 @@ public class LocationBasedCountryDetector extends CountryDetectorBase {
        return country;
    }

    protected boolean isAcceptableProvider(String provider) {
        // We don't want to actively initiate a location fix here (with gps or network providers).
        return LocationManager.PASSIVE_PROVIDER.equals(provider);
    }

    /**
     * Register the listeners with the location providers
     * Register a listener with a provider name
     */
    protected void registerEnabledProviders(List<LocationListener> listeners) {
        int total = listeners.size();
        for (int i = 0; i< total; i++) {
            mLocationManager.requestLocationUpdates(
                    mEnabledProviders.get(i), 0, 0, listeners.get(i));
        }
    protected void registerListener(String provider, LocationListener listener) {
        mLocationManager.requestLocationUpdates(provider, 0, 0, listener);
    }

    /**
     * Unregister the listeners with the location providers
     * Unregister an already registered listener
     */
    protected void unregisterProviders(List<LocationListener> listeners) {
        for (LocationListener listener : listeners) {
    protected void unregisterListener(LocationListener listener) {
        mLocationManager.removeUpdates(listener);
    }
    }

    /**
     * @return the last known location from all providers
@@ -130,14 +129,11 @@ public class LocationBasedCountryDetector extends CountryDetectorBase {
        return QUERY_LOCATION_TIMEOUT;
    }

    /**
     * @return the total number of enabled location providers
     */
    protected int getTotalEnabledProviders() {
    protected List<String> getEnabledProviders() {
        if (mEnabledProviders == null) {
            mEnabledProviders = mLocationManager.getProviders(true);
        }
        return mEnabledProviders.size();
        return mEnabledProviders;
    }

    /**
@@ -152,27 +148,36 @@ public class LocationBasedCountryDetector extends CountryDetectorBase {
            throw new IllegalStateException();
        }
        // Request the location from all enabled providers.
        int totalProviders = getTotalEnabledProviders();
        List<String> enabledProviders = getEnabledProviders();
        int totalProviders = enabledProviders.size();
        if (totalProviders > 0) {
            mLocationListeners = new ArrayList<LocationListener>(totalProviders);
            for (int i = 0; i < totalProviders; i++) {
                String provider = enabledProviders.get(i);
                if (isAcceptableProvider(provider)) {
                    LocationListener listener = new LocationListener () {
                        @Override
                        public void onLocationChanged(Location location) {
                            if (location != null) {
                                LocationBasedCountryDetector.this.stop();
                                queryCountryCode(location);
                            }
                        }
                        @Override
                        public void onProviderDisabled(String provider) {
                        }
                        @Override
                        public void onProviderEnabled(String provider) {
                        }
                        @Override
                        public void onStatusChanged(String provider, int status, Bundle extras) {
                        }
                    };
                    mLocationListeners.add(listener);
                    registerListener(provider, listener);
                }
            }
            registerEnabledProviders(mLocationListeners);

            mTimer = new Timer();
            mTimer.schedule(new TimerTask() {
                @Override
@@ -197,7 +202,9 @@ public class LocationBasedCountryDetector extends CountryDetectorBase {
    @Override
    public synchronized void stop() {
        if (mLocationListeners != null) {
            unregisterProviders(mLocationListeners);
            for (LocationListener listener : mLocationListeners) {
                unregisterListener(listener);
            }
            mLocationListeners = null;
        }
        if (mTimer != null) {
@@ -216,6 +223,7 @@ public class LocationBasedCountryDetector extends CountryDetectorBase {
        }
        if (mQueryThread != null) return;
        mQueryThread = new Thread(new Runnable() {
            @Override
            public void run() {
                String countryIso = null;
                if (location != null) {
+80 −25
Original line number Diff line number Diff line
@@ -15,17 +15,25 @@
 */
package com.android.server.location;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;

import android.location.Country;
import android.location.CountryListener;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.test.AndroidTestCase;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Timer;

public class LocationBasedCountryDetectorTest extends AndroidTestCase {
    private static final List<String> sEnabledProviders = Arrays.asList(
            LocationManager.GPS_PROVIDER, LocationManager.PASSIVE_PROVIDER);
    private class TestCountryDetector extends LocationBasedCountryDetector {
        public static final int TOTAL_PROVIDERS = 2;
        protected Object countryFoundLocker = new Object();
@@ -33,7 +41,7 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
        private final Location mLocation;
        private final String mCountry;
        private final long mQueryLocationTimeout;
        private List<LocationListener> mListeners;
        private Map<String, LocationListener> mListeners;

        public TestCountryDetector(String country, String provider) {
            this(country, provider, 1000 * 60 * 5);
@@ -44,7 +52,7 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
            mCountry = country;
            mLocation = new Location(provider);
            mQueryLocationTimeout = queryLocationTimeout;
            mListeners = new ArrayList<LocationListener>();
            mListeners = new HashMap<String, LocationListener>();
        }

        @Override
@@ -69,16 +77,40 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
            return mLocation;
        }

        private Set<String> mAcceptableProviders;

        public void setAcceptableProvider(Set<String> acceptableProviders) {
            mAcceptableProviders = acceptableProviders;
        }

        @Override
        protected void registerEnabledProviders(List<LocationListener> listeners) {
            mListeners.addAll(listeners);
        protected boolean isAcceptableProvider(String provider) {
            if (mAcceptableProviders != null) {
                return mAcceptableProviders.contains(provider);
            } else {
                return true;
            }
        }

        @Override
        protected void unregisterProviders(List<LocationListener> listeners) {
            for (LocationListener listener : mLocationListeners) {
                assertTrue(mListeners.remove(listener));
        protected void registerListener(String provider, LocationListener listener) {
            assertNotNull(provider);
            mListeners.put(provider, listener);
        }

        @Override
        protected void unregisterListener(LocationListener listener) {
            for (Entry<String, LocationListener> entry : mListeners.entrySet()) {
                if (entry.getValue().equals(listener)) {
                    mListeners.remove(entry.getKey());
                    return;
                }
            }
            fail("Not registered");
        }

        public Map<String, LocationListener> getListeners() {
            return mListeners;
        }

        @Override
@@ -87,8 +119,8 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
        }

        @Override
        protected int getTotalEnabledProviders() {
            return TOTAL_PROVIDERS;
        protected List<String> getEnabledProviders() {
            return sEnabledProviders;
        }

        public void notifyLocationFound() {
@@ -140,16 +172,39 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
    }

    public void testFindingCountry() {
        testFindingCountryCommon(null);
    }

    public void testFindingCountryWithAcceptableProvider() {
        testFindingCountryCommon(new HashSet<String>(Arrays.asList("passive")));
    }

    private void testFindingCountryCommon(Set<String> acceptableProviders) {
        final String country = "us";
        final String provider = "Good";
        CountryListenerImpl countryListener = new CountryListenerImpl();
        TestCountryDetector detector = new TestCountryDetector(country, provider);

        if (acceptableProviders != null) {
            detector.setAcceptableProvider(acceptableProviders);
        }

        detector.setCountryListener(countryListener);
        detector.detectCountry();
        assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS);

        if (acceptableProviders != null) {
            assertEquals(acceptableProviders.size(), detector.getListenersCount());
            Map<String, LocationListener> listeners = detector.getListeners();
            for (String acceptableProvider : acceptableProviders) {
                assertTrue(listeners.containsKey(acceptableProvider));
            }
        } else {
            assertEquals(TestCountryDetector.TOTAL_PROVIDERS, detector.getListenersCount());
        }

        detector.notifyLocationFound();
        // All listeners should be unregistered
        assertEquals(detector.getListenersCount(), 0);
        assertEquals(0, detector.getListenersCount());
        assertNull(detector.getTimer());
        Thread queryThread = waitForQueryThreadLaunched(detector);
        detector.notifyCountryFound();
@@ -168,10 +223,10 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
        TestCountryDetector detector = new TestCountryDetector(country, provider);
        detector.setCountryListener(countryListener);
        detector.detectCountry();
        assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS);
        assertEquals(TestCountryDetector.TOTAL_PROVIDERS, detector.getListenersCount());
        detector.notifyLocationFound();
        // All listeners should be unregistered
        assertEquals(detector.getListenersCount(), 0);
        assertEquals(0, detector.getListenersCount());
        // The time should be stopped
        assertNull(detector.getTimer());
        Thread queryThread = waitForQueryThreadLaunched(detector);
@@ -193,10 +248,10 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
        TestCountryDetector detector = new TestCountryDetector(country, provider);
        detector.setCountryListener(countryListener);
        detector.detectCountry();
        assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS);
        assertEquals(TestCountryDetector.TOTAL_PROVIDERS, detector.getListenersCount());
        detector.stop();
        // All listeners should be unregistered
        assertEquals(detector.getListenersCount(), 0);
        assertEquals(0, detector.getListenersCount());
        // The time should be stopped
        assertNull(detector.getTimer());
        // QueryThread should still be NULL
@@ -217,10 +272,10 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
        CountryListenerImpl countryListener = new CountryListenerImpl();
        detector.setCountryListener(countryListener);
        detector.detectCountry();
        assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS);
        assertEquals(TestCountryDetector.TOTAL_PROVIDERS, detector.getListenersCount());
        waitForTimerReset(detector);
        // All listeners should be unregistered
        assertEquals(detector.getListenersCount(), 0);
        assertEquals(0, detector.getListenersCount());
        // QueryThread should still be NULL
        assertNull(detector.getQueryThread());
        assertTrue(countryListener.notified());
@@ -248,10 +303,10 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
        CountryListenerImpl countryListener = new CountryListenerImpl();
        detector.setCountryListener(countryListener);
        detector.detectCountry();
        assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS);
        assertEquals(TestCountryDetector.TOTAL_PROVIDERS, detector.getListenersCount());
        detector.notifyLocationFound();
        // All listeners should be unregistered
        assertEquals(detector.getListenersCount(), 0);
        assertEquals(0, detector.getListenersCount());
        assertNull(detector.getTimer());
        Thread queryThread = waitForQueryThreadLaunched(detector);
        detector.notifyCountryFound();
@@ -272,10 +327,10 @@ public class LocationBasedCountryDetectorTest extends AndroidTestCase {
        CountryListenerImpl countryListener = new CountryListenerImpl();
        detector.setCountryListener(countryListener);
        detector.detectCountry();
        assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS);
        assertEquals(TestCountryDetector.TOTAL_PROVIDERS, detector.getListenersCount());
        waitForTimerReset(detector);
        // All listeners should be unregistered
        assertEquals(detector.getListenersCount(), 0);
        assertEquals(0, detector.getListenersCount());
        Thread queryThread = waitForQueryThreadLaunched(detector);
        detector.notifyCountryFound();
        // Wait for query thread ending
+3 −3

File changed.

Contains only whitespace changes.