OSDN Git Service

Location Unit tests
authortccyp <tccyp@google.com>
Wed, 15 Nov 2017 18:51:53 +0000 (10:51 -0800)
committertccyp <tccyp@google.com>
Fri, 17 Nov 2017 17:58:12 +0000 (09:58 -0800)
- Added the GnssStatus unit test
- Upgraded the runner to AndroidJunitRunner
- Removed the old non-working unit tests.

To run the tests, use any of this:
1. runtest frameworks-location
2. forrest test FrameworksLocationTests

Bug: 69375757
Test: runtest frameworks-location

Change-Id: Ia52a8ce51ab9334ad1b8dd1686303270ceca270b

location/Android.mk
location/tests/locationtests/Android.mk
location/tests/locationtests/AndroidManifest.xml
location/tests/locationtests/AndroidTest.xml [new file with mode: 0644]
location/tests/locationtests/src/android/location/GnssStatusTest.java [new file with mode: 0644]
location/tests/locationtests/src/android/location/GpsStatusTest.java [deleted file]
location/tests/locationtests/src/android/location/SatelliteInfo.java [new file with mode: 0644]

index feeb8ce..50509c6 100644 (file)
@@ -14,4 +14,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-include $(call all-makefiles-under, $(LOCAL_PATH))
+include $(call all-subdir-makefiles, $(LOCAL_PATH))
\ No newline at end of file
index 902cd96..73b2bb5 100644 (file)
@@ -10,5 +10,13 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_JAVA_LIBRARIES := android.test.runner
 LOCAL_PACKAGE_NAME := FrameworksLocationTests
 
-include $(BUILD_PACKAGE)
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    core-test-rules \
+    guava \
+    mockito-target-minus-junit4 \
+    frameworks-base-testutils \
+    truth-prebuilt \
 
+LOCAL_COMPATIBILITY_SUITE := device-tests
+include $(BUILD_PACKAGE)
index 1d9df0f..ddb8ea6 100644 (file)
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-    
+
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
 
     <instrumentation
-       android:name="android.test.InstrumentationTestRunner"
-       android:targetPackage="com.android.frameworks.locationtests"
-       android:label="Frameworks Location Tests" />
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.frameworks.locationtests"
+        android:label="Frameworks Location Tests" />
 </manifest>
diff --git a/location/tests/locationtests/AndroidTest.xml b/location/tests/locationtests/AndroidTest.xml
new file mode 100644 (file)
index 0000000..0c5b7cc
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs Frameworks Location API Tests.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="FrameworksLocationTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-tag" value="FrameworksLocationTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.frameworks.locationtests" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+    </test>
+</configuration>
diff --git a/location/tests/locationtests/src/android/location/GnssStatusTest.java b/location/tests/locationtests/src/android/location/GnssStatusTest.java
new file mode 100644 (file)
index 0000000..79ea0d6
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.location;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link GnssStatus}.
+ */
+@SmallTest
+public class GnssStatusTest extends TestCase {
+
+  private static final String TAG = GnssStatusTest.class.getSimpleName();
+  public void setUp() throws Exception {
+    super.setUp();
+  }
+
+  /*
+   * Create {@link GnssStatus} with default value, verify whether its fields are set correctly.
+   *
+   */
+  public void testEmptyGnssStatus() throws Exception {
+    Log.i(TAG, "testEmptyGnssStatus");
+    List<SatelliteInfo> svInfos = new ArrayList<>();
+    GnssStatus gnssStatus = createGnssStatus(svInfos);
+    verifyGnssStatus(svInfos, gnssStatus);
+  }
+
+  /*
+   * Create {@link GnssStatus} with only one satellite info, verify whether its fields are set
+   * correctly.
+   */
+  public void testOneSatelliteGnssStatus() throws Exception {
+    Log.i(TAG, "testOneSatelliteGnssStatus");
+    List<SatelliteInfo> svInfos = new ArrayList<>();
+    SatelliteInfo svInfo =
+        new SatelliteInfo(100,1, true, true, true, true, 100f, 20.3f, 45.5f, 100.23f);
+    svInfos.add(svInfo);
+    GnssStatus gnssStatus = createGnssStatus(svInfos);
+    verifyGnssStatus(svInfos, gnssStatus);
+  }
+
+  /*
+   * Create {@link GnssStatus} with multiple satellite info, verify whether its fields are set
+   * correctly.
+   */
+  public void testMultipleSatellitesGnssStatus() throws Exception {
+    Log.i(TAG, "testMultipleSatellitesGnssStatus");
+    List<SatelliteInfo> svInfos = new ArrayList<>();
+    SatelliteInfo svInfo1 =
+        new SatelliteInfo(20, 1,true, true, true, true, 10.1f, 20.3f, 45.5f, 111.23f);
+    SatelliteInfo svInfo2 =
+        new SatelliteInfo(50, 2, true, false, true, false, 20.2f, 21.3f, 46.5f, 222.23f);
+    SatelliteInfo svInfo3 =
+        new SatelliteInfo(192, 3, false, true, false, true, 30.3f, 22.3f, 47.5f, 333.23f);
+    SatelliteInfo svInfo4 =
+        new SatelliteInfo(250, 4, false, false, false, false, 40.4f, 23.3f, 48.5f, 444.23f);
+    svInfos.add(svInfo1);
+    svInfos.add(svInfo2);
+    svInfos.add(svInfo3);
+    svInfos.add(svInfo4);
+    GnssStatus gnssStatus = createGnssStatus(svInfos);
+    verifyGnssStatus(svInfos, gnssStatus);
+  }
+
+  private void verifyGnssStatus(List<SatelliteInfo> svInfos, GnssStatus gnssStatus) {
+    Log.i(TAG, String.format("Verifing {0} satellites info.",svInfos.size()));
+    assertEquals(TAG + "::SatelliteCount", svInfos.size(),
+        gnssStatus.getSatelliteCount());
+    for (int i = 0; i< svInfos.size(); i++) {
+      SatelliteInfo svInfo = svInfos.get(i);
+      assertEquals(TAG + "::Svid", svInfo.mSvid, gnssStatus.getSvid(i));
+      assertEquals(TAG + "::ConstellationType", svInfo.mConstellationType,
+          gnssStatus.getConstellationType(i));
+      assertEquals(TAG + "::Cn0DbHz", svInfo.mCn0DbHz, gnssStatus.getCn0DbHz(i));
+      assertEquals(TAG + "::Elevation", svInfo.mElevation,
+          gnssStatus.getElevationDegrees(i));
+      assertEquals(TAG + "::Azimuth", svInfo.mAzimuth, gnssStatus.getAzimuthDegrees(i));
+      assertEquals(TAG + "::CarrierFrequencyHz", svInfo.mCarrierFrequency,
+          gnssStatus.getCarrierFrequencyHz(i));
+      assertEquals(TAG + "::hasEphemerisData", svInfo.mHasEphemris,
+          gnssStatus.hasEphemerisData(i));
+      assertEquals(TAG + "::HasAlmanacData", svInfo.mHasAlmanac,
+          gnssStatus.hasAlmanacData(i));
+      assertEquals(TAG + "::UsedInFix", svInfo.mUsedInFix, gnssStatus.usedInFix(i));
+      assertEquals(TAG + "::HasCarrierFrequencyHz", svInfo.mHasCarriesFrequency,
+          gnssStatus.hasCarrierFrequencyHz(i));
+    }
+  }
+
+  private static GnssStatus createGnssStatus(List<SatelliteInfo> svInfos) throws Exception {
+    Class<?> intClass = Integer.TYPE;
+    Class<?> floatArrayClass = Class.forName("[F");
+    Class<?> intArrayClass = Class.forName("[I");
+    Class[] cArg = new Class[6];
+    cArg[0] = intClass;
+    cArg[1] = intArrayClass;
+    cArg[2] = floatArrayClass;
+    cArg[3] = floatArrayClass;
+    cArg[4] = floatArrayClass;
+    cArg[5] = floatArrayClass;
+    Constructor<GnssStatus>  ctor = GnssStatus.class.getDeclaredConstructor(cArg);
+    ctor.setAccessible(true);
+    return ctor.newInstance(svInfos.size(),
+        SatelliteInfo.getSvidWithFlagsArray(svInfos),
+        SatelliteInfo.getCn0sArray(svInfos),
+        SatelliteInfo.getElevationsArray(svInfos),
+        SatelliteInfo.getAzimuthsArray(svInfos),
+        SatelliteInfo.getCarrierFrequencyArray(svInfos));
+  }
+}
diff --git a/location/tests/locationtests/src/android/location/GpsStatusTest.java b/location/tests/locationtests/src/android/location/GpsStatusTest.java
deleted file mode 100644 (file)
index 316e88d..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.location;
-
-import junit.framework.TestCase;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Random;
-import java.util.Set;
-
-/**
- * Unit tests for {@link GpsStatus}.
- */
-@SmallTest
-public class GpsStatusTest extends TestCase {
-
-    private static final int MAX_VALUE = 250;
-
-    private final Random mRandom = new Random();
-
-    private GpsStatus mStatus;
-    private int mCount;
-    private int[] mPrns;
-    private float[] mCn0s;
-    private float[] mElevations;
-    private float[] mAzimuth;
-    private int mEphemerisMask;
-    private int mAlmanacMask;
-    private int mUsedInFixMask;
-
-    public void setUp() throws Exception {
-        super.setUp();
-        mStatus = createGpsStatus();
-        generateSatellitesData(generateInt());
-    }
-
-    public void testEmptyGpsStatus() throws Exception {
-        verifyIsEmpty(mStatus);
-    }
-
-    public void testGpsStatusIterator() throws Exception {
-        generateSatellitesData(2);
-        setSatellites(mStatus);
-        Iterator<GpsSatellite> iterator = mStatus.getSatellites().iterator();
-        assertTrue("hasNext(1)", iterator.hasNext());
-        assertTrue("hasNext(1) does not overflow", iterator.hasNext());
-        GpsSatellite satellite1 = iterator.next();
-        assertNotNull("satellite", satellite1);
-        assertTrue("hasNext(2)", iterator.hasNext());
-        assertTrue("hasNext(2) does not overflow", iterator.hasNext());
-        GpsSatellite satellite2 = iterator.next();
-        assertNotNull("satellite", satellite2);
-        assertFalse("hasNext() no elements", iterator.hasNext());
-    }
-
-    public void testTtff() throws Exception {
-        int testTtff = generateInt();
-        set(mStatus, testTtff);
-        verifyTtff(mStatus, testTtff);
-    }
-
-    public void testCopyTtff() throws Exception {
-        int testTtff = generateInt();
-        verifyTtff(mStatus, 0);
-
-        GpsStatus otherStatus = createGpsStatus();
-        set(otherStatus, testTtff);
-        verifyTtff(otherStatus, testTtff);
-
-        set(mStatus, otherStatus);
-        verifyTtff(mStatus, testTtff);
-    }
-
-    public void testSetSatellites() throws Exception {
-        setSatellites(mStatus);
-        verifySatellites(mStatus);
-    }
-
-    public void testCopySatellites() throws Exception {
-        verifyIsEmpty(mStatus);
-
-        GpsStatus otherStatus = createGpsStatus();
-        setSatellites(otherStatus);
-        verifySatellites(otherStatus);
-
-        set(mStatus, otherStatus);
-        verifySatellites(mStatus);
-    }
-
-    public void testOverrideSatellites() throws Exception {
-        setSatellites(mStatus);
-        verifySatellites(mStatus);
-
-        GpsStatus otherStatus = createGpsStatus();
-        generateSatellitesData(mCount, true /* reusePrns */);
-        setSatellites(otherStatus);
-        verifySatellites(otherStatus);
-
-        set(mStatus, otherStatus);
-        verifySatellites(mStatus);
-    }
-
-    public void testAddSatellites() throws Exception {
-        int count = 10;
-        generateSatellitesData(count);
-        setSatellites(mStatus);
-        verifySatellites(mStatus);
-
-        GpsStatus otherStatus = createGpsStatus();
-        generateSatellitesData(count);
-        setSatellites(otherStatus);
-        verifySatellites(otherStatus);
-
-        set(mStatus, otherStatus);
-        verifySatellites(mStatus);
-    }
-
-    public void testAddMoreSatellites() throws Exception {
-        int count = 25;
-        generateSatellitesData(count);
-        setSatellites(mStatus);
-        verifySatellites(mStatus);
-
-        GpsStatus otherStatus = createGpsStatus();
-        generateSatellitesData(count * 2);
-        setSatellites(otherStatus);
-        verifySatellites(otherStatus);
-
-        set(mStatus, otherStatus);
-        verifySatellites(mStatus);
-    }
-
-    public void testAddLessSatellites() throws Exception {
-        int count = 25;
-        generateSatellitesData(count * 2);
-        setSatellites(mStatus);
-        verifySatellites(mStatus);
-
-        GpsStatus otherStatus = createGpsStatus();
-        generateSatellitesData(count);
-        setSatellites(otherStatus);
-        verifySatellites(otherStatus);
-
-        set(mStatus, otherStatus);
-        verifySatellites(mStatus);
-    }
-
-    private static void verifyIsEmpty(GpsStatus status) {
-        verifySatelliteCount(status, 0);
-        verifyTtff(status, 0);
-    }
-
-    private static void verifySatelliteCount(GpsStatus status, int expectedCount) {
-        int satellites = 0;
-        for (GpsSatellite s : status.getSatellites()) {
-            ++satellites;
-        }
-        assertEquals("GpsStatus::SatelliteCount", expectedCount, satellites);
-    }
-
-    private void verifySatellites(GpsStatus status) {
-        verifySatelliteCount(status, mCount);
-        verifySatellites(status, mCount, mPrns, mCn0s, mElevations, mAzimuth, mEphemerisMask,
-                mAlmanacMask, mUsedInFixMask);
-    }
-
-    private static void verifySatellites(
-            GpsStatus status,
-            int count,
-            int[] prns,
-            float[] cn0s,
-            float[] elevations,
-            float[] azimuth,
-            int ephemerisMask,
-            int almanacMask,
-            int usedInFixMask) {
-        for (int i = 0; i < count; ++i) {
-            int prn = prns[i];
-            GpsSatellite satellite = getSatellite(status, prn);
-            assertNotNull(getSatelliteAssertInfo(i, prn, "non-null"), satellite);
-            assertEquals(getSatelliteAssertInfo(i, prn, "Snr"), cn0s[i], satellite.getSnr());
-            assertEquals(
-                    getSatelliteAssertInfo(i, prn, "Elevation"),
-                    elevations[i],
-                    satellite.getElevation());
-            assertEquals(
-                    getSatelliteAssertInfo(i, prn, "Azimuth"),
-                    azimuth[i],
-                    satellite.getAzimuth());
-            int prnShift = 1 << (prn - 1);
-            assertEquals(
-                    getSatelliteAssertInfo(i, prn, "ephemeris"),
-                    (ephemerisMask & prnShift) != 0,
-                    satellite.hasEphemeris());
-            assertEquals(
-                    getSatelliteAssertInfo(i, prn, "almanac"),
-                    (almanacMask & prnShift) != 0,
-                    satellite.hasAlmanac());
-            assertEquals(
-                    getSatelliteAssertInfo(i, prn, "usedInFix"),
-                    (usedInFixMask & prnShift) != 0,
-                    satellite.usedInFix());
-        }
-    }
-
-    private static void verifyTtff(GpsStatus status, int expectedTtff) {
-        assertEquals("GpsStatus::TTFF", expectedTtff, status.getTimeToFirstFix());
-    }
-
-    private static GpsStatus createGpsStatus() throws Exception {
-        Constructor<GpsStatus>  ctor = GpsStatus.class.getDeclaredConstructor();
-        ctor.setAccessible(true);
-        return ctor.newInstance();
-    }
-
-    private static void set(GpsStatus status, int ttff) throws Exception {
-        Class<?> statusClass = status.getClass();
-        Method setTtff = statusClass.getDeclaredMethod("setTimeToFirstFix", Integer.TYPE);
-        setTtff.setAccessible(true);
-        setTtff.invoke(status, ttff);
-    }
-
-    private static void set(GpsStatus status, GpsStatus statusToSet) throws Exception {
-        Class<?> statusClass = status.getClass();
-        Method setStatus = statusClass.getDeclaredMethod("setStatus", statusClass);
-        setStatus.setAccessible(true);
-        setStatus.invoke(status, statusToSet);
-    }
-
-    private void setSatellites(GpsStatus status) throws Exception {
-        set(status, mCount, mPrns, mCn0s, mElevations, mAzimuth, mEphemerisMask, mAlmanacMask,
-                mUsedInFixMask);
-    }
-
-    private static void set(
-            GpsStatus status,
-            int count,
-            int[] prns,
-            float[] cn0s,
-            float[] elevations,
-            float[] azimuth,
-            int ephemerisMask,
-            int almanacMask,
-            int usedInFixMask) throws Exception {
-        Class<?> statusClass = status.getClass();
-        Class<?> intClass = Integer.TYPE;
-        Class<?> floatArrayClass = Class.forName("[F");
-        Method setStatus = statusClass.getDeclaredMethod(
-                "setStatus",
-                intClass,
-                Class.forName("[I"),
-                floatArrayClass,
-                floatArrayClass,
-                floatArrayClass,
-                intClass,
-                intClass,
-                intClass);
-        setStatus.setAccessible(true);
-        setStatus.invoke(
-                status,
-                count,
-                prns,
-                cn0s,
-                elevations,
-                azimuth,
-                ephemerisMask,
-                almanacMask,
-                usedInFixMask);
-    }
-
-    private int generateInt() {
-        return mRandom.nextInt(MAX_VALUE) + 1;
-    }
-
-    private int[] generateIntArray(int count) {
-        Set<Integer> generatedPrns = new HashSet<>();
-        int[] array = new int[count];
-        for(int i = 0; i < count; ++i) {
-            int generated;
-            do {
-                generated = generateInt();
-            } while (generatedPrns.contains(generated));
-            array[i] = generated;
-            generatedPrns.add(generated);
-        }
-        return array;
-    }
-
-    private float[] generateFloatArray(int count) {
-        float[] array = new float[count];
-        for(int i = 0; i < count; ++i) {
-            array[i] = generateInt();
-        }
-        return array;
-    }
-
-    private int generateMask(int[] prns) {
-        int mask = 0;
-        int prnsLength = prns.length;
-        for (int i = 0; i < prnsLength; ++i) {
-            if (mRandom.nextBoolean()) {
-                mask |= 1 << (prns[i] - 1);
-            }
-        }
-        return mask;
-    }
-
-    private void generateSatellitesData(int count) {
-        generateSatellitesData(count, false /* reusePrns */);
-    }
-
-    private void generateSatellitesData(int count, boolean reusePrns) {
-        mCount = count;
-        if (!reusePrns) {
-            mPrns = generateIntArray(count);
-        }
-        mCn0s = generateFloatArray(count);
-        mElevations = generateFloatArray(count);
-        mAzimuth = generateFloatArray(count);
-        mEphemerisMask = generateMask(mPrns);
-        mAlmanacMask = generateMask(mPrns);
-        mUsedInFixMask = generateMask(mPrns);
-    }
-
-    private static GpsSatellite getSatellite(GpsStatus status, int prn) {
-        for (GpsSatellite satellite : status.getSatellites()) {
-            if (satellite.getPrn() == prn) {
-                return satellite;
-            }
-        }
-        return null;
-    }
-
-    private static String getSatelliteAssertInfo(int index, int prn, String param) {
-        return String.format("Satellite::%s [i=%d, prn=%d]", param, index, prn);
-    }
-}
diff --git a/location/tests/locationtests/src/android/location/SatelliteInfo.java b/location/tests/locationtests/src/android/location/SatelliteInfo.java
new file mode 100644 (file)
index 0000000..b6453ef
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.location;
+
+import java.util.List;
+
+/*
+ * Helper class to store single Satellite info, only used it in the unit test.
+ */
+public class SatelliteInfo {
+  private static final int SVID_MAX_BIT_INDEX = 32;
+  private static final int SVID_SHIFT_WIDTH = 8;
+  private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 4;
+
+  // Index for the bits in mSvidWithFlag
+  private static final int GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA_BIT_INDEX = 0;
+  private static final int GNSS_SV_FLAGS_HAS_ALMANAC_DATA_BIT_INDEX = 1;
+  private static final int GNSS_SV_FLAGS_USED_IN_FIX_BIT_INDEX = 2;
+  private static final int GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY_BIT_INDEX = 3;
+  public int mSvid;
+  public int mSvidWithFlag;
+  public float mCn0DbHz;
+  public float mElevation;
+  public float mAzimuth;
+  public float mCarrierFrequency;
+
+  /*
+   * Flag fields, it stores the same information as svidWithFlag, but in different format, easy for
+   * the unit test.
+   */
+  public int mConstellationType;
+  public boolean mHasEphemris;
+  public boolean mHasAlmanac;
+  public boolean mUsedInFix;
+  public boolean mHasCarriesFrequency;
+
+  public SatelliteInfo(int svid, int constellationType, boolean hasEphemris, boolean hasAlmanac,
+      boolean usedInFix, boolean hasCarriesFrequency, float cn0, float elevation, float azimuth,
+      float carrierFrequency) {
+    mSvidWithFlag =
+        setRange(mSvidWithFlag, constellationType, CONSTELLATION_TYPE_SHIFT_WIDTH, SVID_SHIFT_WIDTH);
+    mSvidWithFlag = setRange(mSvidWithFlag, svid, SVID_SHIFT_WIDTH, SVID_MAX_BIT_INDEX);
+    mSvidWithFlag = setBit(mSvidWithFlag, hasEphemris, GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA_BIT_INDEX);
+    mSvidWithFlag = setBit(mSvidWithFlag, hasAlmanac, GNSS_SV_FLAGS_HAS_ALMANAC_DATA_BIT_INDEX);
+    mSvidWithFlag = setBit(mSvidWithFlag, usedInFix, GNSS_SV_FLAGS_USED_IN_FIX_BIT_INDEX);
+    mSvidWithFlag =
+        setBit(mSvidWithFlag, hasCarriesFrequency, GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY_BIT_INDEX);
+    this.mSvid = svid;
+    this.mConstellationType = constellationType;
+    this.mCn0DbHz = cn0;
+    this.mElevation = elevation;
+    this.mAzimuth = azimuth;
+    this.mCarrierFrequency = carrierFrequency;
+    this.mHasEphemris = hasEphemris;
+    this.mHasAlmanac = hasAlmanac;
+    this.mUsedInFix = usedInFix;
+    this.mHasCarriesFrequency = hasCarriesFrequency;
+  }
+
+  /*
+   * Gernerate svidWithFlags array from svInfos
+   */
+  public static int[] getSvidWithFlagsArray(List<SatelliteInfo> svInfos) {
+    int[] svidWithFlags = new int[svInfos.size()];
+    for (int i = 0; i< svInfos.size(); i++) {
+      svidWithFlags[i] = svInfos.get(i).mSvidWithFlag;
+    }
+    return svidWithFlags;
+  }
+
+  /*
+   * Gernerate cn0s array from svInfos
+   */
+  public static float[] getCn0sArray(List<SatelliteInfo> svInfos) {
+    float[] cn0s = new float[svInfos.size()];
+    for (int i = 0; i< svInfos.size(); i++) {
+      cn0s[i] = svInfos.get(i).mCn0DbHz;
+    }
+    return cn0s;
+  }
+
+  /*
+   * Gernerate elevations array from svInfos
+   */
+  public static float[] getElevationsArray(List<SatelliteInfo> svInfos) {
+    float[] elevations = new float[svInfos.size()];
+    for (int i = 0; i< svInfos.size(); i++) {
+      elevations[i] = svInfos.get(i).mElevation;
+    }
+    return elevations;
+  }
+
+  /*
+   * Gernerate azimuths array from svInfos
+   */
+  public static float[] getAzimuthsArray(List<SatelliteInfo> svInfos) {
+    float[] azimuths = new float[svInfos.size()];
+    for (int i = 0; i< svInfos.size(); i++) {
+      azimuths[i] = svInfos.get(i).mAzimuth;
+    }
+    return azimuths;
+  }
+
+  /*
+   * Gernerate carrierFrequency array from svInfos
+   */
+  public static float[] getCarrierFrequencyArray(List<SatelliteInfo> svInfos) {
+    float[] carrierFrequencies = new float[svInfos.size()];
+    for (int i = 0; i< svInfos.size(); i++) {
+      carrierFrequencies[i] = svInfos.get(i).mCarrierFrequency;
+    }
+    return carrierFrequencies;
+  }
+
+  private int setBit(int targetValue, boolean value, int index) {
+    if (value) {
+      targetValue = targetValue | (1 << index);
+    } else {
+      targetValue = targetValue & ~(1 << index);
+    }
+    return targetValue;
+  }
+
+  /*
+   * Set the bit in the range [fromIndex, toIndex), index start from the lowest bit.
+   * value -> 1 1 0 1 1 0 1 0
+   * index -> 7 6 5 4 3 2 1 0
+   * This function will set the bit in the range to the lowest X bits of the value.
+   */
+  private int setRange(int targetValue, int value, int fromIndex, int toIndex) {
+    int rangeLen = toIndex - fromIndex;
+    int valueMask = (1 << rangeLen) -1;
+    value &= valueMask;
+    value = value << fromIndex;
+    valueMask = valueMask << fromIndex;
+    targetValue &= (~valueMask);
+    targetValue |= value;
+    return targetValue;
+  }
+
+}
\ No newline at end of file