Only include chre_api_sensor.cc for SEE am: 1bac9db973
Original change: https://android-review.googlesource.com/c/platform/system/chre/+/1498208
Change-Id: I3786d557b93ac8d41e8d48af77a50fa54f184197
diff --git a/Android.mk b/Android.mk
index fa3a9c3..267c786 100644
--- a/Android.mk
+++ b/Android.mk
@@ -65,9 +65,9 @@
system/chre/platform/shared/include \
system/chre/platform/slpi/include \
system/chre/util/include \
- system/core/base/include \
+ system/libbase/include \
system/core/libcutils/include \
- system/core/liblog/include \
+ system/logging/liblog/include \
system/core/libutils/include \
LOCAL_SHARED_LIBRARIES := \
diff --git a/build/arch/x86.mk b/build/arch/x86.mk
index 695bd5a..0c5ce6b 100644
--- a/build/arch/x86.mk
+++ b/build/arch/x86.mk
@@ -9,7 +9,7 @@
containing a path to the Android source tree. This is typically \
provided by initializing the Android build environment.")
endif
-export X86_TOOLS_PREFIX=$(ANDROID_BUILD_TOP)/prebuilts/clang/host/linux-x86/clang-r370808/bin/
+export X86_TOOLS_PREFIX=$(ANDROID_BUILD_TOP)/prebuilts/clang/host/linux-x86/clang-r383902c/bin/
# x86 Tools ####################################################################
@@ -28,6 +28,9 @@
# Enable position independence.
TARGET_CFLAGS += -fpic
+# Disable double promotion warning for logging
+TARGET_CFLAGS += -Wno-double-promotion
+
# x86 Shared Object Linker Flags ###############################################
TARGET_SO_LDFLAGS += -shared
diff --git a/build/variant/google_x86_googletest.mk b/build/variant/google_x86_googletest.mk
index 3e6313b..eb48c7b 100644
--- a/build/variant/google_x86_googletest.mk
+++ b/build/variant/google_x86_googletest.mk
@@ -7,7 +7,14 @@
TARGET_NAME = google_x86_googletest
TARGET_CFLAGS = -DCHRE_MESSAGE_TO_HOST_MAX_SIZE=2048
TARGET_VARIANT_SRCS = $(GOOGLE_X86_GOOGLETEST_SRCS)
+TARGET_VARIANT_SRCS += $(GOOGLETEST_COMMON_SRCS)
+
+ifeq ($(RUN_PAL_IMPL_TESTS), true)
+TARGET_VARIANT_SRCS += $(GOOGLETEST_PAL_IMPL_SRCS)
+else
TARGET_VARIANT_SRCS += $(GOOGLETEST_SRCS)
+endif
+
TARGET_PLATFORM_ID = 0x476f6f676c000001
TARGET_CFLAGS += $(SIM_CFLAGS)
diff --git a/java/test/settings/src/com/google/android/chre/test/setting/ContextHubWifiSettingsTestExecutor.java b/java/test/settings/src/com/google/android/chre/test/setting/ContextHubWifiSettingsTestExecutor.java
index ae3a09b..50d740d 100644
--- a/java/test/settings/src/com/google/android/chre/test/setting/ContextHubWifiSettingsTestExecutor.java
+++ b/java/test/settings/src/com/google/android/chre/test/setting/ContextHubWifiSettingsTestExecutor.java
@@ -22,6 +22,7 @@
import android.content.IntentFilter;
import android.hardware.location.NanoAppBinary;
import android.net.wifi.WifiManager;
+import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -37,6 +38,7 @@
* A test to check for behavior when WiFi settings are changed.
*/
public class ContextHubWifiSettingsTestExecutor {
+ private static final String TAG = "ContextHubWifiSettingsTestExecutor";
private final ContextHubSettingsTestExecutor mExecutor;
private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -87,6 +89,9 @@
mInitialLocationEnabled = mSettingsUtil.isLocationEnabled();
mInitialWifiEnabled = mSettingsUtil.isWifiEnabled();
mInitialWifiScanningAlwaysEnabled = mSettingsUtil.isWifiScanningAlwaysEnabled();
+ Log.d(TAG, "isLocationEnalbed=" + mInitialLocationEnabled
+ + ", isWifiEnabled=" + mInitialWifiEnabled
+ + ", isWifiScanningAlwaysEnabled=" + mInitialWifiScanningAlwaysEnabled);
mExecutor.init();
}
@@ -127,7 +132,7 @@
wifiUpdateListener.mWifiLatch.await(30, TimeUnit.SECONDS);
// Wait a few seconds to ensure setting is propagated to CHRE path
- Thread.sleep(5000);
+ Thread.sleep(10000);
} catch (InterruptedException e) {
Assert.fail(e.getMessage());
}
diff --git a/pal/pal.mk b/pal/pal.mk
index 0c92ecf..bf4dd46 100644
--- a/pal/pal.mk
+++ b/pal/pal.mk
@@ -9,5 +9,8 @@
# GoogleTest Source Files ######################################################
-GOOGLETEST_SRCS += pal/tests/version_test.cc
-GOOGLETEST_SRCS += pal/tests/wwan_test.cc
+GOOGLETEST_CFLAGS += -Ipal/tests/include
+GOOGLETEST_SRCS += pal/tests/src/version_test.cc
+GOOGLETEST_SRCS += pal/tests/src/wwan_test.cc
+GOOGLETEST_PAL_IMPL_SRCS += pal/tests/src/gnss_pal_impl_test.cc
+GOOGLETEST_PAL_IMPL_SRCS += pal/tests/src/wifi_pal_impl_test.cc
diff --git a/pal/tests/include/gnss_pal_impl_test.h b/pal/tests/include/gnss_pal_impl_test.h
new file mode 100644
index 0000000..b69e960
--- /dev/null
+++ b/pal/tests/include/gnss_pal_impl_test.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef GNSSPAL_IMPL_TEST_H_
+#define GNSSPAL_IMPL_TEST_H_
+
+#include "chre/pal/gnss.h"
+#include "chre/platform/condition_variable.h"
+#include "chre/platform/mutex.h"
+#include "chre/util/fixed_size_vector.h"
+#include "chre/util/time.h"
+#include "gtest/gtest.h"
+
+namespace gnss_pal_impl_test {
+
+class PalGnssTest : public ::testing::Test {
+ public:
+ /**
+ * Implements CHRE PAL API callbacks
+ */
+ void requestStateResync();
+ void locationStatusChangeCallback(bool enabled, uint8_t errorCode);
+ void locationEventCallback(struct chreGnssLocationEvent *event);
+ void measurementStatusChangeCallback(bool enabled, uint8_t errorCode);
+ void measurementEventCallback(struct chreGnssDataEvent *event);
+
+ protected:
+ void SetUp() override;
+
+ void TearDown() override;
+
+ /**
+ * Prepares for a subsequent PAL API call that expects an async response.
+ */
+ void prepareForAsyncResponse() {
+ errorCode_ = CHRE_ERROR_LAST;
+ }
+
+ /**
+ * Waits for an async response by the PAL implementation (e.g. via location
+ * or measurement status change callback), and asserts that a success
+ * error code was received.
+ */
+ void waitForAsyncResponseAssertSuccess(chre::Nanoseconds timeoutNs);
+
+ //! The pointer to the CHRE PAL implementation API
+ const struct chrePalGnssApi *api_;
+
+ //! The error code of the most recent callback
+ uint8_t errorCode_ = CHRE_ERROR_LAST;
+
+ //! True if location session is currently enabled
+ bool locationSessionEnabled_ = false;
+
+ //! True if location session is currently enabled
+ bool measurementSessionEnabled_ = false;
+
+ //! A list to store the location events
+ static constexpr size_t kEventArraySize = 5;
+ chre::FixedSizeVector<chreGnssLocationEvent *, kEventArraySize>
+ locationEventVector_;
+ chre::FixedSizeVector<chreGnssDataEvent *, kEventArraySize>
+ measurementEventVector_;
+
+ //! Mutex to protect class variables
+ chre::Mutex mutex_;
+ chre::ConditionVariable condVar_;
+};
+
+} // namespace gnss_pal_impl_test
+
+#endif // GNSSPAL_IMPL_TEST_H_
diff --git a/pal/tests/include/wifi_pal_impl_test.h b/pal/tests/include/wifi_pal_impl_test.h
new file mode 100644
index 0000000..2188ea6
--- /dev/null
+++ b/pal/tests/include/wifi_pal_impl_test.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef WIFI_PAL_IMPL_TEST_H_
+#define WIFI_PAL_IMPL_TEST_H_
+
+#include "chre/pal/wifi.h"
+#include "chre/platform/condition_variable.h"
+#include "chre/platform/mutex.h"
+#include "chre/util/dynamic_vector.h"
+#include "chre/util/optional.h"
+#include "chre/util/time.h"
+#include "gtest/gtest.h"
+
+namespace wifi_pal_impl_test {
+
+class PalWifiTest : public ::testing::Test {
+ public:
+ /**
+ * Implements CHRE PAL API callbacks
+ */
+ void scanMonitorStatusChangeCallback(bool enabled, uint8_t errorCode);
+ void scanResponseCallback(bool pending, uint8_t errorCode);
+ void scanEventCallback(struct chreWifiScanEvent *event);
+ void rangingEventCallback(uint8_t errorCode,
+ struct chreWifiRangingEvent *event);
+
+ protected:
+ void SetUp() override;
+
+ void TearDown() override;
+
+ /**
+ * Validates an incoming WiFi scan event.
+ *
+ * @param event The WiFi scan event.
+ */
+ void validateWifiScanEvent(const chreWifiScanEvent &event);
+
+ /**
+ * Prepares for a subsequent PAL API call that expects an async response.
+ */
+ void prepareForAsyncResponse() {
+ errorCode_ = CHRE_ERROR_LAST;
+ }
+
+ /**
+ * Waits for an async response by the PAL implementation (e.g. via scan
+ * response/monitor status change callback), and asserts that a success
+ * error code was received.
+ */
+ void waitForAsyncResponseAssertSuccess(chre::Nanoseconds timeoutNs);
+
+ //! The pointer to the CHRE PAL implementation API
+ const struct chrePalWifiApi *api_;
+
+ //! The error code of the most recent callback
+ uint8_t errorCode_ = CHRE_ERROR_LAST;
+
+ //! The number of scan events currently stored
+ uint32_t numScanResultCount_ = 0;
+
+ //! True if the last scan event has been received
+ bool lastScanEventReceived_ = false;
+
+ //! A list to store the scan results
+ chre::DynamicVector<chreWifiScanEvent *> scanEventList_;
+
+ //! Stores active scan params
+ chre::Optional<chreWifiScanParams> scanParams_;
+
+ //! The last scan event index received, UINT8_MAX if invalid
+ uint8_t lastEventIndex_;
+
+ //! True if scan monitoring is currently enabled
+ bool scanMonitorEnabled_ = false;
+
+ //! Mutex to protect class variables
+ chre::Mutex mutex_;
+ chre::ConditionVariable condVar_;
+};
+
+} // namespace wifi_pal_impl_test
+
+#endif // WIFI_PAL_IMPL_TEST_H_
diff --git a/pal/tests/src/gnss_pal_impl_test.cc b/pal/tests/src/gnss_pal_impl_test.cc
new file mode 100644
index 0000000..bbb92e9
--- /dev/null
+++ b/pal/tests/src/gnss_pal_impl_test.cc
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "gnss_pal_impl_test.h"
+
+#include "chre/platform/log.h"
+#include "chre/platform/shared/pal_system_api.h"
+#include "chre/platform/system_time.h"
+#include "chre/util/lock_guard.h"
+
+#include <cinttypes>
+
+//! Flag to require GNSS location sessions capability to be enabled for the test
+//! to pass. Set to false to allow tests to pass on disabled platforms.
+//! Note that it is required to run this test where location can be acquired.
+//! The constants kGnssEventTimeoutNs and kEventArraySize may be tuned if
+//! applicable.
+#ifndef PAL_IMPL_TEST_GNSS_LOCATION_REQUIRED
+#define PAL_IMPL_TEST_GNSS_LOCATION_REQUIRED true
+#endif
+
+//! Same as above for GNSS measurement sessions.
+#ifndef PAL_IMPL_TEST_GNSS_MEASUREMENTS_REQUIRED
+#define PAL_IMPL_TEST_GNSS_MEASUREMENTS_REQUIRED true
+#endif
+
+namespace gnss_pal_impl_test {
+
+namespace {
+
+using ::chre::Nanoseconds;
+using ::chre::Seconds;
+using ::chre::SystemTime;
+
+//! A pointer to the current test running
+gnss_pal_impl_test::PalGnssTest *gTest = nullptr;
+
+//! Timeout as specified by the CHRE API
+const Nanoseconds kGnssAsyncResultTimeoutNs =
+ Nanoseconds(CHRE_GNSS_ASYNC_RESULT_TIMEOUT_NS);
+
+//! Timeout to wait for kEventArraySize events.
+const Nanoseconds kGnssEventTimeoutNs = Seconds(60);
+
+void chrePalRequestStateResync() {
+ if (gTest != nullptr) {
+ gTest->requestStateResync();
+ }
+}
+
+void chrePalLocationStatusChangeCallback(bool enabled, uint8_t errorCode) {
+ if (gTest != nullptr) {
+ gTest->locationStatusChangeCallback(enabled, errorCode);
+ }
+}
+
+void chrePalLocationEventCallback(struct chreGnssLocationEvent *event) {
+ if (gTest != nullptr) {
+ gTest->locationEventCallback(event);
+ }
+}
+
+void chrePalMeasurementStatusChangeCallback(bool enabled, uint8_t errorCode) {
+ if (gTest != nullptr) {
+ gTest->measurementStatusChangeCallback(enabled, errorCode);
+ }
+}
+
+void chrePalMeasurementEventCallback(struct chreGnssDataEvent *event) {
+ if (gTest != nullptr) {
+ gTest->measurementEventCallback(event);
+ }
+}
+
+void logLocationEvent(const struct chreGnssLocationEvent &event) {
+ LOGI("Received location: %" PRId32 ", %" PRId32, event.latitude_deg_e7,
+ event.longitude_deg_e7);
+ LOGI(" timestamp (ms): %" PRIu64, event.timestamp);
+ LOGI(" altitude (m): %f", event.altitude);
+ LOGI(" speed (m/s): %f", event.speed);
+ LOGI(" bearing (deg): %f", event.bearing);
+ LOGI(" accuracy: %f", event.accuracy);
+ LOGI(" flags: 0x%" PRIx16, event.flags);
+ LOGI(" altitude_accuracy: %f", event.altitude_accuracy);
+ LOGI(" speed_accuracy: %f", event.speed_accuracy);
+ LOGI(" bearing_accuracy: %f", event.bearing_accuracy);
+}
+
+void validateLocationEvent(const struct chreGnssLocationEvent &event) {
+ static uint64_t sLastTimestampNs = 0;
+ EXPECT_GE(event.timestamp, sLastTimestampNs);
+ sLastTimestampNs = event.timestamp;
+ if (event.flags & CHRE_GPS_LOCATION_HAS_LAT_LONG) {
+ EXPECT_GE(event.latitude_deg_e7, -90 * 1e7);
+ EXPECT_LE(event.latitude_deg_e7, 90 * 1e7);
+ EXPECT_GE(event.longitude_deg_e7, -180 * 1e7);
+ EXPECT_LE(event.longitude_deg_e7, 180 * 1e7);
+ }
+ if (event.flags & CHRE_GPS_LOCATION_HAS_BEARING) {
+ EXPECT_GE(event.bearing, 0);
+ EXPECT_LT(event.bearing, 360); // [0, 360) per API
+ }
+}
+
+void logMeasurementEvent(const struct chreGnssDataEvent &event) {
+ LOGI("Received data: %" PRIu8 " measurements", event.measurement_count);
+
+ for (uint8_t i = 0; i < event.measurement_count; i++) {
+ LOGI("%" PRIu8 ": const %" PRIu8 ", cn0 %.2f, freq %.3f MHz", i,
+ event.measurements[i].constellation, event.measurements[i].c_n0_dbhz,
+ event.measurements[i].carrier_frequency_hz / 1e6);
+ }
+}
+
+void validateMeasurementEvent(const struct chreGnssDataEvent &event) {
+ EXPECT_GE(event.measurement_count, 0);
+ EXPECT_LE(event.measurement_count, CHRE_GNSS_MAX_MEASUREMENT);
+ if (event.measurement_count > 0) {
+ EXPECT_NE(event.measurements, nullptr);
+ }
+
+ static int64_t sLastClockTimeNs = INT64_MIN;
+ EXPECT_GE(event.clock.time_ns, sLastClockTimeNs);
+ sLastClockTimeNs = event.clock.time_ns;
+
+ for (uint8_t i = 0; i < event.measurement_count; i++) {
+ EXPECT_GE(event.measurements[i].c_n0_dbhz, 0);
+ EXPECT_LE(event.measurements[i].c_n0_dbhz, 63);
+ }
+}
+
+} // anonymous namespace
+
+void PalGnssTest::SetUp() {
+ api_ = chrePalGnssGetApi(CHRE_PAL_GNSS_API_CURRENT_VERSION);
+ ASSERT_NE(api_, nullptr);
+ EXPECT_EQ(api_->moduleVersion, CHRE_PAL_GNSS_API_CURRENT_VERSION);
+
+ // Open the PAL API
+ static const struct chrePalGnssCallbacks kCallbacks = {
+ .requestStateResync = chrePalRequestStateResync,
+ .locationStatusChangeCallback = chrePalLocationStatusChangeCallback,
+ .locationEventCallback = chrePalLocationEventCallback,
+ .measurementStatusChangeCallback = chrePalMeasurementStatusChangeCallback,
+ .measurementEventCallback = chrePalMeasurementEventCallback,
+ };
+ ASSERT_TRUE(api_->open(&chre::gChrePalSystemApi, &kCallbacks));
+ gTest = this;
+
+ errorCode_ = CHRE_ERROR_LAST;
+ locationSessionEnabled_ = false;
+ locationEventVector_.resize(0);
+ measurementSessionEnabled_ = false;
+ measurementEventVector_.resize(0);
+}
+
+void PalGnssTest::TearDown() {
+ gTest = nullptr;
+ api_->close();
+}
+
+void PalGnssTest::requestStateResync() {
+ // TODO:
+}
+
+void PalGnssTest::locationStatusChangeCallback(bool enabled,
+ uint8_t errorCode) {
+ LOGI("Received location status change with enabled %d error %" PRIu8, enabled,
+ errorCode);
+ if (errorCode == CHRE_ERROR_LAST) {
+ LOGE("Received CHRE_ERROR_LAST");
+ errorCode = CHRE_ERROR;
+ }
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+ errorCode_ = errorCode;
+ locationSessionEnabled_ = enabled;
+ condVar_.notify_one();
+}
+
+void PalGnssTest::locationEventCallback(struct chreGnssLocationEvent *event) {
+ LOGI("Received location event");
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+ if (!locationEventVector_.full()) {
+ locationEventVector_.push_back(event);
+ if (locationEventVector_.full()) {
+ condVar_.notify_one();
+ }
+ }
+}
+
+void PalGnssTest::measurementStatusChangeCallback(bool enabled,
+ uint8_t errorCode) {
+ LOGI("Received measurement status change with enabled %d error %" PRIu8,
+ enabled, errorCode);
+ if (errorCode == CHRE_ERROR_LAST) {
+ LOGE("Received CHRE_ERROR_LAST");
+ errorCode = CHRE_ERROR;
+ }
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+ errorCode_ = errorCode;
+ measurementSessionEnabled_ = enabled;
+ condVar_.notify_one();
+}
+
+void PalGnssTest::measurementEventCallback(struct chreGnssDataEvent *event) {
+ LOGI("Received measurement event");
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+ if (!measurementEventVector_.full()) {
+ measurementEventVector_.push_back(event);
+ if (measurementEventVector_.full()) {
+ condVar_.notify_one();
+ }
+ }
+}
+
+void PalGnssTest::waitForAsyncResponseAssertSuccess(
+ chre::Nanoseconds timeoutNs) {
+ bool waitSuccess = true;
+ while (errorCode_ == CHRE_ERROR_LAST && waitSuccess) {
+ waitSuccess = condVar_.wait_for(mutex_, timeoutNs);
+ }
+ ASSERT_TRUE(waitSuccess);
+ ASSERT_EQ(errorCode_, CHRE_ERROR_NONE);
+}
+
+TEST_F(PalGnssTest, LocationSessionTest) {
+ bool hasLocationCapability =
+ ((api_->getCapabilities() & CHRE_GNSS_CAPABILITIES_LOCATION) ==
+ CHRE_GNSS_CAPABILITIES_LOCATION);
+#if PAL_IMPL_TEST_GNSS_LOCATION_REQUIRED
+ ASSERT_TRUE(hasLocationCapability);
+#else
+ if (!hasLocationCapability) {
+ GTEST_SKIP();
+ }
+#endif
+
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+
+ prepareForAsyncResponse();
+ ASSERT_TRUE(api_->controlLocationSession(
+ true /* enable */, 1000 /* minIntervalMs */, 0 /* minTimeToNextFixMs */));
+ waitForAsyncResponseAssertSuccess(kGnssAsyncResultTimeoutNs);
+ ASSERT_TRUE(locationSessionEnabled_);
+
+ bool waitSuccess = true;
+ while (!locationEventVector_.full() && waitSuccess) {
+ waitSuccess = condVar_.wait_for(mutex_, kGnssEventTimeoutNs);
+ }
+
+ for (size_t i = 0; i < locationEventVector_.size(); i++) {
+ logLocationEvent(*locationEventVector_[i]);
+ validateLocationEvent(*locationEventVector_[i]);
+ api_->releaseLocationEvent(locationEventVector_[i]);
+ }
+ EXPECT_TRUE(locationEventVector_.full());
+
+ prepareForAsyncResponse();
+ ASSERT_TRUE(api_->controlLocationSession(
+ false /* enable */, 0 /* minIntervalMs */, 0 /* minTimeToNextFixMs */));
+ waitForAsyncResponseAssertSuccess(kGnssAsyncResultTimeoutNs);
+ ASSERT_FALSE(locationSessionEnabled_);
+}
+
+TEST_F(PalGnssTest, MeasurementSessionTest) {
+ bool hasMeasurementCapability =
+ ((api_->getCapabilities() & CHRE_GNSS_CAPABILITIES_MEASUREMENTS) ==
+ CHRE_GNSS_CAPABILITIES_MEASUREMENTS);
+#if PAL_IMPL_TEST_GNSS_MEAUSUREMENT_REQUIRED
+ ASSERT_TRUE(hasMeasurementCapability);
+#else
+ if (!hasMeasurementCapability) {
+ GTEST_SKIP();
+ }
+#endif
+
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+
+ prepareForAsyncResponse();
+ ASSERT_TRUE(api_->controlMeasurementSession(true /* enable */,
+ 1000 /* minIntervalMs */));
+ waitForAsyncResponseAssertSuccess(kGnssAsyncResultTimeoutNs);
+ ASSERT_TRUE(measurementSessionEnabled_);
+
+ bool waitSuccess = true;
+ while (!measurementEventVector_.full() && waitSuccess) {
+ waitSuccess = condVar_.wait_for(mutex_, kGnssEventTimeoutNs);
+ }
+ EXPECT_TRUE(measurementEventVector_.full());
+
+ for (size_t i = 0; i < measurementEventVector_.size(); i++) {
+ logMeasurementEvent(*measurementEventVector_[i]);
+ validateMeasurementEvent(*measurementEventVector_[i]);
+ api_->releaseMeasurementDataEvent(measurementEventVector_[i]);
+ }
+
+ prepareForAsyncResponse();
+ ASSERT_TRUE(api_->controlMeasurementSession(false /* enable */,
+ 0 /* minIntervalMs */));
+ waitForAsyncResponseAssertSuccess(kGnssAsyncResultTimeoutNs);
+ ASSERT_FALSE(measurementSessionEnabled_);
+}
+
+} // namespace gnss_pal_impl_test
diff --git a/pal/tests/version_test.cc b/pal/tests/src/version_test.cc
similarity index 100%
rename from pal/tests/version_test.cc
rename to pal/tests/src/version_test.cc
diff --git a/pal/tests/src/wifi_pal_impl_test.cc b/pal/tests/src/wifi_pal_impl_test.cc
new file mode 100644
index 0000000..a266a6b
--- /dev/null
+++ b/pal/tests/src/wifi_pal_impl_test.cc
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "wifi_pal_impl_test.h"
+
+#include "chre/platform/log.h"
+#include "chre/platform/shared/pal_system_api.h"
+#include "chre/platform/system_time.h"
+#include "chre/util/lock_guard.h"
+#include "chre/util/nanoapp/wifi.h"
+
+#include <cinttypes>
+
+// Flag to require on-demand WiFi scanning capability to be enabled for the test
+// to pass. Set to false to allow tests to pass on disabled platforms.
+#ifndef PAL_IMPL_TEST_WIFI_ON_DEMAND_SCAN_REQUIRED
+#define PAL_IMPL_TEST_WIFI_ON_DEMAND_SCAN_REQUIRED true
+#endif
+
+// Same as above for scan monitoring.
+#ifndef PAL_IMPL_TEST_WIFI_SCAN_MONITORING_REQUIRED
+#define PAL_IMPL_TEST_WIFI_SCAN_MONITORING_REQUIRED true
+#endif
+
+namespace wifi_pal_impl_test {
+
+namespace {
+
+using ::chre::Nanoseconds;
+using ::chre::Seconds;
+using ::chre::SystemTime;
+
+//! A pointer to the current test running
+wifi_pal_impl_test::PalWifiTest *gTest = nullptr;
+
+//! Timeout as specified by the CHRE API
+const Nanoseconds kAsyncResultTimeoutNs =
+ Nanoseconds(CHRE_ASYNC_RESULT_TIMEOUT_NS);
+const Nanoseconds kScanResultTimeoutNs =
+ Nanoseconds(CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS);
+
+void chrePalScanMonitorStatusChangeCallback(bool enabled, uint8_t errorCode) {
+ if (gTest != nullptr) {
+ gTest->scanMonitorStatusChangeCallback(enabled, errorCode);
+ }
+}
+
+void chrePalScanResponseCallback(bool pending, uint8_t errorCode) {
+ if (gTest != nullptr) {
+ gTest->scanResponseCallback(pending, errorCode);
+ }
+}
+
+void chrePalScanEventCallback(struct chreWifiScanEvent *event) {
+ if (gTest != nullptr) {
+ gTest->scanEventCallback(event);
+ }
+}
+
+void chrePalRangingEventCallback(uint8_t errorCode,
+ struct chreWifiRangingEvent *event) {
+ if (gTest != nullptr) {
+ gTest->rangingEventCallback(errorCode, event);
+ }
+}
+
+void logChreWifiResult(const chreWifiScanResult &result) {
+ const char *ssidStr = "<non-printable>";
+ char ssidBuffer[chre::kMaxSsidStrLen];
+ if (result.ssidLen == 0) {
+ ssidStr = "<empty>";
+ } else if (chre::parseSsidToStr(ssidBuffer, sizeof(ssidBuffer), result.ssid,
+ result.ssidLen)) {
+ ssidStr = ssidBuffer;
+ }
+
+ LOGI("Found network with SSID: %s", ssidStr);
+ const char *bssidStr = "<non-printable>";
+ char bssidBuffer[chre::kBssidStrLen];
+ if (chre::parseBssidToStr(result.bssid, bssidBuffer, sizeof(bssidBuffer))) {
+ bssidStr = bssidBuffer;
+ }
+
+ LOGI(" age (ms): %" PRIu32, result.ageMs);
+ LOGI(" capability info: 0x%" PRIx16, result.capabilityInfo);
+ LOGI(" bssid: %s", bssidStr);
+ LOGI(" flags: 0x%" PRIx8, result.flags);
+ LOGI(" rssi: %" PRId8 "dBm", result.rssi);
+ LOGI(" band: %s (%" PRIu8 ")", chre::parseChreWifiBand(result.band),
+ result.band);
+ LOGI(" primary channel: %" PRIu32, result.primaryChannel);
+ LOGI(" center frequency primary: %" PRIu32, result.centerFreqPrimary);
+ LOGI(" center frequency secondary: %" PRIu32, result.centerFreqSecondary);
+ LOGI(" channel width: %" PRIu8, result.channelWidth);
+ LOGI(" security mode: 0x%" PRIx8, result.securityMode);
+}
+
+} // anonymous namespace
+
+void PalWifiTest::SetUp() {
+ api_ = chrePalWifiGetApi(CHRE_PAL_WIFI_API_CURRENT_VERSION);
+ ASSERT_NE(api_, nullptr);
+ EXPECT_EQ(api_->moduleVersion, CHRE_PAL_WIFI_API_CURRENT_VERSION);
+
+ // Open the PAL API
+ static const struct chrePalWifiCallbacks kCallbacks = {
+ .scanMonitorStatusChangeCallback = chrePalScanMonitorStatusChangeCallback,
+ .scanResponseCallback = chrePalScanResponseCallback,
+ .scanEventCallback = chrePalScanEventCallback,
+ .rangingEventCallback = chrePalRangingEventCallback,
+ };
+ ASSERT_TRUE(api_->open(&chre::gChrePalSystemApi, &kCallbacks));
+ gTest = this;
+
+ errorCode_ = CHRE_ERROR_LAST;
+ numScanResultCount_ = 0;
+ lastScanEventReceived_ = false;
+ scanEventList_.clear();
+ scanParams_.reset();
+ lastEventIndex_ = UINT8_MAX;
+ scanMonitorEnabled_ = false;
+}
+
+void PalWifiTest::TearDown() {
+ gTest = nullptr;
+ api_->close();
+}
+
+void PalWifiTest::scanMonitorStatusChangeCallback(bool enabled,
+ uint8_t errorCode) {
+ LOGI("Received scan monitor response with enabled %d error %" PRIu8, enabled,
+ errorCode);
+ if (errorCode == CHRE_ERROR_LAST) {
+ LOGE("Received CHRE_ERROR_LAST");
+ errorCode = CHRE_ERROR;
+ }
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+ scanMonitorEnabled_ = enabled;
+ errorCode_ = errorCode;
+ condVar_.notify_one();
+}
+
+void PalWifiTest::scanResponseCallback(bool pending, uint8_t errorCode) {
+ LOGI("Received scan response with pending %d error %" PRIu8, pending,
+ errorCode);
+ if (errorCode == CHRE_ERROR_LAST) {
+ LOGE("Received CHRE_ERROR_LAST");
+ errorCode = CHRE_ERROR;
+ }
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+ errorCode_ = errorCode;
+ condVar_.notify_one();
+}
+
+void PalWifiTest::scanEventCallback(struct chreWifiScanEvent *event) {
+ if (event == nullptr) {
+ LOGE("Got null scan event");
+ } else {
+ {
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+ scanEventList_.push_back(event);
+ numScanResultCount_ += event->resultCount;
+ lastScanEventReceived_ = (numScanResultCount_ == event->resultTotal);
+ }
+
+ condVar_.notify_one();
+ }
+}
+
+void PalWifiTest::rangingEventCallback(uint8_t errorCode,
+ struct chreWifiRangingEvent *event) {
+ // TODO:
+}
+
+void PalWifiTest::validateWifiScanEvent(const chreWifiScanEvent &event) {
+ if (scanParams_.has_value()) {
+ EXPECT_EQ(event.scanType, scanParams_->scanType);
+ EXPECT_GE(event.referenceTime,
+ chreGetTime() - (scanParams_->maxScanAgeMs *
+ chre::kOneMillisecondInNanoseconds));
+ EXPECT_EQ(event.radioChainPref, scanParams_->radioChainPref);
+ EXPECT_EQ(event.eventIndex, static_cast<uint8_t>(lastEventIndex_ + 1));
+ }
+}
+
+void PalWifiTest::waitForAsyncResponseAssertSuccess(
+ chre::Nanoseconds timeoutNs) {
+ bool waitSuccess = true;
+ while (errorCode_ == CHRE_ERROR_LAST && waitSuccess) {
+ waitSuccess = condVar_.wait_for(mutex_, timeoutNs);
+ }
+ ASSERT_TRUE(waitSuccess);
+ ASSERT_EQ(errorCode_, CHRE_ERROR_NONE);
+}
+
+TEST_F(PalWifiTest, ScanAsyncTest) {
+ bool hasOnDemandScanCapability =
+ (api_->getCapabilities() & CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN) ==
+ CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN;
+#if PAL_IMPL_TEST_WIFI_ON_DEMAND_SCAN_REQUIRED
+ ASSERT_TRUE(hasOnDemandScanCapability);
+#else
+ if (!hasOnDemandScanCapability) {
+ GTEST_SKIP();
+ }
+#endif
+
+ // Request a WiFi scan
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+
+ struct chreWifiScanParams params = {};
+ params.scanType = CHRE_WIFI_SCAN_TYPE_ACTIVE;
+ params.maxScanAgeMs = 5000; // 5 seconds
+ params.frequencyListLen = 0;
+ params.ssidListLen = 0;
+ params.radioChainPref = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT;
+ scanParams_ = params;
+
+ prepareForAsyncResponse();
+ ASSERT_TRUE(api_->requestScan(&scanParams_.value()));
+ waitForAsyncResponseAssertSuccess(kScanResultTimeoutNs);
+
+ // The CHRE API only poses timeout requirements on the async response. Use
+ // the same timeout to receive the scan results to avoid blocking forever.
+ bool waitSuccess = true;
+ while (!lastScanEventReceived_ && waitSuccess) {
+ waitSuccess = condVar_.wait_for(mutex_, kScanResultTimeoutNs);
+ }
+
+ for (auto *event : scanEventList_) {
+ for (uint8_t i = 0; i < event->resultCount; i++) {
+ const chreWifiScanResult &result = event->results[i];
+ logChreWifiResult(result);
+ }
+ validateWifiScanEvent(*event);
+
+ lastEventIndex_ = event->eventIndex;
+ api_->releaseScanEvent(event);
+ }
+
+ EXPECT_TRUE(lastScanEventReceived_);
+ EXPECT_GT(numScanResultCount_, 0);
+}
+
+// Note: This test only verifies that the scan monitor succeeds according
+// to the async response.
+TEST_F(PalWifiTest, ScanMonitorTest) {
+ bool hasScanMonitoringCapability =
+ (api_->getCapabilities() & CHRE_WIFI_CAPABILITIES_SCAN_MONITORING) ==
+ CHRE_WIFI_CAPABILITIES_SCAN_MONITORING;
+#if PAL_IMPL_TEST_WIFI_SCAN_MONITORING_REQUIRED
+ ASSERT_TRUE(hasScanMonitoringCapability);
+#else
+ if (!hasScanMonitoringCapability) {
+ GTEST_SKIP();
+ }
+#endif
+
+ chre::LockGuard<chre::Mutex> lock(mutex_);
+
+ prepareForAsyncResponse();
+ ASSERT_TRUE(api_->configureScanMonitor(true /* enable */));
+ waitForAsyncResponseAssertSuccess(kAsyncResultTimeoutNs);
+ ASSERT_TRUE(scanMonitorEnabled_);
+
+ prepareForAsyncResponse();
+ ASSERT_TRUE(api_->configureScanMonitor(false /* enable */));
+ waitForAsyncResponseAssertSuccess(kAsyncResultTimeoutNs);
+ ASSERT_FALSE(scanMonitorEnabled_);
+}
+
+} // namespace wifi_pal_impl_test
diff --git a/pal/tests/wwan_test.cc b/pal/tests/src/wwan_test.cc
similarity index 100%
rename from pal/tests/wwan_test.cc
rename to pal/tests/src/wwan_test.cc
diff --git a/platform/platform.mk b/platform/platform.mk
index 2ce2891..fa469c1 100644
--- a/platform/platform.mk
+++ b/platform/platform.mk
@@ -245,10 +245,10 @@
# Add in host sources to allow the executable to both be a socket server and
# CHRE implementation.
-GOOGLE_ARM64_ANDROID_CFLAGS += -I$(ANDROID_BUILD_TOP)/system/core/base/include
+GOOGLE_ARM64_ANDROID_CFLAGS += -I$(ANDROID_BUILD_TOP)/system/libbase/include
GOOGLE_ARM64_ANDROID_CFLAGS += -I$(ANDROID_BUILD_TOP)/system/core/libcutils/include
GOOGLE_ARM64_ANDROID_CFLAGS += -I$(ANDROID_BUILD_TOP)/system/core/libutils/include
-GOOGLE_ARM64_ANDROID_CFLAGS += -I$(ANDROID_BUILD_TOP)/system/core/liblog/include
+GOOGLE_ARM64_ANDROID_CFLAGS += -I$(ANDROID_BUILD_TOP)/system/logging/liblog/include
GOOGLE_ARM64_ANDROID_CFLAGS += -Ihost/common/include
# Also add the linux sources to fall back to the default Linux implementation.
@@ -260,7 +260,7 @@
# Android-specific Source Files ################################################
ANDROID_CUTILS_TOP = $(ANDROID_BUILD_TOP)/system/core/libcutils
-ANDROID_LOG_TOP = $(ANDROID_BUILD_TOP)/system/core/liblog
+ANDROID_LOG_TOP = $(ANDROID_BUILD_TOP)/system/logging/liblog
GOOGLE_ARM64_ANDROID_SRCS += $(ANDROID_CUTILS_TOP)/sockets_unix.cpp
GOOGLE_ARM64_ANDROID_SRCS += $(ANDROID_CUTILS_TOP)/android_get_control_file.cpp
@@ -289,6 +289,6 @@
# GoogleTest Source Files ######################################################
-GOOGLETEST_SRCS += platform/linux/assert.cc
-GOOGLETEST_SRCS += platform/linux/audio_source.cc
-GOOGLETEST_SRCS += platform/linux/platform_audio.cc
+GOOGLETEST_COMMON_SRCS += platform/linux/assert.cc
+GOOGLETEST_COMMON_SRCS += platform/linux/audio_source.cc
+GOOGLETEST_COMMON_SRCS += platform/linux/platform_audio.cc
diff --git a/run_pal_impl_tests.sh b/run_pal_impl_tests.sh
new file mode 100755
index 0000000..4b0daed
--- /dev/null
+++ b/run_pal_impl_tests.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# Quit if any command produces an error.
+set -e
+
+# Build and run the CHRE unit test binary.
+JOB_COUNT=$((`grep -c ^processor /proc/cpuinfo`))
+
+# Export the variant Makefile.
+export CHRE_VARIANT_MK_INCLUDES="$CHRE_VARIANT_MK_INCLUDES \
+ variant/googletest/variant.mk"
+
+export RUN_PAL_IMPL_TESTS=true
+
+make clean
+make google_x86_googletest_debug -j$JOB_COUNT
+./out/google_x86_googletest_debug/libchre $1