Merge "Patch cec@1.0 hal to add two Cec message types"
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index b04adf7..6498289 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -22,6 +22,7 @@
"libaudiopolicycomponents",
"libicuuc",
"libicuuc_stubdata",
+ "libandroidicu",
"libmedia_helper",
"libxml2",
],
diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp
index 88d49d8..de6cad9 100644
--- a/audio/effect/all-versions/vts/functional/Android.bp
+++ b/audio/effect/all-versions/vts/functional/Android.bp
@@ -28,6 +28,7 @@
"libeffectsconfig",
"libicuuc",
"libicuuc_stubdata",
+ "libandroidicu",
"libxml2",
],
header_libs: [
diff --git a/automotive/OWNERS b/automotive/OWNERS
new file mode 100644
index 0000000..4a94494
--- /dev/null
+++ b/automotive/OWNERS
@@ -0,0 +1,3 @@
+randolphs@google.com
+pirozzoj@google.com
+twasilczyk@google.com
diff --git a/automotive/vehicle/2.0/default/OWNERS b/automotive/vehicle/2.0/default/OWNERS
deleted file mode 100644
index d5d9d4c..0000000
--- a/automotive/vehicle/2.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-egranata@google.com
-pavelm@google.com
-spaik@google.com
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 4751a76..e874146 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -131,6 +131,9 @@
* When a property's status field is not set to AVAILABLE:
* - IVehicle#set may return StatusCode::NOT_AVAILABLE.
* - IVehicle#get is not guaranteed to work.
+ *
+ * Properties set to values out of range must be ignored and no action taken
+ * in response to such ill formed requests.
*/
enum VehicleProperty : int32_t {
@@ -243,7 +246,7 @@
* Fuel door location
*
* @change_mode VehiclePropertyChangeMode:STATIC
- * @data_enum FuelDoorLocationType
+ * @data_enum PortLocationType
* @access VehiclePropertyAccess:READ
*/
INFO_FUEL_DOOR_LOCATION = (
@@ -267,6 +270,7 @@
/**
* Driver's seat location
+ * VHAL implementations must ignore the areaId. Use VehicleArea:GLOBAL.
*
* @change_mode VehiclePropertyChangeMode:STATIC
* @data_enum VehicleAreaSeat
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index b96f574..0f23657 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -378,8 +378,12 @@
const uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
UPDATE(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, ×tampSource, 1);
- // Orientation probably isn't useful for external facing camera?
- const int32_t orientation = 0;
+ // Orientation is a bit odd for external camera, but consider it as the orientation
+ // between the external camera sensor (which is usually landscape) and the device's
+ // natural display orientation. For devices with natural landscape display (ex: tablet/TV), the
+ // orientation should be 0. For devices with natural portrait display (phone), the orientation
+ // should be 270.
+ const int32_t orientation = mCfg.orientation;
UPDATE(ANDROID_SENSOR_ORIENTATION, &orientation, 1);
// android.shading
diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp
index 680c95a..0941052 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -160,9 +160,11 @@
namespace common {
namespace {
- const int kDefaultJpegBufSize = 5 << 20; // 5MB
- const int kDefaultNumVideoBuffer = 4;
- const int kDefaultNumStillBuffer = 2;
+ const int kDefaultJpegBufSize = 5 << 20; // 5MB
+ const int kDefaultNumVideoBuffer = 4;
+ const int kDefaultNumStillBuffer = 2;
+ const int kDefaultOrientation = 0; // suitable for natural landscape displays like tablet/TV
+ // For phone devices 270 is better
} // anonymous namespace
const char* ExternalCameraConfig::kDefaultCfgPath = "/vendor/etc/external_camera_config.xml";
@@ -276,10 +278,17 @@
minStreamSize->UnsignedAttribute("height", /*Default*/0)};
}
+ XMLElement *orientation = deviceCfg->FirstChildElement("Orientation");
+ if (orientation == nullptr) {
+ ALOGI("%s: no sensor orientation specified", __FUNCTION__);
+ } else {
+ ret.orientation = orientation->IntAttribute("degree", /*Default*/kDefaultOrientation);
+ }
+
ALOGI("%s: external camera cfg loaded: maxJpgBufSize %d,"
- " num video buffers %d, num still buffers %d",
+ " num video buffers %d, num still buffers %d, orientation %d",
__FUNCTION__, ret.maxJpegBufSize,
- ret.numVideoBuffers, ret.numStillBuffers);
+ ret.numVideoBuffers, ret.numStillBuffers, ret.orientation);
for (const auto& limit : ret.fpsLimits) {
ALOGI("%s: fpsLimitList: %dx%d@%f", __FUNCTION__,
limit.size.width, limit.size.height, limit.fpsUpperBound);
@@ -292,7 +301,8 @@
ExternalCameraConfig::ExternalCameraConfig() :
maxJpegBufSize(kDefaultJpegBufSize),
numVideoBuffers(kDefaultNumVideoBuffer),
- numStillBuffers(kDefaultNumStillBuffer) {
+ numStillBuffers(kDefaultNumStillBuffer),
+ orientation(kDefaultOrientation) {
fpsLimits.push_back({/*Size*/{ 640, 480}, /*FPS upper bound*/30.0});
fpsLimits.push_back({/*Size*/{1280, 720}, /*FPS upper bound*/7.5});
fpsLimits.push_back({/*Size*/{1920, 1080}, /*FPS upper bound*/5.0});
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
index 5754ccb..3b1ac96 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
@@ -80,6 +80,9 @@
// Minimum output stream size
Size minStreamSize;
+ // The value of android.sensor.orientation
+ int32_t orientation;
+
private:
ExternalCameraConfig();
};
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index d4c422d..42ac921 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -240,6 +240,14 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.input.classifier</name>
+ <version>1.0</version>
+ <interface>
+ <name>IInputClassifier</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="false">
<name>android.hardware.keymaster</name>
<version>3.0</version>
@@ -367,6 +375,7 @@
<hal format="hidl" optional="true">
<name>android.hardware.sensors</name>
<version>1.0</version>
+ <version>2.0</version>
<interface>
<name>ISensors</name>
<instance>default</instance>
@@ -439,7 +448,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.vibrator</name>
- <version>1.0-2</version>
+ <version>1.0-3</version>
<interface>
<name>IVibrator</name>
<instance>default</instance>
diff --git a/drm/1.0/default/Android.mk b/drm/1.0/default/Android.mk
index 99773be..d66f377 100644
--- a/drm/1.0/default/Android.mk
+++ b/drm/1.0/default/Android.mk
@@ -19,39 +19,23 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
+
+include $(LOCAL_PATH)/common_default_service.mk
LOCAL_MODULE := android.hardware.drm@1.0-service
LOCAL_INIT_RC := android.hardware.drm@1.0-service.rc
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
- service.cpp \
+LOCAL_SRC_FILES := service.cpp
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.drm@1.0 \
- android.hidl.memory@1.0 \
- libhidlbase \
- libhidltransport \
- libhardware \
- liblog \
- libutils \
- libbinder \
+include $(BUILD_EXECUTABLE)
-LOCAL_STATIC_LIBRARIES := \
- android.hardware.drm@1.0-helper \
+############# Build legacy drm lazy service ############
-LOCAL_C_INCLUDES := \
- hardware/interfaces/drm
+include $(CLEAR_VARS)
-LOCAL_HEADER_LIBRARIES := \
- media_plugin_headers
-
-# TODO(b/18948909) Some legacy DRM plugins only support 32-bit. They need to be
-# migrated to 64-bit. Once all of a device's legacy DRM plugins support 64-bit,
-# that device can turn on TARGET_ENABLE_MEDIADRM_64 to build this service as
-# 64-bit.
-ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
-LOCAL_32_BIT_ONLY := true
-endif
+include $(LOCAL_PATH)/common_default_service.mk
+LOCAL_MODULE := android.hardware.drm@1.0-service-lazy
+LOCAL_OVERRIDES_MODULES := android.hardware.drm@1.0-service
+LOCAL_INIT_RC := android.hardware.drm@1.0-service-lazy.rc
+LOCAL_SRC_FILES := serviceLazy.cpp
include $(BUILD_EXECUTABLE)
diff --git a/drm/1.0/default/android.hardware.drm@1.0-service-lazy.rc b/drm/1.0/default/android.hardware.drm@1.0-service-lazy.rc
new file mode 100644
index 0000000..4b32f7f
--- /dev/null
+++ b/drm/1.0/default/android.hardware.drm@1.0-service-lazy.rc
@@ -0,0 +1,10 @@
+service vendor.drm-hal-1-0 /vendor/bin/hw/android.hardware.drm@1.0-service-lazy
+ interface android.hardware.drm@1.0::ICryptoFactory default
+ interface android.hardware.drm@1.0::IDrmFactory default
+ oneshot
+ disabled
+ class hal
+ user media
+ group mediadrm drmrpc
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
diff --git a/drm/1.0/default/android.hardware.drm@1.0-service.rc b/drm/1.0/default/android.hardware.drm@1.0-service.rc
index a3457b5..790eded 100644
--- a/drm/1.0/default/android.hardware.drm@1.0-service.rc
+++ b/drm/1.0/default/android.hardware.drm@1.0-service.rc
@@ -1,4 +1,6 @@
service vendor.drm-hal-1-0 /vendor/bin/hw/android.hardware.drm@1.0-service
+ interface android.hardware.drm@1.0::ICryptoFactory default
+ interface android.hardware.drm@1.0::IDrmFactory default
class hal
user media
group mediadrm drmrpc
diff --git a/drm/1.0/default/common_default_service.mk b/drm/1.0/default/common_default_service.mk
new file mode 100644
index 0000000..28db567
--- /dev/null
+++ b/drm/1.0/default/common_default_service.mk
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2019 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 $(CLEAR_VARS)
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+
+LOCAL_SHARED_LIBRARIES := \
+ android.hardware.drm@1.0 \
+ android.hidl.memory@1.0 \
+ libhidlbase \
+ libhidltransport \
+ libhardware \
+ liblog \
+ libutils \
+ libbinder \
+
+LOCAL_STATIC_LIBRARIES := \
+ android.hardware.drm@1.0-helper \
+
+LOCAL_C_INCLUDES := \
+ hardware/interfaces/drm
+
+LOCAL_HEADER_LIBRARIES := \
+ media_plugin_headers
+
+# TODO(b/18948909) Some legacy DRM plugins only support 32-bit. They need to be
+# migrated to 64-bit. Once all of a device's legacy DRM plugins support 64-bit,
+# that device can turn on TARGET_ENABLE_MEDIADRM_64 to build this service as
+# 64-bit.
+ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
+LOCAL_32_BIT_ONLY := true
+endif
diff --git a/drm/1.0/default/service.cpp b/drm/1.0/default/service.cpp
index 1a44ce2..98d2c3b 100644
--- a/drm/1.0/default/service.cpp
+++ b/drm/1.0/default/service.cpp
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.drm@1.0-service"
#include <1.0/default/CryptoFactory.h>
#include <1.0/default/DrmFactory.h>
@@ -31,15 +30,8 @@
using android::hardware::drm::V1_0::IDrmFactory;
int main() {
- ALOGD("android.hardware.drm@1.0-service starting...");
-
- // The DRM HAL may communicate to other vendor components via
- // /dev/vndbinder
- android::ProcessState::initWithDriver("/dev/vndbinder");
-
configureRpcThreadpool(8, true /* callerWillJoin */);
- android::status_t status =
- registerPassthroughServiceImplementation<IDrmFactory>();
+ android::status_t status = registerPassthroughServiceImplementation<IDrmFactory>();
LOG_ALWAYS_FATAL_IF(
status != android::OK,
"Error while registering drm service: %d", status);
diff --git a/drm/1.0/default/serviceLazy.cpp b/drm/1.0/default/serviceLazy.cpp
new file mode 100644
index 0000000..e5068b5
--- /dev/null
+++ b/drm/1.0/default/serviceLazy.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 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 <1.0/default/CryptoFactory.h>
+#include <1.0/default/DrmFactory.h>
+
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+
+#include <binder/ProcessState.h>
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::registerLazyPassthroughServiceImplementation;
+
+using android::hardware::drm::V1_0::ICryptoFactory;
+using android::hardware::drm::V1_0::IDrmFactory;
+
+int main() {
+ configureRpcThreadpool(8, true /* callerWillJoin */);
+ android::status_t status = registerLazyPassthroughServiceImplementation<IDrmFactory>();
+ LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering drm service: %d", status);
+ status = registerLazyPassthroughServiceImplementation<ICryptoFactory>();
+ LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering crypto service: %d",
+ status);
+ joinRpcThreadpool();
+}
diff --git a/gnss/2.0/Android.bp b/gnss/2.0/Android.bp
index 200671e..9b6b076 100644
--- a/gnss/2.0/Android.bp
+++ b/gnss/2.0/Android.bp
@@ -13,6 +13,7 @@
"IAGnssRil.hal",
"IGnss.hal",
"IGnssCallback.hal",
+ "IGnssConfiguration.hal",
"IGnssMeasurement.hal",
"IGnssMeasurementCallback.hal",
],
diff --git a/gnss/2.0/IGnss.hal b/gnss/2.0/IGnss.hal
index fb8b040..e1acd6d 100644
--- a/gnss/2.0/IGnss.hal
+++ b/gnss/2.0/IGnss.hal
@@ -20,13 +20,14 @@
import @1.1::IGnss;
import IGnssCallback;
+import IGnssConfiguration;
import IGnssMeasurement;
import IAGnss;
import IAGnssRil;
/** Represents the standard GNSS (Global Navigation Satellite System) interface. */
interface IGnss extends @1.1::IGnss {
- /**
+ /**
* Opens the interface and provides the callback routines to the implementation of this
* interface.
*
@@ -37,6 +38,13 @@
setCallback_2_0(IGnssCallback callback) generates (bool success);
/**
+ * This method returns the IGnssConfiguration interface.
+ *
+ * @return gnssConfigurationIface Handle to the IGnssConfiguration interface.
+ */
+ getExtensionGnssConfiguration_2_0() generates (IGnssConfiguration gnssConfigurationIface);
+
+ /**
* This method returns the IAGnss Interface.
*
* The getExtensionAGnss() must return nullptr as the @1.0::IAGnss interface is
diff --git a/gnss/2.0/IGnssConfiguration.hal b/gnss/2.0/IGnssConfiguration.hal
new file mode 100644
index 0000000..90c376e
--- /dev/null
+++ b/gnss/2.0/IGnssConfiguration.hal
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 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.gnss@2.0;
+
+import @1.1::IGnssConfiguration;
+
+/**
+ * Extended interface for GNSS Configuration support.
+ *
+ * Due to the introduction of new GNSS HAL package android.hardware.gnss.visibility_control@1.0
+ * the following methods in @1.0::IGnssConfiguration are deprecated in this version and not
+ * called by the framework.
+ *
+ * setGpsLock(bitfield<GpsLock> lock) generates (bool success);
+ * setSuplEs(bool enabled) generates (bool success);
+ */
+interface IGnssConfiguration extends @1.1::IGnssConfiguration {
+ /**
+ * This method sets the emergency session extension duration. The GNSS HAL
+ * implementation must serve emergency SUPL and Control Plane network initiated
+ * location requests for this extra duration after the user initiated emergency
+ * session ends.
+ *
+ * @param emergencyExtensionSeconds Number of seconds to extend the emergency
+ * session duration post emergency call.
+ *
+ * @return success True if the GNSS HAL implementation accepts and supports the
+ * extended duration for emergency SUPL and Control Plane location requests.
+ */
+ setEsExtensionSec(uint32_t emergencyExtensionSeconds) generates (bool success);
+};
\ No newline at end of file
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 9119ee4..92d5c1f 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -21,6 +21,7 @@
vendor: true,
vintf_fragments: ["android.hardware.gnss@2.0-service.xml"],
srcs: [
+ "GnssConfiguration.cpp",
"AGnss.cpp",
"AGnssRil.cpp",
"Gnss.cpp",
diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp
index bde904f..5c752d5 100644
--- a/gnss/2.0/default/Gnss.cpp
+++ b/gnss/2.0/default/Gnss.cpp
@@ -20,6 +20,7 @@
#include <log/log.h>
#include "AGnss.h"
#include "AGnssRil.h"
+#include "GnssConfiguration.h"
#include "GnssMeasurement.h"
using ::android::hardware::Status;
@@ -181,6 +182,10 @@
}
// Methods from V2_0::IGnss follow.
+Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
+ return new GnssConfiguration{};
+}
+
Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
return new AGnss{};
}
diff --git a/gnss/2.0/default/Gnss.h b/gnss/2.0/default/Gnss.h
index 47792cf..e86158f 100644
--- a/gnss/2.0/default/Gnss.h
+++ b/gnss/2.0/default/Gnss.h
@@ -72,6 +72,7 @@
Return<bool> injectBestLocation(const V1_0::GnssLocation& location) override;
// Methods from V2_0::IGnss follow.
+ Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
diff --git a/gnss/2.0/default/GnssConfiguration.cpp b/gnss/2.0/default/GnssConfiguration.cpp
new file mode 100644
index 0000000..4389dd2
--- /dev/null
+++ b/gnss/2.0/default/GnssConfiguration.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 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 "GnssConfiguration"
+
+#include "GnssConfiguration.h"
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enable) {
+ ALOGD("setSuplEs enable: %d", enable);
+ // Method deprecated in 2.0 and not expected to be called by the framework.
+ return false;
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setSuplMode(hidl_bitfield<SuplMode>) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setGpsLock(hidl_bitfield<GpsLock> gpsLock) {
+ ALOGD("setGpsLock gpsLock: %hhu", static_cast<GpsLock>(gpsLock));
+ // Method deprecated in 2.0 and not expected to be called by the framework.
+ return false;
+}
+
+Return<bool> GnssConfiguration::setLppProfile(hidl_bitfield<LppProfile>) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol>) {
+ // TODO implement
+ return bool{};
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool) {
+ // TODO implement
+ return bool{};
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+ const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>&) {
+ // TODO (b/122463906): Reuse 1.1 implementation.
+ return bool{};
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
+ ALOGD("setEsExtensionSec emergencyExtensionSeconds: %d", emergencyExtensionSeconds);
+ return true;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/gnss/2.0/default/GnssConfiguration.h b/gnss/2.0/default/GnssConfiguration.h
new file mode 100644
index 0000000..0c02ccd
--- /dev/null
+++ b/gnss/2.0/default/GnssConfiguration.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 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_GNSS_V2_0_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/2.0/IGnssConfiguration.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+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;
+
+struct GnssConfiguration : public IGnssConfiguration {
+ // Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+ Return<bool> setSuplEs(bool enabled) override;
+ Return<bool> setSuplVersion(uint32_t version) override;
+ Return<bool> setSuplMode(hidl_bitfield<SuplMode> mode) override;
+ Return<bool> setGpsLock(hidl_bitfield<GpsLock> lock) override;
+ Return<bool> setLppProfile(hidl_bitfield<LppProfile> lppProfile) override;
+ Return<bool> setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol> protocol) override;
+ Return<bool> setEmergencySuplPdn(bool enable) override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist(
+ const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+ Return<bool> setEsExtensionSec(uint32_t emergencyExtensionSeconds) override;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
\ No newline at end of file
diff --git a/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp b/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp
index ae36c50..a8e40ba 100644
--- a/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp
+++ b/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp
@@ -23,6 +23,7 @@
::testing::AddGlobalTestEnvironment(GnssHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
GnssHidlEnvironment::Instance()->init(&argc, argv);
+ // TODO (b/122463165): Expand coverage to include 1.1 and 1.0 VTS tests.
int status = RUN_ALL_TESTS();
ALOGI("Test result = %d", status);
return status;
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index ef232c9..cef06a2 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -21,6 +21,7 @@
using android::hardware::hidl_vec;
+using IGnssConfiguration_2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
using IAGnssRil_2_0 = android::hardware::gnss::V2_0::IAGnssRil;
using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
@@ -60,6 +61,56 @@
}
/*
+ * TestGnssConfigurationExtension:
+ * Gets the GnssConfigurationExtension and verifies that it returns an actual extension by
+ * calling a method.
+ *
+ * The GNSS HAL 2.0 implementation must support @2.0::IGnssConfiguration interface due to
+ * the deprecation of some methods in @1.0::IGnssConfiguration interface.
+ */
+TEST_F(GnssHalTest, TestGnssConfigurationExtension) {
+ auto gnssConfiguration = gnss_hal_->getExtensionGnssConfiguration_2_0();
+ ASSERT_TRUE(gnssConfiguration.isOk());
+ sp<IGnssConfiguration_2_0> iGnssConfiguration = gnssConfiguration;
+ ASSERT_NE(iGnssConfiguration, nullptr);
+
+ auto result = iGnssConfiguration->setEsExtensionSec(180);
+ ASSERT_TRUE(result.isOk());
+ // Expected result can be true or false depending on whether HAL implementation supports
+ // detecting emergency sessions without involving the framework.
+}
+
+/*
+ * TestGnssConfiguration_setSuplEs_Deprecation:
+ * Calls setSuplEs and verifies that it returns false.
+ */
+TEST_F(GnssHalTest, TestGnssConfiguration_setSuplEs_Deprecation) {
+ auto gnssConfiguration = gnss_hal_->getExtensionGnssConfiguration_2_0();
+ ASSERT_TRUE(gnssConfiguration.isOk());
+ sp<IGnssConfiguration_2_0> iGnssConfiguration = gnssConfiguration;
+ ASSERT_NE(iGnssConfiguration, nullptr);
+
+ auto result = iGnssConfiguration->setSuplEs(false);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_FALSE(result);
+}
+
+/*
+ * TestGnssConfiguration_setGpsLock_Deprecation:
+ * Calls setGpsLock and verifies that it returns false.
+ */
+TEST_F(GnssHalTest, TestGnssConfiguration_setGpsLock_Deprecation) {
+ auto gnssConfiguration = gnss_hal_->getExtensionGnssConfiguration_2_0();
+ ASSERT_TRUE(gnssConfiguration.isOk());
+ sp<IGnssConfiguration_2_0> iGnssConfiguration = gnssConfiguration;
+ ASSERT_NE(iGnssConfiguration, nullptr);
+
+ auto result = iGnssConfiguration->setGpsLock(0);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_FALSE(result);
+}
+
+/*
* TestAGnssRilExtension:
* Gets the AGnssRilExtension and verifies that it returns an actual extension.
*
@@ -76,11 +127,11 @@
}
/*
- * TestAGnssRilUpdateNetworkState_2_0:
+ * TestAGnssRil_UpdateNetworkState_2_0:
* 1. Updates GNSS HAL that a network has connected.
* 2. Updates GNSS HAL that network has disconnected.
*/
-TEST_F(GnssHalTest, TestAGnssRilUpdateNetworkState_2_0) {
+TEST_F(GnssHalTest, TestAGnssRil_UpdateNetworkState_2_0) {
auto agnssRil = gnss_hal_->getExtensionAGnssRil_2_0();
ASSERT_TRUE(agnssRil.isOk());
sp<IAGnssRil_2_0> iAGnssRil = agnssRil;
diff --git a/input/classifier/1.0/Android.bp b/input/classifier/1.0/Android.bp
new file mode 100644
index 0000000..c3c6fc6
--- /dev/null
+++ b/input/classifier/1.0/Android.bp
@@ -0,0 +1,35 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.input.classifier@1.0",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IInputClassifier.hal",
+ ],
+ interfaces: [
+ "android.hidl.base@1.0",
+ ],
+ types: [
+ "Action",
+ "Axis",
+ "Button",
+ "Classification",
+ "EdgeFlag",
+ "Flag",
+ "Meta",
+ "MotionEvent",
+ "PointerCoords",
+ "PointerProperties",
+ "PolicyFlag",
+ "Source",
+ "SourceClass",
+ "ToolType",
+ "VideoFrame",
+ ],
+ gen_java: true,
+}
+
diff --git a/input/classifier/1.0/IInputClassifier.hal b/input/classifier/1.0/IInputClassifier.hal
new file mode 100644
index 0000000..edc1138
--- /dev/null
+++ b/input/classifier/1.0/IInputClassifier.hal
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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.input.classifier@1.0;
+
+interface IInputClassifier {
+
+ /**
+ * Returns the classification for the current sequence of input events.
+ */
+ classify(MotionEvent event) generates (Classification classification);
+
+};
diff --git a/input/classifier/1.0/default/Android.bp b/input/classifier/1.0/default/Android.bp
new file mode 100644
index 0000000..ddd883c
--- /dev/null
+++ b/input/classifier/1.0/default/Android.bp
@@ -0,0 +1,23 @@
+cc_binary {
+ name: "android.hardware.input.classifier@1.0-service-example",
+ init_rc: ["android.hardware.input.classifier@1.0-service-example.rc"],
+ relative_install_path: "hw",
+ vendor: true,
+ vintf_fragments: ["manifest_input.classifier.xml"],
+ srcs: [
+ "InputClassifier.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.input.classifier@1.0",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libutils",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+}
diff --git a/input/classifier/1.0/default/InputClassifier.cpp b/input/classifier/1.0/default/InputClassifier.cpp
new file mode 100644
index 0000000..c463361
--- /dev/null
+++ b/input/classifier/1.0/default/InputClassifier.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 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 "InputClassifierHAL"
+
+#include "InputClassifier.h"
+#include <inttypes.h>
+#include <log/log.h>
+#include <utils/Timers.h>
+
+using namespace android::hardware::input::classifier::V1_0;
+
+namespace android {
+namespace hardware {
+namespace input {
+namespace classifier {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::input::classifier::V1_0::IInputClassifier follow.
+Return<Classification> InputClassifier::classify(const MotionEvent& event) {
+ /**
+ * In this example implementation, we will see how many "pixels" inside the video frame
+ * exceed the value of 250. If more than 6 such pixels are present, then treat the event
+ * as a "DEEP_PRESS".
+ */
+ if (event.frames.size() == 0) {
+ return Classification::NONE;
+ }
+ ALOGI("Frame(O) timestamp = %" PRIu64 ", received %zu frame(s)", event.frames[0].timestamp,
+ event.frames.size());
+ for (const VideoFrame& frame : event.frames) {
+ size_t count = 0;
+ for (size_t i = 0; i < frame.data.size(); i++) {
+ if (frame.data[i] > 250) {
+ count++;
+ }
+ }
+ if (count > 6) {
+ return Classification::DEEP_PRESS;
+ }
+ }
+
+ return Classification::NONE;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace classifier
+} // namespace input
+} // namespace hardware
+} // namespace android
diff --git a/input/classifier/1.0/default/InputClassifier.h b/input/classifier/1.0/default/InputClassifier.h
new file mode 100644
index 0000000..0858ecb
--- /dev/null
+++ b/input/classifier/1.0/default/InputClassifier.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 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_INPUT_CLASSIFIER_V1_0_INPUTCLASSIFIER_H
+#define ANDROID_HARDWARE_INPUT_CLASSIFIER_V1_0_INPUTCLASSIFIER_H
+
+#include <android/hardware/input/classifier/1.0/IInputClassifier.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace input {
+namespace classifier {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+
+struct InputClassifier : public IInputClassifier {
+ // Methods from ::android::hardware::input::classifier::V1_0::IInputClassifier follow.
+ Return<Classification> classify(
+ const ::android::hardware::input::classifier::V1_0::MotionEvent& event) override;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace classifier
+} // namespace input
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_INPUT_CLASSIFIER_V1_0_INPUTCLASSIFIER_H
diff --git a/input/classifier/1.0/default/android.hardware.input.classifier@1.0-service-example.rc b/input/classifier/1.0/default/android.hardware.input.classifier@1.0-service-example.rc
new file mode 100644
index 0000000..f799bf4
--- /dev/null
+++ b/input/classifier/1.0/default/android.hardware.input.classifier@1.0-service-example.rc
@@ -0,0 +1,9 @@
+service vendor.input.classifier-1-0 /vendor/bin/hw/android.hardware.input.classifier@1.0-service-example
+ # Must be specified if "disabled" is set. This HAL will only start if requested via getService
+ interface android.hardware.input.classifier@1.0::IInputClassifier default
+ class hal
+ user nobody
+ # will not be restarted if it exits until it is requested to be restarted
+ oneshot
+ # will only be started when requested
+ disabled
diff --git a/input/classifier/1.0/default/manifest_input.classifier.xml b/input/classifier/1.0/default/manifest_input.classifier.xml
new file mode 100644
index 0000000..8634169
--- /dev/null
+++ b/input/classifier/1.0/default/manifest_input.classifier.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.input.classifier</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IInputClassifier</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/input/classifier/1.0/default/service.cpp b/input/classifier/1.0/default/service.cpp
new file mode 100644
index 0000000..6ef2118
--- /dev/null
+++ b/input/classifier/1.0/default/service.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 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.input.classifier@1.0"
+
+#include <inttypes.h>
+
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+
+#include "InputClassifier.h"
+#include "android/hardware/input/classifier/1.0/IInputClassifier.h"
+
+using android::sp;
+using android::status_t;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::input::classifier::V1_0::IInputClassifier;
+using android::hardware::input::classifier::V1_0::implementation::InputClassifier;
+
+int main() {
+ sp<IInputClassifier> classifier = new InputClassifier();
+
+ configureRpcThreadpool(1, true);
+ const status_t status = classifier->registerAsService();
+
+ if (status != android::OK) {
+ ALOGE("Could not register InputClassifier HAL!");
+ return EXIT_FAILURE; // or handle error
+ }
+
+ joinRpcThreadpool();
+ LOG_ALWAYS_FATAL("Under normal operation, joinRpcThreadpool should never return");
+ return EXIT_FAILURE;
+}
diff --git a/input/classifier/1.0/types.hal b/input/classifier/1.0/types.hal
new file mode 100644
index 0000000..244ecd9
--- /dev/null
+++ b/input/classifier/1.0/types.hal
@@ -0,0 +1,829 @@
+/*
+ * Copyright (C) 2019 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.input.classifier@1.0;
+
+
+/**
+ * Constants that identify each individual axis of a motion event.
+ */
+enum Axis : uint64_t {
+ /**
+ * Axis constant: X axis of a motion event.
+ *
+ * - For a touch screen, reports the absolute X screen position of the center of
+ * the touch contact area. The units are display pixels.
+ * - For a touch pad, reports the absolute X surface position of the center of the touch
+ * contact area. The units are device-dependent.
+ * - For a mouse, reports the absolute X screen position of the mouse pointer.
+ * The units are display pixels.
+ * - For a trackball, reports the relative horizontal displacement of the trackball.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ * - For a joystick, reports the absolute X position of the joystick.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ */
+ X = 0,
+ /**
+ * Axis constant: Y axis of a motion event.
+ *
+ * - For a touch screen, reports the absolute Y screen position of the center of
+ * the touch contact area. The units are display pixels.
+ * - For a touch pad, reports the absolute Y surface position of the center of the touch
+ * contact area. The units are device-dependent.
+ * - For a mouse, reports the absolute Y screen position of the mouse pointer.
+ * The units are display pixels.
+ * - For a trackball, reports the relative vertical displacement of the trackball.
+ * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+ * - For a joystick, reports the absolute Y position of the joystick.
+ * The value is normalized to a range from -1.0 (up or far) to 1.0 (down or near).
+ */
+ Y = 1,
+ /**
+ * Axis constant: Pressure axis of a motion event.
+ *
+ * - For a touch screen or touch pad, reports the approximate pressure applied to the surface
+ * by a finger or other tool. The value is normalized to a range from
+ * 0 (no pressure at all) to 1 (normal pressure), although values higher than 1
+ * may be generated depending on the calibration of the input device.
+ * - For a trackball, the value is set to 1 if the trackball button is pressed
+ * or 0 otherwise.
+ * - For a mouse, the value is set to 1 if the primary mouse button is pressed
+ * or 0 otherwise.
+ */
+ PRESSURE = 2,
+ /**
+ * Axis constant: Size axis of a motion event.
+ *
+ * - For a touch screen or touch pad, reports the approximate size of the contact area in
+ * relation to the maximum detectable size for the device. The value is normalized
+ * to a range from 0 (smallest detectable size) to 1 (largest detectable size),
+ * although it is not a linear scale. This value is of limited use.
+ * To obtain calibrated size information, see
+ * {@link TOUCH_MAJOR} or {@link TOOL_MAJOR}.
+ */
+ SIZE = 3,
+ /**
+ * Axis constant: TouchMajor axis of a motion event.
+ *
+ * - For a touch screen, reports the length of the major axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are display pixels.
+ * - For a touch pad, reports the length of the major axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are device-dependent.
+ */
+ TOUCH_MAJOR = 4,
+ /**
+ * Axis constant: TouchMinor axis of a motion event.
+ *
+ * - For a touch screen, reports the length of the minor axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are display pixels.
+ * - For a touch pad, reports the length of the minor axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are device-dependent.
+ *
+ * When the touch is circular, the major and minor axis lengths will be equal to one another.
+ */
+ TOUCH_MINOR = 5,
+ /**
+ * Axis constant: ToolMajor axis of a motion event.
+ *
+ * - For a touch screen, reports the length of the major axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * - For a touch pad, reports the length of the major axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * The units are device-dependent.
+ *
+ * When the touch is circular, the major and minor axis lengths will be equal to one another.
+ *
+ * The tool size may be larger than the touch size since the tool may not be fully
+ * in contact with the touch sensor.
+ */
+ TOOL_MAJOR = 6,
+ /**
+ * Axis constant: ToolMinor axis of a motion event.
+ *
+ * - For a touch screen, reports the length of the minor axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * - For a touch pad, reports the length of the minor axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * The units are device-dependent.
+ *
+ * When the touch is circular, the major and minor axis lengths will be equal to one another.
+ *
+ * The tool size may be larger than the touch size since the tool may not be fully
+ * in contact with the touch sensor.
+ */
+ TOOL_MINOR = 7,
+ /**
+ * Axis constant: Orientation axis of a motion event.
+ *
+ * - For a touch screen or touch pad, reports the orientation of the finger
+ * or tool in radians relative to the vertical plane of the device.
+ * An angle of 0 radians indicates that the major axis of contact is oriented
+ * upwards, is perfectly circular or is of unknown orientation. A positive angle
+ * indicates that the major axis of contact is oriented to the right. A negative angle
+ * indicates that the major axis of contact is oriented to the left.
+ * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
+ * (finger pointing fully right).
+ * - For a stylus, the orientation indicates the direction in which the stylus
+ * is pointing in relation to the vertical axis of the current orientation of the screen.
+ * The range is from -PI radians to PI radians, where 0 is pointing up,
+ * -PI/2 radians is pointing left, -PI or PI radians is pointing down, and PI/2 radians
+ * is pointing right. See also {@link TILT}.
+ */
+ ORIENTATION = 8,
+ /**
+ * Axis constant: Vertical Scroll axis of a motion event.
+ *
+ * - For a mouse, reports the relative movement of the vertical scroll wheel.
+ * The value is normalized to a range from -1.0 (down) to 1.0 (up).
+ *
+ * The framework may use this axis to scroll views vertically.
+ */
+ VSCROLL = 9,
+ /**
+ * Axis constant: Horizontal Scroll axis of a motion event.
+ *
+ * - For a mouse, reports the relative movement of the horizontal scroll wheel.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ *
+ * The framework may use this axis to scroll views horizontally.
+ */
+ HSCROLL = 10,
+ /**
+ * Axis constant: Z axis of a motion event.
+ *
+ * - For a joystick, reports the absolute Z position of the joystick.
+ * The value is normalized to a range from -1.0 (high) to 1.0 (low).
+ * <em>On game pads with two analog joysticks, this axis is often reinterpreted
+ * to report the absolute X position of the second joystick instead.</em>
+ */
+ Z = 11,
+ /**
+ * Axis constant: X Rotation axis of a motion event.
+ *
+ * - For a joystick, reports the absolute rotation angle about the X axis.
+ * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+ */
+ RX = 12,
+ /**
+ * Axis constant: Y Rotation axis of a motion event.
+ *
+ * - For a joystick, reports the absolute rotation angle about the Y axis.
+ * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+ */
+ RY = 13,
+ /**
+ * Axis constant: Z Rotation axis of a motion event.
+ *
+ * - For a joystick, reports the absolute rotation angle about the Z axis.
+ * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+ * On game pads with two analog joysticks, this axis is often reinterpreted
+ * to report the absolute Y position of the second joystick instead.
+ */
+ RZ = 14,
+ /**
+ * Axis constant: Hat X axis of a motion event.
+ *
+ * - For a joystick, reports the absolute X position of the directional hat control.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ */
+ HAT_X = 15,
+ /**
+ * Axis constant: Hat Y axis of a motion event.
+ *
+ * - For a joystick, reports the absolute Y position of the directional hat control.
+ * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+ */
+ HAT_Y = 16,
+ /**
+ * Axis constant: Left Trigger axis of a motion event.
+ *
+ * - For a joystick, reports the absolute position of the left trigger control.
+ * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+ */
+ LTRIGGER = 17,
+ /**
+ * Axis constant: Right Trigger axis of a motion event.
+ *
+ * - For a joystick, reports the absolute position of the right trigger control.
+ * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+ */
+ RTRIGGER = 18,
+ /**
+ * Axis constant: Throttle axis of a motion event.
+ *
+ * - For a joystick, reports the absolute position of the throttle control.
+ * The value is normalized to a range from 0.0 (fully open) to 1.0 (fully closed).
+ */
+ THROTTLE = 19,
+ /**
+ * Axis constant: Rudder axis of a motion event.
+ *
+ * - For a joystick, reports the absolute position of the rudder control.
+ * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
+ */
+ RUDDER = 20,
+ /**
+ * Axis constant: Wheel axis of a motion event.
+ *
+ * - For a joystick, reports the absolute position of the steering wheel control.
+ * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
+ */
+ WHEEL = 21,
+ /**
+ * Axis constant: Gas axis of a motion event.
+ *
+ * - For a joystick, reports the absolute position of the gas (accelerator) control.
+ * The value is normalized to a range from 0.0 (no acceleration)
+ * to 1.0 (maximum acceleration).
+ */
+ GAS = 22,
+ /**
+ * Axis constant: Brake axis of a motion event.
+ *
+ * - For a joystick, reports the absolute position of the brake control.
+ * The value is normalized to a range from 0.0 (no braking) to 1.0 (maximum braking).
+ */
+ BRAKE = 23,
+ /**
+ * Axis constant: Distance axis of a motion event.
+ *
+ * - For a stylus, reports the distance of the stylus from the screen.
+ * A value of 0.0 indicates direct contact and larger values indicate increasing
+ * distance from the surface.
+ */
+ DISTANCE = 24,
+ /**
+ * Axis constant: Tilt axis of a motion event.
+ *
+ * - For a stylus, reports the tilt angle of the stylus in radians where
+ * 0 radians indicates that the stylus is being held perpendicular to the
+ * surface, and PI/2 radians indicates that the stylus is being held flat
+ * against the surface.
+ */
+ TILT = 25,
+ /**
+ * Axis constant: Generic scroll axis of a motion event.
+ *
+ * - This is used for scroll axis motion events that can't be classified as strictly
+ * vertical or horizontal. The movement of a rotating scroller is an example of this.
+ */
+ SCROLL = 26,
+ /**
+ * Axis constant: The movement of x position of a motion event.
+ *
+ * - For a mouse, reports a difference of x position between the previous position.
+ * This is useful when pointer is captured, in that case the mouse pointer doesn't
+ * change the location but this axis reports the difference which allows the app
+ * to see how the mouse is moved.
+ */
+ RELATIVE_X = 27,
+ /**
+ * Axis constant: The movement of y position of a motion event.
+ *
+ * Same as {@link RELATIVE_X}, but for y position.
+ */
+ RELATIVE_Y = 28,
+ /**
+ * Axis constant: Generic 1 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_1 = 32,
+ /**
+ * Axis constant: Generic 2 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_2 = 33,
+ /**
+ * Axis constant: Generic 3 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_3 = 34,
+ /**
+ * Axis constant: Generic 4 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_4 = 35,
+ /**
+ * Axis constant: Generic 5 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_5 = 36,
+ /**
+ * Axis constant: Generic 6 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_6 = 37,
+ /**
+ * Axis constant: Generic 7 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_7 = 38,
+ /**
+ * Axis constant: Generic 8 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_8 = 39,
+ /**
+ * Axis constant: Generic 9 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_9 = 40,
+ /**
+ * Axis constant: Generic 10 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_10 = 41,
+ /**
+ * Axis constant: Generic 11 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_11 = 42,
+ /**
+ * Axis constant: Generic 12 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_12 = 43,
+ /**
+ * Axis constant: Generic 13 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_13 = 44,
+ /**
+ * Axis constant: Generic 14 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_14 = 45,
+ /**
+ * Axis constant: Generic 15 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_15 = 46,
+ /**
+ * Axis constant: Generic 16 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ */
+ GENERIC_16 = 47,
+};
+
+/**
+ * Tool type of a pointer
+ */
+enum ToolType: uint8_t {
+ UNKNOWN = 0,
+ FINGER = 1,
+ STYLUS = 2,
+ MOUSE = 3,
+ ERASER = 4,
+};
+
+/**
+ * Properties of a particular pointer. Analogous to Android's PointerProperties.
+ */
+struct PointerProperties {
+ /**
+ * A number identifying a specific pointer. When a pointer is lifted,
+ * this value may be reused by another new pointer, even during the
+ * same gesture. For example, if there are two pointers touching the screen
+ * at the same time, they might have pointer ID's of 0 and 1. If the
+ * pointer with id = 0 is lifted, while the pointer with id = 1 remains, and
+ * a new pointer is placed on the screen, then the new pointer may receive
+ * an id of 0. While a pointer is active, it is guaranteed to keep the same
+ * id.
+ */
+ int32_t id;
+ /**
+ * Type of tool used to make contact, such as a finger or stylus, if known.
+ */
+ ToolType toolType;
+};
+
+/**
+ * Pointer coordinate data. Analogous to Android's PointerCoords.
+ */
+struct PointerCoords {
+ /**
+ * Bitfield of axes that are present in this structure.
+ */
+ bitfield<Axis> bits;
+ /**
+ * The values corresponding to each non-zero axis. This vector only
+ * contains non-zero entries. If an axis that is not currently specified
+ * in "bits" is requested, a zero value is returned.
+ * There are only as many values stored here
+ * as there are non-zero bits in the "bits" field.
+ * The values are position-packed. So the first non-zero axis will be
+ * at position 0, the next non-zero axis will be at position 1, and so on.
+ */
+ vec<float> values;
+};
+
+enum SourceClass: uint8_t {
+ NONE = 1 << 0,
+ BUTTON = 1 << 1,
+ POINTER = 1 << 2,
+ NAVIGATION = 1 << 3,
+ POSITION = 1 << 4,
+ JOYSTICK = 1 << 5,
+};
+
+/**
+ * Input sources
+ */
+enum Source: uint32_t {
+ UNKNOWN = 0,
+ KEYBOARD = (1 << 8) | SourceClass:BUTTON,
+ DPAD = (1 << 9) | SourceClass:BUTTON,
+ GAMEPAD = (1 << 10) | SourceClass:BUTTON,
+ TOUCHSCREEN = (1 << 12) | SourceClass:POINTER,
+ MOUSE = (1 << 13) | SourceClass:POINTER,
+ STYLUS = (1 << 14) | SourceClass:POINTER,
+ BLUETOOTH_STYLUS = (1 << 15) | STYLUS,
+ TRACKBALL = (1 << 16) | SourceClass:NAVIGATION,
+ MOUSE_RELATIVE = (1 << 17) | SourceClass:NAVIGATION,
+ TOUCHPAD = (1 << 20) | SourceClass:POSITION,
+ TOUCH_NAVIGATION = (1 << 21) | SourceClass:NONE,
+ ROTARY_ENCODER = (1 << 22) | SourceClass:NONE,
+ JOYSTICK = (1 << 24) | SourceClass:JOYSTICK,
+ ANY = 0xFFFFFF00,
+};
+
+/** Motion event actions */
+enum Action: int32_t {
+ /** A pressed gesture has started, the motion contains the initial starting location. */
+ DOWN = 0,
+ /**
+ * A pressed gesture has finished, the motion contains the final release location
+ * as well as any intermediate points since the last down or move event.
+ */
+ UP = 1,
+ /**
+ * A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and
+ * AMOTION_EVENT_ACTION_UP). The motion contains the most recent point.
+ */
+ MOVE = 2,
+ /**
+ * The current gesture has been aborted.
+ * You will not receive any more points in it. You must treat this as
+ * an up event, but not perform any action that you normally would.
+ */
+ CANCEL = 3,
+ /**
+ * A movement has happened outside of the normal bounds of the UI element.
+ * This does not provide a full gesture, but only the initial location of the movement/touch.
+ */
+ OUTSIDE = 4,
+ /**
+ * A non-primary pointer has gone down.
+ */
+ POINTER_DOWN = 5,
+ /**
+ * A non-primary pointer has gone up.
+ */
+ POINTER_UP = 6,
+ /**
+ * A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).
+ * The motion contains the most recent point, as well as any intermediate points since
+ * the last hover move event.
+ */
+ HOVER_MOVE = 7,
+ /**
+ * The motion event contains relative vertical and/or horizontal scroll offsets.
+ * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL
+ * and AMOTION_EVENT_AXIS_HSCROLL.
+ * The pointer may or may not be down when this event is dispatched.
+ * The framework will always deliver this action to the window under the pointer, which
+ * may not be the window currently touched.
+ */
+ SCROLL = 8,
+ /**
+ * The pointer is not down but has entered the boundaries of a window or view.
+ */
+ HOVER_ENTER = 9,
+ /**
+ * The pointer is not down but has exited the boundaries of a window or view.
+ */
+ HOVER_EXIT = 10,
+ /**
+ * One or more buttons have been pressed.
+ */
+ BUTTON_PRESS = 11,
+ /**
+ * One or more buttons have been released.
+ */
+ BUTTON_RELEASE = 12,
+};
+
+/** Edge flags */
+enum EdgeFlag : int32_t {
+ /** No edges are intersected */
+ NONE = 0,
+ /** Motion intersected top edge of the screen */
+ TOP = 1 << 0,
+ /** Motion intersected bottom edge of the screen */
+ BOTTOM = 1 << 1,
+ /** Motion intersected left edge of the screen */
+ LEFT = 1 << 2,
+ /** Motion intersected right edge of the screen */
+ RIGHT = 1 << 3,
+};
+
+/** Policy flags */
+enum PolicyFlag : uint32_t {
+ // The following flags originate in RawEvents
+
+ /** Event should wake the device */
+ WAKE = 1 << 0,
+ /** Key is virtual, and should generate haptic feedback */
+ VIRTUAL = 1 << 1,
+ /** Key is the special function modifier */
+ FUNCTION = 1 << 2,
+ /**
+ * Key represents a special gesture that has been detected
+ * by the touch firmware or driver.
+ */
+ GESTURE = 1 << 3,
+
+ // The following flags may be generated here in the InputClassifier HAL
+ // or in later InputListener stages
+
+ /** Event was injected */
+ INJECTED = 1 << 24,
+ /**
+ * Event comes from a trusted source, such as a directly attached input
+ * device or an application with system-wide event injection permission.
+ */
+ TRUSTED = 1 << 25,
+ /** Event has passed through an input filter. */
+ FILTERED = 1 << 26,
+ /** Disable automatic key repeating behaviour. */
+ DISABLE_KEY_REPEAT = 1 << 27,
+
+ // The following flags are set by the input reader policy as it intercepts each event
+
+ /** Device was in an interactive state when the event was intercepted */
+ INTERACTIVE = 1 << 29,
+ /** Event should be dispatched to applications */
+ PASS_TO_USER = 1 << 30,
+};
+
+/**
+ * Buttons that are associated with motion events.
+ */
+enum Button : int32_t {
+ NONE = 0,
+ PRIMARY = 1 << 0,
+ SECONDARY = 1 << 1,
+ TERTIARY = 1 << 2,
+ BACK = 1 << 3,
+ FORWARD = 1 << 4,
+ STYLUS_PRIMARY = 1 << 5,
+ STYLUS_SECONDARY = 1 << 6,
+};
+
+/**
+ * Meta key / modifier state
+ */
+enum Meta : int32_t {
+ NONE = 0,
+
+ /** One of the ALT meta keys is pressed. */
+ ALT_ON = 1 << 1, // 0x02
+
+ /** The left ALT meta key is pressed. */
+ ALT_LEFT_ON = 1 << 4, // 0x10
+
+ /** The right ALT meta key is pressed. */
+ ALT_RIGHT_ON = 1 << 5, // 0x20
+
+ /** One of the SHIFT meta keys is pressed. */
+ SHIFT_ON = 1 << 0, // 0x01
+
+ /** The left SHIFT meta key is pressed. */
+ SHIFT_LEFT_ON = 1 << 6, // 0x40
+
+ /** The right SHIFT meta key is pressed. */
+ SHIFT_RIGHT_ON = 1 << 7, // 0x80
+
+ /** The SYM meta key is pressed. */
+ SYM_ON = 1 << 2, // 0x04
+
+ /** The FUNCTION meta key is pressed. */
+ FUNCTION_ON = 1 << 3, // 0x08
+
+ /** One of the CTRL meta keys is pressed. */
+ CTRL_ON = 1 << 12, // 0x1000
+
+ /** The left CTRL meta key is pressed. */
+ CTRL_LEFT_ON = 1 << 13, // 0x2000
+
+ /** The right CTRL meta key is pressed. */
+ CTRL_RIGHT_ON = 1 << 14, // 0x4000
+
+ /** One of the META meta keys is pressed. */
+ META_ON = 1 << 16, // 0x10000
+
+ /** The left META meta key is pressed. */
+ META_LEFT_ON = 1 << 17, // 0x20000
+
+ /** The right META meta key is pressed. */
+ META_RIGHT_ON = 1 << 18, //0x40000
+
+ /** The CAPS LOCK meta key is on. */
+ CAPS_LOCK_ON = 1 << 20, // 0x100000
+
+ /** The NUM LOCK meta key is on. */
+ NUM_LOCK_ON = 1 << 21, // 0x200000
+
+ /** The SCROLL LOCK meta key is on. */
+ SCROLL_LOCK_ON = 1 << 22, // 0x400000
+};
+
+/**
+ * Motion event flags
+ */
+enum Flag : int32_t {
+ /**
+ * Indicates that the window that received this motion event is partly
+ * or wholly obscured by another visible window above it. This flag is set to true
+ * even if the event did not directly pass through the obscured area.
+ * A security sensitive application can check this flag to identify situations in which
+ * a malicious application may have covered up part of its content for the purpose
+ * of misleading the user or hijacking touches. An appropriate response might be
+ * to drop the suspect touches or to take additional precautions to confirm the user's
+ * actual intent.
+ */
+ WINDOW_IS_OBSCURED = 1 << 0,
+ /**
+ * This flag indicates that the event has been generated by a gesture generator. It
+ * could be used, for example, to determine whether touch slop should be applied.
+ */
+ IS_GENERATED_GESTURE = 1 << 3, // 0x8
+ /**
+ * Motion event is inconsistent with previously sent motion events.
+ */
+ TAINTED = 1 << 31, // 0x80000000
+};
+
+/**
+ * Touch heatmap.
+ *
+ * The array is a 2-D row-major matrix with dimensions (height, width).
+ * The heatmap data does not rotate when device orientation changes.
+ *
+ * Example:
+ *
+ * If the data in the array is:
+ * data[i] = i for i in 0 .. 59,
+ * then it can be represented as follows:
+ *
+ * <-- width -- >
+ * 0 1 2 3 4 5 ^
+ * 6 7 8 9 10 11 |
+ * 12 12 14 15 16 17 |
+ * 18 ... 23 | height
+ * 24 ... 29 |
+ * 30 ... 35 |
+ * 36 ... 41 |
+ * 42 ... 47 |
+ * 48 ... 53 |
+ * 54 ... 59 v
+ *
+ * Looking at the device in standard portrait orientation,
+ * the element "0" is the top left of the screen,
+ * "5" is at the top right, and "59" is the bottom right.
+ * Here width=6, and height=10.
+ */
+struct VideoFrame {
+ /**
+ * Video frame data.
+ * Size of the data is width * height.
+ */
+ vec<int16_t> data;
+ uint32_t width;
+ uint32_t height;
+ /**
+ * Time at which the frame was collected, in nanoseconds.
+ * Measured with the same clock that is used to populate MotionEvent times.
+ */
+ uint64_t timestamp;
+};
+
+/**
+ * Analogous to Android's native MotionEvent / NotifyMotionArgs.
+ * Stores the basic information about pointer movements.
+ */
+struct MotionEvent {
+ // InputEvent fields
+ /**
+ * The id of the device which produced this event.
+ */
+ int32_t deviceId;
+ /**
+ * The source type of this event.
+ */
+ Source source;
+ /**
+ * The display id associated with this event.
+ */
+ int32_t displayId;
+
+ // NotifyMotionArgs fields
+ /**
+ * Time when the initial touch down occurred, in nanoseconds.
+ */
+ int64_t downTime;
+ /**
+ * Time when this event occurred, in nanoseconds.
+ */
+ int64_t eventTime;
+ /**
+ * The kind of action being performed.
+ */
+ Action action;
+ /**
+ * For ACTION_POINTER_DOWN or ACTION_POINTER_UP, this contains the associated pointer index.
+ * The index may be used to get information about the pointer that has gone down or up.
+ */
+ uint8_t actionIndex;
+ /**
+ * The button that has been modified during a press or release action.
+ */
+ Button actionButton;
+ /**
+ * The motion event flags.
+ */
+ bitfield<Flag> flags;
+ /**
+ * The motion event policy flags.
+ */
+ bitfield<PolicyFlag> policyFlags;
+ /**
+ * The edges, if any, that were touched by this motion event.
+ */
+ bitfield<EdgeFlag> edgeFlags;
+ /**
+ * The state of any meta / modifier keys that were in effect when the event was generated.
+ */
+ bitfield<Meta> metaState;
+ /**
+ * The state of buttons that are pressed.
+ */
+ bitfield<Button> buttonState;
+ /**
+ * The precision of the X coordinate being reported.
+ */
+ float xPrecision;
+ /**
+ * The precision of the Y coordinate being reported.
+ */
+ float yPrecision;
+ /**
+ * The properties of each pointer present in this motion event.
+ */
+ vec<PointerProperties> pointerProperties;
+ /**
+ * The coordinates of each pointer.
+ */
+ vec<PointerCoords> pointerCoords;
+
+ // Additional fields from NotifyMotionArgs
+ /**
+ * Device time at which the event occurred, in microseconds.
+ * Will wrap after a little over an hour.
+ */
+ uint32_t deviceTimestamp;
+ /**
+ * The video frames, if any, associated with the current or previous motion events.
+ */
+ vec<VideoFrame> frames;
+};
+
+
+enum Classification : uint8_t {
+ NONE = 0,
+ /**
+ * Too early to classify the gesture, need more events.
+ */
+ AMBIGUOUS_GESTURE = 1,
+ /**
+ * User is force-pressing the screen.
+ */
+ DEEP_PRESS = 2,
+};
diff --git a/keymaster/3.0/vts/functional/keymaster_tags.h b/keymaster/3.0/vts/functional/keymaster_tags.h
index f241ef1..8544bf7 100644
--- a/keymaster/3.0/vts/functional/keymaster_tags.h
+++ b/keymaster/3.0/vts/functional/keymaster_tags.h
@@ -274,7 +274,10 @@
*/
template <typename ValueT> class NullOr {
template <typename T> struct reference_initializer {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnull-dereference"
static T&& init() { return *static_cast<std::remove_reference_t<T>*>(nullptr); }
+#pragma GCC diagnostic pop
};
template <typename T> struct pointer_initializer {
static T init() { return nullptr; }
diff --git a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
index 61c444c..97dab68 100644
--- a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
+++ b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
@@ -282,7 +282,10 @@
class NullOr {
template <typename T>
struct reference_initializer {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnull-dereference"
static T&& init() { return *static_cast<std::remove_reference_t<T>*>(nullptr); }
+#pragma GCC diagnostic pop
};
template <typename T>
struct pointer_initializer {
diff --git a/radio/1.4/Android.bp b/radio/1.4/Android.bp
index ad114f3..32f9712 100644
--- a/radio/1.4/Android.bp
+++ b/radio/1.4/Android.bp
@@ -30,6 +30,7 @@
"DataConnActiveStatus",
"DataProfileInfo",
"DataRegStateResult",
+ "EmergencyCallRouting",
"EmergencyNumber",
"EmergencyNumberSource",
"EmergencyServiceCategory",
diff --git a/radio/1.4/IRadio.hal b/radio/1.4/IRadio.hal
index 8438777..b0810a4 100644
--- a/radio/1.4/IRadio.hal
+++ b/radio/1.4/IRadio.hal
@@ -18,9 +18,11 @@
import @1.0::Dial;
import @1.2::DataRequestReason;
+import @1.2::NetworkScanRequest;
import @1.3::IRadio;
import @1.4::AccessNetwork;
import @1.4::DataProfileInfo;
+import @1.4::EmergencyCallRouting;
import @1.4::EmergencyServiceCategory;
import @1.4::RadioAccessFamily;
@@ -101,21 +103,26 @@
oneway setDataProfile_1_4(int32_t serial, vec<DataProfileInfo> profiles);
/**
- * Initiate emergency voice call, with zero or more emergency service category(s).
+ * Initiate emergency voice call, with zero or more emergency service category(s) and routing
+ * information for handling the call. Android uses this request to make its emergency call
+ * instead of using @1.0::IRadio.dial if the 'address' in the 'dialInfo' field is identified
+ * as an emergency number by Android.
*
- * Note this API is the same as IRadio.dial except using the
- * @1.4::EmergencyServiceCategory as the input param.
+ * In multi-sim senario, this radio request is sent through the IRadio service that serves
+ * the subscription the emergency number belongs to, no matter of the PUK/PIN state of the
+ * subscription and the service state.
*
- * If the number in the 'dialInfo' field is identified as an emergency number in Android,
- * Android use this request for its emergency call instead of @1.0::IRadio.dial. The
- * implementation decides how to handle the call (e.g. emergency routing or normal
- * routing).
+ * Some countries or carriers require some emergency numbers that must be handled with normal
+ * call routing or emergency routing. If the 'routing' field is specified as
+ * @1.4::EmergencyNumberRouting#NORMAL, the implementation must use normal call routing to
+ * handle the call; if it is specified as @1.4::EmergencyNumberRouting#EMERGENCY, the
+ * implementation must use emergency routing to handle the call; if it is
+ * @1.4::EmergencyNumberRouting#UNKNOWN, Android does not know how to handle the call.
*
* If the dialed emergency number does not have a specified emergency service category, the
- * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; iff either the
- * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED or the underlying
+ * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the underlying
* technology used to request emergency services does not support the emergency service
- * category, the interpretation of the categories is defined by implementation.
+ * category, the categories may be ignored.
*
* Reference: 3gpp TS 22.101, Section 10 - Emergency Calls
*
@@ -123,11 +130,23 @@
* @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial.
* @param categories bitfield<@1.4::EmergencyServiceCategory> the Emergency Service Category(s)
* of the call.
+ * @param routing @1.4::EmergencyCallRouting the emergency call routing information.
*
* Response function is IRadioResponse.emergencyDialResponse()
*/
oneway emergencyDial(int32_t serial, Dial dialInfo,
- bitfield<EmergencyServiceCategory> categories);
+ bitfield<EmergencyServiceCategory> categories, EmergencyCallRouting routing);
+
+ /**
+ * Starts a network scan
+ *
+ * @param serial Serial number of request.
+ * @param request Defines the radio networks/bands/channels which need to be scanned.
+ *
+ * Same API as @1.2::IRadio.startNetworkScan_1_2, except using the
+ * @1.4::IRadioResponse.startNetworkScanResponse_1_4 as the response.
+ */
+ oneway startNetworkScan_1_4(int32_t serial, NetworkScanRequest request);
/**
* Query the preferred network type bitmap.
diff --git a/radio/1.4/IRadioIndication.hal b/radio/1.4/IRadioIndication.hal
index 626b494..a58d19c 100644
--- a/radio/1.4/IRadioIndication.hal
+++ b/radio/1.4/IRadioIndication.hal
@@ -27,17 +27,17 @@
* Report the current list of emergency numbers
*
* Each emergency number (@1.4::EmergencyNumber) in the emergency number list contains a
- * dialing number, zero or more service category(s), mobile country code, and source(s) that
- * indicate where it comes from.
+ * dialing number, zero or more service category(s), mobile country code, mobile network code,
+ * and source(s) that indicate where it comes from.
*
- * Radio must report all the valid emergency numbers with known mobile country code and
- * emergency service categories from all available sources including network signaling, sim,
- * modem/oem configuration, and default configuration (112 and 911 must be always available;
- * additionally, 000, 08, 110, 999, 118 and 119 must be available when sim is not present).
- * Radio shall not report emergency numbers that are invalid in the current locale. The
- * reported emergency number list must not have duplicate @1.4::EmergencyNumber entries. Please
- * refer the documentation of @1.4::EmergencyNumber to construct each emergency number to
- * report.
+ * Radio must report all the valid emergency numbers with known mobile country code, mobile
+ * network code and emergency service categories from all available sources including network
+ * signaling, sim, modem/oem configuration, and default configuration (112 and 911 must be
+ * always available; additionally, 000, 08, 110, 999, 118 and 119 must be available when sim
+ * is not present). Radio shall not report emergency numbers that are invalid in the current
+ * locale. The reported emergency number list must not have duplicate @1.4::EmergencyNumber
+ * entries. Please refer the documentation of @1.4::EmergencyNumber to construct each
+ * emergency number to report.
*
* Radio must report the complete list of emergency numbers whenever the emergency numbers in
* the list are changed or whenever the client and the radio server are connected.
diff --git a/radio/1.4/IRadioResponse.hal b/radio/1.4/IRadioResponse.hal
index df40969..a58a5c1 100644
--- a/radio/1.4/IRadioResponse.hal
+++ b/radio/1.4/IRadioResponse.hal
@@ -50,6 +50,23 @@
/**
* @param info Response info struct containing response type, serial no. and error
+ *
+ * Same API as @1.1::IRadioResponse.startNetworkScanResponse, except disallowing error codes
+ * OPERATION_NOT_ALLOWED and REQUEST_NOT_SUPPORTED.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:DEVICE_IN_USE
+ * RadioError:INTERNAL_ERR
+ * RadioError:NO_MEMORY
+ * RadioError:MODEM_ERR
+ * RadioError:INVALID_ARGUMENTS
+ */
+ oneway startNetworkScanResponse_1_4(RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
* @param cellInfo List of current cell information known to radio
*
* Valid errors returned:
diff --git a/radio/1.4/types.hal b/radio/1.4/types.hal
index d0eb0ac..74613af 100644
--- a/radio/1.4/types.hal
+++ b/radio/1.4/types.hal
@@ -53,7 +53,7 @@
/**
* Emergency number contains information of number, one or more service category(s), mobile country
- * code (mcc), and source(s) that indicate where it comes from.
+ * code (mcc), mobile network country (mnc) and source(s) that indicate where it comes from.
*
* If the source of the emergency number is associated with country, field ‘mcc’ must be provided;
* otherwise the field ‘mcc’ must be an empty string.
@@ -155,6 +155,25 @@
DEFAULT = 1 << 3,
};
+/**
+ * Indicates how the implementation should handle the emergency call if it is required by Android.
+ */
+enum EmergencyCallRouting : int32_t {
+ /**
+ * Indicates Android does not require how to handle the corresponding emergency call; it is
+ * decided by implementation.
+ */
+ UNKNOWN = 0,
+ /**
+ * Indicates the implementation must handle the call through emergency routing.
+ */
+ EMERGENCY = 1,
+ /**
+ * Indicates the implementation must handle the call through normal call routing.
+ */
+ NORMAL = 2,
+};
+
enum RadioTechnology : @1.0::RadioTechnology {
/** 5G NR. */
NR = 20,
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
index 37b7349..be7415b 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
@@ -24,10 +24,12 @@
using ::android::hardware::EventFlag;
using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
using ::android::hardware::sensors::V1_0::Result;
using ::android::hardware::sensors::V1_0::SensorInfo;
using ::android::hardware::sensors::V2_0::EventQueueFlagBits;
using ::android::hardware::sensors::V2_0::ISensors;
+using ::android::hardware::sensors::V2_0::ISensorsCallback;
template <typename EnumType>
constexpr typename std::underlying_type<EnumType>::type asBaseType(EnumType value) {
@@ -36,6 +38,16 @@
constexpr size_t SensorsHidlEnvironmentV2_0::MAX_RECEIVE_BUFFER_EVENT_COUNT;
+struct SensorsCallback : ISensorsCallback {
+ Return<void> onDynamicSensorsConnected(const hidl_vec<SensorInfo>& /* sensorInfos */) {
+ return Return<void>();
+ }
+
+ Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& /* sensorHandles */) {
+ return Return<void>();
+ }
+};
+
bool SensorsHidlEnvironmentV2_0::resetHal() {
bool succeed = false;
do {
@@ -63,7 +75,7 @@
}
mSensors->initialize(*mEventQueue->getDesc(), *mWakeLockQueue->getDesc(),
- nullptr /* TODO: callback */);
+ new SensorsCallback());
std::vector<SensorInfo> sensorList;
if (!mSensors->getSensorsList([&](const hidl_vec<SensorInfo>& list) { sensorList = list; })
diff --git a/vibrator/1.3/Android.bp b/vibrator/1.3/Android.bp
new file mode 100644
index 0000000..28370d6
--- /dev/null
+++ b/vibrator/1.3/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.vibrator@1.3",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IVibrator.hal",
+ ],
+ interfaces: [
+ "android.hardware.vibrator@1.0",
+ "android.hardware.vibrator@1.1",
+ "android.hardware.vibrator@1.2",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
+
diff --git a/vibrator/1.3/IVibrator.hal b/vibrator/1.3/IVibrator.hal
new file mode 100644
index 0000000..01c2801
--- /dev/null
+++ b/vibrator/1.3/IVibrator.hal
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 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@1.3;
+
+import @1.0::Status;
+import @1.2::IVibrator;
+
+interface IVibrator extends @1.2::IVibrator {
+ /**
+ * Returns whether the vibrator supports control through an alternate interface.
+ */
+ supportsExternalControl() generates (bool supports);
+
+ /**
+ * Enables/disables control override of vibrator to audio.
+ *
+ * When this API is set, the vibrator control should be ceded to audio system
+ * for haptic audio. While this is enabled, issuing of other commands to control
+ * the vibrator is unsupported and the resulting behavior is undefined. Amplitude
+ * control may or may not be supported and is reflected in the return value of
+ * supportsAmplitudeControl() while this is enabled. When this is disabled, the
+ * vibrator should resume to an off state.
+ *
+ * @param enabled Whether external control should be enabled or disabled.
+ * @return status Whether the command was successful or not. Must return
+ * Status::UNSUPPORTED_OPERATION if external control is
+ * not supported by the device.
+ */
+ setExternalControl(bool enabled) generates (Status status);
+};
diff --git a/vibrator/1.3/vts/functional/Android.bp b/vibrator/1.3/vts/functional/Android.bp
new file mode 100644
index 0000000..5b4c893
--- /dev/null
+++ b/vibrator/1.3/vts/functional/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2018 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_test {
+ name: "VtsHalVibratorV1_3TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalVibratorV1_3TargetTest.cpp"],
+ static_libs: [
+ "android.hardware.vibrator@1.0",
+ "android.hardware.vibrator@1.1",
+ "android.hardware.vibrator@1.2",
+ "android.hardware.vibrator@1.3",
+ ],
+ test_suites: ["general-tests"],
+}
+
diff --git a/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
new file mode 100644
index 0000000..a67d1dc
--- /dev/null
+++ b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 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 "vibrator_hidl_hal_test"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/vibrator/1.0/types.h>
+#include <android/hardware/vibrator/1.3/IVibrator.h>
+#include <unistd.h>
+
+using ::android::sp;
+using ::android::hardware::vibrator::V1_0::Status;
+using ::android::hardware::vibrator::V1_3::IVibrator;
+
+// Test environment for Vibrator HIDL HAL.
+class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+ // get the test environment singleton
+ static VibratorHidlEnvironment* Instance() {
+ static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
+ return instance;
+ }
+
+ virtual void registerTestServices() override { registerTestService<IVibrator>(); }
+
+ private:
+ VibratorHidlEnvironment() {}
+};
+
+// The main test class for VIBRATOR HIDL HAL 1.3.
+class VibratorHidlTest_1_3 : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
+ VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+ ASSERT_NE(vibrator, nullptr);
+ }
+
+ virtual void TearDown() override {}
+
+ sp<IVibrator> vibrator;
+};
+
+TEST_F(VibratorHidlTest_1_3, ChangeVibrationalExternalControl) {
+ if (vibrator->supportsExternalControl()) {
+ EXPECT_EQ(Status::OK, vibrator->setExternalControl(true));
+ sleep(1);
+ EXPECT_EQ(Status::OK, vibrator->setExternalControl(false));
+ sleep(1);
+ }
+}
+
+TEST_F(VibratorHidlTest_1_3, SetExternalControlReturnUnsupportedOperationIfNotSupported) {
+ if (!vibrator->supportsExternalControl()) {
+ EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setExternalControl(true));
+ }
+}
+
+int main(int argc, char** argv) {
+ ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
+ ::testing::InitGoogleTest(&argc, argv);
+ VibratorHidlEnvironment::Instance()->init(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
index 3189db4..397ad17 100644
--- a/wifi/1.0/vts/functional/Android.bp
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -45,6 +45,7 @@
static_libs: [
"VtsHalWifiV1_0TargetTestUtil",
"android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
"android.hardware.wifi@1.2",
"android.hardware.wifi@1.3",
],
diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
index a3fdf27..3555c2e 100644
--- a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
@@ -17,6 +17,7 @@
#include <android-base/logging.h>
#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.3/IWifiChip.h>
#include <VtsHalHidlTargetTestBase.h>
@@ -87,7 +88,19 @@
uint32_t configureChipForStaIfaceAndGetCapabilities() {
configureChipForIfaceType(IfaceType::STA, true);
- const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
+
+ sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted =
+ ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip_);
+
+ std::pair<WifiStatus, uint32_t> status_and_caps;
+
+ if (chip_converted != nullptr) {
+ // Call the newer HAL version
+ status_and_caps = HIDL_INVOKE(chip_converted, getCapabilities_1_3);
+ } else {
+ status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
+ }
+
if (status_and_caps.first.code != WifiStatusCode::SUCCESS) {
EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status_and_caps.first.code);
return 0;
diff --git a/wifi/1.1/vts/functional/Android.bp b/wifi/1.1/vts/functional/Android.bp
index 78d7a85..6662314 100644
--- a/wifi/1.1/vts/functional/Android.bp
+++ b/wifi/1.1/vts/functional/Android.bp
@@ -24,6 +24,8 @@
"VtsHalWifiV1_0TargetTestUtil",
"android.hardware.wifi@1.0",
"android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
],
test_suites: ["general-tests"],
}
diff --git a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
index d3a983c..6323547 100644
--- a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
@@ -18,6 +18,7 @@
#include <android/hardware/wifi/1.1/IWifi.h>
#include <android/hardware/wifi/1.1/IWifiChip.h>
+#include <android/hardware/wifi/1.3/IWifiChip.h>
#include <VtsHalHidlTargetTestBase.h>
@@ -58,7 +59,19 @@
ChipModeId mode_id;
EXPECT_TRUE(configureChipToSupportIfaceType(
wifi_chip_, IfaceType::STA, &mode_id));
- const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
+
+ sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted =
+ ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip_);
+
+ std::pair<WifiStatus, uint32_t> status_and_caps;
+
+ if (chip_converted != nullptr) {
+ // Call the newer HAL version
+ status_and_caps = HIDL_INVOKE(chip_converted, getCapabilities_1_3);
+ } else {
+ status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
+ }
+
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
return status_and_caps.second;
}
diff --git a/wifi/1.2/vts/functional/Android.bp b/wifi/1.2/vts/functional/Android.bp
index a969f65..b2956ce 100644
--- a/wifi/1.2/vts/functional/Android.bp
+++ b/wifi/1.2/vts/functional/Android.bp
@@ -27,6 +27,7 @@
"android.hardware.wifi@1.0",
"android.hardware.wifi@1.1",
"android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
],
test_suites: ["general-tests"],
}
diff --git a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp
index a5457b7..9d567fe 100644
--- a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp
@@ -18,6 +18,7 @@
#include <android/hardware/wifi/1.2/IWifiChip.h>
#include <android/hardware/wifi/1.2/IWifiChipEventCallback.h>
+#include <android/hardware/wifi/1.3/IWifiChip.h>
#include <VtsHalHidlTargetCallbackBase.h>
#include <VtsHalHidlTargetTestBase.h>
@@ -104,7 +105,19 @@
ChipModeId mode_id;
EXPECT_TRUE(
configureChipToSupportIfaceType(wifi_chip_, IfaceType::STA, &mode_id));
- const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
+
+ sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted =
+ ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip_);
+
+ std::pair<WifiStatus, uint32_t> status_and_caps;
+
+ if (chip_converted != nullptr) {
+ // Call the newer HAL version
+ status_and_caps = HIDL_INVOKE(chip_converted, getCapabilities_1_3);
+ } else {
+ status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities);
+ }
+
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
return status_and_caps.second;
}
diff --git a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
index 32ba760..3fcc39e 100644
--- a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
@@ -16,6 +16,7 @@
#include <android-base/logging.h>
#include <android-base/macros.h>
+#include <cutils/properties.h>
#include <gmock/gmock.h>
#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38
@@ -117,6 +118,19 @@
.WillRepeatedly(testing::Return(modes));
}
+ void setup_MultiIfaceCombination() {
+ // clang-format off
+ const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinations = {
+ {{{{IfaceType::STA}, 3}}}
+ };
+ const std::vector<V1_0::IWifiChip::ChipMode> modes = {
+ {feature_flags::chip_mode_ids::kV3, combinations}
+ };
+ // clang-format on
+ EXPECT_CALL(*feature_flags_, getChipModes())
+ .WillRepeatedly(testing::Return(modes));
+ }
+
void assertNumberOfModes(uint32_t num_modes) {
chip_->getAvailableModes(
[num_modes](const WifiStatus& status,
@@ -655,6 +669,58 @@
ASSERT_TRUE(createIface(IfaceType::AP).empty());
}
+class WifiChip_MultiIfaceTest : public WifiChipTest {
+ public:
+ void SetUp() override {
+ setup_MultiIfaceCombination();
+ WifiChipTest::SetUp();
+ }
+};
+
+TEST_F(WifiChip_MultiIfaceTest, Create3Sta) {
+ findModeAndConfigureForIfaceType(IfaceType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateStaWithDefaultNames) {
+ property_set("wifi.interface.0", "");
+ property_set("wifi.interface.1", "");
+ property_set("wifi.interface.2", "");
+ property_set("wifi.interface", "");
+ property_set("wifi.concurrent.interface", "");
+ findModeAndConfigureForIfaceType(IfaceType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomNames) {
+ property_set("wifi.interface.0", "test0");
+ property_set("wifi.interface.1", "test1");
+ property_set("wifi.interface.2", "test2");
+ property_set("wifi.interface", "bad0");
+ property_set("wifi.concurrent.interface", "bad1");
+ findModeAndConfigureForIfaceType(IfaceType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "test0");
+ ASSERT_EQ(createIface(IfaceType::STA), "test1");
+ ASSERT_EQ(createIface(IfaceType::STA), "test2");
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomAltNames) {
+ property_set("wifi.interface.0", "");
+ property_set("wifi.interface.1", "");
+ property_set("wifi.interface.2", "");
+ property_set("wifi.interface", "testA0");
+ property_set("wifi.concurrent.interface", "testA1");
+ findModeAndConfigureForIfaceType(IfaceType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "testA0");
+ ASSERT_EQ(createIface(IfaceType::STA), "testA1");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
+}
+
} // namespace implementation
} // namespace V1_3
} // namespace wifi
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index 1f1aa95..e7ebc3b 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -41,6 +41,7 @@
constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
constexpr uint32_t kMaxRingBufferFileNum = 20;
constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
+constexpr unsigned kMaxWlanIfaces = 100;
template <typename Iface>
void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
@@ -78,16 +79,25 @@
return nullptr;
}
-std::string getWlan0IfaceName() {
- std::array<char, PROPERTY_VALUE_MAX> buffer;
- property_get("wifi.interface", buffer.data(), "wlan0");
- return buffer.data();
-}
+std::string getWlanIfaceName(unsigned idx) {
+ if (idx >= kMaxWlanIfaces) {
+ CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
+ return {};
+ }
-std::string getWlan1IfaceName() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
- property_get("wifi.concurrent.interface", buffer.data(), "wlan1");
- return buffer.data();
+ std::string propName = "wifi.interface." + std::to_string(idx);
+ auto res = property_get(propName.c_str(), buffer.data(), nullptr);
+ if (res > 0) return buffer.data();
+
+ if (idx == 0 || idx == 1) {
+ const char* altPropName =
+ (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
+ res = property_get(altPropName, buffer.data(), nullptr);
+ if (res > 0) return buffer.data();
+ }
+
+ return "wlan" + std::to_string(idx);
}
std::string getP2pIfaceName() {
@@ -636,13 +646,14 @@
legacy_hal::wifi_error legacy_status;
uint32_t legacy_feature_set;
uint32_t legacy_logger_feature_set;
+ const auto ifname = getWlanIfaceName(0);
std::tie(legacy_status, legacy_feature_set) =
- legacy_hal_.lock()->getSupportedFeatureSet(getWlan0IfaceName());
+ legacy_hal_.lock()->getSupportedFeatureSet(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {createWifiStatusFromLegacyError(legacy_status), 0};
}
std::tie(legacy_status, legacy_logger_feature_set) =
- legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName());
+ legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
// some devices don't support querying logger feature set
legacy_logger_feature_set = 0;
@@ -703,8 +714,9 @@
IWifiChip::ChipDebugInfo result;
legacy_hal::wifi_error legacy_status;
std::string driver_desc;
+ const auto ifname = getWlanIfaceName(0);
std::tie(legacy_status, driver_desc) =
- legacy_hal_.lock()->getDriverVersion(getWlan0IfaceName());
+ legacy_hal_.lock()->getDriverVersion(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get driver version: "
<< legacyErrorToString(legacy_status);
@@ -716,7 +728,7 @@
std::string firmware_desc;
std::tie(legacy_status, firmware_desc) =
- legacy_hal_.lock()->getFirmwareVersion(getWlan0IfaceName());
+ legacy_hal_.lock()->getFirmwareVersion(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get firmware version: "
<< legacyErrorToString(legacy_status);
@@ -734,7 +746,7 @@
legacy_hal::wifi_error legacy_status;
std::vector<uint8_t> driver_dump;
std::tie(legacy_status, driver_dump) =
- legacy_hal_.lock()->requestDriverMemoryDump(getWlan0IfaceName());
+ legacy_hal_.lock()->requestDriverMemoryDump(getWlanIfaceName(0));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get driver debug dump: "
<< legacyErrorToString(legacy_status);
@@ -749,7 +761,7 @@
legacy_hal::wifi_error legacy_status;
std::vector<uint8_t> firmware_dump;
std::tie(legacy_status, firmware_dump) =
- legacy_hal_.lock()->requestFirmwareMemoryDump(getWlan0IfaceName());
+ legacy_hal_.lock()->requestFirmwareMemoryDump(getWlanIfaceName(0));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get firmware debug dump: "
<< legacyErrorToString(legacy_status);
@@ -809,7 +821,7 @@
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
// These are still assumed to be based on wlan0.
- std::string ifname = getWlan0IfaceName();
+ std::string ifname = getWlanIfaceName(0);
sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
nan_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
@@ -952,7 +964,7 @@
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
sp<WifiRttController> rtt =
- new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_);
+ new WifiRttController(getWlanIfaceName(0), bound_iface, legacy_hal_);
rtt_controllers_.emplace_back(rtt);
return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
}
@@ -963,7 +975,7 @@
std::vector<legacy_hal::wifi_ring_buffer_status>
legacy_ring_buffer_status_vec;
std::tie(legacy_status, legacy_ring_buffer_status_vec) =
- legacy_hal_.lock()->getRingBuffersStatus(getWlan0IfaceName());
+ legacy_hal_.lock()->getRingBuffersStatus(getWlanIfaceName(0));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
@@ -985,7 +997,7 @@
}
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->startRingBufferLogging(
- getWlan0IfaceName(), ring_name,
+ getWlanIfaceName(0), ring_name,
static_cast<
std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
verbose_level),
@@ -1002,7 +1014,7 @@
return status;
}
legacy_hal::wifi_error legacy_status =
- legacy_hal_.lock()->getRingBufferData(getWlan0IfaceName(), ring_name);
+ legacy_hal_.lock()->getRingBufferData(getWlanIfaceName(0), ring_name);
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1018,7 +1030,7 @@
WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
- getWlan0IfaceName());
+ getWlanIfaceName(0));
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1027,7 +1039,7 @@
legacy_hal::wifi_error legacy_status;
legacy_hal::WakeReasonStats legacy_stats;
std::tie(legacy_status, legacy_stats) =
- legacy_hal_.lock()->getWakeReasonStats(getWlan0IfaceName());
+ legacy_hal_.lock()->getWakeReasonStats(getWlanIfaceName(0));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
@@ -1059,10 +1071,10 @@
}
};
legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
- getWlan0IfaceName(), on_alert_callback);
+ getWlanIfaceName(0), on_alert_callback);
} else {
legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
- getWlan0IfaceName());
+ getWlanIfaceName(0));
}
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1070,20 +1082,20 @@
WifiStatus WifiChip::selectTxPowerScenarioInternal(
V1_1::IWifiChip::TxPowerScenario scenario) {
auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
- getWlan0IfaceName(),
+ getWlanIfaceName(0),
hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
return createWifiStatusFromLegacyError(legacy_status);
}
WifiStatus WifiChip::resetTxPowerScenarioInternal() {
auto legacy_status =
- legacy_hal_.lock()->resetTxPowerScenario(getWlan0IfaceName());
+ legacy_hal_.lock()->resetTxPowerScenario(getWlanIfaceName(0));
return createWifiStatusFromLegacyError(legacy_status);
}
WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
auto legacy_status = legacy_hal_.lock()->setLatencyMode(
- getWlan0IfaceName(),
+ getWlanIfaceName(0),
hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1099,7 +1111,7 @@
WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
TxPowerScenario scenario) {
auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
- getWlan0IfaceName(),
+ getWlanIfaceName(0),
hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1179,7 +1191,7 @@
};
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->registerRingBufferCallbackHandler(
- getWlan0IfaceName(), on_ring_buffer_data_callback);
+ getWlanIfaceName(0), on_ring_buffer_data_callback);
if (legacy_status == legacy_hal::WIFI_SUCCESS) {
debug_ring_buffer_cb_registered_ = true;
@@ -1213,7 +1225,7 @@
};
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
- getWlan0IfaceName(), on_radio_mode_change_callback);
+ getWlanIfaceName(0), on_radio_mode_change_callback);
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1330,22 +1342,17 @@
return false;
}
-// Return "wlan0", if "wlan0" is not already in use, else return "wlan1".
-// This is based on the assumption that we'll have a max of 2 concurrent
-// AP/STA ifaces.
+// Return the first wlan (wlan0, wlan1 etc.) not already in use.
+// This doesn't check the actual presence of these interfaces.
std::string WifiChip::allocateApOrStaIfaceName() {
- auto ap_iface = findUsingName(ap_ifaces_, getWlan0IfaceName());
- auto sta_iface = findUsingName(sta_ifaces_, getWlan0IfaceName());
- if (!ap_iface.get() && !sta_iface.get()) {
- return getWlan0IfaceName();
- }
- ap_iface = findUsingName(ap_ifaces_, getWlan1IfaceName());
- sta_iface = findUsingName(sta_ifaces_, getWlan1IfaceName());
- if (!ap_iface.get() && !sta_iface.get()) {
- return getWlan1IfaceName();
+ for (unsigned i = 0; i < kMaxWlanIfaces; i++) {
+ const auto ifname = getWlanIfaceName(i);
+ if (findUsingName(ap_ifaces_, ifname)) continue;
+ if (findUsingName(sta_ifaces_, ifname)) continue;
+ return ifname;
}
// This should never happen. We screwed up somewhere if it did.
- CHECK(0) << "wlan0 and wlan1 in use already!";
+ CHECK(false) << "All wlan interfaces in use already!";
return {};
}
diff --git a/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp
index e195ade..71e90ac 100644
--- a/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp
+++ b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -43,6 +43,13 @@
virtual void TearDown() override { stopWifi(); }
protected:
+ bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask) {
+ const auto& status_and_caps =
+ HIDL_INVOKE(wifi_sta_iface_, getCapabilities);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
+ return (status_and_caps.second & cap_mask) != 0;
+ }
+
sp<IWifiStaIface> wifi_sta_iface_;
};
@@ -61,3 +68,30 @@
EXPECT_NE(0, status_and_mac.second[i]);
}
}
+
+/*
+ * GetLinkLayerStats_1_3
+ * Ensures that calls to get link layer stats V1_3 will retrieve a non-empty
+ * StaLinkLayerStats after link layer stats collection is enabled.
+ */
+TEST_F(WifiStaIfaceHidlTest, GetLinkLayerStats_1_3) {
+ if (!isCapabilitySupported(
+ IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) {
+ // No-op if link layer stats is not supported.
+ return;
+ }
+
+ // Enable link layer stats collection.
+ EXPECT_EQ(WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true)
+ .code);
+ // Retrieve link layer stats.
+ const auto& status_and_stats =
+ HIDL_INVOKE(wifi_sta_iface_, getLinkLayerStats_1_3);
+ EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_stats.first.code);
+ EXPECT_GT(status_and_stats.second.timeStampInMs, 0u);
+ // Disable link layer stats collection.
+ EXPECT_EQ(
+ WifiStatusCode::SUCCESS,
+ HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code);
+}