166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangpackage com.android.server.location;
266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport static com.google.common.truth.Truth.assertThat;
466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport static org.mockito.Matchers.any;
666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport static org.mockito.Mockito.never;
766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport static org.mockito.Mockito.verify;
866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport android.content.ContentResolver;
1066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport android.content.Context;
1166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport android.database.ContentObserver;
1266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport android.os.Looper;
1366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport android.platform.test.annotations.Presubmit;
1466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport android.provider.Settings;
1566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
1666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport com.android.server.testing.FrameworkRobolectricTestRunner;
1766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport com.android.server.testing.SystemLoaderPackages;
1866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
1966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport org.junit.Before;
2066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport org.junit.Test;
2166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport org.junit.runner.RunWith;
2266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport org.mockito.ArgumentCaptor;
2366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport org.mockito.Mock;
2466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport org.mockito.MockitoAnnotations;
2566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport org.robolectric.RuntimeEnvironment;
2666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport org.robolectric.Shadows;
2766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport org.robolectric.annotation.Config;
2866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
2966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport java.util.Collection;
3066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangimport java.util.List;
3166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
3266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang/**
3366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang * Unit tests for {@link GnssSatelliteBlacklistHelper}.
3466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang */
3566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang@RunWith(FrameworkRobolectricTestRunner.class)
3666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang@Config(
3766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        manifest = Config.NONE,
3866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        shadows = {
3966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        },
4066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        sdk = 27
4166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang)
4266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang@SystemLoaderPackages({"com.android.server.location"})
4366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang@Presubmit
4466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yangpublic class GnssSatelliteBlacklistHelperTest {
4566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
4666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    private Context mContext;
4766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    private ContentResolver mContentResolver;
4866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    @Mock
4966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    private GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback mCallback;
5066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
5166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    @Before
5266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    public void setUp() {
5366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        MockitoAnnotations.initMocks(this);
5466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        mContext = RuntimeEnvironment.application;
5566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        mContentResolver = mContext.getContentResolver();
5666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        new GnssSatelliteBlacklistHelper(mContext, Looper.myLooper(), mCallback);
5766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
5866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
5966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    @Test
6066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    public void blacklistOf2Satellites_callbackIsCalled() {
6166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        String blacklist = "3,0,5,24";
6266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        updateBlacklistAndVerifyCallbackIsCalled(blacklist);
6366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
6466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
6566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    @Test
6666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    public void blacklistWithSpaces_callbackIsCalled() {
6766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        String blacklist = "3, 11";
6866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        updateBlacklistAndVerifyCallbackIsCalled(blacklist);
6966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
7066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
7166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    @Test
7266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    public void emptyBlacklist_callbackIsCalled() {
7366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        String blacklist = "";
7466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        updateBlacklistAndVerifyCallbackIsCalled(blacklist);
7566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
7666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
7766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    @Test
7866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    public void blacklistWithOddNumberOfValues_callbackIsNotCalled() {
7966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        String blacklist = "3,0,5";
8066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        updateBlacklistAndNotifyContentObserver(blacklist);
8166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        verify(mCallback, never()).onUpdateSatelliteBlacklist(any(int[].class), any(int[].class));
8266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
8366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
8466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    @Test
8566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    public void blacklistWithNegativeValue_callbackIsNotCalled() {
8666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        String blacklist = "3,-11";
8766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        updateBlacklistAndNotifyContentObserver(blacklist);
8866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        verify(mCallback, never()).onUpdateSatelliteBlacklist(any(int[].class), any(int[].class));
8966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
9066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
9166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    @Test
9266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    public void blacklistWithNonDigitCharacter_callbackIsNotCalled() {
9366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        String blacklist = "3,1a,5,11";
9466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        updateBlacklistAndNotifyContentObserver(blacklist);
9566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        verify(mCallback, never()).onUpdateSatelliteBlacklist(any(int[].class), any(int[].class));
9666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
9766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
9866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    private void updateBlacklistAndNotifyContentObserver(String blacklist) {
9966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        Settings.Global.putString(mContentResolver,
10066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang                Settings.Global.GNSS_SATELLITE_BLACKLIST, blacklist);
10166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        notifyContentObserverFor(Settings.Global.GNSS_SATELLITE_BLACKLIST);
10266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
10366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
10466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    private void updateBlacklistAndVerifyCallbackIsCalled(String blacklist) {
10566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        updateBlacklistAndNotifyContentObserver(blacklist);
10666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
10766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        ArgumentCaptor<int[]> constellationsCaptor = ArgumentCaptor.forClass(int[].class);
10866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        ArgumentCaptor<int[]> svIdsCaptor = ArgumentCaptor.forClass(int[].class);
10966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        verify(mCallback).onUpdateSatelliteBlacklist(constellationsCaptor.capture(),
11066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang                svIdsCaptor.capture());
11166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
11266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        int[] constellations = constellationsCaptor.getValue();
11366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        int[] svIds = svIdsCaptor.getValue();
11466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        List<Integer> values = GnssSatelliteBlacklistHelper.parseSatelliteBlacklist(blacklist);
11566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        assertThat(values.size()).isEqualTo(constellations.length * 2);
11666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        assertThat(svIds.length).isEqualTo(constellations.length);
11766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        for (int i = 0; i < constellations.length; i++) {
11866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang            assertThat(constellations[i]).isEqualTo(values.get(i * 2));
11966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang            assertThat(svIds[i]).isEqualTo(values.get(i * 2 + 1));
12066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        }
12166c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
12266c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang
12366c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    private static void notifyContentObserverFor(String globalSetting) {
12466c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        Collection<ContentObserver> contentObservers =
12566c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang                Shadows.shadowOf(RuntimeEnvironment.application.getContentResolver())
12666c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang                        .getContentObservers(Settings.Global.getUriFor(globalSetting));
12766c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        assertThat(contentObservers).isNotEmpty();
12866c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang        contentObservers.iterator().next().onChange(false /* selfChange */);
12966c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang    }
13066c7ea91b413c9d812047288efb343c16b23d865Yu-Han Yang}
131