LocationBasedCountryDetectorTest.java revision a58a8751b4c2ce457f0082a0baaee61312d56195
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16package com.android.server.location; 17 18import java.util.ArrayList; 19import java.util.List; 20import java.util.Timer; 21 22import android.location.Country; 23import android.location.CountryListener; 24import android.location.Location; 25import android.location.LocationListener; 26import android.test.AndroidTestCase; 27 28public class LocationBasedCountryDetectorTest extends AndroidTestCase { 29 private class TestCountryDetector extends LocationBasedCountryDetector { 30 public static final int TOTAL_PROVIDERS = 2; 31 protected Object countryFoundLocker = new Object(); 32 protected boolean notifyCountry = false; 33 private final Location mLocation; 34 private final String mCountry; 35 private final long mQueryLocationTimeout; 36 private List<LocationListener> mListeners; 37 38 public TestCountryDetector(String country, String provider) { 39 this(country, provider, 1000 * 60 * 5); 40 } 41 42 public TestCountryDetector(String country, String provider, long queryLocationTimeout) { 43 super(getContext()); 44 mCountry = country; 45 mLocation = new Location(provider); 46 mQueryLocationTimeout = queryLocationTimeout; 47 mListeners = new ArrayList<LocationListener>(); 48 } 49 50 @Override 51 protected String getCountryFromLocation(Location location) { 52 synchronized (countryFoundLocker) { 53 if (!notifyCountry) { 54 try { 55 countryFoundLocker.wait(); 56 } catch (InterruptedException e) { 57 } 58 } 59 } 60 if (mLocation.getProvider().endsWith(location.getProvider())) { 61 return mCountry; 62 } else { 63 return null; 64 } 65 } 66 67 @Override 68 protected Location getLastKnownLocation() { 69 return mLocation; 70 } 71 72 @Override 73 protected void registerEnabledProviders(List<LocationListener> listeners) { 74 mListeners.addAll(listeners); 75 } 76 77 @Override 78 protected void unregisterProviders(List<LocationListener> listeners) { 79 for (LocationListener listener : mLocationListeners) { 80 assertTrue(mListeners.remove(listener)); 81 } 82 } 83 84 @Override 85 protected long getQueryLocationTimeout() { 86 return mQueryLocationTimeout; 87 } 88 89 @Override 90 protected int getTotalEnabledProviders() { 91 return TOTAL_PROVIDERS; 92 } 93 94 public void notifyLocationFound() { 95 // Listener could be removed in the notification. 96 LocationListener[] listeners = new LocationListener[mListeners.size()]; 97 mLocationListeners.toArray(listeners); 98 for (LocationListener listener :listeners) { 99 listener.onLocationChanged(mLocation); 100 } 101 } 102 103 public int getListenersCount() { 104 return mListeners.size(); 105 } 106 107 public void notifyCountryFound() { 108 synchronized (countryFoundLocker) { 109 notifyCountry = true; 110 countryFoundLocker.notify(); 111 } 112 } 113 114 public Timer getTimer() { 115 return mTimer; 116 } 117 118 public Thread getQueryThread() { 119 return mQueryThread; 120 } 121 } 122 123 private class CountryListenerImpl implements CountryListener { 124 private boolean mNotified; 125 private String mCountryCode; 126 public void onCountryDetected(Country country) { 127 mNotified = true; 128 if (country != null) { 129 mCountryCode = country.getCountryIso(); 130 } 131 } 132 133 public boolean notified() { 134 return mNotified; 135 } 136 137 public String getCountry() { 138 return mCountryCode; 139 } 140 } 141 142 public void testFindingCountry() { 143 final String country = "us"; 144 final String provider = "Good"; 145 CountryListenerImpl countryListener = new CountryListenerImpl(); 146 TestCountryDetector detector = new TestCountryDetector(country, provider); 147 detector.setCountryListener(countryListener); 148 detector.detectCountry(); 149 assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS); 150 detector.notifyLocationFound(); 151 // All listeners should be unregistered 152 assertEquals(detector.getListenersCount(), 0); 153 assertNull(detector.getTimer()); 154 Thread queryThread = waitForQueryThreadLaunched(detector); 155 detector.notifyCountryFound(); 156 // Wait for query thread ending 157 waitForThreadEnding(queryThread); 158 // QueryThread should be set to NULL 159 assertNull(detector.getQueryThread()); 160 assertTrue(countryListener.notified()); 161 assertEquals(countryListener.getCountry(), country); 162 } 163 164 public void testFindingCountryCancelled() { 165 final String country = "us"; 166 final String provider = "Good"; 167 CountryListenerImpl countryListener = new CountryListenerImpl(); 168 TestCountryDetector detector = new TestCountryDetector(country, provider); 169 detector.setCountryListener(countryListener); 170 detector.detectCountry(); 171 assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS); 172 detector.notifyLocationFound(); 173 // All listeners should be unregistered 174 assertEquals(detector.getListenersCount(), 0); 175 // The time should be stopped 176 assertNull(detector.getTimer()); 177 Thread queryThread = waitForQueryThreadLaunched(detector); 178 detector.stop(); 179 // There is no way to stop the thread, let's test it could be stopped, after get country 180 detector.notifyCountryFound(); 181 // Wait for query thread ending 182 waitForThreadEnding(queryThread); 183 // QueryThread should be set to NULL 184 assertNull(detector.getQueryThread()); 185 assertTrue(countryListener.notified()); 186 assertEquals(countryListener.getCountry(), country); 187 } 188 189 public void testFindingLocationCancelled() { 190 final String country = "us"; 191 final String provider = "Good"; 192 CountryListenerImpl countryListener = new CountryListenerImpl(); 193 TestCountryDetector detector = new TestCountryDetector(country, provider); 194 detector.setCountryListener(countryListener); 195 detector.detectCountry(); 196 assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS); 197 detector.stop(); 198 // All listeners should be unregistered 199 assertEquals(detector.getListenersCount(), 0); 200 // The time should be stopped 201 assertNull(detector.getTimer()); 202 // QueryThread should still be NULL 203 assertNull(detector.getQueryThread()); 204 assertFalse(countryListener.notified()); 205 } 206 207 public void testFindingLocationFailed() { 208 final String country = "us"; 209 final String provider = "Good"; 210 long timeout = 1000; 211 TestCountryDetector detector = new TestCountryDetector(country, provider, timeout) { 212 @Override 213 protected Location getLastKnownLocation() { 214 return null; 215 } 216 }; 217 CountryListenerImpl countryListener = new CountryListenerImpl(); 218 detector.setCountryListener(countryListener); 219 detector.detectCountry(); 220 assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS); 221 waitForTimerReset(detector); 222 // All listeners should be unregistered 223 assertEquals(detector.getListenersCount(), 0); 224 // QueryThread should still be NULL 225 assertNull(detector.getQueryThread()); 226 assertTrue(countryListener.notified()); 227 assertNull(countryListener.getCountry()); 228 } 229 230 public void testFindingCountryFailed() { 231 final String country = "us"; 232 final String provider = "Good"; 233 TestCountryDetector detector = new TestCountryDetector(country, provider) { 234 @Override 235 protected String getCountryFromLocation(Location location) { 236 synchronized (countryFoundLocker) { 237 if (! notifyCountry) { 238 try { 239 countryFoundLocker.wait(); 240 } catch (InterruptedException e) { 241 } 242 } 243 } 244 // We didn't find country. 245 return null; 246 } 247 }; 248 CountryListenerImpl countryListener = new CountryListenerImpl(); 249 detector.setCountryListener(countryListener); 250 detector.detectCountry(); 251 assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS); 252 detector.notifyLocationFound(); 253 // All listeners should be unregistered 254 assertEquals(detector.getListenersCount(), 0); 255 assertNull(detector.getTimer()); 256 Thread queryThread = waitForQueryThreadLaunched(detector); 257 detector.notifyCountryFound(); 258 // Wait for query thread ending 259 waitForThreadEnding(queryThread); 260 // QueryThread should be set to NULL 261 assertNull(detector.getQueryThread()); 262 // CountryListener should be notified 263 assertTrue(countryListener.notified()); 264 assertNull(countryListener.getCountry()); 265 } 266 267 public void testFindingCountryWithLastKnownLocation() { 268 final String country = "us"; 269 final String provider = "Good"; 270 long timeout = 1000; 271 TestCountryDetector detector = new TestCountryDetector(country, provider, timeout); 272 CountryListenerImpl countryListener = new CountryListenerImpl(); 273 detector.setCountryListener(countryListener); 274 detector.detectCountry(); 275 assertEquals(detector.getListenersCount(), TestCountryDetector.TOTAL_PROVIDERS); 276 waitForTimerReset(detector); 277 // All listeners should be unregistered 278 assertEquals(detector.getListenersCount(), 0); 279 Thread queryThread = waitForQueryThreadLaunched(detector); 280 detector.notifyCountryFound(); 281 // Wait for query thread ending 282 waitForThreadEnding(queryThread); 283 // QueryThread should be set to NULL 284 assertNull(detector.getQueryThread()); 285 // CountryListener should be notified 286 assertTrue(countryListener.notified()); 287 assertEquals(countryListener.getCountry(), country); 288 } 289 290 private void waitForTimerReset(TestCountryDetector detector) { 291 int count = 5; 292 long interval = 1000; 293 try { 294 while (count-- > 0 && detector.getTimer() != null) { 295 Thread.sleep(interval); 296 } 297 } catch (InterruptedException e) { 298 } 299 Timer timer = detector.getTimer(); 300 assertTrue(timer == null); 301 } 302 303 private void waitForThreadEnding(Thread thread) { 304 try { 305 thread.join(5000); 306 } catch (InterruptedException e) { 307 e.printStackTrace(); 308 } 309 } 310 311 private Thread waitForQueryThreadLaunched(TestCountryDetector detector) { 312 int count = 5; 313 long interval = 1000; 314 try { 315 while (count-- > 0 && detector.getQueryThread() == null) { 316 Thread.sleep(interval); 317 } 318 } catch (InterruptedException e) { 319 } 320 Thread thread = detector.getQueryThread(); 321 assertTrue(thread != null); 322 return thread; 323 } 324} 325