diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index b764ce5..abd2a35 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -50,8 +50,8 @@
 const int FIELD_ID_NAME = 2;
 
 StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap,
-                                     const std::function<void(const vector<uint8_t>&)>& pushLog)
-    : mUidMap(uidMap), mPushLog(pushLog) {
+                                     const std::function<void(const ConfigKey&)>& sendBroadcast)
+    : mUidMap(uidMap), mSendBroadcast(sendBroadcast) {
 }
 
 StatsLogProcessor::~StatsLogProcessor() {
@@ -102,12 +102,27 @@
     }
 }
 
-vector<uint8_t> StatsLogProcessor::onDumpReport(const ConfigKey& key) {
+size_t StatsLogProcessor::GetMetricsSize(const ConfigKey& key) {
     auto it = mMetricsManagers.find(key);
     if (it == mMetricsManagers.end()) {
         ALOGW("Config source %s does not exist", key.ToString().c_str());
-        return vector<uint8_t>();
+        return 0;
     }
+    return it->second->byteSize();
+}
+
+void StatsLogProcessor::onDumpReport(const ConfigKey& key, vector<uint8_t>* outData) {
+    auto it = mMetricsManagers.find(key);
+    if (it == mMetricsManagers.end()) {
+        ALOGW("Config source %s does not exist", key.ToString().c_str());
+        return;
+    }
+
+    // This allows another broadcast to be sent within the rate-limit period if we get close to
+    // filling the buffer again soon.
+    mBroadcastTimesMutex.lock();
+    mLastBroadcastTimes.erase(key);
+    mBroadcastTimesMutex.unlock();
 
     ProtoOutputStream proto;
 
@@ -131,17 +146,18 @@
     uidMap.SerializeToArray(&uidMapBuffer[0], uidMapSize);
     proto.write(FIELD_TYPE_MESSAGE | FIELD_ID_UID_MAP, uidMapBuffer, uidMapSize);
 
-    vector<uint8_t> buffer(proto.size());
-    size_t pos = 0;
-    auto iter = proto.data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-        std::memcpy(&buffer[pos], iter.readBuffer(), toRead);
-        pos += toRead;
-        iter.rp()->move(toRead);
+    if (outData != nullptr) {
+        outData->clear();
+        outData->resize(proto.size());
+        size_t pos = 0;
+        auto iter = proto.data();
+        while (iter.readBuffer() != NULL) {
+            size_t toRead = iter.currentToRead();
+            std::memcpy(&((*outData)[pos]), iter.readBuffer(), toRead);
+            pos += toRead;
+            iter.rp()->move(toRead);
+        }
     }
-
-    return buffer;
 }
 
 void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) {
@@ -151,42 +167,34 @@
         mMetricsManagers.erase(it);
         mUidMap->OnConfigRemoved(key);
     }
-    auto flushTime = mLastFlushTimes.find(key);
-    if (flushTime != mLastFlushTimes.end()) {
-        mLastFlushTimes.erase(flushTime);
-    }
+
+    std::lock_guard<std::mutex> lock(mBroadcastTimesMutex);
+    mLastBroadcastTimes.erase(key);
 }
 
 void StatsLogProcessor::flushIfNecessary(uint64_t timestampNs,
                                          const ConfigKey& key,
                                          const unique_ptr<MetricsManager>& metricsManager) {
-    auto lastFlushNs = mLastFlushTimes.find(key);
-    if (lastFlushNs != mLastFlushTimes.end()) {
-        if (timestampNs - lastFlushNs->second < kMinFlushPeriod) {
-            return;
-        }
-    }
+    std::lock_guard<std::mutex> lock(mBroadcastTimesMutex);
 
     size_t totalBytes = metricsManager->byteSize();
-    if (totalBytes > kMaxSerializedBytes) {
-        flush();
-        mLastFlushTimes[key] = std::move(timestampNs);
+    if (totalBytes > .9 * kMaxSerializedBytes) { // Send broadcast so that receivers can pull data.
+        auto lastFlushNs = mLastBroadcastTimes.find(key);
+        if (lastFlushNs != mLastBroadcastTimes.end()) {
+            if (timestampNs - lastFlushNs->second < kMinBroadcastPeriod) {
+                return;
+            }
+        }
+        mLastBroadcastTimes[key] = timestampNs;
+        ALOGD("StatsD requesting broadcast for %s", key.ToString().c_str());
+        mSendBroadcast(key);
+    } else if (totalBytes > kMaxSerializedBytes) { // Too late. We need to start clearing data.
+        // We ignore the return value so we force each metric producer to clear its contents.
+        metricsManager->onDumpReport();
+        ALOGD("StatsD had to toss out metrics for %s", key.ToString().c_str());
     }
 }
 
-void StatsLogProcessor::flush() {
-    // TODO: Take ConfigKey as an argument and flush metrics related to the
-    // ConfigKey. Also, create a wrapper that holds a repeated field of
-    // StatsLogReport's.
-    /*
-    StatsLogReport logReport;
-    const int numBytes = logReport.ByteSize();
-    vector<uint8_t> logReportBuffer(numBytes);
-    logReport.SerializeToArray(&logReportBuffer[0], numBytes);
-    mPushLog(logReportBuffer);
-    */
-}
-
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index f38d715..2091774 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -33,7 +33,7 @@
 class StatsLogProcessor : public ConfigListener {
 public:
     StatsLogProcessor(const sp<UidMap>& uidMap,
-                      const std::function<void(const vector<uint8_t>&)>& pushLog);
+                      const std::function<void(const ConfigKey&)>& sendBroadcast);
     virtual ~StatsLogProcessor();
 
     virtual void OnLogEvent(const LogEvent& event);
@@ -41,15 +41,16 @@
     void OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config);
     void OnConfigRemoved(const ConfigKey& key);
 
-    vector<uint8_t> onDumpReport(const ConfigKey& key);
+    size_t GetMetricsSize(const ConfigKey& key);
 
-    /* Request a flush through a binder call. */
-    void flush();
+    void onDumpReport(const ConfigKey& key, vector<uint8_t>* outData);
 
 private:
+    mutable mutex mBroadcastTimesMutex;
+
     std::unordered_map<ConfigKey, std::unique_ptr<MetricsManager>> mMetricsManagers;
 
-    std::unordered_map<ConfigKey, long> mLastFlushTimes;
+    std::unordered_map<ConfigKey, long> mLastBroadcastTimes;
 
     sp<UidMap> mUidMap;  // Reference to the UidMap to lookup app name and version for each uid.
 
@@ -60,17 +61,18 @@
      */
     static const size_t kMaxSerializedBytes = 16 * 1024;
 
-    /* Check if the buffer size exceeds the max buffer size when the new entry is added, and flush
-       the logs to callback clients if true. */
+    /* Check if we should send a broadcast if approaching memory limits and if we're over, we
+     * actually delete the data. */
     void flushIfNecessary(uint64_t timestampNs,
                           const ConfigKey& key,
                           const unique_ptr<MetricsManager>& metricsManager);
 
-    std::function<void(const vector<uint8_t>&)> mPushLog;
+    // Function used to send a broadcast so that receiver for the config key can call getData
+    // to retrieve the stored data.
+    std::function<void(const ConfigKey& key)> mSendBroadcast;
 
-    /* Minimum period between two flushes in nanoseconds. Currently set to 10
-     * minutes. */
-    static const unsigned long long kMinFlushPeriod = 600 * NS_PER_SEC;
+    /* Minimum period between two broadcasts in nanoseconds. Currently set to 60 seconds. */
+    static const unsigned long long kMinBroadcastPeriod = 60 * NS_PER_SEC;
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 8b76cff..10952a9 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -73,8 +73,18 @@
 {
     mUidMap = new UidMap();
     mConfigManager = new ConfigManager();
-    mProcessor = new StatsLogProcessor(mUidMap, [](const vector<uint8_t>& log) {
-        // TODO: Update how we send data out of StatsD.
+    mProcessor = new StatsLogProcessor(mUidMap, [this](const ConfigKey& key) {
+        auto sc = getStatsCompanionService();
+        auto receiver = mConfigManager->GetConfigReceiver(key);
+        if (sc == nullptr) {
+            ALOGD("Could not find StatsCompanionService");
+        } else if (receiver.first.size() == 0) {
+            ALOGD("Statscompanion could not find a broadcast receiver for %s",
+                  key.ToString().c_str());
+        } else {
+            sc->sendBroadcast(String16(receiver.first.c_str()),
+                              String16(receiver.second.c_str()));
+        }
     });
 
     mConfigManager->AddListener(mProcessor);
@@ -206,7 +216,11 @@
         }
 
         if (!args[0].compare(String8("send-broadcast"))) {
-            return cmd_trigger_broadcast(args);
+            return cmd_trigger_broadcast(out, args);
+        }
+
+        if (!args[0].compare(String8("print-stats"))) {
+            return cmd_print_stats(out);
         }
 
         if (!args[0].compare(String8("clear-config"))) {
@@ -259,16 +273,56 @@
     fprintf(out, "  NAME          The name of the configuration\n");
     fprintf(out, "\n");
     fprintf(out, "\n");
-    fprintf(out, "usage: adb shell cmd stats send-broadcast PACKAGE CLASS\n");
-    fprintf(out, "  Send a broadcast that triggers one subscriber to fetch metrics.\n");
-    fprintf(out, "  PACKAGE        The name of the package to receive the broadcast.\n");
-    fprintf(out, "  CLASS          The name of the class to receive the broadcast.\n");
+    fprintf(out, "usage: adb shell cmd stats send-broadcast [UID] NAME\n");
+    fprintf(out, "  Send a broadcast that triggers the subscriber to fetch metrics.\n");
+    fprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
+    fprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
+    fprintf(out, "                calling uid is used.\n");
+    fprintf(out, "  NAME          The name of the configuration\n");
+    fprintf(out, "\n");
+    fprintf(out, "\n");
+    fprintf(out, "usage: adb shell cmd stats print-stats\n");
+    fprintf(out, "  Prints some basic stats.\n");
 }
 
-status_t StatsService::cmd_trigger_broadcast(Vector<String8>& args) {
+status_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) {
+    string name;
+    bool good = false;
+    int uid;
+    const int argCount = args.size();
+    if (argCount == 2) {
+        // Automatically pick the UID
+        uid = IPCThreadState::self()->getCallingUid();
+        // TODO: What if this isn't a binder call? Should we fail?
+        name.assign(args[1].c_str(), args[1].size());
+        good = true;
+    } else if (argCount == 3) {
+        // If it's a userdebug or eng build, then the shell user can
+        // impersonate other uids.
+        if (mEngBuild) {
+            const char* s = args[1].c_str();
+            if (*s != '\0') {
+                char* end = NULL;
+                uid = strtol(s, &end, 0);
+                if (*end == '\0') {
+                    name.assign(args[2].c_str(), args[2].size());
+                    good = true;
+                }
+            }
+        } else {
+            fprintf(out,
+                    "The metrics can only be dumped for other UIDs on eng or userdebug "
+                            "builds.\n");
+        }
+    }
+    if (!good) {
+        print_cmd_help(out);
+        return UNKNOWN_ERROR;
+    }
+    auto receiver = mConfigManager->GetConfigReceiver(ConfigKey(uid, name));
     auto sc = getStatsCompanionService();
-    sc->sendBroadcast(String16(args[1]), String16(args[2]));
-    ALOGD("StatsService::trigger broadcast succeeded");
+    sc->sendBroadcast(String16(receiver.first.c_str()), String16(receiver.second.c_str()));
+    ALOGD("StatsService::trigger broadcast succeeded to %s, %s", args[1].c_str(), args[2].c_str());
     return NO_ERROR;
 }
 
@@ -373,7 +427,8 @@
             }
         }
         if (good) {
-            mProcessor->onDumpReport(ConfigKey(uid, name));
+            vector<uint8_t> data;
+            mProcessor->onDumpReport(ConfigKey(uid, name), &data);
             // TODO: print the returned StatsLogReport to file instead of printing to logcat.
             fprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
             fprintf(out, "See the StatsLogReport in logcat...\n");
@@ -389,6 +444,15 @@
     }
 }
 
+status_t StatsService::cmd_print_stats(FILE* out) {
+    vector<ConfigKey> configs = mConfigManager->GetAllConfigKeys();
+    for (const ConfigKey& key : configs) {
+        fprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(),
+                mProcessor->GetMetricsSize(key));
+    }
+    return NO_ERROR;
+}
+
 status_t StatsService::cmd_print_stats_log(FILE* out, const Vector<String8>& args) {
     long msec = 0;
 
@@ -573,10 +637,14 @@
     mProcessor->OnLogEvent(event);
 }
 
-Status StatsService::getData(const String16& key, vector<uint8_t>* output) {
+Status StatsService::getData(const String16& key, vector <uint8_t>* output) {
     IPCThreadState* ipc = IPCThreadState::self();
+    ALOGD("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(),
+          ipc->getCallingUid());
     if (checkCallingPermission(String16(kPermissionDump))) {
-        // TODO: Implement this.
+        string keyStr = string(String8(key).string());
+        ConfigKey configKey(ipc->getCallingUid(), keyStr);
+        mProcessor->onDumpReport(configKey, output);
         return Status::ok();
     } else {
         return Status::fromExceptionCode(binder::Status::EX_SECURITY);
@@ -588,10 +656,9 @@
                                       const String16& package, const String16& cls,
                                       bool* success) {
     IPCThreadState* ipc = IPCThreadState::self();
-    int32_t* uid = reinterpret_cast<int32_t*>(ipc->getCallingUid());
     if (checkCallingPermission(String16(kPermissionDump))) {
         string keyString = string(String8(key).string());
-        ConfigKey configKey(*uid, keyString);
+        ConfigKey configKey(ipc->getCallingUid(), keyString);
         StatsdConfig cfg;
         cfg.ParseFromArray(&config[0], config.size());
         mConfigManager->UpdateConfig(configKey, cfg);
@@ -607,7 +674,8 @@
 Status StatsService::removeConfiguration(const String16& key, bool* success) {
     IPCThreadState* ipc = IPCThreadState::self();
     if (checkCallingPermission(String16(kPermissionDump))) {
-        // TODO: Implement this.
+        string keyStr = string(String8(key).string());
+        mConfigManager->RemoveConfig(ConfigKey(ipc->getCallingUid(), keyStr));
         return Status::ok();
     } else {
         *success = false;
@@ -615,7 +683,7 @@
     }
 }
 
-void StatsService::binderDied(const wp<IBinder>& who) {
+void StatsService::binderDied(const wp <IBinder>& who) {
     for (size_t i = 0; i < mCallbacks.size(); i++) {
         if (IInterface::asBinder(mCallbacks[i]) == who) {
             mCallbacks.removeAt(i);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 0163f94..888f97b 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -124,7 +124,7 @@
     /**
      * Trigger a broadcast.
      */
-    status_t cmd_trigger_broadcast(Vector<String8>& args);
+    status_t cmd_trigger_broadcast(FILE* out, Vector<String8>& args);
 
     /**
      * Handle the config sub-command.
@@ -132,6 +132,11 @@
     status_t cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args);
 
     /**
+     * Prints some basic stats to std out.
+     */
+    status_t cmd_print_stats(FILE* out);
+
+    /**
      * Print the event log.
      */
     status_t cmd_print_stats_log(FILE* out, const Vector<String8>& args);
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index 3319f6d..9680e4a 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -134,12 +134,34 @@
     }
 }
 
+vector<ConfigKey> ConfigManager::GetAllConfigKeys() {
+    vector<ConfigKey> ret;
+    for (auto it = mConfigs.cbegin(); it != mConfigs.cend(); ++it) {
+        ret.push_back(it->first);
+    }
+    return ret;
+}
+
+const pair<string, string> ConfigManager::GetConfigReceiver(const ConfigKey& key) {
+    auto it = mConfigReceivers.find(key);
+    if (it == mConfigReceivers.end()) {
+        return pair<string,string>();
+    } else {
+        return it->second;
+    }
+}
+
 void ConfigManager::Dump(FILE* out) {
     fprintf(out, "CONFIGURATIONS (%d)\n", (int)mConfigs.size());
     fprintf(out, "     uid name\n");
     for (unordered_map<ConfigKey, StatsdConfig>::const_iterator it = mConfigs.begin();
          it != mConfigs.end(); it++) {
         fprintf(out, "  %6d %s\n", it->first.GetUid(), it->first.GetName().c_str());
+        auto receiverIt = mConfigReceivers.find(it->first);
+        if (receiverIt != mConfigReceivers.end()) {
+            fprintf(out, "    -> received by %s, %s\n", receiverIt->second.first.c_str(),
+                    receiverIt->second.second.c_str());
+        }
         // TODO: Print the contents of the config too.
     }
 }
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
index 5b612cc..01d7fb9 100644
--- a/cmds/statsd/src/config/ConfigManager.h
+++ b/cmds/statsd/src/config/ConfigManager.h
@@ -68,6 +68,16 @@
     void SetConfigReceiver(const ConfigKey& key, const string& pkg, const string& cls);
 
     /**
+     * Returns the package name and class name representing the broadcast receiver for this config.
+     */
+    const pair<string, string> GetConfigReceiver(const ConfigKey& key);
+
+    /**
+     * Returns all config keys registered.
+     */
+    vector<ConfigKey> GetAllConfigKeys();
+
+    /**
      * Erase any broadcast receiver associated with this config key.
      */
     void RemoveConfigReceiver(const ConfigKey& key);
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index 74ba40b..bd288a1 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -121,7 +121,10 @@
     event.ToProto(*mProto);
     mProto->end(eventToken);
     mProto->end(wrapperToken);
-    // TODO: Find a proper way to derive the size of incoming LogEvent.
+
+    // TODO: Increment mByteSize with a real value. Until this feature is working, we assume 50
+    // bytes.
+    mByteSize += 50;
 }
 
 size_t EventMetricProducer::byteSize() {
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index c0930e3..c7982a8 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -61,12 +61,15 @@
 
     // TODO: Pass a timestamp as a parameter in onDumpReport and update all its
     // implementations.
+    // onDumpReport returns the proto-serialized output and clears the previously stored contents.
     virtual std::unique_ptr<std::vector<uint8_t>> onDumpReport() = 0;
 
     virtual bool isConditionSliced() const {
         return mConditionSliced;
     };
 
+    // Returns the memory in bytes currently used to store this metric's data. Does not change
+    // state.
     virtual size_t byteSize() = 0;
 
 protected:
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 39c79f9..fb16779 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -46,6 +46,8 @@
     // Config source owner can call onDumpReport() to get all the metrics collected.
     std::vector<std::unique_ptr<std::vector<uint8_t>>> onDumpReport();
 
+    // Computes the total byte size of all metrics managed by a single config source.
+    // Does not change the state.
     size_t byteSize();
 
 private:
diff --git a/location/Android.mk b/location/Android.mk
index feeb8ce..50509c6 100644
--- a/location/Android.mk
+++ b/location/Android.mk
@@ -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
diff --git a/location/tests/locationtests/Android.mk b/location/tests/locationtests/Android.mk
index 902cd96..73b2bb5 100644
--- a/location/tests/locationtests/Android.mk
+++ b/location/tests/locationtests/Android.mk
@@ -10,5 +10,13 @@
 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)
diff --git a/location/tests/locationtests/AndroidManifest.xml b/location/tests/locationtests/AndroidManifest.xml
index 1d9df0f..ddb8ea6 100644
--- a/location/tests/locationtests/AndroidManifest.xml
+++ b/location/tests/locationtests/AndroidManifest.xml
@@ -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.
@@ -23,13 +23,13 @@
     <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
index 0000000..0c5b7cc
--- /dev/null
+++ b/location/tests/locationtests/AndroidTest.xml
@@ -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
index 0000000..79ea0d6
--- /dev/null
+++ b/location/tests/locationtests/src/android/location/GnssStatusTest.java
@@ -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
index 316e88d..0000000
--- a/location/tests/locationtests/src/android/location/GpsStatusTest.java
+++ /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
index 0000000..b6453ef
--- /dev/null
+++ b/location/tests/locationtests/src/android/location/SatelliteInfo.java
@@ -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
