| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package org.chromium.device.geolocation; |
| |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.mockito.Mockito.doAnswer; |
| |
| import android.content.Context; |
| import android.location.LocationManager; |
| |
| import com.google.android.gms.common.api.GoogleApiClient; |
| import com.google.android.gms.location.FusedLocationProviderApi; |
| |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.Mock; |
| import org.mockito.Mockito; |
| import org.mockito.MockitoAnnotations; |
| import org.mockito.invocation.InvocationOnMock; |
| import org.mockito.stubbing.Answer; |
| import org.robolectric.ParameterizedRobolectricTestRunner; |
| import org.robolectric.ParameterizedRobolectricTestRunner.Parameters; |
| import org.robolectric.Shadows; |
| import org.robolectric.annotation.Config; |
| import org.robolectric.internal.Shadow; |
| import org.robolectric.shadows.ShadowLocationManager; |
| import org.robolectric.shadows.ShadowLog; // remove me ? |
| |
| import org.chromium.base.ThreadUtils; |
| import org.chromium.base.test.util.Feature; |
| |
| import java.util.Arrays; |
| import java.util.Collection; |
| |
| /** |
| * Test suite for Java Geolocation. |
| */ |
| @RunWith(ParameterizedRobolectricTestRunner.class) |
| @Config(sdk = 21, manifest = Config.NONE) |
| public class LocationProviderTest { |
| public static enum LocationProviderType { MOCK, ANDROID, GMS_CORE } |
| |
| @Parameters |
| public static Collection<Object[]> data() { |
| return Arrays.asList(new Object[][] {{LocationProviderType.MOCK}, |
| {LocationProviderType.ANDROID}, {LocationProviderType.GMS_CORE}}); |
| } |
| |
| @Mock |
| private Context mContext; |
| |
| // Member variables for LocationProviderType.GMS_CORE case. |
| @Mock |
| private GoogleApiClient mGoogleApiClient; |
| private boolean mGoogleApiClientIsConnected; |
| |
| // Member variables for LocationProviderType.ANDROID case. |
| private LocationManager mLocationManager; |
| private ShadowLocationManager mShadowLocationManager; |
| |
| private LocationProviderAdapter mLocationProviderAdapter; |
| |
| private final LocationProviderType mApi; |
| |
| public LocationProviderTest(LocationProviderType api) { |
| mApi = api; |
| } |
| |
| @Before |
| public void setUp() { |
| ShadowLog.stream = System.out; |
| MockitoAnnotations.initMocks(this); |
| |
| mContext = Mockito.mock(Context.class); |
| } |
| |
| /** |
| * Verify a normal start/stop call pair with the given LocationProvider. |
| */ |
| @Test |
| @Feature({"Location"}) |
| public void testStartStop() { |
| assertTrue("Should be on UI thread", ThreadUtils.runningOnUiThread()); |
| |
| setLocationProvider(); |
| |
| createLocationProviderAdapter(); |
| startLocationProviderAdapter(false); |
| stopLocationProviderAdapter(); |
| } |
| |
| /** |
| * Verify a start/upgrade/stop call sequencewith the given LocationProvider. |
| */ |
| @Test |
| @Feature({"Location"}) |
| public void testStartUpgradeStop() { |
| assertTrue("Should be on UI thread", ThreadUtils.runningOnUiThread()); |
| |
| setLocationProvider(); |
| |
| createLocationProviderAdapter(); |
| startLocationProviderAdapter(false); |
| startLocationProviderAdapter(true); |
| stopLocationProviderAdapter(); |
| } |
| |
| private void createLocationProviderAdapter() { |
| mLocationProviderAdapter = LocationProviderAdapter.create(mContext); |
| assertNotNull("LocationProvider", mLocationProviderAdapter); |
| } |
| |
| private void setLocationProvider() { |
| if (mApi == LocationProviderType.MOCK) { |
| setLocationProviderMock(); |
| } else if (mApi == LocationProviderType.ANDROID) { |
| setLocationProviderAndroid(); |
| } else if (mApi == LocationProviderType.GMS_CORE) { |
| setLocationProviderGmsCore(); |
| } else { |
| assert false; |
| } |
| } |
| |
| private void setLocationProviderMock() { |
| LocationProviderFactory.setLocationProviderImpl(new MockLocationProvider()); |
| } |
| |
| private void setLocationProviderAndroid() { |
| LocationProviderAndroid locationProviderAndroid = new LocationProviderAndroid(mContext); |
| |
| // Robolectric has a ShadowLocationManager class that mocks the behaviour of the real |
| // class very closely. Use it here. |
| mLocationManager = Shadow.newInstanceOf(LocationManager.class); |
| mShadowLocationManager = Shadows.shadowOf(mLocationManager); |
| locationProviderAndroid.setLocationManagerForTesting(mLocationManager); |
| LocationProviderFactory.setLocationProviderImpl(locationProviderAndroid); |
| } |
| |
| private void setLocationProviderGmsCore() { |
| // Robolectric has a ShadowGoogleApiClientBuilder class that mocks the behaviour of the real |
| // class very closely, but it's not available in our build |
| mGoogleApiClient = Mockito.mock(GoogleApiClient.class); |
| mGoogleApiClientIsConnected = false; |
| doAnswer(new Answer<Boolean>() { |
| public Boolean answer(InvocationOnMock invocation) { |
| return mGoogleApiClientIsConnected; |
| } |
| }) |
| .when(mGoogleApiClient) |
| .isConnected(); |
| |
| doAnswer(new Answer<Void>() { |
| public Void answer(InvocationOnMock invocation) { |
| mGoogleApiClientIsConnected = true; |
| return null; |
| } |
| }) |
| .when(mGoogleApiClient) |
| .connect(); |
| |
| doAnswer(new Answer<Void>() { |
| public Void answer(InvocationOnMock invocation) { |
| mGoogleApiClientIsConnected = false; |
| return null; |
| } |
| }) |
| .when(mGoogleApiClient) |
| .disconnect(); |
| |
| FusedLocationProviderApi fusedLocationProviderApi = |
| Mockito.mock(FusedLocationProviderApi.class); |
| |
| LocationProviderGmsCore locationProviderGmsCore = |
| new LocationProviderGmsCore(mGoogleApiClient, fusedLocationProviderApi); |
| |
| LocationProviderFactory.setLocationProviderImpl(locationProviderGmsCore); |
| } |
| |
| private void startLocationProviderAdapter(boolean highResolution) { |
| mLocationProviderAdapter.start(highResolution); |
| assertTrue("Should be running", mLocationProviderAdapter.isRunning()); |
| } |
| |
| private void stopLocationProviderAdapter() { |
| mLocationProviderAdapter.stop(); |
| assertFalse("Should have stopped", mLocationProviderAdapter.isRunning()); |
| } |
| } |