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

Commit efe2a0e6 authored by Daisuke Miyakawa's avatar Daisuke Miyakawa Committed by Android (Google) Code Review
Browse files

Merge "Use passive provider for location based country detection"

parents 988ec4bd a550bdc8
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.