Merge "Implement NNAPI canonical interfaces"
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 590adc5..8d1693a 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -32,7 +32,7 @@
defaults: ["vhal_v2_0_defaults"],
shared_libs: [
"libbinder_ndk",
- "carwatchdog_aidl_interface-ndk_platform",
+ "android.automotive.watchdog-ndk_platform",
],
}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 80a1831..5ecce46 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -417,7 +417,7 @@
.minSampleRate = 1.0f,
.maxSampleRate = 2.0f,
},
- .initialValue = {.floatValues = {100.0f}}}, // units in meters
+ .initialValue = {.floatValues = {50000.0f}}}, // units in meters
{.config =
{
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
index 9f977f5..365ae58 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
@@ -21,4 +21,9 @@
android.hardware.biometrics.common.CommonProps commonProps;
android.hardware.biometrics.face.FaceSensorType sensorType;
boolean halControlsPreview;
+ int enrollPreviewWidth;
+ int enrollPreviewHeight;
+ float enrollTranslationX;
+ float enrollTranslationY;
+ float enrollPreviewScale;
}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
index 53cc44e..9c2f9a1 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
@@ -39,5 +39,36 @@
* the framework.
*/
boolean halControlsPreview;
+
+ /**
+ * For implementations where the HAL manages the preview, this is the width, in pixels, of each
+ * frame that the camera is set up to output.
+ */
+ int enrollPreviewWidth;
+
+ /**
+ * For implementations where the HAL manages the preview, this is the height, in pixels, of
+ * each frame that the camera is set up to output.
+ */
+ int enrollPreviewHeight;
+
+ /**
+ * For implementations where the HAL manages the preview, this is the distance in pixels that
+ * the enrollment preview should be translated. This is typically used by devices where the
+ * camera used for enrollment preview is not centered.
+ */
+ float enrollTranslationX;
+
+ /**
+ * For implementations where the HAL manages the preview, this is the distance in pixels that
+ * the enrollment preview should be translated.
+ */
+ float enrollTranslationY;
+
+ /**
+ * For implementations where the HAL manages the preview, this is the scale factor that should
+ * be applied when configuring the preview texture.
+ */
+ float enrollPreviewScale;
}
diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp
index 1526245..929c7e7 100644
--- a/biometrics/face/aidl/default/Face.cpp
+++ b/biometrics/face/aidl/default/Face.cpp
@@ -46,6 +46,11 @@
props.commonProps = std::move(commonProps);
props.sensorType = kSensorType;
props.halControlsPreview = kHalControlsPreview;
+ props.enrollPreviewWidth = 1080;
+ props.enrollPreviewHeight = 1920;
+ props.enrollTranslationX = 100.f;
+ props.enrollTranslationY = 50.f;
+ props.enrollPreviewScale = 1.f;
*return_val = {std::move(props)};
return ndk::ScopedAStatus::ok();
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index aa5c48f..f1f0f18 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -1209,7 +1209,12 @@
return notify;
}
- if (physicalCameraMetadata.size() != request->expectedPhysicalResults.size()) {
+ // Physical device results are only expected in the last/final
+ // partial result notification.
+ bool expectPhysicalResults = !(request->usePartialResult &&
+ (results.partialResult < request->numPartialResults));
+ if (expectPhysicalResults &&
+ (physicalCameraMetadata.size() != request->expectedPhysicalResults.size())) {
ALOGE("%s: Frame %d: Returned physical metadata count %zu "
"must be equal to expected count %zu", __func__, frameNumber,
physicalCameraMetadata.size(), request->expectedPhysicalResults.size());
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 57f390c..ff925d9 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -521,7 +521,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.usb.gadget</name>
- <version>1.0-1</version>
+ <version>1.0-2</version>
<interface>
<name>IUsbGadget</name>
<instance>default</instance>
@@ -534,6 +534,13 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.vibrator</name>
+ <interface>
+ <name>IVibratorManager</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.vr</name>
<version>1.0</version>
diff --git a/gnss/1.1/default/GnssDebug.cpp b/gnss/1.1/default/GnssDebug.cpp
index 252f4e6..39efcd2 100644
--- a/gnss/1.1/default/GnssDebug.cpp
+++ b/gnss/1.1/default/GnssDebug.cpp
@@ -37,8 +37,8 @@
.latitudeDegrees = gMockLatitudeDegrees,
.longitudeDegrees = gMockLongitudeDegrees,
.altitudeMeters = gMockAltitudeMeters,
- .speedMetersPerSec = kMockSpeedMetersPerSec,
- .bearingDegrees = kMockBearingDegrees,
+ .speedMetersPerSec = gMockSpeedMetersPerSec,
+ .bearingDegrees = gMockBearingDegrees,
.horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
.verticalAccuracyMeters = kMockVerticalAccuracyMeters,
.speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp
index 175bc75..aae3571 100644
--- a/gnss/2.1/vts/functional/Android.bp
+++ b/gnss/2.1/vts/functional/Android.bp
@@ -18,6 +18,7 @@
name: "VtsHalGnssV2_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
+ "gnss_hal_test.cpp",
"gnss_hal_test_cases.cpp",
"VtsHalGnssV2_1TargetTest.cpp",
],
@@ -31,6 +32,9 @@
"android.hardware.gnss@2.1",
"android.hardware.gnss@common-vts-lib",
],
+ shared_libs: [
+ "libvintf",
+ ],
test_suites: [
"general-tests",
"vts",
diff --git a/gnss/2.1/vts/functional/gnss_hal_test.cpp b/gnss/2.1/vts/functional/gnss_hal_test.cpp
new file mode 100644
index 0000000..1154260
--- /dev/null
+++ b/gnss/2.1/vts/functional/gnss_hal_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GnssHalTest"
+
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <hidl/ServiceManagement.h>
+#include <log/log.h>
+#include <vintf/VintfObject.h>
+
+#include "gnss_hal_test.h"
+
+using ::android::hardware::hidl_string;
+using ::android::hidl::manager::V1_2::IServiceManager;
+
+bool GnssHalTest::IsGnssHalVersion_2_1() const {
+ sp<IServiceManager> manager = ::android::hardware::defaultServiceManager1_2();
+ bool hasGnssHalVersion_2_1 = false;
+ manager->listManifestByInterface(
+ "android.hardware.gnss@2.1::IGnss",
+ [&hasGnssHalVersion_2_1](const hidl_vec<hidl_string>& registered) {
+ hasGnssHalVersion_2_1 = registered.size() > 0;
+ });
+
+ auto deviceManifest = ::android::vintf::VintfObject::GetDeviceHalManifest();
+ bool hasGnssAidl =
+ deviceManifest->getAidlInstances("android.hardware.gnss", "IGnss").size() > 0;
+
+ return hasGnssHalVersion_2_1 && !hasGnssAidl;
+}
\ No newline at end of file
diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h
index c28e248..7950670 100644
--- a/gnss/2.1/vts/functional/gnss_hal_test.h
+++ b/gnss/2.1/vts/functional/gnss_hal_test.h
@@ -22,4 +22,11 @@
using android::hardware::gnss::V2_1::IGnss;
// The main test class for GNSS HAL.
-class GnssHalTest : public GnssHalTestTemplate<IGnss> {};
+class GnssHalTest : public GnssHalTestTemplate<IGnss> {
+ public:
+ /**
+ * IsGnssHalVersion_2_1:
+ * returns true if the GNSS HAL version is exactly 2.1.
+ */
+ bool IsGnssHalVersion_2_1() const;
+};
diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
index 2902809..7afd49c 100644
--- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
@@ -87,6 +87,10 @@
* Gets the GnssConfigurationExtension and verifies that it returns an actual extension.
*/
TEST_P(GnssHalTest, TestGnssConfigurationExtension) {
+ if (!IsGnssHalVersion_2_1()) {
+ ALOGI("Test TestGnssConfigurationExtension skipped. GNSS HAL version is greater than 2.1.");
+ return;
+ }
auto gnssConfiguration_2_1 = gnss_hal_->getExtensionGnssConfiguration_2_1();
auto gnssConfiguration_2_0 = gnss_hal_->getExtensionGnssConfiguration_2_0();
auto gnssConfiguration_1_1 = gnss_hal_->getExtensionGnssConfiguration_1_1();
@@ -358,20 +362,24 @@
}
/*
- * BlacklistIndividualSatellites:
+ * BlocklistIndividualSatellites:
*
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus for common satellites (strongest and one other.)
- * 2a & b) Turns off location, and blacklists common satellites.
+ * 2a & b) Turns off location, and blocklists common satellites.
* 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus does not use those satellites.
- * 4a & b) Turns off location, and send in empty blacklist.
+ * 4a & b) Turns off location, and send in empty blocklist.
* 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus does re-use at least the previously strongest satellite
* 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
* formerly strongest satellite
*/
-TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
+TEST_P(GnssHalTest, BlocklistIndividualSatellites) {
+ if (!IsGnssHalVersion_2_1()) {
+ ALOGI("Test BlocklistIndividualSatellites skipped. GNSS HAL version is greater than 2.1.");
+ return;
+ }
if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) {
ALOGI("Test BlacklistIndividualSatellites skipped. SATELLITE_BLACKLIST capability not "
"supported.");
@@ -509,16 +517,21 @@
}
/*
- * BlacklistConstellationLocationOff:
+ * BlocklistConstellationLocationOff:
*
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus for any non-GPS constellations.
- * 2a & b) Turns off location, and blacklist first non-GPS constellations.
+ * 2a & b) Turns off location, and blocklist first non-GPS constellations.
* 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus does not use any constellation but GPS.
- * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ * 4a & b) Clean up by turning off location, and send in empty blocklist.
*/
-TEST_P(GnssHalTest, BlacklistConstellationLocationOff) {
+TEST_P(GnssHalTest, BlocklistConstellationLocationOff) {
+ if (!IsGnssHalVersion_2_1()) {
+ ALOGI("Test BlocklistConstellationLocationOff skipped. GNSS HAL version is greater than "
+ "2.1.");
+ return;
+ }
if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) {
ALOGI("Test BlacklistConstellationLocationOff skipped. SATELLITE_BLACKLIST capability not "
"supported.");
@@ -591,16 +604,21 @@
}
/*
- * BlacklistConstellationLocationOn:
+ * BlocklistConstellationLocationOn:
*
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus for any non-GPS constellations.
- * 2a & b) Blacklist first non-GPS constellation, and turn off location.
+ * 2a & b) Blocklist first non-GPS constellation, and turn off location.
* 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus does not use any constellation but GPS.
- * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ * 4a & b) Clean up by turning off location, and send in empty blocklist.
*/
-TEST_P(GnssHalTest, BlacklistConstellationLocationOn) {
+TEST_P(GnssHalTest, BlocklistConstellationLocationOn) {
+ if (!IsGnssHalVersion_2_1()) {
+ ALOGI("Test BlocklistConstellationLocationOn skipped. GNSS HAL version is greater than "
+ "2.1.");
+ return;
+ }
if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) {
ALOGI("Test BlacklistConstellationLocationOn skipped. SATELLITE_BLACKLIST capability not "
"supported.");
diff --git a/gnss/aidl/TEST_MAPPING b/gnss/aidl/TEST_MAPPING
new file mode 100644
index 0000000..c21c3e4
--- /dev/null
+++ b/gnss/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "VtsHalGnssTargetTest"
+ }
+ ]
+}
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 2b8a447..d621053 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -46,7 +46,7 @@
ASSERT_TRUE(iGnssPsds != nullptr);
status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector<uint8_t>());
- ASSERT_TRUE(status.isOk());
+ ASSERT_FALSE(status.isOk());
}
/*
diff --git a/gnss/common/utils/default/MockLocation.cpp b/gnss/common/utils/default/MockLocation.cpp
index 2d8e7c5..c90075f 100644
--- a/gnss/common/utils/default/MockLocation.cpp
+++ b/gnss/common/utils/default/MockLocation.cpp
@@ -21,5 +21,7 @@
float gMockLatitudeDegrees{37.4219999};
float gMockLongitudeDegrees{-122.0840575};
float gMockAltitudeMeters{1.60062531};
+float gMockBearingDegrees{0};
+float gMockSpeedMetersPerSec{0};
} // namespace android::hardware::gnss::common
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index fa83634..d336f1b 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -145,8 +145,8 @@
.latitudeDegrees = gMockLatitudeDegrees,
.longitudeDegrees = gMockLongitudeDegrees,
.altitudeMeters = gMockAltitudeMeters,
- .speedMetersPerSec = kMockSpeedMetersPerSec,
- .bearingDegrees = kMockBearingDegrees,
+ .speedMetersPerSec = gMockSpeedMetersPerSec,
+ .bearingDegrees = gMockBearingDegrees,
.horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
.verticalAccuracyMeters = kMockVerticalAccuracyMeters,
.speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h
index ad4e0eb..a290ed2 100644
--- a/gnss/common/utils/default/include/Constants.h
+++ b/gnss/common/utils/default/include/Constants.h
@@ -24,8 +24,6 @@
namespace gnss {
namespace common {
-const float kMockSpeedMetersPerSec = 0;
-const float kMockBearingDegrees = 0;
const float kMockHorizontalAccuracyMeters = 5;
const float kMockVerticalAccuracyMeters = 5;
const float kMockSpeedAccuracyMetersPerSecond = 1;
diff --git a/gnss/common/utils/default/include/MockLocation.h b/gnss/common/utils/default/include/MockLocation.h
index cd8cb5d..0bfdd1a 100644
--- a/gnss/common/utils/default/include/MockLocation.h
+++ b/gnss/common/utils/default/include/MockLocation.h
@@ -27,6 +27,8 @@
extern float gMockLatitudeDegrees;
extern float gMockLongitudeDegrees;
extern float gMockAltitudeMeters;
+extern float gMockBearingDegrees;
+extern float gMockSpeedMetersPerSec;
} // namespace common
} // namespace gnss
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index cbf3933..4d1baa7 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -651,6 +651,8 @@
auto lat = gMockLatitudeDegrees;
auto lon = gMockLongitudeDegrees;
auto ele = gMockAltitudeMeters;
+ auto bea = gMockBearingDegrees;
+ auto spd = gMockSpeedMetersPerSec;
for (size_t i = 1; i < options.size(); ++i) {
std::string option = options[i];
@@ -663,6 +665,12 @@
} else if (option.rfind("ele=", 0) == 0) {
option = option.substr(4);
ele = stof(option);
+ } else if (option.rfind("bea=", 0) == 0) {
+ option = option.substr(4);
+ bea = stof(option);
+ } else if (option.rfind("spd=", 0) == 0) {
+ option = option.substr(4);
+ spd = stof(option);
} else {
dprintf(fd->data[0], "unsupported location argument: %s\n", option.c_str());
}
@@ -671,9 +679,12 @@
gMockLatitudeDegrees = lat;
gMockLongitudeDegrees = lon;
gMockAltitudeMeters = ele;
+ gMockBearingDegrees = bea;
+ gMockSpeedMetersPerSec = spd;
- dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f\n", gMockLatitudeDegrees,
- gMockLongitudeDegrees, gMockAltitudeMeters);
+ dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f bea=%f spd=%f\n",
+ gMockLatitudeDegrees, gMockLongitudeDegrees, gMockAltitudeMeters, gMockBearingDegrees,
+ gMockSpeedMetersPerSec);
return Void();
}
@@ -682,7 +693,7 @@
Return<void> GnssTemplate<T_IGnss>::help(const hidl_handle& fd) {
dprintf(fd->data[0],
"invalid option for Gnss HAL; valid options are:\n"
- "location lat=.. lon=.. ele=..\n");
+ "location [lat=..] [lon=..] [ele=..] [bea=..] [spd=..]\n");
return Void();
}
diff --git a/gnss/common/utils/default/v2_1/GnssDebug.cpp b/gnss/common/utils/default/v2_1/GnssDebug.cpp
index d78b0b6..537a90c 100644
--- a/gnss/common/utils/default/v2_1/GnssDebug.cpp
+++ b/gnss/common/utils/default/v2_1/GnssDebug.cpp
@@ -33,8 +33,8 @@
.latitudeDegrees = gMockLatitudeDegrees,
.longitudeDegrees = gMockLongitudeDegrees,
.altitudeMeters = gMockAltitudeMeters,
- .speedMetersPerSec = kMockSpeedMetersPerSec,
- .bearingDegrees = kMockBearingDegrees,
+ .speedMetersPerSec = gMockSpeedMetersPerSec,
+ .bearingDegrees = gMockBearingDegrees,
.horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
.verticalAccuracyMeters = kMockVerticalAccuracyMeters,
.speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl
index 341909e..4d56ccf 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl
@@ -20,5 +20,6 @@
parcelable EnergyMeasurement {
int channelId;
long timestampMs;
+ long durationMs;
long energyUWs;
}
diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
index f873849..d81914d 100644
--- a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
@@ -23,11 +23,15 @@
*/
int channelId;
/**
- * Time since boot in milliseconds
+ * Approximate time of data capture in millseconds since boot
*/
long timestampMs;
/**
- * Accumulated energy since boot in microwatt-seconds (uWs)
+ * Duration in milliseconds that energy has been accumulated
+ */
+ long durationMs;
+ /**
+ * Accumulated energy in microwatt-seconds (uWs)
*/
long energyUWs;
}
diff --git a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl
index 85a2ce0..05e2004 100644
--- a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl
@@ -96,7 +96,7 @@
ChannelInfo[] getEnergyMeterInfo();
/**
- * Reports accumulated energy since boot for each specified channel.
+ * Reports accumulated energy for each specified channel.
*
* @param channelIds IDs of channels for which data is requested.
* Passing an empty list will return energy measurements for all available channels.
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
index a093dee..91709fa 100644
--- a/radio/1.6/IRadio.hal
+++ b/radio/1.6/IRadio.hal
@@ -320,4 +320,29 @@
*/
oneway setAllowedNetworkTypeBitmap(
uint32_t serial, bitfield<RadioAccessFamily> networkTypeBitmap);
+
+ /**
+ * Control data throttling at modem.
+ * - DataThrottlingAction:NO_DATA_THROTTLING should clear any existing
+ * data throttling within the requested completion window.
+ * - DataThrottlingAction:THROTTLE_SECONDARY_CARRIER: Remove any existing
+ * throttling on anchor carrier and achieve maximum data throttling on
+ * secondary carrier within the requested completion window.
+ * - DataThrottlingAction:THROTTLE_ANCHOR_CARRIER: disable secondary
+ * carrier and achieve maximum data throttling on anchor carrier by
+ * requested completion window.
+ * - DataThrottlingAction:HOLD: Immediately hold on to current level of
+ * throttling.
+ *
+ * @param serial Serial number of request.
+ * @param dataThrottlingAction DataThrottlingAction as defined in types.hal
+ * @param completionWindowSecs window, in seconds, in which the requested
+ * throttling action has to be achieved. This must be 0 when
+ * dataThrottlingAction is DataThrottlingAction:HOLD.
+ *
+ * Response function is IRadioResponse.setDataThrottlingResponse()
+ */
+ oneway setDataThrottling(int32_t serial,
+ DataThrottlingAction dataThrottlingAction,
+ int32_t completionWindowSecs);
};
diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal
index c135090..f195c0e 100644
--- a/radio/1.6/IRadioIndication.hal
+++ b/radio/1.6/IRadioIndication.hal
@@ -18,6 +18,8 @@
import @1.0::RadioIndicationType;
import @1.5::IRadioIndication;
+import @1.6::SetupDataCallResult;
+import @1.6::LinkCapacityEstimate;
/**
* Interface declaring unsolicited radio indications.
@@ -53,4 +55,16 @@
* @param apn Apn to unthrottle
*/
oneway unthrottleApn(RadioIndicationType type, string apn);
+
+ /**
+ * Indicates current link capacity estimate.
+ * This replaces @1.2::IRadioIndication.currentLinkCapacityEstimate().
+ * This indication is sent whenever the reporting criteria, as set by
+ * @1.2::IRadio.setLinkCapacityReportingCriteria, are met and the indication is not
+ * suppressed by @1.2::IRadio.setIndicationFilter_1_2().
+ *
+ * @param type Type of radio indication
+ * @param lce LinkCapacityEstimate
+ */
+ oneway currentLinkCapacityEstimate_1_6(RadioIndicationType type, LinkCapacityEstimate lce);
};
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index 0379e00..acae5c7 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -306,4 +306,15 @@
* RadioError:NO_RESOURCES
*/
oneway setAllowedNetworkTypeBitmapResponse(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:MODEM_ERR
+ * RadioError:INVALID_ARGUMENTS
+ */
+ oneway setDataThrottlingResponse(RadioResponseInfo info);
};
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 8f842a3..2cba915 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -350,3 +350,69 @@
*/
DISABLE_IMMEDIATE= 3,
};
+
+/**
+ * Overwritten from @1.2::LinkCapacityEstimate to update LinkCapacityEstimate to 1.6 version.
+ */
+struct LinkCapacityEstimate {
+
+ /**
+ * Estimated downlink capacity in kbps. In case of a dual connected network,
+ * this includes capacity of both primary and secondary. This bandwidth estimate shall be
+ * the estimated maximum sustainable link bandwidth (as would be measured
+ * at the Upper PDCP or SNDCP SAP). If the DL Aggregate Maximum Bit Rate is known,
+ * this value shall not exceed the DL-AMBR for the Internet PDN connection.
+ * This must be filled with -1 if network is not connected.
+ */
+ uint32_t downlinkCapacityKbps;
+
+ /**
+ * Estimated uplink capacity in kbps. In case of a dual connected network,
+ * this includes capacity of both primary and secondary. This bandwidth estimate shall be the
+ * estimated maximum sustainable link bandwidth (as would be measured at the
+ * Upper PDCP or SNDCP SAP). If the UL Aggregate Maximum Bit Rate is known,
+ * this value shall not exceed the UL-AMBR for the Internet PDN connection.
+ * This must be filled with -1 if network is not connected.
+ */
+ uint32_t uplinkCapacityKbps;
+
+ /**
+ * Estimated downlink capacity of secondary carrier in a dual connected NR mode in kbps.
+ * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth
+ * (as would be measured at the Upper PDCP or SNDCP SAP). This is valid only
+ * in if device is connected to both primary and secodary in dual connected
+ * mode. This must be filled with -1 if secondary is not connected.
+ */
+ uint32_t secondaryDownlinkCapacityKbps;
+
+ /**
+ * Estimated uplink capacity secondary carrier in a dual connected NR mode in kbps.
+ * This bandwidth estimate shall be the estimated
+ * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP).
+ * This is valid only in if device is connected to both primary and secodary in dual connected
+ * mode.This must be filled with -1 if secondary is not connected.
+ */
+ uint32_t secondaryUplinkCapacityKbps;
+};
+
+enum DataThrottlingAction : int32_t {
+ /* Clear all existing data throttling. */
+ NO_DATA_THROTTLING = 0,
+
+ /**
+ * Enact secondary carrier data throttling and remove any existing data
+ * throttling on anchor carrier.
+ */
+ THROTTLE_SECONDARY_CARRIER = 1,
+
+ /**
+ * Enact anchor carrier data throttling and disable data on secondary
+ * carrier if currently enabled.
+ */
+ THROTTLE_ANCHOR_CARRIER = 2,
+
+ /**
+ * Immediately hold on to current level of throttling.
+ */
+ HOLD = 3
+};
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 6547611..ac84417 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -295,3 +295,69 @@
::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR,
::android::hardware::radio::V1_6::RadioError::NONE}));
}
+
+/*
+ * Test IRadio.setDataThrottling() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, setDataThrottling) {
+ serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_6->setDataThrottling(
+ serial, DataThrottlingAction::THROTTLE_SECONDARY_CARRIER, 60);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::MODEM_ERR,
+ ::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
+
+ serial = GetRandomSerialNumber();
+
+ res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::THROTTLE_ANCHOR_CARRIER, 60);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::MODEM_ERR,
+ ::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
+
+ serial = GetRandomSerialNumber();
+
+ res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::HOLD, 60);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::MODEM_ERR,
+ ::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
+
+ serial = GetRandomSerialNumber();
+
+ res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::NO_DATA_THROTTLING, 60);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::MODEM_ERR,
+ ::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
+}
\ No newline at end of file
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 989ba6d..31bb1d7 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -792,6 +792,9 @@
Return<void> setAllowedNetworkTypeBitmapResponse(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info);
+
+ Return<void> setDataThrottlingResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info);
};
/* Callback class for radio indication */
@@ -865,6 +868,10 @@
RadioIndicationType type,
const ::android::hardware::radio::V1_2::LinkCapacityEstimate& lce);
+ Return<void> currentLinkCapacityEstimate_1_6(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_6::LinkCapacityEstimate& lce);
+
Return<void> currentPhysicalChannelConfigs(
RadioIndicationType type,
const ::android::hardware::hidl_vec<
diff --git a/radio/1.6/vts/functional/radio_indication.cpp b/radio/1.6/vts/functional/radio_indication.cpp
index b353c82..afde291 100644
--- a/radio/1.6/vts/functional/radio_indication.cpp
+++ b/radio/1.6/vts/functional/radio_indication.cpp
@@ -124,6 +124,12 @@
return Void();
}
+Return<void> RadioIndication_v1_6::currentLinkCapacityEstimate_1_6(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_6::LinkCapacityEstimate& /*lce*/) {
+ return Void();
+}
+
Return<void> RadioIndication_v1_6::currentPhysicalChannelConfigs(
RadioIndicationType /*type*/,
const ::android::hardware::hidl_vec<
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index 18cda6a..09a2bac 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -1156,3 +1156,10 @@
parent_v1_6.notify(info.serial);
return Void();
}
+
+Return<void> RadioResponse_v1_6::setDataThrottlingResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
diff --git a/sensors/common/default/2.X/Sensor.cpp b/sensors/common/default/2.X/Sensor.cpp
index 1841dff..870980f 100644
--- a/sensors/common/default/2.X/Sensor.cpp
+++ b/sensors/common/default/2.X/Sensor.cpp
@@ -57,11 +57,11 @@
return mSensorInfo;
}
-void Sensor::batch(int32_t samplingPeriodNs) {
- if (samplingPeriodNs < mSensorInfo.minDelay * 1000) {
- samplingPeriodNs = mSensorInfo.minDelay * 1000;
- } else if (samplingPeriodNs > mSensorInfo.maxDelay * 1000) {
- samplingPeriodNs = mSensorInfo.maxDelay * 1000;
+void Sensor::batch(int64_t samplingPeriodNs) {
+ if (samplingPeriodNs < mSensorInfo.minDelay * 1000ll) {
+ samplingPeriodNs = mSensorInfo.minDelay * 1000ll;
+ } else if (samplingPeriodNs > mSensorInfo.maxDelay * 1000ll) {
+ samplingPeriodNs = mSensorInfo.maxDelay * 1000ll;
}
if (mSamplingPeriodNs != samplingPeriodNs) {
@@ -133,6 +133,11 @@
}
std::vector<Event> Sensor::readEvents() {
+ // For an accelerometer sensor type, default the z-direction
+ // value to -9.8
+ float zValue = (mSensorInfo.type == SensorType::ACCELEROMETER)
+ ? -9.8 : 0.0;
+
std::vector<Event> events;
Event event;
event.sensorHandle = mSensorInfo.sensorHandle;
@@ -140,7 +145,7 @@
event.timestamp = ::android::elapsedRealtimeNano();
event.u.vec3.x = 0;
event.u.vec3.y = 0;
- event.u.vec3.z = 0;
+ event.u.vec3.z = zValue;
event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
events.push_back(event);
return events;
@@ -330,25 +335,6 @@
mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
};
-DeviceTempSensor::DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
- : OnChangeSensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
- mSensorInfo.name = "Device Temp Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
- mSensorInfo.type = SensorType::TEMPERATURE;
- mSensorInfo.typeAsString = "";
- mSensorInfo.maxRange = 80.0f;
- mSensorInfo.resolution = 0.01f;
- mSensorInfo.power = 0.001f;
- mSensorInfo.minDelay = 40 * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
-}
-
RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle,
ISensorsEventCallback* callback)
: OnChangeSensor(callback) {
diff --git a/sensors/common/default/2.X/Sensor.h b/sensors/common/default/2.X/Sensor.h
index 2f8a143..a792797 100644
--- a/sensors/common/default/2.X/Sensor.h
+++ b/sensors/common/default/2.X/Sensor.h
@@ -32,7 +32,7 @@
namespace V2_X {
namespace implementation {
-static constexpr float kDefaultMaxDelayUs = 10 * 1000 * 1000;
+static constexpr int32_t kDefaultMaxDelayUs = 10 * 1000 * 1000;
class ISensorsEventCallback {
public:
@@ -54,7 +54,7 @@
virtual ~Sensor();
const SensorInfo& getSensorInfo() const;
- void batch(int32_t samplingPeriodNs);
+ void batch(int64_t samplingPeriodNs);
virtual void activate(bool enable);
Result flush();
@@ -113,11 +113,6 @@
AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
-class DeviceTempSensor : public OnChangeSensor {
- public:
- DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
-};
-
class PressureSensor : public Sensor {
public:
PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
diff --git a/sensors/common/default/2.X/Sensors.h b/sensors/common/default/2.X/Sensors.h
index ee8240d..8969c0f 100644
--- a/sensors/common/default/2.X/Sensors.h
+++ b/sensors/common/default/2.X/Sensors.h
@@ -64,7 +64,6 @@
AddSensor<AccelSensor>();
AddSensor<GyroSensor>();
AddSensor<AmbientTempSensor>();
- AddSensor<DeviceTempSensor>();
AddSensor<PressureSensor>();
AddSensor<MagnetometerSensor>();
AddSensor<LightSensor>();
diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
index 1efd971..69debb6 100644
--- a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
+++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
@@ -71,9 +71,10 @@
return mSensorInfo;
}
-void Sensor::batch(int32_t samplingPeriodNs) {
- samplingPeriodNs =
- std::clamp(samplingPeriodNs, mSensorInfo.minDelay * 1000, mSensorInfo.maxDelay * 1000);
+void Sensor::batch(int64_t samplingPeriodNs) {
+ samplingPeriodNs = std::clamp(samplingPeriodNs,
+ static_cast<int64_t>(mSensorInfo.minDelay) * 1000,
+ static_cast<int64_t>(mSensorInfo.maxDelay) * 1000);
if (mSamplingPeriodNs != samplingPeriodNs) {
mSamplingPeriodNs = samplingPeriodNs;
@@ -323,17 +324,6 @@
mSensorInfo.minDelay = 40 * 1000; // microseconds
}
-DeviceTempSensor::DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
- : ContinuousSensor(sensorHandle, callback) {
- mSensorInfo.name = "Device Temp Sensor";
- mSensorInfo.type = SensorType::TEMPERATURE;
- mSensorInfo.typeAsString = SENSOR_STRING_TYPE_TEMPERATURE;
- mSensorInfo.maxRange = 80.0f;
- mSensorInfo.resolution = 0.01f;
- mSensorInfo.power = 0.001f;
- mSensorInfo.minDelay = 40 * 1000; // microseconds
-}
-
RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle,
ISensorsEventCallback* callback)
: OnChangeSensor(sensorHandle, callback) {
diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h
index 5cf9f83..08c8647 100644
--- a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h
+++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h
@@ -49,7 +49,7 @@
virtual ~Sensor();
const SensorInfo& getSensorInfo() const;
- void batch(int32_t samplingPeriodNs);
+ void batch(int64_t samplingPeriodNs);
virtual void activate(bool enable);
Result flush();
@@ -114,11 +114,6 @@
std::vector<Event> readEvents() override;
};
-class DeviceTempSensor : public ContinuousSensor {
- public:
- DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
-};
-
class PressureSensor : public ContinuousSensor {
public:
PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h b/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h
index 1a78e84..353563c 100644
--- a/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h
+++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h
@@ -206,7 +206,6 @@
ISensorsSubHalBase::AddSensor<GyroSensor>();
ISensorsSubHalBase::AddSensor<MagnetometerSensor>();
ISensorsSubHalBase::AddSensor<PressureSensor>();
- ISensorsSubHalBase::AddSensor<DeviceTempSensor>();
}
};
@@ -231,7 +230,6 @@
ISensorsSubHalBase::AddSensor<GyroSensor>();
ISensorsSubHalBase::AddSensor<MagnetometerSensor>();
ISensorsSubHalBase::AddSensor<PressureSensor>();
- ISensorsSubHalBase::AddSensor<DeviceTempSensor>();
ISensorsSubHalBase::AddSensor<AmbientTempSensor>();
ISensorsSubHalBase::AddSensor<LightSensor>();
ISensorsSubHalBase::AddSensor<ProximitySensor>();
diff --git a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
index e674ddb..f857827 100644
--- a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
+++ b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h
@@ -845,7 +845,11 @@
std::shared_ptr<SensorsTestSharedMemory<SensorTypeVersion, EventType>> mem,
int32_t* directChannelHandle, bool supportsSharedMemType, bool supportsAnyDirectChannel) {
char* buffer = mem->getBuffer();
- memset(buffer, 0xff, mem->getSize());
+ size_t size = mem->getSize();
+
+ if (supportsSharedMemType) {
+ memset(buffer, 0xff, size);
+ }
registerDirectChannel(mem->getSharedMemInfo(), [&](Result result, int32_t channelHandle) {
if (supportsSharedMemType) {
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
index 03bec87..a8e1996 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
@@ -109,7 +109,6 @@
case SensorTypeT::MAGNETIC_FIELD:
case SensorTypeT::ORIENTATION:
case SensorTypeT::PRESSURE:
- case SensorTypeT::TEMPERATURE:
case SensorTypeT::GRAVITY:
case SensorTypeT::LINEAR_ACCELERATION:
case SensorTypeT::ROTATION_VECTOR:
@@ -145,6 +144,10 @@
case SensorTypeT::DYNAMIC_SENSOR_META:
return SensorFlagBits::SPECIAL_REPORTING_MODE;
+ case SensorTypeT::TEMPERATURE:
+ ALOGW("Device temperature sensor is deprecated, ignoring for test");
+ return (SensorFlagBits)-1;
+
default:
ALOGW("Type %d is not implemented in expectedReportModeForType", (int)type);
return (SensorFlagBits)-1;
@@ -334,7 +337,7 @@
usleep(500000); // sleep 0.5 sec to wait for change rate to happen
events1 = collectEvents(collectionTimeoutUs, minNEvent, getEnvironment());
- // second collection, without stop sensor
+ // second collection, without stopping the sensor
ASSERT_EQ(batch(handle, secondCollectionPeriod, batchingPeriodInNs), Result::OK);
usleep(500000); // sleep 0.5 sec to wait for change rate to happen
diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp
index ed40d25..80f7727 100644
--- a/tests/extension/vibrator/aidl/default/Android.bp
+++ b/tests/extension/vibrator/aidl/default/Android.bp
@@ -19,7 +19,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.vibrator-ndk_platform",
- "android.hardware.tests.extension.vibrator-ndk_platform",
+ "android.hardware.vibrator-unstable-ndk_platform",
+ "android.hardware.tests.extension.vibrator-unstable-ndk_platform",
],
}
diff --git a/usb/gadget/1.2/Android.bp b/usb/gadget/1.2/Android.bp
new file mode 100644
index 0000000..386f00f
--- /dev/null
+++ b/usb/gadget/1.2/Android.bp
@@ -0,0 +1,17 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.usb.gadget@1.2",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ "IUsbGadget.hal",
+ "IUsbGadgetCallback.hal",
+ ],
+ interfaces: [
+ "android.hardware.usb.gadget@1.0",
+ "android.hardware.usb.gadget@1.1",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/usb/gadget/1.2/IUsbGadget.hal b/usb/gadget/1.2/IUsbGadget.hal
new file mode 100644
index 0000000..5c6e930
--- /dev/null
+++ b/usb/gadget/1.2/IUsbGadget.hal
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package android.hardware.usb.gadget@1.2;
+
+import IUsbGadgetCallback;
+import android.hardware.usb.gadget@1.1::IUsbGadget;
+
+interface IUsbGadget extends @1.1::IUsbGadget {
+ /**
+ * The function is used to query current USB speed.
+ *
+ * @param callback IUsbGadgetCallback::getUsbSpeedCb used to propagate
+ * current USB speed.
+ */
+ oneway getUsbSpeed(IUsbGadgetCallback callback);
+};
diff --git a/usb/gadget/1.2/IUsbGadgetCallback.hal b/usb/gadget/1.2/IUsbGadgetCallback.hal
new file mode 100644
index 0000000..4170573
--- /dev/null
+++ b/usb/gadget/1.2/IUsbGadgetCallback.hal
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package android.hardware.usb.gadget@1.2;
+
+import UsbSpeed;
+import android.hardware.usb.gadget@1.0::IUsbGadgetCallback;
+
+interface IUsbGadgetCallback extends @1.0::IUsbGadgetCallback {
+ /**
+ * Used to convey the current USB speed to the caller.
+ * Must be called either when USB state changes due to USB enumeration or
+ * when caller requested for USB speed through getUsbSpeed.
+ *
+ * @param speed USB Speed defined by UsbSpeed showed current USB
+ * connection speed.
+ */
+ oneway getUsbSpeedCb(UsbSpeed speed);
+};
+
diff --git a/usb/gadget/1.2/default/Android.bp b/usb/gadget/1.2/default/Android.bp
new file mode 100644
index 0000000..9c73a59
--- /dev/null
+++ b/usb/gadget/1.2/default/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+cc_binary {
+ name: "android.hardware.usb.gadget@1.2-service",
+ defaults: ["hidl_defaults"],
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.usb.gadget@1.2-service.rc"],
+ vintf_fragments: ["android.hardware.usb.gadget@1.2-service.xml"],
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "UsbGadget.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.usb.gadget@1.0",
+ "android.hardware.usb.gadget@1.1",
+ "android.hardware.usb.gadget@1.2",
+ "libbase",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: ["libusbconfigfs-2"],
+}
diff --git a/usb/gadget/1.2/default/UsbGadget.cpp b/usb/gadget/1.2/default/UsbGadget.cpp
new file mode 100644
index 0000000..8dd229e
--- /dev/null
+++ b/usb/gadget/1.2/default/UsbGadget.cpp
@@ -0,0 +1,286 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.usb.gadget@1.2-service"
+
+#include "UsbGadget.h"
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/inotify.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+namespace V1_2 {
+namespace implementation {
+
+UsbGadget::UsbGadget() {
+ if (access(OS_DESC_PATH, R_OK) != 0) {
+ ALOGE("configfs setup not done yet");
+ abort();
+ }
+}
+
+void currentFunctionsAppliedCallback(bool functionsApplied, void* payload) {
+ UsbGadget* gadget = (UsbGadget*)payload;
+ gadget->mCurrentUsbFunctionsApplied = functionsApplied;
+}
+
+Return<void> UsbGadget::getCurrentUsbFunctions(const sp<V1_0::IUsbGadgetCallback>& callback) {
+ Return<void> ret = callback->getCurrentUsbFunctionsCb(
+ mCurrentUsbFunctions, mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED
+ : Status::FUNCTIONS_NOT_APPLIED);
+ if (!ret.isOk()) ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.description().c_str());
+
+ return Void();
+}
+
+Return<void> UsbGadget::getUsbSpeed(const sp<V1_2::IUsbGadgetCallback>& callback) {
+ std::string current_speed;
+ if (ReadFileToString(SPEED_PATH, ¤t_speed)) {
+ current_speed = Trim(current_speed);
+ ALOGI("current USB speed is %s", current_speed.c_str());
+ if (current_speed == "low-speed")
+ mUsbSpeed = UsbSpeed::LOWSPEED;
+ else if (current_speed == "full-speed")
+ mUsbSpeed = UsbSpeed::FULLSPEED;
+ else if (current_speed == "high-speed")
+ mUsbSpeed = UsbSpeed::HIGHSPEED;
+ else if (current_speed == "super-speed")
+ mUsbSpeed = UsbSpeed::SUPERSPEED;
+ else if (current_speed == "super-speed-plus")
+ mUsbSpeed = UsbSpeed::SUPERSPEED_10Gb;
+ else if (current_speed == "UNKNOWN")
+ mUsbSpeed = UsbSpeed::UNKNOWN;
+ else {
+ /**
+ * This part is used for USB4 or reserved speed.
+ *
+ * If reserved speed is detected, it needs to convert to other speeds.
+ * For example:
+ * If the bandwidth of new speed is 7G, adding new if
+ * statement and set mUsbSpeed to SUPERSPEED.
+ * If the bandwidth of new speed is 80G, adding new if
+ * statement and set mUsbSpeed to USB4_GEN3_40Gb.
+ */
+ mUsbSpeed = UsbSpeed::RESERVED_SPEED;
+ }
+ } else {
+ ALOGE("Fail to read current speed");
+ mUsbSpeed = UsbSpeed::UNKNOWN;
+ }
+
+ if (callback) {
+ Return<void> ret = callback->getUsbSpeedCb(mUsbSpeed);
+
+ if (!ret.isOk()) ALOGE("Call to getUsbSpeedCb failed %s", ret.description().c_str());
+ }
+
+ return Void();
+}
+
+V1_0::Status UsbGadget::tearDownGadget() {
+ if (resetGadget() != V1_0::Status::SUCCESS) return V1_0::Status::ERROR;
+
+ if (monitorFfs.isMonitorRunning()) {
+ monitorFfs.reset();
+ } else {
+ ALOGI("mMonitor not running");
+ }
+ return V1_0::Status::SUCCESS;
+}
+
+Return<Status> UsbGadget::reset() {
+ if (!WriteStringToFile("none", PULLUP_PATH)) {
+ ALOGI("Gadget cannot be pulled down");
+ return Status::ERROR;
+ }
+
+ usleep(kDisconnectWaitUs);
+
+ if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) {
+ ALOGI("Gadget cannot be pulled up");
+ return Status::ERROR;
+ }
+
+ return Status::SUCCESS;
+}
+
+static V1_0::Status validateAndSetVidPid(uint64_t functions) {
+ V1_0::Status ret = V1_0::Status::SUCCESS;
+
+ switch (functions) {
+ case static_cast<uint64_t>(V1_2::GadgetFunction::MTP):
+ ret = setVidPid("0x18d1", "0x4ee1");
+ break;
+ case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::MTP:
+ ret = setVidPid("0x18d1", "0x4ee2");
+ break;
+ case static_cast<uint64_t>(V1_2::GadgetFunction::RNDIS):
+ ret = setVidPid("0x18d1", "0x4ee3");
+ break;
+ case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::RNDIS:
+ ret = setVidPid("0x18d1", "0x4ee4");
+ break;
+ case static_cast<uint64_t>(V1_2::GadgetFunction::PTP):
+ ret = setVidPid("0x18d1", "0x4ee5");
+ break;
+ case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::PTP:
+ ret = setVidPid("0x18d1", "0x4ee6");
+ break;
+ case static_cast<uint64_t>(V1_2::GadgetFunction::ADB):
+ ret = setVidPid("0x18d1", "0x4ee7");
+ break;
+ case static_cast<uint64_t>(V1_2::GadgetFunction::MIDI):
+ ret = setVidPid("0x18d1", "0x4ee8");
+ break;
+ case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::MIDI:
+ ret = setVidPid("0x18d1", "0x4ee9");
+ break;
+ case static_cast<uint64_t>(V1_2::GadgetFunction::NCM):
+ ret = setVidPid("0x18d1", "0x4eeb");
+ break;
+ case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::NCM:
+ ret = setVidPid("0x18d1", "0x4eec");
+ break;
+ case static_cast<uint64_t>(V1_2::GadgetFunction::ACCESSORY):
+ ret = setVidPid("0x18d1", "0x2d00");
+ break;
+ case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::ACCESSORY:
+ ret = setVidPid("0x18d1", "0x2d01");
+ break;
+ case static_cast<uint64_t>(V1_2::GadgetFunction::AUDIO_SOURCE):
+ ret = setVidPid("0x18d1", "0x2d02");
+ break;
+ case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::AUDIO_SOURCE:
+ ret = setVidPid("0x18d1", "0x2d03");
+ break;
+ case V1_2::GadgetFunction::ACCESSORY | V1_2::GadgetFunction::AUDIO_SOURCE:
+ ret = setVidPid("0x18d1", "0x2d04");
+ break;
+ case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::ACCESSORY |
+ V1_2::GadgetFunction::AUDIO_SOURCE:
+ ret = setVidPid("0x18d1", "0x2d05");
+ break;
+ default:
+ ALOGE("Combination not supported");
+ ret = V1_0::Status::CONFIGURATION_NOT_SUPPORTED;
+ }
+ return ret;
+}
+
+V1_0::Status UsbGadget::setupFunctions(uint64_t functions,
+ const sp<V1_0::IUsbGadgetCallback>& callback,
+ uint64_t timeout) {
+ bool ffsEnabled = false;
+ int i = 0;
+
+ if (addGenericAndroidFunctions(&monitorFfs, functions, &ffsEnabled, &i) !=
+ V1_0::Status::SUCCESS)
+ return V1_0::Status::ERROR;
+
+ if ((functions & V1_2::GadgetFunction::ADB) != 0) {
+ ffsEnabled = true;
+ if (addAdb(&monitorFfs, &i) != V1_0::Status::SUCCESS) return V1_0::Status::ERROR;
+ }
+
+ // Pull up the gadget right away when there are no ffs functions.
+ if (!ffsEnabled) {
+ if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) return V1_0::Status::ERROR;
+ mCurrentUsbFunctionsApplied = true;
+ if (callback) callback->setCurrentUsbFunctionsCb(functions, V1_0::Status::SUCCESS);
+ return V1_0::Status::SUCCESS;
+ }
+
+ monitorFfs.registerFunctionsAppliedCallback(¤tFunctionsAppliedCallback, this);
+ // Monitors the ffs paths to pull up the gadget when descriptors are written.
+ // Also takes of the pulling up the gadget again if the userspace process
+ // dies and restarts.
+ monitorFfs.startMonitor();
+
+ if (kDebug) ALOGI("Mainthread in Cv");
+
+ if (callback) {
+ bool pullup = monitorFfs.waitForPullUp(timeout);
+ Return<void> ret = callback->setCurrentUsbFunctionsCb(
+ functions, pullup ? V1_0::Status::SUCCESS : V1_0::Status::ERROR);
+ if (!ret.isOk()) ALOGE("setCurrentUsbFunctionsCb error %s", ret.description().c_str());
+ }
+
+ return V1_0::Status::SUCCESS;
+}
+
+Return<void> UsbGadget::setCurrentUsbFunctions(uint64_t functions,
+ const sp<V1_0::IUsbGadgetCallback>& callback,
+ uint64_t timeout) {
+ std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
+
+ mCurrentUsbFunctions = functions;
+ mCurrentUsbFunctionsApplied = false;
+
+ // Unlink the gadget and stop the monitor if running.
+ V1_0::Status status = tearDownGadget();
+ if (status != V1_0::Status::SUCCESS) {
+ goto error;
+ }
+
+ ALOGI("Returned from tearDown gadget");
+
+ // Leave the gadget pulled down to give time for the host to sense disconnect.
+ usleep(kDisconnectWaitUs);
+
+ if (functions == static_cast<uint64_t>(V1_2::GadgetFunction::NONE)) {
+ if (callback == NULL) return Void();
+ Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, V1_0::Status::SUCCESS);
+ if (!ret.isOk())
+ ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
+ return Void();
+ }
+
+ status = validateAndSetVidPid(functions);
+
+ if (status != V1_0::Status::SUCCESS) {
+ goto error;
+ }
+
+ status = setupFunctions(functions, callback, timeout);
+ if (status != V1_0::Status::SUCCESS) {
+ goto error;
+ }
+
+ ALOGI("Usb Gadget setcurrent functions called successfully");
+ return Void();
+
+error:
+ ALOGI("Usb Gadget setcurrent functions failed");
+ if (callback == NULL) return Void();
+ Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, status);
+ if (!ret.isOk())
+ ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
+ return Void();
+}
+} // namespace implementation
+} // namespace V1_2
+} // namespace gadget
+} // namespace usb
+} // namespace hardware
+} // namespace android
diff --git a/usb/gadget/1.2/default/UsbGadget.h b/usb/gadget/1.2/default/UsbGadget.h
new file mode 100644
index 0000000..12ad8ee
--- /dev/null
+++ b/usb/gadget/1.2/default/UsbGadget.h
@@ -0,0 +1,108 @@
+/*
+ * 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 ANDROID_HARDWARE_USB_GADGET_V1_2_USBGADGET_H
+#define ANDROID_HARDWARE_USB_GADGET_V1_2_USBGADGET_H
+
+#include <UsbGadgetCommon.h>
+#include <android-base/file.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/usb/gadget/1.2/IUsbGadget.h>
+#include <android/hardware/usb/gadget/1.2/types.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <utils/Log.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+namespace V1_2 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::base::GetProperty;
+using ::android::base::ReadFileToString;
+using ::android::base::SetProperty;
+using ::android::base::Trim;
+using ::android::base::unique_fd;
+using ::android::base::WriteStringToFile;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::usb::gadget::addAdb;
+using ::android::hardware::usb::gadget::addEpollFd;
+using ::android::hardware::usb::gadget::getVendorFunctions;
+using ::android::hardware::usb::gadget::kDebug;
+using ::android::hardware::usb::gadget::kDisconnectWaitUs;
+using ::android::hardware::usb::gadget::linkFunction;
+using ::android::hardware::usb::gadget::MonitorFfs;
+using ::android::hardware::usb::gadget::resetGadget;
+using ::android::hardware::usb::gadget::setVidPid;
+using ::android::hardware::usb::gadget::unlinkFunctions;
+using ::std::string;
+
+constexpr char kGadgetName[] = "11110000.usb";
+static MonitorFfs monitorFfs(kGadgetName);
+
+#define UDC_PATH "/sys/class/udc/11110000.usb/"
+#define SPEED_PATH UDC_PATH "current_speed"
+
+struct UsbGadget : public IUsbGadget {
+ UsbGadget();
+
+ // Makes sure that only one request is processed at a time.
+ std::mutex mLockSetCurrentFunction;
+ uint64_t mCurrentUsbFunctions;
+ bool mCurrentUsbFunctionsApplied;
+ UsbSpeed mUsbSpeed;
+
+ Return<void> setCurrentUsbFunctions(uint64_t functions,
+ const sp<V1_0::IUsbGadgetCallback>& callback,
+ uint64_t timeout) override;
+
+ Return<void> getCurrentUsbFunctions(const sp<V1_0::IUsbGadgetCallback>& callback) override;
+
+ Return<Status> reset() override;
+
+ Return<void> getUsbSpeed(const sp<V1_2::IUsbGadgetCallback>& callback) override;
+
+ private:
+ V1_0::Status tearDownGadget();
+ V1_0::Status setupFunctions(uint64_t functions, const sp<V1_0::IUsbGadgetCallback>& callback,
+ uint64_t timeout);
+};
+
+} // namespace implementation
+} // namespace V1_2
+} // namespace gadget
+} // namespace usb
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_USB_V1_2_USBGADGET_H
diff --git a/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc
new file mode 100644
index 0000000..650b085
--- /dev/null
+++ b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc
@@ -0,0 +1,7 @@
+service vendor.usb-gadget-hal-1-2 /vendor/bin/hw/android.hardware.usb.gadget@1.2-service
+ interface android.hardware.usb.gadget@1.0::IUsbGadget default
+ interface android.hardware.usb.gadget@1.1::IUsbGadget default
+ interface android.hardware.usb.gadget@1.2::IUsbGadget default
+ class hal
+ user system
+ group system shell mtp
diff --git a/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml
new file mode 100644
index 0000000..8557f6f
--- /dev/null
+++ b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.usb.gadget</name>
+ <transport>hwbinder</transport>
+ <version>1.2</version>
+ <interface>
+ <name>IUsbGadget</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/usb/gadget/1.2/default/lib/Android.bp b/usb/gadget/1.2/default/lib/Android.bp
new file mode 100644
index 0000000..727de13
--- /dev/null
+++ b/usb/gadget/1.2/default/lib/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+cc_library_static {
+ name: "libusbconfigfs-2",
+ vendor_available: true,
+ export_include_dirs: ["include"],
+
+ srcs: [
+ "UsbGadgetUtils.cpp",
+ "MonitorFfs.cpp",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "android.hardware.usb.gadget@1.0",
+ "android.hardware.usb.gadget@1.1",
+ "android.hardware.usb.gadget@1.2",
+ "libbase",
+ "libcutils",
+ "libhidlbase",
+ "libutils",
+ ],
+}
diff --git a/usb/gadget/1.2/default/lib/MonitorFfs.cpp b/usb/gadget/1.2/default/lib/MonitorFfs.cpp
new file mode 100644
index 0000000..0cdf038
--- /dev/null
+++ b/usb/gadget/1.2/default/lib/MonitorFfs.cpp
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "libusbconfigfs"
+
+#include "include/UsbGadgetCommon.h"
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+static volatile bool gadgetPullup;
+
+MonitorFfs::MonitorFfs(const char* const gadget)
+ : mWatchFd(),
+ mEndpointList(),
+ mLock(),
+ mCv(),
+ mLockFd(),
+ mCurrentUsbFunctionsApplied(false),
+ mMonitor(),
+ mCallback(NULL),
+ mPayload(NULL),
+ mGadgetName(gadget),
+ mMonitorRunning(false) {
+ unique_fd eventFd(eventfd(0, 0));
+ if (eventFd == -1) {
+ ALOGE("mEventFd failed to create %d", errno);
+ abort();
+ }
+
+ unique_fd epollFd(epoll_create(2));
+ if (epollFd == -1) {
+ ALOGE("mEpollFd failed to create %d", errno);
+ abort();
+ }
+
+ unique_fd inotifyFd(inotify_init());
+ if (inotifyFd < 0) {
+ ALOGE("inotify init failed");
+ abort();
+ }
+
+ if (addEpollFd(epollFd, inotifyFd) == -1) abort();
+
+ if (addEpollFd(epollFd, eventFd) == -1) abort();
+
+ mEpollFd = move(epollFd);
+ mInotifyFd = move(inotifyFd);
+ mEventFd = move(eventFd);
+ gadgetPullup = false;
+}
+
+static void displayInotifyEvent(struct inotify_event* i) {
+ ALOGE(" wd =%2d; ", i->wd);
+ if (i->cookie > 0) ALOGE("cookie =%4d; ", i->cookie);
+
+ ALOGE("mask = ");
+ if (i->mask & IN_ACCESS) ALOGE("IN_ACCESS ");
+ if (i->mask & IN_ATTRIB) ALOGE("IN_ATTRIB ");
+ if (i->mask & IN_CLOSE_NOWRITE) ALOGE("IN_CLOSE_NOWRITE ");
+ if (i->mask & IN_CLOSE_WRITE) ALOGE("IN_CLOSE_WRITE ");
+ if (i->mask & IN_CREATE) ALOGE("IN_CREATE ");
+ if (i->mask & IN_DELETE) ALOGE("IN_DELETE ");
+ if (i->mask & IN_DELETE_SELF) ALOGE("IN_DELETE_SELF ");
+ if (i->mask & IN_IGNORED) ALOGE("IN_IGNORED ");
+ if (i->mask & IN_ISDIR) ALOGE("IN_ISDIR ");
+ if (i->mask & IN_MODIFY) ALOGE("IN_MODIFY ");
+ if (i->mask & IN_MOVE_SELF) ALOGE("IN_MOVE_SELF ");
+ if (i->mask & IN_MOVED_FROM) ALOGE("IN_MOVED_FROM ");
+ if (i->mask & IN_MOVED_TO) ALOGE("IN_MOVED_TO ");
+ if (i->mask & IN_OPEN) ALOGE("IN_OPEN ");
+ if (i->mask & IN_Q_OVERFLOW) ALOGE("IN_Q_OVERFLOW ");
+ if (i->mask & IN_UNMOUNT) ALOGE("IN_UNMOUNT ");
+ ALOGE("\n");
+
+ if (i->len > 0) ALOGE(" name = %s\n", i->name);
+}
+
+void* MonitorFfs::startMonitorFd(void* param) {
+ MonitorFfs* monitorFfs = (MonitorFfs*)param;
+ char buf[kBufferSize];
+ bool writeUdc = true, stopMonitor = false;
+ struct epoll_event events[kEpollEvents];
+ steady_clock::time_point disconnect;
+
+ bool descriptorWritten = true;
+ for (int i = 0; i < static_cast<int>(monitorFfs->mEndpointList.size()); i++) {
+ if (access(monitorFfs->mEndpointList.at(i).c_str(), R_OK)) {
+ descriptorWritten = false;
+ break;
+ }
+ }
+
+ // notify here if the endpoints are already present.
+ if (descriptorWritten) {
+ usleep(kPullUpDelay);
+ if (!!WriteStringToFile(monitorFfs->mGadgetName, PULLUP_PATH)) {
+ lock_guard<mutex> lock(monitorFfs->mLock);
+ monitorFfs->mCurrentUsbFunctionsApplied = true;
+ monitorFfs->mCallback(monitorFfs->mCurrentUsbFunctionsApplied, monitorFfs->mPayload);
+ gadgetPullup = true;
+ writeUdc = false;
+ ALOGI("GADGET pulled up");
+ monitorFfs->mCv.notify_all();
+ }
+ }
+
+ while (!stopMonitor) {
+ int nrEvents = epoll_wait(monitorFfs->mEpollFd, events, kEpollEvents, -1);
+
+ if (nrEvents <= 0) {
+ ALOGE("epoll wait did not return descriptor number");
+ continue;
+ }
+
+ for (int i = 0; i < nrEvents; i++) {
+ ALOGI("event=%u on fd=%d\n", events[i].events, events[i].data.fd);
+
+ if (events[i].data.fd == monitorFfs->mInotifyFd) {
+ // Process all of the events in buffer returned by read().
+ int numRead = read(monitorFfs->mInotifyFd, buf, kBufferSize);
+ for (char* p = buf; p < buf + numRead;) {
+ struct inotify_event* event = (struct inotify_event*)p;
+ if (kDebug) displayInotifyEvent(event);
+
+ p += sizeof(struct inotify_event) + event->len;
+
+ bool descriptorPresent = true;
+ for (int j = 0; j < static_cast<int>(monitorFfs->mEndpointList.size()); j++) {
+ if (access(monitorFfs->mEndpointList.at(j).c_str(), R_OK)) {
+ if (kDebug) ALOGI("%s absent", monitorFfs->mEndpointList.at(j).c_str());
+ descriptorPresent = false;
+ break;
+ }
+ }
+
+ if (!descriptorPresent && !writeUdc) {
+ if (kDebug) ALOGI("endpoints not up");
+ writeUdc = true;
+ disconnect = std::chrono::steady_clock::now();
+ } else if (descriptorPresent && writeUdc) {
+ steady_clock::time_point temp = steady_clock::now();
+
+ if (std::chrono::duration_cast<microseconds>(temp - disconnect).count() <
+ kPullUpDelay)
+ usleep(kPullUpDelay);
+
+ if (!!WriteStringToFile(monitorFfs->mGadgetName, PULLUP_PATH)) {
+ lock_guard<mutex> lock(monitorFfs->mLock);
+ monitorFfs->mCurrentUsbFunctionsApplied = true;
+ monitorFfs->mCallback(monitorFfs->mCurrentUsbFunctionsApplied,
+ monitorFfs->mPayload);
+ ALOGI("GADGET pulled up");
+ writeUdc = false;
+ gadgetPullup = true;
+ // notify the main thread to signal userspace.
+ monitorFfs->mCv.notify_all();
+ }
+ }
+ }
+ } else {
+ uint64_t flag;
+ read(monitorFfs->mEventFd, &flag, sizeof(flag));
+ if (flag == 100) {
+ stopMonitor = true;
+ break;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+void MonitorFfs::reset() {
+ lock_guard<mutex> lock(mLockFd);
+ uint64_t flag = 100;
+ unsigned long ret;
+
+ if (mMonitorRunning) {
+ // Stop the monitor thread by writing into signal fd.
+ ret = TEMP_FAILURE_RETRY(write(mEventFd, &flag, sizeof(flag)));
+ if (ret < 0) ALOGE("Error writing eventfd errno=%d", errno);
+
+ ALOGI("mMonitor signalled to exit");
+ mMonitor->join();
+ ALOGI("mMonitor destroyed");
+ mMonitorRunning = false;
+ }
+
+ for (std::vector<int>::size_type i = 0; i != mWatchFd.size(); i++)
+ inotify_rm_watch(mInotifyFd, mWatchFd[i]);
+
+ mEndpointList.clear();
+ gadgetPullup = false;
+ mCallback = NULL;
+ mPayload = NULL;
+}
+
+bool MonitorFfs::startMonitor() {
+ mMonitor = unique_ptr<thread>(new thread(this->startMonitorFd, this));
+ mMonitorRunning = true;
+ return true;
+}
+
+bool MonitorFfs::isMonitorRunning() {
+ return mMonitorRunning;
+}
+
+bool MonitorFfs::waitForPullUp(int timeout_ms) {
+ std::unique_lock<std::mutex> lk(mLock);
+
+ if (gadgetPullup) return true;
+
+ if (mCv.wait_for(lk, timeout_ms * 1ms, [] { return gadgetPullup; })) {
+ ALOGI("monitorFfs signalled true");
+ return true;
+ } else {
+ ALOGI("monitorFfs signalled error");
+ // continue monitoring as the descriptors might be written at a later
+ // point.
+ return false;
+ }
+}
+
+bool MonitorFfs::addInotifyFd(string fd) {
+ lock_guard<mutex> lock(mLockFd);
+ int wfd;
+
+ wfd = inotify_add_watch(mInotifyFd, fd.c_str(), IN_ALL_EVENTS);
+ if (wfd == -1)
+ return false;
+ else
+ mWatchFd.push_back(wfd);
+
+ return true;
+}
+
+void MonitorFfs::addEndPoint(string ep) {
+ lock_guard<mutex> lock(mLockFd);
+
+ mEndpointList.push_back(ep);
+}
+
+void MonitorFfs::registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied,
+ void* payload),
+ void* payload) {
+ mCallback = callback;
+ mPayload = payload;
+}
+
+} // namespace gadget
+} // namespace usb
+} // namespace hardware
+} // namespace android
diff --git a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
new file mode 100644
index 0000000..8986556
--- /dev/null
+++ b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "libusbconfigfs"
+
+#include "include/UsbGadgetCommon.h"
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+int unlinkFunctions(const char* path) {
+ DIR* config = opendir(path);
+ struct dirent* function;
+ char filepath[kMaxFilePathLength];
+ int ret = 0;
+
+ if (config == NULL) return -1;
+
+ // d_type does not seems to be supported in /config
+ // so filtering by name.
+ while (((function = readdir(config)) != NULL)) {
+ if ((strstr(function->d_name, FUNCTION_NAME) == NULL)) continue;
+ // build the path for each file in the folder.
+ sprintf(filepath, "%s/%s", path, function->d_name);
+ ret = remove(filepath);
+ if (ret) {
+ ALOGE("Unable remove file %s errno:%d", filepath, errno);
+ break;
+ }
+ }
+
+ closedir(config);
+ return ret;
+}
+
+int addEpollFd(const unique_fd& epfd, const unique_fd& fd) {
+ struct epoll_event event;
+ int ret;
+
+ event.data.fd = fd;
+ event.events = EPOLLIN;
+
+ ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
+ if (ret) ALOGE("epoll_ctl error %d", errno);
+
+ return ret;
+}
+
+int linkFunction(const char* function, int index) {
+ char functionPath[kMaxFilePathLength];
+ char link[kMaxFilePathLength];
+
+ sprintf(functionPath, "%s%s", FUNCTIONS_PATH, function);
+ sprintf(link, "%s%d", FUNCTION_PATH, index);
+ if (symlink(functionPath, link)) {
+ ALOGE("Cannot create symlink %s -> %s errno:%d", link, functionPath, errno);
+ return -1;
+ }
+ return 0;
+}
+
+Status setVidPid(const char* vid, const char* pid) {
+ if (!WriteStringToFile(vid, VENDOR_ID_PATH)) return Status::ERROR;
+
+ if (!WriteStringToFile(pid, PRODUCT_ID_PATH)) return Status::ERROR;
+
+ return Status::SUCCESS;
+}
+
+std::string getVendorFunctions() {
+ if (GetProperty(kBuildType, "") == "user") return "user";
+
+ std::string bootMode = GetProperty(PERSISTENT_BOOT_MODE, "");
+ std::string persistVendorFunctions = GetProperty(kPersistentVendorConfig, "");
+ std::string vendorFunctions = GetProperty(kVendorConfig, "");
+ std::string ret = "";
+
+ if (vendorFunctions != "") {
+ ret = vendorFunctions;
+ } else if (bootMode == "usbradio" || bootMode == "factory" || bootMode == "ffbm-00" ||
+ bootMode == "ffbm-01") {
+ if (persistVendorFunctions != "")
+ ret = persistVendorFunctions;
+ else
+ ret = "diag";
+ // vendor.usb.config will reflect the current configured functions
+ SetProperty(kVendorConfig, ret);
+ }
+
+ return ret;
+}
+
+Status resetGadget() {
+ ALOGI("setCurrentUsbFunctions None");
+
+ if (!WriteStringToFile("none", PULLUP_PATH)) ALOGI("Gadget cannot be pulled down");
+
+ if (!WriteStringToFile("0", DEVICE_CLASS_PATH)) return Status::ERROR;
+
+ if (!WriteStringToFile("0", DEVICE_SUB_CLASS_PATH)) return Status::ERROR;
+
+ if (!WriteStringToFile("0", DEVICE_PROTOCOL_PATH)) return Status::ERROR;
+
+ if (!WriteStringToFile("0", DESC_USE_PATH)) return Status::ERROR;
+
+ if (unlinkFunctions(CONFIG_PATH)) return Status::ERROR;
+
+ return Status::SUCCESS;
+}
+
+Status addGenericAndroidFunctions(MonitorFfs* monitorFfs, uint64_t functions, bool* ffsEnabled,
+ int* functionCount) {
+ if (((functions & GadgetFunction::MTP) != 0)) {
+ *ffsEnabled = true;
+ ALOGI("setCurrentUsbFunctions mtp");
+ if (!WriteStringToFile("1", DESC_USE_PATH)) return Status::ERROR;
+
+ if (!monitorFfs->addInotifyFd("/dev/usb-ffs/mtp/")) return Status::ERROR;
+
+ if (linkFunction("ffs.mtp", (*functionCount)++)) return Status::ERROR;
+
+ // Add endpoints to be monitored.
+ monitorFfs->addEndPoint("/dev/usb-ffs/mtp/ep1");
+ monitorFfs->addEndPoint("/dev/usb-ffs/mtp/ep2");
+ monitorFfs->addEndPoint("/dev/usb-ffs/mtp/ep3");
+ } else if (((functions & GadgetFunction::PTP) != 0)) {
+ *ffsEnabled = true;
+ ALOGI("setCurrentUsbFunctions ptp");
+ if (!WriteStringToFile("1", DESC_USE_PATH)) return Status::ERROR;
+
+ if (!monitorFfs->addInotifyFd("/dev/usb-ffs/ptp/")) return Status::ERROR;
+
+ if (linkFunction("ffs.ptp", (*functionCount)++)) return Status::ERROR;
+
+ // Add endpoints to be monitored.
+ monitorFfs->addEndPoint("/dev/usb-ffs/ptp/ep1");
+ monitorFfs->addEndPoint("/dev/usb-ffs/ptp/ep2");
+ monitorFfs->addEndPoint("/dev/usb-ffs/ptp/ep3");
+ }
+
+ if ((functions & GadgetFunction::MIDI) != 0) {
+ ALOGI("setCurrentUsbFunctions MIDI");
+ if (linkFunction("midi.gs5", (*functionCount)++)) return Status::ERROR;
+ }
+
+ if ((functions & GadgetFunction::ACCESSORY) != 0) {
+ ALOGI("setCurrentUsbFunctions Accessory");
+ if (linkFunction("accessory.gs2", (*functionCount)++)) return Status::ERROR;
+ }
+
+ if ((functions & GadgetFunction::AUDIO_SOURCE) != 0) {
+ ALOGI("setCurrentUsbFunctions Audio Source");
+ if (linkFunction("audio_source.gs3", (*functionCount)++)) return Status::ERROR;
+ }
+
+ if ((functions & GadgetFunction::RNDIS) != 0) {
+ ALOGI("setCurrentUsbFunctions rndis");
+ if (linkFunction("gsi.rndis", (*functionCount)++)) return Status::ERROR;
+ std::string rndisFunction = GetProperty(kVendorRndisConfig, "");
+ if (rndisFunction != "") {
+ if (linkFunction(rndisFunction.c_str(), (*functionCount)++)) return Status::ERROR;
+ } else {
+ // link gsi.rndis for older pixel projects
+ if (linkFunction("gsi.rndis", (*functionCount)++)) return Status::ERROR;
+ }
+ }
+
+ if ((functions & GadgetFunction::NCM) != 0) {
+ ALOGI("setCurrentUsbFunctions ncm");
+ if (linkFunction("ncm.gs6", (*functionCount)++)) return Status::ERROR;
+ }
+
+ return Status::SUCCESS;
+}
+
+Status addAdb(MonitorFfs* monitorFfs, int* functionCount) {
+ ALOGI("setCurrentUsbFunctions Adb");
+ if (!monitorFfs->addInotifyFd("/dev/usb-ffs/adb/")) return Status::ERROR;
+
+ if (linkFunction("ffs.adb", (*functionCount)++)) return Status::ERROR;
+ monitorFfs->addEndPoint("/dev/usb-ffs/adb/ep1");
+ monitorFfs->addEndPoint("/dev/usb-ffs/adb/ep2");
+ ALOGI("Service started");
+ return Status::SUCCESS;
+}
+
+} // namespace gadget
+} // namespace usb
+} // namespace hardware
+} // namespace android
diff --git a/usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h b/usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h
new file mode 100644
index 0000000..18b8101
--- /dev/null
+++ b/usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h
@@ -0,0 +1,179 @@
+/*
+ * 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 HARDWARE_USB_USBGADGETCOMMON_H
+#define HARDWARE_USB_USBGADGETCOMMON_H
+
+#include <android-base/file.h>
+#include <android-base/properties.h>
+#include <android-base/unique_fd.h>
+
+#include <android/hardware/usb/gadget/1.2/IUsbGadget.h>
+#include <android/hardware/usb/gadget/1.2/types.h>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <sys/inotify.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+constexpr int kBufferSize = 512;
+constexpr int kMaxFilePathLength = 256;
+constexpr int kEpollEvents = 10;
+constexpr bool kDebug = false;
+constexpr int kDisconnectWaitUs = 100000;
+constexpr int kPullUpDelay = 500000;
+constexpr int kShutdownMonitor = 100;
+
+constexpr char kBuildType[] = "ro.build.type";
+constexpr char kPersistentVendorConfig[] = "persist.vendor.usb.usbradio.config";
+constexpr char kVendorConfig[] = "vendor.usb.config";
+constexpr char kVendorRndisConfig[] = "vendor.usb.rndis.config";
+
+#define GADGET_PATH "/config/usb_gadget/g1/"
+#define PULLUP_PATH GADGET_PATH "UDC"
+#define PERSISTENT_BOOT_MODE "ro.bootmode"
+#define VENDOR_ID_PATH GADGET_PATH "idVendor"
+#define PRODUCT_ID_PATH GADGET_PATH "idProduct"
+#define DEVICE_CLASS_PATH GADGET_PATH "bDeviceClass"
+#define DEVICE_SUB_CLASS_PATH GADGET_PATH "bDeviceSubClass"
+#define DEVICE_PROTOCOL_PATH GADGET_PATH "bDeviceProtocol"
+#define DESC_USE_PATH GADGET_PATH "os_desc/use"
+#define OS_DESC_PATH GADGET_PATH "os_desc/b.1"
+#define CONFIG_PATH GADGET_PATH "configs/b.1/"
+#define FUNCTIONS_PATH GADGET_PATH "functions/"
+#define FUNCTION_NAME "function"
+#define FUNCTION_PATH CONFIG_PATH FUNCTION_NAME
+#define RNDIS_PATH FUNCTIONS_PATH "gsi.rndis"
+
+using ::android::base::GetProperty;
+using ::android::base::SetProperty;
+using ::android::base::unique_fd;
+using ::android::base::WriteStringToFile;
+using ::android::hardware::usb::gadget::V1_0::Status;
+using ::android::hardware::usb::gadget::V1_2::GadgetFunction;
+
+using ::std::lock_guard;
+using ::std::move;
+using ::std::mutex;
+using ::std::string;
+using ::std::thread;
+using ::std::unique_ptr;
+using ::std::vector;
+using ::std::chrono::microseconds;
+using ::std::chrono::steady_clock;
+using ::std::literals::chrono_literals::operator""ms;
+
+// MonitorFfs automously manages gadget pullup by monitoring
+// the ep file status. Restarts the usb gadget when the ep
+// owner restarts.
+class MonitorFfs {
+ private:
+ // Monitors the endpoints Inotify events.
+ unique_fd mInotifyFd;
+ // Control pipe for shutting down the mMonitor thread.
+ // mMonitor exits when SHUTDOWN_MONITOR is written into
+ // mEventFd/
+ unique_fd mEventFd;
+ // Pools on mInotifyFd and mEventFd.
+ unique_fd mEpollFd;
+ vector<int> mWatchFd;
+
+ // Maintains the list of Endpoints.
+ vector<string> mEndpointList;
+ // protects the CV.
+ std::mutex mLock;
+ std::condition_variable mCv;
+ // protects mInotifyFd, mEpollFd.
+ std::mutex mLockFd;
+
+ // Flag to maintain the current status of gadget pullup.
+ bool mCurrentUsbFunctionsApplied;
+
+ // Thread object that executes the ep monitoring logic.
+ unique_ptr<thread> mMonitor;
+ // Callback to be invoked when gadget is pulled up.
+ void (*mCallback)(bool functionsApplied, void* payload);
+ void* mPayload;
+ // Name of the USB gadget. Used for pullup.
+ const char* const mGadgetName;
+ // Monitor State
+ bool mMonitorRunning;
+
+ public:
+ MonitorFfs(const char* const gadget);
+ // Inits all the UniqueFds.
+ void reset();
+ // Starts monitoring endpoints and pullup the gadget when
+ // the descriptors are written.
+ bool startMonitor();
+ // Waits for timeout_ms for gadget pull up to happen.
+ // Returns immediately if the gadget is already pulled up.
+ bool waitForPullUp(int timeout_ms);
+ // Adds the given fd to the watch list.
+ bool addInotifyFd(string fd);
+ // Adds the given endpoint to the watch list.
+ void addEndPoint(string ep);
+ // Registers the async callback from the caller to notify the caller
+ // when the gadget pull up happens.
+ void registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied, void*(payload)),
+ void* payload);
+ bool isMonitorRunning();
+ // Ep monitoring and the gadget pull up logic.
+ static void* startMonitorFd(void* param);
+};
+
+//**************** Helper functions ************************//
+
+// Adds the given fd to the epollfd(epfd).
+int addEpollFd(const unique_fd& epfd, const unique_fd& fd);
+// Removes all the usb functions link in the specified path.
+int unlinkFunctions(const char* path);
+// Craetes a configfs link for the function.
+int linkFunction(const char* function, int index);
+// Sets the USB VID and PID.
+Status setVidPid(const char* vid, const char* pid);
+// Extracts vendor functions from the vendor init properties.
+std::string getVendorFunctions();
+// Adds Adb to the usb configuration.
+Status addAdb(MonitorFfs* monitorFfs, int* functionCount);
+// Adds all applicable generic android usb functions other than ADB.
+Status addGenericAndroidFunctions(MonitorFfs* monitorFfs, uint64_t functions, bool* ffsEnabled,
+ int* functionCount);
+// Pulls down USB gadget.
+Status resetGadget();
+
+} // namespace gadget
+} // namespace usb
+} // namespace hardware
+} // namespace android
+#endif
diff --git a/usb/gadget/1.2/default/service.cpp b/usb/gadget/1.2/default/service.cpp
new file mode 100644
index 0000000..80c56a6
--- /dev/null
+++ b/usb/gadget/1.2/default/service.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.usb.gadget@1.2-service"
+
+#include <hidl/HidlTransportSupport.h>
+#include "UsbGadget.h"
+
+using android::sp;
+
+// libhwbinder:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::hardware::usb::gadget::V1_2::IUsbGadget;
+using android::hardware::usb::gadget::V1_2::implementation::UsbGadget;
+
+using android::OK;
+using android::status_t;
+
+int main() {
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+ android::sp<IUsbGadget> service = new UsbGadget();
+
+ status_t status = service->registerAsService();
+
+ if (status != OK) {
+ ALOGE("Cannot register USB Gadget HAL service");
+ return 1;
+ }
+
+ ALOGI("USB Gadget HAL Ready.");
+ joinRpcThreadpool();
+ // Under noraml cases, execution will not reach this line.
+ ALOGI("USB Gadget HAL failed to join thread pool.");
+ return 1;
+}
diff --git a/usb/gadget/1.2/types.hal b/usb/gadget/1.2/types.hal
new file mode 100644
index 0000000..a5c079d
--- /dev/null
+++ b/usb/gadget/1.2/types.hal
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+package android.hardware.usb.gadget@1.2;
+
+import android.hardware.usb.gadget@1.0::GadgetFunction;
+
+enum GadgetFunction : @1.0::GadgetFunction {
+ /**
+ * NCM - NCM function.
+ */
+ NCM = 1 << 10,
+};
+
+enum UsbSpeed : uint32_t {
+ /**
+ * UNKNOWN - Not Connected or Unsupported Speed
+ */
+ UNKNOWN = -1,
+
+ /**
+ * USB Low Speed
+ */
+ LOWSPEED = 0,
+
+ /**
+ * USB Full Speed
+ */
+ FULLSPEED = 1,
+
+ /**
+ * USB High Speed
+ */
+ HIGHSPEED = 2,
+
+ /**
+ * USB Super Speed
+ */
+ SUPERSPEED = 3,
+
+ /**
+ * USB Super Speed 10Gbps
+ */
+ SUPERSPEED_10Gb = 4,
+
+ /**
+ * USB Super Speed 20Gbps
+ */
+ SUPERSPEED_20Gb = 5,
+
+ /**
+ * USB4 Gen2 x 1 (10Gbps)
+ */
+ USB4_GEN2_10Gb = 6,
+
+ /**
+ * USB4 Gen2 x 2 (20Gbps)
+ */
+ USB4_GEN2_20Gb = 7,
+
+ /**
+ * USB4 Gen3 x 1 (20Gbps)
+ */
+ USB4_GEN3_20Gb = 8,
+
+ /**
+ * USB4 Gen3 x 2 (40Gbps)
+ */
+ USB4_GEN3_40Gb = 9,
+
+ /**
+ * This is a suggestion if needed.
+ *
+ * Reserved Speed -- It is a newer speed after USB4 v1.0 announcement.
+ * If this speed is detected, the HAL implementation should convert current
+ * speed to above speeds which is lower and the closest.
+ */
+ RESERVED_SPEED = 64,
+};
diff --git a/vibrator/aidl/TEST_MAPPING b/vibrator/aidl/TEST_MAPPING
index 5ae32e7..2414b84 100644
--- a/vibrator/aidl/TEST_MAPPING
+++ b/vibrator/aidl/TEST_MAPPING
@@ -2,6 +2,9 @@
"presubmit": [
{
"name": "VtsHalVibratorTargetTest"
+ },
+ {
+ "name": "VtsHalVibratorManagerTargetTest"
}
]
}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
new file mode 100644
index 0000000..99cd448
--- /dev/null
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.vibrator;
+@VintfStability
+interface IVibratorManager {
+ int getCapabilities();
+ int[] getVibratorIds();
+ android.hardware.vibrator.IVibrator getVibrator(in int vibratorId);
+ void prepareSynced(in int[] vibratorIds);
+ void triggerSynced(in android.hardware.vibrator.IVibratorCallback callback);
+ void cancelSynced();
+ const int CAP_SYNC = 1;
+ const int CAP_PREPARE_ON = 2;
+ const int CAP_PREPARE_PERFORM = 4;
+ const int CAP_PREPARE_COMPOSE = 8;
+ const int CAP_MIXED_TRIGGER_ON = 16;
+ const int CAP_MIXED_TRIGGER_PERFORM = 32;
+ const int CAP_MIXED_TRIGGER_COMPOSE = 64;
+ const int CAP_TRIGGER_CALLBACK = 128;
+}
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl
new file mode 100644
index 0000000..eb5e9cc
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+package android.hardware.vibrator;
+
+import android.hardware.vibrator.IVibrator;
+import android.hardware.vibrator.IVibratorCallback;
+
+@VintfStability
+interface IVibratorManager {
+ /**
+ * Whether prepare/trigger synced are supported.
+ */
+ const int CAP_SYNC = 1 << 0;
+ /**
+ * Whether IVibrator 'on' can be used with 'prepareSynced' function.
+ */
+ const int CAP_PREPARE_ON = 1 << 1;
+ /**
+ * Whether IVibrator 'perform' can be used with 'prepareSynced' function.
+ */
+ const int CAP_PREPARE_PERFORM = 1 << 2;
+ /**
+ * Whether IVibrator 'compose' can be used with 'prepareSynced' function.
+ */
+ const int CAP_PREPARE_COMPOSE = 1 << 3;
+ /**
+ * Whether IVibrator 'on' can be triggered with other functions in sync with 'triggerSynced'.
+ */
+ const int CAP_MIXED_TRIGGER_ON = 1 << 4;
+ /**
+ * Whether IVibrator 'perform' can be triggered with other functions in sync with 'triggerSynced'.
+ */
+ const int CAP_MIXED_TRIGGER_PERFORM = 1 << 5;
+ /**
+ * Whether IVibrator 'compose' can be triggered with other functions in sync with 'triggerSynced'.
+ */
+ const int CAP_MIXED_TRIGGER_COMPOSE = 1 << 6;
+ /**
+ * Whether on w/ IVibratorCallback can be used w/ 'trigerSynced' function.
+ */
+ const int CAP_TRIGGER_CALLBACK = 1 << 7;
+
+ /**
+ * Determine capabilities of the vibrator manager HAL (CAP_* mask)
+ */
+ int getCapabilities();
+
+ /**
+ * List the id of available vibrators. This result should be static and not change.
+ */
+ int[] getVibratorIds();
+
+ /**
+ * Return an available vibrator identified with given id.
+ */
+ IVibrator getVibrator(in int vibratorId);
+
+ /**
+ * Start preparation for a synced vibration
+ *
+ * This function must only be called after the previous synced vibration was triggered or
+ * canceled (through cancelSynced()).
+ *
+ * Doing this operation while any of the specified vibrators is already on is undefined behavior.
+ * Clients should explicitly call off in each vibrator.
+ *
+ * @param vibratorIds ids of the vibrators to play vibrations in sync.
+ */
+ void prepareSynced(in int[] vibratorIds);
+
+ /**
+ * Trigger a prepared synced vibration
+ *
+ * Trigger a previously-started preparation for synced vibration, if any.
+ * A callback is only expected to be supported when getCapabilities CAP_TRIGGER_CALLBACK
+ * is specified.
+ *
+ * @param callback A callback used to inform Frameworks of state change, if supported.
+ */
+ void triggerSynced(in IVibratorCallback callback);
+
+ /**
+ * Cancel preparation of synced vibration
+ *
+ * Cancel a previously-started preparation for synced vibration, if any.
+ */
+ void cancelSynced();
+}
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index 9e6d9cf..f9d45bb 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -4,10 +4,13 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.vibrator-ndk_platform",
+ "android.hardware.vibrator-unstable-ndk_platform",
],
export_include_dirs: ["include"],
- srcs: ["Vibrator.cpp"],
+ srcs: [
+ "Vibrator.cpp",
+ "VibratorManager.cpp",
+ ],
visibility: [
":__subpackages__",
"//hardware/interfaces/tests/extension/vibrator:__subpackages__",
@@ -23,7 +26,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.vibrator-ndk_platform",
+ "android.hardware.vibrator-unstable-ndk_platform",
],
static_libs: [
"libvibratorexampleimpl",
diff --git a/vibrator/aidl/default/VibratorManager.cpp b/vibrator/aidl/default/VibratorManager.cpp
new file mode 100644
index 0000000..7cf9e6a
--- /dev/null
+++ b/vibrator/aidl/default/VibratorManager.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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 "vibrator-impl/VibratorManager.h"
+
+#include <android-base/logging.h>
+#include <thread>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace vibrator {
+
+static constexpr int32_t kDefaultVibratorId = 1;
+
+ndk::ScopedAStatus VibratorManager::getCapabilities(int32_t* _aidl_return) {
+ LOG(INFO) << "Vibrator manager reporting capabilities";
+ *_aidl_return =
+ IVibratorManager::CAP_SYNC | IVibratorManager::CAP_PREPARE_ON |
+ IVibratorManager::CAP_PREPARE_PERFORM | IVibratorManager::CAP_PREPARE_COMPOSE |
+ IVibratorManager::CAP_MIXED_TRIGGER_ON | IVibratorManager::CAP_MIXED_TRIGGER_PERFORM |
+ IVibratorManager::CAP_MIXED_TRIGGER_COMPOSE | IVibratorManager::CAP_TRIGGER_CALLBACK;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VibratorManager::getVibratorIds(std::vector<int32_t>* _aidl_return) {
+ LOG(INFO) << "Vibrator manager getting vibrator ids";
+ *_aidl_return = {kDefaultVibratorId};
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VibratorManager::getVibrator(int32_t vibratorId,
+ std::shared_ptr<IVibrator>* _aidl_return) {
+ LOG(INFO) << "Vibrator manager getting vibrator " << vibratorId;
+ if (vibratorId == kDefaultVibratorId) {
+ *_aidl_return = mDefaultVibrator;
+ return ndk::ScopedAStatus::ok();
+ } else {
+ *_aidl_return = nullptr;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+}
+
+ndk::ScopedAStatus VibratorManager::prepareSynced(const std::vector<int32_t>& vibratorIds) {
+ LOG(INFO) << "Vibrator Manager prepare synced";
+ if (vibratorIds.size() == 1 && vibratorIds[0] == kDefaultVibratorId) {
+ return ndk::ScopedAStatus::ok();
+ } else {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+}
+
+ndk::ScopedAStatus VibratorManager::triggerSynced(
+ const std::shared_ptr<IVibratorCallback>& callback) {
+ LOG(INFO) << "Vibrator Manager trigger synced";
+ std::thread([=] {
+ if (callback != nullptr) {
+ LOG(INFO) << "Notifying perform complete";
+ callback->onComplete();
+ }
+ }).detach();
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VibratorManager::cancelSynced() {
+ LOG(INFO) << "Vibrator Manager cancel synced";
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace vibrator
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h b/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h
new file mode 100644
index 0000000..319eb05
--- /dev/null
+++ b/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/vibrator/BnVibratorManager.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace vibrator {
+
+class VibratorManager : public BnVibratorManager {
+ public:
+ VibratorManager(std::shared_ptr<IVibrator> vibrator) : mDefaultVibrator(std::move(vibrator)){};
+ ndk::ScopedAStatus getCapabilities(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus getVibratorIds(std::vector<int32_t>* _aidl_return) override;
+ ndk::ScopedAStatus getVibrator(int32_t vibratorId,
+ std::shared_ptr<IVibrator>* _aidl_return) override;
+ ndk::ScopedAStatus prepareSynced(const std::vector<int32_t>& vibratorIds) override;
+ ndk::ScopedAStatus triggerSynced(const std::shared_ptr<IVibratorCallback>& callback) override;
+ ndk::ScopedAStatus cancelSynced() override;
+
+ private:
+ std::shared_ptr<IVibrator> mDefaultVibrator;
+};
+
+} // namespace vibrator
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/vibrator/aidl/default/main.cpp b/vibrator/aidl/default/main.cpp
index ebb0905..bd834d2 100644
--- a/vibrator/aidl/default/main.cpp
+++ b/vibrator/aidl/default/main.cpp
@@ -15,19 +15,29 @@
*/
#include "vibrator-impl/Vibrator.h"
+#include "vibrator-impl/VibratorManager.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using aidl::android::hardware::vibrator::Vibrator;
+using aidl::android::hardware::vibrator::VibratorManager;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
- std::shared_ptr<Vibrator> vib = ndk::SharedRefBase::make<Vibrator>();
- const std::string instance = std::string() + Vibrator::descriptor + "/default";
- binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str());
+ // make a default vibrator service
+ auto vib = ndk::SharedRefBase::make<Vibrator>();
+ const std::string vibName = std::string() + Vibrator::descriptor + "/default";
+ binder_status_t status = AServiceManager_addService(vib->asBinder().get(), vibName.c_str());
+ CHECK(status == STATUS_OK);
+
+ // make the vibrator manager service with a different vibrator
+ auto managedVib = ndk::SharedRefBase::make<Vibrator>();
+ auto vibManager = ndk::SharedRefBase::make<VibratorManager>(std::move(managedVib));
+ const std::string vibManagerName = std::string() + VibratorManager::descriptor + "/default";
+ status = AServiceManager_addService(vibManager->asBinder().get(), vibManagerName.c_str());
CHECK(status == STATUS_OK);
ABinderProcess_joinThreadPool();
diff --git a/vibrator/aidl/default/vibrator-default.xml b/vibrator/aidl/default/vibrator-default.xml
index 49b11ec..9f9cd40 100644
--- a/vibrator/aidl/default/vibrator-default.xml
+++ b/vibrator/aidl/default/vibrator-default.xml
@@ -3,4 +3,8 @@
<name>android.hardware.vibrator</name>
<fqname>IVibrator/default</fqname>
</hal>
+ <hal format="aidl">
+ <name>android.hardware.vibrator</name>
+ <fqname>IVibratorManager/default</fqname>
+ </hal>
</manifest>
diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp
index 28cb4d9..d06b50e 100644
--- a/vibrator/aidl/vts/Android.bp
+++ b/vibrator/aidl/vts/Android.bp
@@ -9,7 +9,26 @@
"libbinder",
],
static_libs: [
- "android.hardware.vibrator-cpp",
+ "android.hardware.vibrator-unstable-cpp",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
+
+cc_test {
+ name: "VtsHalVibratorManagerTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalVibratorManagerTargetTest.cpp"],
+ shared_libs: [
+ "libbinder",
+ ],
+ static_libs: [
+ "android.hardware.vibrator-unstable-cpp",
],
test_suites: [
"general-tests",
diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
new file mode 100644
index 0000000..9789188
--- /dev/null
+++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
@@ -0,0 +1,220 @@
+/*
+ * 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 <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <android/hardware/vibrator/BnVibratorCallback.h>
+#include <android/hardware/vibrator/IVibrator.h>
+#include <android/hardware/vibrator/IVibratorManager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include <cmath>
+#include <future>
+
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using android::binder::Status;
+using android::hardware::vibrator::BnVibratorCallback;
+using android::hardware::vibrator::CompositeEffect;
+using android::hardware::vibrator::CompositePrimitive;
+using android::hardware::vibrator::Effect;
+using android::hardware::vibrator::EffectStrength;
+using android::hardware::vibrator::IVibrator;
+using android::hardware::vibrator::IVibratorManager;
+using std::chrono::high_resolution_clock;
+
+const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
+ android::enum_range<Effect>().end()};
+const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
+ android::enum_range<EffectStrength>().end()};
+const std::vector<CompositePrimitive> kPrimitives{android::enum_range<CompositePrimitive>().begin(),
+ android::enum_range<CompositePrimitive>().end()};
+
+class CompletionCallback : public BnVibratorCallback {
+ public:
+ CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
+ Status onComplete() override {
+ mCallback();
+ return Status::ok();
+ }
+
+ private:
+ std::function<void()> mCallback;
+};
+
+class VibratorAidl : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ manager = android::waitForDeclaredService<IVibratorManager>(String16(GetParam().c_str()));
+ ASSERT_NE(manager, nullptr);
+ ASSERT_TRUE(manager->getCapabilities(&capabilities).isOk());
+ EXPECT_TRUE(manager->getVibratorIds(&vibratorIds).isOk());
+ }
+
+ sp<IVibratorManager> manager;
+ int32_t capabilities;
+ std::vector<int32_t> vibratorIds;
+};
+
+TEST_P(VibratorAidl, ValidateExistingVibrators) {
+ sp<IVibrator> vibrator;
+ for (auto& id : vibratorIds) {
+ EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ ASSERT_NE(vibrator, nullptr);
+ }
+}
+
+TEST_P(VibratorAidl, GetVibratorWithInvalidId) {
+ int32_t invalidId = *max_element(vibratorIds.begin(), vibratorIds.end()) + 1;
+ sp<IVibrator> vibrator;
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+ manager->getVibrator(invalidId, &vibrator).exceptionCode());
+ ASSERT_EQ(vibrator, nullptr);
+}
+
+TEST_P(VibratorAidl, ValidatePrepareSyncedExistingVibrators) {
+ if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+ if (vibratorIds.empty()) return;
+ EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+}
+
+TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) {
+ if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+ std::vector<int32_t> emptyIds;
+ EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, manager->prepareSynced(emptyIds).exceptionCode());
+}
+
+TEST_P(VibratorAidl, PrepareSyncedNotSupported) {
+ if (!(capabilities & IVibratorManager::CAP_SYNC)) {
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+ manager->prepareSynced(vibratorIds).exceptionCode());
+ }
+}
+
+TEST_P(VibratorAidl, PrepareOnNotSupported) {
+ if (vibratorIds.empty()) return;
+ if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+ if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
+ uint32_t durationMs = 250;
+ EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+ sp<IVibrator> vibrator;
+ for (auto& id : vibratorIds) {
+ EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ ASSERT_NE(vibrator, nullptr);
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+ vibrator->on(durationMs, nullptr).exceptionCode());
+ }
+ EXPECT_TRUE(manager->cancelSynced().isOk());
+ }
+}
+
+TEST_P(VibratorAidl, PreparePerformNotSupported) {
+ if (vibratorIds.empty()) return;
+ if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+ if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
+ EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+ sp<IVibrator> vibrator;
+ for (auto& id : vibratorIds) {
+ EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ ASSERT_NE(vibrator, nullptr);
+ int32_t lengthMs = 0;
+ Status status = vibrator->perform(kEffects[0], kEffectStrengths[0], nullptr, &lengthMs);
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
+ }
+ EXPECT_TRUE(manager->cancelSynced().isOk());
+ }
+}
+
+TEST_P(VibratorAidl, PrepareComposeNotSupported) {
+ if (vibratorIds.empty()) return;
+ if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+ if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
+ std::vector<CompositeEffect> composite;
+ CompositeEffect effect;
+ effect.delayMs = 10;
+ effect.primitive = kPrimitives[0];
+ effect.scale = 1.0f;
+ composite.emplace_back(effect);
+
+ EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+ sp<IVibrator> vibrator;
+ for (auto& id : vibratorIds) {
+ EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ ASSERT_NE(vibrator, nullptr);
+ Status status = vibrator->compose(composite, nullptr);
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
+ }
+ EXPECT_TRUE(manager->cancelSynced().isOk());
+ }
+}
+
+TEST_P(VibratorAidl, TriggerWithCallback) {
+ if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+ if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) return;
+ if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) return;
+ if (vibratorIds.empty()) return;
+
+ std::promise<void> completionPromise;
+ std::future<void> completionFuture{completionPromise.get_future()};
+ sp<CompletionCallback> callback =
+ new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+ uint32_t durationMs = 250;
+ std::chrono::milliseconds timeout{durationMs * 2};
+
+ EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+ sp<IVibrator> vibrator;
+ for (auto& id : vibratorIds) {
+ EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ ASSERT_NE(vibrator, nullptr);
+ EXPECT_TRUE(vibrator->on(durationMs, nullptr).isOk());
+ }
+
+ EXPECT_TRUE(manager->triggerSynced(callback).isOk());
+ EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
+ EXPECT_TRUE(manager->cancelSynced().isOk());
+}
+
+TEST_P(VibratorAidl, TriggerSyncNotSupported) {
+ if (!(capabilities & IVibratorManager::CAP_SYNC)) {
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+ manager->triggerSynced(nullptr).exceptionCode());
+ }
+}
+
+TEST_P(VibratorAidl, TriggerCallbackNotSupported) {
+ if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+ if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) {
+ sp<CompletionCallback> callback = new CompletionCallback([] {});
+ EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+ EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+ manager->triggerSynced(callback).exceptionCode());
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
+INSTANTIATE_TEST_SUITE_P(
+ Vibrator, VibratorAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IVibratorManager::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 888a403..dfd2524 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -18,6 +18,7 @@
#include <android/hardware/vibrator/BnVibratorCallback.h>
#include <android/hardware/vibrator/IVibrator.h>
+#include <android/hardware/vibrator/IVibratorManager.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
@@ -34,6 +35,7 @@
using android::hardware::vibrator::Effect;
using android::hardware::vibrator::EffectStrength;
using android::hardware::vibrator::IVibrator;
+using android::hardware::vibrator::IVibratorManager;
using std::chrono::high_resolution_clock;
const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
@@ -77,10 +79,28 @@
std::function<void()> mCallback;
};
-class VibratorAidl : public testing::TestWithParam<std::string> {
+class VibratorAidl : public testing::TestWithParam<std::tuple<int32_t, int32_t>> {
public:
virtual void SetUp() override {
- vibrator = android::waitForDeclaredService<IVibrator>(String16(GetParam().c_str()));
+ int32_t managerIdx = std::get<0>(GetParam());
+ int32_t vibratorId = std::get<1>(GetParam());
+ auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
+
+ if (managerIdx < 0) {
+ // Testing a unmanaged vibrator, using vibratorId as index from registered HALs
+ auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
+ ASSERT_LT(vibratorId, vibratorAidlNames.size());
+ auto vibratorName = String16(vibratorAidlNames[vibratorId].c_str());
+ vibrator = android::waitForDeclaredService<IVibrator>(vibratorName);
+ } else {
+ // Testing a managed vibrator, using vibratorId to retrieve it from the manager
+ ASSERT_LT(managerIdx, managerAidlNames.size());
+ auto managerName = String16(managerAidlNames[managerIdx].c_str());
+ auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
+ auto vibratorResult = vibratorManager->getVibrator(vibratorId, &vibrator);
+ ASSERT_TRUE(vibratorResult.isOk());
+ }
+
ASSERT_NE(vibrator, nullptr);
ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
}
@@ -518,10 +538,41 @@
}
}
+std::vector<std::tuple<int32_t, int32_t>> GenerateVibratorMapping() {
+ std::vector<std::tuple<int32_t, int32_t>> tuples;
+ auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
+ std::vector<int32_t> vibratorIds;
+
+ for (int i = 0; i < managerAidlNames.size(); i++) {
+ auto managerName = String16(managerAidlNames[i].c_str());
+ auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
+ if (vibratorManager->getVibratorIds(&vibratorIds).isOk()) {
+ for (auto& vibratorId : vibratorIds) {
+ tuples.push_back(std::make_tuple(i, vibratorId));
+ }
+ }
+ }
+
+ auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
+ for (int i = 0; i < vibratorAidlNames.size(); i++) {
+ tuples.push_back(std::make_tuple(-1, i));
+ }
+
+ return tuples;
+}
+
+std::string PrintGeneratedTest(const testing::TestParamInfo<VibratorAidl::ParamType>& info) {
+ const auto& [managerIdx, vibratorId] = info.param;
+ if (managerIdx < 0) {
+ return std::string("TOP_LEVEL_VIBRATOR_") + std::to_string(vibratorId);
+ }
+ return std::string("MANAGER_") + std::to_string(managerIdx) + "_VIBRATOR_ID_" +
+ std::to_string(vibratorId);
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
-INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
- testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
- android::PrintInstanceNameToString);
+INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(GenerateVibratorMapping()),
+ PrintGeneratedTest);
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
diff --git a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp
index fc7dcd6..5b0f173 100644
--- a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp
+++ b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -59,7 +59,7 @@
* code.
*/
TEST_P(WifiApIfaceHidlTest, SetMacAddress) {
- const hidl_array<uint8_t, 6> kMac{{0x12, 0x22, 0x33, 0x52, 0x10, 0x41}};
+ const hidl_array<uint8_t, 6> kMac{{0x12, 0x22, 0x33, 0x52, 0x10, 0x44}};
EXPECT_EQ(WifiStatusCode::SUCCESS,
HIDL_INVOKE(wifi_ap_iface_, setMacAddress, kMac).code);
}
diff --git a/wifi/1.5/default/wifi_feature_flags.cpp b/wifi/1.5/default/wifi_feature_flags.cpp
index 9f91bd7..124ba32 100644
--- a/wifi/1.5/default/wifi_feature_flags.cpp
+++ b/wifi/1.5/default/wifi_feature_flags.cpp
@@ -14,6 +14,11 @@
* limitations under the License.
*/
+#include <string>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
#include "wifi_feature_flags.h"
namespace android {
@@ -131,7 +136,7 @@
#define AP IfaceType::AP
#define P2P IfaceType::P2P
#define NAN IfaceType::NAN
-static const std::vector<IWifiChip::ChipMode> kChipModes{
+static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
{kMainModeId,
ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})},
#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
@@ -146,6 +151,50 @@
{WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
#endif
};
+
+constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
+ "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
+// List of pre-defined interface combinations that can be enabled at runtime via
+// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
+// corresponding index value.
+static const std::vector<
+ std::pair<std::string, std::vector<IWifiChip::ChipMode>>>
+ kDebugChipModes{
+ // Legacy combination - No STA/AP concurrencies.
+ // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
+ {"No STA/AP Concurrency",
+ {{kMainModeId,
+ ChipIfaceCombination::make_vec(
+ {{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + AP concurrency
+ // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+ {"STA + AP Concurrency",
+ {{kMainModeId,
+ ChipIfaceCombination::make_vec(
+ {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + STA concurrency
+ // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
+ {"Dual STA Concurrency",
+ {{kMainModeId,
+ ChipIfaceCombination::make_vec(
+ {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+ // AP + AP + STA concurrency
+ // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
+ {"Dual AP Concurrency",
+ {{kMainModeId,
+ ChipIfaceCombination::make_vec(
+ {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + STA concurrency and AP + AP + STA concurrency
+ // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
+ {"Dual STA & Dual AP Concurrency",
+ {{kMainModeId,
+ ChipIfaceCombination::make_vec(
+ {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}};
+
#undef STA
#undef AP
#undef P2P
@@ -161,9 +210,31 @@
WifiFeatureFlags::WifiFeatureFlags() {}
+std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty,
+ buffer.data(), nullptr);
+ // Debug propety not set, use the device preset interface combination.
+ if (res <= 0) return kChipModesPrimary;
+
+ // Debug propety set, use one of the debug preset interface combination.
+ unsigned long idx = std::stoul(buffer.data());
+ if (idx >= kDebugChipModes.size()) {
+ LOG(ERROR) << "Invalid index set in property: "
+ << kDebugPresetInterfaceCombinationIdxProperty;
+ return kChipModesPrimary;
+ }
+ std::string name;
+ std::vector<IWifiChip::ChipMode> chip_modes;
+ std::tie(name, chip_modes) = kDebugChipModes[idx];
+ LOG(INFO) << "Using debug chip mode: <" << name << "> set via property: "
+ << kDebugPresetInterfaceCombinationIdxProperty;
+ return chip_modes;
+}
+
std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(
bool is_primary) {
- return (is_primary) ? kChipModes : kChipModesSecondary;
+ return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
}
} // namespace feature_flags
diff --git a/wifi/1.5/default/wifi_feature_flags.h b/wifi/1.5/default/wifi_feature_flags.h
index cb68b8c..7d561fc 100644
--- a/wifi/1.5/default/wifi_feature_flags.h
+++ b/wifi/1.5/default/wifi_feature_flags.h
@@ -44,6 +44,9 @@
virtual std::vector<V1_0::IWifiChip::ChipMode> getChipModes(
bool is_primary);
+
+ private:
+ std::vector<V1_0::IWifiChip::ChipMode> getChipModesForPrimary();
};
} // namespace feature_flags
diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
index 9234a5b..bdbe651 100644
--- a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp
@@ -468,5 +468,5 @@
testing::ValuesIn(
android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
testing::ValuesIn(android::hardware::getAllHalInstanceNames(
- android::hardware::wifi::hostapd::V1_2::IHostapd::descriptor))),
+ android::hardware::wifi::hostapd::V1_3::IHostapd::descriptor))),
android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 6b85e00..1c3141e 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -22,6 +22,7 @@
#include <VtsCoreUtil.h>
#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
+#include <android/hardware/wifi/supplicant/1.1/ISupplicantStaIface.h>
#include "supplicant_hidl_call_util.h"
#include "supplicant_hidl_test_utils.h"
@@ -73,11 +74,16 @@
sta_iface_ = getSupplicantStaIface(supplicant_);
ASSERT_NE(sta_iface_.get(), nullptr);
+ v1_1 = ::android::hardware::wifi::supplicant::V1_1::
+ ISupplicantStaIface::castFrom(sta_iface_);
+
memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size());
}
protected:
bool isP2pOn_ = false;
+ sp<::android::hardware::wifi::supplicant::V1_1::ISupplicantStaIface> v1_1 =
+ nullptr;
// ISupplicantStaIface object used for all tests in this fixture.
sp<ISupplicantStaIface> sta_iface_;
// MAC address to use for various tests.
@@ -175,10 +181,13 @@
* RegisterCallback
*/
TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback) {
- sta_iface_->registerCallback(
- new IfaceCallback(), [](const SupplicantStatus& status) {
- EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
- });
+ SupplicantStatusCode expectedCode =
+ (nullptr != v1_1) ? SupplicantStatusCode::FAILURE_UNKNOWN
+ : SupplicantStatusCode::SUCCESS;
+ sta_iface_->registerCallback(new IfaceCallback(),
+ [&](const SupplicantStatus& status) {
+ EXPECT_EQ(expectedCode, status.code);
+ });
}
/*
diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp
index 44b020e..ee80628 100644
--- a/wifi/supplicant/1.1/vts/functional/Android.bp
+++ b/wifi/supplicant/1.1/vts/functional/Android.bp
@@ -47,6 +47,7 @@
"VtsHalWifiSupplicantV1_1TargetTestUtil",
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
+ "android.hardware.wifi.supplicant@1.2",
"android.hardware.wifi@1.0",
"android.hardware.wifi@1.1",
"libgmock",
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
index 8d7ea54..a8e72b8 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
@@ -75,7 +75,7 @@
* AddP2pInterface
*/
TEST_P(SupplicantHidlTest, AddP2pInterface) {
- if (isP2pOn_) return;
+ if (!isP2pOn_) return;
ISupplicant::IfaceInfo iface_info;
iface_info.name = getP2pIfaceName();
iface_info.type = IfaceType::P2P;
@@ -115,7 +115,7 @@
* RemoveP2pInterface
*/
TEST_P(SupplicantHidlTest, RemoveP2pInterface) {
- if (isP2pOn_) return;
+ if (!isP2pOn_) return;
ISupplicant::IfaceInfo iface_info;
iface_info.name = getP2pIfaceName();
iface_info.type = IfaceType::P2P;
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp
index db6323c..418def2 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/1.1/IWifi.h>
#include <android/hardware/wifi/supplicant/1.1/ISupplicantStaIface.h>
+#include <android/hardware/wifi/supplicant/1.2/ISupplicantStaIface.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
@@ -45,11 +46,16 @@
SupplicantHidlTestBaseV1_1::SetUp();
sta_iface_ = getSupplicantStaIface_1_1(supplicant_);
ASSERT_NE(sta_iface_.get(), nullptr);
+
+ v1_2 = ::android::hardware::wifi::supplicant::V1_2::
+ ISupplicantStaIface::castFrom(sta_iface_);
}
protected:
// ISupplicantStaIface object used for all tests in this fixture.
sp<ISupplicantStaIface> sta_iface_;
+ sp<::android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface> v1_2 =
+ nullptr;
};
class IfaceCallback : public ISupplicantStaIfaceCallback {
@@ -133,10 +139,13 @@
* RegisterCallback_1_1
*/
TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_1) {
- sta_iface_->registerCallback_1_1(
- new IfaceCallback(), [](const SupplicantStatus& status) {
- EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
- });
+ SupplicantStatusCode expectedCode =
+ (nullptr != v1_2) ? SupplicantStatusCode::FAILURE_UNKNOWN
+ : SupplicantStatusCode::SUCCESS;
+ sta_iface_->registerCallback_1_1(new IfaceCallback(),
+ [&](const SupplicantStatus& status) {
+ EXPECT_EQ(expectedCode, status.code);
+ });
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest);
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
index cd08468..7799390 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -60,6 +60,9 @@
sta_iface_ = getSupplicantStaIface_1_2(supplicant_);
ASSERT_NE(sta_iface_.get(), nullptr);
count_ = 0;
+
+ v1_3 = ::android::hardware::wifi::supplicant::V1_3::
+ ISupplicantStaIface::castFrom(sta_iface_);
}
enum DppCallbackType {
@@ -102,6 +105,7 @@
protected:
// ISupplicantStaIface object used for all tests in this fixture.
sp<ISupplicantStaIface> sta_iface_;
+ sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3;
bool isDppSupported() {
uint32_t keyMgmtMask = 0;
@@ -262,10 +266,13 @@
* RegisterCallback_1_2
*/
TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_2) {
- sta_iface_->registerCallback_1_2(
- new IfaceCallback(), [](const SupplicantStatus& status) {
- EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
- });
+ SupplicantStatusCode expectedCode =
+ (nullptr != v1_3) ? SupplicantStatusCode::FAILURE_UNKNOWN
+ : SupplicantStatusCode::SUCCESS;
+ sta_iface_->registerCallback_1_2(new IfaceCallback(),
+ [&](const SupplicantStatus& status) {
+ EXPECT_EQ(expectedCode, status.code);
+ });
}
/*
@@ -339,9 +346,6 @@
* it is waiting for will never be called. Note that this test is also
* implemented in the 1.3 VTS test.
*/
- sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3 =
- ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface::
- castFrom(sta_iface_);
if (v1_3 != nullptr) {
GTEST_SKIP() << "Test not supported with this HAL version";
}
@@ -404,10 +408,6 @@
* it is waiting for will never be called. Note that this test is also
* implemented in the 1.3 VTS test.
*/
- sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3 =
- ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface::
- castFrom(sta_iface_);
-
if (v1_3 != nullptr) {
GTEST_SKIP() << "Test not supported with this HAL version";
return;
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 189e2b9..9ffe0ec 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -325,10 +325,13 @@
* RegisterCallback_1_3
*/
TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_3) {
- sta_iface_->registerCallback_1_3(
- new IfaceCallback(), [](const SupplicantStatus& status) {
- EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
- });
+ SupplicantStatusCode expectedCode =
+ (nullptr != sta_iface_v1_4_) ? SupplicantStatusCode::FAILURE_UNKNOWN
+ : SupplicantStatusCode::SUCCESS;
+ sta_iface_->registerCallback_1_3(new IfaceCallback(),
+ [&](const SupplicantStatus& status) {
+ EXPECT_EQ(expectedCode, status.code);
+ });
}
/*
@@ -428,6 +431,11 @@
return;
}
+ if (sta_iface_v1_4_ != nullptr) {
+ GTEST_SKIP() << "Test not supported with this HAL version";
+ return;
+ }
+
hidl_string uri =
"DPP:C:81/1,117/"
"40;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj"
@@ -480,6 +488,11 @@
return;
}
+ if (sta_iface_v1_4_ != nullptr) {
+ GTEST_SKIP() << "Test not supported with this HAL version";
+ return;
+ }
+
hidl_string uri =
"DPP:C:81/1,117/"
"40;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj"