From 80af4e446509a0fed1561798ac77233d84bc7f1e Mon Sep 17 00:00:00 2001 From: Sundong Ahn Date: Thu, 2 Dec 2021 01:01:49 +0000 Subject: Prepares android.hardware.wifi@1.0-service Prepares android.hardware.wifi@1.0-service for use by a wifi HAL vendor APEX. - Creates a cc_defaults with soong config vars for @1.0-service and @1.0-service lib that customized implementations can override. Bug: 205065320 Test: m -j with mac80211_hwsim vendor APEX on Cuttlefish Test: Connect to wifi Change-Id: I5827ed1ceb9be8278a54fd828249bf8e549fb950 --- wifi/1.5/default/Android.bp | 105 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 wifi/1.5/default/Android.bp diff --git a/wifi/1.5/default/Android.bp b/wifi/1.5/default/Android.bp new file mode 100644 index 0000000000..6333b6e265 --- /dev/null +++ b/wifi/1.5/default/Android.bp @@ -0,0 +1,105 @@ +// Copyright (C) 2021 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 { + default_applicable_licenses: ["hardware_interfaces_license"], +} + +filegroup { + name: "android.hardware.wifi@1.0-service_srcs", + srcs: ["service.cpp"], +} + +cc_defaults { + name: "android.hardware.wifi@1.0-service_default", + srcs: [":android.hardware.wifi@1.0-service_srcs"], + relative_install_path: "hw", + soc_specific: true, + shared_libs: [ + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", + "libbase", + "libcutils", + "libhidlbase", + "liblog", + "libnl", + "libutils", + "libwifi-system-iface", + "libxml2", + ], + cppflags: [ + "-Wall", + "-Werror", + "-Wextra", + ], +} + +filegroup { + name: "android.hardware.wifi@1.0-service-lib_srcs", + srcs: [ + "hidl_struct_util.cpp", + "hidl_sync_util.cpp", + "ringbuffer.cpp", + "wifi.cpp", + "wifi_ap_iface.cpp", + "wifi_chip.cpp", + "wifi_feature_flags.cpp", + "wifi_iface_util.cpp", + "wifi_legacy_hal.cpp", + "wifi_legacy_hal_factory.cpp", + "wifi_legacy_hal_stubs.cpp", + "wifi_mode_controller.cpp", + "wifi_nan_iface.cpp", + "wifi_p2p_iface.cpp", + "wifi_rtt_controller.cpp", + "wifi_sta_iface.cpp", + "wifi_status_util.cpp", + ], +} + +cc_defaults { + name: "android.hardware.wifi@1.0-service-lib_defaults", + srcs: [":android.hardware.wifi@1.0-service-lib_srcs"], + relative_install_path: "hw", + soc_specific: true, + shared_libs: [ + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", + "libbase", + "libcutils", + "libhidlbase", + "liblog", + "libnl", + "libutils", + "libwifi-system-iface", + "libxml2", + ], + // Generated by building android.hardware.wifi@1.0-service-lib and printing LOCAL_CPPFLAGS. + cppflags: [ + "-Wall", + "-Werror", + "-Wextra", + "-DWIFI_HIDL_FEATURE_DUAL_INTERFACE", + ], + export_include_dirs: ["."], + include_dirs: ["external/libxml2/include"], +} -- cgit v1.2.3 From afe17c509334c2eae771cc65001152ea96792e1c Mon Sep 17 00:00:00 2001 From: Kensuke Miyagi Date: Thu, 16 Dec 2021 01:06:15 -0800 Subject: Enable LnbCallback in hidl/aidl default tuner implementation Bug: 210960436 Test: cts.TunerTest#testLnbAddAndRemoveSharee Change-Id: I11443144dcd1979afe9b077c446faaa293ccb61c --- tv/tuner/1.0/default/Lnb.cpp | 12 ++++++++++-- tv/tuner/1.0/default/Lnb.h | 1 + tv/tuner/1.1/default/Lnb.cpp | 12 ++++++++++-- tv/tuner/1.1/default/Lnb.h | 1 + tv/tuner/aidl/default/Lnb.cpp | 14 ++++++++++++-- tv/tuner/aidl/default/Lnb.h | 1 + 6 files changed, 35 insertions(+), 6 deletions(-) diff --git a/tv/tuner/1.0/default/Lnb.cpp b/tv/tuner/1.0/default/Lnb.cpp index 6025339ba7..c770e91145 100644 --- a/tv/tuner/1.0/default/Lnb.cpp +++ b/tv/tuner/1.0/default/Lnb.cpp @@ -33,9 +33,10 @@ Lnb::Lnb(int id) { Lnb::~Lnb() {} -Return Lnb::setCallback(const sp& /* callback */) { +Return Lnb::setCallback(const sp& callback) { ALOGV("%s", __FUNCTION__); + mCallback = callback; return Result::SUCCESS; } @@ -57,9 +58,16 @@ Return Lnb::setSatellitePosition(LnbPosition /* position */) { return Result::SUCCESS; } -Return Lnb::sendDiseqcMessage(const hidl_vec& /* diseqcMessage */) { +Return Lnb::sendDiseqcMessage(const hidl_vec& diseqcMessage) { ALOGV("%s", __FUNCTION__); + if (mCallback != nullptr) { + // The correct implementation should be to return the response from the + // device via onDiseqcMessage(). The below implementation is only to enable + // testing for LnbCallbacks. + ALOGV("[hidl] %s - this is for test purpose only, and must be replaced!", __FUNCTION__); + mCallback->onDiseqcMessage(diseqcMessage); + } return Result::SUCCESS; } diff --git a/tv/tuner/1.0/default/Lnb.h b/tv/tuner/1.0/default/Lnb.h index 1e97214430..c14bbd8735 100644 --- a/tv/tuner/1.0/default/Lnb.h +++ b/tv/tuner/1.0/default/Lnb.h @@ -57,6 +57,7 @@ class Lnb : public ILnb { private: int mId; virtual ~Lnb(); + sp mCallback; }; } // namespace implementation diff --git a/tv/tuner/1.1/default/Lnb.cpp b/tv/tuner/1.1/default/Lnb.cpp index 044727ff54..5dd01472d5 100644 --- a/tv/tuner/1.1/default/Lnb.cpp +++ b/tv/tuner/1.1/default/Lnb.cpp @@ -33,9 +33,10 @@ Lnb::Lnb(int id) { Lnb::~Lnb() {} -Return Lnb::setCallback(const sp& /* callback */) { +Return Lnb::setCallback(const sp& callback) { ALOGV("%s", __FUNCTION__); + mCallback = callback; return Result::SUCCESS; } @@ -57,9 +58,16 @@ Return Lnb::setSatellitePosition(LnbPosition /* position */) { return Result::SUCCESS; } -Return Lnb::sendDiseqcMessage(const hidl_vec& /* diseqcMessage */) { +Return Lnb::sendDiseqcMessage(const hidl_vec& diseqcMessage) { ALOGV("%s", __FUNCTION__); + if (mCallback != nullptr) { + // The correct implementation should be to return the response from the + // device via onDiseqcMessage(). The below implementation is only to enable + // testing for LnbCallbacks. + ALOGV("[hidl] %s - this is for test purpose only, and must be replaced!", __FUNCTION__); + mCallback->onDiseqcMessage(diseqcMessage); + } return Result::SUCCESS; } diff --git a/tv/tuner/1.1/default/Lnb.h b/tv/tuner/1.1/default/Lnb.h index 70a8e41b8b..b34ca396ca 100644 --- a/tv/tuner/1.1/default/Lnb.h +++ b/tv/tuner/1.1/default/Lnb.h @@ -51,6 +51,7 @@ class Lnb : public ILnb { private: int mId; virtual ~Lnb(); + sp mCallback; }; } // namespace implementation diff --git a/tv/tuner/aidl/default/Lnb.cpp b/tv/tuner/aidl/default/Lnb.cpp index 35d2da6310..f9343ae6c8 100644 --- a/tv/tuner/aidl/default/Lnb.cpp +++ b/tv/tuner/aidl/default/Lnb.cpp @@ -34,9 +34,11 @@ Lnb::Lnb(int id) { Lnb::~Lnb() {} -::ndk::ScopedAStatus Lnb::setCallback(const std::shared_ptr& /* in_callback */) { +::ndk::ScopedAStatus Lnb::setCallback(const std::shared_ptr& in_callback) { ALOGV("%s", __FUNCTION__); + mCallback = in_callback; + return ::ndk::ScopedAStatus::ok(); } @@ -58,9 +60,17 @@ Lnb::~Lnb() {} return ::ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus Lnb::sendDiseqcMessage(const std::vector& /* in_diseqcMessage */) { +::ndk::ScopedAStatus Lnb::sendDiseqcMessage(const std::vector& in_diseqcMessage) { ALOGV("%s", __FUNCTION__); + if (mCallback != nullptr) { + // The correct implementation should be to return the response from the + // device via onDiseqcMessage(). The below implementation is only to enable + // testing for LnbCallbacks. + ALOGV("[aidl] %s - this is for test purpose only, and must be replaced!", __FUNCTION__); + mCallback->onDiseqcMessage(in_diseqcMessage); + } + return ::ndk::ScopedAStatus::ok(); } diff --git a/tv/tuner/aidl/default/Lnb.h b/tv/tuner/aidl/default/Lnb.h index bfe3097ddc..464f9a453f 100644 --- a/tv/tuner/aidl/default/Lnb.h +++ b/tv/tuner/aidl/default/Lnb.h @@ -44,6 +44,7 @@ class Lnb : public BnLnb { private: int mId; virtual ~Lnb(); + std::shared_ptr mCallback; }; } // namespace tuner -- cgit v1.2.3 From 2d91b225eccb284e7fd353bbc10a37f652966aec Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Tue, 17 Aug 2021 00:57:04 -0700 Subject: Enable MS OS descriptors for adb. This change ported from https://android-review.googlesource.com/c/platform/hardware/google/pixel/+/1116495 Bug: 68993980 Test: check_ms_os_desc Change-Id: Ifb758f796e58ee648987a71c3aa6f2b4b8004273 --- usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp | 3 +++ usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp index 8402853b99..4c40bf88af 100644 --- a/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp +++ b/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp @@ -178,6 +178,9 @@ Status addGenericAndroidFunctions(MonitorFfs* monitorFfs, uint64_t functions, bo Status addAdb(MonitorFfs* monitorFfs, int* functionCount) { ALOGI("setCurrentUsbFunctions Adb"); + if (!WriteStringToFile("1", DESC_USE_PATH)) + return Status::ERROR; + if (!monitorFfs->addInotifyFd("/dev/usb-ffs/adb/")) return Status::ERROR; if (linkFunction("ffs.adb", (*functionCount)++)) return Status::ERROR; diff --git a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp index 898655651c..fa50821b5b 100644 --- a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp +++ b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp @@ -190,6 +190,9 @@ Status addGenericAndroidFunctions(MonitorFfs* monitorFfs, uint64_t functions, bo Status addAdb(MonitorFfs* monitorFfs, int* functionCount) { ALOGI("setCurrentUsbFunctions Adb"); + if (!WriteStringToFile("1", DESC_USE_PATH)) + return Status::ERROR; + if (!monitorFfs->addInotifyFd("/dev/usb-ffs/adb/")) return Status::ERROR; if (linkFunction("ffs.adb", (*functionCount)++)) return Status::ERROR; -- cgit v1.2.3 From 830a0b445e683eec00ec7a3d2db3d0b4b7a35801 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Wed, 29 Dec 2021 11:44:52 -0500 Subject: Add DisplayCapability::DISPLAY_DECORATION Bug: 193170859 Test: manual Test: TODO (b/212697197) Change-Id: I5e5efe671f0b3d724bafeff93e2d97007cb167ab --- .../android/hardware/graphics/composer3/DisplayCapability.aidl | 1 + .../aidl/android/hardware/graphics/composer3/DisplayCapability.aidl | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl index 9f5342ef4b..fdf110032d 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl @@ -41,4 +41,5 @@ enum DisplayCapability { PROTECTED_CONTENTS = 4, AUTO_LOW_LATENCY_MODE = 5, SUSPEND = 6, + DISPLAY_DECORATION = 7, } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl index eacf1068e1..249fed03a0 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl @@ -75,4 +75,8 @@ enum DisplayCapability { * PowerMode.ON_SUSPEND and PowerMode.DOZE_SUSPEND must be supported. */ SUSPEND = 6, + /** + * Indicates that the display supports Composition.DISPLAY_DECORATION. + */ + DISPLAY_DECORATION = 7, } -- cgit v1.2.3 From 12788a42882872c7207cd9239541a9832aa58ad2 Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Wed, 5 Jan 2022 01:00:33 +0000 Subject: Add android.hardware.ir to vndk Bug: 206116595 Test: m Change-Id: Iab49b78b87957387fd3f82685fc430dc3da00456 --- ir/aidl/Android.bp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp index 6dacb858d2..df9ab21a02 100644 --- a/ir/aidl/Android.bp +++ b/ir/aidl/Android.bp @@ -26,8 +26,7 @@ aidl_interface { }, ndk: { vndk: { - // TODO(b/206116595) enable this - enabled: false, + enabled: true, }, }, }, -- cgit v1.2.3 From c5ec034276603cac55a4d995ce8f4d1a1b8ae2a4 Mon Sep 17 00:00:00 2001 From: Sundong Ahn Date: Thu, 2 Dec 2021 01:01:49 +0000 Subject: Prepares android.hardware.wifi@1.0-service Prepares android.hardware.wifi@1.0-service for use by a wifi HAL vendor APEX. - Creates a cc_defaults with soong config vars for @1.0-service and @1.0-service lib that customized implementations can override. Bug: 205065320 Test: m -j with mac80211_hwsim vendor APEX on Cuttlefish Test: Connect to wifi Change-Id: I5827ed1ceb9be8278a54fd828249bf8e549fb950 Merged-In: I5827ed1ceb9be8278a54fd828249bf8e549fb950 --- wifi/1.5/default/Android.bp | 105 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 wifi/1.5/default/Android.bp diff --git a/wifi/1.5/default/Android.bp b/wifi/1.5/default/Android.bp new file mode 100644 index 0000000000..6333b6e265 --- /dev/null +++ b/wifi/1.5/default/Android.bp @@ -0,0 +1,105 @@ +// Copyright (C) 2021 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 { + default_applicable_licenses: ["hardware_interfaces_license"], +} + +filegroup { + name: "android.hardware.wifi@1.0-service_srcs", + srcs: ["service.cpp"], +} + +cc_defaults { + name: "android.hardware.wifi@1.0-service_default", + srcs: [":android.hardware.wifi@1.0-service_srcs"], + relative_install_path: "hw", + soc_specific: true, + shared_libs: [ + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", + "libbase", + "libcutils", + "libhidlbase", + "liblog", + "libnl", + "libutils", + "libwifi-system-iface", + "libxml2", + ], + cppflags: [ + "-Wall", + "-Werror", + "-Wextra", + ], +} + +filegroup { + name: "android.hardware.wifi@1.0-service-lib_srcs", + srcs: [ + "hidl_struct_util.cpp", + "hidl_sync_util.cpp", + "ringbuffer.cpp", + "wifi.cpp", + "wifi_ap_iface.cpp", + "wifi_chip.cpp", + "wifi_feature_flags.cpp", + "wifi_iface_util.cpp", + "wifi_legacy_hal.cpp", + "wifi_legacy_hal_factory.cpp", + "wifi_legacy_hal_stubs.cpp", + "wifi_mode_controller.cpp", + "wifi_nan_iface.cpp", + "wifi_p2p_iface.cpp", + "wifi_rtt_controller.cpp", + "wifi_sta_iface.cpp", + "wifi_status_util.cpp", + ], +} + +cc_defaults { + name: "android.hardware.wifi@1.0-service-lib_defaults", + srcs: [":android.hardware.wifi@1.0-service-lib_srcs"], + relative_install_path: "hw", + soc_specific: true, + shared_libs: [ + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", + "libbase", + "libcutils", + "libhidlbase", + "liblog", + "libnl", + "libutils", + "libwifi-system-iface", + "libxml2", + ], + // Generated by building android.hardware.wifi@1.0-service-lib and printing LOCAL_CPPFLAGS. + cppflags: [ + "-Wall", + "-Werror", + "-Wextra", + "-DWIFI_HIDL_FEATURE_DUAL_INTERFACE", + ], + export_include_dirs: ["."], + include_dirs: ["external/libxml2/include"], +} -- cgit v1.2.3 From 6acef468ccc7c9767b9dcf859fd484558d2a72a0 Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Wed, 5 Jan 2022 11:14:10 -0800 Subject: [LSC] Add LOCAL_LICENSE_KINDS to hardware/interfaces Added SPDX-license-identifier-Apache-2.0 to: ir/aidl/Android.bp ir/aidl/default/Android.bp wifi/supplicant/aidl/Android.bp Bug: 68860345 Bug: 151177513 Bug: 151953481 Test: m all Change-Id: I6796bb068122811520f911c0376b7f6caecf471c --- ir/aidl/Android.bp | 9 +++++++++ ir/aidl/default/Android.bp | 9 +++++++++ wifi/supplicant/aidl/Android.bp | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp index 6dacb858d2..a623491c36 100644 --- a/ir/aidl/Android.bp +++ b/ir/aidl/Android.bp @@ -12,6 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + aidl_interface { name: "android.hardware.ir", vendor_available: true, diff --git a/ir/aidl/default/Android.bp b/ir/aidl/default/Android.bp index 6519664dec..a4fb439566 100644 --- a/ir/aidl/default/Android.bp +++ b/ir/aidl/default/Android.bp @@ -13,6 +13,15 @@ // limitations under the License. // Example binder service of the ir HAL. +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_binary { name: "android.hardware.ir-service.example", relative_install_path: "hw", diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp index c97a6f917c..d00dd2189f 100644 --- a/wifi/supplicant/aidl/Android.bp +++ b/wifi/supplicant/aidl/Android.bp @@ -12,6 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + aidl_interface { name: "android.hardware.wifi.supplicant", vendor_available: true, -- cgit v1.2.3 From b5f634fc37d70e9c595efa318f10b35e201180bd Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Mon, 13 Dec 2021 15:13:46 -0800 Subject: Camera: Add device 3.8 and HDR10 native APIs Initial set of native API extensions to support 10-bit output capable device: - Identification - Configuration - Data plumbing Bug: 195946346 Test: adb shell /data/nativetest64/VtsHalCameraProviderV2_4TargetTest/VtsHalCameraProviderV2_4TargetTest --gtest_filter=PerInstance/CameraHidlTest.process10BitDynamicRangeRequest/0_internal_0 Change-Id: I526120944232ce211259cbd215935db7e445a6c5 --- camera/common/1.0/default/HandleImporter.cpp | 65 +++ camera/common/1.0/default/include/HandleImporter.h | 5 + camera/device/3.8/Android.bp | 3 +- camera/device/3.8/ICameraDevice.hal | 15 +- camera/device/3.8/ICameraDeviceSession.hal | 95 ++++ camera/device/3.8/types.hal | 77 +++ camera/metadata/3.8/types.hal | 63 +++ camera/provider/2.4/vts/functional/Android.bp | 4 + .../VtsHalCameraProviderV2_4TargetTest.cpp | 565 +++++++++++++++++++-- 9 files changed, 858 insertions(+), 34 deletions(-) create mode 100644 camera/device/3.8/ICameraDeviceSession.hal diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp index 7fcf52330c..fbe8686766 100644 --- a/camera/common/1.0/default/HandleImporter.cpp +++ b/camera/common/1.0/default/HandleImporter.cpp @@ -30,6 +30,7 @@ namespace helper { using aidl::android::hardware::graphics::common::PlaneLayout; using aidl::android::hardware::graphics::common::PlaneLayoutComponent; using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; +using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType; using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error; using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error; using MapperErrorV4 = android::hardware::graphics::mapper::V4_0::Error; @@ -123,6 +124,21 @@ YCbCrLayout HandleImporter::lockYCbCrInternal(const sp mapper, buffer_handle_ return layout; } +bool isMetadataPesent(const sp mapper, const buffer_handle_t& buf, + MetadataType metadataType) { + auto buffer = const_cast(buf); + mapper->get(buffer, metadataType, [] (const auto& tmpError, + const auto& tmpMetadata) { + if (tmpError == MapperErrorV4::NONE) { + return tmpMetadata.size() > 0; + } else { + ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError); + return false; + }}); + + return false; +} + std::vector getPlaneLayouts(const sp mapper, buffer_handle_t& buf) { auto buffer = const_cast(buf); std::vector planeLayouts; @@ -449,6 +465,55 @@ int HandleImporter::unlock(buffer_handle_t& buf) { return -1; } +bool HandleImporter::isSmpte2086Present(const buffer_handle_t& buf) { + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2086); + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + } + + return false; +} + +bool HandleImporter::isSmpte2094_10Present(const buffer_handle_t& buf) { + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_10); + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + } + + return false; +} + +bool HandleImporter::isSmpte2094_40Present(const buffer_handle_t& buf) { + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_40); + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + } + + return false; +} + + } // namespace helper } // namespace V1_0 } // namespace common diff --git a/camera/common/1.0/default/include/HandleImporter.h b/camera/common/1.0/default/include/HandleImporter.h index e404439cb6..83fa755c99 100644 --- a/camera/common/1.0/default/include/HandleImporter.h +++ b/camera/common/1.0/default/include/HandleImporter.h @@ -61,6 +61,11 @@ public: int unlock(buffer_handle_t& buf); // returns release fence + // Query Gralloc4 metadata + bool isSmpte2086Present(const buffer_handle_t& buf); + bool isSmpte2094_10Present(const buffer_handle_t& buf); + bool isSmpte2094_40Present(const buffer_handle_t& buf); + private: void initializeLocked(); void cleanup(); diff --git a/camera/device/3.8/Android.bp b/camera/device/3.8/Android.bp index 2a1f215023..c3c29416a9 100644 --- a/camera/device/3.8/Android.bp +++ b/camera/device/3.8/Android.bp @@ -9,7 +9,6 @@ package { default_applicable_licenses: ["hardware_interfaces_license"], } - hidl_interface { name: "android.hardware.camera.device@3.8", root: "android.hardware", @@ -17,6 +16,7 @@ hidl_interface { "types.hal", "ICameraDevice.hal", "ICameraDeviceCallback.hal", + "ICameraDeviceSession.hal", ], interfaces: [ "android.hardware.camera.common@1.0", @@ -31,6 +31,7 @@ hidl_interface { "android.hardware.camera.metadata@3.4", "android.hardware.camera.metadata@3.5", "android.hardware.camera.metadata@3.6", + "android.hardware.camera.metadata@3.8", "android.hardware.graphics.common@1.0", "android.hidl.base@1.0", ], diff --git a/camera/device/3.8/ICameraDevice.hal b/camera/device/3.8/ICameraDevice.hal index 1101819a4d..8832c68098 100644 --- a/camera/device/3.8/ICameraDevice.hal +++ b/camera/device/3.8/ICameraDevice.hal @@ -26,8 +26,8 @@ import @3.7::ICameraDevice; * API at LIMITED or better hardware level. * * ICameraDevice.open() must return @3.2::ICameraDeviceSession, - * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, or - * @3.7::ICameraDeviceSession. + * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, + * @3.7::ICameraDeviceSession, or @3.8::ICameraDeviceSession. */ interface ICameraDevice extends @3.7::ICameraDevice { /** @@ -107,4 +107,15 @@ interface ICameraDevice extends @3.7::ICameraDevice { * */ getTorchStrengthLevel() generates (Status status, int32_t torchStrength); + + /** + * isStreamCombinationSupported_3_8: + * + * Identical to @3.7::ICameraDevice.isStreamCombinationSupported, except + * that it takes a @3.8::StreamConfiguration parameter, which could contain + * additional information about a specific 10-bit dynamic range profile. + * + */ + isStreamCombinationSupported_3_8(StreamConfiguration streams) + generates (Status status, bool queryStatus); }; diff --git a/camera/device/3.8/ICameraDeviceSession.hal b/camera/device/3.8/ICameraDeviceSession.hal new file mode 100644 index 0000000000..88e4338209 --- /dev/null +++ b/camera/device/3.8/ICameraDeviceSession.hal @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2021 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.camera.device@3.8; + +import android.hardware.camera.common@1.0::Status; +import @3.5::StreamConfiguration; +import @3.7::ICameraDeviceSession; +import @3.6::HalStreamConfiguration; + +/** + * Camera device active session interface. + * + * Obtained via ICameraDevice::open(), this interface contains the methods to + * configure and request captures from an active camera device. + */ +interface ICameraDeviceSession extends @3.7::ICameraDeviceSession { + /** + * configureStreams_3_8: + * + * Identical to @3.7::ICameraDeviceSession.configureStreams_3_7, except that: + * + * - The requestedConfiguration allows the camera framework to configure + * 10-bit dynamic range profile. + * + * @return status Status code for the operation, one of: + * OK: + * On successful stream configuration. + * INTERNAL_ERROR: + * If there has been a fatal error and the device is no longer + * operational. Only close() can be called successfully by the + * framework after this error is returned. + * ILLEGAL_ARGUMENT: + * If the requested stream configuration is invalid. Some examples + * of invalid stream configurations include: + * - Including more than 1 INPUT stream + * - Not including any OUTPUT streams + * - Including streams with unsupported formats, or an unsupported + * size for that format. + * - Including too many output streams of a certain format. + * - Unsupported rotation configuration + * - Stream sizes/formats don't satisfy the + * StreamConfigurationMode requirements + * for non-NORMAL mode, or the requested operation_mode is not + * supported by the HAL. + * - Unsupported usage flag + * - Unsupported stream groupIds, or unsupported multi-resolution + * input stream. + * - Invalid combination between a 10-bit dynamic range profile + * and none impl. defined 8-bit format for a particular stream. + * The camera service cannot filter out all possible illegal stream + * configurations, since some devices may support more simultaneous + * streams or larger stream resolutions than the minimum required + * for a given camera device hardware level. The HAL must return an + * ILLEGAL_ARGUMENT for any unsupported stream set, and then be + * ready to accept a future valid stream configuration in a later + * configureStreams call. + * @return halConfiguration The stream parameters desired by the HAL for + * each stream, including maximum buffers, the usage flags, and the + * override format and dataspace. + */ + configureStreams_3_8(StreamConfiguration requestedConfiguration) + generates (Status status, @3.6::HalStreamConfiguration halConfiguration); + + /** + * repeatingRequestEnd: + * + * Notification about the last frame number in a repeating request along with the + * ids of all streams included in the repeating request. + * + * This can be called at any point after 'processCaptureRequest' in response + * to camera clients disabling an active repeating request. + * + * Performance requirements: + * The call must not be blocked for extensive periods and should be extremely lightweight. There + * must be no frame rate degradation or frame jitter introduced. + * + * This method must always succeed, even if the device has encountered a + * serious error. + */ + repeatingRequestEnd(uint32_t frameNumber, vec streamIds); +}; diff --git a/camera/device/3.8/types.hal b/camera/device/3.8/types.hal index 843d050bb2..9d1ac22f5a 100644 --- a/camera/device/3.8/types.hal +++ b/camera/device/3.8/types.hal @@ -19,6 +19,11 @@ package android.hardware.camera.device@3.8; import @3.2::ErrorMsg; import @3.2::MsgType; import @3.2::ShutterMsg; +import @3.2::CameraMetadata; +import @3.2::StreamConfigurationMode; +import @3.7::Stream; + +import android.hardware.camera.metadata@3.8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap; /** * ShutterMsg: @@ -67,3 +72,75 @@ struct NotifyMsg { ShutterMsg shutter; } msg; }; + +/** + * Stream: + * + * A descriptor for a single camera input or output stream. A stream is defined + * by the framework by its buffer resolution and format, and additionally by the + * HAL with the gralloc usage flags and the maximum in-flight buffer count. + * + * This version extends the @3.7 Stream with the dynamic range profile field. + */ +struct Stream { + /** + * The definition of Stream from the prior version. + */ + @3.7::Stream v3_7; + + /** + * The dynamic range profile for this stream. + * + * This field is valid and must only be considered for streams with format + * android.hardware.graphics.common.PixelFormat.YCBCR_P010 or + * android.hardware.graphics.common.PixelFormat.IMPLEMENTATION_DEFINED on devices supporting the + * ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_10_BIT capability. + * + */ + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap dynamicRangeProfile; +}; + +/** + * StreamConfiguration: + * + * Identical to @3.7::StreamConfiguration, except that the streams + * vector contains @3.8::Stream. + */ +struct StreamConfiguration { + /** + * An array of camera stream pointers, defining the input/output + * configuration for the camera HAL device. + */ + vec streams; + + /** + * The definition of operation mode from prior version. + * + */ + @3.2::StreamConfigurationMode operationMode; + + /** + * The definition of session parameters from prior version. + */ + @3.2::CameraMetadata sessionParams; + + /** + * The definition of stream configuration counter from prior version. + */ + uint32_t streamConfigCounter; + + /** + * If an input stream is configured, whether the input stream is expected to + * receive variable resolution images. + * + * This flag can only be set to true if the camera device supports + * multi-resolution input streams by advertising input stream configurations in + * physicalCameraMultiResolutionStreamConfigurations in its physical cameras' + * characteristics. + * + * When this flag is set to true, the input stream's width and height can be + * any one of the supported multi-resolution input stream sizes. + */ + bool multiResolutionInputImage; +}; + diff --git a/camera/metadata/3.8/types.hal b/camera/metadata/3.8/types.hal index 11360da72b..4c70eb9528 100644 --- a/camera/metadata/3.8/types.hal +++ b/camera/metadata/3.8/types.hal @@ -53,6 +53,21 @@ enum CameraMetadataTag : @3.7::CameraMetadataTag { ANDROID_FLASH_INFO_END_3_8, + /** android.request.availableDynamicRangeProfilesMap [static, enum[], ndk_public] + * + *

A map of all available 10-bit dynamic range profiles along with their + * capture request constraints.

+ */ + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP = android.hardware.camera.metadata@3.4::CameraMetadataTag:ANDROID_REQUEST_END_3_4, + + /** android.request.recommendedTenBitDynamicRangeProfile [static, int32, java_public] + * + *

Recommended 10-bit dynamic range profile.

+ */ + ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE, + + ANDROID_REQUEST_END_3_8, + }; /* @@ -66,3 +81,51 @@ enum CameraMetadataEnumAndroidControlVideoStabilizationMode : @3.2::CameraMetadataEnumAndroidControlVideoStabilizationMode { ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION, }; + +/** android.request.availableCapabilities enumeration values added since v3.6 + * @see ANDROID_REQUEST_AVAILABLE_CAPABILITIES + */ +enum CameraMetadataEnumAndroidRequestAvailableCapabilities : + @3.6::CameraMetadataEnumAndroidRequestAvailableCapabilities { + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT, +}; + +/** android.request.availableDynamicRangeProfilesMap enumeration values + * @see ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP + */ +enum CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap : uint32_t { + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD + = 0x1, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 0x2, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 0x4, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS + = 0x8, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF + = 0x10, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO + = 0x20, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM + = 0x40, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO + = 0x80, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF + = 0x100, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO + = 0x200, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM + = 0x400, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO + = 0x800, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000, +}; + +/** android.scaler.availableRecommendedStreamConfigurations enumeration values added since v3.4 + * @see ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS + */ +enum CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations : + @3.4::CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations { + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT + = 0x8, + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8 + = 0x9, +}; diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp index 2c141ee1d6..0e622655df 100644 --- a/camera/provider/2.4/vts/functional/Android.bp +++ b/camera/provider/2.4/vts/functional/Android.bp @@ -51,11 +51,15 @@ cc_test { "android.hardware.camera.device@3.7", "android.hardware.camera.device@3.8", "android.hardware.camera.metadata@3.4", + "android.hardware.camera.metadata@3.8", "android.hardware.camera.provider@2.4", "android.hardware.camera.provider@2.5", "android.hardware.camera.provider@2.6", "android.hardware.camera.provider@2.7", "android.hardware.graphics.common@1.0", + "android.hardware.graphics.mapper@2.0", + "android.hardware.graphics.mapper@3.0", + "android.hardware.graphics.mapper@4.0", "android.hidl.allocator@1.0", "libgrallocusage", "libhidlmemory", diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index d39850d06d..dd45b0dca8 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -45,7 +46,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -97,6 +100,7 @@ using ::android::hardware::camera::common::V1_0::Status; using ::android::hardware::camera::common::V1_0::TorchMode; using ::android::hardware::camera::common::V1_0::TorchModeStatus; using ::android::hardware::camera::common::V1_0::helper::CameraParameters; +using ::android::hardware::camera::common::V1_0::helper::HandleImporter; using ::android::hardware::camera::common::V1_0::helper::Size; using ::android::hardware::camera::device::V1_0::CameraFacing; using ::android::hardware::camera::device::V1_0::CameraFrameMetadata; @@ -129,6 +133,8 @@ using ::android::hardware::camera::metadata::V3_4:: CameraMetadataEnumAndroidSensorInfoColorFilterArrangement; using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag; using ::android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode; +using ::android::hardware::camera::metadata::V3_8:: + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap; using ::android::hardware::camera::provider::V2_4::ICameraProvider; using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; using ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination; @@ -136,7 +142,6 @@ using ::android::hardware::graphics::common::V1_0::BufferUsage; using ::android::hardware::graphics::common::V1_0::Dataspace; using ::android::hardware::graphics::common::V1_0::PixelFormat; using ::android::hidl::allocator::V1_0::IAllocator; -using ::android::hidl::memory::V1_0::IMapper; using ::android::hidl::memory::V1_0::IMemory; using ResultMetadataQueue = MessageQueue; using ::android::hidl::manager::V1_0::IServiceManager; @@ -781,13 +786,15 @@ public: sp *session3_4 /*out*/, sp *session3_5 /*out*/, sp *session3_6 /*out*/, - sp *session3_7 /*out*/); + sp *session3_7 /*out*/, + sp *session3_8 /*out*/); void castInjectionSession( const sp& session, sp* injectionSession3_7 /*out*/); void castDevice(const sp& device, int32_t deviceVersion, sp* device3_5 /*out*/, - sp* device3_7 /*out*/); + sp* device3_7 /*out*/, + sp* device3_8 /*out*/); void createStreamConfiguration( const ::android::hardware::hidl_vec& streams3_2, StreamConfigurationMode configMode, @@ -817,6 +824,16 @@ public: uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, sp* outCb /*out*/, uint32_t streamConfigCounter, bool maxResolution); + void configureStreams3_8(const std::string& name, int32_t deviceVersion, + sp provider, PixelFormat format, + sp* session3_8 /*out*/, + V3_2::Stream* previewStream /*out*/, + device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, + bool* supportsPartialResults /*out*/, + uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, + sp* outCb /*out*/, uint32_t streamConfigCounter, + bool maxResolution, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap prof); void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp provider, @@ -896,6 +913,9 @@ public: static bool isDepthOnly(const camera_metadata_t* staticMeta); static bool isUltraHighResolution(const camera_metadata_t* staticMeta); + static void get10BitDynamicRangeProfiles(const camera_metadata_t* staticMeta, + std::vector *profiles); + static bool is10BitDynamicRangeCapable(const camera_metadata_t* staticMeta); static Status getAvailableOutputStreams(const camera_metadata_t* staticMeta, std::vector& outputStreams, @@ -1077,6 +1097,10 @@ protected: expectedPhysicalResults(extraPhysicalResult) {} }; + static void verify10BitMetadata(HandleImporter& importer, + const InFlightRequest& request, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap profile); + // Map from frame number to the in-flight request state typedef ::android::KeyedVector InFlightMap; @@ -1105,6 +1129,8 @@ protected: // Camera provider type. std::string mProviderType; + + HandleImporter mHandleImporter; }; Return CameraHidlTest::Camera1DeviceCb::notifyCallback( @@ -3342,10 +3368,13 @@ TEST_P(CameraHidlTest, openClose) { sp sessionV3_5; sp sessionV3_6; sp sessionV3_7; + sp sessionV3_8; castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4, &sessionV3_5, &sessionV3_6, - &sessionV3_7); - if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) { + &sessionV3_7, &sessionV3_8); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_8) { + ASSERT_TRUE(sessionV3_8.get() != nullptr); + } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) { ASSERT_TRUE(sessionV3_7.get() != nullptr); } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) { ASSERT_TRUE(sessionV3_6.get() != nullptr); @@ -3513,14 +3542,17 @@ TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) { sp session3_5; sp session3_6; sp session3_7; + sp session3_8; sp cameraDevice; sp cameraDevice3_5; sp cameraDevice3_7; + sp cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); @@ -3616,9 +3648,11 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { sp session3_5; sp session3_6; sp session3_7; + sp session3_8; sp cameraDevice; sp cameraDevice3_5; sp cameraDevice3_7; + sp cameraDevice3_8; ::android::hardware::camera::device::V3_7::StreamConfiguration config3_7; ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; @@ -3655,8 +3689,9 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { openEmptyDeviceSession(name, mProvider2_6, &cti.session /*out*/, &cti.staticMeta /*out*/, &cti.cameraDevice /*out*/); castSession(cti.session, deviceVersion, &cti.session3_3, &cti.session3_4, - &cti.session3_5, &cti.session3_6, &cti.session3_7); - castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5, &cti.cameraDevice3_7); + &cti.session3_5, &cti.session3_6, &cti.session3_7, &cti.session3_8); + castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5, &cti.cameraDevice3_7, + &cti.cameraDevice3_8); outputStreams.clear(); ASSERT_EQ(Status::OK, getMandatoryConcurrentStreams(cti.staticMeta, &outputStreams)); @@ -3785,14 +3820,17 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { sp session3_5; sp session3_6; sp session3_7; + sp session3_8; sp cameraDevice; sp cameraDevice3_5; sp cameraDevice3_7; + sp cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); @@ -3998,14 +4036,17 @@ TEST_P(CameraHidlTest, configureStreamsZSLInputOutputs) { sp session3_5; sp session3_6; sp session3_7; + sp session3_8; sp cameraDevice; sp cameraDevice3_5; sp cameraDevice3_7; + sp cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); Status rc = isZSLModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -4184,9 +4225,10 @@ TEST_P(CameraHidlTest, configureStreamsWithSessionParameters) { sp session3_5; sp session3_6; sp session3_7; + sp session3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) { ASSERT_NE(session3_4, nullptr); } else { @@ -4325,14 +4367,17 @@ TEST_P(CameraHidlTest, configureStreamsPreviewStillOutputs) { sp session3_5; sp session3_6; sp session3_7; + sp session3_8; sp cameraDevice; sp cameraDevice3_5; sp cameraDevice3_7; + sp cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); // Check if camera support depth only if (isDepthOnly(staticMeta)) { @@ -4459,14 +4504,17 @@ TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) { sp session3_5; sp session3_6; sp session3_7; + sp session3_8; sp cameraDevice; sp cameraDevice3_5; sp cameraDevice3_7; + sp cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); Status rc = isConstrainedModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -4706,14 +4754,17 @@ TEST_P(CameraHidlTest, configureStreamsVideoStillOutputs) { sp session3_5; sp session3_6; sp session3_7; + sp session3_8; sp cameraDevice; sp cameraDevice3_5; sp cameraDevice3_7; + sp cameraDevice3_8; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); - castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + &session3_6, &session3_7, &session3_8); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, + &cameraDevice3_8); // Check if camera support depth only if (isDepthOnly(staticMeta)) { @@ -4997,6 +5048,20 @@ void CameraHidlTest::processCaptureRequestInternal(uint64_t bufferUsage, ASSERT_EQ(Status::OK, status); ASSERT_EQ(numRequestProcessed, 1u); + if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8) { + sp session3_3; + sp session3_4; + sp session3_5; + sp session3_6; + sp session3_7; + sp session3_8; + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7, &session3_8); + ASSERT_TRUE(session3_8.get() != nullptr); + hidl_vec streamIds = { halStreamConfig.streams[0].id }; + session3_8->repeatingRequestEnd(request.frameNumber, streamIds); + } + { std::unique_lock l(mLock); while (!inflightReq.errorCodeValid && @@ -5640,6 +5705,188 @@ TEST_P(CameraHidlTest, processUltraHighResolutionRequest) { } } +// Generate and verify 10-bit dynamic range request +TEST_P(CameraHidlTest, process10BitDynamicRangeRequest) { + hidl_vec cameraDeviceNames = getCameraDeviceNames(mProvider); + uint64_t bufferId = 1; + uint32_t frameNumber = 1; + ::android::hardware::hidl_vec settings; + + for (const auto& name : cameraDeviceNames) { + int deviceVersion = getCameraDeviceVersion(name, mProviderType); + if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_8) { + continue; + } + std::string version, deviceId; + ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId)); + camera_metadata_t* staticMeta; + Return ret; + sp session; + openEmptyDeviceSession(name, mProvider, &session, &staticMeta); + if (!is10BitDynamicRangeCapable(staticMeta)) { + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + std::vector profileList; + get10BitDynamicRangeProfiles(staticMeta, &profileList); + ASSERT_FALSE(profileList.empty()); + + android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings; + ret = session->constructDefaultRequestSettings( + RequestTemplate::STILL_CAPTURE, + [&defaultSettings](auto status, const auto& req) mutable { + ASSERT_EQ(Status::OK, status); + + const camera_metadata_t* metadata = + reinterpret_cast(req.data()); + size_t expectedSize = req.size(); + int result = validate_camera_metadata_structure(metadata, &expectedSize); + ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED)); + + size_t entryCount = get_camera_metadata_entry_count(metadata); + ASSERT_GT(entryCount, 0u); + defaultSettings = metadata; + }); + ASSERT_TRUE(ret.isOk()); + + const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock(); + settings.setToExternal( + reinterpret_cast(const_cast(settingsBuffer)), + get_camera_metadata_size(settingsBuffer)); + overrideRotateAndCrop(&settings); + + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + V3_6::HalStreamConfiguration halStreamConfig; + bool supportsPartialResults = false; + bool useHalBufManager = false; + uint32_t partialResultCount = 0; + V3_2::Stream previewStream; + sp session3_8; + sp cb; + for (const auto& profile : profileList) { + configureStreams3_8(name, deviceVersion, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, + &session3_8, &previewStream, &halStreamConfig, + &supportsPartialResults, &partialResultCount, &useHalBufManager, + &cb, 0, /*maxResolution*/ false, profile); + ASSERT_NE(session3_8, nullptr); + + std::shared_ptr resultQueue; + auto resultQueueRet = session3_8->getCaptureResultMetadataQueue( + [&resultQueue](const auto& descriptor) { + resultQueue = std::make_shared(descriptor); + if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) { + ALOGE("%s: HAL returns empty result metadata fmq," + " not use it", + __func__); + resultQueue = nullptr; + // Don't use the queue onwards. + } + }); + ASSERT_TRUE(resultQueueRet.isOk()); + + std::vector graphicBuffers; + graphicBuffers.reserve(halStreamConfig.streams.size()); + ::android::hardware::hidl_vec outputBuffers; + outputBuffers.resize(halStreamConfig.streams.size()); + InFlightRequest inflightReq = {static_cast(halStreamConfig.streams.size()), + false, + supportsPartialResults, + partialResultCount, + std::unordered_set(), + resultQueue}; + + size_t k = 0; + for (const auto& halStream : halStreamConfig.streams) { + hidl_handle buffer_handle; + if (useHalBufManager) { + outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, + 0, + buffer_handle, + BufferStatus::OK, + nullptr, + nullptr}; + } else { + allocateGraphicBuffer( + previewStream.width, previewStream.height, + android_convertGralloc1To0Usage(halStream.v3_4.v3_3.v3_2.producerUsage, + halStream.v3_4.v3_3.v3_2.consumerUsage), + halStream.v3_4.v3_3.v3_2.overrideFormat, &buffer_handle); + + graphicBuffers.push_back(buffer_handle); + outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id, + bufferId, + buffer_handle, + BufferStatus::OK, + nullptr, + nullptr}; + bufferId++; + } + k++; + } + + StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; + V3_4::CaptureRequest request3_4; + request3_4.v3_2.frameNumber = frameNumber; + request3_4.v3_2.fmqSettingsSize = 0; + request3_4.v3_2.settings = settings; + request3_4.v3_2.inputBuffer = emptyInputBuffer; + request3_4.v3_2.outputBuffers = outputBuffers; + V3_7::CaptureRequest request3_7; + request3_7.v3_4 = request3_4; + request3_7.inputWidth = 0; + request3_7.inputHeight = 0; + + { + std::unique_lock l(mLock); + mInflightMap.clear(); + mInflightMap.add(frameNumber, &inflightReq); + } + + Status stat = Status::INTERNAL_ERROR; + uint32_t numRequestProcessed = 0; + hidl_vec cachesToRemove; + Return returnStatus = session3_8->processCaptureRequest_3_7( + {request3_7}, cachesToRemove, + [&stat, &numRequestProcessed](auto s, uint32_t n) { + stat = s; + numRequestProcessed = n; + }); + ASSERT_TRUE(returnStatus.isOk()); + ASSERT_EQ(Status::OK, stat); + ASSERT_EQ(numRequestProcessed, 1u); + + { + std::unique_lock l(mLock); + while (!inflightReq.errorCodeValid && + ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) { + auto timeout = std::chrono::system_clock::now() + + std::chrono::seconds(kStreamBufferTimeoutSec); + ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); + } + + ASSERT_FALSE(inflightReq.errorCodeValid); + ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); + verify10BitMetadata(mHandleImporter, inflightReq, profile); + } + if (useHalBufManager) { + hidl_vec streamIds(halStreamConfig.streams.size()); + for (size_t i = 0; i < streamIds.size(); i++) { + streamIds[i] = halStreamConfig.streams[i].v3_4.v3_3.v3_2.id; + } + session3_8->signalStreamFlush(streamIds, /*streamConfigCounter*/ 0); + cb->waitForBuffersReturned(); + } + + ret = session3_8->close(); + ASSERT_TRUE(ret.isOk()); + } + } +} + // Generate and verify a burst containing alternating sensor sensitivity values TEST_P(CameraHidlTest, processCaptureRequestBurstISO) { hidl_vec cameraDeviceNames = getCameraDeviceNames(mProvider); @@ -7448,8 +7695,9 @@ void CameraHidlTest::configureStreams3_7( sp session3_4; sp session3_5; sp session3_6; + sp session3_8; castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6, - session3_7); + session3_7, &session3_8); ASSERT_NE(nullptr, (*session3_7).get()); *useHalBufManager = false; @@ -7497,7 +7745,8 @@ void CameraHidlTest::configureStreams3_7( ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7); sp cameraDevice3_5 = nullptr; sp cameraDevice3_7 = nullptr; - castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + sp cameraDevice3_8 = nullptr; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8); ASSERT_NE(cameraDevice3_7, nullptr); bool supported = false; ret = cameraDevice3_7->isStreamCombinationSupported_3_7( @@ -7530,6 +7779,153 @@ void CameraHidlTest::configureStreams3_7( ASSERT_TRUE(ret.isOk()); } +// Configure streams +void CameraHidlTest::configureStreams3_8( + const std::string& name, int32_t deviceVersion, sp provider, + PixelFormat format, sp* session3_8 /*out*/, + V3_2::Stream* previewStream /*out*/, + device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, + bool* supportsPartialResults /*out*/, uint32_t* partialResultCount /*out*/, + bool* useHalBufManager /*out*/, sp* outCb /*out*/, uint32_t streamConfigCounter, + bool maxResolution, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap prof) { + ASSERT_NE(nullptr, session3_8); + ASSERT_NE(nullptr, halStreamConfig); + ASSERT_NE(nullptr, previewStream); + ASSERT_NE(nullptr, supportsPartialResults); + ASSERT_NE(nullptr, partialResultCount); + ASSERT_NE(nullptr, useHalBufManager); + ASSERT_NE(nullptr, outCb); + ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8); + + std::vector outputStreams; + ::android::sp device3_x; + ALOGI("configureStreams: Testing camera device %s", name.c_str()); + Return ret; + ret = provider->getCameraDeviceInterface_V3_x(name, [&](auto status, const auto& device) { + ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(device, nullptr); + device3_x = device; + }); + ASSERT_TRUE(ret.isOk()); + + camera_metadata_t* staticMeta; + ret = device3_x->getCameraCharacteristics([&](Status s, CameraMetadata metadata) { + ASSERT_EQ(Status::OK, s); + staticMeta = + clone_camera_metadata(reinterpret_cast(metadata.data())); + ASSERT_NE(nullptr, staticMeta); + }); + ASSERT_TRUE(ret.isOk()); + + camera_metadata_ro_entry entry; + auto status = + find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); + if ((0 == status) && (entry.count > 0)) { + *partialResultCount = entry.data.i32[0]; + *supportsPartialResults = (*partialResultCount > 1); + } + + sp cb = new DeviceCb(this, deviceVersion, staticMeta); + sp session; + ret = device3_x->open(cb, [&session](auto status, const auto& newSession) { + ALOGI("device::open returns status:%d", (int)status); + ASSERT_EQ(Status::OK, status); + ASSERT_NE(newSession, nullptr); + session = newSession; + }); + ASSERT_TRUE(ret.isOk()); + *outCb = cb; + + sp session3_3; + sp session3_4; + sp session3_5; + sp session3_6; + sp session3_7; + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6, + &session3_7, session3_8); + ASSERT_NE(nullptr, (*session3_8).get()); + + *useHalBufManager = false; + status = find_camera_metadata_ro_entry( + staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry); + if ((0 == status) && (entry.count == 1)) { + *useHalBufManager = (entry.data.u8[0] == + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); + } + + outputStreams.clear(); + Size maxSize; + auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution); + ASSERT_EQ(Status::OK, rc); + free_camera_metadata(staticMeta); + + ::android::hardware::hidl_vec streams3_8(1); + streams3_8[0].v3_7.groupId = -1; + streams3_8[0].v3_7.sensorPixelModesUsed = { + CameraMetadataEnumAndroidSensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT}; + streams3_8[0].v3_7.v3_4.bufferSize = 0; + streams3_8[0].v3_7.v3_4.v3_2.id = 0; + streams3_8[0].v3_7.v3_4.v3_2.streamType = StreamType::OUTPUT; + streams3_8[0].v3_7.v3_4.v3_2.width = static_cast(maxSize.width); + streams3_8[0].v3_7.v3_4.v3_2.height = static_cast(maxSize.height); + streams3_8[0].v3_7.v3_4.v3_2.format = static_cast(format); + streams3_8[0].v3_7.v3_4.v3_2.usage = GRALLOC1_CONSUMER_USAGE_CPU_READ; + streams3_8[0].v3_7.v3_4.v3_2.dataSpace = 0; + streams3_8[0].v3_7.v3_4.v3_2.rotation = StreamRotation::ROTATION_0; + streams3_8[0].dynamicRangeProfile = prof; + + ::android::hardware::camera::device::V3_8::StreamConfiguration config3_8; + config3_8.streams = streams3_8; + config3_8.operationMode = StreamConfigurationMode::NORMAL_MODE; + config3_8.streamConfigCounter = streamConfigCounter; + config3_8.multiResolutionInputImage = false; + RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE; + ret = (*session3_8) + ->constructDefaultRequestSettings(reqTemplate, + [&config3_8](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + config3_8.sessionParams = req; + }); + ASSERT_TRUE(ret.isOk()); + + sp cameraDevice3_5 = nullptr; + sp cameraDevice3_7 = nullptr; + sp cameraDevice3_8 = nullptr; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8); + ASSERT_NE(cameraDevice3_8, nullptr); + bool supported = false; + ret = cameraDevice3_8->isStreamCombinationSupported_3_8( + config3_8, [&supported](Status s, bool combStatus) { + ASSERT_TRUE((Status::OK == s) || (Status::METHOD_NOT_SUPPORTED == s)); + if (Status::OK == s) { + supported = combStatus; + } + }); + ASSERT_TRUE(ret.isOk()); + ASSERT_EQ(supported, true); + + if (*session3_8 != nullptr) { + ret = (*session3_8) + ->configureStreams_3_8( + config3_8, + [&](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + *halStreamConfig = halConfig; + if (*useHalBufManager) { + hidl_vec streams(1); + hidl_vec halStreams(1); + streams[0] = streams3_8[0].v3_7.v3_4; + halStreams[0] = halConfig.streams[0].v3_4.v3_3.v3_2; + cb->setCurrentStreamConfig(streams, halStreams); + } + }); + } + *previewStream = streams3_8[0].v3_7.v3_4.v3_2; + ASSERT_TRUE(ret.isOk()); +} + // Configure multiple preview streams using different physical ids. void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp provider, @@ -7604,8 +8000,9 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t sp session3_3; sp session3_6; sp session3_7; + sp session3_8; castSession(session, deviceVersion, &session3_3, session3_4, session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); ASSERT_NE(nullptr, (*session3_4).get()); *useHalBufManager = false; @@ -7650,7 +8047,8 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t if (allowUnsupport) { sp cameraDevice3_5; sp cameraDevice3_7; - castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); + sp cameraDevice3_8; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8); bool supported = false; ret = cameraDevice3_5->isStreamCombinationSupported(config3_4, @@ -7843,6 +8241,95 @@ bool CameraHidlTest::isUltraHighResolution(const camera_metadata_t* staticMeta) return false; } +void CameraHidlTest::get10BitDynamicRangeProfiles(const camera_metadata_t* staticMeta, + std::vector *profiles) { + ASSERT_NE(nullptr, staticMeta); + ASSERT_NE(nullptr, profiles); + camera_metadata_ro_entry entry; + std::unordered_set entries; + int rc = find_camera_metadata_ro_entry(staticMeta, + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP, &entry); + ASSERT_EQ(rc, 0); + ASSERT_TRUE(entry.count > 0); + ASSERT_EQ(entry.count % 2, 0); + + for (uint32_t i = 0; i < entry.count; i += 2) { + ASSERT_NE(entry.data.i32[i], + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD); + ASSERT_EQ(entries.find(entry.data.i32[i]), entries.end()); + entries.insert(static_cast(entry.data.i32[i])); + profiles->emplace_back( + static_cast + (entry.data.i32[i])); + } + + if (!entries.empty()) { + ASSERT_NE(entries.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10), + entries.end()); + } +} + +bool CameraHidlTest::is10BitDynamicRangeCapable(const camera_metadata_t* staticMeta) { + camera_metadata_ro_entry scalarEntry; + int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, + &scalarEntry); + if (rc == 0) { + for (uint32_t i = 0; i < scalarEntry.count; i++) { + if (scalarEntry.data.u8[i] == + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) { + return true; + } + } + } + return false; +} + +void CameraHidlTest::verify10BitMetadata(HandleImporter& importer, + const InFlightRequest& request, + CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap profile) { + for (const auto& b : request.resultOutputBuffers) { + bool smpte2086Present = importer.isSmpte2086Present(b.buffer.buffer.getNativeHandle()); + bool smpte2094_10Present = importer.isSmpte2094_10Present( + b.buffer.buffer.getNativeHandle()); + bool smpte2094_40Present = importer.isSmpte2094_40Present( + b.buffer.buffer.getNativeHandle()); + + switch (static_cast(profile)) { + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10: + ASSERT_FALSE(smpte2086Present); + ASSERT_FALSE(smpte2094_10Present); + ASSERT_FALSE(smpte2094_40Present); + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: + ASSERT_TRUE(smpte2086Present); + ASSERT_FALSE(smpte2094_10Present); + ASSERT_FALSE(smpte2094_40Present); + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: + ASSERT_FALSE(smpte2086Present); + ASSERT_FALSE(smpte2094_10Present); + ASSERT_TRUE(smpte2094_40Present); + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM: + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO: + ASSERT_FALSE(smpte2086Present); + ASSERT_TRUE(smpte2094_10Present); + ASSERT_FALSE(smpte2094_40Present); + break; + default: + ALOGE("%s: Unexpected 10-bit dynamic range profile: %d", + __FUNCTION__, profile); + ADD_FAILURE(); + } + } +} + bool CameraHidlTest::isDepthOnly(const camera_metadata_t* staticMeta) { camera_metadata_ro_entry scalarEntry; camera_metadata_ro_entry depthEntry; @@ -8006,8 +8493,9 @@ void CameraHidlTest::configureSingleStream( sp session3_5; sp session3_6; sp session3_7; + sp session3_8; castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); *useHalBufManager = false; status = find_camera_metadata_ro_entry(staticMeta, @@ -8138,12 +8626,19 @@ void CameraHidlTest::configureSingleStream( void CameraHidlTest::castDevice(const sp& device, int32_t deviceVersion, sp* device3_5 /*out*/, - sp* device3_7 /*out*/) { + sp* device3_7 /*out*/, + sp* device3_8 /*out*/) { ASSERT_NE(nullptr, device3_5); ASSERT_NE(nullptr, device3_7); + ASSERT_NE(nullptr, device3_8); switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_8: + case CAMERA_DEVICE_API_VERSION_3_8: { + auto castResult = device::V3_8::ICameraDevice::castFrom(device); + ASSERT_TRUE(castResult.isOk()); + *device3_8 = castResult; + } + [[fallthrough]]; case CAMERA_DEVICE_API_VERSION_3_7: { auto castResult = device::V3_7::ICameraDevice::castFrom(device); ASSERT_TRUE(castResult.isOk()); @@ -8192,15 +8687,22 @@ void CameraHidlTest::castSession(const sp &session, int32_ sp *session3_4 /*out*/, sp *session3_5 /*out*/, sp *session3_6 /*out*/, - sp *session3_7 /*out*/) { + sp *session3_7 /*out*/, + sp *session3_8 /*out*/) { ASSERT_NE(nullptr, session3_3); ASSERT_NE(nullptr, session3_4); ASSERT_NE(nullptr, session3_5); ASSERT_NE(nullptr, session3_6); ASSERT_NE(nullptr, session3_7); + ASSERT_NE(nullptr, session3_8); switch (deviceVersion) { - case CAMERA_DEVICE_API_VERSION_3_8: + case CAMERA_DEVICE_API_VERSION_3_8: { + auto castResult = device::V3_8::ICameraDeviceSession::castFrom(session); + ASSERT_TRUE(castResult.isOk()); + *session3_8 = castResult; + } + [[fallthrough]]; case CAMERA_DEVICE_API_VERSION_3_7: { auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session); ASSERT_TRUE(castResult.isOk()); @@ -9077,8 +9579,9 @@ void CameraHidlTest::verifyBuffersReturned( sp session3_5; sp session3_6; sp session3_7; + sp session3_8; castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, - &session3_6, &session3_7); + &session3_6, &session3_7, &session3_8); ASSERT_NE(nullptr, session3_5.get()); hidl_vec streamIds(1); @@ -9320,7 +9823,7 @@ void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) { size_t CONFIG_ENTRY_TYPE_OFFSET = 3; size_t CONFIG_ENTRY_BITFIELD_OFFSET = 4; uint32_t maxPublicUsecase = - ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END; + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8; uint32_t vendorUsecaseStart = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START; uint32_t usecaseMask = (1 << vendorUsecaseStart) - 1; -- cgit v1.2.3 From 73cddd17b59b51e6affc550e7270da3bbd20609c Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Tue, 26 Oct 2021 14:00:00 -0700 Subject: audio: Add AIDL definitions for Playback/RecordTrackMetadata This is a temporary change for unblocking Bluetooth audio AIDL development. When Audio AIDL gets released officially, it should be overwritten. Bug: 198812639 Test: m android.hardware.audio.common Test: m check-vintf-all Change-Id: Ia63135da4af4682e471e7de6b191b19e7a326a1e Merged-In: I7064c3819d4c8e61981542ca2ccc52ca992a4ef8 --- audio/aidl/Android.bp | 54 ++++++++++++++++++++++ .../audio/common/PlaybackTrackMetadata.aidl | 41 ++++++++++++++++ .../hardware/audio/common/RecordTrackMetadata.aidl | 40 ++++++++++++++++ .../hardware/audio/common/SinkMetadata.aidl | 38 +++++++++++++++ .../hardware/audio/common/SourceMetadata.aidl | 38 +++++++++++++++ .../audio/common/PlaybackTrackMetadata.aidl | 44 ++++++++++++++++++ .../hardware/audio/common/RecordTrackMetadata.aidl | 42 +++++++++++++++++ .../hardware/audio/common/SinkMetadata.aidl | 28 +++++++++++ .../hardware/audio/common/SourceMetadata.aidl | 28 +++++++++++ compatibility_matrices/exclude/fcm_exclude.cpp | 1 + 10 files changed, 354 insertions(+) create mode 100644 audio/aidl/Android.bp create mode 100644 audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/PlaybackTrackMetadata.aidl create mode 100644 audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/RecordTrackMetadata.aidl create mode 100644 audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SinkMetadata.aidl create mode 100644 audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SourceMetadata.aidl create mode 100644 audio/aidl/android/hardware/audio/common/PlaybackTrackMetadata.aidl create mode 100644 audio/aidl/android/hardware/audio/common/RecordTrackMetadata.aidl create mode 100644 audio/aidl/android/hardware/audio/common/SinkMetadata.aidl create mode 100644 audio/aidl/android/hardware/audio/common/SourceMetadata.aidl diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp new file mode 100644 index 0000000000..c1726745cd --- /dev/null +++ b/audio/aidl/Android.bp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +aidl_interface { + name: "android.hardware.audio.common", + vendor_available: true, + srcs: [ + "android/hardware/audio/common/PlaybackTrackMetadata.aidl", + "android/hardware/audio/common/RecordTrackMetadata.aidl", + "android/hardware/audio/common/SinkMetadata.aidl", + "android/hardware/audio/common/SourceMetadata.aidl", + ], + imports: [ + "android.media.audio.common.types", + ], + stability: "vintf", + backend: { + cpp: { + enabled: true, + }, + java: { + platform_apis: true, + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, + versions: [ + ], +} diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/PlaybackTrackMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/PlaybackTrackMetadata.aidl new file mode 100644 index 0000000000..8fe869683b --- /dev/null +++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/PlaybackTrackMetadata.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.audio.common; +@JavaDerive(equals=true, toString=true) @VintfStability +parcelable PlaybackTrackMetadata { + android.media.audio.common.AudioUsage usage = android.media.audio.common.AudioUsage.INVALID; + android.media.audio.common.AudioContentType contentType = android.media.audio.common.AudioContentType.UNKNOWN; + float gain; + @utf8InCpp String[] tags; +} diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/RecordTrackMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/RecordTrackMetadata.aidl new file mode 100644 index 0000000000..50330ef8da --- /dev/null +++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/RecordTrackMetadata.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.audio.common; +@JavaDerive(equals=true, toString=true) @VintfStability +parcelable RecordTrackMetadata { + android.media.audio.common.AudioSource source = android.media.audio.common.AudioSource.SYS_RESERVED_INVALID; + float gain; + @utf8InCpp String[] tags; +} diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SinkMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SinkMetadata.aidl new file mode 100644 index 0000000000..270147d2bb --- /dev/null +++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SinkMetadata.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.audio.common; +@JavaDerive(equals=true, toString=true) @VintfStability +parcelable SinkMetadata { + android.hardware.audio.common.RecordTrackMetadata[] tracks; +} diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SourceMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SourceMetadata.aidl new file mode 100644 index 0000000000..2d4a982352 --- /dev/null +++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SourceMetadata.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.audio.common; +@JavaDerive(equals=true, toString=true) @VintfStability +parcelable SourceMetadata { + android.hardware.audio.common.PlaybackTrackMetadata[] tracks; +} diff --git a/audio/aidl/android/hardware/audio/common/PlaybackTrackMetadata.aidl b/audio/aidl/android/hardware/audio/common/PlaybackTrackMetadata.aidl new file mode 100644 index 0000000000..28a2f32fe6 --- /dev/null +++ b/audio/aidl/android/hardware/audio/common/PlaybackTrackMetadata.aidl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 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.audio.common; + +import android.media.audio.common.AudioContentType; +import android.media.audio.common.AudioUsage; + +/** + * Metadata of a playback track for an output stream. + */ +@JavaDerive(equals=true, toString=true) +@VintfStability +parcelable PlaybackTrackMetadata { + AudioUsage usage = AudioUsage.INVALID; + AudioContentType contentType = AudioContentType.UNKNOWN; + /** + * Non-negative linear gain (scaling) applied to track samples. + * 0 means muted, 1 is unity gain, 2 means double amplitude, etc. + */ + float gain; + /** + * Tags from AudioTrack audio attributes. Tag is an additional use case + * qualifier complementing AudioUsage and AudioContentType. Tags are set by + * vendor specific applications and must be prefixed by "VX_". Vendor must + * namespace their tag names to avoid conflicts, for example: + * "VX_GOOGLE_VR". At least 3 characters are required for the vendor + * namespace. + */ + @utf8InCpp String[] tags; +} diff --git a/audio/aidl/android/hardware/audio/common/RecordTrackMetadata.aidl b/audio/aidl/android/hardware/audio/common/RecordTrackMetadata.aidl new file mode 100644 index 0000000000..9a59b4175f --- /dev/null +++ b/audio/aidl/android/hardware/audio/common/RecordTrackMetadata.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2021 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.audio.common; + +import android.media.audio.common.AudioSource; + +/** + * Metadata of a record track for an input stream. + */ +@JavaDerive(equals=true, toString=true) +@VintfStability +parcelable RecordTrackMetadata { + AudioSource source = AudioSource.SYS_RESERVED_INVALID; + /** + * Non-negative linear gain (scaling) applied to track samples. + * 0 means muted, 1 is unity gain, 2 means double amplitude, etc. + */ + float gain; + /** + * Tags from AudioRecord audio attributes. Tag is an additional use case + * qualifier complementing AudioUsage and AudioContentType. Tags are set by + * vendor specific applications and must be prefixed by "VX_". Vendor must + * namespace their tag names to avoid conflicts, for example: + * "VX_GOOGLE_VR". At least 3 characters are required for the vendor + * namespace. + */ + @utf8InCpp String[] tags; +} diff --git a/audio/aidl/android/hardware/audio/common/SinkMetadata.aidl b/audio/aidl/android/hardware/audio/common/SinkMetadata.aidl new file mode 100644 index 0000000000..188c84700b --- /dev/null +++ b/audio/aidl/android/hardware/audio/common/SinkMetadata.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 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.audio.common; + +import android.hardware.audio.common.RecordTrackMetadata; + +/** + * Metadata of record tracks for an input stream. + */ +@JavaDerive(equals=true, toString=true) +@VintfStability +parcelable SinkMetadata { + RecordTrackMetadata[] tracks; +} diff --git a/audio/aidl/android/hardware/audio/common/SourceMetadata.aidl b/audio/aidl/android/hardware/audio/common/SourceMetadata.aidl new file mode 100644 index 0000000000..e9f23c6a9a --- /dev/null +++ b/audio/aidl/android/hardware/audio/common/SourceMetadata.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 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.audio.common; + +import android.hardware.audio.common.PlaybackTrackMetadata; + +/** + * Metadata of playback tracks for an output stream. + */ +@JavaDerive(equals=true, toString=true) +@VintfStability +parcelable SourceMetadata { + PlaybackTrackMetadata[] tracks; +} diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp index d8c9170000..f34009d329 100644 --- a/compatibility_matrices/exclude/fcm_exclude.cpp +++ b/compatibility_matrices/exclude/fcm_exclude.cpp @@ -51,6 +51,7 @@ bool ShouldCheckMissingHalsInFcm(const std::string& package) { "android.hardware.media.bufferpool@2.0", "android.hardware.radio.config@1.2", // AIDL + "android.hardware.audio.common", "android.hardware.biometrics.common", "android.hardware.common", "android.hardware.common.fmq", -- cgit v1.2.3 From a4dbaffaecd9f45a0c00919ed844ce2471361a3b Mon Sep 17 00:00:00 2001 From: Alice Kuo Date: Mon, 18 Oct 2021 03:35:59 +0800 Subject: Add new aidl interface for android.hardware.bluetooth.audio Bug: 203490261 Test: m android.hardware.bluetooth.audio-update-api Change-Id: Ida6d664b2c3eedfb4c3abaece7c3540623c72270 Merged-In: Ida6d664b2c3eedfb4c3abaece7c3540623c72270 --- bluetooth/audio/aidl/Android.bp | 39 +++++++++++ .../hardware/bluetooth/audio/AacCapabilities.aidl | 42 ++++++++++++ .../hardware/bluetooth/audio/AacConfiguration.aidl | 42 ++++++++++++ .../hardware/bluetooth/audio/AacObjectType.aidl | 41 ++++++++++++ .../hardware/bluetooth/audio/AptxCapabilities.aidl | 40 ++++++++++++ .../bluetooth/audio/AptxConfiguration.aidl | 40 ++++++++++++ .../bluetooth/audio/AudioCapabilities.aidl | 40 ++++++++++++ .../bluetooth/audio/AudioConfiguration.aidl | 40 ++++++++++++ .../hardware/bluetooth/audio/AudioLocation.aidl | 40 ++++++++++++ .../bluetooth/audio/BluetoothAudioStatus.aidl | 41 ++++++++++++ .../bluetooth/audio/BroadcastConfiguration.aidl | 44 +++++++++++++ .../hardware/bluetooth/audio/ChannelMode.aidl | 40 ++++++++++++ .../bluetooth/audio/CodecCapabilities.aidl | 46 +++++++++++++ .../bluetooth/audio/CodecConfiguration.aidl | 49 ++++++++++++++ .../hardware/bluetooth/audio/CodecType.aidl | 44 +++++++++++++ .../bluetooth/audio/IBluetoothAudioPort.aidl | 42 ++++++++++++ .../bluetooth/audio/IBluetoothAudioProvider.aidl | 41 ++++++++++++ .../audio/IBluetoothAudioProviderFactory.aidl | 39 +++++++++++ .../hardware/bluetooth/audio/Lc3Capabilities.aidl | 42 ++++++++++++ .../hardware/bluetooth/audio/Lc3Configuration.aidl | 42 ++++++++++++ .../hardware/bluetooth/audio/LdacCapabilities.aidl | 41 ++++++++++++ .../hardware/bluetooth/audio/LdacChannelMode.aidl | 41 ++++++++++++ .../bluetooth/audio/LdacConfiguration.aidl | 41 ++++++++++++ .../hardware/bluetooth/audio/LdacQualityIndex.aidl | 41 ++++++++++++ .../bluetooth/audio/LeAudioCapabilities.aidl | 51 +++++++++++++++ .../bluetooth/audio/LeAudioCodecConfiguration.aidl | 43 +++++++++++++ .../bluetooth/audio/LeAudioConfiguration.aidl | 45 +++++++++++++ .../hardware/bluetooth/audio/LeAudioMode.aidl | 40 ++++++++++++ .../hardware/bluetooth/audio/PcmCapabilities.aidl | 41 ++++++++++++ .../hardware/bluetooth/audio/PcmConfiguration.aidl | 41 ++++++++++++ .../bluetooth/audio/PresentationPosition.aidl | 45 +++++++++++++ .../hardware/bluetooth/audio/SbcAllocMethod.aidl | 39 +++++++++++ .../hardware/bluetooth/audio/SbcCapabilities.aidl | 45 +++++++++++++ .../hardware/bluetooth/audio/SbcChannelMode.aidl | 42 ++++++++++++ .../hardware/bluetooth/audio/SbcConfiguration.aidl | 45 +++++++++++++ .../hardware/bluetooth/audio/SessionType.aidl | 45 +++++++++++++ .../bluetooth/audio/UnicastConfiguration.aidl | 45 +++++++++++++ .../hardware/bluetooth/audio/AacCapabilities.aidl | 34 ++++++++++ .../hardware/bluetooth/audio/AacConfiguration.aidl | 32 +++++++++ .../hardware/bluetooth/audio/AacObjectType.aidl | 38 +++++++++++ .../hardware/bluetooth/audio/AptxCapabilities.aidl | 30 +++++++++ .../bluetooth/audio/AptxConfiguration.aidl | 29 +++++++++ .../bluetooth/audio/AudioCapabilities.aidl | 31 +++++++++ .../bluetooth/audio/AudioConfiguration.aidl | 31 +++++++++ .../hardware/bluetooth/audio/AudioLocation.aidl | 25 ++++++++ .../bluetooth/audio/BluetoothAudioStatus.aidl | 27 ++++++++ .../bluetooth/audio/BroadcastConfiguration.aidl | 39 +++++++++++ .../hardware/bluetooth/audio/ChannelMode.aidl | 25 ++++++++ .../bluetooth/audio/CodecCapabilities.aidl | 40 ++++++++++++ .../bluetooth/audio/CodecConfiguration.aidl | 57 ++++++++++++++++ .../hardware/bluetooth/audio/CodecType.aidl | 29 +++++++++ .../bluetooth/audio/IBluetoothAudioPort.aidl | 73 +++++++++++++++++++++ .../bluetooth/audio/IBluetoothAudioProvider.aidl | 75 ++++++++++++++++++++++ .../audio/IBluetoothAudioProviderFactory.aidl | 65 +++++++++++++++++++ .../hardware/bluetooth/audio/Lc3Capabilities.aidl | 44 +++++++++++++ .../hardware/bluetooth/audio/Lc3Configuration.aidl | 44 +++++++++++++ .../hardware/bluetooth/audio/LdacCapabilities.aidl | 34 ++++++++++ .../hardware/bluetooth/audio/LdacChannelMode.aidl | 29 +++++++++ .../bluetooth/audio/LdacConfiguration.aidl | 32 +++++++++ .../hardware/bluetooth/audio/LdacQualityIndex.aidl | 38 +++++++++++ .../bluetooth/audio/LeAudioCapabilities.aidl | 47 ++++++++++++++ .../bluetooth/audio/LeAudioCodecConfiguration.aidl | 29 +++++++++ .../bluetooth/audio/LeAudioConfiguration.aidl | 37 +++++++++++ .../hardware/bluetooth/audio/LeAudioMode.aidl | 25 ++++++++ .../hardware/bluetooth/audio/PcmCapabilities.aidl | 33 ++++++++++ .../hardware/bluetooth/audio/PcmConfiguration.aidl | 33 ++++++++++ .../bluetooth/audio/PresentationPosition.aidl | 52 +++++++++++++++ .../hardware/bluetooth/audio/SbcAllocMethod.aidl | 30 +++++++++ .../hardware/bluetooth/audio/SbcCapabilities.aidl | 43 +++++++++++++ .../hardware/bluetooth/audio/SbcChannelMode.aidl | 27 ++++++++ .../hardware/bluetooth/audio/SbcConfiguration.aidl | 41 ++++++++++++ .../hardware/bluetooth/audio/SessionType.aidl | 51 +++++++++++++++ .../bluetooth/audio/UnicastConfiguration.aidl | 41 ++++++++++++ .../compatibility_matrix.current.xml | 7 ++ 74 files changed, 2962 insertions(+) create mode 100644 bluetooth/audio/aidl/Android.bp create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp new file mode 100644 index 0000000000..60da877af2 --- /dev/null +++ b/bluetooth/audio/aidl/Android.bp @@ -0,0 +1,39 @@ +// Copyright (C) 2021 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. + +aidl_interface { + name: "android.hardware.bluetooth.audio", + vendor_available: true, + srcs: ["android/hardware/bluetooth/audio/*.aidl"], + stability: "vintf", + imports: [ + "android.hardware.common-V2", + "android.hardware.common.fmq-V1", + "android.hardware.audio.common", + ], + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + enabled: false, + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl new file mode 100644 index 0000000000..ad44c26f59 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl @@ -0,0 +1,42 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable AacCapabilities { + android.hardware.bluetooth.audio.AacObjectType objectType; + int[] sampleRateHz; + android.hardware.bluetooth.audio.ChannelMode channelMode; + boolean variableBitRateSupported; + byte[] bitsPerSample; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl new file mode 100644 index 0000000000..6adef6df16 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl @@ -0,0 +1,42 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable AacConfiguration { + android.hardware.bluetooth.audio.AacObjectType objectType; + int sampleRateHz; + android.hardware.bluetooth.audio.ChannelMode channelMode; + boolean variableBitRateEnabled; + byte bitsPerSample; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl new file mode 100644 index 0000000000..c129c66b40 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="byte") @VintfStability +enum AacObjectType { + MPEG2_LC = 1, + MPEG4_LC = 2, + MPEG4_LTP = 4, + MPEG4_SCALABLE = 8, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl new file mode 100644 index 0000000000..4767b696ec --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable AptxCapabilities { + int[] sampleRateHz; + android.hardware.bluetooth.audio.ChannelMode channelMode; + byte[] bitsPerSample; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl new file mode 100644 index 0000000000..91e88b32f3 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable AptxConfiguration { + int sampleRateHz; + android.hardware.bluetooth.audio.ChannelMode channelMode; + byte bitsPerSample; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl new file mode 100644 index 0000000000..20a7731010 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +union AudioCapabilities { + android.hardware.bluetooth.audio.PcmCapabilities pcmCapabilities; + android.hardware.bluetooth.audio.CodecCapabilities codecCapabilities; + android.hardware.bluetooth.audio.LeAudioCapabilities leAudioCapabilities; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl new file mode 100644 index 0000000000..34f7837967 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +union AudioConfiguration { + android.hardware.bluetooth.audio.PcmConfiguration pcmConfig; + android.hardware.bluetooth.audio.CodecConfiguration codecConfig; + android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl new file mode 100644 index 0000000000..319a5e2ad0 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="int") @VintfStability +enum AudioLocation { + UNKNOWN = 1, + FRONT_LEFT = 2, + FRONT_RIGHT = 4, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl new file mode 100644 index 0000000000..7c0d82588c --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="int") @VintfStability +enum BluetoothAudioStatus { + UNKNOWN = 0, + SUCCESS = 1, + UNSUPPORTED_CODEC_CONFIGURATION = 2, + FAILURE = 3, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl new file mode 100644 index 0000000000..b3aa709ddd --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl @@ -0,0 +1,44 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable BroadcastConfiguration { + android.hardware.bluetooth.audio.BroadcastConfiguration.BroadcastStreamMap[] streamMap; + @VintfStability + parcelable BroadcastStreamMap { + char streamHandle; + int audioChannelAllocation; + android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCondecConfig; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl new file mode 100644 index 0000000000..3ca93c3e03 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="byte") @VintfStability +enum ChannelMode { + UNKNOWN = 1, + MONO = 2, + STEREO = 4, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl new file mode 100644 index 0000000000..b451880e05 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl @@ -0,0 +1,46 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable CodecCapabilities { + android.hardware.bluetooth.audio.CodecType codecType; + android.hardware.bluetooth.audio.CodecCapabilities.Capabilities capabilities; + @VintfStability + union Capabilities { + android.hardware.bluetooth.audio.SbcCapabilities sbcCapabilities; + android.hardware.bluetooth.audio.AacCapabilities aacCapabilities; + android.hardware.bluetooth.audio.LdacCapabilities ldacCapabilities; + android.hardware.bluetooth.audio.AptxCapabilities aptxCapabilities; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl new file mode 100644 index 0000000000..863aee244c --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl @@ -0,0 +1,49 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable CodecConfiguration { + android.hardware.bluetooth.audio.CodecType codecType; + int encodedAudioBitrate; + int peerMtu; + boolean isScmstEnabled; + android.hardware.bluetooth.audio.CodecConfiguration.CodecSpecific config; + @VintfStability + union CodecSpecific { + android.hardware.bluetooth.audio.SbcConfiguration sbcConfig; + android.hardware.bluetooth.audio.AacConfiguration aacConfig; + android.hardware.bluetooth.audio.LdacConfiguration ldacConfig; + android.hardware.bluetooth.audio.AptxConfiguration aptxConfig; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl new file mode 100644 index 0000000000..44b434bbd7 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl @@ -0,0 +1,44 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="int") @VintfStability +enum CodecType { + UNKNOWN = 0, + SBC = 1, + AAC = 2, + APTX = 3, + APTX_HD = 4, + LDAC = 5, + LC3 = 6, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl new file mode 100644 index 0000000000..e389ef3876 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl @@ -0,0 +1,42 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +interface IBluetoothAudioPort { + android.hardware.bluetooth.audio.PresentationPosition getPresentationPosition(); + void startStream(); + void stopStream(); + void suspendStream(); + void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata); +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl new file mode 100644 index 0000000000..e5e79cb1c4 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +interface IBluetoothAudioProvider { + void endSession(); + android.hardware.common.fmq.MQDescriptor startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig); + void streamStarted(in android.hardware.bluetooth.audio.BluetoothAudioStatus status); + void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status); +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl new file mode 100644 index 0000000000..5e33deb856 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl @@ -0,0 +1,39 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +interface IBluetoothAudioProviderFactory { + android.hardware.bluetooth.audio.AudioCapabilities[] getProviderCapabilities(in android.hardware.bluetooth.audio.SessionType sessionType); + android.hardware.bluetooth.audio.IBluetoothAudioProvider openProvider(in android.hardware.bluetooth.audio.SessionType sessionType); +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl new file mode 100644 index 0000000000..3c650da4f7 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl @@ -0,0 +1,42 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable Lc3Capabilities { + byte[] pcmBitDepth; + int[] samplingFrequencyHz; + int[] frameDurationUs; + int[] octetsPerFrame; + byte[] blocksPerSdu; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl new file mode 100644 index 0000000000..ef77da7023 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl @@ -0,0 +1,42 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable Lc3Configuration { + byte pcmBitDepth; + int samplingFrequencyHz; + int frameDurationUs; + int octetsPerFrame; + byte blocksPerSdu; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl new file mode 100644 index 0000000000..19e041a15c --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable LdacCapabilities { + int[] sampleRateHz; + android.hardware.bluetooth.audio.LdacChannelMode channelMode; + android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex; + byte[] bitsPerSample; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl new file mode 100644 index 0000000000..a9d6c5e14e --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="byte") @VintfStability +enum LdacChannelMode { + UNKNOWN = 1, + STEREO = 2, + DUAL = 4, + MONO = 8, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl new file mode 100644 index 0000000000..8a3763800b --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable LdacConfiguration { + int sampleRateHz; + android.hardware.bluetooth.audio.LdacChannelMode channelMode; + android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex; + byte bitsPerSample; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl new file mode 100644 index 0000000000..693392fe51 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="byte") @VintfStability +enum LdacQualityIndex { + HIGH = 1, + MID = 2, + LOW = 4, + ABR = 8, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl new file mode 100644 index 0000000000..a7224ca5da --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl @@ -0,0 +1,51 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable LeAudioCapabilities { + android.hardware.bluetooth.audio.LeAudioMode mode; + android.hardware.bluetooth.audio.CodecType codecType; + android.hardware.bluetooth.audio.AudioLocation supportedChannel; + int supportedChannelCount; + android.hardware.bluetooth.audio.LeAudioCapabilities.LeAudioCodecCapabilities leAudioCodecCapabilities; + @VintfStability + parcelable VendorCapabilities { + ParcelableHolder extension; + } + @VintfStability + union LeAudioCodecCapabilities { + android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities; + android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl new file mode 100644 index 0000000000..bb3d7e4b1e --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl @@ -0,0 +1,43 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +union LeAudioCodecConfiguration { + android.hardware.bluetooth.audio.Lc3Configuration lc3Config; + android.hardware.bluetooth.audio.LeAudioCodecConfiguration.VendorConfiguration vendorConfig; + @VintfStability + parcelable VendorConfiguration { + ParcelableHolder extension; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl new file mode 100644 index 0000000000..2bc179163f --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl @@ -0,0 +1,45 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable LeAudioConfiguration { + android.hardware.bluetooth.audio.LeAudioMode mode; + android.hardware.bluetooth.audio.LeAudioConfiguration.LeAudioModeConfig modeConfig; + android.hardware.bluetooth.audio.CodecType codecType; + @VintfStability + union LeAudioModeConfig { + android.hardware.bluetooth.audio.UnicastConfiguration unicastConfig; + android.hardware.bluetooth.audio.BroadcastConfiguration broadcastConfig; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl new file mode 100644 index 0000000000..766f6376c6 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="byte") @VintfStability +enum LeAudioMode { + UNKNOWN = 0, + UNICAST = 1, + BROADCAST = 2, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl new file mode 100644 index 0000000000..6cfe5cd78c --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable PcmCapabilities { + int[] sampleRateHz; + android.hardware.bluetooth.audio.ChannelMode channelMode; + byte[] bitsPerSample; + int[] dataIntervalUs; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl new file mode 100644 index 0000000000..93d7805a33 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable PcmConfiguration { + int sampleRateHz; + android.hardware.bluetooth.audio.ChannelMode channelMode; + byte bitsPerSample; + int dataIntervalUs; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl new file mode 100644 index 0000000000..7e997e8c8f --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable PresentationPosition { + long remoteDeviceAudioDelayNanos; + long transmittedOctets; + android.hardware.bluetooth.audio.PresentationPosition.TimeSpec transmittedOctetsTimestamp; + @VintfStability + parcelable TimeSpec { + long tvSec; + long tvNSec; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl new file mode 100644 index 0000000000..5170f164a3 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl @@ -0,0 +1,39 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="byte") @VintfStability +enum SbcAllocMethod { + ALLOC_MD_S = 1, + ALLOC_MD_L = 2, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl new file mode 100644 index 0000000000..ec3aa0f262 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl @@ -0,0 +1,45 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable SbcCapabilities { + int[] sampleRateHz; + android.hardware.bluetooth.audio.SbcChannelMode channelMode; + byte[] blockLength; + byte[] numSubbands; + android.hardware.bluetooth.audio.SbcAllocMethod allocMethod; + byte[] bitsPerSample; + int minBitpool; + int maxBitpool; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl new file mode 100644 index 0000000000..88fca4aac4 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl @@ -0,0 +1,42 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="byte") @VintfStability +enum SbcChannelMode { + UNKNOWN = 1, + JOINT_STEREO = 2, + STEREO = 4, + DUAL = 8, + MONO = 16, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl new file mode 100644 index 0000000000..8eab9c3d96 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl @@ -0,0 +1,45 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable SbcConfiguration { + int sampleRateHz; + android.hardware.bluetooth.audio.SbcChannelMode channelMode; + byte blockLength; + byte numSubbands; + android.hardware.bluetooth.audio.SbcAllocMethod allocMethod; + byte bitsPerSample; + int minBitpool; + int maxBitpool; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl new file mode 100644 index 0000000000..72d7fb247a --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl @@ -0,0 +1,45 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="byte") @VintfStability +enum SessionType { + UNKNOWN = 0, + A2DP_SOFTWARE_ENCODING_DATAPATH = 1, + A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 2, + HEARING_AID_SOFTWARE_ENCODING_DATAPATH = 3, + LE_AUDIO_SOFTWARE_ENCODING_DATAPATH = 4, + LE_AUDIO_SOFTWARE_DECODING_DATAPATH = 5, + LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 6, + LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH = 7, +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl new file mode 100644 index 0000000000..b385763fa6 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl @@ -0,0 +1,45 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable UnicastConfiguration { + android.hardware.bluetooth.audio.UnicastConfiguration.UnicastStreamMap[] streamMap; + int peerDelay; + android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig; + @VintfStability + parcelable UnicastStreamMap { + char streamHandle; + int audioChannelAllocation; + } +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl new file mode 100644 index 0000000000..43038836aa --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl @@ -0,0 +1,34 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.AacObjectType; +import android.hardware.bluetooth.audio.ChannelMode; + +/** + * Used for Hardware Encoding AAC codec capabilities + */ +@VintfStability +parcelable AacCapabilities { + /* bitfield */ + AacObjectType objectType; + int[] sampleRateHz; + /* bitfield */ + ChannelMode channelMode; + boolean variableBitRateSupported; + byte[] bitsPerSample; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl new file mode 100644 index 0000000000..30338e76d0 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl @@ -0,0 +1,32 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.AacObjectType; +import android.hardware.bluetooth.audio.ChannelMode; + +/** + * Used for Hardware Encoding AAC codec configuration + */ +@VintfStability +parcelable AacConfiguration { + AacObjectType objectType; + int sampleRateHz; + ChannelMode channelMode; + boolean variableBitRateEnabled; + byte bitsPerSample; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl new file mode 100644 index 0000000000..480e422e1c --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="byte") +enum AacObjectType { + /** + * MPEG-2 Low Complexity. Support is Mandatory. + */ + MPEG2_LC = 1, + /** + * MPEG-4 Low Complexity. Support is Optional. + */ + MPEG4_LC = 1 << 1, + /** + * MPEG-4 Long Term Prediction. Support is Optional. + */ + MPEG4_LTP = 1 << 2, + /** + * MPEG-4 Scalable. Support is Optional. + */ + MPEG4_SCALABLE = 1 << 3, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl new file mode 100644 index 0000000000..6a37fc6a41 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl @@ -0,0 +1,30 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.ChannelMode; + +/** + * Used for Hardware Encoding AptX and AptX-HD codec capabilities + */ +@VintfStability +parcelable AptxCapabilities { + int[] sampleRateHz; + /* bitfield */ + ChannelMode channelMode; + byte[] bitsPerSample; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl new file mode 100644 index 0000000000..83b7b0cc09 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl @@ -0,0 +1,29 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.ChannelMode; + +/** + * Used for Hardware Encoding AptX and AptX-HD codec configuration + */ +@VintfStability +parcelable AptxConfiguration { + int sampleRateHz; + ChannelMode channelMode; + byte bitsPerSample; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl new file mode 100644 index 0000000000..6ed44722cc --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl @@ -0,0 +1,31 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.CodecCapabilities; +import android.hardware.bluetooth.audio.LeAudioCapabilities; +import android.hardware.bluetooth.audio.PcmCapabilities; + +/** + * Used to specify the capabilities of the different session types + */ +@VintfStability +union AudioCapabilities { + PcmCapabilities pcmCapabilities; + CodecCapabilities codecCapabilities; + LeAudioCapabilities leAudioCapabilities; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl new file mode 100644 index 0000000000..ce515b5611 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl @@ -0,0 +1,31 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.CodecConfiguration; +import android.hardware.bluetooth.audio.LeAudioConfiguration; +import android.hardware.bluetooth.audio.PcmConfiguration; + +/** + * Used to configure either a Hardware or Software Encoding session based on session type + */ +@VintfStability +union AudioConfiguration { + PcmConfiguration pcmConfig; + CodecConfiguration codecConfig; + LeAudioConfiguration leAudioConfig; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl new file mode 100644 index 0000000000..dedfbf98a6 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl @@ -0,0 +1,25 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="int") +enum AudioLocation { + UNKNOWN = 1, + FRONT_LEFT = 1 << 1, + FRONT_RIGHT = 1 << 2, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl new file mode 100644 index 0000000000..ec78445e6e --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl @@ -0,0 +1,27 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="int") +enum BluetoothAudioStatus { + UNKNOWN = 0, + SUCCESS = 1, + UNSUPPORTED_CODEC_CONFIGURATION = 2, + // General failure + FAILURE = 3 +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl new file mode 100644 index 0000000000..07d05f1bd7 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl @@ -0,0 +1,39 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.LeAudioCodecConfiguration; + +@VintfStability +parcelable BroadcastConfiguration { + @VintfStability + parcelable BroadcastStreamMap { + /* + * The connection handle used for a unicast or a broadcast group. + * Range: 0x0000 to 0xEFFF + */ + char streamHandle; + /* + * Audio channel allocation is a bit field, each enabled bit means that given audio + * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the + * least significant bit to the most significant bit. + */ + int audioChannelAllocation; + LeAudioCodecConfiguration leAudioCondecConfig; + } + BroadcastStreamMap[] streamMap; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl new file mode 100644 index 0000000000..2df879d837 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl @@ -0,0 +1,25 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="byte") +enum ChannelMode { + UNKNOWN = 1, + MONO = 1 << 1, + STEREO = 1 << 2, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl new file mode 100644 index 0000000000..0eee8cb55b --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.AacCapabilities; +import android.hardware.bluetooth.audio.AptxCapabilities; +import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.LdacCapabilities; +import android.hardware.bluetooth.audio.SbcCapabilities; + +/** + * Used to specify the capabilities of the codecs supported by Hardware Encoding. + * AptX and AptX-HD both use the AptxCapabilities field. + */ +@VintfStability +parcelable CodecCapabilities { + @VintfStability + union Capabilities { + SbcCapabilities sbcCapabilities; + AacCapabilities aacCapabilities; + LdacCapabilities ldacCapabilities; + AptxCapabilities aptxCapabilities; + } + CodecType codecType; + Capabilities capabilities; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl new file mode 100644 index 0000000000..fac90f065d --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl @@ -0,0 +1,57 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.AacConfiguration; +import android.hardware.bluetooth.audio.AptxConfiguration; +import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.LdacConfiguration; +import android.hardware.bluetooth.audio.SbcConfiguration; + +/** + * Used to configure a Hardware Encoding session. + * AptX and AptX-HD both use the AptxConfiguration field. + */ +@VintfStability +parcelable CodecConfiguration { + @VintfStability + union CodecSpecific { + SbcConfiguration sbcConfig; + AacConfiguration aacConfig; + LdacConfiguration ldacConfig; + AptxConfiguration aptxConfig; + } + CodecType codecType; + /** + * The encoded audio bitrate in bits / second. + * 0x00000000 - The audio bitrate is not specified / unused + * 0x00000001 - 0x00FFFFFF - Encoded audio bitrate in bits/second + * 0x01000000 - 0xFFFFFFFF - Reserved + * + * The HAL needs to support all legal bitrates for the selected codec. + */ + int encodedAudioBitrate; + /** + * Peer MTU (in two-octets) + */ + int peerMtu; + /** + * Content protection by SCMS-T + */ + boolean isScmstEnabled; + CodecSpecific config; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl new file mode 100644 index 0000000000..68c60f548e --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl @@ -0,0 +1,29 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="int") +enum CodecType { + UNKNOWN, + SBC, + AAC, + APTX, + APTX_HD, + LDAC, + LC3, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl new file mode 100644 index 0000000000..50e3197c48 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl @@ -0,0 +1,73 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.audio.common.SourceMetadata; +import android.hardware.bluetooth.audio.PresentationPosition; + +/** + * HAL interface from the Audio HAL to the Bluetooth stack + * + * The Audio HAL calls methods in this interface to start, suspend, and stop + * an audio stream. These calls return immediately and the results, if any, + * are sent over the IBluetoothAudioProvider interface. + * + * Moreover, the Audio HAL can also get the presentation position of the stream + * and provide stream metadata. + * + */ +@VintfStability +interface IBluetoothAudioPort { + /** + * Get the audio presentation position. + * + * @return the audio presentation position + * + */ + PresentationPosition getPresentationPosition(); + + /** + * This indicates that the caller of this method has opened the data path + * and wants to start an audio stream. The caller must wait for a + * IBluetoothAudioProvider.streamStarted(Status) call. + */ + void startStream(); + + /** + * This indicates that the caller of this method wants to stop the audio + * stream. The data path will be closed after this call. There is no + * callback from the IBluetoothAudioProvider interface even though the + * teardown is asynchronous. + */ + void stopStream(); + + /** + * This indicates that the caller of this method wants to suspend the audio + * stream. The caller must wait for the Bluetooth process to call + * IBluetoothAudioProvider.streamSuspended(Status). The caller still keeps + * the data path open. + */ + void suspendStream(); + + /** + * Called when the metadata of the stream's source has been changed. + * + * @param sourceMetadata Description of the audio that is played by the + * clients. + */ + void updateMetadata(in SourceMetadata sourceMetadata); +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl new file mode 100644 index 0000000000..a2c5ae9a76 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -0,0 +1,75 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.AudioConfiguration; +import android.hardware.bluetooth.audio.BluetoothAudioStatus; +import android.hardware.bluetooth.audio.IBluetoothAudioPort; +import android.hardware.common.fmq.MQDescriptor; +import android.hardware.common.fmq.SynchronizedReadWrite; + +/** + * HAL interface from the Bluetooth stack to the Audio HAL + * + * The Bluetooth stack calls methods in this interface to start and end audio + * sessions and sends callback events to the Audio HAL. + * + */ +@VintfStability +interface IBluetoothAudioProvider { + /** + * Ends the current session and unregisters the IBluetoothAudioPort + * interface. + */ + void endSession(); + + /** + * This method indicates that the Bluetooth stack is ready to stream audio. + * It registers an instance of IBluetoothAudioPort with and provides the + * current negotiated codec to the Audio HAL. After this method is called, + * the Audio HAL can invoke IBluetoothAudioPort.startStream(). + * + * Note: endSession() must be called to unregister this IBluetoothAudioPort + * + * @param hostIf An instance of IBluetoothAudioPort for stream control + * @param audioConfig The audio configuration negotiated with the remote + * device. The PCM parameters are set if software based encoding, + * otherwise the correct codec configuration is used for hardware + * encoding. + * + * @return The fast message queue for audio data from/to this + * provider. Audio data will be in PCM format as specified by the + * audioConfig.pcmConfig parameter. Invalid if streaming is offloaded + * from/to hardware or on failure + */ + MQDescriptor startSession( + in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig); + + /** + * Callback for IBluetoothAudioPort.startStream() + * + * @param status true for SUCCESS or false for FAILURE + */ + void streamStarted(in BluetoothAudioStatus status); + + /** + * Callback for IBluetoothAudioPort.suspendStream() + * + * @param status true for SUCCESS or false for FAILURE + */ + void streamSuspended(in BluetoothAudioStatus status); +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl new file mode 100644 index 0000000000..3cde22ca2c --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl @@ -0,0 +1,65 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.AudioCapabilities; +import android.hardware.bluetooth.audio.IBluetoothAudioProvider; +import android.hardware.bluetooth.audio.SessionType; +/** + * This factory allows a HAL implementation to be split into multiple + * independent providers. + * + * When the Bluetooth stack is ready to create an audio session, it must first + * obtain the IBluetoothAudioProvider for that session type by calling + * openProvider(). + * + */ + +@VintfStability +interface IBluetoothAudioProviderFactory { + /** + * Gets a list of audio capabilities for a session type. + * + * For software encoding, the PCM capabilities are returned. + * For hardware encoding, the supported codecs and their capabilities are + * returned. + * + * @param sessionType The session type (e.g. + * A2DP_SOFTWARE_ENCODING_DATAPATH). + * @return A list containing all the capabilities + * supported by the sesson type. The capabilities is a list of + * available options when configuring the codec for the session. + * For software encoding it is the PCM data rate. + * For hardware encoding it is the list of supported codecs and their + * capabilities. + * If a provider isn't supported, an empty list should be returned. + * Note: Only one entry should exist per codec when using hardware + * encoding. + */ + AudioCapabilities[] getProviderCapabilities(in SessionType sessionType); + + /** + * Opens an audio provider for a session type. To close the provider, it is + * necessary to release references to the returned provider object. + * + * @param sessionType The session type (e.g. + * LE_AUDIO_SOFTWARE_ENCODING_DATAPATH). + * + * @return provider The provider of the specified session type + */ + IBluetoothAudioProvider openProvider(in SessionType sessionType); +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl new file mode 100644 index 0000000000..1aedefd2d5 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl @@ -0,0 +1,44 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +/** + * Used for Hardware Encoding/Decoding LC3 codec capabilities. + */ +@VintfStability +parcelable Lc3Capabilities { + /* + * PCM is Input for encoder, Output for decoder + */ + byte[] pcmBitDepth; + /* + * codec-specific parameters + */ + int[] samplingFrequencyHz; + /* + * FrameDuration based on microseconds. + */ + int[] frameDurationUs; + /* + * length in octets of a codec frame + */ + int[] octetsPerFrame; + /* + * Number of blocks of codec frames per single SDU (Service Data Unit) + */ + byte[] blocksPerSdu; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl new file mode 100644 index 0000000000..77c04c1b6e --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl @@ -0,0 +1,44 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +/** + * Used for Hardware Encoding/Decoding LC3 codec configuration. + */ +@VintfStability +parcelable Lc3Configuration { + /* + * PCM is Input for encoder, Output for decoder + */ + byte pcmBitDepth; + /* + * codec-specific parameters + */ + int samplingFrequencyHz; + /* + * FrameDuration based on microseconds. + */ + int frameDurationUs; + /* + * length in octets of a codec frame + */ + int octetsPerFrame; + /* + * Number of blocks of codec frames per single SDU (Service Data Unit) + */ + byte blocksPerSdu; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl new file mode 100644 index 0000000000..44cca7e071 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl @@ -0,0 +1,34 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.LdacChannelMode; +import android.hardware.bluetooth.audio.LdacQualityIndex; + +/** + * Used for Hardware Encoding LDAC codec capabilities + * all qualities must be supported. + */ +@VintfStability +parcelable LdacCapabilities { + int[] sampleRateHz; + /* bitfiled */ + LdacChannelMode channelMode; + /* bitfiled */ + LdacQualityIndex qualityIndex; + byte[] bitsPerSample; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl new file mode 100644 index 0000000000..3acca32fc2 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl @@ -0,0 +1,29 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +/** + * Channel Mode: 3 bits + */ +@VintfStability +@Backing(type="byte") +enum LdacChannelMode { + UNKNOWN = 1, + STEREO = 1 << 1, + DUAL = 1 << 2, + MONO = 1 << 3, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl new file mode 100644 index 0000000000..cc03dd0fc1 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl @@ -0,0 +1,32 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.LdacChannelMode; +import android.hardware.bluetooth.audio.LdacQualityIndex; + +/** + * Used for Hardware Encoding LDAC codec configuration + * Only used when configuring the codec. + */ +@VintfStability +parcelable LdacConfiguration { + int sampleRateHz; + LdacChannelMode channelMode; + LdacQualityIndex qualityIndex; + byte bitsPerSample; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl new file mode 100644 index 0000000000..cb125839ef --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl @@ -0,0 +1,38 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="byte") +enum LdacQualityIndex { + /** + * 990kbps + */ + HIGH = 1, + /** + * 660kbps + */ + MID = 1 << 1, + /** + * 330kbps + */ + LOW = 1 << 2, + /** + * Adaptive Bit Rate mode + */ + ABR = 1 << 3, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl new file mode 100644 index 0000000000..732427f060 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl @@ -0,0 +1,47 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.AudioLocation; +import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.Lc3Capabilities; +import android.hardware.bluetooth.audio.LeAudioMode; + +/** + * Used to specify the capabilities of the LC3 codecs supported by Hardware Encoding. + */ +@VintfStability +parcelable LeAudioCapabilities { + @VintfStability + parcelable VendorCapabilities { + ParcelableHolder extension; + } + @VintfStability + union LeAudioCodecCapabilities { + Lc3Capabilities lc3Capabilities; + VendorCapabilities vendorCapabillities; + } + LeAudioMode mode; + CodecType codecType; + /* + * This is bitfield, if bit N is set, HW Offloader supports N+1 channels at the same time. + * Example: 0x27 = 0b00100111: One, two, three or six channels supported. + */ + AudioLocation supportedChannel; + int supportedChannelCount; + LeAudioCodecCapabilities leAudioCodecCapabilities; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl new file mode 100644 index 0000000000..421eeb27f2 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl @@ -0,0 +1,29 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.Lc3Configuration; + +@VintfStability +union LeAudioCodecConfiguration { + @VintfStability + parcelable VendorConfiguration { + ParcelableHolder extension; + } + Lc3Configuration lc3Config; + VendorConfiguration vendorConfig; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl new file mode 100644 index 0000000000..515794b247 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl @@ -0,0 +1,37 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.BroadcastConfiguration; +import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.LeAudioMode; +import android.hardware.bluetooth.audio.UnicastConfiguration; + +@VintfStability +parcelable LeAudioConfiguration { + @VintfStability + union LeAudioModeConfig { + UnicastConfiguration unicastConfig; + BroadcastConfiguration broadcastConfig; + } + /* + * The mode of the LE audio + */ + LeAudioMode mode; + LeAudioModeConfig modeConfig; + CodecType codecType; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl new file mode 100644 index 0000000000..2cf019e9ad --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl @@ -0,0 +1,25 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="byte") +enum LeAudioMode { + UNKNOWN, + UNICAST, + BROADCAST, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl new file mode 100644 index 0000000000..f5d699edf1 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl @@ -0,0 +1,33 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.ChannelMode; + +/** + * Used for Software Encoding audio feed capabilities + */ +@VintfStability +parcelable PcmCapabilities { + int[] sampleRateHz; + ChannelMode channelMode; + byte[] bitsPerSample; + /** + * Data interval for data transfer + */ + int[] dataIntervalUs; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl new file mode 100644 index 0000000000..03aa27bb78 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl @@ -0,0 +1,33 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.ChannelMode; + +/** + * Used for Software Encoding audio feed configuration + */ +@VintfStability +parcelable PcmConfiguration { + int sampleRateHz; + ChannelMode channelMode; + byte bitsPerSample; + /** + * Data interval for data transfer + */ + int dataIntervalUs; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl new file mode 100644 index 0000000000..f3b8aed488 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2021 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.bluetooth.audio; + +@VintfStability +parcelable PresentationPosition { + @VintfStability + parcelable TimeSpec { + /** + * seconds + */ + long tvSec; + /** + * nanoseconds + */ + long tvNSec; + } + /* + * remoteDeviceAudioDelayNanos the audio delay from when the remote + * device (e.g. headset) receives audio data to when the device plays the + * sound. If the delay is unknown, the value is set to zero. + */ + long remoteDeviceAudioDelayNanos; + /* + * transmittedOctets the number of audio data octets that were sent + * to a remote device. This excludes octets that have been written to the + * data path but have not been sent to the remote device. The count is + * not reset until stopStream() is called. If the software data path is + * unused (e.g. Hardware Offload), the value is set to 0. + */ + long transmittedOctets; + /* + * transmittedOctetsTimestamp the value of CLOCK_MONOTONIC + * corresponding to transmittedOctets. If the software data path is + * unused (e.g., for Hardware Offload), the value is set to zero. + */ + TimeSpec transmittedOctetsTimestamp; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl new file mode 100644 index 0000000000..7047e346dc --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl @@ -0,0 +1,30 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="byte") +enum SbcAllocMethod { + /** + * SNR + */ + ALLOC_MD_S = 1, + /** + * Loudness + */ + ALLOC_MD_L = 1 << 1, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl new file mode 100644 index 0000000000..cf62ed4e5e --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl @@ -0,0 +1,43 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.SbcAllocMethod; +import android.hardware.bluetooth.audio.SbcChannelMode; + +/** + * Used for Hardware Encoding SBC codec capabilities. + */ +@VintfStability +parcelable SbcCapabilities { + int[] sampleRateHz; + /* bitfield */ + SbcChannelMode channelMode; + byte[] blockLength; + byte[] numSubbands; + /* bitfield */ + SbcAllocMethod allocMethod; + byte[] bitsPerSample; + /* + * range from 2 to 250. + */ + int minBitpool; + /* + * range from 2 to 250. + */ + int maxBitpool; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl new file mode 100644 index 0000000000..7eb38cd9f7 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl @@ -0,0 +1,27 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="byte") +enum SbcChannelMode { + UNKNOWN = 1, + JOINT_STEREO = 1 << 1, + STEREO = 1 << 2, + DUAL = 1 << 3, + MONO = 1 << 4, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl new file mode 100644 index 0000000000..054d03e94a --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.SbcAllocMethod; +import android.hardware.bluetooth.audio.SbcChannelMode; + +/** + * Used for Hardware Encoding SBC codec configuration. + */ +@VintfStability +parcelable SbcConfiguration { + int sampleRateHz; + SbcChannelMode channelMode; + byte blockLength; + byte numSubbands; + SbcAllocMethod allocMethod; + byte bitsPerSample; + /* + * range from 2 to 250. + */ + int minBitpool; + /* + * range from 2 to 250. + */ + int maxBitpool; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl new file mode 100644 index 0000000000..30faae31c9 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl @@ -0,0 +1,51 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +@VintfStability +@Backing(type="byte") +enum SessionType { + UNKNOWN, + /** + * A2DP legacy that AVDTP media is encoded by Bluetooth Stack + */ + A2DP_SOFTWARE_ENCODING_DATAPATH, + /** + * The encoding of AVDTP media is done by HW and there is control only + */ + A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH, + /** + * Used when encoded by Bluetooth Stack and streaming to Hearing Aid + */ + HEARING_AID_SOFTWARE_ENCODING_DATAPATH, + /** + * Used when encoded by Bluetooth Stack and streaming to LE Audio device + */ + LE_AUDIO_SOFTWARE_ENCODING_DATAPATH, + /** + * Used when decoded by Bluetooth Stack and streaming to audio framework + */ + LE_AUDIO_SOFTWARE_DECODING_DATAPATH, + /** + * Encoding is done by HW an there is control only + */ + LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH, + /** + * Decoding is done by HW an there is control only + */ + LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl new file mode 100644 index 0000000000..7be2c5b7bb --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.LeAudioCodecConfiguration; + +@VintfStability +parcelable UnicastConfiguration { + @VintfStability + parcelable UnicastStreamMap { + /* + * The connection handle used for a unicast or a broadcast group. + * Range: 0x0000 to 0xEFFF + */ + char streamHandle; + /* + * Audio channel allocation is a bit field, each enabled bit means that given audio + * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the + * least significant bit to the most significant bit. The valus follows the Bluetooth SIG + * Audio Location assigned number. + */ + int audioChannelAllocation; + } + UnicastStreamMap[] streamMap; + int peerDelay; + LeAudioCodecConfiguration leAudioCodecConfig; +} diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index fcff6bcbd4..ffbcb36e21 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -139,6 +139,13 @@ default + + android.hardware.bluetooth.audio + + IBluetoothAudioProviderFactory + default + + android.hardware.boot 1.2 -- cgit v1.2.3 From 5f33dbe46c9bf323837ba8c55facbd688b2c4e3f Mon Sep 17 00:00:00 2001 From: Shinru Han Date: Tue, 14 Dec 2021 12:06:02 +0800 Subject: Add IAGnssRil AIDL HAL (hardware/interfaces) Bug: 205185251 Bug: 182975915 Test: atest VtsHalGnssTargetTest Change-Id: Ie5746ae25db3beff20f1311f4ddaa592d8ca934b --- .../current/android/hardware/gnss/IAGnssRil.aidl | 79 ++++++++++ .../android/hardware/gnss/IAGnssRilCallback.aidl | 39 +++++ .../current/android/hardware/gnss/IGnss.aidl | 1 + gnss/aidl/android/hardware/gnss/IAGnssRil.aidl | 163 +++++++++++++++++++++ .../android/hardware/gnss/IAGnssRilCallback.aidl | 38 +++++ gnss/aidl/android/hardware/gnss/IGnss.aidl | 8 + gnss/aidl/default/AGnssRil.cpp | 55 +++++++ gnss/aidl/default/AGnssRil.h | 37 +++++ gnss/aidl/default/Android.bp | 1 + gnss/aidl/default/Gnss.cpp | 9 +- gnss/aidl/default/Gnss.h | 2 + gnss/aidl/vts/AGnssRilCallbackAidl.cpp | 28 ++++ gnss/aidl/vts/AGnssRilCallbackAidl.h | 28 ++++ gnss/aidl/vts/Android.bp | 1 + gnss/aidl/vts/gnss_hal_test_cases.cpp | 38 +++++ 15 files changed, 526 insertions(+), 1 deletion(-) create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRilCallback.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IAGnssRil.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IAGnssRilCallback.aidl create mode 100644 gnss/aidl/default/AGnssRil.cpp create mode 100644 gnss/aidl/default/AGnssRil.h create mode 100644 gnss/aidl/vts/AGnssRilCallbackAidl.cpp create mode 100644 gnss/aidl/vts/AGnssRilCallbackAidl.h diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl new file mode 100644 index 0000000000..73df1950bf --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +interface IAGnssRil { + void setCallback(in android.hardware.gnss.IAGnssRilCallback callback); + void setRefLocation(in android.hardware.gnss.IAGnssRil.AGnssRefLocation agnssReflocation); + void setSetId(in android.hardware.gnss.IAGnssRil.SetIDType type, in @utf8InCpp String setid); + void updateNetworkState(in android.hardware.gnss.IAGnssRil.NetworkAttributes attributes); + const int NETWORK_CAPABILITY_NOT_METERED = 1; + const int NETWORK_CAPABILITY_NOT_ROAMING = 2; + @Backing(type="int") @VintfStability + enum AGnssRefLocationType { + GSM_CELLID = 1, + UMTS_CELLID = 2, + LTE_CELLID = 4, + NR_CELLID = 8, + } + @Backing(type="int") @VintfStability + enum SetIDType { + NONE = 0, + IMSI = 1, + MSISDM = 2, + } + @VintfStability + parcelable AGnssRefLocationCellID { + android.hardware.gnss.IAGnssRil.AGnssRefLocationType type; + int mcc; + int mnc; + int lac; + long cid; + int tac; + int pcid; + int arfcn; + } + @VintfStability + parcelable AGnssRefLocation { + android.hardware.gnss.IAGnssRil.AGnssRefLocationType type; + android.hardware.gnss.IAGnssRil.AGnssRefLocationCellID cellID; + } + @VintfStability + parcelable NetworkAttributes { + long networkHandle; + boolean isConnected; + int capabilities; + @utf8InCpp String apn; + } +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRilCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRilCallback.aidl new file mode 100644 index 0000000000..152b10aea0 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRilCallback.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +interface IAGnssRilCallback { + void requestSetIdCb(in int setIdflag); + void requestRefLocCb(); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl index 1b4c5817ce..8e967444ef 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl @@ -44,6 +44,7 @@ interface IGnss { @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence(); @nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage(); android.hardware.gnss.IAGnss getExtensionAGnss(); + android.hardware.gnss.IAGnssRil getExtensionAGnssRil(); android.hardware.gnss.IGnssDebug getExtensionGnssDebug(); android.hardware.gnss.visibility_control.IGnssVisibilityControl getExtensionGnssVisibilityControl(); void start(); diff --git a/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl b/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl new file mode 100644 index 0000000000..b57c9bffb4 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2022 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; + +import android.hardware.gnss.IAGnssRilCallback; +import android.hardware.gnss.IAGnssRilCallback.SetIDType; + +/** + * Extended interface for AGNSS RIL support. An Assisted GNSS Radio Interface + * Layer interface allows the GNSS chipset to request radio interface layer + * information from Android platform. Examples of such information are reference + * location, unique subscriber ID, phone number string and network availability changes. + */ +@VintfStability +interface IAGnssRil { + /** Network capability mode bitmask for not metered. */ + const int NETWORK_CAPABILITY_NOT_METERED = 0x01; + + /** Network capability mode bitmask for not roaming. */ + const int NETWORK_CAPABILITY_NOT_ROAMING = 0x02; + + /** AGNSS reference location type */ + @VintfStability + @Backing(type="int") + enum AGnssRefLocationType { + GSM_CELLID = 1, + UMTS_CELLID = 2, + LTE_CELLID = 4, + NR_CELLID = 8, + } + + /** SET ID type*/ + @VintfStability + @Backing(type="int") + enum SetIDType { + NONE = 0, + IMSI = 1, + MSISDM = 2, + } + + /** CellID for 2G, 3G ,LTE and NR used in AGNSS. */ + @VintfStability + parcelable AGnssRefLocationCellID { + AGnssRefLocationType type; + + /** Mobile Country Code. */ + int mcc; + + /** Mobile Network Code .*/ + int mnc; + + /** + * Location Area Code in 2G, 3G and LTE. In 3G lac is discarded. In LTE, + * lac is populated with tac, to ensure that we don't break old clients that + * might rely on the old (wrong) behavior. + */ + int lac; + + /** + * Cell id in 2G. Utran Cell id in 3G. Cell Global Id EUTRA in LTE. + * Cell Global Id NR in 5G. + */ + long cid; + + /** Tracking Area Code in LTE and NR. */ + int tac; + + /** Physical Cell id in LTE and NR (not used in 2G and 3G) */ + int pcid; + + /** Absolute Radio Frequency Channel Number in NR. */ + int arfcn; + } + + /** Represents ref locations */ + @VintfStability + parcelable AGnssRefLocation { + AGnssRefLocationType type; + + AGnssRefLocationCellID cellID; + } + + /** Represents network connection status and capabilities. */ + @VintfStability + parcelable NetworkAttributes { + /** Network handle of the network for use with the NDK API. */ + long networkHandle; + + /** + * True indicates that network connectivity exists and it is possible to + * establish connections and pass data. If false, only the networkHandle field + * is populated to indicate that this network has just disconnected. + */ + boolean isConnected; + + /** + * A bitfield of flags indicating the capabilities of this network. The bit masks are + * defined in NETWORK_CAPABILITY_*. + */ + int capabilities; + + /** + * Telephony preferred Access Point Name to use for carrier data connection when + * connected to a cellular network. Empty string, otherwise. + */ + @utf8InCpp String apn; + } + + /** + * Opens the AGNSS interface and provides the callback routines + * to the implementation of this interface. + * + * @param callback Interface for AGnssRil callbacks. + * + */ + void setCallback(in IAGnssRilCallback callback); + + /** + * Sets the reference location. + * + * @param agnssReflocation AGNSS reference location CellID. + * + */ + void setRefLocation(in AGnssRefLocation agnssReflocation); + + /** + * Sets the SET ID. + * + * @param type Must be populated with either IMSI or MSISDN or NONE. + * @param setid If type is IMSI then setid is populated with + * a string representing the unique Subscriber ID, for example, the IMSI for + * a GMS phone. If type is MSISDN, then setid must contain + * the phone number string for line 1. For example, the MSISDN for a GSM phone. + * If the type is NONE, then the string must be empty. + * + */ + void setSetId(in SetIDType type, in @utf8InCpp String setid); + + /** + * Notifies GNSS of network status changes. + * + * The framework calls this method to update the GNSS HAL implementation of network + * state changes. + * + * @param attributes Updated network attributes. + * + */ + void updateNetworkState(in NetworkAttributes attributes); +} diff --git a/gnss/aidl/android/hardware/gnss/IAGnssRilCallback.aidl b/gnss/aidl/android/hardware/gnss/IAGnssRilCallback.aidl new file mode 100644 index 0000000000..6fb093e165 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IAGnssRilCallback.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 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; + +/** + * Callback for IAGnssRil interface. Used to request SET ID and + * Reference Location. + */ +@VintfStability +interface IAGnssRilCallback { + /** + * The Hal uses this API to request a SET ID. + * + * @param setIdflag A bitfield of IAGnssRil.SetIDType that is required by + * the HAL. The framework will inject an empty SET ID if the flag is NONE. + * + */ + void requestSetIdCb(in int setIdflag); + + /** + * The Hal uses this API to request a reference location. + */ + void requestRefLocCb(); +} diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index 4ddc6a6193..b6bd38a118 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -18,6 +18,7 @@ package android.hardware.gnss; import android.hardware.gnss.GnssLocation; import android.hardware.gnss.IAGnss; +import android.hardware.gnss.IAGnssRil; import android.hardware.gnss.IGnssBatching; import android.hardware.gnss.IGnssCallback; import android.hardware.gnss.IGnssConfiguration; @@ -185,6 +186,13 @@ interface IGnss { */ IAGnss getExtensionAGnss(); + /** + * This method returns the IAGnssRil interface. + * + * @return The IAGnssRil interface. + */ + IAGnssRil getExtensionAGnssRil(); + /** * This method returns the IGnssDebug interface. * diff --git a/gnss/aidl/default/AGnssRil.cpp b/gnss/aidl/default/AGnssRil.cpp new file mode 100644 index 0000000000..e6009bdcd9 --- /dev/null +++ b/gnss/aidl/default/AGnssRil.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2021 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 "AGnssRilAidl" + +#include "AGnssRil.h" +#include + +namespace aidl::android::hardware::gnss { + +std::shared_ptr AGnssRil::sCallback = nullptr; + +ndk::ScopedAStatus AGnssRil::setCallback(const std::shared_ptr& callback) { + ALOGD("AGnssRil::setCallback"); + std::unique_lock lock(mMutex); + sCallback = callback; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus AGnssRil::setRefLocation(const AGnssRefLocation& agnssReflocation) { + const AGnssRefLocationCellID& cellInfo = agnssReflocation.cellID; + ALOGD("AGnssRil::setRefLocation: type: %s, mcc: %d, mnc: %d, lac: %d, cid: %ld, tac: %d, pcid: " + "%d, arfcn: %d", + toString(agnssReflocation.type).c_str(), cellInfo.mcc, cellInfo.mnc, cellInfo.lac, + cellInfo.cid, cellInfo.tac, cellInfo.pcid, cellInfo.arfcn); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus AGnssRil::setSetId(SetIDType type, const std::string& setid) { + ALOGD("AGnssRil::setSetId: type:%s, setid: %s", toString(type).c_str(), setid.c_str()); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus AGnssRil::updateNetworkState(const NetworkAttributes& attributes) { + ALOGD("AGnssRil::updateNetworkState: networkHandle: %ld, isConnected: %d, capabilities: %d, " + "apn: %s", + attributes.networkHandle, attributes.isConnected, attributes.capabilities, + attributes.apn.c_str()); + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/AGnssRil.h b/gnss/aidl/default/AGnssRil.h new file mode 100644 index 0000000000..7e429ee8f4 --- /dev/null +++ b/gnss/aidl/default/AGnssRil.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::gnss { + +struct AGnssRil : public BnAGnssRil { + public: + ndk::ScopedAStatus setCallback(const std::shared_ptr& callback) override; + ndk::ScopedAStatus setRefLocation(const AGnssRefLocation& agnssReflocation) override; + ndk::ScopedAStatus setSetId(SetIDType type, const std::string& setid) override; + ndk::ScopedAStatus updateNetworkState(const NetworkAttributes& attributes) override; + + private: + // Synchronization lock for sCallback + mutable std::mutex mMutex; + // Guarded by mMutex + static std::shared_ptr sCallback; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 29c26d16ec..5797e1c645 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -56,6 +56,7 @@ cc_binary { "android.hardware.gnss-V2-ndk", ], srcs: [ + "AGnssRil.cpp", "AGnss.cpp", "Gnss.cpp", "GnssBatching.cpp", diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index e296351d95..dba54a017d 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -20,6 +20,7 @@ #include #include #include "AGnss.h" +#include "AGnssRil.h" #include "GnssBatching.h" #include "GnssConfiguration.h" #include "GnssDebug.h" @@ -154,7 +155,7 @@ ScopedAStatus Gnss::close() { return ScopedAStatus::ok(); } -ndk::ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr* iAGnss) { +ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr* iAGnss) { ALOGD("Gnss::getExtensionAGnss"); *iAGnss = SharedRefBase::make(); return ndk::ScopedAStatus::ok(); @@ -166,6 +167,12 @@ ScopedAStatus Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int unce return ScopedAStatus::ok(); } +ScopedAStatus Gnss::getExtensionAGnssRil(std::shared_ptr* iAGnssRil) { + ALOGD("Gnss::getExtensionAGnssRil"); + *iAGnssRil = SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + ScopedAStatus Gnss::injectLocation(const GnssLocation& location) { ALOGD("injectLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees, location.longitudeDegrees, location.horizontalAccuracyMeters); diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index 384c8629a2..731eaa3f36 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include #include @@ -65,6 +66,7 @@ class Gnss : public BnGnss { ndk::ScopedAStatus getExtensionGnssNavigationMessage( std::shared_ptr* iGnssNavigationMessage) override; ndk::ScopedAStatus getExtensionAGnss(std::shared_ptr* iAGnss) override; + ndk::ScopedAStatus getExtensionAGnssRil(std::shared_ptr* iAGnssRil) override; ndk::ScopedAStatus getExtensionGnssDebug(std::shared_ptr* iGnssDebug) override; ndk::ScopedAStatus getExtensionGnssVisibilityControl( std::shared_ptr* diff --git a/gnss/aidl/vts/AGnssRilCallbackAidl.cpp b/gnss/aidl/vts/AGnssRilCallbackAidl.cpp new file mode 100644 index 0000000000..4e4166d61d --- /dev/null +++ b/gnss/aidl/vts/AGnssRilCallbackAidl.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 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 "AGnssRilCallbackAidl.h" +#include + +android::binder::Status AGnssRilCallbackAidl::requestSetIdCb(int setIdflag) { + ALOGI("requestSetIdCb setIdflag %d", setIdflag); + return android::binder::Status::ok(); +} + +android::binder::Status AGnssRilCallbackAidl::requestRefLocCb() { + ALOGI("requestRefLocCb"); + return android::binder::Status::ok(); +} diff --git a/gnss/aidl/vts/AGnssRilCallbackAidl.h b/gnss/aidl/vts/AGnssRilCallbackAidl.h new file mode 100644 index 0000000000..74b34eee94 --- /dev/null +++ b/gnss/aidl/vts/AGnssRilCallbackAidl.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +/** Implementation for IAGnssRilCallback. */ +class AGnssRilCallbackAidl : public android::hardware::gnss::BnAGnssRilCallback { + public: + AGnssRilCallbackAidl(){}; + ~AGnssRilCallbackAidl(){}; + android::binder::Status requestSetIdCb(int setIdflag) override; + android::binder::Status requestRefLocCb() override; +}; diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index d532fad357..c39803f970 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -31,6 +31,7 @@ cc_test { "gnss_hal_test.cpp", "gnss_hal_test_cases.cpp", "AGnssCallbackAidl.cpp", + "AGnssRilCallbackAidl.cpp", "GnssBatchingCallback.cpp", "GnssCallbackAidl.cpp", "GnssGeofenceCallback.cpp", diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 9acef8bed0..6811b7b847 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -27,6 +27,7 @@ #include #include #include "AGnssCallbackAidl.h" +#include "AGnssRilCallbackAidl.h" #include "GnssBatchingCallback.h" #include "GnssGeofenceCallback.h" #include "GnssMeasurementCallbackAidl.h" @@ -43,6 +44,7 @@ using android::hardware::gnss::GnssData; using android::hardware::gnss::GnssMeasurement; using android::hardware::gnss::GnssPowerStats; using android::hardware::gnss::IAGnss; +using android::hardware::gnss::IAGnssRil; using android::hardware::gnss::IGnss; using android::hardware::gnss::IGnssBatching; using android::hardware::gnss::IGnssBatchingCallback; @@ -857,6 +859,42 @@ TEST_P(GnssHalTest, TestAGnssExtension) { ASSERT_TRUE(status.isOk()); } +/* + * TestAGnssRilExtension: + * 1. Gets the IAGnssRil extension. + * 2. Sets AGnssRilCallback. + * 3. Sets reference location. + */ +TEST_P(GnssHalTest, TestAGnssRilExtension) { + if (aidl_gnss_hal_->getInterfaceVersion() == 1) { + return; + } + sp iAGnssRil; + auto status = aidl_gnss_hal_->getExtensionAGnssRil(&iAGnssRil); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iAGnssRil != nullptr); + + auto agnssRilCallback = sp::make(); + status = iAGnssRil->setCallback(agnssRilCallback); + ASSERT_TRUE(status.isOk()); + + // Set RefLocation + IAGnssRil::AGnssRefLocationCellID agnssReflocationCellId; + agnssReflocationCellId.type = IAGnssRil::AGnssRefLocationType::LTE_CELLID; + agnssReflocationCellId.mcc = 466; + agnssReflocationCellId.mnc = 97; + agnssReflocationCellId.lac = 46697; + agnssReflocationCellId.cid = 59168142; + agnssReflocationCellId.pcid = 420; + agnssReflocationCellId.tac = 11460; + IAGnssRil::AGnssRefLocation agnssReflocation; + agnssReflocation.type = IAGnssRil::AGnssRefLocationType::LTE_CELLID; + agnssReflocation.cellID = agnssReflocationCellId; + + status = iAGnssRil->setRefLocation(agnssReflocation); + ASSERT_TRUE(status.isOk()); +} + /* * GnssDebugValuesSanityTest: * Ensures that GnssDebug values make sense. -- cgit v1.2.3 From 2e64b4d9f6883dea04d13a72fcaba6e31820ffb6 Mon Sep 17 00:00:00 2001 From: Patty Date: Thu, 6 Jan 2022 15:24:01 +0800 Subject: Update HAL structure to include offload capability for broadcast Bug: 205806028 Bug: 150670922 Test: make build Change-Id: Ife4a3585474999855ffb04f3946462a137fdc181 --- .../2.2/default/BluetoothAudioProvidersFactory.cpp | 2 +- bluetooth/audio/2.2/types.hal | 31 +++++++---- .../BluetoothAudioSupportedCodecsDB_2_2.cpp | 60 ++++++++++++---------- .../session/BluetoothAudioSupportedCodecsDB_2_2.h | 2 +- 4 files changed, 56 insertions(+), 39 deletions(-) diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp index 2fe31d5246..9dfc8289c5 100644 --- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp +++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp @@ -239,7 +239,7 @@ Return BluetoothAudioProvidersFactory::getProviderCapabilities_2_2( LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || sessionType == V2_1::SessionType:: LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - std::vector db_codec_capabilities = + std::vector db_codec_capabilities = android::bluetooth::audio::GetLeAudioOffloadCodecCapabilities( sessionType); if (db_codec_capabilities.size()) { diff --git a/bluetooth/audio/2.2/types.hal b/bluetooth/audio/2.2/types.hal index 8ec366060c..67558995f9 100644 --- a/bluetooth/audio/2.2/types.hal +++ b/bluetooth/audio/2.2/types.hal @@ -83,23 +83,22 @@ safe_union AudioConfiguration { safe_union AudioCapabilities { PcmParameters pcmCapabilities; CodecCapabilities codecCapabilities; - LeAudioCodecCapabilitiesPair leAudioCapabilities; + LeAudioCodecCapabilitiesSetting leAudioCapabilities; }; /** - * Used to specify th le audio capabilities pair of the Hardware offload encode and decode. + * Used to specify the le audio capabilities for unicast and broadcast hardware offload. */ -struct LeAudioCodecCapabilitiesPair{ - LeAudioMode mode; - LeAudioCodecCapability encodeCapability; - LeAudioCodecCapability decodeCapability; +struct LeAudioCodecCapabilitiesSetting{ + UnicastCapability unicastEncodeCapability; + UnicastCapability unicastDecodeCapability; + BroadcastCapability broadcastCapability; }; /** - * Used to specify the le audio capabilities of the codecs supported by Hardware offload - * for encode or decode. + * Used to specify the le audio unicast codec capabilities for hardware offload. */ -struct LeAudioCodecCapability { +struct UnicastCapability { CodecType codecType; AudioLocation supportedChannel; @@ -112,3 +111,17 @@ struct LeAudioCodecCapability { // Should use safe union when there is more than one codec Lc3Parameters capabilities; }; + +/** + * Used to specify the le audio broadcast codec capabilities for hardware offload. + */ +struct BroadcastCapability { + CodecType codecType; + AudioLocation supportedChannel; + + // Supported channel count for each stream + uint8_t channelCountPerStream; + + // Should use safe union when there is more than one codec + vec capabilities; +}; diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp index 34cfd7efb7..4c99b0f620 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp @@ -30,16 +30,20 @@ using ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration; using ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters; using ::android::hardware::bluetooth::audio::V2_1::SampleRate; using ::android::hardware::bluetooth::audio::V2_2::AudioLocation; -using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesPair; -using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapability; -using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode; +using ::android::hardware::bluetooth::audio::V2_2::BroadcastCapability; +using ::android::hardware::bluetooth::audio::V2_2:: + LeAudioCodecCapabilitiesSetting; +using ::android::hardware::bluetooth::audio::V2_2::UnicastCapability; using SessionType_2_1 = ::android::hardware::bluetooth::audio::V2_1::SessionType; // Stores the list of offload supported capability -std::vector kDefaultOffloadLeAudioCapabilities; +std::vector kDefaultOffloadLeAudioCapabilities; -static const LeAudioCodecCapability kInvalidLc3Capability = { +static const UnicastCapability kInvalidUnicastCapability = { + .codecType = CodecType::UNKNOWN}; + +static const BroadcastCapability kInvalidBroadcastCapability = { .codecType = CodecType::UNKNOWN}; // Default Supported Codecs @@ -94,53 +98,53 @@ bool IsOffloadLeAudioConfigurationValid( return true; } -LeAudioCodecCapability composeLc3Capability(AudioLocation audioLocation, - uint8_t deviceCnt, - uint8_t channelCount, - Lc3Parameters capability) { - return LeAudioCodecCapability{.codecType = CodecType::LC3, - .supportedChannel = audioLocation, - .deviceCount = deviceCnt, - .channelCountPerDevice = channelCount, - .capabilities = capability}; +UnicastCapability composeUnicastLc3Capability(AudioLocation audioLocation, + uint8_t deviceCnt, + uint8_t channelCount, + Lc3Parameters capability) { + return UnicastCapability{.codecType = CodecType::LC3, + .supportedChannel = audioLocation, + .deviceCount = deviceCnt, + .channelCountPerDevice = channelCount, + .capabilities = capability}; } -std::vector GetLeAudioOffloadCodecCapabilities( +std::vector GetLeAudioOffloadCodecCapabilities( const SessionType_2_1& session_type) { if (session_type != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && session_type != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - return std::vector(0); + return std::vector(0); } if (kDefaultOffloadLeAudioCapabilities.empty()) { for (auto [audioLocation, deviceCnt, channelCount] : supportedDeviceSetting) { for (auto capability : supportedLc3CapabilityList) { - LeAudioCodecCapability lc3Capability = composeLc3Capability( + UnicastCapability lc3Capability = composeUnicastLc3Capability( audioLocation, deviceCnt, channelCount, capability); - LeAudioCodecCapability lc3MonoCapability = - composeLc3Capability(monoAudio, 1, 1, capability); + UnicastCapability lc3MonoDecodeCapability = + composeUnicastLc3Capability(monoAudio, 1, 1, capability); // Adds the capability for encode only kDefaultOffloadLeAudioCapabilities.push_back( - {.mode = LeAudioMode::UNICAST, - .encodeCapability = lc3Capability, - .decodeCapability = kInvalidLc3Capability}); + {.unicastEncodeCapability = lc3Capability, + .unicastDecodeCapability = kInvalidUnicastCapability, + .broadcastCapability = kInvalidBroadcastCapability}); // Adds the capability for decode only kDefaultOffloadLeAudioCapabilities.push_back( - {.mode = LeAudioMode::UNICAST, - .encodeCapability = kInvalidLc3Capability, - .decodeCapability = lc3Capability}); + {.unicastEncodeCapability = kInvalidUnicastCapability, + .unicastDecodeCapability = lc3Capability, + .broadcastCapability = kInvalidBroadcastCapability}); // Adds the capability for the case that encode and decode exist at the // same time kDefaultOffloadLeAudioCapabilities.push_back( - {.mode = LeAudioMode::UNICAST, - .encodeCapability = lc3Capability, - .decodeCapability = lc3MonoCapability}); + {.unicastEncodeCapability = lc3Capability, + .unicastDecodeCapability = lc3MonoDecodeCapability, + .broadcastCapability = kInvalidBroadcastCapability}); } } } diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h index 89da6a383f..34bba5f671 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h +++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h @@ -31,7 +31,7 @@ bool IsOffloadLeAudioConfigurationValid( const ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration& le_audio_codec_config); -std::vector +std::vector GetLeAudioOffloadCodecCapabilities( const ::android::hardware::bluetooth::audio::V2_1::SessionType& session_type); -- cgit v1.2.3 From 7ae4255438c5b187186416e2a5c84842eeed1192 Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Thu, 6 Jan 2022 19:39:47 +0000 Subject: Adjust Context Hub AIDL based on feedback - Add additional documentation of ContextHubMessage.aidl. - Remove redundant TYPE_ specifier in HostEndpointInfo.aidl. Bug: 213474931 Test: Compile Change-Id: Ice1ac925a8b977abee8a9fa376ad40b33f315a3f --- .../current/android/hardware/contexthub/HostEndpointInfo.aidl | 4 ++-- .../aidl/android/hardware/contexthub/ContextHubMessage.aidl | 8 ++++++-- contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl | 8 ++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl index e7dcbc706d..84e8531eb9 100644 --- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl +++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl @@ -40,7 +40,7 @@ parcelable HostEndpointInfo { @nullable String attributionTag; @Backing(type="int") @VintfStability enum Type { - TYPE_FRAMEWORK = 1, - TYPE_APP = 2, + FRAMEWORK = 1, + APP = 2, } } diff --git a/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl b/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl index 867da2f9c0..95d478e6c2 100644 --- a/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl +++ b/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl @@ -32,10 +32,14 @@ parcelable ContextHubMessage { */ char hostEndPoint; - /** The type of this message */ + /** + * The type of this message payload, defined by the communication endpoints (i.e. + * either the nanoapp or the host endpoint). This value can be used to distinguish + * the handling of messageBody (e.g. for decoding). + */ int messageType; - /** The payload containing the message */ + /** The payload containing the message. */ byte[] messageBody; /** diff --git a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl index 40a231d804..a9d6657097 100644 --- a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl +++ b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl @@ -37,12 +37,12 @@ parcelable HostEndpointInfo { @Backing(type="int") enum Type { /** - This endpoint is from the Android framework, where packageName and attributionTag may be - empty. + * This endpoint is from the Android framework, where packageName and attributionTag may be + * empty. */ - TYPE_FRAMEWORK = 1, + FRAMEWORK = 1, /** This endpoint is an Android app. */ - TYPE_APP = 2, + APP = 2, } } -- cgit v1.2.3 From 60564e18c8e069c3d3da1d786956a4b927a06e85 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Thu, 9 Dec 2021 18:48:20 -0800 Subject: Adjustments to composer apis for HDR: 1. Add setDisplayBrightness as a display command, so that it may be set atomically with composition updates for that display. 2. Adjust tests to set display brightness using display commands. The setDisplayBrightness api on IComposer should be deprecated. It will be removed in a follow-up patch. Bug: 210151839 Test: builds Change-Id: I2e4348e1d7f799d1744390afbb9bd206054eb933 --- .../graphics/composer3/DisplayBrightness.aidl | 38 ++++++++++ .../graphics/composer3/DisplayCommand.aidl | 1 + .../graphics/composer3/DisplayBrightness.aidl | 26 +++++++ .../graphics/composer3/DisplayCommand.aidl | 24 +++++++ .../VtsHalGraphicsComposer3_TargetTest.cpp | 80 +++++++++++++--------- .../graphics/composer3/ComposerClientWriter.h | 6 ++ 6 files changed, 144 insertions(+), 31 deletions(-) create mode 100644 graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayBrightness.aidl create mode 100644 graphics/composer/aidl/android/hardware/graphics/composer3/DisplayBrightness.aidl diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayBrightness.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayBrightness.aidl new file mode 100644 index 0000000000..be623df763 --- /dev/null +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayBrightness.aidl @@ -0,0 +1,38 @@ +/** + * Copyright 2021, 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.graphics.composer3; +@VintfStability +parcelable DisplayBrightness { + float brightness; +} diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl index 3382633554..662240e96b 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl @@ -37,6 +37,7 @@ parcelable DisplayCommand { long display; android.hardware.graphics.composer3.LayerCommand[] layers; @nullable float[] colorTransformMatrix; + @nullable android.hardware.graphics.composer3.DisplayBrightness brightness; @nullable android.hardware.graphics.composer3.ClientTarget clientTarget; @nullable android.hardware.graphics.composer3.Buffer virtualDisplayOutputBuffer; @nullable android.hardware.graphics.composer3.ClockMonotonicTimestamp expectedPresentTime; diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayBrightness.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayBrightness.aidl new file mode 100644 index 0000000000..f66b235098 --- /dev/null +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayBrightness.aidl @@ -0,0 +1,26 @@ +/** + * Copyright 2021, 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.graphics.composer3; + +@VintfStability +parcelable DisplayBrightness { + /** + * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), a negative value to + * turn the backlight off. + */ + float brightness; +} diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl index 18461aded7..f1ce1a7dad 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl @@ -19,6 +19,7 @@ package android.hardware.graphics.composer3; import android.hardware.graphics.composer3.Buffer; import android.hardware.graphics.composer3.ClientTarget; import android.hardware.graphics.composer3.ClockMonotonicTimestamp; +import android.hardware.graphics.composer3.DisplayBrightness; import android.hardware.graphics.composer3.LayerCommand; @VintfStability @@ -68,6 +69,29 @@ parcelable DisplayCommand { */ @nullable float[] colorTransformMatrix; + /** + * Sets the desired brightness of the display. + * + * Ideally, the brightness of the display will take effect within this frame so that it can be + * aligned with color transforms. Some display architectures may take multiple frames to apply + * the display brightness, for example when internally switching the display between multiple + * power modes to achieve higher luminance. In those cases, the underlying display panel's real + * brightness may not be applied atomically; however, layer dimming when mixing HDR and SDR + * content must be synchronized. + * + * As an illustrative example: suppose two layers have white + * points of 200 nits and 1000 nits respectively, the old display luminance is 200 nits, and the + * new display luminance is 1000 nits. If the new display luminance takes two frames to apply, + * then: In the first frame, there must not be any relative dimming of layers (treat both layers + * as 200 nits as the maximum luminance of the display is 200 nits). In the second frame, there + * dimming should be applied to ensure that the first layer does not become perceptually + * brighter during the transition. + * + * The display luminance must be updated by this command even if there is not pending validate + * or present command. + */ + @nullable DisplayBrightness brightness; + /** * Sets the buffer handle which will receive the output of client * composition. Layers marked as Composition.CLIENT must be composited diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index 4dbe191f0c..a591aaa67d 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -568,37 +568,6 @@ TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSample) { } } -/* - * Test that if brightness operations are supported, setDisplayBrightness works as expected. - */ -TEST_P(GraphicsComposerAidlTest, setDisplayBrightness) { - std::vector capabilities; - auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities); - ASSERT_TRUE(error.isOk()); - bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(), - DisplayCapability::BRIGHTNESS) != capabilities.end(); - if (!brightnessSupport) { - EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f) - .getServiceSpecificError(), - IComposerClient::EX_UNSUPPORTED); - GTEST_SUCCEED() << "Brightness operations are not supported"; - return; - } - - EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.0f).isOk()); - EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f).isOk()); - EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 1.0f).isOk()); - EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -1.0f).isOk()); - - error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, +2.0f); - EXPECT_FALSE(error.isOk()); - EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER); - - error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f); - EXPECT_FALSE(error.isOk()); - EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER); -} - TEST_P(GraphicsComposerAidlTest, getDisplayConnectionType) { DisplayConnectionType type; EXPECT_FALSE(mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type).isOk()); @@ -1494,6 +1463,55 @@ TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) { } } +TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) { + std::vector capabilities; + auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities); + ASSERT_TRUE(error.isOk()); + bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(), + DisplayCapability::BRIGHTNESS) != capabilities.end(); + if (!brightnessSupport) { + mWriter.setDisplayBrightness(mPrimaryDisplay, 0.5f); + execute(); + const auto errors = mReader.takeErrors(); + EXPECT_EQ(1, errors.size()); + EXPECT_EQ(EX_UNSUPPORTED_OPERATION, errors[0].errorCode); + GTEST_SUCCEED() << "SetDisplayBrightness is not supported"; + return; + } + + mWriter.setDisplayBrightness(mPrimaryDisplay, 0.0f); + execute(); + EXPECT_TRUE(mReader.takeErrors().empty()); + + mWriter.setDisplayBrightness(mPrimaryDisplay, 0.5f); + execute(); + EXPECT_TRUE(mReader.takeErrors().empty()); + + mWriter.setDisplayBrightness(mPrimaryDisplay, 1.0f); + execute(); + EXPECT_TRUE(mReader.takeErrors().empty()); + + mWriter.setDisplayBrightness(mPrimaryDisplay, -1.0f); + execute(); + EXPECT_TRUE(mReader.takeErrors().empty()); + + mWriter.setDisplayBrightness(mPrimaryDisplay, 2.0f); + execute(); + { + const auto errors = mReader.takeErrors(); + EXPECT_EQ(1, errors.size()); + EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode); + } + + mWriter.setDisplayBrightness(mPrimaryDisplay, -2.0f); + execute(); + { + const auto errors = mReader.takeErrors(); + EXPECT_EQ(1, errors.size()); + EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode); + } +} + TEST_P(GraphicsComposerAidlCommandTest, SET_CLIENT_TARGET) { EXPECT_TRUE( mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk()); diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h index 16d63e57ca..b202b34c64 100644 --- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h +++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h @@ -29,9 +29,11 @@ #include #include #include +#include #include #include #include +#include #include @@ -79,6 +81,10 @@ class ComposerClientWriter { getDisplayCommand(display).colorTransformMatrix.emplace(std::move(matVec)); } + void setDisplayBrightness(int64_t display, float brightness) { + getDisplayCommand(display).brightness.emplace(DisplayBrightness{.brightness = brightness}); + } + void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target, int acquireFence, Dataspace dataspace, const std::vector& damage) { ClientTarget clientTargetCommand; -- cgit v1.2.3 From 406cb76efedd24d345660451362f804fd2d819d5 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Tue, 28 Dec 2021 12:14:22 -0800 Subject: Add GnssAgc to GnssMeasurementsEvent (hardware/interfaces) Bug: 206670536 Test: atest VtsHalGnssTargetTest Change-Id: I024c503f05c17d769e0833090ca555dc2a6f3ece --- .../current/android/hardware/gnss/GnssData.aidl | 7 +++ gnss/aidl/android/hardware/gnss/GnssData.aidl | 54 +++++++++++++++++++++- gnss/aidl/vts/gnss_hal_test_cases.cpp | 43 +++++++++++++++++ gnss/common/utils/default/Utils.cpp | 20 +++++++- 4 files changed, 121 insertions(+), 3 deletions(-) diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl index ebb5d0bdff..aa514da38c 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl @@ -37,4 +37,11 @@ parcelable GnssData { android.hardware.gnss.GnssMeasurement[] measurements; android.hardware.gnss.GnssClock clock; android.hardware.gnss.ElapsedRealtime elapsedRealtime; + @nullable android.hardware.gnss.GnssData.GnssAgc[] gnssAgcs; + @VintfStability + parcelable GnssAgc { + double agcLevelDb; + android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN; + long carrierFrequencyHz; + } } diff --git a/gnss/aidl/android/hardware/gnss/GnssData.aidl b/gnss/aidl/android/hardware/gnss/GnssData.aidl index ed30c989f8..204eb65e6b 100644 --- a/gnss/aidl/android/hardware/gnss/GnssData.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssData.aidl @@ -18,6 +18,7 @@ package android.hardware.gnss; import android.hardware.gnss.ElapsedRealtime; import android.hardware.gnss.GnssClock; +import android.hardware.gnss.GnssConstellationType; import android.hardware.gnss.GnssMeasurement; /** @@ -41,4 +42,55 @@ parcelable GnssData { * clock. */ ElapsedRealtime elapsedRealtime; -} \ No newline at end of file + + /** + * Represents a reading of GNSS AGC value of a constellation type and a frequency band. + */ + @VintfStability + parcelable GnssAgc { + /** + * Automatic gain control (AGC) level. AGC acts as a variable gain amplifier adjusting the + * power of the incoming signal. The AGC level may be used to indicate potential + * interference. Higher gain (and/or lower input power) must be output as a positive number. + * Hence in cases of strong jamming, in the band of this signal, this value must go more + * negative. This value must be consistent given the same level of the incoming signal + * power. + * + * Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW + * components) may also affect the typical output of this value on any given hardware design + * in an open sky test - the important aspect of this output is that changes in this value + * are indicative of changes on input signal power in the frequency band for this + * measurement. + */ + double agcLevelDb; + + /** + * Constellation type of the SV that transmits the signal. + */ + GnssConstellationType constellation = GnssConstellationType.UNKNOWN; + + /** + * Carrier frequency of the signal tracked, for example it can be the + * GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz, L5 = + * 1176.45 MHz, varying GLO channels, etc. If the field is not set, it + * is the primary common use central frequency, e.g. L1 = 1575.45 MHz + * for GPS. + * + * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same + * time, two raw measurement structs must be reported for this same + * satellite, in one of the measurement structs, all the values related + * to L1 must be filled, and in the other all of the values related to + * L5 must be filled. + */ + long carrierFrequencyHz; + } + + /** + * The array of GNSS AGC values. + * + * This field must be reported when the GNSS measurement engine is running, even when the + * GnssMeasurement or GnssClock fields are not reported yet. E.g., when a GNSS signal is too + * weak to be acquired, the AGC value must still be reported. + */ + @nullable GnssAgc[] gnssAgcs; +} diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 9acef8bed0..eec50b0a13 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -966,3 +966,46 @@ TEST_P(GnssHalTest, TestGnssMeasurementSetCallbackWithOptions) { status = iGnssMeasurement->close(); ASSERT_TRUE(status.isOk()); } + +/* + * TestGnssAgcInGnssMeasurement: + * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension. + * 2. Sets a GnssMeasurementCallback, waits for a measurement. + */ +TEST_P(GnssHalTest, TestGnssAgcInGnssMeasurement) { + if (aidl_gnss_hal_->getInterfaceVersion() == 1) { + return; + } + const int kFirstGnssMeasurementTimeoutSeconds = 10; + const int kNumMeasurementEvents = 15; + + sp iGnssMeasurement; + auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iGnssMeasurement != nullptr); + + auto callback = sp::make(); + status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ false, + /* enableCorrVecOutputs */ false); + ASSERT_TRUE(status.isOk()); + + for (int i = 0; i < kNumMeasurementEvents; i++) { + GnssData lastMeasurement; + ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement, + kFirstGnssMeasurementTimeoutSeconds)); + EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1); + ASSERT_TRUE(lastMeasurement.measurements.size() > 0); + + // Validity check GnssData fields + CheckGnssMeasurementClockFields(lastMeasurement); + + ASSERT_TRUE(lastMeasurement.gnssAgcs.has_value()); + for (const auto& gnssAgc : lastMeasurement.gnssAgcs.value()) { + ASSERT_TRUE(gnssAgc.has_value()); + ASSERT_TRUE(gnssAgc.value().carrierFrequencyHz >= 0); + } + } + + status = iGnssMeasurement->close(); + ASSERT_TRUE(status.isOk()); +} diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index 563c6d5d21..1ff84eb9a5 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -38,6 +38,7 @@ using GnssSvInfo = aidl::android::hardware::gnss::IGnssCallback::GnssSvInfo; using GnssSvFlags = aidl::android::hardware::gnss::IGnssCallback::GnssSvFlags; using GnssSvFlagsV1_0 = V1_0::IGnssCallback::GnssSvFlags; +using GnssAgc = aidl::android::hardware::gnss::GnssData::GnssAgc; using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags; using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags; using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState; @@ -231,8 +232,23 @@ GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) { measurement.flags |= GnssMeasurement::HAS_CORRELATION_VECTOR; } - GnssData gnssData = { - .measurements = {measurement}, .clock = clock, .elapsedRealtime = timestamp}; + GnssAgc gnssAgc1 = { + .agcLevelDb = 3.5, + .constellation = GnssConstellationType::GLONASS, + .carrierFrequencyHz = (int64_t)kGloG1FreqHz, + }; + + GnssAgc gnssAgc2 = { + .agcLevelDb = -5.1, + .constellation = GnssConstellationType::GPS, + .carrierFrequencyHz = (int64_t)kGpsL1FreqHz, + }; + + GnssData gnssData = {.measurements = {measurement}, + .clock = clock, + .elapsedRealtime = timestamp, + .gnssAgcs = std::make_optional(std::vector( + {std::make_optional(gnssAgc1), std::make_optional(gnssAgc2)}))}; return gnssData; } -- cgit v1.2.3 From eabd9d6d2ac5b50dc06eb0c9ac2c3d8715eec030 Mon Sep 17 00:00:00 2001 From: Brian J Murray Date: Thu, 6 Jan 2022 15:13:51 -0800 Subject: Verify op_ is not a nullptr If op_ is a nullptr, the test runner can SIGSEGV. Test: manual, atest EncryptionOperationsTest#TripleDesCbcPkcs7PaddingCorrupted Bug: None Signed-off-by: Brian J Murray Change-Id: Ibdd6139952ca8bc83ac1a82202839feee39562e1 --- security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 3695f1e094..02462fce3a 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -537,6 +537,9 @@ ErrorCode KeyMintAidlTestBase::Update(const string& input, string* output) { Status result; if (!output) return ErrorCode::UNEXPECTED_NULL_POINTER; + EXPECT_NE(op_, nullptr); + if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER; + std::vector o_put; result = op_->update(vector(input.begin(), input.end()), {}, {}, &o_put); -- cgit v1.2.3 From 8ee98880efef3fec2418b53683771425782aa885 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Tue, 4 Jan 2022 23:37:35 -0800 Subject: Add Stable AIDL interface for DRM service Test: m -j128 android.hardware.drm-update-api Bug: 200055138 Bug: 170964303 Change-Id: I091d839cd94075bf36670a9494aa99f7b6c97365 --- .../compatibility_matrix.current.xml | 12 + drm/aidl/Android.bp | 32 + .../current/android/hardware/drm/BufferType.aidl | 39 ++ .../android/hardware/drm/DecryptResult.aidl | 39 ++ .../android/hardware/drm/DestinationBuffer.aidl | 40 ++ .../current/android/hardware/drm/DrmMetric.aidl | 40 ++ .../android/hardware/drm/DrmMetricGroup.aidl | 38 ++ .../android/hardware/drm/DrmMetricNamedValue.aidl | 39 ++ .../android/hardware/drm/DrmMetricValue.aidl | 40 ++ .../current/android/hardware/drm/EventType.aidl | 42 ++ .../current/android/hardware/drm/HdcpLevel.aidl | 45 ++ .../current/android/hardware/drm/HdcpLevels.aidl | 39 ++ .../android/hardware/drm/ICryptoFactory.aidl | 39 ++ .../android/hardware/drm/ICryptoPlugin.aidl | 43 ++ .../current/android/hardware/drm/IDrmFactory.aidl | 41 ++ .../current/android/hardware/drm/IDrmPlugin.aidl | 77 +++ .../android/hardware/drm/IDrmPluginListener.aidl | 41 ++ .../current/android/hardware/drm/KeyRequest.aidl | 40 ++ .../android/hardware/drm/KeyRequestType.aidl | 43 ++ .../current/android/hardware/drm/KeySetId.aidl | 38 ++ .../current/android/hardware/drm/KeyStatus.aidl | 39 ++ .../android/hardware/drm/KeyStatusType.aidl | 43 ++ .../current/android/hardware/drm/KeyType.aidl | 40 ++ .../current/android/hardware/drm/KeyValue.aidl | 39 ++ .../current/android/hardware/drm/LogMessage.aidl | 40 ++ .../current/android/hardware/drm/LogPriority.aidl | 45 ++ .../current/android/hardware/drm/Mode.aidl | 41 ++ .../android/hardware/drm/NumberOfSessions.aidl | 39 ++ .../android/hardware/drm/OfflineLicenseState.aidl | 40 ++ .../current/android/hardware/drm/OpaqueData.aidl | 38 ++ .../current/android/hardware/drm/Pattern.aidl | 39 ++ .../drm/ProvideProvisionResponseResult.aidl | 39 ++ .../android/hardware/drm/ProvisionRequest.aidl | 39 ++ .../current/android/hardware/drm/SecureStop.aidl | 38 ++ .../current/android/hardware/drm/SecureStopId.aidl | 38 ++ .../android/hardware/drm/SecurityLevel.aidl | 44 ++ .../current/android/hardware/drm/SharedBuffer.aidl | 40 ++ .../current/android/hardware/drm/Status.aidl | 77 +++ .../current/android/hardware/drm/SubSample.aidl | 39 ++ .../current/android/hardware/drm/Uuid.aidl | 38 ++ drm/aidl/android/hardware/drm/BufferType.aidl | 24 + drm/aidl/android/hardware/drm/DecryptResult.aidl | 33 + .../android/hardware/drm/DestinationBuffer.aidl | 45 ++ drm/aidl/android/hardware/drm/DrmMetric.aidl | 46 ++ drm/aidl/android/hardware/drm/DrmMetricGroup.aidl | 61 ++ .../android/hardware/drm/DrmMetricNamedValue.aidl | 28 + drm/aidl/android/hardware/drm/DrmMetricValue.aidl | 27 + drm/aidl/android/hardware/drm/EventType.aidl | 51 ++ drm/aidl/android/hardware/drm/HdcpLevel.aidl | 59 ++ drm/aidl/android/hardware/drm/HdcpLevels.aidl | 28 + drm/aidl/android/hardware/drm/ICryptoFactory.aidl | 51 ++ drm/aidl/android/hardware/drm/ICryptoPlugin.aidl | 138 ++++ drm/aidl/android/hardware/drm/IDrmFactory.aidl | 76 +++ drm/aidl/android/hardware/drm/IDrmPlugin.aidl | 755 +++++++++++++++++++++ .../android/hardware/drm/IDrmPluginListener.aidl | 76 +++ drm/aidl/android/hardware/drm/KeyRequest.aidl | 46 ++ drm/aidl/android/hardware/drm/KeyRequestType.aidl | 52 ++ drm/aidl/android/hardware/drm/KeySetId.aidl | 22 + drm/aidl/android/hardware/drm/KeyStatus.aidl | 29 + drm/aidl/android/hardware/drm/KeyStatusType.aidl | 51 ++ drm/aidl/android/hardware/drm/KeyType.aidl | 38 ++ drm/aidl/android/hardware/drm/KeyValue.aidl | 23 + drm/aidl/android/hardware/drm/LogMessage.aidl | 38 ++ drm/aidl/android/hardware/drm/LogPriority.aidl | 30 + drm/aidl/android/hardware/drm/Mode.aidl | 29 + .../android/hardware/drm/NumberOfSessions.aidl | 26 + .../android/hardware/drm/OfflineLicenseState.aidl | 36 + drm/aidl/android/hardware/drm/OpaqueData.aidl | 22 + drm/aidl/android/hardware/drm/Pattern.aidl | 39 ++ .../drm/ProvideProvisionResponseResult.aidl | 34 + .../android/hardware/drm/ProvisionRequest.aidl | 31 + drm/aidl/android/hardware/drm/SecureStop.aidl | 25 + drm/aidl/android/hardware/drm/SecureStopId.aidl | 22 + drm/aidl/android/hardware/drm/SecurityLevel.aidl | 55 ++ drm/aidl/android/hardware/drm/SharedBuffer.aidl | 39 ++ drm/aidl/android/hardware/drm/Status.aidl | 221 ++++++ drm/aidl/android/hardware/drm/SubSample.aidl | 27 + drm/aidl/android/hardware/drm/Uuid.aidl | 22 + 78 files changed, 4097 insertions(+) create mode 100644 drm/aidl/Android.bp create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.aidl create mode 100644 drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.aidl create mode 100644 drm/aidl/android/hardware/drm/BufferType.aidl create mode 100644 drm/aidl/android/hardware/drm/DecryptResult.aidl create mode 100644 drm/aidl/android/hardware/drm/DestinationBuffer.aidl create mode 100644 drm/aidl/android/hardware/drm/DrmMetric.aidl create mode 100644 drm/aidl/android/hardware/drm/DrmMetricGroup.aidl create mode 100644 drm/aidl/android/hardware/drm/DrmMetricNamedValue.aidl create mode 100644 drm/aidl/android/hardware/drm/DrmMetricValue.aidl create mode 100644 drm/aidl/android/hardware/drm/EventType.aidl create mode 100644 drm/aidl/android/hardware/drm/HdcpLevel.aidl create mode 100644 drm/aidl/android/hardware/drm/HdcpLevels.aidl create mode 100644 drm/aidl/android/hardware/drm/ICryptoFactory.aidl create mode 100644 drm/aidl/android/hardware/drm/ICryptoPlugin.aidl create mode 100644 drm/aidl/android/hardware/drm/IDrmFactory.aidl create mode 100644 drm/aidl/android/hardware/drm/IDrmPlugin.aidl create mode 100644 drm/aidl/android/hardware/drm/IDrmPluginListener.aidl create mode 100644 drm/aidl/android/hardware/drm/KeyRequest.aidl create mode 100644 drm/aidl/android/hardware/drm/KeyRequestType.aidl create mode 100644 drm/aidl/android/hardware/drm/KeySetId.aidl create mode 100644 drm/aidl/android/hardware/drm/KeyStatus.aidl create mode 100644 drm/aidl/android/hardware/drm/KeyStatusType.aidl create mode 100644 drm/aidl/android/hardware/drm/KeyType.aidl create mode 100644 drm/aidl/android/hardware/drm/KeyValue.aidl create mode 100644 drm/aidl/android/hardware/drm/LogMessage.aidl create mode 100644 drm/aidl/android/hardware/drm/LogPriority.aidl create mode 100644 drm/aidl/android/hardware/drm/Mode.aidl create mode 100644 drm/aidl/android/hardware/drm/NumberOfSessions.aidl create mode 100644 drm/aidl/android/hardware/drm/OfflineLicenseState.aidl create mode 100644 drm/aidl/android/hardware/drm/OpaqueData.aidl create mode 100644 drm/aidl/android/hardware/drm/Pattern.aidl create mode 100644 drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.aidl create mode 100644 drm/aidl/android/hardware/drm/ProvisionRequest.aidl create mode 100644 drm/aidl/android/hardware/drm/SecureStop.aidl create mode 100644 drm/aidl/android/hardware/drm/SecureStopId.aidl create mode 100644 drm/aidl/android/hardware/drm/SecurityLevel.aidl create mode 100644 drm/aidl/android/hardware/drm/SharedBuffer.aidl create mode 100644 drm/aidl/android/hardware/drm/Status.aidl create mode 100644 drm/aidl/android/hardware/drm/SubSample.aidl create mode 100644 drm/aidl/android/hardware/drm/Uuid.aidl diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index c480c13554..cb9bd3db45 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -209,6 +209,18 @@ default + + android.hardware.drm + 1 + + ICryptoFactory + .* + + + IDrmFactory + .* + + android.hardware.drm 1.3-4 diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp new file mode 100644 index 0000000000..d8500ec3b2 --- /dev/null +++ b/drm/aidl/Android.bp @@ -0,0 +1,32 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +aidl_interface { + name: "android.hardware.drm", + vendor_available: true, + srcs: ["android/hardware/drm/*.aidl"], + stability: "vintf", + imports: [ + "android.hardware.common-V2", + ], + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + vndk: { + enabled: true, + }, + min_sdk_version: "current", + }, + }, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.aidl new file mode 100644 index 0000000000..b6ec34d897 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum BufferType { + SHARED_MEMORY = 0, + NATIVE_HANDLE = 1, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.aidl new file mode 100644 index 0000000000..d2b48d2b98 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable DecryptResult { + int bytesWritten; + String detailedError; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.aidl new file mode 100644 index 0000000000..4f2d133cae --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable DestinationBuffer { + android.hardware.drm.BufferType type; + android.hardware.drm.SharedBuffer nonsecureMemory; + android.hardware.common.NativeHandle secureMemory; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.aidl new file mode 100644 index 0000000000..c78dff0b16 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable DrmMetric { + String name; + List attributes; + List values; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.aidl new file mode 100644 index 0000000000..4128eaa54d --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable DrmMetricGroup { + List metrics; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.aidl new file mode 100644 index 0000000000..76ec35c0cf --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable DrmMetricNamedValue { + String name; + android.hardware.drm.DrmMetricValue value; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.aidl new file mode 100644 index 0000000000..806491357c --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +union DrmMetricValue { + long int64Value; + double doubleValue; + String stringValue; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl new file mode 100644 index 0000000000..80ebb285ae --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum EventType { + PROVISION_REQUIRED = 0, + KEY_NEEDED = 1, + KEY_EXPIRED = 2, + VENDOR_DEFINED = 3, + SESSION_RECLAIMED = 4, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl new file mode 100644 index 0000000000..5704fb0726 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum HdcpLevel { + HDCP_UNKNOWN = 0, + HDCP_NONE = 1, + HDCP_V1 = 2, + HDCP_V2 = 3, + HDCP_V2_1 = 4, + HDCP_V2_2 = 5, + HDCP_NO_OUTPUT = 6, + HDCP_V2_3 = 7, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl new file mode 100644 index 0000000000..a6f86ace67 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable HdcpLevels { + android.hardware.drm.HdcpLevel connectedLevel; + android.hardware.drm.HdcpLevel maxLevel; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.aidl new file mode 100644 index 0000000000..0d4296ec1f --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +interface ICryptoFactory { + @nullable android.hardware.drm.ICryptoPlugin createPlugin(in android.hardware.drm.Uuid uuid, in byte[] initData); + boolean isCryptoSchemeSupported(in android.hardware.drm.Uuid uuid); +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl new file mode 100644 index 0000000000..2224795198 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +interface ICryptoPlugin { + android.hardware.drm.DecryptResult decrypt(in boolean secure, in byte[] keyId, in byte[] iv, in android.hardware.drm.Mode mode, in android.hardware.drm.Pattern pattern, in android.hardware.drm.SubSample[] subSamples, in android.hardware.drm.SharedBuffer source, in long offset, in android.hardware.drm.DestinationBuffer destination); + List getLogMessages(); + void notifyResolution(in int width, in int height); + boolean requiresSecureDecoderComponent(in String mime); + void setMediaDrmSession(in byte[] sessionId); + void setSharedBufferBase(in android.hardware.common.Ashmem base, in int bufferId); +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.aidl new file mode 100644 index 0000000000..af48737892 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +interface IDrmFactory { + @nullable android.hardware.drm.IDrmPlugin createPlugin(in android.hardware.drm.Uuid uuid, in String appPackageName); + List getSupportedCryptoSchemes(); + boolean isContentTypeSupported(in String mimeType); + boolean isCryptoSchemeSupported(in android.hardware.drm.Uuid uuid, in String mimeType, in android.hardware.drm.SecurityLevel securityLevel); +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl new file mode 100644 index 0000000000..5f839d763c --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +interface IDrmPlugin { + void closeSession(in byte[] sessionId); + byte[] decrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv); + byte[] encrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv); + android.hardware.drm.HdcpLevels getHdcpLevels(); + android.hardware.drm.KeyRequest getKeyRequest(in byte[] scope, in byte[] initData, in String mimeType, in android.hardware.drm.KeyType keyType, in android.hardware.drm.KeyValue[] optionalParameters); + List getLogMessages(); + List getMetrics(); + android.hardware.drm.NumberOfSessions getNumberOfSessions(); + List getOfflineLicenseKeySetIds(); + android.hardware.drm.OfflineLicenseState getOfflineLicenseState(in android.hardware.drm.KeySetId keySetId); + byte[] getPropertyByteArray(in String propertyName); + String getPropertyString(in String propertyName); + android.hardware.drm.ProvisionRequest getProvisionRequest(in String certificateType, in String certificateAuthority); + android.hardware.drm.SecureStop getSecureStop(in android.hardware.drm.SecureStopId secureStopId); + List getSecureStopIds(); + List getSecureStops(); + android.hardware.drm.SecurityLevel getSecurityLevel(in byte[] sessionId); + byte[] openSession(in android.hardware.drm.SecurityLevel securityLevel); + android.hardware.drm.KeySetId provideKeyResponse(in byte[] scope, in byte[] response); + android.hardware.drm.ProvideProvisionResponseResult provideProvisionResponse(in byte[] response); + List queryKeyStatus(in byte[] sessionId); + void releaseAllSecureStops(); + void releaseSecureStop(in android.hardware.drm.SecureStopId secureStopId); + void releaseSecureStops(in android.hardware.drm.OpaqueData ssRelease); + void removeAllSecureStops(); + void removeKeys(in byte[] sessionId); + void removeOfflineLicense(in android.hardware.drm.KeySetId keySetId); + void removeSecureStop(in android.hardware.drm.SecureStopId secureStopId); + boolean requiresSecureDecoder(in String mime, in android.hardware.drm.SecurityLevel level); + boolean requiresSecureDecoderDefault(in String mime); + void restoreKeys(in byte[] sessionId, in android.hardware.drm.KeySetId keySetId); + void setCipherAlgorithm(in byte[] sessionId, in String algorithm); + void setListener(in android.hardware.drm.IDrmPluginListener listener); + void setMacAlgorithm(in byte[] sessionId, in String algorithm); + void setPlaybackId(in byte[] sessionId, in String playbackId); + void setPropertyByteArray(in String propertyName, in byte[] value); + void setPropertyString(in String propertyName, in String value); + byte[] sign(in byte[] sessionId, in byte[] keyId, in byte[] message); + byte[] signRSA(in byte[] sessionId, in String algorithm, in byte[] message, in byte[] wrappedkey); + boolean verify(in byte[] sessionId, in byte[] keyId, in byte[] message, in byte[] signature); +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.aidl new file mode 100644 index 0000000000..0a4b4b70bc --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +interface IDrmPluginListener { + oneway void onEvent(in android.hardware.drm.EventType eventType, in byte[] sessionId, in byte[] data); + oneway void onExpirationUpdate(in byte[] sessionId, in long expiryTimeInMS); + oneway void onKeysChange(in byte[] sessionId, in android.hardware.drm.KeyStatus[] keyStatusList, in boolean hasNewUsableKey); + oneway void onSessionLostState(in byte[] sessionId); +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.aidl new file mode 100644 index 0000000000..267f532755 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable KeyRequest { + byte[] request; + android.hardware.drm.KeyRequestType requestType; + String defaultUrl; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl new file mode 100644 index 0000000000..34b9615c55 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum KeyRequestType { + INITIAL = 0, + RENEWAL = 1, + RELEASE = 2, + UNKNOWN = 3, + NONE = 4, + UPDATE = 5, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.aidl new file mode 100644 index 0000000000..58dfe1a412 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable KeySetId { + byte[] keySetId; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.aidl new file mode 100644 index 0000000000..53ab70f0fb --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable KeyStatus { + byte[] keyId; + android.hardware.drm.KeyStatusType type; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl new file mode 100644 index 0000000000..e88d3886a2 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum KeyStatusType { + USABLE = 0, + EXPIRED = 1, + OUTPUTNOTALLOWED = 2, + STATUSPENDING = 3, + INTERNALERROR = 4, + USABLEINFUTURE = 5, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl new file mode 100644 index 0000000000..7a9d633578 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum KeyType { + OFFLINE = 0, + STREAMING = 1, + RELEASE = 2, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.aidl new file mode 100644 index 0000000000..35d7b77bc9 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable KeyValue { + String key; + String value; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.aidl new file mode 100644 index 0000000000..93f76e1c41 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable LogMessage { + long timeMs; + android.hardware.drm.LogPriority priority; + String message; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl new file mode 100644 index 0000000000..83362c359f --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum LogPriority { + UNKNOWN = 0, + DEFAULT = 1, + VERBOSE = 2, + DEBUG = 3, + INFO = 4, + WARN = 5, + ERROR = 6, + FATAL = 7, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.aidl new file mode 100644 index 0000000000..7379774093 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum Mode { + UNENCRYPTED = 0, + AES_CTR = 1, + AES_CBC_CTS = 2, + AES_CBC = 3, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.aidl new file mode 100644 index 0000000000..a421125fc3 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable NumberOfSessions { + int currentSessions; + int maxSessions; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl new file mode 100644 index 0000000000..629564d706 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum OfflineLicenseState { + UNKNOWN = 0, + USABLE = 1, + INACTIVE = 2, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.aidl new file mode 100644 index 0000000000..3085889faf --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable OpaqueData { + byte[] opaqueData; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.aidl new file mode 100644 index 0000000000..b01562e67e --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable Pattern { + int encryptBlocks; + int skipBlocks; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.aidl new file mode 100644 index 0000000000..827de59093 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable ProvideProvisionResponseResult { + byte[] certificate; + byte[] wrappedKey; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.aidl new file mode 100644 index 0000000000..84c56621f2 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable ProvisionRequest { + byte[] request; + String defaultUrl; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.aidl new file mode 100644 index 0000000000..81d2dfe75c --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable SecureStop { + byte[] opaqueData; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.aidl new file mode 100644 index 0000000000..2b904c8629 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable SecureStopId { + byte[] secureStopId; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl new file mode 100644 index 0000000000..65b2b9d2ae --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum SecurityLevel { + UNKNOWN = 0, + SW_SECURE_CRYPTO = 1, + SW_SECURE_DECODE = 2, + HW_SECURE_CRYPTO = 3, + HW_SECURE_DECODE = 4, + HW_SECURE_ALL = 5, + DEFAULT = 6, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.aidl new file mode 100644 index 0000000000..973ef0db3d --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable SharedBuffer { + int bufferId; + long offset; + long size; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl new file mode 100644 index 0000000000..c64068958f --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@Backing(type="int") @VintfStability +enum Status { + OK = 0, + ERROR_DRM_NO_LICENSE = 1, + ERROR_DRM_LICENSE_EXPIRED = 2, + ERROR_DRM_SESSION_NOT_OPENED = 3, + ERROR_DRM_CANNOT_HANDLE = 4, + ERROR_DRM_INVALID_STATE = 5, + BAD_VALUE = 6, + ERROR_DRM_NOT_PROVISIONED = 7, + ERROR_DRM_RESOURCE_BUSY = 8, + ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = 9, + ERROR_DRM_DEVICE_REVOKED = 10, + ERROR_DRM_DECRYPT = 11, + ERROR_DRM_UNKNOWN = 12, + ERROR_DRM_INSUFFICIENT_SECURITY = 13, + ERROR_DRM_FRAME_TOO_LARGE = 14, + ERROR_DRM_SESSION_LOST_STATE = 15, + ERROR_DRM_RESOURCE_CONTENTION = 16, + CANNOT_DECRYPT_ZERO_SUBSAMPLES = 17, + CRYPTO_LIBRARY_ERROR = 18, + GENERAL_OEM_ERROR = 19, + GENERAL_PLUGIN_ERROR = 20, + INIT_DATA_INVALID = 21, + KEY_NOT_LOADED = 22, + LICENSE_PARSE_ERROR = 23, + LICENSE_POLICY_ERROR = 24, + LICENSE_RELEASE_ERROR = 25, + LICENSE_REQUEST_REJECTED = 26, + LICENSE_RESTORE_ERROR = 27, + LICENSE_STATE_ERROR = 28, + MALFORMED_CERTIFICATE = 29, + MEDIA_FRAMEWORK_ERROR = 30, + MISSING_CERTIFICATE = 31, + PROVISIONING_CERTIFICATE_ERROR = 32, + PROVISIONING_CONFIGURATION_ERROR = 33, + PROVISIONING_PARSE_ERROR = 34, + PROVISIONING_REQUEST_REJECTED = 35, + RETRYABLE_PROVISIONING_ERROR = 36, + SECURE_STOP_RELEASE_ERROR = 37, + STORAGE_READ_FAILURE = 38, + STORAGE_WRITE_FAILURE = 39, +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.aidl new file mode 100644 index 0000000000..57d815eeb2 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable SubSample { + int numBytesOfClearData; + int numBytesOfEncryptedData; +} diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.aidl new file mode 100644 index 0000000000..ec2eb164c9 --- /dev/null +++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.drm; +@VintfStability +parcelable Uuid { + byte[] uuid; +} diff --git a/drm/aidl/android/hardware/drm/BufferType.aidl b/drm/aidl/android/hardware/drm/BufferType.aidl new file mode 100644 index 0000000000..089c950656 --- /dev/null +++ b/drm/aidl/android/hardware/drm/BufferType.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +@Backing(type="int") +enum BufferType { + SHARED_MEMORY = 0, + NATIVE_HANDLE = 1, +} diff --git a/drm/aidl/android/hardware/drm/DecryptResult.aidl b/drm/aidl/android/hardware/drm/DecryptResult.aidl new file mode 100644 index 0000000000..17e939bc95 --- /dev/null +++ b/drm/aidl/android/hardware/drm/DecryptResult.aidl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * The DecryptResult parcelable contains the result of + * ICryptoPlugin decrypt method. + */ +@VintfStability +parcelable DecryptResult { + /** The number of decrypted bytes. */ + int bytesWritten; + + /** + * Vendor-specific error message if provided by the vendor's + * crypto HAL. + */ + String detailedError; +} diff --git a/drm/aidl/android/hardware/drm/DestinationBuffer.aidl b/drm/aidl/android/hardware/drm/DestinationBuffer.aidl new file mode 100644 index 0000000000..0f1e3f5398 --- /dev/null +++ b/drm/aidl/android/hardware/drm/DestinationBuffer.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.common.NativeHandle; +import android.hardware.drm.BufferType; +import android.hardware.drm.SharedBuffer; + +/** + * A decrypt destination buffer can be either normal user-space shared + * memory for the non-secure decrypt case, or it can be a secure buffer + * which is referenced by a native-handle. The native handle is allocated + * by the vendor's buffer allocator. + */ +@VintfStability +parcelable DestinationBuffer { + /** + * The type of the buffer + */ + BufferType type; + /** + * If type == SHARED_MEMORY, the decrypted data must be written + * to user-space non-secure shared memory. + */ + SharedBuffer nonsecureMemory; + /** + * If type == NATIVE_HANDLE, the decrypted data must be written + * to secure memory referenced by the vendor's buffer allocator. + */ + NativeHandle secureMemory; +} diff --git a/drm/aidl/android/hardware/drm/DrmMetric.aidl b/drm/aidl/android/hardware/drm/DrmMetric.aidl new file mode 100644 index 0000000000..6199af6d4d --- /dev/null +++ b/drm/aidl/android/hardware/drm/DrmMetric.aidl @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.DrmMetricNamedValue; + +/** + * The metric being captured. + * + * A metric must have a name and at least one value. A metric may have 0 or + * more attributes. The fields of a Metric are opaque to the framework. + */ +@VintfStability +parcelable DrmMetric { + String name; + + /** + * Detail(s) about the metric being captured. + * + * The fields of an Attribute are opaque to the framework. + */ + List attributes; + + /** + * Value(s) of the metric. + * + * A metric may have multiple values. The component name may be left empty + * if there is only supposed to be one value for the given metric. The + * fields of the Value are opaque to the framework. + */ + List values; +} diff --git a/drm/aidl/android/hardware/drm/DrmMetricGroup.aidl b/drm/aidl/android/hardware/drm/DrmMetricGroup.aidl new file mode 100644 index 0000000000..3b1f3c9b0e --- /dev/null +++ b/drm/aidl/android/hardware/drm/DrmMetricGroup.aidl @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.DrmMetric; + +/** + * This message contains plugin-specific metrics made available to the client. + * The message is used for making vendor-specific metrics available to an + * application. The framework is not consuming any of the information. + * + * Metrics are grouped in instances of DrmMetricGroup. Each group contains + * multiple instances of Metric. + * + * Example: + * + * Capture the timing information of a buffer copy event, "buf_copy", broken + * out by the "size" of the buffer. + * + * DrmMetricGroup { + * metrics[0] { + * name: "buf_copy" + * attributes[0] { + * name: "size" + * type: INT64_TYPE + * int64Value: 1024 + * } + * values[0] { + * componentName: "operation_count" + * type: INT64_TYPE + * int64Value: 75 + * } + * values[1] { + * component_name: "average_time_seconds" + * type: DOUBLE_TYPE + * doubleValue: 0.00000042 + * } + * } + * } + */ +@VintfStability +parcelable DrmMetricGroup { + /** + * The list of metrics to be captured. + */ + List metrics; +} diff --git a/drm/aidl/android/hardware/drm/DrmMetricNamedValue.aidl b/drm/aidl/android/hardware/drm/DrmMetricNamedValue.aidl new file mode 100644 index 0000000000..5bb17a6036 --- /dev/null +++ b/drm/aidl/android/hardware/drm/DrmMetricNamedValue.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.DrmMetricValue; + +/** + * A name-value pair used in drm metrics. + */ +@VintfStability +parcelable DrmMetricNamedValue { + String name; + DrmMetricValue value; +} diff --git a/drm/aidl/android/hardware/drm/DrmMetricValue.aidl b/drm/aidl/android/hardware/drm/DrmMetricValue.aidl new file mode 100644 index 0000000000..0203f3f801 --- /dev/null +++ b/drm/aidl/android/hardware/drm/DrmMetricValue.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * The value of a metric or a metric's attribute. + */ +@VintfStability +union DrmMetricValue { + long int64Value; + double doubleValue; + String stringValue; +} diff --git a/drm/aidl/android/hardware/drm/EventType.aidl b/drm/aidl/android/hardware/drm/EventType.aidl new file mode 100644 index 0000000000..7a06eb0505 --- /dev/null +++ b/drm/aidl/android/hardware/drm/EventType.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * EventType enumerates the events that can be delivered by sendEvent + */ +@VintfStability +@Backing(type="int") +enum EventType { + /** + * This event type indicates that the app needs to request a certificate + * from the provisioning server. The request message data is obtained using + * getProvisionRequest(). + */ + PROVISION_REQUIRED, + /** + * This event type indicates that the app needs to request keys from a + * license server. The request message data is obtained using getKeyRequest. + */ + KEY_NEEDED, + /** + * This event type indicates that the licensed usage duration for keys in a + * session has expired. The keys are no longer valid. + */ + KEY_EXPIRED, + /** + * This event may indicate some specific vendor-defined condition, see your + * DRM provider documentation for details. + */ + VENDOR_DEFINED, + /** + * This event indicates that a session opened by the app has been reclaimed + * by the resource manager. + */ + SESSION_RECLAIMED, +} diff --git a/drm/aidl/android/hardware/drm/HdcpLevel.aidl b/drm/aidl/android/hardware/drm/HdcpLevel.aidl new file mode 100644 index 0000000000..3497b78431 --- /dev/null +++ b/drm/aidl/android/hardware/drm/HdcpLevel.aidl @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * HDCP specifications are defined by Digital Content Protection LLC (DCP). + * "HDCP Specification Rev. 2.3 Interface Independent Adaptation" + * "HDCP 2.3 on HDMI Specification" + */ +@VintfStability +@Backing(type="int") +enum HdcpLevel { + /** + * Unable to determine the HDCP level + */ + HDCP_UNKNOWN, + /** + * No HDCP, output is unprotected + */ + HDCP_NONE, + /** + * HDCP version 1.0 + */ + HDCP_V1, + /** + * HDCP version 2.0 Type 1. + */ + HDCP_V2, + /** + * HDCP version 2.1 Type 1. + */ + HDCP_V2_1, + /** + * HDCP version 2.2 Type 1. + */ + HDCP_V2_2, + /** + * No digital output, implicitly secure + */ + HDCP_NO_OUTPUT, + /** + * HDCP version 2.3 Type 1. + */ + HDCP_V2_3, +} diff --git a/drm/aidl/android/hardware/drm/HdcpLevels.aidl b/drm/aidl/android/hardware/drm/HdcpLevels.aidl new file mode 100644 index 0000000000..cd4642ba42 --- /dev/null +++ b/drm/aidl/android/hardware/drm/HdcpLevels.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.HdcpLevel; + +@VintfStability +parcelable HdcpLevels { + /** The lowest HDCP level for any connected displays. */ + HdcpLevel connectedLevel; + + /** The highest HDCP level that can be supported by the device. */ + HdcpLevel maxLevel; +} diff --git a/drm/aidl/android/hardware/drm/ICryptoFactory.aidl b/drm/aidl/android/hardware/drm/ICryptoFactory.aidl new file mode 100644 index 0000000000..202bd3dbfe --- /dev/null +++ b/drm/aidl/android/hardware/drm/ICryptoFactory.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.Uuid; + +/** + * ICryptoFactory is the main entry point for interacting with a vendor's + * crypto HAL to create crypto plugins. + + * Crypto plugins create crypto sessions which are used by a codec to decrypt + * protected video content. + */ +@VintfStability +interface ICryptoFactory { + /** + * Create a crypto plugin for the specified uuid and scheme-specific + * initialization data. + * + * @param uuid uniquely identifies the drm scheme. See + * http://dashif.org/identifiers/protection for uuid assignments + * + * @param initData scheme-specific init data. + * + * @return A crypto plugin instance if successful, or null if not created. + */ + @nullable android.hardware.drm.ICryptoPlugin createPlugin( + in Uuid uuid, in byte[] initData); + + /** + * Determine if a crypto scheme is supported by this HAL. + * + * @param uuid identifies the crypto scheme in question + * @return must be true only if the scheme is supported + */ + boolean isCryptoSchemeSupported(in Uuid uuid); +} diff --git a/drm/aidl/android/hardware/drm/ICryptoPlugin.aidl b/drm/aidl/android/hardware/drm/ICryptoPlugin.aidl new file mode 100644 index 0000000000..80a63dfdae --- /dev/null +++ b/drm/aidl/android/hardware/drm/ICryptoPlugin.aidl @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.common.Ashmem; +import android.hardware.drm.DecryptResult; +import android.hardware.drm.DestinationBuffer; +import android.hardware.drm.LogMessage; +import android.hardware.drm.Mode; +import android.hardware.drm.Pattern; +import android.hardware.drm.SharedBuffer; +import android.hardware.drm.Status; +import android.hardware.drm.SubSample; + +/** + * ICryptoPlugin is the HAL for vendor-provided crypto plugins. + * + * It allows crypto sessions to be opened and operated on, to + * load crypto keys for a codec to decrypt protected video content. + */ +@VintfStability +interface ICryptoPlugin { + /** + * Decrypt an array of subsamples from the source memory buffer to the + * destination memory buffer. + * + * @param secure a flag to indicate if a secure decoder is being used. + * This enables the plugin to configure buffer modes to work + * consistently with a secure decoder. + * @param the keyId for the key that is used to do the decryption. The + * keyId refers to a key in the associated MediaDrm instance. + * @param iv the initialization vector to use + * @param mode the crypto mode to use + * @param pattern the crypto pattern to use + * @param subSamples a vector of subsamples indicating the number + * of clear and encrypted bytes to process. This allows the decrypt + * call to operate on a range of subsamples in a single call + * @param source the input buffer for the decryption + * @param offset the offset of the first byte of encrypted data from + * the base of the source buffer + * @param destination the output buffer for the decryption + * + * @return DecryptResult parcelable + * Implicit error codes: + * + ERROR_DRM_CANNOT_HANDLE in other failure cases + * + ERROR_DRM_DECRYPT if the decrypt operation fails + * + ERROR_DRM_FRAME_TOO_LARGE if the frame being decrypted into + * the secure output buffer exceeds the size of the buffer + * + ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION if required output + * protections are not active + * + ERROR_DRM_INSUFFICIENT_SECURITY if the security level of the + * device is not sufficient to meet the requirements in + * the license policy + * + ERROR_DRM_INVALID_STATE if the device is in a state where it + * is not able to perform decryption + * + ERROR_DRM_LICENSE_EXPIRED if the license keys have expired + * + ERROR_DRM_NO_LICENSE if no license keys have been loaded + * + ERROR_DRM_RESOURCE_BUSY if the resources required to perform + * the decryption are not available + * + ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not + * opened + */ + DecryptResult decrypt(in boolean secure, in byte[] keyId, in byte[] iv, in Mode mode, + in Pattern pattern, in SubSample[] subSamples, in SharedBuffer source, in long offset, + in DestinationBuffer destination); + + /** + * Get OEMCrypto or plugin error messages. + * + * @return LogMessages + * Implicit error codes: + * + GENERAL_OEM_ERROR on OEM-provided, low-level component failures; + * + GENERAL_PLUGIN_ERROR on unexpected plugin-level errors. + */ + List getLogMessages(); + + /** + * Notify a plugin of the currently configured resolution. + * + * @param width - the display resolutions's width + * @param height - the display resolution's height + */ + void notifyResolution(in int width, in int height); + + /** + * Check if the specified mime-type requires a secure decoder + * component. + * + * @param mime The content mime-type + * @return must be true only if a secure decoder is required + * for the specified mime-type + */ + boolean requiresSecureDecoderComponent(in String mime); + + /** + * Associate a mediadrm session with this crypto session. + * + * @param sessionId the MediaDrm session ID to associate with + * this crypto session + * @return (implicit) the status of the call, status can be: + * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened, or + * ERROR_DRM_CANNOT_HANDLE if the operation is not supported by + * the drm scheme + */ + void setMediaDrmSession(in byte[] sessionId); + + /** + * Set a shared memory base for subsequent decrypt operations. + * The buffer base is mmaped from a ParcelFileDesciptor in Ashmem + * which maps shared memory in the HAL module. + * After the shared buffer base is established, the decrypt() method + * receives SharedBuffer instances which specify the buffer address range + * for decrypt source and destination addresses. + * + * There can be multiple shared buffers per crypto plugin. The buffers + * are distinguished by the bufferId. + * + * @param base the base of the memory buffer identified by + * bufferId + * @param bufferId identifies the specific shared buffer for which + * the base is being set. + */ + void setSharedBufferBase(in Ashmem base, in int bufferId); +} diff --git a/drm/aidl/android/hardware/drm/IDrmFactory.aidl b/drm/aidl/android/hardware/drm/IDrmFactory.aidl new file mode 100644 index 0000000000..b9622a427b --- /dev/null +++ b/drm/aidl/android/hardware/drm/IDrmFactory.aidl @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.SecurityLevel; +import android.hardware.drm.Uuid; + +/** + * IDrmFactory is the main entry point for interacting with a vendor's + * drm HAL to create drm plugin instances. A drm plugin instance + * creates drm sessions which are used to obtain keys for a crypto + * session so it can decrypt protected video content. + */ +@VintfStability +interface IDrmFactory { + /** + * Create a drm plugin instance for the specified uuid and + * scheme-specific initialization data. + * + * @param uuid uniquely identifies the drm scheme. See + * http://dashif.org/identifiers/protection for uuid assignments + * @param appPackageName identifies the package name of the calling + * application. + * + * @return A DRM plugin instance if successful, or null if not created. + * Implicit error codes: + * + ERROR_DRM_CANNOT_HANDLE if the plugin cannot be created. + */ + @nullable android.hardware.drm.IDrmPlugin createPlugin( + in Uuid uuid, in String appPackageName); + + /** + * Return vector of uuids identifying crypto schemes supported by + * this HAL. + * + * @return List of uuids for which isCryptoSchemeSupported is true; + * each uuid can be used as input to createPlugin. + */ + List getSupportedCryptoSchemes(); + + /** + * Determine if the HAL factory is able to construct plugins that + * support a given media container format specified by mimeType + * + * @param mimeType identifies the mime type in question + * + * @return must be true only if the scheme is supported + */ + boolean isContentTypeSupported(in String mimeType); + + /** + * Determine if a specific security level is supported by the device. + * + * @param uuid identifies the crypto scheme in question + * @param mimeType identifies the mime type in question + * @param securityLevel specifies the security level required + * + * @return must be true only if the scheme is supported + */ + boolean isCryptoSchemeSupported( + in Uuid uuid, in String mimeType, in SecurityLevel securityLevel); +} diff --git a/drm/aidl/android/hardware/drm/IDrmPlugin.aidl b/drm/aidl/android/hardware/drm/IDrmPlugin.aidl new file mode 100644 index 0000000000..e649f264ea --- /dev/null +++ b/drm/aidl/android/hardware/drm/IDrmPlugin.aidl @@ -0,0 +1,755 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.DrmMetricGroup; +import android.hardware.drm.HdcpLevels; +import android.hardware.drm.IDrmPluginListener; +import android.hardware.drm.KeySetId; +import android.hardware.drm.KeyRequest; +import android.hardware.drm.KeyStatus; +import android.hardware.drm.KeyType; +import android.hardware.drm.KeyValue; +import android.hardware.drm.LogMessage; +import android.hardware.drm.NumberOfSessions; +import android.hardware.drm.OfflineLicenseState; +import android.hardware.drm.OpaqueData; +import android.hardware.drm.ProvideProvisionResponseResult; +import android.hardware.drm.ProvisionRequest; +import android.hardware.drm.SecureStop; +import android.hardware.drm.SecureStopId; +import android.hardware.drm.SecurityLevel; + +/** + * IDrmPlugin is used to interact with a specific drm plugin that was + * created by IDrmFactory::createPlugin. + * + * A drm plugin provides methods for obtaining drm keys to be used by a codec + * to decrypt protected video content. + */ +@VintfStability +interface IDrmPlugin { + /** + * Close a session on the DrmPlugin object + * + * @param sessionId the session id the call applies to + * + * @return (implicit) the status of the call: + * BAD_VALUE if the sessionId is invalid + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the session cannot be closed. + * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + */ + void closeSession(in byte[] sessionId); + + /** + * Decrypt the provided input buffer with the cipher algorithm + * specified by setCipherAlgorithm and the key selected by keyId, + * and return the decrypted data. + * + * @param sessionId the session id the call applies to + * @param keyId the ID of the key to use for decryption + * @param input the input data to decrypt + * @param iv the initialization vector to use for decryption + * + * @return decrypted output buffer + * Implicit error codes: + * + BAD_VALUE if the sessionId is invalid + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the decrypt operation cannot be performed. + * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + */ + byte[] decrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv); + + /** + * Encrypt the provided input buffer with the cipher algorithm specified by + * setCipherAlgorithm and the key selected by keyId, and return the + * encrypted data. + * + * @param sessionId the session id the call applies to + * @param keyId the ID of the key to use for encryption + * @param input the input data to encrypt + * @param iv the initialization vector to use for encryption + * + * @return encrypted output buffer + * Implicit error codes: + * + BAD_VALUE if the sessionId is invalid + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the encrypt operation cannot be performed. + * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + */ + byte[] encrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv); + + /** + * Return the currently negotiated and max supported HDCP levels. + * + * The current level is based on the display(s) the device is connected to. + * If multiple HDCP-capable displays are simultaneously connected to + * separate interfaces, this method returns the lowest negotiated HDCP level + * of all interfaces. + * + * The maximum HDCP level is the highest level that can potentially be + * negotiated. It is a constant for any device, i.e. it does not depend on + * downstream receiving devices that could be connected. For example, if + * the device has HDCP 1.x keys and is capable of negotiating HDCP 1.x, but + * does not have HDCP 2.x keys, then the maximum HDCP capability would be + * reported as 1.x. If multiple HDCP-capable interfaces are present, it + * indicates the highest of the maximum HDCP levels of all interfaces. + * + * This method should only be used for informational purposes, not for + * enforcing compliance with HDCP requirements. Trusted enforcement of HDCP + * policies must be handled by the DRM system. + * + * @return HdcpLevels parcelable + * Implicit error codes: + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the HDCP level cannot be queried + */ + HdcpLevels getHdcpLevels(); + + /** + * A key request/response exchange occurs between the app and a License + * Server to obtain the keys required to decrypt the content. + * getKeyRequest() is used to obtain an opaque key request blob that is + * delivered to the license server. + * + * @param scope either a sessionId or a keySetId, depending on the + * specified keyType. When the keyType is OFFLINE or STREAMING, scope + * must be set to the sessionId the keys will be provided to. When the + * keyType is RELEASE, scope must be set to the keySetId of the keys + * being released. + * @param initData container-specific data, its meaning is interpreted + * based on the mime type provided in the mimeType parameter. It could + * contain, for example, the content ID, key ID or other data obtained + * from the content metadata that is required to generate the key + * request. initData must be empty when keyType is RELEASE. + * @param mimeType identifies the mime type of the content + * @param keyType specifies if the keys are to be used for streaming, + * offline or a release + * @param optionalParameters included in the key request message to + * allow a client application to provide additional message parameters + * to the server. + * + * @return KeyRequest parcelable + * Implicit error codes: + * + BAD_VALUE if any parameters are invalid + * + ERROR_DRM_CANNOT_HANDLE if getKeyRequest is not supported at + * the time of the call + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * a key request cannot be generated + * + ERROR_DRM_NOT_PROVISIONED if the device requires provisioning + * before it is able to generate a key request + * + ERROR_DRM_RESOURCE_CONTENTION if client applications using the + * hal are temporarily exceeding the available crypto resources + * such that a retry of the operation is likely to succeed + * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + */ + KeyRequest getKeyRequest(in byte[] scope, in byte[] initData, in String mimeType, + in KeyType keyType, in KeyValue[] optionalParameters); + + /** + * Get Plugin error messages. + * + * @return LogMessages + * Implicit error codes: + * + GENERAL_OEM_ERROR on OEM-provided, low-level component failures; + * + GENERAL_PLUGIN_ERROR on unexpected plugin-level errors. + */ + List getLogMessages(); + + /** + * Returns the plugin-specific metrics. Multiple metric groups may be + * returned in one call to getMetrics(). The scope and definition of the + * metrics is defined by the plugin. + * + * @return collection of metric groups provided by the plugin + * Implicit error codes: + * + ERROR_DRM_INVALID_STATE if the metrics are not available to be + * returned. + */ + List getMetrics(); + + /** + * Return the current number of open sessions and the maximum number of + * sessions that may be opened simultaneously among all DRM instances + * for the active DRM scheme. + * + * @return NumberOfSessions parcelable + * Implicit error codes: + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * number of sessions cannot be queried + */ + NumberOfSessions getNumberOfSessions(); + + /** + * The keys in an offline license allow protected content to be + * played even if the device is not connected to a network. + * Offline licenses are stored on the device after a key + * request/response exchange when the key request KeyType is + * OFFLINE. Normally each app is responsible for keeping track of + * the KeySetIds it has created. In some situations however, it + * will be necessary to request the list of stored offline license + * KeySetIds. If an app loses the KeySetId for any stored licenses + * that it created, for example, it must be able to recover the + * stored KeySetIds so those licenses will be removed when they + * expire or when the app is uninstalled. + * + * This method returns a list of the KeySetIds for all offline + * licenses. The offline license KeySetId allows an app to query + * the status of an offline license or remove it. + * + * @return list of keySetIds + * Implicit error codes: + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * KeySetIds can't be returned + */ + List getOfflineLicenseKeySetIds(); + + /** + * Request the state of an offline license. An offline license must + * be usable or inactive. The keys in a usable offline license are + * available for decryption. When the offline license state is + * inactive, the keys have been marked for release using + * getKeyRequest with KeyType RELEASE but the key response has not + * been received. The keys in an inactive offline license are not + * usable for decryption. + * + * @param keySetId the id of the offline license + * + * @return The offline license state, UNKNOWN, USABLE or INACTIVE. + * Implicit error codes: + * + BAD_VALUE if the license is not found + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * offline license state can't be queried + */ + OfflineLicenseState getOfflineLicenseState(in KeySetId keySetId); + + /** + * Read a byte array property value given the property name. + * See getPropertyString. + * + * @param propertyName the name of the property + * + * @return property value bye array + * Implicit error codes: + * + BAD_VALUE if the property name is invalid + * + ERROR_DRM_CANNOT_HANDLE if the property is not supported + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * property cannot be obtained + */ + byte[] getPropertyByteArray(in String propertyName); + + /** + * A drm scheme can have properties that are settable and readable + * by an app. There are a few forms of property access methods, + * depending on the data type of the property. + * + * Property values defined by the public API are: + * "vendor" [string] identifies the maker of the drm scheme + * "version" [string] identifies the version of the drm scheme + * "description" [string] describes the drm scheme + * 'deviceUniqueId' [byte array] The device unique identifier is + * established during device provisioning and provides a means of + * uniquely identifying each device. + * + * Since drm scheme properties may vary, additional field names may be + * defined by each DRM vendor. Refer to your DRM provider documentation + * for definitions of its additional field names. + * + * Read a string property value given the property name. + * + * @param propertyName the name of the property + * + * @return the property value string. + * Implicit error codes: + * + BAD_VALUE if the property name is invalid + * + ERROR_DRM_CANNOT_HANDLE if the property is not supported + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * property cannot be obtained + */ + String getPropertyString(in String propertyName); + + /** + * A provision request/response exchange occurs between the app + * and a provisioning server to retrieve a device certificate. + * getProvisionRequest is used to obtain an opaque provisioning + * request blob that is delivered to the provisioning server. + * + * @param certificateType the type of certificate requested, e.g. "X.509" + * @param certificateAuthority identifies the certificate authority. + * A certificate authority (CA) is an entity which issues digital + * certificates for use by other parties. It is an example of a + * trusted third party. + * + * @return ProvisionRequest parcelable + * Implicit error codes: + * + ERROR_DRM_CANNOT_HANDLE if the drm scheme does not require + * provisioning + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the provision request cannot be generated + * + ERROR_DRM_RESOURCE_CONTENTION if client applications using + * the hal are temporarily exceeding the available crypto + * resources such that a retry of the operation is likely + * to succeed + */ + ProvisionRequest getProvisionRequest( + in String certificateType, in String certificateAuthority); + + /** + * Get all secure stops by secure stop ID + * + * @param secureStopId the ID of the secure stop to return. + * The secure stop ID is delivered by the key server + * as part of the key response and must also be known by the app. + * + * @return secure stop opaque object. + * Implicit error codes: + * + BAD_VALUE if the secureStopId is invalid + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the secure stop cannot be returned + */ + SecureStop getSecureStop(in SecureStopId secureStopId); + + /** + * Get the IDs of all secure stops on the device + * + * @return list of secure stops IDs. + * Implicit error codes: + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the secure stop IDs list cannot be returned + */ + List getSecureStopIds(); + + /** + * SecureStop is a way of enforcing the concurrent stream limit per + * subscriber. + * + * It can securely monitor the lifetime of sessions across device reboots + * by periodically persisting the session lifetime status in secure + * storage. + * + * A signed version of the sessionID is written to persistent storage on the + * device when each MediaCrypto object is created and periodically during + * playback. The sessionID is signed by the device private key to prevent + * tampering. + * + * When playback is completed the session is destroyed, and the secure + * stops are queried by the app. The app then delivers the secure stop + * message to a server which verifies the signature to confirm that the + * session and its keys have been removed from the device. The persisted + * record on the device is removed after receiving and verifying the + * signed response from the server. + * + * Get all secure stops on the device + * + * @return list of the opaque secure stop objects. + * Implicit error codes: + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the secure stops cannot be returned + */ + List getSecureStops(); + + /** + * Return the current security level of a session. A session has an initial + * security level determined by the robustness of the DRM system's + * implementation on the device. + * + * @param sessionId the session id the call applies to + * + * @return the current security level for the session. + * Implicit error codes: + * + BAD_VALUE if the sessionId is invalid + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the security level cannot be queried + * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + */ + SecurityLevel getSecurityLevel(in byte[] sessionId); + + /** + * Open a new session at a requested security level. The security level + * represents the robustness of the device's DRM implementation. By default, + * sessions are opened at the native security level of the device which is + * the maximum level that can be supported. Overriding the security level is + * necessary when the decrypted frames need to be manipulated, such as for + * image compositing. The security level parameter must be equal to or lower + * than the native level. If the requested level is not supported, the next + * lower supported security level must be set. The level can be queried + * using {@link #getSecurityLevel}. A session ID is returned. + * + * @param level the requested security level + * + * @return sessionId + */ + byte[] openSession(in SecurityLevel securityLevel); + + /** + * After a key response is received by the app, it is provided to the + * Drm plugin using provideKeyResponse. + * + * @param scope may be a sessionId or a keySetId depending on the + * type of the response. Scope should be set to the sessionId + * when the response is for either streaming or offline key requests. + * Scope should be set to the keySetId when the response is for + * a release request. + * @param response the response from the key server that is being + * provided to the drm HAL. + * + * @return a keySetId that can be used to later restore the keys to a new + * session with the method restoreKeys when the response is for an + * offline key request. + * Implicit error codes: + * + BAD_VALUE if any parameters are invalid + * + ERROR_DRM_CANNOT_HANDLE if provideKeyResponse is not supported + * at the time of the call + * + ERROR_DRM_DEVICE_REVOKED if the device has been disabled by + * the license policy + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where + * a key response cannot be handled. + * + ERROR_DRM_NOT_PROVISIONED if the device requires provisioning + * before it can handle the key response + * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + */ + KeySetId provideKeyResponse(in byte[] scope, in byte[] response); + + /** + * After a provision response is received by the app from a provisioning + * server, it is provided to the Drm HAL using provideProvisionResponse. + * The HAL implementation must receive the provision request and + * store the provisioned credentials. + * + * @param response the opaque provisioning response received by the + * app from a provisioning server. + * + * @return ProvideProvisionResponseResult parcelable, which contains + * the public certificate and encrypted private key that can be + * used by signRSA to compute an RSA signature on a message. + * Implicit error codes: + * + BAD_VALUE if any parameters are invalid + * + ERROR_DRM_DEVICE_REVOKED if the device has been disabled by + * the license policy + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * provision response cannot be handled + */ + ProvideProvisionResponseResult provideProvisionResponse(in byte[] response); + + /** + * Request an informative description of the license for the session. + * The status is in the form of {name, value} pairs. Since DRM license + * policies vary by vendor, the specific status field names are + * determined by each DRM vendor. Refer to your DRM provider + * documentation for definitions of the field names for a particular + * drm scheme. + * + * @param sessionId the session id the call applies to + * + * @return a list of name value pairs describing the license. + * Implicit error codes: + * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + * + BAD_VALUE if any parameters are invalid + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * key status cannot be queried. + */ + List queryKeyStatus(in byte[] sessionId); + + /** + * Release all secure stops on the device + * + * @return (implicit) the status of the call: + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the secure stops cannot be released. + */ + void releaseAllSecureStops(); + + /** + * Release a secure stop by secure stop ID + * + * @param secureStopId the ID of the secure stop to release. + * The secure stop ID is delivered by the key server as + * part of the key response and must also be known by the app. + * + * @return (implicit) the status of the call: + * BAD_VALUE if the secureStopId is invalid + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the secure stop cannot be released. + */ + void releaseSecureStop(in SecureStopId secureStopId); + + /** + * Release secure stops given a release message from the key server + * + * @param ssRelease the secure stop release message identifying + * one or more secure stops to release. ssRelease is opaque, + * it is passed directly from a DRM license server through + * the app and media framework to the vendor HAL module. + * The format and content of ssRelease must be defined by the + * DRM scheme being implemented according to this HAL. + * The DRM scheme can be identified by its UUID which + * can be queried using IDrmFactory::isCryptoSchemeSupported. + * + * @return (implicit) the status of the call: + * BAD_VALUE if ssRelease is invalid + * ERROR_DRM_INVALID_STATE if the HAL is in a state wherei + * the secure stop cannot be released. + */ + void releaseSecureStops(in OpaqueData ssRelease); + + /** + * Remove all secure stops on the device without requiring a secure + * stop release response message from the key server. + * + * @return (implicit) the status of the call: + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the secure stops cannot be removed. + */ + void removeAllSecureStops(); + + /** + * Remove the current keys from a session + * + * @param sessionId the session id the call applies to + * + * @return (implicit) the status of the call: + * BAD_VALUE if the sessionId is invalid + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the keys cannot be removed. + * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + */ + void removeKeys(in byte[] sessionId); + + /** + * Normally offline licenses are released using a key + * request/response exchange using getKeyRequest where the KeyType + * is RELEASE, followed by provideKeyResponse. This allows the + * server to cryptographically confirm that the license has been + * removed and then adjust the count of offline licenses allocated + * to the device. + *

+ * In some exceptional situations it will be necessary to directly + * remove offline licenses without notifying the server, which is + * performed by this method. + * + * @param keySetId the id of the offline license to remove + * + * @return (implicit) the status of the call: + * BAD_VALUE if the license is not found + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the KeySetIds can't be removed. + */ + void removeOfflineLicense(in KeySetId keySetId); + + /** + * Remove a secure stop given its secure stop ID, without requiring + * a secure stop release response message from the key server. + * + * @param secureStopId the ID of the secure stop to release. + * + * @return the status of the call: + * BAD_VALUE if the secureStopId is invalid + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the secure stop cannot be removed. + */ + void removeSecureStop(in SecureStopId secureStopId); + + /** + * Check if the specified mime-type & security level require a secure decoder + * component. + * + * @param mime The content mime-type + * @param level the requested security level + * + * @return must be true if and only if a secure decoder is + * required for the specified mime-type & security level + */ + boolean requiresSecureDecoder(in String mime, in SecurityLevel level); + + /** + * Check if the specified mime-type requires a secure decoder component + * at the highest security level supported on the device. + * + * @param mime The content mime-type + * + * @return must be true if and only if a secure decoder is required + * for the specified mime-type + */ + boolean requiresSecureDecoderDefault(in String mime); + + /** + * Restore persisted offline keys into a new session + * + * @param sessionId the session id the call applies to + * @param keySetId identifies the keys to load, obtained from + * a prior call to provideKeyResponse(). + * + * @return (implicit) the status of the call: + * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + * BAD_VALUE if any parameters are invalid + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * keys cannot be restored. + */ + void restoreKeys(in byte[] sessionId, in KeySetId keySetId); + + /** + * The following methods implement operations on a CryptoSession to support + * encrypt, decrypt, sign verify operations on operator-provided + * session keys. + * + * + * Set the cipher algorithm to be used for the specified session. + * + * @param sessionId the session id the call applies to + * @param algorithm the algorithm to use. The string conforms to JCA + * Standard Names for Cipher Transforms and is case insensitive. An + * example algorithm is "AES/CBC/PKCS5Padding". + * + * @return (implicit) the status of the call: + * BAD_VALUE if any parameters are invalid + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the algorithm cannot be set. + * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened` + */ + void setCipherAlgorithm(in byte[] sessionId, in String algorithm); + + /** + * Plugins call the following methods to deliver events to the + * java app. + * + * + * Set a listener for a drm session. This allows the drm HAL to + * make asynchronous calls back to the client of IDrm. + * + * @param listener instance of IDrmPluginListener to receive the events + */ + void setListener(in IDrmPluginListener listener); + + /** + * Set the MAC algorithm to be used for computing hashes in a session. + * + * @param sessionId the session id the call applies to + * @param algorithm the algorithm to use. The string conforms to JCA + * Standard Names for Mac Algorithms and is case insensitive. An example MAC + * algorithm string is "HmacSHA256". + * + * @return (implicit) the status of the call: + * BAD_VALUE if any parameters are invalid + * ERROR_DRM_INVALID_STATE if the HAL is in a state where + * the algorithm cannot be set. + * ERROR_DRM_SESSION_NOT_OPENED if the session is not opened` + */ + void setMacAlgorithm(in byte[] sessionId, in String algorithm); + + /** + * Set playback id of a drm session. The playback id can be used to join drm session metrics + * with metrics from other low level media components, e.g. codecs, or metrics from the high + * level player. + * + * @param sessionId drm session id + * @param playbackId high level playback id + * + * @return (implicit) the status of the call: + * ERROR_DRM_SESSION_NOT_OPENED if the drm session cannot be found + */ + void setPlaybackId(in byte[] sessionId, in String playbackId); + + /** + * Write a property byte array value given the property name + * + * @param propertyName the name of the property + * @param value the value to write + * + * @return (implicit) the status of the call: + * BAD_VALUE if the property name is invalid + * ERROR_DRM_CANNOT_HANDLE if the property is not supported + * ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * property cannot be set + */ + void setPropertyByteArray(in String propertyName, in byte[] value); + + /** + * Write a property string value given the property name + * + * @param propertyName the name of the property + * @param value the value to write + * + * @return (implicit) status of the call: + * BAD_VALUE if the property name is invalid + * ERROR_DRM_CANNOT_HANDLE if the property is not supported + * ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * property cannot be set + */ + void setPropertyString(in String propertyName, in String value); + + /** + * Compute a signature over the provided message using the mac algorithm + * specified by setMacAlgorithm and the key selected by keyId and return + * the signature. + * + * @param sessionId the session id the call applies to + * @param keyId the ID of the key to use for decryption + * @param message the message to compute a signature over + * + * @return signature computed over the message + * Implicit error codes: + * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + * + BAD_VALUE if any parameters are invalid + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * sign operation cannot be performed. + */ + byte[] sign(in byte[] sessionId, in byte[] keyId, in byte[] message); + + /** + * Compute an RSA signature on the provided message using the specified + * algorithm. + * + * @param sessionId the session id the call applies to + * @param algorithm the signing algorithm, such as "RSASSA-PSS-SHA1" + * or "PKCS1-BlockType1" + * @param message the message to compute the signature on + * @param wrappedKey the private key returned during provisioning as + * returned by provideProvisionResponse. + * + * @return signature computed over the message + * Implicit error codes: + * + BAD_VALUE if any parameters are invalid + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * signRSA operation operation cannot be performed + * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + */ + byte[] signRSA( + in byte[] sessionId, in String algorithm, in byte[] message, + in byte[] wrappedkey); + + /** + * Compute a hash of the provided message using the mac algorithm specified + * by setMacAlgorithm and the key selected by keyId, and compare with the + * expected result. + * + * @param sessionId the session id the call applies to + * @param keyId the ID of the key to use for decryption + * @param message the message to compute a hash of + * @param signature the signature to verify + * + * @return true if the signature is verified positively, false otherwise. + * Implicit error codes: + * + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened + * + BAD_VALUE if any parameters are invalid + * + ERROR_DRM_INVALID_STATE if the HAL is in a state where the + * verify operation cannot be performed. + */ + boolean verify( + in byte[] sessionId, in byte[] keyId, in byte[] message, + in byte[] signature); +} diff --git a/drm/aidl/android/hardware/drm/IDrmPluginListener.aidl b/drm/aidl/android/hardware/drm/IDrmPluginListener.aidl new file mode 100644 index 0000000000..d52da66742 --- /dev/null +++ b/drm/aidl/android/hardware/drm/IDrmPluginListener.aidl @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.EventType; +import android.hardware.drm.KeyStatus; + +/** + * IDrmPluginListener is a listener interface for Drm events sent from an + * IDrmPlugin instance. + */ +@VintfStability +interface IDrmPluginListener { + /** + * Legacy event sending method, it sends events of various types using a + * single overloaded set of parameters. This form is deprecated. + * + * @param eventType the type of the event + * @param sessionId identifies the session the event originated from + * @param data event-specific data blob + */ + oneway void onEvent(in EventType eventType, in byte[] sessionId, in byte[] data); + + /** + * Send a license expiration update to the listener. The expiration + * update indicates how long the current keys are valid before they + * need to be renewed. + * + * @param sessionId identifies the session the event originated from + * @param expiryTimeInMS the time when the keys need to be renewed. + * The time is in milliseconds, relative to the Unix epoch. A time + * of 0 indicates that the keys never expire. + */ + oneway void onExpirationUpdate(in byte[] sessionId, in long expiryTimeInMS); + + /** + * Send a keys change event to the listener. The keys change event + * indicates the status of each key in the session. Keys can be + * indicated as being usable, expired, outputnotallowed or statuspending. + * + * @param sessionId identifies the session the event originated from + * @param keyStatusList indicates the status for each key ID in the + * session. + * @param hasNewUsableKey indicates if the event includes at least one + * key that has become usable. + */ + oneway void onKeysChange( + in byte[] sessionId, in KeyStatus[] keyStatusList, in boolean hasNewUsableKey); + + /** + * Some device crypto hardware is incapable of retaining crypto + * session state across suspend and resume cycles. A + * SessionLostState event must be signaled when a session has + * become invalid for this reason. This event must not be used to + * indicate a failure in the crypto system. Closing the session + * and opening a new one must allow the application to resume + * normal use of the drm hal module. + * + * @param sessionId identifies the session that has been invalidated + */ + oneway void onSessionLostState(in byte[] sessionId); +} diff --git a/drm/aidl/android/hardware/drm/KeyRequest.aidl b/drm/aidl/android/hardware/drm/KeyRequest.aidl new file mode 100644 index 0000000000..0c732055f2 --- /dev/null +++ b/drm/aidl/android/hardware/drm/KeyRequest.aidl @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.KeyRequestType; + +@VintfStability +parcelable KeyRequest { + /** The opaque key request blob. */ + byte[] request; + + /** + * Enumerated type: + * INITIAL - the first key request for a license + * NONE - indicates that no request is needed because the keys + * are already loaded + * RENEWAL - is a subsequent key request used to refresh the + * keys in a license + * RELEASE - indicates keys are being released + * UPDATE - indicates that the keys need to be refetched after + * the initial license request + */ + KeyRequestType requestType; + + /** + * The URL that the request may be sent to, + * if provided by the drm HAL. The app can choose to + * override this URL. If the HAL implementation does not provide + * a defaultUrl, the returned string must be empty. + */ + String defaultUrl; +} diff --git a/drm/aidl/android/hardware/drm/KeyRequestType.aidl b/drm/aidl/android/hardware/drm/KeyRequestType.aidl new file mode 100644 index 0000000000..3a603ff6c8 --- /dev/null +++ b/drm/aidl/android/hardware/drm/KeyRequestType.aidl @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * An app determines the type of a key request returned from getKeyRequest. + */ +@VintfStability +@Backing(type="int") +enum KeyRequestType { + /** + * Key request type is for an initial license request + */ + INITIAL, + /** + * Key request type is for license renewal. Renewal requests are used + * to extend the validity period for streaming keys. + */ + RENEWAL, + /** + * Key request type is a release. A key release causes offline keys + * to become available for streaming. + */ + RELEASE, + /** + * Key request type is unknown due to some error condition. + */ + UNKNOWN, + /** + * Keys are already loaded. No key request is needed. + */ + NONE, + /** + * Keys have previously been loaded. An additional (non-renewal) license + * request is needed. + */ + UPDATE, +} diff --git a/drm/aidl/android/hardware/drm/KeySetId.aidl b/drm/aidl/android/hardware/drm/KeySetId.aidl new file mode 100644 index 0000000000..be0ce0efa8 --- /dev/null +++ b/drm/aidl/android/hardware/drm/KeySetId.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +parcelable KeySetId { + byte[] keySetId; +} diff --git a/drm/aidl/android/hardware/drm/KeyStatus.aidl b/drm/aidl/android/hardware/drm/KeyStatus.aidl new file mode 100644 index 0000000000..16e042a147 --- /dev/null +++ b/drm/aidl/android/hardware/drm/KeyStatus.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.KeyStatusType; + +/** + * Used by sendKeysChange to report the usability status of each key + * to the app. + */ +@VintfStability +parcelable KeyStatus { + byte[] keyId; + KeyStatusType type; +} diff --git a/drm/aidl/android/hardware/drm/KeyStatusType.aidl b/drm/aidl/android/hardware/drm/KeyStatusType.aidl new file mode 100644 index 0000000000..6902d8708c --- /dev/null +++ b/drm/aidl/android/hardware/drm/KeyStatusType.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +@Backing(type="int") +enum KeyStatusType { + /** + * The key is currently usable to decrypt media data. + */ + USABLE, + /** + * The key is no longer usable to decrypt media data because its expiration + * time has passed. + */ + EXPIRED, + /** + * The key is not currently usable to decrypt media data because its output + * requirements cannot currently be met. + */ + OUTPUTNOTALLOWED, + /** + * The status of the key is not yet known and is being determined. + */ + STATUSPENDING, + /** + * The key is not currently usable to decrypt media data because of an + * internal error in processing unrelated to input parameters. + */ + INTERNALERROR, + /** + * The key is not yet usable to decrypt media because the start + * time is in the future. The key must become usable when + * its start time is reached. + */ + USABLEINFUTURE, +} diff --git a/drm/aidl/android/hardware/drm/KeyType.aidl b/drm/aidl/android/hardware/drm/KeyType.aidl new file mode 100644 index 0000000000..78b4d8369c --- /dev/null +++ b/drm/aidl/android/hardware/drm/KeyType.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +@Backing(type="int") +enum KeyType { + /** + * Drm keys can be for offline content or for online streaming. + * Offline keys are persisted on the device and may be used when the device + * is disconnected from the network. + */ + OFFLINE, + /** + * Keys for streaming are not persisted and require the device to be + * connected to the network for periodic renewal. + */ + STREAMING, + /** + * The Release type is used to request that offline keys be no longer + * restricted to offline use. + */ + RELEASE, +} diff --git a/drm/aidl/android/hardware/drm/KeyValue.aidl b/drm/aidl/android/hardware/drm/KeyValue.aidl new file mode 100644 index 0000000000..e26781b58b --- /dev/null +++ b/drm/aidl/android/hardware/drm/KeyValue.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +parcelable KeyValue { + String key; + String value; +} diff --git a/drm/aidl/android/hardware/drm/LogMessage.aidl b/drm/aidl/android/hardware/drm/LogMessage.aidl new file mode 100644 index 0000000000..8ac1ced585 --- /dev/null +++ b/drm/aidl/android/hardware/drm/LogMessage.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 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.drm; + +import android.hardware.drm.LogPriority; + +/** + * Returned by getLogMessages to report error diagnostics to the + * app. + * + * The |message| field is for informational purposes only, and + * NOT meant to be parsed programmatically when handling errors. + * For programmatic error handling, please check the return |Status| + * of APIs instead. + */ +@VintfStability +parcelable LogMessage { + /** + * Epoch time in milliseconds. + */ + long timeMs; + LogPriority priority; + String message; +} diff --git a/drm/aidl/android/hardware/drm/LogPriority.aidl b/drm/aidl/android/hardware/drm/LogPriority.aidl new file mode 100644 index 0000000000..4db3b40982 --- /dev/null +++ b/drm/aidl/android/hardware/drm/LogPriority.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +@Backing(type="int") +enum LogPriority { + UNKNOWN, + DEFAULT, + VERBOSE, + DEBUG, + INFO, + WARN, + ERROR, + FATAL, +} diff --git a/drm/aidl/android/hardware/drm/Mode.aidl b/drm/aidl/android/hardware/drm/Mode.aidl new file mode 100644 index 0000000000..6fc00651a8 --- /dev/null +++ b/drm/aidl/android/hardware/drm/Mode.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * Enumerate the supported crypto modes + */ +@VintfStability +@Backing(type="int") +enum Mode { + UNENCRYPTED = 0, + AES_CTR = 1, + AES_CBC_CTS = 2, + AES_CBC = 3, +} diff --git a/drm/aidl/android/hardware/drm/NumberOfSessions.aidl b/drm/aidl/android/hardware/drm/NumberOfSessions.aidl new file mode 100644 index 0000000000..75b7c2ece8 --- /dev/null +++ b/drm/aidl/android/hardware/drm/NumberOfSessions.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +parcelable NumberOfSessions { + /** The number of currently opened sessions. */ + int currentSessions; + + /** The maximum number of sessions that the device can support. */ + int maxSessions; +} diff --git a/drm/aidl/android/hardware/drm/OfflineLicenseState.aidl b/drm/aidl/android/hardware/drm/OfflineLicenseState.aidl new file mode 100644 index 0000000000..0f447db2fa --- /dev/null +++ b/drm/aidl/android/hardware/drm/OfflineLicenseState.aidl @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +@Backing(type="int") +enum OfflineLicenseState { + /** + * Offline license state is unknown + */ + UNKNOWN, + /** + * Offline license state is usable, the keys are usable for decryption. + */ + USABLE, + /** + * Offline license state is inactive, the keys have been marked for + * release using {@link #getKeyRequest} with KEY_TYPE_RELEASE but the + * key response has not been received. + */ + INACTIVE, +} diff --git a/drm/aidl/android/hardware/drm/OpaqueData.aidl b/drm/aidl/android/hardware/drm/OpaqueData.aidl new file mode 100644 index 0000000000..6b2a2e79c0 --- /dev/null +++ b/drm/aidl/android/hardware/drm/OpaqueData.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +parcelable OpaqueData { + byte[] opaqueData; +} diff --git a/drm/aidl/android/hardware/drm/Pattern.aidl b/drm/aidl/android/hardware/drm/Pattern.aidl new file mode 100644 index 0000000000..88d22cf221 --- /dev/null +++ b/drm/aidl/android/hardware/drm/Pattern.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * A crypto Pattern is a repeating sequence of encrypted and clear blocks + * occurring within the bytes indicated by mNumBytesOfEncryptedDatad bytes + * of a subsample. Patterns are used to reduce the CPU overhead of + * decrypting samples. As an example, HLS uses 1:9 patterns where every + * 10th block is encrypted. + */ +@VintfStability +parcelable Pattern { + /** + * The number of blocks to be encrypted in the pattern. If zero, + * pattern encryption is inoperative. + */ + int encryptBlocks; + + /** + * The number of blocks to be skipped (left clear) in the pattern. If + * zero, pattern encryption is inoperative. + */ + int skipBlocks; +} diff --git a/drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.aidl b/drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.aidl new file mode 100644 index 0000000000..e9f1e2b956 --- /dev/null +++ b/drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.aidl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +parcelable ProvideProvisionResponseResult { + /** + * The public certificate resulting from the provisioning + * operation, if any. An empty vector indicates that no + * certificate was returned. + */ + byte[] certificate; + + /** + * An opaque object containing encrypted private key material + * to be used by signRSA when computing an RSA signature on a + * message, see the signRSA method. + */ + byte[] wrappedKey; +} diff --git a/drm/aidl/android/hardware/drm/ProvisionRequest.aidl b/drm/aidl/android/hardware/drm/ProvisionRequest.aidl new file mode 100644 index 0000000000..eb42d32c87 --- /dev/null +++ b/drm/aidl/android/hardware/drm/ProvisionRequest.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +parcelable ProvisionRequest { + /** The opaque certificate request blob. */ + byte[] request; + + /** + * The URL that the provisioning request may be sent to, + * if known by the HAL implementation. An app can choose to + * override this URL. If the HAL implementation does not provide + * a defaultUrl, the returned string must be empty. + */ + String defaultUrl; +} diff --git a/drm/aidl/android/hardware/drm/SecureStop.aidl b/drm/aidl/android/hardware/drm/SecureStop.aidl new file mode 100644 index 0000000000..37cfbd39ab --- /dev/null +++ b/drm/aidl/android/hardware/drm/SecureStop.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * Encapsulates a secure stop opaque object. + */ +@VintfStability +parcelable SecureStop { + byte[] opaqueData; +} diff --git a/drm/aidl/android/hardware/drm/SecureStopId.aidl b/drm/aidl/android/hardware/drm/SecureStopId.aidl new file mode 100644 index 0000000000..775e60b391 --- /dev/null +++ b/drm/aidl/android/hardware/drm/SecureStopId.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +parcelable SecureStopId { + byte[] secureStopId; +} diff --git a/drm/aidl/android/hardware/drm/SecurityLevel.aidl b/drm/aidl/android/hardware/drm/SecurityLevel.aidl new file mode 100644 index 0000000000..aac1b686f3 --- /dev/null +++ b/drm/aidl/android/hardware/drm/SecurityLevel.aidl @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +@Backing(type="int") +enum SecurityLevel { + /** + * Unable to determine the security level + */ + UNKNOWN, + /** + * Software-based whitebox crypto + */ + SW_SECURE_CRYPTO, + /** + * Software-based whitebox crypto and an obfuscated decoder + */ + SW_SECURE_DECODE, + /** + * DRM key management and crypto operations are performed within a + * hardware backed trusted execution environment + */ + HW_SECURE_CRYPTO, + /** + * DRM key management, crypto operations and decoding of content + * are performed within a hardware backed trusted execution environment + */ + HW_SECURE_DECODE, + /** + * DRM key management, crypto operations, decoding of content and all + * handling of the media (compressed and uncompressed) is handled within + * a hardware backed trusted execution environment. + */ + HW_SECURE_ALL, + /** + * The default security level is defined as the highest security level + * supported on the device. + */ + DEFAULT, +} diff --git a/drm/aidl/android/hardware/drm/SharedBuffer.aidl b/drm/aidl/android/hardware/drm/SharedBuffer.aidl new file mode 100644 index 0000000000..69772840ba --- /dev/null +++ b/drm/aidl/android/hardware/drm/SharedBuffer.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * SharedBuffer describes a decrypt buffer which is defined by a bufferId, an + * offset and a size. The offset is relative to the shared memory base for the + * memory region identified by bufferId, which is established by + * setSharedMemoryBase(). + */ +@VintfStability +parcelable SharedBuffer { + /** + * The unique buffer identifier + */ + int bufferId; + /** + * The offset from the shared memory base + */ + long offset; + /** + * The size of the shared buffer in bytes + */ + long size; +} diff --git a/drm/aidl/android/hardware/drm/Status.aidl b/drm/aidl/android/hardware/drm/Status.aidl new file mode 100644 index 0000000000..ee57d64608 --- /dev/null +++ b/drm/aidl/android/hardware/drm/Status.aidl @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +@Backing(type="int") +enum Status { + /** + * The DRM plugin must return OK when an operation completes without any + * errors. + */ + OK, + /** + * The DRM plugin must return ERROR_DRM_NO_LICENSE, when decryption is + * attempted and no license keys have been provided. + */ + ERROR_DRM_NO_LICENSE, + /** + * ERROR_DRM_LICENSE_EXPIRED must be returned when an attempt is made + * to use a license and the keys in that license have expired. + */ + ERROR_DRM_LICENSE_EXPIRED, + /** + * The DRM plugin must return ERROR_DRM_SESSION_NOT_OPENED when an + * attempt is made to use a session that has not been opened. + */ + ERROR_DRM_SESSION_NOT_OPENED, + /** + * The DRM plugin must return ERROR_DRM_CANNOT_HANDLE when an unsupported + * data format or operation is attempted. + */ + ERROR_DRM_CANNOT_HANDLE, + /** + * ERROR_DRM_INVALID_STATE must be returned when the device is in a state + * where it is not able to perform decryption. + */ + ERROR_DRM_INVALID_STATE, + /** + * The DRM plugin must return BAD_VALUE whenever an illegal parameter is + * passed to one of the interface functions. + */ + BAD_VALUE, + /** + * The DRM plugin must return ERROR_DRM_NOT_PROVISIONED from getKeyRequest, + * openSession or provideKeyResponse when the device has not yet been + * provisioned. + */ + ERROR_DRM_NOT_PROVISIONED, + /** + * ERROR_DRM_RESOURCE_BUSY must be returned when resources, such as drm + * sessions or secure buffers are not available to perform a requested + * operation because they are already in use. + */ + ERROR_DRM_RESOURCE_BUSY, + /** + * The DRM Plugin must return ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION + * when the output protection level enabled on the device is not + * sufficient to meet the requirements in the license policy. HDCP is an + * example of a form of output protection. + */ + ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION, + /** + * The DRM Plugin must return ERROR_DRM_DEVICE_REVOKED from + * provideProvisionResponse and provideKeyResponse if the response indicates + * that the device has been revoked. Device revocation means that the device + * is no longer permitted to play content. + */ + ERROR_DRM_DEVICE_REVOKED, + /** + * The DRM Plugin must return ERROR_DRM_DECRYPT if the CryptoPlugin + * decrypt operation fails. + */ + ERROR_DRM_DECRYPT, + /** + * ERROR_DRM_UNKNOWN must be returned when a fatal failure occurs and no + * other defined error is appropriate. + */ + ERROR_DRM_UNKNOWN, + /** + * The drm HAL module must return ERROR_DRM_INSUFFICIENT_SECURITY + * from the crypto plugin decrypt method when the security level + * of the device is not sufficient to meet the requirements in the + * license policy. + */ + ERROR_DRM_INSUFFICIENT_SECURITY, + /** + * The drm HAL module must return ERROR_FRAME_TOO_LARGE from the + * decrypt method when the frame being decrypted into the secure + * output buffer exceeds the size of the buffer. + */ + ERROR_DRM_FRAME_TOO_LARGE, + /** + * This error must be returned from any session method when an + * attempt is made to use the session after the crypto hardware + * state has been invalidated. Some devices are not able to + * retain crypto session state across device suspend/resume which + * results in invalid session state. + */ + ERROR_DRM_SESSION_LOST_STATE, + /** + * The drm HAL module must return this error if client + * applications using the hal are temporarily exceeding the + * capacity of available crypto resources such that a retry of + * the operation is likely to succeed. + */ + ERROR_DRM_RESOURCE_CONTENTION, + /** + * queueSecureInput buffer called with 0 subsamples. + */ + CANNOT_DECRYPT_ZERO_SUBSAMPLES, + /** + * An error happened within the crypto library used by the drm plugin. + */ + CRYPTO_LIBRARY_ERROR, + /** + * Non-specific error reported by the device OEM subsystem. + */ + GENERAL_OEM_ERROR, + /** + * Unexpected internal failure in the drm/crypto plugin. + */ + GENERAL_PLUGIN_ERROR, + /** + * The init data parameter passed to getKeyRequest is empty or invalid. + */ + INIT_DATA_INVALID, + /** + * Either the key was not loaded from the license before attempting the + * operation, or the key ID parameter provided by the app is incorrect. + */ + KEY_NOT_LOADED, + /** + * The license response was empty, fields are missing or otherwise unable + * to be parsed. + */ + LICENSE_PARSE_ERROR, + /** + * The operation (e.g. to renew or persist a license) is prohibited by the + * license policy. + */ + LICENSE_POLICY_ERROR, + /** + * Failed to generate a release request because a field in the stored + * license is empty or malformed. + */ + LICENSE_RELEASE_ERROR, + /** + * The license server detected an error in the license request. + */ + LICENSE_REQUEST_REJECTED, + /** + * Failed to restore an offline license because a field is empty or + * malformed. + */ + LICENSE_RESTORE_ERROR, + /** + * License is in an invalid state for the attempted operation. + */ + LICENSE_STATE_ERROR, + /** + * Certificate is malformed or is of the wrong type. + */ + MALFORMED_CERTIFICATE, + /** + * Failure in the media framework. + */ + MEDIA_FRAMEWORK_ERROR, + /** + * Certificate has not been set. + */ + MISSING_CERTIFICATE, + /** + * There was an error loading the provisioned certificate. + */ + PROVISIONING_CERTIFICATE_ERROR, + /** + * Required steps where not performed before provisioning was attempted. + */ + PROVISIONING_CONFIGURATION_ERROR, + /** + * The provisioning response was empty, fields are missing or otherwise + * unable to be parsed. + */ + PROVISIONING_PARSE_ERROR, + /** + * The provisioning server detected an error in the provisioning request. + */ + PROVISIONING_REQUEST_REJECTED, + /** + * Provisioning failed in a way that is likely to succeed on a subsequent + * attempt. + */ + RETRYABLE_PROVISIONING_ERROR, + /** + * Failed to generate a secure stop request because a field in the stored + * license is empty or malformed. + */ + SECURE_STOP_RELEASE_ERROR, + /** + * The plugin was unable to read data from the filesystem. + */ + STORAGE_READ_FAILURE, + /** + * The plugin was unable to write data to the filesystem. + */ + STORAGE_WRITE_FAILURE, +} diff --git a/drm/aidl/android/hardware/drm/SubSample.aidl b/drm/aidl/android/hardware/drm/SubSample.aidl new file mode 100644 index 0000000000..68a8fb1123 --- /dev/null +++ b/drm/aidl/android/hardware/drm/SubSample.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2021 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.drm; + +/** + * A subsample consists of some number of bytes of clear (unencrypted) + * data followed by a number of bytes of encrypted data. + */ +@VintfStability +parcelable SubSample { + int numBytesOfClearData; + int numBytesOfEncryptedData; +} diff --git a/drm/aidl/android/hardware/drm/Uuid.aidl b/drm/aidl/android/hardware/drm/Uuid.aidl new file mode 100644 index 0000000000..b36c409c66 --- /dev/null +++ b/drm/aidl/android/hardware/drm/Uuid.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2021 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.drm; + +@VintfStability +parcelable Uuid { + byte[] uuid; +} -- cgit v1.2.3 From 070f47dd7fd64c0c979a85a65c23fe559f65a6ed Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Thu, 6 Jan 2022 22:42:10 +0000 Subject: Make return values of IContextHub.aidl more consistent Follow the pattern of using well-defined AIDL error codes as return values for methods. Bug: 213474931 Test: Compile, run VTS Change-Id: If04d989cf504161638ec47b2302e60cbf32db502 --- .../android/hardware/contexthub/IContextHub.aidl | 15 ++--- .../android/hardware/contexthub/IContextHub.aidl | 57 ++++++++++++----- contexthub/aidl/default/ContextHub.cpp | 73 +++++++++------------- .../default/include/contexthub-impl/ContextHub.h | 18 +++--- .../aidl/vts/VtsAidlHalContextHubTargetTest.cpp | 58 ++++++----------- 5 files changed, 104 insertions(+), 117 deletions(-) diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl index facce4b65e..f0676bec74 100644 --- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl +++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl @@ -35,14 +35,15 @@ package android.hardware.contexthub; @VintfStability interface IContextHub { List getContextHubs(); - boolean loadNanoapp(in int contextHubId, in android.hardware.contexthub.NanoappBinary appBinary, in int transactionId); - boolean unloadNanoapp(in int contextHubId, in long appId, in int transactionId); - boolean disableNanoapp(in int contextHubId, in long appId, in int transactionId); - boolean enableNanoapp(in int contextHubId, in long appId, in int transactionId); + void loadNanoapp(in int contextHubId, in android.hardware.contexthub.NanoappBinary appBinary, in int transactionId); + void unloadNanoapp(in int contextHubId, in long appId, in int transactionId); + void disableNanoapp(in int contextHubId, in long appId, in int transactionId); + void enableNanoapp(in int contextHubId, in long appId, in int transactionId); void onSettingChanged(in android.hardware.contexthub.Setting setting, in boolean enabled); - boolean queryNanoapps(in int contextHubId); - boolean registerCallback(in int contextHubId, in android.hardware.contexthub.IContextHubCallback cb); - boolean sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message); + void queryNanoapps(in int contextHubId); + void registerCallback(in int contextHubId, in android.hardware.contexthub.IContextHubCallback cb); + void sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message); void onHostEndpointConnected(in android.hardware.contexthub.HostEndpointInfo hostEndpointInfo); void onHostEndpointDisconnected(char hostEndpointId); + const int EX_CONTEXT_HUB_UNSPECIFIED = -1; } diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl index 33d241a3c3..2135041ed7 100644 --- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl +++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl @@ -52,9 +52,12 @@ interface IContextHub { * @param appBinary The nanoapp binary with header * @param transactionId The transaction ID associated with this request * - * @return The return code + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean loadNanoapp(in int contextHubId, in NanoappBinary appBinary, in int transactionId); + void loadNanoapp(in int contextHubId, in NanoappBinary appBinary, in int transactionId); /** * Invokes the nanoapp's deinitialization "end()" entrypoint, and unloads the nanoapp. @@ -69,9 +72,12 @@ interface IContextHub { * @param appId The unique ID of the nanoapp * @param transactionId The transaction ID associated with this request * - * @return The return code + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean unloadNanoapp(in int contextHubId, in long appId, in int transactionId); + void unloadNanoapp(in int contextHubId, in long appId, in int transactionId); /** * Disables a nanoapp by invoking the nanoapp's "end()" entrypoint, but does not unload the @@ -87,9 +93,12 @@ interface IContextHub { * @param appId The unique ID of the nanoapp * @param transactionId The transaction ID associated with this request * - * @return The return code + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean disableNanoapp(in int contextHubId, in long appId, in int transactionId); + void disableNanoapp(in int contextHubId, in long appId, in int transactionId); /** * Enables a nanoapp by invoking the nanoapp's initialization "start()" entrypoint. @@ -104,9 +113,12 @@ interface IContextHub { * @param appId appIdentifier returned by the HAL * @param message message to be sent * - * @return true on success + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean enableNanoapp(in int contextHubId, in long appId, in int transactionId); + void enableNanoapp(in int contextHubId, in long appId, in int transactionId); /** * Notification sent by the framework to indicate that the user has changed a setting. @@ -124,9 +136,12 @@ interface IContextHub { * * @param contextHubId The identifier of the Context Hub * - * @return true on success + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_UNSUPPORTED_OPERATION if this functionality is unsupported. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean queryNanoapps(in int contextHubId); + void queryNanoapps(in int contextHubId); /** * Register a callback for the HAL implementation to send asynchronous messages to the service @@ -138,10 +153,11 @@ interface IContextHub { * @param contextHubId The identifier of the Context Hub * @param callback an implementation of the IContextHubCallbacks * - * @return true on success - * + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean registerCallback(in int contextHubId, in IContextHubCallback cb); + void registerCallback(in int contextHubId, in IContextHubCallback cb); /** * Sends a message targeted to a nanoapp to the Context Hub. @@ -149,9 +165,11 @@ interface IContextHub { * @param contextHubId The identifier of the Context Hub * @param message The message to be sent * - * @return true on success + * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid. + * EX_SERVICE_SPECIFIC on error + * - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons. */ - boolean sendMessageToHub(in int contextHubId, in ContextHubMessage message); + void sendMessageToHub(in int contextHubId, in ContextHubMessage message); /** * Invoked when a host endpoint has connected with the ContextHubService. @@ -173,8 +191,13 @@ interface IContextHub { * * @param hostEndPointId The ID of the host that has disconnected. * - * @return Status::ok on success - * EX_ILLEGAL_ARGUMENT if hostEndpointId is not associated with a connected host. + * @throws EX_ILLEGAL_ARGUMENT if hostEndpointId is not associated with a connected host. */ void onHostEndpointDisconnected(char hostEndpointId); + + /** + * Error codes that are used as service specific errors with the AIDL return + * value EX_SERVICE_SPECIFIC. + */ + const int EX_CONTEXT_HUB_UNSPECIFIED = -1; } diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp index 6da690da4f..4c23cbc8bf 100644 --- a/contexthub/aidl/default/ContextHub.cpp +++ b/contexthub/aidl/default/ContextHub.cpp @@ -21,7 +21,9 @@ namespace android { namespace hardware { namespace contexthub { -::ndk::ScopedAStatus ContextHub::getContextHubs(std::vector* out_contextHubInfos) { +using ::ndk::ScopedAStatus; + +ScopedAStatus ContextHub::getContextHubs(std::vector* out_contextHubInfos) { ContextHubInfo hub = {}; hub.name = "Mock Context Hub"; hub.vendor = "AOSP"; @@ -39,85 +41,70 @@ namespace contexthub { } // We don't expose any nanoapps for the default impl, therefore all nanoapp-related APIs fail. -::ndk::ScopedAStatus ContextHub::loadNanoapp(int32_t /* in_contextHubId */, - const NanoappBinary& /* in_appBinary */, - int32_t /* in_transactionId */, bool* _aidl_return) { - *_aidl_return = false; - return ndk::ScopedAStatus::ok(); +ScopedAStatus ContextHub::loadNanoapp(int32_t /* in_contextHubId */, + const NanoappBinary& /* in_appBinary */, + int32_t /* in_transactionId */) { + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -::ndk::ScopedAStatus ContextHub::unloadNanoapp(int32_t /* in_contextHubId */, - int64_t /* in_appId */, - int32_t /* in_transactionId */, bool* _aidl_return) { - *_aidl_return = false; - return ndk::ScopedAStatus::ok(); +ScopedAStatus ContextHub::unloadNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */, + int32_t /* in_transactionId */) { + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -::ndk::ScopedAStatus ContextHub::disableNanoapp(int32_t /* in_contextHubId */, - int64_t /* in_appId */, - int32_t /* in_transactionId */, - bool* _aidl_return) { - *_aidl_return = false; - return ndk::ScopedAStatus::ok(); +ScopedAStatus ContextHub::disableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */, + int32_t /* in_transactionId */) { + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -::ndk::ScopedAStatus ContextHub::enableNanoapp(int32_t /* in_contextHubId */, - int64_t /* in_appId */, - int32_t /* in_transactionId */, bool* _aidl_return) { - *_aidl_return = false; - return ndk::ScopedAStatus::ok(); +ScopedAStatus ContextHub::enableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */, + int32_t /* in_transactionId */) { + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -::ndk::ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) { +ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) { return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId, bool* _aidl_return) { +ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId) { if (in_contextHubId == kMockHubId && mCallback != nullptr) { std::vector nanoapps; mCallback->handleNanoappInfo(nanoapps); - *_aidl_return = true; + return ndk::ScopedAStatus::ok(); } else { - *_aidl_return = false; + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - - return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId, - const std::shared_ptr& in_cb, - bool* _aidl_return) { +ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId, + const std::shared_ptr& in_cb) { if (in_contextHubId == kMockHubId) { mCallback = in_cb; - *_aidl_return = true; + return ndk::ScopedAStatus::ok(); } else { - *_aidl_return = false; + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::sendMessageToHub(int32_t in_contextHubId, - const ContextHubMessage& /* in_message */, - bool* _aidl_return) { +ScopedAStatus ContextHub::sendMessageToHub(int32_t in_contextHubId, + const ContextHubMessage& /* in_message */) { if (in_contextHubId == kMockHubId) { // Return true here to indicate that the HAL has accepted the message. // Successful delivery of the message to a nanoapp should be handled at // a higher level protocol. - *_aidl_return = true; + return ndk::ScopedAStatus::ok(); } else { - *_aidl_return = false; + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - - return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) { +ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) { mConnectedHostEndpoints.insert(in_info.hostEndpointId); return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) { +ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) { if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) { mConnectedHostEndpoints.erase(in_hostEndpointId); return ndk::ScopedAStatus::ok(); diff --git a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h index dd739e63f8..03d8432134 100644 --- a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h +++ b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h @@ -28,21 +28,19 @@ namespace contexthub { class ContextHub : public BnContextHub { ::ndk::ScopedAStatus getContextHubs(std::vector* out_contextHubInfos) override; ::ndk::ScopedAStatus loadNanoapp(int32_t in_contextHubId, const NanoappBinary& in_appBinary, - int32_t in_transactionId, bool* _aidl_return) override; + int32_t in_transactionId) override; ::ndk::ScopedAStatus unloadNanoapp(int32_t in_contextHubId, int64_t in_appId, - int32_t in_transactionId, bool* _aidl_return) override; + int32_t in_transactionId) override; ::ndk::ScopedAStatus disableNanoapp(int32_t in_contextHubId, int64_t in_appId, - int32_t in_transactionId, bool* _aidl_return) override; + int32_t in_transactionId) override; ::ndk::ScopedAStatus enableNanoapp(int32_t in_contextHubId, int64_t in_appId, - int32_t in_transactionId, bool* _aidl_return) override; + int32_t in_transactionId) override; ::ndk::ScopedAStatus onSettingChanged(Setting in_setting, bool in_enabled) override; - ::ndk::ScopedAStatus queryNanoapps(int32_t in_contextHubId, bool* _aidl_return) override; - ::ndk::ScopedAStatus registerCallback(int32_t in_contextHubId, - const std::shared_ptr& in_cb, - bool* _aidl_return) override; + ::ndk::ScopedAStatus queryNanoapps(int32_t in_contextHubId) override; + ::ndk::ScopedAStatus registerCallback( + int32_t in_contextHubId, const std::shared_ptr& in_cb) override; ::ndk::ScopedAStatus sendMessageToHub(int32_t in_contextHubId, - const ContextHubMessage& in_message, - bool* _aidl_return) override; + const ContextHubMessage& in_message) override; ::ndk::ScopedAStatus onHostEndpointConnected(const HostEndpointInfo& in_info) override; ::ndk::ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override; diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp index 392e23c9c1..a47f64e5be 100644 --- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp +++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp @@ -103,15 +103,12 @@ class EmptyContextHubCallback : public android::hardware::contexthub::BnContextH }; TEST_P(ContextHubAidl, TestRegisterCallback) { - bool success; sp cb = sp::make(); - ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk()); } TEST_P(ContextHubAidl, TestRegisterNullCallback) { - bool success; - ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr, &success).isOk()); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk()); } // Helper callback that puts the async appInfo callback data into a promise @@ -140,12 +137,8 @@ class QueryAppsCallback : public android::hardware::contexthub::BnContextHubCall // Calls queryApps() and checks the returned metadata TEST_P(ContextHubAidl, TestQueryApps) { sp cb = sp::make(); - bool success; - ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk()); - ASSERT_TRUE(success); - - ASSERT_TRUE(contextHub->queryNanoapps(getHubId(), &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk()); + ASSERT_TRUE(contextHub->queryNanoapps(getHubId()).isOk()); std::vector appInfoList; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &appInfoList)); @@ -197,9 +190,7 @@ class ContextHubTransactionTest : public ContextHubAidl { public: virtual void SetUp() override { ContextHubAidl::SetUp(); - bool success; - ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk()); } sp cb = sp::make(); @@ -213,9 +204,7 @@ TEST_P(ContextHubTransactionTest, TestSendMessageToNonExistentNanoapp) { std::fill(message.messageBody.begin(), message.messageBody.end(), 0); ALOGD("Sending message to non-existent nanoapp"); - bool success; - ASSERT_TRUE(contextHub->sendMessageToHub(getHubId(), message, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->sendMessageToHub(getHubId(), message).isOk()); } TEST_P(ContextHubTransactionTest, TestLoadEmptyNanoapp) { @@ -229,9 +218,7 @@ TEST_P(ContextHubTransactionTest, TestLoadEmptyNanoapp) { emptyApp.targetChreApiMinorVersion = 0; ALOGD("Loading empty nanoapp"); - bool success; - ASSERT_TRUE(contextHub->loadNanoapp(getHubId(), emptyApp, cb->expectedTransactionId, &success) - .isOk()); + bool success = contextHub->loadNanoapp(getHubId(), emptyApp, cb->expectedTransactionId).isOk(); if (success) { bool transactionSuccess; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess)); @@ -243,11 +230,9 @@ TEST_P(ContextHubTransactionTest, TestUnloadNonexistentNanoapp) { cb->expectedTransactionId = 1234; ALOGD("Unloading nonexistent nanoapp"); - bool success; - ASSERT_TRUE(contextHub - ->unloadNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId, - &success) - .isOk()); + bool success = + contextHub->unloadNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId) + .isOk(); if (success) { bool transactionSuccess; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess)); @@ -259,11 +244,9 @@ TEST_P(ContextHubTransactionTest, TestEnableNonexistentNanoapp) { cb->expectedTransactionId = 2345; ALOGD("Enabling nonexistent nanoapp"); - bool success; - ASSERT_TRUE(contextHub - ->enableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId, - &success) - .isOk()); + bool success = + contextHub->enableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId) + .isOk(); if (success) { bool transactionSuccess; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess)); @@ -275,11 +258,9 @@ TEST_P(ContextHubTransactionTest, TestDisableNonexistentNanoapp) { cb->expectedTransactionId = 3456; ALOGD("Disabling nonexistent nanoapp"); - bool success; - ASSERT_TRUE(contextHub - ->disableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId, - &success) - .isOk()); + bool success = + contextHub->disableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId) + .isOk(); if (success) { bool transactionSuccess; ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess)); @@ -290,16 +271,13 @@ TEST_P(ContextHubTransactionTest, TestDisableNonexistentNanoapp) { void ContextHubAidl::testSettingChanged(Setting setting) { // In VTS, we only test that sending the values doesn't cause things to blow up - GTS tests // verify the expected E2E behavior in CHRE - bool success; sp cb = sp::make(); - ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk()); ASSERT_TRUE(contextHub->onSettingChanged(setting, true /* enabled */).isOk()); ASSERT_TRUE(contextHub->onSettingChanged(setting, false /* enabled */).isOk()); - ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr, &success).isOk()); - ASSERT_TRUE(success); + ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk()); } TEST_P(ContextHubAidl, TestOnLocationSettingChanged) { -- cgit v1.2.3 From 536f04e354c055a60be2e19c52b579730dc50582 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Tue, 4 Jan 2022 13:33:11 -0500 Subject: Add LayerCommand.blockingRegion This hint tells the HWC that it may use a blocking feature to skip a portion of the layer's buffer. Bug: 212736475 Test: TODO (b/213361853) Change-Id: Ib0fa41e56196feeff201637d5599830d2565da2b --- .../android/hardware/graphics/composer3/LayerCommand.aidl | 1 + .../android/hardware/graphics/composer3/LayerCommand.aidl | 11 +++++++++++ .../hardware/graphics/composer3/ComposerClientWriter.h | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl index ab77880daf..ac080ddab4 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl @@ -54,4 +54,5 @@ parcelable LayerCommand { @nullable android.hardware.graphics.composer3.WhitePointNits whitePointNits; @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata; @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob; + @nullable android.hardware.graphics.common.Rect[] blockingRegion; } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl index 44fd4dcb9a..f9ae28ee6e 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl @@ -264,4 +264,15 @@ parcelable LayerCommand { * This command may be called every frame. */ @nullable PerFrameMetadataBlob[] perFrameMetadataBlob; + + /** + * Specifies a region of the layer that is transparent and may be skipped + * by the DPU, e.g. using a blocking region, in order to save power. This + * is only a hint, so the composition of the layer must look the same + * whether or not this region is skipped. + * + * The region is in screen space and must not exceed the dimensions of + * the screen. + */ + @nullable Rect[] blockingRegion; } diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h index 16d63e57ca..128bc1a095 100644 --- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h +++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h @@ -213,6 +213,10 @@ class ComposerClientWriter { .whitePointNits.emplace(WhitePointNits{.nits = whitePointNits}); } + void setLayerBlockingRegion(int64_t display, int64_t layer, const std::vector& blocking) { + getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end()); + } + const std::vector& getPendingCommands() { flushLayerCommand(); flushDisplayCommand(); -- cgit v1.2.3 From 738d3d5950523bffb2d7ef714f56a4d5f5242a1a Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Fri, 7 Jan 2022 22:15:32 +0000 Subject: remove libbinder_ndk_host_user no longer needed Bug: 211908498 Test: build Change-Id: Iadffdf1d7759e32986c4e0e28acb2087d9f27ab0 --- common/support/Android.bp | 12 ++++++++++-- health/aidl/Android.bp | 8 +++++--- health/utils/libhealthshim/Android.bp | 8 +++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/common/support/Android.bp b/common/support/Android.bp index b24893b16e..718901ef6a 100644 --- a/common/support/Android.bp +++ b/common/support/Android.bp @@ -11,7 +11,11 @@ cc_library_static { name: "libaidlcommonsupport", vendor_available: true, host_supported: true, - defaults: ["libbinder_ndk_host_user"], + target: { + darwin: { + enabled: false, + }, + }, srcs: ["NativeHandle.cpp"], export_include_dirs: ["include"], shared_libs: [ @@ -28,7 +32,11 @@ cc_library_static { cc_test { name: "libaidlcommonsupport_test", host_supported: true, - defaults: ["libbinder_ndk_host_user"], + target: { + darwin: { + enabled: false, + }, + }, srcs: ["test.cpp"], static_libs: [ "android.hardware.common-V2-ndk", diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp index 22bb4fadc3..86bca69e07 100644 --- a/health/aidl/Android.bp +++ b/health/aidl/Android.bp @@ -62,9 +62,11 @@ cc_library { "android.hardware.health@2.0", "android.hardware.health@2.1", ], - defaults: [ - "libbinder_ndk_host_user", - ], + target: { + darwin: { + enabled: false, + }, + }, } java_library { diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp index 311e951b7f..42e4ea7cc0 100644 --- a/health/utils/libhealthshim/Android.bp +++ b/health/utils/libhealthshim/Android.bp @@ -24,9 +24,11 @@ package { cc_defaults { name: "libhealthshim_defaults", host_supported: true, // for testing - defaults: [ - "libbinder_ndk_host_user", - ], + target: { + darwin: { + enabled: false, + }, + }, cflags: [ "-Wall", "-Werror", -- cgit v1.2.3 From 4718025a6c3b4c0fe62eb39879b93aec90340446 Mon Sep 17 00:00:00 2001 From: David Gross Date: Fri, 7 Jan 2022 14:56:03 -0800 Subject: FL7: Refine MIRROR_PAD specification Test: N/A Bug: 202280925 Change-Id: If19d45d806f6ba33f9aa6c7af9bc411957cdc706 --- .../android/hardware/neuralnetworks/OperationType.aidl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl index 0ad254dc4e..5f7810b778 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl @@ -5331,6 +5331,18 @@ enum OperationType { /** * Pads a tensor with mirrored values. * + * This operator specifies one of two padding modes: REFLECT or SYMMETRIC. + * In the case of REFLECT mode, the mirroring excludes the border element + * on the padding side. + * In the case of SYMMETRIC mode, the mirroring includes the border element + * on the padding side. + * + * For example, if the input is the 1-D tensor `[1, 2, 3]` and the padding + * is `[0, 2]` (i.e., pad no elements before the first (and only) dimension, + * and two elements after the first (and only) dimension), then: + * - REFLECT mode produces the output `[1, 2, 3, 2, 1]` + * - SYMMETRIC mode produces the output `[1, 2, 3, 3, 2]` + * * Supported tensor {@link OperandType}: * * {@link OperandType::TENSOR_FLOAT16} * * {@link OperandType::TENSOR_FLOAT32} @@ -5349,6 +5361,11 @@ enum OperationType { * front of dimension i. * padding[i, 1] specifies the number of elements to be padded after the * end of dimension i. + * Each padding value must be nonnegative. + * In the case of REFLECT mode, each padding value must be less than the + * corresponding dimension. + * In the case of SYMMETRIC mode, each padding value must be less than or + * equal to the corresponding dimension. * * 2: An {@link OperandType::INT32} scalar, specifying the mode. * Options are 0:REFLECT and 1:SYMMETRIC. * -- cgit v1.2.3 From d1f6dea042f015748ad34da3fd3cd92deb783bfb Mon Sep 17 00:00:00 2001 From: Kedar Chitnis Date: Mon, 10 Jan 2022 12:38:49 +0000 Subject: Fix dumpstate AIDL interface API comments Bug: 213475867 Test: Build test Change-Id: I12b6f6a5edb732a5ec6d76da7c54998079054ca1 --- dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl index 3b42546a46..b994d04e0c 100644 --- a/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl +++ b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl @@ -103,8 +103,9 @@ interface IDumpstateDevice { * @param timeoutMillis An approximate "budget" for how much time this call has been allotted. * If execution runs longer than this, the IDumpstateDevice service may be killed and only * partial information will be included in the report. - * @return If error, return service specific error with code - * ERROR_UNSUPPORTED_MODE or ERROR_DEVICE_LOGGING_NOT_ENABLED + * @throws ServiceSpecificException with one of the following values: + * |ERROR_UNSUPPORTED_MODE|, + * |ERROR_DEVICE_LOGGING_NOT_ENABLED| */ void dumpstateBoard(in ParcelFileDescriptor[] fd, in DumpstateMode mode, in long timeoutMillis); -- cgit v1.2.3 From 4811381f3ee7fac2b700669996170b646f9fe034 Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Mon, 10 Jan 2022 17:42:53 +0000 Subject: Update IConsumerIr method comments and add units to parameter Test: atest ConsumerIrTest VtsHalIrTargetTest hal_implementation_test Bug: 213468221 Change-Id: Ied20fec1a522e3757fbbc9ec60812b6805acd0f5 --- .../current/android/hardware/ir/IConsumerIr.aidl | 2 +- ir/aidl/android/hardware/ir/IConsumerIr.aidl | 16 +++++++--------- ir/aidl/default/main.cpp | 6 +++--- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl index 056a8b1235..07bf4b4af2 100644 --- a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl +++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl @@ -35,5 +35,5 @@ package android.hardware.ir; @VintfStability interface IConsumerIr { android.hardware.ir.ConsumerIrFreqRange[] getCarrierFreqs(); - void transmit(in int carrierFreq, in int[] pattern); + void transmit(in int carrierFreqHz, in int[] pattern); } diff --git a/ir/aidl/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/android/hardware/ir/IConsumerIr.aidl index d14fa566bc..f6f9742fdb 100644 --- a/ir/aidl/android/hardware/ir/IConsumerIr.aidl +++ b/ir/aidl/android/hardware/ir/IConsumerIr.aidl @@ -23,23 +23,21 @@ interface IConsumerIr { /** * Enumerates which frequencies the IR transmitter supports. * - * Status OK (EX_NONE) on success. - * * @return - an array of all supported frequency ranges. */ ConsumerIrFreqRange[] getCarrierFreqs(); /** * Sends an IR pattern at a given frequency in HZ. + * This call must return when the transmit is complete or encounters an error. * - * The pattern is alternating series of carrier on and off periods measured in - * microseconds. The carrier should be turned off at the end of a transmit - * even if there are and odd number of entries in the pattern array. + * @param carrierFreq - Frequency of the transmission in HZ. * - * This call must return when the transmit is complete or encounters an error. + * @param pattern - Alternating series of on and off periods measured in + * microseconds. The carrier should be turned off at the end of a transmit + * even if there are an odd number of entries in the pattern array. * - * Status OK (EX_NONE) on success. - * EX_UNSUPPORTED_OPERATION when the frequency is not supported. + * @throws EX_UNSUPPORTED_OPERATION when the frequency is not supported. */ - void transmit(in int carrierFreq, in int[] pattern); + void transmit(in int carrierFreqHz, in int[] pattern); } diff --git a/ir/aidl/default/main.cpp b/ir/aidl/default/main.cpp index 764aeaf641..7c4a8169c8 100644 --- a/ir/aidl/default/main.cpp +++ b/ir/aidl/default/main.cpp @@ -30,7 +30,7 @@ const std::vector kSupportedFreqs = { class ConsumerIr : public BnConsumerIr { ::ndk::ScopedAStatus getCarrierFreqs(std::vector* _aidl_return) override; - ::ndk::ScopedAStatus transmit(int32_t in_carrierFreq, + ::ndk::ScopedAStatus transmit(int32_t in_carrierFreqHz, const std::vector& in_pattern) override; }; @@ -46,9 +46,9 @@ bool isSupportedFreq(int32_t freq) { return false; } -::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreq, +::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreqHz, const std::vector& in_pattern) { - if (isSupportedFreq(in_carrierFreq)) { + if (isSupportedFreq(in_carrierFreqHz)) { // trasmit the pattern, each integer is number of microseconds in an // alternating on/off state. usleep(std::accumulate(in_pattern.begin(), in_pattern.end(), 0)); -- cgit v1.2.3 From bc1c7438327559d6985841ca82b58c841809b17e Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Thu, 9 Dec 2021 18:48:20 -0800 Subject: Cleanup to composer apis for HDR: 1. Remove the setDisplayBrightness method, as it's been moved to a display command 2. Rename the WhitePointNits stable stuct to Luminance, since it's a more general descriptor. Bug: 210151839 Test: builds Change-Id: Ic948dce737ce718772100b0e976ec93069d5e8e1 --- .../graphics/composer3/IComposerClient.aidl | 1 - .../hardware/graphics/composer3/LayerCommand.aidl | 2 +- .../hardware/graphics/composer3/Luminance.aidl | 38 ++++++++++++++++++++++ .../graphics/composer3/WhitePointNits.aidl | 38 ---------------------- .../graphics/composer3/IComposerClient.aidl | 19 ----------- .../hardware/graphics/composer3/LayerCommand.aidl | 4 +-- .../hardware/graphics/composer3/Luminance.aidl | 26 +++++++++++++++ .../graphics/composer3/WhitePointNits.aidl | 29 ----------------- .../graphics/composer3/ComposerClientWriter.h | 5 ++- 9 files changed, 69 insertions(+), 93 deletions(-) create mode 100644 graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl delete mode 100644 graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl create mode 100644 graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl delete mode 100644 graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl index 2d17e0fdea..e9d9745dff 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl @@ -65,7 +65,6 @@ interface IComposerClient { void setClientTargetSlotCount(long display, int clientTargetSlotCount); void setColorMode(long display, android.hardware.graphics.composer3.ColorMode mode, android.hardware.graphics.composer3.RenderIntent intent); void setContentType(long display, android.hardware.graphics.composer3.ContentType type); - void setDisplayBrightness(long display, float brightness); void setDisplayedContentSamplingEnabled(long display, boolean enable, android.hardware.graphics.composer3.FormatColorComponent componentMask, long maxFrames); void setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode); void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in @nullable ParcelFileDescriptor releaseFence); diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl index ab77880daf..7e6c00b1f5 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl @@ -51,7 +51,7 @@ parcelable LayerCommand { @nullable android.hardware.graphics.common.Rect[] visibleRegion; @nullable android.hardware.graphics.composer3.ZOrder z; @nullable float[] colorTransform; - @nullable android.hardware.graphics.composer3.WhitePointNits whitePointNits; + @nullable android.hardware.graphics.composer3.Luminance whitePointNits; @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata; @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob; } diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl new file mode 100644 index 0000000000..adb49a81b4 --- /dev/null +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2021, 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.graphics.composer3; +@VintfStability +parcelable Luminance { + float nits; +} diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl deleted file mode 100644 index c3925d2153..0000000000 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2021, 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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.graphics.composer3; -@VintfStability -parcelable WhitePointNits { - float nits; -} diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl index ab7f39781e..3ab6329bff 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl @@ -615,25 +615,6 @@ interface IComposerClient { */ void setContentType(long display, ContentType type); - /** - * Sets the brightness of a display. - * - * Ideally, the brightness change should take effect in the next frame post (so that it can be - * aligned with color transforms). - * - * @param display - * The display whose brightness is set. - * @param brightness - * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0 to - * turn the backlight off. - * - * @exception EX_BAD_DISPLAY when the display is invalid, or - * @exception EX_UNSUPPORTED when brightness operations are not supported, or - * @exception EX_BAD_PARAMETER when the brightness is invalid, or - * @exception EX_NO_RESOURCES when the brightness cannot be applied. - */ - void setDisplayBrightness(long display, float brightness); - /** * Enables or disables the collection of color content statistics * on this display. diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl index 44fd4dcb9a..fa2d154c9b 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl @@ -23,6 +23,7 @@ import android.hardware.graphics.common.Rect; import android.hardware.graphics.composer3.Buffer; import android.hardware.graphics.composer3.Color; import android.hardware.graphics.composer3.FloatColor; +import android.hardware.graphics.composer3.Luminance; import android.hardware.graphics.composer3.ParcelableBlendMode; import android.hardware.graphics.composer3.ParcelableComposition; import android.hardware.graphics.composer3.ParcelableDataspace; @@ -30,7 +31,6 @@ import android.hardware.graphics.composer3.ParcelableTransform; import android.hardware.graphics.composer3.PerFrameMetadata; import android.hardware.graphics.composer3.PerFrameMetadataBlob; import android.hardware.graphics.composer3.PlaneAlpha; -import android.hardware.graphics.composer3.WhitePointNits; import android.hardware.graphics.composer3.ZOrder; @VintfStability @@ -243,7 +243,7 @@ parcelable LayerCommand { * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point * provided. */ - @nullable WhitePointNits whitePointNits; + @nullable Luminance whitePointNits; /** * Sets the PerFrameMetadata for the display. This metadata must be used diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl new file mode 100644 index 0000000000..5b1c1b40fe --- /dev/null +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2021, 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.graphics.composer3; + +@VintfStability +parcelable Luminance { + /** + * Photometric measure of luminous intensity per unit area of light. + * Units are nits, or cd/m^2. + */ + float nits; +} diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl deleted file mode 100644 index 2a1d1c666c..0000000000 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2021, 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.graphics.composer3; - -@VintfStability -parcelable WhitePointNits { - /** - * The desired white point for the layer. This is intended to be used when presenting - * an SDR layer alongside HDR content. The HDR content will be presented at the display - * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point - * provided. - * @see LayerCommand.whitePointNits. - */ - float nits; -} diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h index b202b34c64..2d927cdae4 100644 --- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h +++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h @@ -31,9 +31,9 @@ #include #include #include +#include #include #include -#include #include @@ -215,8 +215,7 @@ class ComposerClientWriter { } void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) { - getLayerCommand(display, layer) - .whitePointNits.emplace(WhitePointNits{.nits = whitePointNits}); + getLayerCommand(display, layer).whitePointNits.emplace(Luminance{.nits = whitePointNits}); } const std::vector& getPendingCommands() { -- cgit v1.2.3 From 494ba666ac41fb44d6beeb12d743daa171e1c26f Mon Sep 17 00:00:00 2001 From: Hongguang Date: Wed, 5 Jan 2022 22:08:10 -0800 Subject: Add CRC32 checking hint. Bug: 172985025 Test: atest VtsHalTvTunerTargetTest Change-Id: Ie26cfee7ba0254fe20e485cd173e65d391f7a254 --- .../android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl | 1 + .../android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl | 10 +++++++++- tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h | 1 + tv/tuner/config/api/current.txt | 2 ++ tv/tuner/config/tuner_testing_dynamic_configuration.xsd | 1 + 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl index 2858565099..7936e59001 100644 --- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl +++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl @@ -39,4 +39,5 @@ parcelable DemuxFilterSectionSettings { boolean isCheckCrc; boolean isRepeat; boolean isRaw; + int bitWidthOfLengthField; } diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl index f6788ee131..aa30175823 100644 --- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl +++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl @@ -19,7 +19,7 @@ package android.hardware.tv.tuner; import android.hardware.tv.tuner.DemuxFilterSectionSettingsCondition; /** - * Filter Settings for Section data according to ISO/IEC 13818-1. + * Filter Settings for Section data according to ISO/IEC 13818-1 and ISO/IEC 23008-1. * @hide */ @VintfStability @@ -49,4 +49,12 @@ parcelable DemuxFilterSectionSettings { * true if the filter send onFilterStatus instead of onFilterEvent. */ boolean isRaw; + + /** + * The bit width of the MMTP (MPEG Media Transport Protocol) section message's length field + * according to ISO/IEC 23008-1. + * + * The filter uses this for CRC checking when isCheckCrc is true. + */ + int bitWidthOfLengthField; } diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h index b6cc5f80b0..b73d59411b 100644 --- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h +++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h @@ -954,6 +954,7 @@ struct TunerTestingConfigAidlReader1_0 { settings.isCheckCrc = section->getIsCheckCrc(); settings.isRepeat = section->getIsRepeat(); settings.isRaw = section->getIsRaw(); + settings.bitWidthOfLengthField = section->getBitWidthOfLengthField(); return settings; } diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt index db1d076e10..4d519d7cb5 100644 --- a/tv/tuner/config/api/current.txt +++ b/tv/tuner/config/api/current.txt @@ -477,9 +477,11 @@ package android.media.tuner.testing.configuration.V1_0 { public class SectionFilterSettings { ctor public SectionFilterSettings(); + method @Nullable public java.math.BigInteger getBitWidthOfLengthField(); method @Nullable public boolean getIsCheckCrc(); method @Nullable public boolean getIsRaw(); method @Nullable public boolean getIsRepeat(); + method public void setBitWidthOfLengthField(@Nullable java.math.BigInteger); method public void setIsCheckCrc(@Nullable boolean); method public void setIsRaw(@Nullable boolean); method public void setIsRepeat(@Nullable boolean); diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd index 54cedfcf6b..94f108b43a 100644 --- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd +++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd @@ -226,6 +226,7 @@ + -- cgit v1.2.3 From 1eb12b29728adcbbe5b8694f671c67b8a624fe4a Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Sat, 11 Sep 2021 13:59:43 -0400 Subject: identity: Add multi-document presentation support. This new IPresentationSession interface enables an application to do a multi-document presentation, something which isn't possible with the existing API. As a practical example of this consider presenting both your Mobile Driving License and your Vaccination Certificate in a single transaction. Bug: 197965513 Test: New CTS tests and new screen in CtsVerifier Change-Id: I11712dca35df7f1224debf454731bc17ea9bfb37 --- .../compatibility_matrix.current.xml | 2 +- .../android/hardware/identity/Certificate.aidl | 3 +- .../android/hardware/identity/CipherSuite.aidl | 3 +- .../hardware/identity/HardwareInformation.aidl | 3 +- .../hardware/identity/IIdentityCredential.aidl | 3 +- .../identity/IIdentityCredentialStore.aidl | 4 +- .../hardware/identity/IPresentationSession.aidl | 42 +++ .../identity/IWritableIdentityCredential.aidl | 3 +- .../android/hardware/identity/RequestDataItem.aidl | 3 +- .../hardware/identity/RequestNamespace.aidl | 3 +- .../identity/SecureAccessControlProfile.aidl | 3 +- .../hardware/identity/IIdentityCredential.aidl | 26 +- .../identity/IIdentityCredentialStore.aidl | 28 +- .../hardware/identity/IPresentationSession.aidl | 101 +++++ identity/aidl/default/Android.bp | 10 +- identity/aidl/default/EicOpsImpl.cc | 30 +- identity/aidl/default/EicTests.cpp | 3 +- identity/aidl/default/FakeSecureHardwareProxy.cpp | 406 ++++++++++++++++++--- identity/aidl/default/FakeSecureHardwareProxy.h | 103 +++++- .../android.hardware.identity_credential.xml | 2 +- .../aidl/default/common/IdentityCredential.cpp | 241 +++++++++--- identity/aidl/default/common/IdentityCredential.h | 15 +- .../default/common/IdentityCredentialStore.cpp | 27 +- .../aidl/default/common/IdentityCredentialStore.h | 3 + .../aidl/default/common/PresentationSession.cpp | 149 ++++++++ identity/aidl/default/common/PresentationSession.h | 83 +++++ identity/aidl/default/common/SecureHardwareProxy.h | 52 ++- identity/aidl/default/identity-default.xml | 2 +- identity/aidl/default/libeic/EicCommon.h | 3 + identity/aidl/default/libeic/EicOps.h | 12 + identity/aidl/default/libeic/EicPresentation.c | 108 +++++- identity/aidl/default/libeic/EicPresentation.h | 22 +- identity/aidl/default/libeic/EicProvisioning.c | 35 ++ identity/aidl/default/libeic/EicProvisioning.h | 7 + identity/aidl/default/libeic/EicSession.c | 120 ++++++ identity/aidl/default/libeic/EicSession.h | 73 ++++ identity/aidl/default/libeic/libeic.h | 3 +- identity/aidl/vts/Android.bp | 7 +- identity/aidl/vts/PresentationSessionTests.cpp | 197 ++++++++++ 39 files changed, 1774 insertions(+), 166 deletions(-) create mode 100644 identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.aidl create mode 100644 identity/aidl/android/hardware/identity/IPresentationSession.aidl create mode 100644 identity/aidl/default/common/PresentationSession.cpp create mode 100644 identity/aidl/default/common/PresentationSession.h create mode 100644 identity/aidl/default/libeic/EicSession.c create mode 100644 identity/aidl/default/libeic/EicSession.h create mode 100644 identity/aidl/vts/PresentationSessionTests.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index fcff6bcbd4..eeff7bb64a 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -285,7 +285,7 @@ android.hardware.identity - 1-3 + 1-4 IIdentityCredentialStore default diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl index d8a8128c8e..83e1797386 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl @@ -12,7 +12,8 @@ * 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. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl index 2685525044..e6ec04e805 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl @@ -12,7 +12,8 @@ * 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. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl index f8d5a9e7e6..cd8d56b5bd 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl @@ -12,7 +12,8 @@ * 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. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl index 3224e4bf06..5065641109 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl @@ -12,7 +12,8 @@ * 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. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl index c6fb3c889e..c912c526ab 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl @@ -12,7 +12,8 @@ * 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. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -36,6 +37,7 @@ interface IIdentityCredentialStore { android.hardware.identity.HardwareInformation getHardwareInformation(); android.hardware.identity.IWritableIdentityCredential createCredential(in @utf8InCpp String docType, in boolean testCredential); android.hardware.identity.IIdentityCredential getCredential(in android.hardware.identity.CipherSuite cipherSuite, in byte[] credentialData); + android.hardware.identity.IPresentationSession createPresentationSession(in android.hardware.identity.CipherSuite cipherSuite); const int STATUS_OK = 0; const int STATUS_FAILED = 1; const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2; diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.aidl new file mode 100644 index 0000000000..705dc292c5 --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.aidl @@ -0,0 +1,42 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.identity; +@VintfStability +interface IPresentationSession { + byte[] getEphemeralKeyPair(); + long getAuthChallenge(); + void setReaderEphemeralPublicKey(in byte[] publicKey); + void setSessionTranscript(in byte[] sessionTranscript); + android.hardware.identity.IIdentityCredential getCredential(in byte[] credentialData); +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl index 19a29ec719..9a0fa9e9e5 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl @@ -12,7 +12,8 @@ * 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. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl index c9c2b9fec6..cec8e0c94d 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl @@ -12,7 +12,8 @@ * 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. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl index aaf1e20f1d..05b9ec295f 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl @@ -12,7 +12,8 @@ * 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. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl index 695fb3fb26..2003594eb4 100644 --- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl +++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl @@ -12,7 +12,8 @@ * 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. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl index 8ae293b2d3..84d6ed0e8a 100644 --- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl +++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl @@ -17,9 +17,9 @@ package android.hardware.identity; import android.hardware.identity.Certificate; +import android.hardware.identity.IWritableIdentityCredential; import android.hardware.identity.RequestNamespace; import android.hardware.identity.SecureAccessControlProfile; -import android.hardware.identity.IWritableIdentityCredential; import android.hardware.keymaster.HardwareAuthToken; import android.hardware.keymaster.VerificationToken; @@ -44,6 +44,9 @@ interface IIdentityCredential { * This method was deprecated in API version 3 because there's no challenge so freshness * can't be checked. Use deleteCredentalWithChallenge() instead. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @return a COSE_Sign1 signature described above * @deprecated use deleteCredentalWithChallenge() instead. */ @@ -60,6 +63,9 @@ interface IIdentityCredential { * This method may only be called once per instance. If called more than once, STATUS_FAILED * will be returned. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @return the private key, in DER format as specified in RFC 5915. */ byte[] createEphemeralKeyPair(); @@ -70,6 +76,9 @@ interface IIdentityCredential { * This method may only be called once per instance. If called more than once, STATUS_FAILED * will be returned. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @param publicKey contains the reader's ephemeral public key, in uncompressed * form (e.g. 0x04 || X || Y). */ @@ -83,6 +92,9 @@ interface IIdentityCredential { * This method may only be called once per instance. If called more than once, STATUS_FAILED * will be returned. If user authentication is not needed, this method may not be called. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @return challenge, a non-zero number. */ long createAuthChallenge(); @@ -371,6 +383,9 @@ interface IIdentityCredential { * This CBOR enables an issuer to determine the exact state of the credential it * returns issuer-signed data for. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @param out signingKeyBlob contains an AES-GCM-ENC(storageKey, R, signingKey, docType) * where signingKey is an EC private key in uncompressed form. That is, the returned * blob is an encrypted copy of the newly-generated private signing key. @@ -420,6 +435,9 @@ interface IIdentityCredential { * * This method was introduced in API version 3. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes. * @return a COSE_Sign1 signature described above. @@ -442,6 +460,9 @@ interface IIdentityCredential { * * This method was introduced in API version 3. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes. * @return a COSE_Sign1 signature described above. @@ -456,6 +477,9 @@ interface IIdentityCredential { * * This method was introduced in API version 3. * + * If the method is called on an instance obtained via IPresentationSession.getCredential(), + * STATUS_FAILED must be returned. + * * @return an IWritableIdentityCredential */ IWritableIdentityCredential updateCredential(); diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl index 638be796c4..86be7f5879 100644 --- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl +++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl @@ -16,10 +16,11 @@ package android.hardware.identity; +import android.hardware.identity.CipherSuite; +import android.hardware.identity.HardwareInformation; import android.hardware.identity.IIdentityCredential; +import android.hardware.identity.IPresentationSession; import android.hardware.identity.IWritableIdentityCredential; -import android.hardware.identity.HardwareInformation; -import android.hardware.identity.CipherSuite; /** * IIdentityCredentialStore provides an interface to a secure store for user identity documents. @@ -105,7 +106,7 @@ import android.hardware.identity.CipherSuite; * STATUS_* integers defined in this interface. Each method states which status can be returned * and under which circumstances. * - * The API described here is API version 3 which corresponds to feature version 202101 + * The API described here is API version 4 which corresponds to feature version 202201 * of the android.security.identity Framework API. An XML file declaring the feature * android.hardware.identity_credential (or android.hardware.identity_credential.direct_access * if implementing the Direct Access HAL) should be included declaring this feature version. @@ -241,4 +242,25 @@ interface IIdentityCredentialStore { * @return an IIdentityCredential interface that provides operations on the Credential. */ IIdentityCredential getCredential(in CipherSuite cipherSuite, in byte[] credentialData); + + /** + * createPresentationSession creates IPresentationSession interface which can be used to + * present one or more credentials to a remote verifier device. + * + * The cipher suite used to communicate with the remote verifier must be specified. Currently + * only a single cipher-suite is supported. Support for other cipher suites may be added in a + * future version of this HAL. If the requested cipher suite is not support the call fails + * with STATUS_CIPHER_SUITE_NOT_SUPPORTED. + * + * In this version of the HAL, implementations are only required to support a single session + * being active. In a future version, implementations may be required to support multiple + * presentation sessions being active at the same time. + * + * This method was introduced in API version 4. + * + * @param cipherSuite The cipher suite to use. + * + * @return an IPresentationSession interface. + */ + IPresentationSession createPresentationSession(in CipherSuite cipherSuite); } diff --git a/identity/aidl/android/hardware/identity/IPresentationSession.aidl b/identity/aidl/android/hardware/identity/IPresentationSession.aidl new file mode 100644 index 0000000000..b0449f0bba --- /dev/null +++ b/identity/aidl/android/hardware/identity/IPresentationSession.aidl @@ -0,0 +1,101 @@ +/* + * Copyright 2021 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.identity; + +import android.hardware.identity.CipherSuite; +import android.hardware.identity.IIdentityCredential; + +/** + * An interface to present multiple credentials in the same session. + * + * This interface was introduced in API version 4. + * + */ +@VintfStability +interface IPresentationSession { + /** + * Gets the ephemeral EC key pair to be used in establishing a secure session with a reader. + * This method returns the private key so the caller can perform an ECDH key agreement operation + * with the reader. The reason for generating the key pair in the secure environment is so that + * the secure environment knows what public key to expect to find in the session transcript + * when presenting credentials. + * + * The generated key matches the selected cipher suite of the presentation session (e.g. EC + * key using the P-256 curve). + * + * @return the private key, in DER format as specified in RFC 5915. + */ + byte[] getEphemeralKeyPair(); + + /** + * Gets the challenge value to be used for proving successful user authentication. This + * is to be included in the authToken passed to the IIdentityCredential.startRetrieval() + * method and the verificationToken passed to the IIdentityCredential.setVerificationToken() + * method. + * + * @return challenge, a non-zero number. + */ + long getAuthChallenge(); + + /** + * Sets the public part of the reader's ephemeral key pair to be used to complete + * an ECDH key agreement for the session. + * + * The curve of the key must match the curve for the key returned by getEphemeralKeyPair(). + * + * This method may only be called once per instance. If called more than once, STATUS_FAILED + * must be returned. + * + * @param publicKey contains the reader's ephemeral public key, in uncompressed + * form (e.g. 0x04 || X || Y). + */ + void setReaderEphemeralPublicKey(in byte[] publicKey); + + /** + * Sets the session transcript for the session. + * + * This can be empty but if it's non-empty it must be valid CBOR. + * + * This method may only be called once per instance. If called more than once, STATUS_FAILED + * must be returned. + * + * @param sessionTrancsript the session transcript. + */ + void setSessionTranscript(in byte[] sessionTranscript); + + /** + * getCredential() retrieves an IIdentityCredential interface for presentation in the + * current presentation session. + * + * On the returned instance only the methods startRetrieval(), startRetrieveEntryValue(), + * retrieveEntryValue(), finishRetrieval(), setRequestedNamespaces(), setVerificationToken() + * may be called. Other methods will fail with STATUS_FAILED. + * + * The implementation is expected to get the session transcript, ephemeral key, reader + * ephemeral key, and auth challenge from this instance. + * + * @param credentialData is a CBOR-encoded structure containing metadata about the credential + * and an encrypted byte array that contains data used to secure the credential. See the + * return argument of the same name in IWritableIdentityCredential.finishAddingEntries(). + * + * Note that the format of credentialData may depend on the feature version. + * Implementations must support credentialData created by an earlier feature version. + * + * @return an IIdentityCredential interface that provides operations on the Credential. + */ + IIdentityCredential getCredential(in byte[] credentialData); +} diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp index 3de8d30148..ca24afa6cc 100644 --- a/identity/aidl/default/Android.bp +++ b/identity/aidl/default/Android.bp @@ -13,6 +13,7 @@ cc_library_static { srcs: [ "common/IdentityCredential.cpp", "common/IdentityCredentialStore.cpp", + "common/PresentationSession.cpp", "common/WritableIdentityCredential.cpp", ], export_include_dirs: [ @@ -39,8 +40,8 @@ cc_library_static { "libsoft_attestation_cert", "libpuresoftkeymasterdevice", "android.hardware.identity-support-lib", - "android.hardware.identity-V3-ndk", - "android.hardware.keymaster-V3-ndk", + "android.hardware.identity-V4-ndk", + "android.hardware.keymaster-V4-ndk", ], } @@ -49,6 +50,7 @@ cc_library_static { vendor_available: true, srcs: [ "libeic/EicCbor.c", + "libeic/EicSession.c", "libeic/EicPresentation.c", "libeic/EicProvisioning.c", "EicOpsImpl.cc", @@ -100,8 +102,8 @@ cc_binary { "libsoft_attestation_cert", "libpuresoftkeymasterdevice", "android.hardware.identity-support-lib", - "android.hardware.identity-V3-ndk", - "android.hardware.keymaster-V3-ndk", + "android.hardware.identity-V4-ndk", + "android.hardware.keymaster-V4-ndk", "android.hardware.identity-libeic-hal-common", "android.hardware.identity-libeic-library", ], diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc index 8ec4cc9b58..c98a91ebc3 100644 --- a/identity/aidl/default/EicOpsImpl.cc +++ b/identity/aidl/default/EicOpsImpl.cc @@ -20,9 +20,13 @@ #include #include +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include + #include #include -#include #include @@ -63,6 +67,11 @@ size_t eicStrLen(const char* s) { return strlen(s); } +void* eicMemMem(const uint8_t* haystack, size_t haystackLen, const uint8_t* needle, + size_t needleLen) { + return memmem(haystack, haystackLen, needle, needleLen); +} + int eicCryptoMemCmp(const void* s1, const void* s2, size_t n) { return CRYPTO_memcmp(s1, s2, n); } @@ -117,6 +126,25 @@ bool eicOpsRandom(uint8_t* buf, size_t numBytes) { return true; } +bool eicNextId(uint32_t* id) { + uint32_t oldId = *id; + uint32_t newId = 0; + + do { + union { + uint8_t value8; + uint32_t value32; + } value; + if (!eicOpsRandom(&value.value8, sizeof(value))) { + return false; + } + newId = value.value32; + } while (newId == oldId && newId == 0); + + *id = newId; + return true; +} + bool eicOpsEncryptAes128Gcm( const uint8_t* key, // Must be 16 bytes const uint8_t* nonce, // Must be 12 bytes diff --git a/identity/aidl/default/EicTests.cpp b/identity/aidl/default/EicTests.cpp index a28080d009..7b69b75acd 100644 --- a/identity/aidl/default/EicTests.cpp +++ b/identity/aidl/default/EicTests.cpp @@ -66,7 +66,8 @@ TEST(EicTest, AccessControlIsEnforced) { // Then present data from it... // FakeSecureHardwarePresentationProxy presentationProxy; - ASSERT_TRUE(presentationProxy.initialize(isTestCredential, docType, credData.value())); + ASSERT_TRUE(presentationProxy.initialize(0 /* sessionId */, isTestCredential, docType, + credData.value())); AccessCheckResult res = presentationProxy.startRetrieveEntryValue(nameSpace, name, 1, content.size(), acpIds); ASSERT_EQ(res, AccessCheckResult::kNoAccessControlProfiles); diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp index f0307dc324..91e634c0c3 100644 --- a/identity/aidl/default/FakeSecureHardwareProxy.cpp +++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -52,38 +53,110 @@ namespace android::hardware::identity { // ---------------------------------------------------------------------- -FakeSecureHardwareProvisioningProxy::FakeSecureHardwareProvisioningProxy() {} +// The singleton EicProvisioning object used everywhere. +// +EicProvisioning FakeSecureHardwareProvisioningProxy::ctx_; -FakeSecureHardwareProvisioningProxy::~FakeSecureHardwareProvisioningProxy() {} - -bool FakeSecureHardwareProvisioningProxy::shutdown() { - LOG(INFO) << "FakeSecureHardwarePresentationProxy shutdown"; - return true; +FakeSecureHardwareProvisioningProxy::~FakeSecureHardwareProvisioningProxy() { + if (id_ != 0) { + shutdown(); + } } bool FakeSecureHardwareProvisioningProxy::initialize(bool testCredential) { - LOG(INFO) << "FakeSecureHardwareProvisioningProxy created, sizeof(EicProvisioning): " - << sizeof(EicProvisioning); - return eicProvisioningInit(&ctx_, testCredential); + if (id_ != 0) { + LOG(WARNING) << "Proxy is already initialized"; + return false; + } + bool initialized = eicProvisioningInit(&ctx_, testCredential); + if (!initialized) { + return false; + } + optional id = getId(); + if (!id) { + LOG(WARNING) << "Error getting id"; + return false; + } + id_ = id.value(); + return true; } bool FakeSecureHardwareProvisioningProxy::initializeForUpdate( - bool testCredential, string docType, vector encryptedCredentialKeys) { - return eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(), - docType.size(), - encryptedCredentialKeys.data(), - encryptedCredentialKeys.size()); + bool testCredential, const string& docType, + const vector& encryptedCredentialKeys) { + if (id_ != 0) { + LOG(WARNING) << "Proxy is already initialized"; + return false; + } + bool initialized = eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(), + docType.size(), encryptedCredentialKeys.data(), + encryptedCredentialKeys.size()); + if (!initialized) { + return false; + } + optional id = getId(); + if (!id) { + LOG(WARNING) << "Error getting id"; + return false; + } + id_ = id.value(); + return true; +} + +optional FakeSecureHardwareProvisioningProxy::getId() { + uint32_t id; + if (!eicProvisioningGetId(&ctx_, &id)) { + return std::nullopt; + } + return id; +} + +bool FakeSecureHardwareProvisioningProxy::validateId(const string& callerName) { + if (id_ == 0) { + LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName + << ": While validating expected id is 0"; + return false; + } + optional id = getId(); + if (!id) { + LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName + << ": Error getting id for validating"; + return false; + } + if (id.value() != id_) { + LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName + << ": While validating expected id " << id_ << " but got " << id.value(); + return false; + } + return true; +} + +bool FakeSecureHardwareProvisioningProxy::shutdown() { + bool validated = validateId(__func__); + id_ = 0; + if (!validated) { + return false; + } + if (!eicProvisioningShutdown(&ctx_)) { + LOG(INFO) << "Error shutting down provisioning"; + return false; + } + return true; } // Returns public key certificate. optional> FakeSecureHardwareProvisioningProxy::createCredentialKey( const vector& challenge, const vector& applicationId) { + if (!validateId(__func__)) { + return std::nullopt; + } + uint8_t publicKeyCert[4096]; size_t publicKeyCertSize = sizeof publicKeyCert; if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(), applicationId.data(), applicationId.size(), publicKeyCert, &publicKeyCertSize)) { - return {}; + return std::nullopt; } vector pubKeyCert(publicKeyCertSize); memcpy(pubKeyCert.data(), publicKeyCert, publicKeyCertSize); @@ -91,8 +164,11 @@ optional> FakeSecureHardwareProvisioningProxy::createCredentialK } bool FakeSecureHardwareProvisioningProxy::startPersonalization( - int accessControlProfileCount, vector entryCounts, const string& docType, + int accessControlProfileCount, const vector& entryCounts, const string& docType, size_t expectedProofOfProvisioningSize) { + if (!validateId(__func__)) { + return false; + } if (!eicProvisioningStartPersonalization(&ctx_, accessControlProfileCount, entryCounts.data(), @@ -108,13 +184,17 @@ bool FakeSecureHardwareProvisioningProxy::startPersonalization( optional> FakeSecureHardwareProvisioningProxy::addAccessControlProfile( int id, const vector& readerCertificate, bool userAuthenticationRequired, uint64_t timeoutMillis, uint64_t secureUserId) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector mac(28); uint8_t scratchSpace[512]; if (!eicProvisioningAddAccessControlProfile( &ctx_, id, readerCertificate.data(), readerCertificate.size(), userAuthenticationRequired, timeoutMillis, secureUserId, mac.data(), scratchSpace, sizeof(scratchSpace))) { - return {}; + return std::nullopt; } return mac; } @@ -122,6 +202,10 @@ optional> FakeSecureHardwareProvisioningProxy::addAccessControlP bool FakeSecureHardwareProvisioningProxy::beginAddEntry(const vector& accessControlProfileIds, const string& nameSpace, const string& name, uint64_t entrySize) { + if (!validateId(__func__)) { + return false; + } + uint8_t scratchSpace[512]; vector uint8AccessControlProfileIds; for (size_t i = 0; i < accessControlProfileIds.size(); i++) { @@ -138,6 +222,10 @@ bool FakeSecureHardwareProvisioningProxy::beginAddEntry(const vector& acces optional> FakeSecureHardwareProvisioningProxy::addEntryValue( const vector& accessControlProfileIds, const string& nameSpace, const string& name, const vector& content) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector eicEncryptedContent; uint8_t scratchSpace[512]; vector uint8AccessControlProfileIds; @@ -150,16 +238,20 @@ optional> FakeSecureHardwareProvisioningProxy::addEntryValue( &ctx_, uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(), nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(), content.data(), content.size(), eicEncryptedContent.data(), scratchSpace, sizeof(scratchSpace))) { - return {}; + return std::nullopt; } return eicEncryptedContent; } // Returns signatureOfToBeSigned (EIC_ECDSA_P256_SIGNATURE_SIZE bytes). optional> FakeSecureHardwareProvisioningProxy::finishAddingEntries() { + if (!validateId(__func__)) { + return std::nullopt; + } + vector signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); if (!eicProvisioningFinishAddingEntries(&ctx_, signatureOfToBeSigned.data())) { - return {}; + return std::nullopt; } return signatureOfToBeSigned; } @@ -167,11 +259,15 @@ optional> FakeSecureHardwareProvisioningProxy::finishAddingEntri // Returns encryptedCredentialKeys. optional> FakeSecureHardwareProvisioningProxy::finishGetCredentialData( const string& docType) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector encryptedCredentialKeys(116); size_t size = encryptedCredentialKeys.size(); if (!eicProvisioningFinishGetCredentialData(&ctx_, docType.c_str(), docType.size(), encryptedCredentialKeys.data(), &size)) { - return {}; + return std::nullopt; } encryptedCredentialKeys.resize(size); return encryptedCredentialKeys; @@ -179,21 +275,200 @@ optional> FakeSecureHardwareProvisioningProxy::finishGetCredenti // ---------------------------------------------------------------------- -FakeSecureHardwarePresentationProxy::FakeSecureHardwarePresentationProxy() {} +// The singleton EicSession object used everywhere. +// +EicSession FakeSecureHardwareSessionProxy::ctx_; + +FakeSecureHardwareSessionProxy::~FakeSecureHardwareSessionProxy() { + if (id_ != 0) { + shutdown(); + } +} + +bool FakeSecureHardwareSessionProxy::initialize() { + if (id_ != 0) { + LOG(WARNING) << "Proxy is already initialized"; + return false; + } + bool initialized = eicSessionInit(&ctx_); + if (!initialized) { + return false; + } + optional id = getId(); + if (!id) { + LOG(WARNING) << "Error getting id"; + return false; + } + id_ = id.value(); + return true; +} + +optional FakeSecureHardwareSessionProxy::getId() { + uint32_t id; + if (!eicSessionGetId(&ctx_, &id)) { + return std::nullopt; + } + return id; +} + +bool FakeSecureHardwareSessionProxy::shutdown() { + bool validated = validateId(__func__); + id_ = 0; + if (!validated) { + return false; + } + if (!eicSessionShutdown(&ctx_)) { + LOG(INFO) << "Error shutting down session"; + return false; + } + return true; +} + +bool FakeSecureHardwareSessionProxy::validateId(const string& callerName) { + if (id_ == 0) { + LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName + << ": While validating expected id is 0"; + return false; + } + optional id = getId(); + if (!id) { + LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName + << ": Error getting id for validating"; + return false; + } + if (id.value() != id_) { + LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName + << ": While validating expected id " << id_ << " but got " << id.value(); + return false; + } + return true; +} -FakeSecureHardwarePresentationProxy::~FakeSecureHardwarePresentationProxy() {} +optional FakeSecureHardwareSessionProxy::getAuthChallenge() { + if (!validateId(__func__)) { + return std::nullopt; + } -bool FakeSecureHardwarePresentationProxy::initialize(bool testCredential, string docType, - vector encryptedCredentialKeys) { - LOG(INFO) << "FakeSecureHardwarePresentationProxy created, sizeof(EicPresentation): " - << sizeof(EicPresentation); - return eicPresentationInit(&ctx_, testCredential, docType.c_str(), docType.size(), - encryptedCredentialKeys.data(), encryptedCredentialKeys.size()); + uint64_t authChallenge; + if (!eicSessionGetAuthChallenge(&ctx_, &authChallenge)) { + return std::nullopt; + } + return authChallenge; +} + +optional> FakeSecureHardwareSessionProxy::getEphemeralKeyPair() { + if (!validateId(__func__)) { + return std::nullopt; + } + + vector priv(EIC_P256_PRIV_KEY_SIZE); + if (!eicSessionGetEphemeralKeyPair(&ctx_, priv.data())) { + return std::nullopt; + } + return priv; +} + +bool FakeSecureHardwareSessionProxy::setReaderEphemeralPublicKey( + const vector& readerEphemeralPublicKey) { + if (!validateId(__func__)) { + return false; + } + + return eicSessionSetReaderEphemeralPublicKey(&ctx_, readerEphemeralPublicKey.data()); +} + +bool FakeSecureHardwareSessionProxy::setSessionTranscript( + const vector& sessionTranscript) { + if (!validateId(__func__)) { + return false; + } + + return eicSessionSetSessionTranscript(&ctx_, sessionTranscript.data(), + sessionTranscript.size()); +} + +// ---------------------------------------------------------------------- + +// The singleton EicPresentation object used everywhere. +// +EicPresentation FakeSecureHardwarePresentationProxy::ctx_; + +FakeSecureHardwarePresentationProxy::~FakeSecureHardwarePresentationProxy() { + if (id_ != 0) { + shutdown(); + } +} + +bool FakeSecureHardwarePresentationProxy::initialize( + uint32_t sessionId, bool testCredential, const string& docType, + const vector& encryptedCredentialKeys) { + if (id_ != 0) { + LOG(WARNING) << "Proxy is already initialized"; + return false; + } + bool initialized = + eicPresentationInit(&ctx_, sessionId, testCredential, docType.c_str(), docType.size(), + encryptedCredentialKeys.data(), encryptedCredentialKeys.size()); + if (!initialized) { + return false; + } + optional id = getId(); + if (!id) { + LOG(WARNING) << "Error getting id"; + return false; + } + id_ = id.value(); + return true; +} + +optional FakeSecureHardwarePresentationProxy::getId() { + uint32_t id; + if (!eicPresentationGetId(&ctx_, &id)) { + return std::nullopt; + } + return id; +} + +bool FakeSecureHardwarePresentationProxy::validateId(const string& callerName) { + if (id_ == 0) { + LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName + << ": While validating expected id is 0"; + return false; + } + optional id = getId(); + if (!id) { + LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName + << ": Error getting id for validating"; + return false; + } + if (id.value() != id_) { + LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName + << ": While validating expected id " << id_ << " but got " << id.value(); + return false; + } + return true; +} + +bool FakeSecureHardwarePresentationProxy::shutdown() { + bool validated = validateId(__func__); + id_ = 0; + if (!validated) { + return false; + } + if (!eicPresentationShutdown(&ctx_)) { + LOG(INFO) << "Error shutting down presentation"; + return false; + } + return true; } // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component) optional, vector>> -FakeSecureHardwarePresentationProxy::generateSigningKeyPair(string docType, time_t now) { +FakeSecureHardwarePresentationProxy::generateSigningKeyPair(const string& docType, time_t now) { + if (!validateId(__func__)) { + return std::nullopt; + } + uint8_t publicKeyCert[512]; size_t publicKeyCertSize = sizeof(publicKeyCert); vector signingKeyBlob(60); @@ -201,7 +476,7 @@ FakeSecureHardwarePresentationProxy::generateSigningKeyPair(string docType, time if (!eicPresentationGenerateSigningKeyPair(&ctx_, docType.c_str(), docType.size(), now, publicKeyCert, &publicKeyCertSize, signingKeyBlob.data())) { - return {}; + return std::nullopt; } vector cert; @@ -213,33 +488,44 @@ FakeSecureHardwarePresentationProxy::generateSigningKeyPair(string docType, time // Returns private key optional> FakeSecureHardwarePresentationProxy::createEphemeralKeyPair() { + if (!validateId(__func__)) { + return std::nullopt; + } + vector priv(EIC_P256_PRIV_KEY_SIZE); if (!eicPresentationCreateEphemeralKeyPair(&ctx_, priv.data())) { - return {}; + return std::nullopt; } return priv; } optional FakeSecureHardwarePresentationProxy::createAuthChallenge() { + if (!validateId(__func__)) { + return std::nullopt; + } + uint64_t challenge; if (!eicPresentationCreateAuthChallenge(&ctx_, &challenge)) { - return {}; + return std::nullopt; } return challenge; } -bool FakeSecureHardwarePresentationProxy::shutdown() { - LOG(INFO) << "FakeSecureHardwarePresentationProxy shutdown"; - return true; -} - bool FakeSecureHardwarePresentationProxy::pushReaderCert(const vector& certX509) { + if (!validateId(__func__)) { + return false; + } + return eicPresentationPushReaderCert(&ctx_, certX509.data(), certX509.size()); } bool FakeSecureHardwarePresentationProxy::validateRequestMessage( const vector& sessionTranscript, const vector& requestMessage, int coseSignAlg, const vector& readerSignatureOfToBeSigned) { + if (!validateId(__func__)) { + return false; + } + return eicPresentationValidateRequestMessage( &ctx_, sessionTranscript.data(), sessionTranscript.size(), requestMessage.data(), requestMessage.size(), coseSignAlg, readerSignatureOfToBeSigned.data(), @@ -251,6 +537,10 @@ bool FakeSecureHardwarePresentationProxy::setAuthToken( int hardwareAuthenticatorType, uint64_t timeStamp, const vector& mac, uint64_t verificationTokenChallenge, uint64_t verificationTokenTimestamp, int verificationTokenSecurityLevel, const vector& verificationTokenMac) { + if (!validateId(__func__)) { + return false; + } + return eicPresentationSetAuthToken(&ctx_, challenge, secureUserId, authenticatorId, hardwareAuthenticatorType, timeStamp, mac.data(), mac.size(), verificationTokenChallenge, verificationTokenTimestamp, @@ -261,6 +551,10 @@ bool FakeSecureHardwarePresentationProxy::setAuthToken( optional FakeSecureHardwarePresentationProxy::validateAccessControlProfile( int id, const vector& readerCertificate, bool userAuthenticationRequired, int timeoutMillis, uint64_t secureUserId, const vector& mac) { + if (!validateId(__func__)) { + return std::nullopt; + } + bool accessGranted = false; uint8_t scratchSpace[512]; if (!eicPresentationValidateAccessControlProfile(&ctx_, id, readerCertificate.data(), @@ -268,12 +562,16 @@ optional FakeSecureHardwarePresentationProxy::validateAccessControlProfile userAuthenticationRequired, timeoutMillis, secureUserId, mac.data(), &accessGranted, scratchSpace, sizeof(scratchSpace))) { - return {}; + return std::nullopt; } return accessGranted; } bool FakeSecureHardwarePresentationProxy::startRetrieveEntries() { + if (!validateId(__func__)) { + return false; + } + return eicPresentationStartRetrieveEntries(&ctx_); } @@ -281,6 +579,10 @@ bool FakeSecureHardwarePresentationProxy::calcMacKey( const vector& sessionTranscript, const vector& readerEphemeralPublicKey, const vector& signingKeyBlob, const string& docType, unsigned int numNamespacesWithValues, size_t expectedProofOfProvisioningSize) { + if (!validateId(__func__)) { + return false; + } + if (signingKeyBlob.size() != 60) { eicDebug("Unexpected size %zd of signingKeyBlob, expected 60", signingKeyBlob.size()); return false; @@ -294,6 +596,10 @@ bool FakeSecureHardwarePresentationProxy::calcMacKey( AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue( const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries, int32_t entrySize, const vector& accessControlProfileIds) { + if (!validateId(__func__)) { + return AccessCheckResult::kFailed; + } + uint8_t scratchSpace[512]; vector uint8AccessControlProfileIds; for (size_t i = 0; i < accessControlProfileIds.size(); i++) { @@ -324,6 +630,10 @@ AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue( optional> FakeSecureHardwarePresentationProxy::retrieveEntryValue( const vector& encryptedContent, const string& nameSpace, const string& name, const vector& accessControlProfileIds) { + if (!validateId(__func__)) { + return std::nullopt; + } + uint8_t scratchSpace[512]; vector uint8AccessControlProfileIds; for (size_t i = 0; i < accessControlProfileIds.size(); i++) { @@ -337,16 +647,20 @@ optional> FakeSecureHardwarePresentationProxy::retrieveEntryValu nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(), uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(), scratchSpace, sizeof(scratchSpace))) { - return {}; + return std::nullopt; } return content; } optional> FakeSecureHardwarePresentationProxy::finishRetrieval() { + if (!validateId(__func__)) { + return std::nullopt; + } + vector mac(32); size_t macSize = 32; if (!eicPresentationFinishRetrieval(&ctx_, mac.data(), &macSize)) { - return {}; + return std::nullopt; } mac.resize(macSize); return mac; @@ -355,11 +669,15 @@ optional> FakeSecureHardwarePresentationProxy::finishRetrieval() optional> FakeSecureHardwarePresentationProxy::deleteCredential( const string& docType, const vector& challenge, bool includeChallenge, size_t proofOfDeletionCborSize) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), docType.size(), challenge.data(), challenge.size(), includeChallenge, proofOfDeletionCborSize, signatureOfToBeSigned.data())) { - return {}; + return std::nullopt; } return signatureOfToBeSigned; } @@ -367,11 +685,15 @@ optional> FakeSecureHardwarePresentationProxy::deleteCredential( optional> FakeSecureHardwarePresentationProxy::proveOwnership( const string& docType, bool testCredential, const vector& challenge, size_t proofOfOwnershipCborSize) { + if (!validateId(__func__)) { + return std::nullopt; + } + vector signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); if (!eicPresentationProveOwnership(&ctx_, docType.c_str(), docType.size(), testCredential, challenge.data(), challenge.size(), proofOfOwnershipCborSize, signatureOfToBeSigned.data())) { - return {}; + return std::nullopt; } return signatureOfToBeSigned; } diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h index 6852c1a979..df98c7a121 100644 --- a/identity/aidl/default/FakeSecureHardwareProxy.h +++ b/identity/aidl/default/FakeSecureHardwareProxy.h @@ -27,21 +27,23 @@ namespace android::hardware::identity { // class FakeSecureHardwareProvisioningProxy : public SecureHardwareProvisioningProxy { public: - FakeSecureHardwareProvisioningProxy(); + FakeSecureHardwareProvisioningProxy() = default; virtual ~FakeSecureHardwareProvisioningProxy(); bool initialize(bool testCredential) override; - bool initializeForUpdate(bool testCredential, string docType, - vector encryptedCredentialKeys) override; + bool initializeForUpdate(bool testCredential, const string& docType, + const vector& encryptedCredentialKeys) override; bool shutdown() override; + optional getId() override; + // Returns public key certificate. optional> createCredentialKey(const vector& challenge, const vector& applicationId) override; - bool startPersonalization(int accessControlProfileCount, vector entryCounts, + bool startPersonalization(int accessControlProfileCount, const vector& entryCounts, const string& docType, size_t expectedProofOfProvisioningSize) override; @@ -67,21 +69,81 @@ class FakeSecureHardwareProvisioningProxy : public SecureHardwareProvisioningPro optional> finishGetCredentialData(const string& docType) override; protected: - EicProvisioning ctx_; + // See docs for id_. + // + bool validateId(const string& callerName); + + // We use a singleton libeic object, shared by all proxy instances. This is to + // properly simulate a situation where libeic is used on constrained hardware + // with only enough RAM for a single instance of the libeic object. + // + static EicProvisioning ctx_; + + // On the HAL side we keep track of the ID that was assigned to the libeic object + // created in secure hardware. For every call into libeic we validate that this + // identifier matches what is on the secure side. This is what the validateId() + // method does. + // + uint32_t id_ = 0; +}; + +// This implementation uses libEmbeddedIC in-process. +// +class FakeSecureHardwareSessionProxy : public SecureHardwareSessionProxy { + public: + FakeSecureHardwareSessionProxy() = default; + virtual ~FakeSecureHardwareSessionProxy(); + + bool initialize() override; + + bool shutdown() override; + + optional getId() override; + + optional getAuthChallenge() override; + + // Returns private key + optional> getEphemeralKeyPair() override; + + bool setReaderEphemeralPublicKey(const vector& readerEphemeralPublicKey) override; + + bool setSessionTranscript(const vector& sessionTranscript) override; + + protected: + // See docs for id_. + // + bool validateId(const string& callerName); + + // We use a singleton libeic object, shared by all proxy instances. This is to + // properly simulate a situation where libeic is used on constrained hardware + // with only enough RAM for a single instance of the libeic object. + // + static EicSession ctx_; + + // On the HAL side we keep track of the ID that was assigned to the libeic object + // created in secure hardware. For every call into libeic we validate that this + // identifier matches what is on the secure side. This is what the validateId() + // method does. + // + uint32_t id_ = 0; }; // This implementation uses libEmbeddedIC in-process. // class FakeSecureHardwarePresentationProxy : public SecureHardwarePresentationProxy { public: - FakeSecureHardwarePresentationProxy(); + FakeSecureHardwarePresentationProxy() = default; virtual ~FakeSecureHardwarePresentationProxy(); - bool initialize(bool testCredential, string docType, - vector encryptedCredentialKeys) override; + bool initialize(uint32_t sessionId, bool testCredential, const string& docType, + const vector& encryptedCredentialKeys) override; + + bool shutdown() override; + + optional getId() override; // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component) - optional, vector>> generateSigningKeyPair(string docType, + optional, vector>> generateSigningKeyPair(const string& docType, time_t now) override; // Returns private key @@ -133,10 +195,23 @@ class FakeSecureHardwarePresentationProxy : public SecureHardwarePresentationPro const vector& challenge, size_t proofOfOwnershipCborSize) override; - bool shutdown() override; - protected: - EicPresentation ctx_; + // See docs for id_. + // + bool validateId(const string& callerName); + + // We use a singleton libeic object, shared by all proxy instances. This is to + // properly simulate a situation where libeic is used on constrained hardware + // with only enough RAM for a single instance of the libeic object. + // + static EicPresentation ctx_; + + // On the HAL side we keep track of the ID that was assigned to the libeic object + // created in secure hardware. For every call into libeic we validate that this + // identifier matches what is on the secure side. This is what the validateId() + // method does. + // + uint32_t id_ = 0; }; // Factory implementation. @@ -150,6 +225,10 @@ class FakeSecureHardwareProxyFactory : public SecureHardwareProxyFactory { return new FakeSecureHardwareProvisioningProxy(); } + sp createSessionProxy() override { + return new FakeSecureHardwareSessionProxy(); + } + sp createPresentationProxy() override { return new FakeSecureHardwarePresentationProxy(); } diff --git a/identity/aidl/default/android.hardware.identity_credential.xml b/identity/aidl/default/android.hardware.identity_credential.xml index 5149792b7f..20b2710e1e 100644 --- a/identity/aidl/default/android.hardware.identity_credential.xml +++ b/identity/aidl/default/android.hardware.identity_credential.xml @@ -14,5 +14,5 @@ limitations under the License. --> - + diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp index 95557b5c9d..7678ecb918 100644 --- a/identity/aidl/default/common/IdentityCredential.cpp +++ b/identity/aidl/default/common/IdentityCredential.cpp @@ -72,14 +72,38 @@ int IdentityCredential::initialize() { testCredential_ = testCredentialItem->value(); encryptedCredentialKeys_ = encryptedCredentialKeysItem->value(); - if (!hwProxy_->initialize(testCredential_, docType_, encryptedCredentialKeys_)) { - LOG(ERROR) << "hwProxy->initialize failed"; - return false; + + // If in a session, delay the initialization of the proxy. + // + if (!session_) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + LOG(ERROR) << "Error initializing hw proxy"; + return IIdentityCredentialStore::STATUS_FAILED; + } } return IIdentityCredentialStore::STATUS_OK; } +ndk::ScopedAStatus IdentityCredential::ensureHwProxy() { + if (hwProxy_) { + return ndk::ScopedAStatus::ok(); + } + hwProxy_ = hwProxyFactory_->createPresentationProxy(); + if (!hwProxy_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Error creating hw proxy")); + } + uint64_t sessionId = session_ ? session_->getSessionId() : EIC_PRESENTATION_ID_UNSET; + if (!hwProxy_->initialize(sessionId, testCredential_, docType_, encryptedCredentialKeys_)) { + hwProxy_.clear(); + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Error initializing hw proxy")); + } + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus IdentityCredential::deleteCredential( vector* outProofOfDeletionSignature) { return deleteCredentialCommon({}, false, outProofOfDeletionSignature); @@ -93,6 +117,14 @@ ndk::ScopedAStatus IdentityCredential::deleteCredentialWithChallenge( ndk::ScopedAStatus IdentityCredential::deleteCredentialCommon( const vector& challenge, bool includeChallenge, vector* outProofOfDeletionSignature) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } if (challenge.size() > 32) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big")); @@ -128,6 +160,14 @@ ndk::ScopedAStatus IdentityCredential::deleteCredentialCommon( ndk::ScopedAStatus IdentityCredential::proveOwnership( const vector& challenge, vector* outProofOfOwnershipSignature) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } if (challenge.size() > 32) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big")); @@ -159,6 +199,14 @@ ndk::ScopedAStatus IdentityCredential::proveOwnership( } ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector* outKeyPair) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } optional> ephemeralPriv = hwProxy_->createEphemeralKeyPair(); if (!ephemeralPriv) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( @@ -186,11 +234,23 @@ ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector* o ndk::ScopedAStatus IdentityCredential::setReaderEphemeralPublicKey( const vector& publicKey) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } readerPublicKey_ = publicKey; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus IdentityCredential::createAuthChallenge(int64_t* outChallenge) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } optional challenge = hwProxy_->createAuthChallenge(); if (!challenge) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( @@ -217,16 +277,22 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( const HardwareAuthToken& authToken, const vector& itemsRequest, const vector& signingKeyBlob, const vector& sessionTranscript, const vector& readerSignature, const vector& requestCounts) { - std::unique_ptr sessionTranscriptItem; - if (sessionTranscript.size() > 0) { - auto [item, _, message] = cppbor::parse(sessionTranscript); - if (item == nullptr) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + + // If in a session, ensure the passed-in session transcript matches the + // session transcript from the session. + if (session_) { + if (sessionTranscript != session_->getSessionTranscript()) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_INVALID_DATA, - "SessionTranscript contains invalid CBOR")); + IIdentityCredentialStore::STATUS_SESSION_TRANSCRIPT_MISMATCH, + "In a session and passed-in SessionTranscript doesn't match the one " + "from the session")); } - sessionTranscriptItem = std::move(item); } + if (numStartRetrievalCalls_ > 0) { if (sessionTranscript_ != sessionTranscript) { LOG(ERROR) << "Session Transcript changed"; @@ -390,32 +456,36 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( } } - // TODO: move this check to the TA -#if 1 - // To prevent replay-attacks, we check that the public part of the ephemeral - // key we previously created, is present in the DeviceEngagement part of - // SessionTranscript as a COSE_Key, in uncompressed form. - // - // We do this by just searching for the X and Y coordinates. - if (sessionTranscript.size() > 0) { - auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_); - if (!getXYSuccess) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, - "Error extracting X and Y from ePub")); - } - if (sessionTranscript.size() > 0 && - !(memmem(sessionTranscript.data(), sessionTranscript.size(), ePubX.data(), - ePubX.size()) != nullptr && - memmem(sessionTranscript.data(), sessionTranscript.size(), ePubY.data(), - ePubY.size()) != nullptr)) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, - "Did not find ephemeral public key's X and Y coordinates in " - "SessionTranscript (make sure leading zeroes are not used)")); + if (session_) { + // If presenting in a session, the TA has already done this check. + + } else { + // To prevent replay-attacks, we check that the public part of the ephemeral + // key we previously created, is present in the DeviceEngagement part of + // SessionTranscript as a COSE_Key, in uncompressed form. + // + // We do this by just searching for the X and Y coordinates. + // + // Would be nice to move this check to the TA. + if (sessionTranscript.size() > 0) { + auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_); + if (!getXYSuccess) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, + "Error extracting X and Y from ePub")); + } + if (sessionTranscript.size() > 0 && + !(memmem(sessionTranscript.data(), sessionTranscript.size(), ePubX.data(), + ePubX.size()) != nullptr && + memmem(sessionTranscript.data(), sessionTranscript.size(), ePubY.data(), + ePubY.size()) != nullptr)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, + "Did not find ephemeral public key's X and Y coordinates in " + "SessionTranscript (make sure leading zeroes are not used)")); + } } } -#endif // itemsRequest: If non-empty, contains request data that may be signed by the // reader. The content can be defined in the way appropriate for the @@ -537,21 +607,38 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( // Finally, pass info so the HMAC key can be derived and the TA can start // creating the DeviceNameSpaces CBOR... - if (sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0 && signingKeyBlob.size() > 0) { - // We expect the reader ephemeral public key to be same size and curve - // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH - // won't work. So its length should be 65 bytes and it should be - // starting with 0x04. - if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_FAILED, - "Reader public key is not in expected format")); + if (!session_) { + if (sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0 && + signingKeyBlob.size() > 0) { + // We expect the reader ephemeral public key to be same size and curve + // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH + // won't work. So its length should be 65 bytes and it should be + // starting with 0x04. + if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Reader public key is not in expected format")); + } + vector pubKeyP256(readerPublicKey_.begin() + 1, readerPublicKey_.end()); + if (!hwProxy_->calcMacKey(sessionTranscript_, pubKeyP256, signingKeyBlob, docType_, + numNamespacesWithValues, expectedDeviceNameSpacesSize_)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Error starting retrieving entries")); + } } - vector pubKeyP256(readerPublicKey_.begin() + 1, readerPublicKey_.end()); - if (!hwProxy_->calcMacKey(sessionTranscript_, pubKeyP256, signingKeyBlob, docType_, - numNamespacesWithValues, expectedDeviceNameSpacesSize_)) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_FAILED, "Error starting retrieving entries")); + } else { + if (session_->getSessionTranscript().size() > 0 && + session_->getReaderEphemeralPublicKey().size() > 0 && signingKeyBlob.size() > 0) { + // Don't actually pass the reader ephemeral public key in, the TA will get + // it from the session object. + // + if (!hwProxy_->calcMacKey(sessionTranscript_, {}, signingKeyBlob, docType_, + numNamespacesWithValues, expectedDeviceNameSpacesSize_)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Error starting retrieving entries")); + } } } @@ -665,6 +752,11 @@ void IdentityCredential::calcDeviceNameSpacesSize(uint32_t accessControlProfileM ndk::ScopedAStatus IdentityCredential::startRetrieveEntryValue( const string& nameSpace, const string& name, int32_t entrySize, const vector& accessControlProfileIds) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + if (name.empty()) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, "Name cannot be empty")); @@ -785,6 +877,11 @@ ndk::ScopedAStatus IdentityCredential::startRetrieveEntryValue( ndk::ScopedAStatus IdentityCredential::retrieveEntryValue(const vector& encryptedContent, vector* outContent) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + optional> content = hwProxy_->retrieveEntryValue( encryptedContent, currentNameSpace_, currentName_, currentAccessControlProfileIds_); if (!content) { @@ -829,6 +926,11 @@ ndk::ScopedAStatus IdentityCredential::retrieveEntryValue(const vector& ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector* outMac, vector* outDeviceNameSpaces) { + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) { deviceNameSpacesMap_.add(currentNameSpace_, std::move(currentNameSpaceDeviceNameSpacesMap_)); @@ -846,18 +948,23 @@ ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector* outMac, .c_str())); } - // If there's no signing key or no sessionTranscript or no reader ephemeral - // public key, we return the empty MAC. + // If the TA calculated a MAC (it might not have), format it as a COSE_Mac0 + // optional> mac; - if (signingKeyBlob_.size() > 0 && sessionTranscript_.size() > 0 && - readerPublicKey_.size() > 0) { - optional> digestToBeMaced = hwProxy_->finishRetrieval(); - if (!digestToBeMaced || digestToBeMaced.value().size() != 32) { + optional> digestToBeMaced = hwProxy_->finishRetrieval(); + + // The MAC not being set means an error occurred. + if (!digestToBeMaced) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_INVALID_DATA, "Error generating digestToBeMaced")); + } + // Size 0 means that the MAC isn't set. If it's set, it has to be 32 bytes. + if (digestToBeMaced.value().size() != 0) { + if (digestToBeMaced.value().size() != 32) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, - "Error generating digestToBeMaced")); + "Unexpected size for digestToBeMaced")); } - // Now construct COSE_Mac0 from the returned MAC... mac = support::coseMacWithDigest(digestToBeMaced.value(), {} /* data */); } @@ -868,6 +975,15 @@ ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector* outMac, ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair( vector* outSigningKeyBlob, Certificate* outSigningKeyCertificate) { + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + ndk::ScopedAStatus status = ensureHwProxy(); + if (!status.isOk()) { + return status; + } + time_t now = time(NULL); optional, vector>> pair = hwProxy_->generateSigningKeyPair(docType_, now); @@ -885,9 +1001,18 @@ ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair( ndk::ScopedAStatus IdentityCredential::updateCredential( shared_ptr* outWritableCredential) { - sp hwProxy = hwProxyFactory_->createProvisioningProxy(); + if (session_) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session")); + } + sp provisioningHwProxy = + hwProxyFactory_->createProvisioningProxy(); + if (!provisioningHwProxy) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, "Error creating provisioning proxy")); + } shared_ptr wc = - ndk::SharedRefBase::make(hwProxy, docType_, + ndk::SharedRefBase::make(provisioningHwProxy, docType_, testCredential_); if (!wc->initializeForUpdate(encryptedCredentialKeys_)) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h index ef9d13351c..2935fb80a7 100644 --- a/identity/aidl/default/common/IdentityCredential.h +++ b/identity/aidl/default/common/IdentityCredential.h @@ -30,6 +30,7 @@ #include #include "IdentityCredentialStore.h" +#include "PresentationSession.h" #include "SecureHardwareProxy.h" namespace aidl::android::hardware::identity { @@ -46,11 +47,11 @@ using ::std::vector; class IdentityCredential : public BnIdentityCredential { public: IdentityCredential(sp hwProxyFactory, - sp hwProxy, - const vector& credentialData) + const vector& credentialData, + std::shared_ptr session) : hwProxyFactory_(hwProxyFactory), - hwProxy_(hwProxy), credentialData_(credentialData), + session_(std::move(session)), numStartRetrievalCalls_(0), expectedDeviceNameSpacesSize_(0) {} @@ -94,10 +95,13 @@ class IdentityCredential : public BnIdentityCredential { bool includeChallenge, vector* outProofOfDeletionSignature); + // Creates and initializes hwProxy_. + ndk::ScopedAStatus ensureHwProxy(); + // Set by constructor sp hwProxyFactory_; - sp hwProxy_; vector credentialData_; + shared_ptr session_; int numStartRetrievalCalls_; // Set by initialize() @@ -105,6 +109,9 @@ class IdentityCredential : public BnIdentityCredential { bool testCredential_; vector encryptedCredentialKeys_; + // Set by ensureHwProxy() + sp hwProxy_; + // Set by createEphemeralKeyPair() vector ephemeralPublicKey_; diff --git a/identity/aidl/default/common/IdentityCredentialStore.cpp b/identity/aidl/default/common/IdentityCredentialStore.cpp index e6b5466096..4703ffe646 100644 --- a/identity/aidl/default/common/IdentityCredentialStore.cpp +++ b/identity/aidl/default/common/IdentityCredentialStore.cpp @@ -20,6 +20,7 @@ #include "IdentityCredential.h" #include "IdentityCredentialStore.h" +#include "PresentationSession.h" #include "WritableIdentityCredential.h" namespace aidl::android::hardware::identity { @@ -61,9 +62,8 @@ ndk::ScopedAStatus IdentityCredentialStore::getCredential( "Unsupported cipher suite")); } - sp hwProxy = hwProxyFactory_->createPresentationProxy(); - shared_ptr credential = - ndk::SharedRefBase::make(hwProxyFactory_, hwProxy, credentialData); + shared_ptr credential = ndk::SharedRefBase::make( + hwProxyFactory_, credentialData, nullptr /* session */); auto ret = credential->initialize(); if (ret != IIdentityCredentialStore::STATUS_OK) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( @@ -73,4 +73,25 @@ ndk::ScopedAStatus IdentityCredentialStore::getCredential( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus IdentityCredentialStore::createPresentationSession( + CipherSuite cipherSuite, shared_ptr* outSession) { + // We only support CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 right now. + if (cipherSuite != CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_CIPHER_SUITE_NOT_SUPPORTED, + "Unsupported cipher suite")); + } + + sp hwProxy = hwProxyFactory_->createSessionProxy(); + shared_ptr session = + ndk::SharedRefBase::make(hwProxyFactory_, hwProxy); + auto ret = session->initialize(); + if (ret != IIdentityCredentialStore::STATUS_OK) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + int(ret), "Error initializing PresentationSession")); + } + *outSession = session; + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::identity diff --git a/identity/aidl/default/common/IdentityCredentialStore.h b/identity/aidl/default/common/IdentityCredentialStore.h index d35e632984..77b894dbd6 100644 --- a/identity/aidl/default/common/IdentityCredentialStore.h +++ b/identity/aidl/default/common/IdentityCredentialStore.h @@ -47,6 +47,9 @@ class IdentityCredentialStore : public BnIdentityCredentialStore { ndk::ScopedAStatus getCredential(CipherSuite cipherSuite, const vector& credentialData, shared_ptr* outCredential) override; + ndk::ScopedAStatus createPresentationSession( + CipherSuite cipherSuite, shared_ptr* outSession) override; + private: sp hwProxyFactory_; }; diff --git a/identity/aidl/default/common/PresentationSession.cpp b/identity/aidl/default/common/PresentationSession.cpp new file mode 100644 index 0000000000..fbd897281a --- /dev/null +++ b/identity/aidl/default/common/PresentationSession.cpp @@ -0,0 +1,149 @@ +/* + * Copyright 2021, 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 "PresentationSession" + +#include "PresentationSession.h" +#include "IdentityCredentialStore.h" + +#include + +#include + +#include +#include + +#include +#include + +#include "FakeSecureHardwareProxy.h" +#include "IdentityCredential.h" +#include "PresentationSession.h" + +namespace aidl::android::hardware::identity { + +using ::std::optional; + +using namespace ::android::hardware::identity; + +PresentationSession::~PresentationSession() {} + +int PresentationSession::initialize() { + if (!hwProxy_->initialize()) { + LOG(ERROR) << "hwProxy->initialize failed"; + return IIdentityCredentialStore::STATUS_FAILED; + } + + optional id = hwProxy_->getId(); + if (!id) { + LOG(ERROR) << "Error getting id for session"; + return IIdentityCredentialStore::STATUS_FAILED; + } + id_ = id.value(); + + optional> ephemeralKeyPriv = hwProxy_->getEphemeralKeyPair(); + if (!ephemeralKeyPriv) { + LOG(ERROR) << "Error getting ephemeral private key for session"; + return IIdentityCredentialStore::STATUS_FAILED; + } + optional> ephemeralKeyPair = + support::ecPrivateKeyToKeyPair(ephemeralKeyPriv.value()); + if (!ephemeralKeyPair) { + LOG(ERROR) << "Error creating ephemeral key-pair"; + return IIdentityCredentialStore::STATUS_FAILED; + } + ephemeralKeyPair_ = ephemeralKeyPair.value(); + + optional authChallenge = hwProxy_->getAuthChallenge(); + if (!authChallenge) { + LOG(ERROR) << "Error getting authChallenge for session"; + return IIdentityCredentialStore::STATUS_FAILED; + } + authChallenge_ = authChallenge.value(); + + return IIdentityCredentialStore::STATUS_OK; +} + +ndk::ScopedAStatus PresentationSession::getEphemeralKeyPair(vector* outKeyPair) { + *outKeyPair = ephemeralKeyPair_; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PresentationSession::getAuthChallenge(int64_t* outChallenge) { + *outChallenge = authChallenge_; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PresentationSession::setReaderEphemeralPublicKey( + const vector& publicKey) { + // We expect the reader ephemeral public key to be same size and curve + // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH + // won't work. So its length should be 65 bytes and it should be + // starting with 0x04. + if (publicKey.size() != 65 || publicKey[0] != 0x04) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Reader public key is not in expected format")); + } + readerPublicKey_ = publicKey; + vector pubKeyP256(publicKey.begin() + 1, publicKey.end()); + if (!hwProxy_->setReaderEphemeralPublicKey(pubKeyP256)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Error setting readerEphemeralPublicKey for session")); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PresentationSession::setSessionTranscript( + const vector& sessionTranscript) { + sessionTranscript_ = sessionTranscript; + if (!hwProxy_->setSessionTranscript(sessionTranscript)) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_FAILED, + "Error setting SessionTranscript for session")); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PresentationSession::getCredential( + const vector& credentialData, shared_ptr* outCredential) { + shared_ptr p = ref(); + shared_ptr credential = + ndk::SharedRefBase::make(hwProxyFactory_, credentialData, p); + int ret = credential->initialize(); + if (ret != IIdentityCredentialStore::STATUS_OK) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + ret, "Error initializing IdentityCredential")); + } + *outCredential = std::move(credential); + + return ndk::ScopedAStatus::ok(); +} + +uint64_t PresentationSession::getSessionId() { + return id_; +} + +vector PresentationSession::getSessionTranscript() { + return sessionTranscript_; +} + +vector PresentationSession::getReaderEphemeralPublicKey() { + return readerPublicKey_; +} + +} // namespace aidl::android::hardware::identity diff --git a/identity/aidl/default/common/PresentationSession.h b/identity/aidl/default/common/PresentationSession.h new file mode 100644 index 0000000000..76ca67b675 --- /dev/null +++ b/identity/aidl/default/common/PresentationSession.h @@ -0,0 +1,83 @@ +/* + * Copyright 2021, 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_IDENTITY_PRESENTATIONSESSION_H +#define ANDROID_HARDWARE_IDENTITY_PRESENTATIONSESSION_H + +#include +#include + +#include + +#include + +#include "IdentityCredentialStore.h" +#include "SecureHardwareProxy.h" + +namespace aidl::android::hardware::identity { + +using ::aidl::android::hardware::keymaster::HardwareAuthToken; +using ::aidl::android::hardware::keymaster::VerificationToken; +using ::android::sp; +using ::android::hardware::identity::SecureHardwareSessionProxy; +using ::std::vector; + +class PresentationSession : public BnPresentationSession { + public: + PresentationSession(sp hwProxyFactory, + sp hwProxy) + : hwProxyFactory_(std::move(hwProxyFactory)), hwProxy_(std::move(hwProxy)) {} + + virtual ~PresentationSession(); + + // Creates ephemeral key and auth-challenge in TA. Returns a status code from + // IIdentityCredentialStore. Must be called right after construction. + int initialize(); + + uint64_t getSessionId(); + + vector getSessionTranscript(); + vector getReaderEphemeralPublicKey(); + + // Methods from IPresentationSession follow. + ndk::ScopedAStatus getEphemeralKeyPair(vector* outKeyPair) override; + ndk::ScopedAStatus getAuthChallenge(int64_t* outChallenge) override; + ndk::ScopedAStatus setReaderEphemeralPublicKey(const vector& publicKey) override; + ndk::ScopedAStatus setSessionTranscript(const vector& sessionTranscript) override; + + ndk::ScopedAStatus getCredential(const vector& credentialData, + shared_ptr* outCredential) override; + + private: + // Set by constructor + sp hwProxyFactory_; + sp hwProxy_; + + // Set by initialize() + uint64_t id_; + vector ephemeralKeyPair_; + uint64_t authChallenge_; + + // Set by setReaderEphemeralPublicKey() + vector readerPublicKey_; + + // Set by setSessionTranscript() + vector sessionTranscript_; +}; + +} // namespace aidl::android::hardware::identity + +#endif // ANDROID_HARDWARE_IDENTITY_PRESENTATIONSESSION_H diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h index a1ed1ef03b..a580444230 100644 --- a/identity/aidl/default/common/SecureHardwareProxy.h +++ b/identity/aidl/default/common/SecureHardwareProxy.h @@ -42,6 +42,7 @@ using ::std::vector; // Forward declare. // class SecureHardwareProvisioningProxy; +class SecureHardwareSessionProxy; class SecureHardwarePresentationProxy; // This is a class used to create proxies. @@ -52,6 +53,7 @@ class SecureHardwareProxyFactory : public RefBase { virtual ~SecureHardwareProxyFactory() {} virtual sp createProvisioningProxy() = 0; + virtual sp createSessionProxy() = 0; virtual sp createPresentationProxy() = 0; }; @@ -64,8 +66,12 @@ class SecureHardwareProvisioningProxy : public RefBase { virtual bool initialize(bool testCredential) = 0; - virtual bool initializeForUpdate(bool testCredential, string docType, - vector encryptedCredentialKeys) = 0; + virtual bool initializeForUpdate(bool testCredential, const string& docType, + const vector& encryptedCredentialKeys) = 0; + + virtual optional getId() = 0; + + virtual bool shutdown() = 0; // Returns public key certificate chain with attestation. // @@ -76,7 +82,7 @@ class SecureHardwareProvisioningProxy : public RefBase { virtual optional> createCredentialKey(const vector& challenge, const vector& applicationId) = 0; - virtual bool startPersonalization(int accessControlProfileCount, vector entryCounts, + virtual bool startPersonalization(int accessControlProfileCount, const vector& entryCounts, const string& docType, size_t expectedProofOfProvisioningSize) = 0; @@ -98,8 +104,6 @@ class SecureHardwareProvisioningProxy : public RefBase { // Returns encryptedCredentialKeys (80 bytes). virtual optional> finishGetCredentialData(const string& docType) = 0; - - virtual bool shutdown() = 0; }; enum AccessCheckResult { @@ -110,6 +114,30 @@ enum AccessCheckResult { kReaderAuthenticationFailed, }; +// The proxy used for sessions. +// +class SecureHardwareSessionProxy : public RefBase { + public: + SecureHardwareSessionProxy() {} + + virtual ~SecureHardwareSessionProxy() {} + + virtual bool initialize() = 0; + + virtual optional getId() = 0; + + virtual bool shutdown() = 0; + + virtual optional getAuthChallenge() = 0; + + // Returns private key + virtual optional> getEphemeralKeyPair() = 0; + + virtual bool setReaderEphemeralPublicKey(const vector& readerEphemeralPublicKey) = 0; + + virtual bool setSessionTranscript(const vector& sessionTranscript) = 0; +}; + // The proxy used for presentation. // class SecureHardwarePresentationProxy : public RefBase { @@ -117,12 +145,16 @@ class SecureHardwarePresentationProxy : public RefBase { SecureHardwarePresentationProxy() {} virtual ~SecureHardwarePresentationProxy() {} - virtual bool initialize(bool testCredential, string docType, - vector encryptedCredentialKeys) = 0; + virtual bool initialize(uint32_t sessionId, bool testCredential, const string& docType, + const vector& encryptedCredentialKeys) = 0; + + virtual optional getId() = 0; + + virtual bool shutdown() = 0; // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component) - virtual optional, vector>> generateSigningKeyPair(string docType, - time_t now) = 0; + virtual optional, vector>> generateSigningKeyPair( + const string& docType, time_t now) = 0; // Returns private key virtual optional> createEphemeralKeyPair() = 0; @@ -174,8 +206,6 @@ class SecureHardwarePresentationProxy : public RefBase { virtual optional> proveOwnership(const string& docType, bool testCredential, const vector& challenge, size_t proofOfOwnershipCborSize) = 0; - - virtual bool shutdown() = 0; }; } // namespace android::hardware::identity diff --git a/identity/aidl/default/identity-default.xml b/identity/aidl/default/identity-default.xml index a074250901..cc0ddc7d51 100644 --- a/identity/aidl/default/identity-default.xml +++ b/identity/aidl/default/identity-default.xml @@ -1,7 +1,7 @@ android.hardware.identity - 3 + 4 IIdentityCredentialStore default diff --git a/identity/aidl/default/libeic/EicCommon.h b/identity/aidl/default/libeic/EicCommon.h index 476276ebcf..2a08a35f65 100644 --- a/identity/aidl/default/libeic/EicCommon.h +++ b/identity/aidl/default/libeic/EicCommon.h @@ -21,6 +21,9 @@ #ifndef ANDROID_HARDWARE_IDENTITY_EIC_COMMON_H #define ANDROID_HARDWARE_IDENTITY_EIC_COMMON_H +// KeyMint auth-challenges are 64-bit numbers and 0 typically means unset. +#define EIC_KM_AUTH_CHALLENGE_UNSET 0 + // Feature version 202009: // // CredentialKeys = [ diff --git a/identity/aidl/default/libeic/EicOps.h b/identity/aidl/default/libeic/EicOps.h index d4fcf0e1bb..aa26e6202a 100644 --- a/identity/aidl/default/libeic/EicOps.h +++ b/identity/aidl/default/libeic/EicOps.h @@ -141,6 +141,10 @@ void* eicMemCpy(void* dest, const void* src, size_t n); // String length, see strlen(3). size_t eicStrLen(const char* s); +// Locate a substring, see memmem(3) +void* eicMemMem(const uint8_t* haystack, size_t haystackLen, const uint8_t* needle, + size_t needleLen); + // Memory compare, see CRYPTO_memcmp(3SSL) // // It takes an amount of time dependent on len, but independent of the contents of the @@ -151,6 +155,12 @@ int eicCryptoMemCmp(const void* s1, const void* s2, size_t n); // Random number generation. bool eicOpsRandom(uint8_t* buf, size_t numBytes); +// Creates a new non-zero identifier in |id|. +// +// Is guaranteed to be non-zero and different than what is already in |id|. +// +bool eicNextId(uint32_t* id); + // If |testCredential| is true, returns the 128-bit AES Hardware-Bound Key (16 bytes). // // Otherwise returns all zeroes (16 bytes). @@ -295,6 +305,8 @@ bool eicOpsValidateAuthToken(uint64_t challenge, uint64_t secureUserId, uint64_t int verificationTokenSecurityLevel, const uint8_t* verificationTokenMac, size_t verificationTokenMacSize); +// Also see eicOpsLookupActiveSessionFromId() defined in EicSession.h + #ifdef __cplusplus } #endif diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c index 0d03ae9620..104a559697 100644 --- a/identity/aidl/default/libeic/EicPresentation.c +++ b/identity/aidl/default/libeic/EicPresentation.c @@ -16,11 +16,17 @@ #include "EicPresentation.h" #include "EicCommon.h" +#include "EicSession.h" #include -bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType, - size_t docTypeLength, const uint8_t* encryptedCredentialKeys, +// Global used for assigning ids for presentation objects. +// +static uint32_t gPresentationLastIdAssigned = 0; + +bool eicPresentationInit(EicPresentation* ctx, uint32_t sessionId, bool testCredential, + const char* docType, size_t docTypeLength, + const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize) { uint8_t credentialKeys[EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202101]; bool expectPopSha256 = false; @@ -39,6 +45,13 @@ bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* } eicMemSet(ctx, '\0', sizeof(EicPresentation)); + ctx->sessionId = sessionId; + + if (!eicNextId(&gPresentationLastIdAssigned)) { + eicDebug("Error getting id for object"); + return false; + } + ctx->id = gPresentationLastIdAssigned; if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys, encryptedCredentialKeysSize, @@ -86,6 +99,23 @@ bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* if (expectPopSha256) { eicMemCpy(ctx->proofOfProvisioningSha256, credentialKeys + 54, EIC_SHA256_DIGEST_SIZE); } + + eicDebug("Initialized presentation with id %" PRIu32, ctx->id); + return true; +} + +bool eicPresentationShutdown(EicPresentation* ctx) { + if (ctx->id == 0) { + eicDebug("Trying to shut down presentation with id 0"); + return false; + } + eicDebug("Shut down presentation with id %" PRIu32, ctx->id); + eicMemSet(ctx, '\0', sizeof(EicPresentation)); + return true; +} + +bool eicPresentationGetId(EicPresentation* ctx, uint32_t* outId) { + *outId = ctx->id; return true; } @@ -174,7 +204,7 @@ bool eicPresentationCreateAuthChallenge(EicPresentation* ctx, uint64_t* authChal eicDebug("Failed generating random challenge"); return false; } - } while (ctx->authChallenge == 0); + } while (ctx->authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET); eicDebug("Created auth challenge %" PRIu64, ctx->authChallenge); *authChallenge = ctx->authChallenge; return true; @@ -190,6 +220,24 @@ bool eicPresentationValidateRequestMessage(EicPresentation* ctx, const uint8_t* int coseSignAlg, const uint8_t* readerSignatureOfToBeSigned, size_t readerSignatureOfToBeSignedSize) { + if (ctx->sessionId != 0) { + EicSession* session = eicSessionGetForId(ctx->sessionId); + if (session == NULL) { + eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId); + return false; + } + EicSha256Ctx sha256; + uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE]; + eicOpsSha256Init(&sha256); + eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize); + eicOpsSha256Final(&sha256, sessionTranscriptSha256); + if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256, + EIC_SHA256_DIGEST_SIZE) != 0) { + eicDebug("SessionTranscript mismatch"); + return false; + } + } + if (ctx->readerPublicKeySize == 0) { eicDebug("No public key for reader"); return false; @@ -330,6 +378,20 @@ bool eicPresentationPushReaderCert(EicPresentation* ctx, const uint8_t* certX509 return true; } +static bool getChallenge(EicPresentation* ctx, uint64_t* outAuthChallenge) { + // Use authChallenge from session if applicable. + *outAuthChallenge = ctx->authChallenge; + if (ctx->sessionId != 0) { + EicSession* session = eicSessionGetForId(ctx->sessionId); + if (session == NULL) { + eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId); + return false; + } + *outAuthChallenge = session->authChallenge; + } + return true; +} + bool eicPresentationSetAuthToken(EicPresentation* ctx, uint64_t challenge, uint64_t secureUserId, uint64_t authenticatorId, int hardwareAuthenticatorType, uint64_t timeStamp, const uint8_t* mac, size_t macSize, @@ -338,14 +400,19 @@ bool eicPresentationSetAuthToken(EicPresentation* ctx, uint64_t challenge, uint6 int verificationTokenSecurityLevel, const uint8_t* verificationTokenMac, size_t verificationTokenMacSize) { + uint64_t authChallenge; + if (!getChallenge(ctx, &authChallenge)) { + return false; + } + // It doesn't make sense to accept any tokens if eicPresentationCreateAuthChallenge() // was never called. - if (ctx->authChallenge == 0) { - eicDebug("Trying validate tokens when no auth-challenge was previously generated"); + if (authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET) { + eicDebug("Trying to validate tokens when no auth-challenge was previously generated"); return false; } // At least the verification-token must have the same challenge as what was generated. - if (verificationTokenChallenge != ctx->authChallenge) { + if (verificationTokenChallenge != authChallenge) { eicDebug("Challenge in verification token does not match the challenge " "previously generated"); return false; @@ -354,6 +421,7 @@ bool eicPresentationSetAuthToken(EicPresentation* ctx, uint64_t challenge, uint6 challenge, secureUserId, authenticatorId, hardwareAuthenticatorType, timeStamp, mac, macSize, verificationTokenChallenge, verificationTokenTimestamp, verificationTokenSecurityLevel, verificationTokenMac, verificationTokenMacSize)) { + eicDebug("Error validating authToken"); return false; } ctx->authTokenChallenge = challenge; @@ -377,11 +445,16 @@ static bool checkUserAuth(EicPresentation* ctx, bool userAuthenticationRequired, // Only ACP with auth-on-every-presentation - those with timeout == 0 - need the // challenge to match... if (timeoutMillis == 0) { - if (ctx->authTokenChallenge != ctx->authChallenge) { + uint64_t authChallenge; + if (!getChallenge(ctx, &authChallenge)) { + return false; + } + + if (ctx->authTokenChallenge != authChallenge) { eicDebug("Challenge in authToken (%" PRIu64 ") doesn't match the challenge " "that was created (%" PRIu64 ") for this session", - ctx->authTokenChallenge, ctx->authChallenge); + ctx->authTokenChallenge, authChallenge); return false; } } @@ -490,6 +563,25 @@ bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTrans const uint8_t signingKeyBlob[60], const char* docType, size_t docTypeLength, unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize) { + if (ctx->sessionId != 0) { + EicSession* session = eicSessionGetForId(ctx->sessionId); + if (session == NULL) { + eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId); + return false; + } + EicSha256Ctx sha256; + uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE]; + eicOpsSha256Init(&sha256); + eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize); + eicOpsSha256Final(&sha256, sessionTranscriptSha256); + if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256, + EIC_SHA256_DIGEST_SIZE) != 0) { + eicDebug("SessionTranscript mismatch"); + return false; + } + readerEphemeralPublicKey = session->readerEphemeralPublicKey; + } + uint8_t signingKeyPriv[EIC_P256_PRIV_KEY_SIZE]; if (!eicOpsDecryptAes128Gcm(ctx->storageKey, signingKeyBlob, 60, (const uint8_t*)docType, docTypeLength, signingKeyPriv)) { diff --git a/identity/aidl/default/libeic/EicPresentation.h b/identity/aidl/default/libeic/EicPresentation.h index 6f7f432960..a031890e58 100644 --- a/identity/aidl/default/libeic/EicPresentation.h +++ b/identity/aidl/default/libeic/EicPresentation.h @@ -30,7 +30,13 @@ extern "C" { // The maximum size we support for public keys in reader certificates. #define EIC_PRESENTATION_MAX_READER_PUBLIC_KEY_SIZE 65 +// Constant used to convey that no session is associated with a presentation. +#define EIC_PRESENTATION_ID_UNSET 0 + typedef struct { + // A non-zero number unique for this EicPresentation instance + uint32_t id; + int featureLevel; uint8_t storageKey[EIC_AES_128_KEY_SIZE]; @@ -38,6 +44,10 @@ typedef struct { uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]; + // If non-zero (not EIC_PRESENTATION_ID_UNSET), the id of the EicSession object this + // presentation object is associated with. + uint32_t sessionId; + // The challenge generated with eicPresentationCreateAuthChallenge() uint64_t authChallenge; @@ -93,10 +103,18 @@ typedef struct { EicCbor cbor; } EicPresentation; -bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType, - size_t docTypeLength, const uint8_t* encryptedCredentialKeys, +// If sessionId is zero (EIC_PRESENTATION_ID_UNSET), the presentation object is not associated +// with a session object. Otherwise it's the id of the session object. +// +bool eicPresentationInit(EicPresentation* ctx, uint32_t sessionId, bool testCredential, + const char* docType, size_t docTypeLength, + const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize); +bool eicPresentationShutdown(EicPresentation* ctx); + +bool eicPresentationGetId(EicPresentation* ctx, uint32_t* outId); + bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType, size_t docTypeLength, time_t now, uint8_t* publicKeyCert, size_t* publicKeyCertSize, diff --git a/identity/aidl/default/libeic/EicProvisioning.c b/identity/aidl/default/libeic/EicProvisioning.c index c9df4fd74f..a241b71b50 100644 --- a/identity/aidl/default/libeic/EicProvisioning.c +++ b/identity/aidl/default/libeic/EicProvisioning.c @@ -17,8 +17,21 @@ #include "EicProvisioning.h" #include "EicCommon.h" +#include + +// Global used for assigning ids for provisioning objects. +// +static uint32_t gProvisioningLastIdAssigned = 0; + bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential) { eicMemSet(ctx, '\0', sizeof(EicProvisioning)); + + if (!eicNextId(&gProvisioningLastIdAssigned)) { + eicDebug("Error getting id for object"); + return false; + } + ctx->id = gProvisioningLastIdAssigned; + ctx->testCredential = testCredential; if (!eicOpsRandom(ctx->storageKey, EIC_AES_128_KEY_SIZE)) { return false; @@ -47,6 +60,13 @@ bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, con } eicMemSet(ctx, '\0', sizeof(EicProvisioning)); + + if (!eicNextId(&gProvisioningLastIdAssigned)) { + eicDebug("Error getting id for object"); + return false; + } + ctx->id = gProvisioningLastIdAssigned; + ctx->testCredential = testCredential; if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys, @@ -96,6 +116,21 @@ bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, con return true; } +bool eicProvisioningShutdown(EicProvisioning* ctx) { + if (ctx->id == 0) { + eicDebug("Trying to shut down provsioning with id 0"); + return false; + } + eicDebug("Shut down provsioning with id %" PRIu32, ctx->id); + eicMemSet(ctx, '\0', sizeof(EicProvisioning)); + return true; +} + +bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId) { + *outId = ctx->id; + return true; +} + bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge, size_t challengeSize, const uint8_t* applicationId, size_t applicationIdSize, uint8_t* publicKeyCert, diff --git a/identity/aidl/default/libeic/EicProvisioning.h b/identity/aidl/default/libeic/EicProvisioning.h index 92f1e4a2a0..d94f8f18c2 100644 --- a/identity/aidl/default/libeic/EicProvisioning.h +++ b/identity/aidl/default/libeic/EicProvisioning.h @@ -31,6 +31,9 @@ extern "C" { #define EIC_MAX_NUM_ACCESS_CONTROL_PROFILE_IDS 32 typedef struct { + // A non-zero number unique for this EicProvisioning instance + uint32_t id; + // Set by eicCreateCredentialKey() OR eicProvisioningInitForUpdate() uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE]; @@ -68,6 +71,10 @@ bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, con size_t docTypeLength, const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize); +bool eicProvisioningShutdown(EicProvisioning* ctx); + +bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId); + bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge, size_t challengeSize, const uint8_t* applicationId, size_t applicationIdSize, uint8_t* publicKeyCert, diff --git a/identity/aidl/default/libeic/EicSession.c b/identity/aidl/default/libeic/EicSession.c new file mode 100644 index 0000000000..d0c7a0d77e --- /dev/null +++ b/identity/aidl/default/libeic/EicSession.c @@ -0,0 +1,120 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "EicCommon.h" +#include "EicSession.h" + +// Global used for assigning ids for session objects. +// +static uint32_t gSessionLastIdAssigned = 0; + +// The current session object or NULL if never initialized or if it has been shut down. +// +static EicSession* gSessionCurrent = NULL; + +EicSession* eicSessionGetForId(uint32_t sessionId) { + if (gSessionCurrent != NULL && gSessionCurrent->id == sessionId) { + return gSessionCurrent; + } + return NULL; +} + +bool eicSessionInit(EicSession* ctx) { + eicMemSet(ctx, '\0', sizeof(EicSession)); + + if (!eicNextId(&gSessionLastIdAssigned)) { + eicDebug("Error getting id for object"); + return false; + } + ctx->id = gSessionLastIdAssigned; + + do { + if (!eicOpsRandom((uint8_t*)&(ctx->authChallenge), sizeof(ctx->authChallenge))) { + eicDebug("Failed generating random challenge"); + return false; + } + } while (ctx->authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET); + + if (!eicOpsCreateEcKey(ctx->ephemeralPrivateKey, ctx->ephemeralPublicKey)) { + eicDebug("Error creating ephemeral key-pair"); + return false; + } + + gSessionCurrent = ctx; + eicDebug("Initialized session with id %" PRIu32, ctx->id); + return true; +} + +bool eicSessionShutdown(EicSession* ctx) { + if (ctx->id == 0) { + eicDebug("Trying to shut down session with id 0"); + return false; + } + eicDebug("Shut down session with id %" PRIu32, ctx->id); + eicMemSet(ctx, '\0', sizeof(EicSession)); + gSessionCurrent = NULL; + return true; +} + +bool eicSessionGetId(EicSession* ctx, uint32_t* outId) { + *outId = ctx->id; + return true; +} + +bool eicSessionGetAuthChallenge(EicSession* ctx, uint64_t* outAuthChallenge) { + *outAuthChallenge = ctx->authChallenge; + return true; +} + +bool eicSessionGetEphemeralKeyPair(EicSession* ctx, + uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]) { + eicMemCpy(ephemeralPrivateKey, ctx->ephemeralPrivateKey, EIC_P256_PRIV_KEY_SIZE); + return true; +} + +bool eicSessionSetReaderEphemeralPublicKey( + EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]) { + eicMemCpy(ctx->readerEphemeralPublicKey, readerEphemeralPublicKey, EIC_P256_PUB_KEY_SIZE); + return true; +} + +bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript, + size_t sessionTranscriptSize) { + // Only accept the SessionTranscript if X and Y from the ephemeral key + // we created is somewhere in SessionTranscript... + // + if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey, + EIC_P256_PUB_KEY_SIZE / 2) == NULL) { + eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript"); + return false; + } + if (eicMemMem(sessionTranscript, sessionTranscriptSize, + ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2, + EIC_P256_PUB_KEY_SIZE / 2) == NULL) { + eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript"); + return false; + } + + // To save space we only store the SHA-256 of SessionTranscript + // + EicSha256Ctx shaCtx; + eicOpsSha256Init(&shaCtx); + eicOpsSha256Update(&shaCtx, sessionTranscript, sessionTranscriptSize); + eicOpsSha256Final(&shaCtx, ctx->sessionTranscriptSha256); + return true; +} diff --git a/identity/aidl/default/libeic/EicSession.h b/identity/aidl/default/libeic/EicSession.h new file mode 100644 index 0000000000..0303dae1c3 --- /dev/null +++ b/identity/aidl/default/libeic/EicSession.h @@ -0,0 +1,73 @@ +/* + * Copyright 2021, 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. + */ + +#if !defined(EIC_INSIDE_LIBEIC_H) && !defined(EIC_COMPILATION) +#error "Never include this file directly, include libeic.h instead." +#endif + +#ifndef ANDROID_HARDWARE_IDENTITY_EIC_SESSION_H +#define ANDROID_HARDWARE_IDENTITY_EIC_SESSION_H + +#include "EicOps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + // A non-zero number unique for this EicSession instance + uint32_t id; + + // The challenge generated at construction time by eicSessionInit(). + uint64_t authChallenge; + + uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]; + uint8_t ephemeralPublicKey[EIC_P256_PUB_KEY_SIZE]; + + uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]; + + uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE]; + +} EicSession; + +bool eicSessionInit(EicSession* ctx); + +bool eicSessionShutdown(EicSession* ctx); + +bool eicSessionGetId(EicSession* ctx, uint32_t* outId); + +bool eicSessionGetAuthChallenge(EicSession* ctx, uint64_t* outAuthChallenge); + +bool eicSessionGetEphemeralKeyPair(EicSession* ctx, + uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]); + +bool eicSessionSetReaderEphemeralPublicKey( + EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]); + +bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript, + size_t sessionTranscriptSize); + +// Looks up an active session with the given id. +// +// Returns NULL if no active session with the given id is found. +// +EicSession* eicSessionGetForId(uint32_t sessionId); + +#ifdef __cplusplus +} +#endif + +#endif // ANDROID_HARDWARE_IDENTITY_EIC_PRESENTATION_H diff --git a/identity/aidl/default/libeic/libeic.h b/identity/aidl/default/libeic/libeic.h index 20c889660f..d89fc9a0e3 100644 --- a/identity/aidl/default/libeic/libeic.h +++ b/identity/aidl/default/libeic/libeic.h @@ -27,10 +27,11 @@ extern "C" { */ #define EIC_INSIDE_LIBEIC_H #include "EicCbor.h" +#include "EicCommon.h" #include "EicOps.h" #include "EicPresentation.h" #include "EicProvisioning.h" -#include "EicCommon.h" +#include "EicSession.h" #undef EIC_INSIDE_LIBEIC_H #ifdef __cplusplus diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp index e5de91e22e..7b6f2c81ee 100644 --- a/identity/aidl/vts/Android.bp +++ b/identity/aidl/vts/Android.bp @@ -28,6 +28,7 @@ cc_test { "EndToEndTests.cpp", "TestCredentialTests.cpp", "AuthenticationKeyTests.cpp", + "PresentationSessionTests.cpp", ], shared_libs: [ "libbinder", @@ -40,9 +41,9 @@ cc_test { "libpuresoftkeymasterdevice", "android.hardware.keymaster@4.0", "android.hardware.identity-support-lib", - "android.hardware.identity-V3-cpp", - "android.hardware.keymaster-V3-cpp", - "android.hardware.keymaster-V3-ndk", + "android.hardware.identity-V4-cpp", + "android.hardware.keymaster-V4-cpp", + "android.hardware.keymaster-V4-ndk", "libkeymaster4support", "libkeymaster4_1support", ], diff --git a/identity/aidl/vts/PresentationSessionTests.cpp b/identity/aidl/vts/PresentationSessionTests.cpp new file mode 100644 index 0000000000..88acb269e2 --- /dev/null +++ b/identity/aidl/vts/PresentationSessionTests.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "PresentationSessionTests" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Util.h" + +namespace android::hardware::identity { + +using std::endl; +using std::make_pair; +using std::map; +using std::optional; +using std::pair; +using std::string; +using std::tie; +using std::vector; + +using ::android::sp; +using ::android::String16; +using ::android::binder::Status; + +using ::android::hardware::keymaster::HardwareAuthToken; +using ::android::hardware::keymaster::VerificationToken; + +class PresentationSessionTests : public testing::TestWithParam { + public: + virtual void SetUp() override { + credentialStore_ = android::waitForDeclaredService( + String16(GetParam().c_str())); + ASSERT_NE(credentialStore_, nullptr); + halApiVersion_ = credentialStore_->getInterfaceVersion(); + } + + void provisionData(); + + void provisionSingleDocument(const string& docType, vector* outCredentialData, + vector* outCredentialPubKey); + + // Set by provisionData + vector credential1Data_; + vector credential1PubKey_; + vector credential2Data_; + vector credential2PubKey_; + + sp credentialStore_; + int halApiVersion_; +}; + +void PresentationSessionTests::provisionData() { + provisionSingleDocument("org.iso.18013-5.2019.mdl", &credential1Data_, &credential1PubKey_); + provisionSingleDocument("org.blah.OtherhDocTypeXX", &credential2Data_, &credential2PubKey_); +} + +void PresentationSessionTests::provisionSingleDocument(const string& docType, + vector* outCredentialData, + vector* outCredentialPubKey) { + bool testCredential = true; + sp wc; + ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk()); + + vector attestationApplicationId; + vector attestationChallenge = {1}; + vector certChain; + ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge, + &certChain) + .isOk()); + + optional> optCredentialPubKey = + support::certificateChainGetTopMostKey(certChain[0].encodedCertificate); + ASSERT_TRUE(optCredentialPubKey); + *outCredentialPubKey = optCredentialPubKey.value(); + + size_t proofOfProvisioningSize = 106; + // Not in v1 HAL, may fail + wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize); + + ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */, + {1} /* numDataElementsPerNamespace */) + .isOk()); + + // Access control profile 0: open access - don't care about the returned SACP + SecureAccessControlProfile sacp; + ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk()); + + // Single entry - don't care about the returned encrypted data + ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Some Data", 1).isOk()); + vector encryptedData; + ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk()); + + vector proofOfProvisioningSignature; + Status status = wc->finishAddingEntries(outCredentialData, &proofOfProvisioningSignature); + EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage(); +} + +// This checks that any methods called on an IIdentityCredential obtained via a session +// returns STATUS_FAILED except for startRetrieval(), startRetrieveEntryValue(), +// retrieveEntryValue(), finishRetrieval(), setRequestedNamespaces(), setVerificationToken() +// +TEST_P(PresentationSessionTests, returnsFailureOnUnsupportedMethods) { + if (halApiVersion_ < 4) { + GTEST_SKIP() << "Need HAL API version 4, have " << halApiVersion_; + } + + provisionData(); + + sp session; + ASSERT_TRUE(credentialStore_ + ->createPresentationSession( + CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256, + &session) + .isOk()); + + sp credential; + ASSERT_TRUE(session->getCredential(credential1Data_, &credential).isOk()); + + Status result; + + vector signatureProofOfDeletion; + result = credential->deleteCredential(&signatureProofOfDeletion); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + vector ephemeralKeyPair; + result = credential->createEphemeralKeyPair(&ephemeralKeyPair); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + result = credential->setReaderEphemeralPublicKey({}); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + int64_t authChallenge; + result = credential->createAuthChallenge(&authChallenge); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + Certificate certificate; + vector signingKeyBlob; + result = credential->generateSigningKeyPair(&signingKeyBlob, &certificate); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + result = credential->deleteCredentialWithChallenge({}, &signatureProofOfDeletion); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + vector signatureProofOfOwnership; + result = credential->proveOwnership({}, &signatureProofOfOwnership); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); + + sp writableCredential; + result = credential->updateCredential(&writableCredential); + EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode()); + EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode()); +} + +// TODO: need to add tests to check that the returned IIdentityCredential works +// as intended. + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PresentationSessionTests); +INSTANTIATE_TEST_SUITE_P( + Identity, PresentationSessionTests, + testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)), + android::PrintInstanceNameToString); + +} // namespace android::hardware::identity -- cgit v1.2.3 From df084f35fc18077b4e6026e8708a64e842d611c9 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Mon, 10 Jan 2022 14:10:23 -0800 Subject: composer: deflake Test_expectedPresentTime Test_expectedPresentTime might fail due to scheduling delays. To avoid that, we test that the actual presentation didn't happen too early, but we allow for a late presentation. Bug: 198186194 Test: VTS Change-Id: I9be4bfe5a848443e69ef7b62ffb3dae675a9b81f --- .../composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index a591aaa67d..24b742e80c 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -1426,8 +1426,7 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { presentFence2->waitForever(LOG_TAG); const auto actualPresentTime = presentFence2->getSignalTime(); - const auto presentError = std::abs(expectedPresentTime - actualPresentTime); - EXPECT_LE(presentError, vsyncPeriod / 2); + EXPECT_GE(actualPresentTime, expectedPresentTime - vsyncPeriod / 2); ASSERT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF).isOk()); } -- cgit v1.2.3 From faeb133031e13da5f71f2d1d2ec37d52a1e16f8d Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 22 Dec 2021 16:17:02 +0800 Subject: wifi: add certificate HAL callback for Trust On First Use support This API is used to pass the certificate returned from the server to the framework. Bug: 196180536 Test: atest VtsHalWifiSupplicantStaIfaceTargetTest \ VtsHalWifiSupplicantStaNetworkTargetTest \ VtsHalWifiSupplicantP2pIfaceTargetTest Change-Id: I462008e8b2a0f18824b2886613f300213544c785 --- .../hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl | 1 + .../hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl | 1 + .../hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl | 9 +++++++++ .../hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl | 4 ++++ .../aidl/vts/functional/supplicant_sta_network_aidl_test.cpp | 6 ++++++ 5 files changed, 21 insertions(+) diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl index 4f7584d938..6276a3521b 100644 --- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl +++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl @@ -38,4 +38,5 @@ interface ISupplicantStaNetworkCallback { oneway void onNetworkEapSimGsmAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimGsmAuthParams params); oneway void onNetworkEapSimUmtsAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams params); oneway void onTransitionDisable(in android.hardware.wifi.supplicant.TransitionDisableIndication ind); + oneway void onServerCertificateAvailable(in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob); } diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl index 43772af0c0..9a0a924c66 100644 --- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl +++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl @@ -38,4 +38,5 @@ enum WpaDriverCapabilitiesMask { OCE = 2, SAE_PK = 4, WFD_R2 = 8, + TRUST_ON_FIRST_USE = 16, } diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl index c28b494d6a..4024c35fed 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl @@ -62,4 +62,13 @@ interface ISupplicantStaNetworkCallback { * Used to notify WPA3 transition disable. */ oneway void onTransitionDisable(in TransitionDisableIndication ind); + + /** + * Used to notify EAP certificate event. + * + * On receiving a server certifidate from TLS handshake, send this certificate + * to the framework for Trust On First Use. + */ + oneway void onServerCertificateAvailable( + in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob); } diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl index e174199c78..08006cffba 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl @@ -38,4 +38,8 @@ enum WpaDriverCapabilitiesMask { * Wi-Fi Display R2 */ WFD_R2 = 1 << 3, + /** + * Trust On First Use + */ + TRUST_ON_FIRST_USE = 1 << 4, } diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp index 66c88073cc..26cf817c68 100644 --- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp +++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp @@ -92,6 +92,12 @@ class SupplicantStaNetworkCallback : public BnSupplicantStaNetworkCallback { TransitionDisableIndication /* ind */) override { return ndk::ScopedAStatus::ok(); } + ::ndk::ScopedAStatus onServerCertificateAvailable( + int32_t /* depth */, const std::vector& /* subject */, + const std::vector& /* certHash */, + const std::vector& /* certBlob */) override { + return ndk::ScopedAStatus::ok(); + } }; class SupplicantStaNetworkAidlTest -- cgit v1.2.3 From 4596369b26016adbb2fffc3d832bad3d45aeae9a Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Thu, 6 Jan 2022 16:12:57 -0800 Subject: composer: remove FloatColor Currently not used. Bug: 207139550 Test: VTS Change-Id: I190382a7e72bd07b84a44f22f7b4b8b39b961355 --- .../hardware/graphics/composer3/FloatColor.aidl | 41 ---------------------- .../hardware/graphics/composer3/LayerCommand.aidl | 1 - .../hardware/graphics/composer3/FloatColor.aidl | 29 --------------- .../graphics/composer3/Hidl2AidlAsserts.cpp | 1 - .../hardware/graphics/composer3/LayerCommand.aidl | 8 ----- .../graphics/composer3/ComposerClientWriter.h | 5 --- 6 files changed, 85 deletions(-) delete mode 100644 graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl delete mode 100644 graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl deleted file mode 100644 index faadf575d1..0000000000 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2021, 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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.graphics.composer3; -@VintfStability -parcelable FloatColor { - float r; - float g; - float b; - float a; -} diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl index 7e6c00b1f5..49fbededf8 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl @@ -40,7 +40,6 @@ parcelable LayerCommand { @nullable android.hardware.graphics.common.Rect[] damage; @nullable android.hardware.graphics.composer3.ParcelableBlendMode blendMode; @nullable android.hardware.graphics.composer3.Color color; - @nullable android.hardware.graphics.composer3.FloatColor floatColor; @nullable android.hardware.graphics.composer3.ParcelableComposition composition; @nullable android.hardware.graphics.composer3.ParcelableDataspace dataspace; @nullable android.hardware.graphics.common.Rect displayFrame; diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl deleted file mode 100644 index a0a1d4b179..0000000000 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2021, 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.graphics.composer3; - -/** - * Color representation as a floating point number in the range [0.0 - 1.0] - */ - -@VintfStability -parcelable FloatColor { - float r; - float g; - float b; - float a; -} diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp index d34b4051fa..d2cabff346 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp @@ -25,7 +25,6 @@ #include "aidl/android/hardware/graphics/composer3/DisplayAttribute.h" #include "aidl/android/hardware/graphics/composer3/DisplayCapability.h" #include "aidl/android/hardware/graphics/composer3/DisplayConnectionType.h" -#include "aidl/android/hardware/graphics/composer3/FloatColor.h" #include "aidl/android/hardware/graphics/composer3/FormatColorComponent.h" #include "aidl/android/hardware/graphics/composer3/IComposer.h" #include "aidl/android/hardware/graphics/composer3/PerFrameMetadata.h" diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl index fa2d154c9b..e481d12c01 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl @@ -22,7 +22,6 @@ import android.hardware.graphics.common.Point; import android.hardware.graphics.common.Rect; import android.hardware.graphics.composer3.Buffer; import android.hardware.graphics.composer3.Color; -import android.hardware.graphics.composer3.FloatColor; import android.hardware.graphics.composer3.Luminance; import android.hardware.graphics.composer3.ParcelableBlendMode; import android.hardware.graphics.composer3.ParcelableComposition; @@ -113,13 +112,6 @@ parcelable LayerCommand { */ @nullable Color color; - /** - * Sets the color of the given layer. If the composition type of the layer - * is not Composition.SOLID_COLOR, this call must succeed and have no - * other effect. - */ - @nullable FloatColor floatColor; - /** * Sets the desired composition type of the given layer. During * validateDisplay, the device may request changes to the composition diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h index 2d927cdae4..b2776d6517 100644 --- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h +++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -210,10 +209,6 @@ class ComposerClientWriter { .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end()); } - void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) { - getLayerCommand(display, layer).floatColor.emplace(color); - } - void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) { getLayerCommand(display, layer).whitePointNits.emplace(Luminance{.nits = whitePointNits}); } -- cgit v1.2.3 From 1bee7abe605ba79a7db6e11de8f8ad68c7053270 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Thu, 6 Jan 2022 17:22:08 -0800 Subject: composer: Color.aidl should use floats Color is represented as a float [0.0 - 1.0] in the upper part of the stack, so make composer3 interface consistent. Bug: 207139550 Test: VTS Change-Id: Ic14288b5c87ff5cccfc9a0756d2630b8715759f7 --- .../android/hardware/graphics/composer3/Color.aidl | 8 ++--- .../android/hardware/graphics/composer3/Color.aidl | 11 +++--- .../VtsHalGraphicsComposer3_ReadbackTest.cpp | 39 ++++++++++------------ .../VtsHalGraphicsComposer3_TargetTest.cpp | 6 ++-- .../vts/functional/composer-vts/ReadbackVts.cpp | 26 ++++++--------- .../functional/composer-vts/include/ReadbackVts.h | 13 ++++---- 6 files changed, 46 insertions(+), 57 deletions(-) diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl index 7733debc9e..822290908e 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl @@ -34,8 +34,8 @@ package android.hardware.graphics.composer3; @VintfStability parcelable Color { - byte r; - byte g; - byte b; - byte a; + float r; + float g; + float b; + float a; } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl index 979f677379..151a8540c9 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl @@ -16,10 +16,13 @@ package android.hardware.graphics.composer3; +/** + * Color representation as a floating point number in the range [0.0 - 1.0] + */ @VintfStability parcelable Color { - byte r; - byte g; - byte b; - byte a; + float r; + float g; + float b; + float a; } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp index 0ece1d55a4..e519221159 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp @@ -922,35 +922,30 @@ class GraphicsBlendModeCompositionTest auto layer = mLayers[1]; BlendMode blendMode = layer->getBlendMode(); - float alpha = mTopLayerColor.a / 255.0f * layer->getAlpha(); + float alpha = mTopLayerColor.a * layer->getAlpha(); if (blendMode == BlendMode::NONE) { for (auto& expectedColor : expectedColors) { - expectedColor.r = mTopLayerColor.r * static_cast(layer->getAlpha()); - expectedColor.g = mTopLayerColor.g * static_cast(layer->getAlpha()); - expectedColor.b = mTopLayerColor.b * static_cast(layer->getAlpha()); - expectedColor.a = static_cast(alpha * 255.0); + expectedColor.r = mTopLayerColor.r * layer->getAlpha(); + expectedColor.g = mTopLayerColor.g * layer->getAlpha(); + expectedColor.b = mTopLayerColor.b * layer->getAlpha(); + expectedColor.a = alpha; } } else if (blendMode == BlendMode::PREMULTIPLIED) { for (auto& expectedColor : expectedColors) { - expectedColor.r = static_cast( - mTopLayerColor.r * static_cast(layer->getAlpha()) + - mBackgroundColor.r * (1.0 - alpha)); - expectedColor.g = static_cast(mTopLayerColor.g * layer->getAlpha() + - mBackgroundColor.g * (1.0 - alpha)); - expectedColor.b = static_cast(mTopLayerColor.b * layer->getAlpha() + - mBackgroundColor.b * (1.0 - alpha)); - expectedColor.a = static_cast(alpha + mBackgroundColor.a * (1.0 - alpha)); + expectedColor.r = + mTopLayerColor.r * layer->getAlpha() + mBackgroundColor.r * (1.0f - alpha); + expectedColor.g = + mTopLayerColor.g * layer->getAlpha() + mBackgroundColor.g * (1.0f - alpha); + expectedColor.b = + mTopLayerColor.b * layer->getAlpha() + mBackgroundColor.b * (1.0f - alpha); + expectedColor.a = alpha + mBackgroundColor.a * (1.0f - alpha); } } else if (blendMode == BlendMode::COVERAGE) { for (auto& expectedColor : expectedColors) { - expectedColor.r = static_cast(mTopLayerColor.r * alpha + - mBackgroundColor.r * (1.0 - alpha)); - expectedColor.g = static_cast(mTopLayerColor.g * alpha + - mBackgroundColor.g * (1.0 - alpha)); - expectedColor.b = static_cast(mTopLayerColor.b * alpha + - mBackgroundColor.b * (1.0 - alpha)); - expectedColor.a = static_cast(mTopLayerColor.a * alpha + - mBackgroundColor.a * (1.0 - alpha)); + expectedColor.r = mTopLayerColor.r * alpha + mBackgroundColor.r * (1.0f - alpha); + expectedColor.g = mTopLayerColor.g * alpha + mBackgroundColor.g * (1.0f - alpha); + expectedColor.b = mTopLayerColor.b * alpha + mBackgroundColor.b * (1.0f - alpha); + expectedColor.a = mTopLayerColor.a * alpha + mBackgroundColor.a * (1.0f - alpha); } } } @@ -1083,7 +1078,7 @@ class GraphicsTransformCompositionTest : public GraphicsCompositionTest { GraphicsCompositionTest::SetUp(); auto backgroundLayer = std::make_shared(mComposerClient, mPrimaryDisplay); - backgroundLayer->setColor({0, 0, 0, 0}); + backgroundLayer->setColor({0.0f, 0.0f, 0.0f, 0.0f}); backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); backgroundLayer->setZOrder(0); diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index a591aaa67d..c61693e458 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -1720,13 +1720,11 @@ TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COLOR) { int64_t layer; EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk()); - mWriter.setLayerColor(mPrimaryDisplay, layer, - Color{static_cast(0xff), static_cast(0xff), - static_cast(0xff), static_cast(0xff)}); + mWriter.setLayerColor(mPrimaryDisplay, layer, Color{1.0f, 1.0f, 1.0f, 1.0f}); execute(); ASSERT_TRUE(mReader.takeErrors().empty()); - mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0, 0, 0, 0}); + mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0.0f, 0.0f, 0.0f, 0.0f}); execute(); ASSERT_TRUE(mReader.takeErrors().empty()); } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp index 5eb912bb3f..deb5ac3106 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp @@ -131,12 +131,12 @@ void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride int offset = (row * static_cast(stride) + col) * bytesPerPixel; uint8_t* pixelColor = (uint8_t*)bufferData + offset; - pixelColor[0] = static_cast(srcColor.r); - pixelColor[1] = static_cast(srcColor.g); - pixelColor[2] = static_cast(srcColor.b); + pixelColor[0] = static_cast(std::round(255.0f * srcColor.r)); + pixelColor[1] = static_cast(std::round(255.0f * srcColor.g)); + pixelColor[2] = static_cast(std::round(255.0f * srcColor.b)); if (bytesPerPixel == 4) { - pixelColor[3] = static_cast(srcColor.a); + pixelColor[3] = static_cast(std::round(255.0f * srcColor.a)); } } } @@ -184,13 +184,11 @@ void ReadbackHelper::compareColorBuffers(std::vector& expectedColors, voi auto pixel = row * static_cast(width) + col; int offset = (row * stride + col) * bytesPerPixel; uint8_t* pixelColor = (uint8_t*)bufferData + offset; + const Color expectedColor = expectedColors[static_cast(pixel)]; - ASSERT_EQ(static_cast(expectedColors[static_cast(pixel)].r), - pixelColor[0]); - ASSERT_EQ(static_cast(expectedColors[static_cast(pixel)].g), - pixelColor[1]); - ASSERT_EQ(static_cast(expectedColors[static_cast(pixel)].b), - pixelColor[2]); + ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]); + ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]); + ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]); } } } @@ -262,12 +260,8 @@ void TestColorLayer::write(ComposerClientWriter& writer) { LayerSettings TestColorLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.solidColor = - ::android::half3(static_cast<::android::half>(mColor.r) / 255.0, - static_cast<::android::half>(mColor.g) / 255.0, - static_cast<::android::half>(mColor.b) / 255.0); - layerSettings.alpha = - mAlpha * static_cast((static_cast<::android::half>(mColor.a) / 255.0)); + layerSettings.source.solidColor = ::android::half3(mColor.r, mColor.g, mColor.b); + layerSettings.alpha = mAlpha * mColor.a; return layerSettings; } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h index 60a036e3fd..0fac2b3bfe 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h @@ -41,13 +41,12 @@ using common::Dataspace; using common::PixelFormat; using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper; -static const Color BLACK = {0, 0, 0, static_cast(0xff)}; -static const Color RED = {static_cast(0xff), 0, 0, static_cast(0xff)}; -static const Color TRANSLUCENT_RED = {static_cast(0xff), 0, 0, 0x33}; -static const Color GREEN = {0, static_cast(0xff), 0, static_cast(0xff)}; -static const Color BLUE = {0, 0, static_cast(0xff), static_cast(0xff)}; -static const Color WHITE = {static_cast(0xff), static_cast(0xff), - static_cast(0xff), static_cast(0xff)}; +static const Color BLACK = {0.0f, 0.0f, 0.0f, 1.0f}; +static const Color RED = {1.0f, 0.0f, 0.0f, 1.0f}; +static const Color TRANSLUCENT_RED = {1.0f, 0.0f, 0.0f, 0.3f}; +static const Color GREEN = {0.0f, 1.0f, 0.0f, 1.0f}; +static const Color BLUE = {0.0f, 0.0f, 1.0f, 1.0f}; +static const Color WHITE = {1.0f, 1.0f, 1.0f, 1.0f}; class TestRenderEngine; -- cgit v1.2.3 From dd7f7b9a9b8ed020e49a329ff2025da713b878e3 Mon Sep 17 00:00:00 2001 From: Shubham Dubey Date: Tue, 11 Jan 2022 05:26:13 +0000 Subject: Revert "Add IAGnssRil AIDL HAL (hardware/interfaces)" Revert "Add AGnssRil AIDL HAL (frameworks/base)" Revert submission 16548632-IAGnssRil-AIDL Reason for revert: Breaking Build BUGID: b/213964109 Reverted Changes: I087f7c9ae:Add AGnssRil AIDL HAL (frameworks/base) Ie5746ae25:Add IAGnssRil AIDL HAL (hardware/interfaces) Change-Id: I2404199e0b881a18429cc2a4ebc87bb41e5be655 --- .../current/android/hardware/gnss/IAGnssRil.aidl | 79 ---------- .../android/hardware/gnss/IAGnssRilCallback.aidl | 39 ----- .../current/android/hardware/gnss/IGnss.aidl | 1 - gnss/aidl/android/hardware/gnss/IAGnssRil.aidl | 163 --------------------- .../android/hardware/gnss/IAGnssRilCallback.aidl | 38 ----- gnss/aidl/android/hardware/gnss/IGnss.aidl | 8 - gnss/aidl/default/AGnssRil.cpp | 55 ------- gnss/aidl/default/AGnssRil.h | 37 ----- gnss/aidl/default/Android.bp | 1 - gnss/aidl/default/Gnss.cpp | 9 +- gnss/aidl/default/Gnss.h | 2 - gnss/aidl/vts/AGnssRilCallbackAidl.cpp | 28 ---- gnss/aidl/vts/AGnssRilCallbackAidl.h | 28 ---- gnss/aidl/vts/Android.bp | 1 - gnss/aidl/vts/gnss_hal_test_cases.cpp | 38 ----- 15 files changed, 1 insertion(+), 526 deletions(-) delete mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl delete mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRilCallback.aidl delete mode 100644 gnss/aidl/android/hardware/gnss/IAGnssRil.aidl delete mode 100644 gnss/aidl/android/hardware/gnss/IAGnssRilCallback.aidl delete mode 100644 gnss/aidl/default/AGnssRil.cpp delete mode 100644 gnss/aidl/default/AGnssRil.h delete mode 100644 gnss/aidl/vts/AGnssRilCallbackAidl.cpp delete mode 100644 gnss/aidl/vts/AGnssRilCallbackAidl.h diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl deleted file mode 100644 index 73df1950bf..0000000000 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.gnss; -@VintfStability -interface IAGnssRil { - void setCallback(in android.hardware.gnss.IAGnssRilCallback callback); - void setRefLocation(in android.hardware.gnss.IAGnssRil.AGnssRefLocation agnssReflocation); - void setSetId(in android.hardware.gnss.IAGnssRil.SetIDType type, in @utf8InCpp String setid); - void updateNetworkState(in android.hardware.gnss.IAGnssRil.NetworkAttributes attributes); - const int NETWORK_CAPABILITY_NOT_METERED = 1; - const int NETWORK_CAPABILITY_NOT_ROAMING = 2; - @Backing(type="int") @VintfStability - enum AGnssRefLocationType { - GSM_CELLID = 1, - UMTS_CELLID = 2, - LTE_CELLID = 4, - NR_CELLID = 8, - } - @Backing(type="int") @VintfStability - enum SetIDType { - NONE = 0, - IMSI = 1, - MSISDM = 2, - } - @VintfStability - parcelable AGnssRefLocationCellID { - android.hardware.gnss.IAGnssRil.AGnssRefLocationType type; - int mcc; - int mnc; - int lac; - long cid; - int tac; - int pcid; - int arfcn; - } - @VintfStability - parcelable AGnssRefLocation { - android.hardware.gnss.IAGnssRil.AGnssRefLocationType type; - android.hardware.gnss.IAGnssRil.AGnssRefLocationCellID cellID; - } - @VintfStability - parcelable NetworkAttributes { - long networkHandle; - boolean isConnected; - int capabilities; - @utf8InCpp String apn; - } -} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRilCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRilCallback.aidl deleted file mode 100644 index 152b10aea0..0000000000 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRilCallback.aidl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.gnss; -@VintfStability -interface IAGnssRilCallback { - void requestSetIdCb(in int setIdflag); - void requestRefLocCb(); -} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl index 8e967444ef..1b4c5817ce 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl @@ -44,7 +44,6 @@ interface IGnss { @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence(); @nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage(); android.hardware.gnss.IAGnss getExtensionAGnss(); - android.hardware.gnss.IAGnssRil getExtensionAGnssRil(); android.hardware.gnss.IGnssDebug getExtensionGnssDebug(); android.hardware.gnss.visibility_control.IGnssVisibilityControl getExtensionGnssVisibilityControl(); void start(); diff --git a/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl b/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl deleted file mode 100644 index b57c9bffb4..0000000000 --- a/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2022 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; - -import android.hardware.gnss.IAGnssRilCallback; -import android.hardware.gnss.IAGnssRilCallback.SetIDType; - -/** - * Extended interface for AGNSS RIL support. An Assisted GNSS Radio Interface - * Layer interface allows the GNSS chipset to request radio interface layer - * information from Android platform. Examples of such information are reference - * location, unique subscriber ID, phone number string and network availability changes. - */ -@VintfStability -interface IAGnssRil { - /** Network capability mode bitmask for not metered. */ - const int NETWORK_CAPABILITY_NOT_METERED = 0x01; - - /** Network capability mode bitmask for not roaming. */ - const int NETWORK_CAPABILITY_NOT_ROAMING = 0x02; - - /** AGNSS reference location type */ - @VintfStability - @Backing(type="int") - enum AGnssRefLocationType { - GSM_CELLID = 1, - UMTS_CELLID = 2, - LTE_CELLID = 4, - NR_CELLID = 8, - } - - /** SET ID type*/ - @VintfStability - @Backing(type="int") - enum SetIDType { - NONE = 0, - IMSI = 1, - MSISDM = 2, - } - - /** CellID for 2G, 3G ,LTE and NR used in AGNSS. */ - @VintfStability - parcelable AGnssRefLocationCellID { - AGnssRefLocationType type; - - /** Mobile Country Code. */ - int mcc; - - /** Mobile Network Code .*/ - int mnc; - - /** - * Location Area Code in 2G, 3G and LTE. In 3G lac is discarded. In LTE, - * lac is populated with tac, to ensure that we don't break old clients that - * might rely on the old (wrong) behavior. - */ - int lac; - - /** - * Cell id in 2G. Utran Cell id in 3G. Cell Global Id EUTRA in LTE. - * Cell Global Id NR in 5G. - */ - long cid; - - /** Tracking Area Code in LTE and NR. */ - int tac; - - /** Physical Cell id in LTE and NR (not used in 2G and 3G) */ - int pcid; - - /** Absolute Radio Frequency Channel Number in NR. */ - int arfcn; - } - - /** Represents ref locations */ - @VintfStability - parcelable AGnssRefLocation { - AGnssRefLocationType type; - - AGnssRefLocationCellID cellID; - } - - /** Represents network connection status and capabilities. */ - @VintfStability - parcelable NetworkAttributes { - /** Network handle of the network for use with the NDK API. */ - long networkHandle; - - /** - * True indicates that network connectivity exists and it is possible to - * establish connections and pass data. If false, only the networkHandle field - * is populated to indicate that this network has just disconnected. - */ - boolean isConnected; - - /** - * A bitfield of flags indicating the capabilities of this network. The bit masks are - * defined in NETWORK_CAPABILITY_*. - */ - int capabilities; - - /** - * Telephony preferred Access Point Name to use for carrier data connection when - * connected to a cellular network. Empty string, otherwise. - */ - @utf8InCpp String apn; - } - - /** - * Opens the AGNSS interface and provides the callback routines - * to the implementation of this interface. - * - * @param callback Interface for AGnssRil callbacks. - * - */ - void setCallback(in IAGnssRilCallback callback); - - /** - * Sets the reference location. - * - * @param agnssReflocation AGNSS reference location CellID. - * - */ - void setRefLocation(in AGnssRefLocation agnssReflocation); - - /** - * Sets the SET ID. - * - * @param type Must be populated with either IMSI or MSISDN or NONE. - * @param setid If type is IMSI then setid is populated with - * a string representing the unique Subscriber ID, for example, the IMSI for - * a GMS phone. If type is MSISDN, then setid must contain - * the phone number string for line 1. For example, the MSISDN for a GSM phone. - * If the type is NONE, then the string must be empty. - * - */ - void setSetId(in SetIDType type, in @utf8InCpp String setid); - - /** - * Notifies GNSS of network status changes. - * - * The framework calls this method to update the GNSS HAL implementation of network - * state changes. - * - * @param attributes Updated network attributes. - * - */ - void updateNetworkState(in NetworkAttributes attributes); -} diff --git a/gnss/aidl/android/hardware/gnss/IAGnssRilCallback.aidl b/gnss/aidl/android/hardware/gnss/IAGnssRilCallback.aidl deleted file mode 100644 index 6fb093e165..0000000000 --- a/gnss/aidl/android/hardware/gnss/IAGnssRilCallback.aidl +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2022 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; - -/** - * Callback for IAGnssRil interface. Used to request SET ID and - * Reference Location. - */ -@VintfStability -interface IAGnssRilCallback { - /** - * The Hal uses this API to request a SET ID. - * - * @param setIdflag A bitfield of IAGnssRil.SetIDType that is required by - * the HAL. The framework will inject an empty SET ID if the flag is NONE. - * - */ - void requestSetIdCb(in int setIdflag); - - /** - * The Hal uses this API to request a reference location. - */ - void requestRefLocCb(); -} diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index b6bd38a118..4ddc6a6193 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -18,7 +18,6 @@ package android.hardware.gnss; import android.hardware.gnss.GnssLocation; import android.hardware.gnss.IAGnss; -import android.hardware.gnss.IAGnssRil; import android.hardware.gnss.IGnssBatching; import android.hardware.gnss.IGnssCallback; import android.hardware.gnss.IGnssConfiguration; @@ -186,13 +185,6 @@ interface IGnss { */ IAGnss getExtensionAGnss(); - /** - * This method returns the IAGnssRil interface. - * - * @return The IAGnssRil interface. - */ - IAGnssRil getExtensionAGnssRil(); - /** * This method returns the IGnssDebug interface. * diff --git a/gnss/aidl/default/AGnssRil.cpp b/gnss/aidl/default/AGnssRil.cpp deleted file mode 100644 index e6009bdcd9..0000000000 --- a/gnss/aidl/default/AGnssRil.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2021 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 "AGnssRilAidl" - -#include "AGnssRil.h" -#include - -namespace aidl::android::hardware::gnss { - -std::shared_ptr AGnssRil::sCallback = nullptr; - -ndk::ScopedAStatus AGnssRil::setCallback(const std::shared_ptr& callback) { - ALOGD("AGnssRil::setCallback"); - std::unique_lock lock(mMutex); - sCallback = callback; - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus AGnssRil::setRefLocation(const AGnssRefLocation& agnssReflocation) { - const AGnssRefLocationCellID& cellInfo = agnssReflocation.cellID; - ALOGD("AGnssRil::setRefLocation: type: %s, mcc: %d, mnc: %d, lac: %d, cid: %ld, tac: %d, pcid: " - "%d, arfcn: %d", - toString(agnssReflocation.type).c_str(), cellInfo.mcc, cellInfo.mnc, cellInfo.lac, - cellInfo.cid, cellInfo.tac, cellInfo.pcid, cellInfo.arfcn); - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus AGnssRil::setSetId(SetIDType type, const std::string& setid) { - ALOGD("AGnssRil::setSetId: type:%s, setid: %s", toString(type).c_str(), setid.c_str()); - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus AGnssRil::updateNetworkState(const NetworkAttributes& attributes) { - ALOGD("AGnssRil::updateNetworkState: networkHandle: %ld, isConnected: %d, capabilities: %d, " - "apn: %s", - attributes.networkHandle, attributes.isConnected, attributes.capabilities, - attributes.apn.c_str()); - return ndk::ScopedAStatus::ok(); -} - -} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/AGnssRil.h b/gnss/aidl/default/AGnssRil.h deleted file mode 100644 index 7e429ee8f4..0000000000 --- a/gnss/aidl/default/AGnssRil.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -namespace aidl::android::hardware::gnss { - -struct AGnssRil : public BnAGnssRil { - public: - ndk::ScopedAStatus setCallback(const std::shared_ptr& callback) override; - ndk::ScopedAStatus setRefLocation(const AGnssRefLocation& agnssReflocation) override; - ndk::ScopedAStatus setSetId(SetIDType type, const std::string& setid) override; - ndk::ScopedAStatus updateNetworkState(const NetworkAttributes& attributes) override; - - private: - // Synchronization lock for sCallback - mutable std::mutex mMutex; - // Guarded by mMutex - static std::shared_ptr sCallback; -}; - -} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 5797e1c645..29c26d16ec 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -56,7 +56,6 @@ cc_binary { "android.hardware.gnss-V2-ndk", ], srcs: [ - "AGnssRil.cpp", "AGnss.cpp", "Gnss.cpp", "GnssBatching.cpp", diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index dba54a017d..e296351d95 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -20,7 +20,6 @@ #include #include #include "AGnss.h" -#include "AGnssRil.h" #include "GnssBatching.h" #include "GnssConfiguration.h" #include "GnssDebug.h" @@ -155,7 +154,7 @@ ScopedAStatus Gnss::close() { return ScopedAStatus::ok(); } -ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr* iAGnss) { +ndk::ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr* iAGnss) { ALOGD("Gnss::getExtensionAGnss"); *iAGnss = SharedRefBase::make(); return ndk::ScopedAStatus::ok(); @@ -167,12 +166,6 @@ ScopedAStatus Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int unce return ScopedAStatus::ok(); } -ScopedAStatus Gnss::getExtensionAGnssRil(std::shared_ptr* iAGnssRil) { - ALOGD("Gnss::getExtensionAGnssRil"); - *iAGnssRil = SharedRefBase::make(); - return ndk::ScopedAStatus::ok(); -} - ScopedAStatus Gnss::injectLocation(const GnssLocation& location) { ALOGD("injectLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees, location.longitudeDegrees, location.horizontalAccuracyMeters); diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index 731eaa3f36..384c8629a2 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -17,7 +17,6 @@ #pragma once #include -#include #include #include #include @@ -66,7 +65,6 @@ class Gnss : public BnGnss { ndk::ScopedAStatus getExtensionGnssNavigationMessage( std::shared_ptr* iGnssNavigationMessage) override; ndk::ScopedAStatus getExtensionAGnss(std::shared_ptr* iAGnss) override; - ndk::ScopedAStatus getExtensionAGnssRil(std::shared_ptr* iAGnssRil) override; ndk::ScopedAStatus getExtensionGnssDebug(std::shared_ptr* iGnssDebug) override; ndk::ScopedAStatus getExtensionGnssVisibilityControl( std::shared_ptr* diff --git a/gnss/aidl/vts/AGnssRilCallbackAidl.cpp b/gnss/aidl/vts/AGnssRilCallbackAidl.cpp deleted file mode 100644 index 4e4166d61d..0000000000 --- a/gnss/aidl/vts/AGnssRilCallbackAidl.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2022 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 "AGnssRilCallbackAidl.h" -#include - -android::binder::Status AGnssRilCallbackAidl::requestSetIdCb(int setIdflag) { - ALOGI("requestSetIdCb setIdflag %d", setIdflag); - return android::binder::Status::ok(); -} - -android::binder::Status AGnssRilCallbackAidl::requestRefLocCb() { - ALOGI("requestRefLocCb"); - return android::binder::Status::ok(); -} diff --git a/gnss/aidl/vts/AGnssRilCallbackAidl.h b/gnss/aidl/vts/AGnssRilCallbackAidl.h deleted file mode 100644 index 74b34eee94..0000000000 --- a/gnss/aidl/vts/AGnssRilCallbackAidl.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -/** Implementation for IAGnssRilCallback. */ -class AGnssRilCallbackAidl : public android::hardware::gnss::BnAGnssRilCallback { - public: - AGnssRilCallbackAidl(){}; - ~AGnssRilCallbackAidl(){}; - android::binder::Status requestSetIdCb(int setIdflag) override; - android::binder::Status requestRefLocCb() override; -}; diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index c39803f970..d532fad357 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -31,7 +31,6 @@ cc_test { "gnss_hal_test.cpp", "gnss_hal_test_cases.cpp", "AGnssCallbackAidl.cpp", - "AGnssRilCallbackAidl.cpp", "GnssBatchingCallback.cpp", "GnssCallbackAidl.cpp", "GnssGeofenceCallback.cpp", diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 6811b7b847..9acef8bed0 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -27,7 +27,6 @@ #include #include #include "AGnssCallbackAidl.h" -#include "AGnssRilCallbackAidl.h" #include "GnssBatchingCallback.h" #include "GnssGeofenceCallback.h" #include "GnssMeasurementCallbackAidl.h" @@ -44,7 +43,6 @@ using android::hardware::gnss::GnssData; using android::hardware::gnss::GnssMeasurement; using android::hardware::gnss::GnssPowerStats; using android::hardware::gnss::IAGnss; -using android::hardware::gnss::IAGnssRil; using android::hardware::gnss::IGnss; using android::hardware::gnss::IGnssBatching; using android::hardware::gnss::IGnssBatchingCallback; @@ -859,42 +857,6 @@ TEST_P(GnssHalTest, TestAGnssExtension) { ASSERT_TRUE(status.isOk()); } -/* - * TestAGnssRilExtension: - * 1. Gets the IAGnssRil extension. - * 2. Sets AGnssRilCallback. - * 3. Sets reference location. - */ -TEST_P(GnssHalTest, TestAGnssRilExtension) { - if (aidl_gnss_hal_->getInterfaceVersion() == 1) { - return; - } - sp iAGnssRil; - auto status = aidl_gnss_hal_->getExtensionAGnssRil(&iAGnssRil); - ASSERT_TRUE(status.isOk()); - ASSERT_TRUE(iAGnssRil != nullptr); - - auto agnssRilCallback = sp::make(); - status = iAGnssRil->setCallback(agnssRilCallback); - ASSERT_TRUE(status.isOk()); - - // Set RefLocation - IAGnssRil::AGnssRefLocationCellID agnssReflocationCellId; - agnssReflocationCellId.type = IAGnssRil::AGnssRefLocationType::LTE_CELLID; - agnssReflocationCellId.mcc = 466; - agnssReflocationCellId.mnc = 97; - agnssReflocationCellId.lac = 46697; - agnssReflocationCellId.cid = 59168142; - agnssReflocationCellId.pcid = 420; - agnssReflocationCellId.tac = 11460; - IAGnssRil::AGnssRefLocation agnssReflocation; - agnssReflocation.type = IAGnssRil::AGnssRefLocationType::LTE_CELLID; - agnssReflocation.cellID = agnssReflocationCellId; - - status = iAGnssRil->setRefLocation(agnssReflocation); - ASSERT_TRUE(status.isOk()); -} - /* * GnssDebugValuesSanityTest: * Ensures that GnssDebug values make sense. -- cgit v1.2.3 From 0f5c11d9653be2523c4a61d9e93b640f37a87e7b Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Thu, 9 Dec 2021 12:22:37 +0100 Subject: bluetooth.audio pass both source and sink metadata Currently just source metadata is passed through the new aidl. Test: m android.hardware.bluetooth.audio-update-api Bug: 203490261 Bug: 150670922 Change-Id: I76a44bb8c5cb0b6c16845aca36ba93517ecd07b4 Merged-In: I76a44bb8c5cb0b6c16845aca36ba93517ecd07b4 --- .../android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl | 3 ++- .../android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl index e389ef3876..9a1557a488 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl @@ -38,5 +38,6 @@ interface IBluetoothAudioPort { void startStream(); void stopStream(); void suspendStream(); - void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata); + void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata); + void updateSinkMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata); } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl index 50e3197c48..827f57d91b 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl @@ -16,6 +16,7 @@ package android.hardware.bluetooth.audio; +import android.hardware.audio.common.SinkMetadata; import android.hardware.audio.common.SourceMetadata; import android.hardware.bluetooth.audio.PresentationPosition; @@ -69,5 +70,12 @@ interface IBluetoothAudioPort { * @param sourceMetadata Description of the audio that is played by the * clients. */ - void updateMetadata(in SourceMetadata sourceMetadata); + void updateSourceMetadata(in SourceMetadata sourceMetadata); + + /** + * Called when the metadata of the stream's sink has been changed. + * + * @param sinkMetadata as passed from Audio Framework + */ + void updateSinkMetadata(in SinkMetadata sinkMetadata); } -- cgit v1.2.3 From 60b00151bddb0ca5e5f3afbeb539f8070212e105 Mon Sep 17 00:00:00 2001 From: Alice Kuo Date: Mon, 10 Jan 2022 18:17:48 +0800 Subject: Add le audio capabilities and audio config update supported in aidl Bug: 203490261 Bug: 150670922 Test: m android.hardware.bluetooth.audio-update-api Change-Id: I035aad6ee6f6ac0833d9716b50323620ce6df34b --- .../bluetooth/audio/AudioCapabilities.aidl | 2 +- .../bluetooth/audio/BroadcastCapability.aidl | 50 +++++++++++++++++++++ .../bluetooth/audio/BroadcastConfiguration.aidl | 2 +- .../bluetooth/audio/IBluetoothAudioProvider.aidl | 1 + .../bluetooth/audio/LeAudioCapabilities.aidl | 51 ---------------------- .../audio/LeAudioCodecCapabilitiesSetting.aidl | 40 +++++++++++++++++ .../bluetooth/audio/UnicastCapability.aidl | 51 ++++++++++++++++++++++ .../bluetooth/audio/AudioCapabilities.aidl | 4 +- .../bluetooth/audio/BroadcastCapability.aidl | 43 ++++++++++++++++++ .../bluetooth/audio/BroadcastConfiguration.aidl | 2 +- .../bluetooth/audio/IBluetoothAudioProvider.aidl | 10 +++++ .../bluetooth/audio/LeAudioCapabilities.aidl | 47 -------------------- .../audio/LeAudioCodecCapabilitiesSetting.aidl | 30 +++++++++++++ .../bluetooth/audio/UnicastCapability.aidl | 45 +++++++++++++++++++ 14 files changed, 275 insertions(+), 103 deletions(-) create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl delete mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl delete mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl index 20a7731010..43d79111d9 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl @@ -36,5 +36,5 @@ package android.hardware.bluetooth.audio; union AudioCapabilities { android.hardware.bluetooth.audio.PcmCapabilities pcmCapabilities; android.hardware.bluetooth.audio.CodecCapabilities codecCapabilities; - android.hardware.bluetooth.audio.LeAudioCapabilities leAudioCapabilities; + android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting leAudioCapabilities; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl new file mode 100644 index 0000000000..58710effe7 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl @@ -0,0 +1,50 @@ +/* + * Copyright 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable BroadcastCapability { + android.hardware.bluetooth.audio.CodecType codecType; + android.hardware.bluetooth.audio.AudioLocation supportedChannel; + int channelCountPerStream; + android.hardware.bluetooth.audio.BroadcastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities; + @VintfStability + parcelable VendorCapabilities { + ParcelableHolder extension; + } + @VintfStability + union LeAudioCodecCapabilities { + @nullable android.hardware.bluetooth.audio.Lc3Capabilities[] lc3Capabilities; + @nullable android.hardware.bluetooth.audio.BroadcastCapability.VendorCapabilities[] vendorCapabillities; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl index b3aa709ddd..5fa392631b 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl @@ -39,6 +39,6 @@ parcelable BroadcastConfiguration { parcelable BroadcastStreamMap { char streamHandle; int audioChannelAllocation; - android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCondecConfig; + android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig; } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl index e5e79cb1c4..0dcba2e818 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -38,4 +38,5 @@ interface IBluetoothAudioProvider { android.hardware.common.fmq.MQDescriptor startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig); void streamStarted(in android.hardware.bluetooth.audio.BluetoothAudioStatus status); void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status); + void updateAudioConfiguration(in android.hardware.bluetooth.audio.AudioConfiguration audioConfig); } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl deleted file mode 100644 index a7224ca5da..0000000000 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2021 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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.bluetooth.audio; -@VintfStability -parcelable LeAudioCapabilities { - android.hardware.bluetooth.audio.LeAudioMode mode; - android.hardware.bluetooth.audio.CodecType codecType; - android.hardware.bluetooth.audio.AudioLocation supportedChannel; - int supportedChannelCount; - android.hardware.bluetooth.audio.LeAudioCapabilities.LeAudioCodecCapabilities leAudioCodecCapabilities; - @VintfStability - parcelable VendorCapabilities { - ParcelableHolder extension; - } - @VintfStability - union LeAudioCodecCapabilities { - android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities; - android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities; - } -} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl new file mode 100644 index 0000000000..9818d543ac --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl @@ -0,0 +1,40 @@ +/* + * Copyright 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable LeAudioCodecCapabilitiesSetting { + android.hardware.bluetooth.audio.UnicastCapability unicastEncodeCapability; + android.hardware.bluetooth.audio.UnicastCapability unicastDecodeCapability; + android.hardware.bluetooth.audio.BroadcastCapability broadcastCapability; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl new file mode 100644 index 0000000000..130fef971c --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl @@ -0,0 +1,51 @@ +/* + * Copyright 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable UnicastCapability { + android.hardware.bluetooth.audio.CodecType codecType; + android.hardware.bluetooth.audio.AudioLocation supportedChannel; + int deviceCount; + int channelCountPerDevice; + android.hardware.bluetooth.audio.UnicastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities; + @VintfStability + parcelable VendorCapabilities { + ParcelableHolder extension; + } + @VintfStability + union LeAudioCodecCapabilities { + android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities; + android.hardware.bluetooth.audio.UnicastCapability.VendorCapabilities vendorCapabillities; + } +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl index 6ed44722cc..339c475d47 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl @@ -17,7 +17,7 @@ package android.hardware.bluetooth.audio; import android.hardware.bluetooth.audio.CodecCapabilities; -import android.hardware.bluetooth.audio.LeAudioCapabilities; +import android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting; import android.hardware.bluetooth.audio.PcmCapabilities; /** @@ -27,5 +27,5 @@ import android.hardware.bluetooth.audio.PcmCapabilities; union AudioCapabilities { PcmCapabilities pcmCapabilities; CodecCapabilities codecCapabilities; - LeAudioCapabilities leAudioCapabilities; + LeAudioCodecCapabilitiesSetting leAudioCapabilities; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl new file mode 100644 index 0000000000..cb63f88ea9 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl @@ -0,0 +1,43 @@ +/* + * Copyright 2022 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.AudioLocation; +import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.Lc3Capabilities; +import android.hardware.bluetooth.audio.LeAudioMode; + +/** + * Used to specify the le audio broadcast codec capabilities for hardware offload. + */ +@VintfStability +parcelable BroadcastCapability { + @VintfStability + parcelable VendorCapabilities { + ParcelableHolder extension; + } + @VintfStability + union LeAudioCodecCapabilities { + @nullable Lc3Capabilities[] lc3Capabilities; + @nullable VendorCapabilities[] vendorCapabillities; + } + CodecType codecType; + AudioLocation supportedChannel; + // Supported channel count for each stream + int channelCountPerStream; + LeAudioCodecCapabilities leAudioCodecCapabilities; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl index 07d05f1bd7..cfc9d3aa01 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl @@ -33,7 +33,7 @@ parcelable BroadcastConfiguration { * least significant bit to the most significant bit. */ int audioChannelAllocation; - LeAudioCodecConfiguration leAudioCondecConfig; + LeAudioCodecConfiguration leAudioCodecConfig; } BroadcastStreamMap[] streamMap; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl index a2c5ae9a76..6f88f3041a 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -72,4 +72,14 @@ interface IBluetoothAudioProvider { * @param status true for SUCCESS or false for FAILURE */ void streamSuspended(in BluetoothAudioStatus status); + + /** + * Called when the audio configuration of the stream has been changed. + * + * @param audioConfig The audio configuration negotiated with the remote + * device. The PCM parameters are set if software based encoding, + * otherwise the correct codec configuration is used for hardware + * encoding. + */ + void updateAudioConfiguration(in AudioConfiguration audioConfig); } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl deleted file mode 100644 index 732427f060..0000000000 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2021 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.bluetooth.audio; - -import android.hardware.bluetooth.audio.AudioLocation; -import android.hardware.bluetooth.audio.CodecType; -import android.hardware.bluetooth.audio.Lc3Capabilities; -import android.hardware.bluetooth.audio.LeAudioMode; - -/** - * Used to specify the capabilities of the LC3 codecs supported by Hardware Encoding. - */ -@VintfStability -parcelable LeAudioCapabilities { - @VintfStability - parcelable VendorCapabilities { - ParcelableHolder extension; - } - @VintfStability - union LeAudioCodecCapabilities { - Lc3Capabilities lc3Capabilities; - VendorCapabilities vendorCapabillities; - } - LeAudioMode mode; - CodecType codecType; - /* - * This is bitfield, if bit N is set, HW Offloader supports N+1 channels at the same time. - * Example: 0x27 = 0b00100111: One, two, three or six channels supported. - */ - AudioLocation supportedChannel; - int supportedChannelCount; - LeAudioCodecCapabilities leAudioCodecCapabilities; -} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl new file mode 100644 index 0000000000..58dac06080 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl @@ -0,0 +1,30 @@ +/* + * Copyright 2022 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.BroadcastCapability; +import android.hardware.bluetooth.audio.UnicastCapability; + +/** + * Used to specify the le audio capabilities for unicast and broadcast hardware offload. + */ +@VintfStability +parcelable LeAudioCodecCapabilitiesSetting { + UnicastCapability unicastEncodeCapability; + UnicastCapability unicastDecodeCapability; + BroadcastCapability broadcastCapability; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl new file mode 100644 index 0000000000..cd8a4c1971 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl @@ -0,0 +1,45 @@ +/* + * Copyright 2021 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.bluetooth.audio; + +import android.hardware.bluetooth.audio.AudioLocation; +import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.Lc3Capabilities; +import android.hardware.bluetooth.audio.LeAudioMode; + +/** + * Used to specify the le audio unicast codec capabilities for hardware offload. + */ +@VintfStability +parcelable UnicastCapability { + @VintfStability + parcelable VendorCapabilities { + ParcelableHolder extension; + } + @VintfStability + union LeAudioCodecCapabilities { + Lc3Capabilities lc3Capabilities; + VendorCapabilities vendorCapabillities; + } + CodecType codecType; + AudioLocation supportedChannel; + // The number of connected device + int deviceCount; + // Supported channel count for each device + int channelCountPerDevice; + LeAudioCodecCapabilities leAudioCodecCapabilities; +} -- cgit v1.2.3 From 1bc606fafea8e2488836ad34f51d6d51c60169fa Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Tue, 21 Dec 2021 03:17:23 -0800 Subject: BT: Support LC3 over A2DP Test: m android.hardware.bluetooth.audio-update-api Bug: 211589164 Change-Id: Ib2efd9b5af71fa0188edb85b13cf031710b6fe21 --- .../current/android/hardware/bluetooth/audio/AudioCapabilities.aidl | 2 +- .../android/hardware/bluetooth/audio/AudioConfiguration.aidl | 2 +- .../current/android/hardware/bluetooth/audio/CodecCapabilities.aidl | 1 + .../android/hardware/bluetooth/audio/CodecConfiguration.aidl | 1 + .../current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl | 1 + .../current/android/hardware/bluetooth/audio/Lc3Configuration.aidl | 1 + .../aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl | 2 +- .../aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl | 2 +- .../aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl | 2 ++ .../aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl | 2 ++ .../aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl | 6 ++++++ .../aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl | 6 ++++++ 12 files changed, 24 insertions(+), 4 deletions(-) diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl index 43d79111d9..8ae716ff23 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl @@ -35,6 +35,6 @@ package android.hardware.bluetooth.audio; @VintfStability union AudioCapabilities { android.hardware.bluetooth.audio.PcmCapabilities pcmCapabilities; - android.hardware.bluetooth.audio.CodecCapabilities codecCapabilities; + android.hardware.bluetooth.audio.CodecCapabilities a2dpCapabilities; android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting leAudioCapabilities; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl index 34f7837967..50b54c30c0 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl @@ -35,6 +35,6 @@ package android.hardware.bluetooth.audio; @VintfStability union AudioConfiguration { android.hardware.bluetooth.audio.PcmConfiguration pcmConfig; - android.hardware.bluetooth.audio.CodecConfiguration codecConfig; + android.hardware.bluetooth.audio.CodecConfiguration a2dpConfig; android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl index b451880e05..e2a08a0e6d 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl @@ -42,5 +42,6 @@ parcelable CodecCapabilities { android.hardware.bluetooth.audio.AacCapabilities aacCapabilities; android.hardware.bluetooth.audio.LdacCapabilities ldacCapabilities; android.hardware.bluetooth.audio.AptxCapabilities aptxCapabilities; + android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities; } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl index 863aee244c..34ebd60530 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl @@ -45,5 +45,6 @@ parcelable CodecConfiguration { android.hardware.bluetooth.audio.AacConfiguration aacConfig; android.hardware.bluetooth.audio.LdacConfiguration ldacConfig; android.hardware.bluetooth.audio.AptxConfiguration aptxConfig; + android.hardware.bluetooth.audio.Lc3Configuration lc3Config; } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl index 3c650da4f7..cc4449aea9 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl @@ -39,4 +39,5 @@ parcelable Lc3Capabilities { int[] frameDurationUs; int[] octetsPerFrame; byte[] blocksPerSdu; + android.hardware.bluetooth.audio.ChannelMode[] channelMode; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl index ef77da7023..7e8dccff5f 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl @@ -39,4 +39,5 @@ parcelable Lc3Configuration { int frameDurationUs; int octetsPerFrame; byte blocksPerSdu; + android.hardware.bluetooth.audio.ChannelMode channelMode; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl index 339c475d47..a75c4457e9 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl @@ -26,6 +26,6 @@ import android.hardware.bluetooth.audio.PcmCapabilities; @VintfStability union AudioCapabilities { PcmCapabilities pcmCapabilities; - CodecCapabilities codecCapabilities; + CodecCapabilities a2dpCapabilities; LeAudioCodecCapabilitiesSetting leAudioCapabilities; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl index ce515b5611..81b41dcf7f 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl @@ -26,6 +26,6 @@ import android.hardware.bluetooth.audio.PcmConfiguration; @VintfStability union AudioConfiguration { PcmConfiguration pcmConfig; - CodecConfiguration codecConfig; + CodecConfiguration a2dpConfig; LeAudioConfiguration leAudioConfig; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl index 0eee8cb55b..5bf0252bf8 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl @@ -19,6 +19,7 @@ package android.hardware.bluetooth.audio; import android.hardware.bluetooth.audio.AacCapabilities; import android.hardware.bluetooth.audio.AptxCapabilities; import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.Lc3Capabilities; import android.hardware.bluetooth.audio.LdacCapabilities; import android.hardware.bluetooth.audio.SbcCapabilities; @@ -34,6 +35,7 @@ parcelable CodecCapabilities { AacCapabilities aacCapabilities; LdacCapabilities ldacCapabilities; AptxCapabilities aptxCapabilities; + Lc3Capabilities lc3Capabilities; } CodecType codecType; Capabilities capabilities; diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl index fac90f065d..9e43f2244a 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl @@ -19,6 +19,7 @@ package android.hardware.bluetooth.audio; import android.hardware.bluetooth.audio.AacConfiguration; import android.hardware.bluetooth.audio.AptxConfiguration; import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.Lc3Configuration; import android.hardware.bluetooth.audio.LdacConfiguration; import android.hardware.bluetooth.audio.SbcConfiguration; @@ -34,6 +35,7 @@ parcelable CodecConfiguration { AacConfiguration aacConfig; LdacConfiguration ldacConfig; AptxConfiguration aptxConfig; + Lc3Configuration lc3Config; } CodecType codecType; /** diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl index 1aedefd2d5..fc2f382d18 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl @@ -16,6 +16,8 @@ package android.hardware.bluetooth.audio; +import android.hardware.bluetooth.audio.ChannelMode; + /** * Used for Hardware Encoding/Decoding LC3 codec capabilities. */ @@ -41,4 +43,8 @@ parcelable Lc3Capabilities { * Number of blocks of codec frames per single SDU (Service Data Unit) */ byte[] blocksPerSdu; + /* + * Channel mode used in A2DP special audio, ignored in standard LE Audio mode + */ + ChannelMode[] channelMode; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl index 77c04c1b6e..e8a93b27d8 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl @@ -16,6 +16,8 @@ package android.hardware.bluetooth.audio; +import android.hardware.bluetooth.audio.ChannelMode; + /** * Used for Hardware Encoding/Decoding LC3 codec configuration. */ @@ -41,4 +43,8 @@ parcelable Lc3Configuration { * Number of blocks of codec frames per single SDU (Service Data Unit) */ byte blocksPerSdu; + /* + * Channel mode used in A2DP special audio, ignored in standard LE Audio mode + */ + ChannelMode channelMode; } -- cgit v1.2.3 From 4d37f69678a4907d2510e72d25ccf1da7ae9970f Mon Sep 17 00:00:00 2001 From: Serik Beketayev Date: Mon, 29 Nov 2021 15:24:19 -0800 Subject: [IHostapd] Support vendor-specific AP config elem Bug: 139204496 Test: mma -j Change-Id: I7caa7d3b27bca7898d8857bfb841b5466643644e --- .../current/android/hardware/wifi/hostapd/NetworkParams.aidl | 1 + .../hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl index ffe2f33475..4554223751 100644 --- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl +++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl @@ -39,4 +39,5 @@ parcelable NetworkParams { android.hardware.wifi.hostapd.EncryptionType encryptionType; String passphrase; boolean isMetered; + byte[] vendorElements; } diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl index df84eca23d..47d9e6f96b 100644 --- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl +++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl @@ -44,4 +44,12 @@ parcelable NetworkParams { * CHARGEABLE_PUBLIC_NETWORK when set to true. */ boolean isMetered; + /** + * Additional vendor specific elements for Beacon and Probe Response frames + * This parameter can be used to add additional vendor specific element(s) into + * the end of the Beacon and Probe Response frames. The format for these + * element(s) is a binary dump of the raw information elements (id+len+payload for + * one or more elements). Example: byte[]{ 221, 4, 17, 34, 51, 1 } + */ + byte[] vendorElements; } -- cgit v1.2.3 From 37f1609ed5d1a5aa81b24a74b787b47750b44cf2 Mon Sep 17 00:00:00 2001 From: Janis Danisevskis Date: Tue, 14 Dec 2021 16:32:44 -0800 Subject: DICE: Use fixed sized arrays for fixed sized fields. Bug: 210149444 Test: N/A Change-Id: I1d4e502cb6535117f51d2d0ce008f2669fc90e96 --- .../current/android/hardware/security/dice/BccHandover.aidl | 4 ++-- .../current/android/hardware/security/dice/InputValues.aidl | 6 +++--- .../dice/aidl/android/hardware/security/dice/BccHandover.aidl | 8 ++++---- .../dice/aidl/android/hardware/security/dice/InputValues.aidl | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl index ab50c369a7..8baca94ce8 100644 --- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl +++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl @@ -35,7 +35,7 @@ package android.hardware.security.dice; /* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable BccHandover { - byte[] cdiAttest; - byte[] cdiSeal; + byte[32] cdiAttest; + byte[32] cdiSeal; android.hardware.security.dice.Bcc bcc; } diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl index 79583fbb98..e43c4292e4 100644 --- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl +++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl @@ -35,10 +35,10 @@ package android.hardware.security.dice; /* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable InputValues { - byte[] codeHash; + byte[64] codeHash; android.hardware.security.dice.Config config; - byte[] authorityHash; + byte[64] authorityHash; @nullable byte[] authorityDescriptor; android.hardware.security.dice.Mode mode = android.hardware.security.dice.Mode.NOT_INITIALIZED; - byte[] hidden; + byte[64] hidden; } diff --git a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl index d522cef7a4..6ca862cdf9 100644 --- a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl +++ b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl @@ -27,13 +27,13 @@ import android.hardware.security.dice.Bcc; @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) parcelable BccHandover { /** - * CDI_attest. Must a exactly 32 bytes of data. + * CDI_attest. Must be exactly 32 bytes of data. */ - byte[] cdiAttest; + byte[32] cdiAttest; /** - * CDI_seal. Must a exactly 32 bytes of data. + * CDI_seal. Must be exactly 32 bytes of data. */ - byte[] cdiSeal; + byte[32] cdiSeal; /** * CBOR encoded BCC. * diff --git a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl index e44ef22365..711d5232c5 100644 --- a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl +++ b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl @@ -34,7 +34,7 @@ parcelable InputValues { /** * The target code hash. Must be exactly 64 bytes. */ - byte[] codeHash; + byte[64] codeHash; /** * The configuration data. */ @@ -42,7 +42,7 @@ parcelable InputValues { /** * The authority hash. Must be exactly 64 bytes. Must be all zero if unused. */ - byte[] authorityHash; + byte[64] authorityHash; /** * Optional free form authorityDescriptor. */ @@ -54,5 +54,5 @@ parcelable InputValues { /** * Optional hidden values. Must be exactly 64 bytes. Must be all zero if unused. */ - byte[] hidden; + byte[64] hidden; } -- cgit v1.2.3 From 189cf702dba99639db7ca3074a6d94937233a3ac Mon Sep 17 00:00:00 2001 From: Sunil Ravi Date: Wed, 8 Dec 2021 18:54:10 -0800 Subject: Inform p2p framework about the channel change event Added a callback function to indicate that the p2p operating frequency has been changed. Bug: 202758240 Test: vts test Test: Manually triggered channel switch through hostapd command and verified the new frequency in logs. Change-Id: I5814a108c77478cf96bc88f2d8fd8193bd8168be --- .../hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl | 1 + .../hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl | 8 ++++++++ .../aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl index ed435e2097..826d9167b9 100644 --- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl +++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl @@ -50,4 +50,5 @@ interface ISupplicantP2pIfaceCallback { oneway void onServiceDiscoveryResponse(in byte[] srcAddress, in char updateIndicator, in byte[] tlvs); oneway void onStaAuthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress); oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress); + oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency); } diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl index f0cabd6ff8..2b58cc2c82 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl @@ -205,4 +205,12 @@ interface ISupplicantP2pIfaceCallback { * @param p2pDeviceAddress P2P device address. */ oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress); + + /** + * Used to indicate that operating frequency has changed for this P2P group interface. + * + * @param groupIfName Interface name of the group. (For ex: p2p-p2p0-1) + * @param frequency New operating frequency in MHz. + */ + oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency); } diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp index 2f4f06d355..db67867d80 100644 --- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp +++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp @@ -159,6 +159,10 @@ class SupplicantP2pIfaceCallback : public BnSupplicantP2pIfaceCallback { const std::vector& /* p2pDeviceAddress */) override { return ndk::ScopedAStatus::ok(); } + ::ndk::ScopedAStatus onGroupFrequencyChanged(const std::string& /* groupIfname */, + int32_t /* frequency */) override { + return ndk::ScopedAStatus::ok(); + } }; class SupplicantP2pIfaceAidlTest : public testing::TestWithParam { -- cgit v1.2.3 From 17857cc469d41de1297d216ab78186a29bb2c5b6 Mon Sep 17 00:00:00 2001 From: Tyler Trephan Date: Tue, 16 Nov 2021 21:23:12 +0000 Subject: Updated multihal to use new sensors AIDL interface. Test: make android.hardware.sensors@aidl-multihal Fix: 206867060 Change-Id: I9b78a0f25117d11fdf4beb1e0913393c1c14620d --- sensors/aidl/default/multihal/Android.bp | 57 +++ sensors/aidl/default/multihal/HalProxyAidl.cpp | 213 +++++++++++ .../aidl/default/multihal/include/ConvertUtils.h | 422 +++++++++++++++++++++ .../include/EventMessageQueueWrapperAidl.h | 99 +++++ .../aidl/default/multihal/include/HalProxyAidl.h | 64 ++++ .../multihal/include/ISensorsCallbackWrapperAidl.h | 66 ++++ .../include/WakeLockMessageQueueWrapperAidl.h | 62 +++ sensors/aidl/multihal/Android.bp | 59 +++ sensors/aidl/multihal/OWNERS | 3 + .../multihal/android.hardware.sensors-multihal.xml | 23 ++ .../android.hardware.sensors-service-multihal.rc | 7 + sensors/aidl/multihal/service.cpp | 36 ++ sensors/common/default/2.X/multihal/HalProxy.cpp | 21 +- .../common/default/2.X/multihal/include/HalProxy.h | 12 +- sensors/common/utils/WakeLockMessageQueueWrapper.h | 72 ++++ 15 files changed, 1206 insertions(+), 10 deletions(-) create mode 100644 sensors/aidl/default/multihal/Android.bp create mode 100644 sensors/aidl/default/multihal/HalProxyAidl.cpp create mode 100644 sensors/aidl/default/multihal/include/ConvertUtils.h create mode 100644 sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h create mode 100644 sensors/aidl/default/multihal/include/HalProxyAidl.h create mode 100644 sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h create mode 100644 sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h create mode 100644 sensors/aidl/multihal/Android.bp create mode 100644 sensors/aidl/multihal/OWNERS create mode 100644 sensors/aidl/multihal/android.hardware.sensors-multihal.xml create mode 100644 sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc create mode 100644 sensors/aidl/multihal/service.cpp create mode 100644 sensors/common/utils/WakeLockMessageQueueWrapper.h diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp new file mode 100644 index 0000000000..a7f6af2df2 --- /dev/null +++ b/sensors/aidl/default/multihal/Android.bp @@ -0,0 +1,57 @@ +// +// Copyright (C) 2021 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_library_static { + name: "android.hardware.sensors@aidl-multihal", + vendor: true, + header_libs: [ + "android.hardware.sensors@2.X-multihal.header", + "android.hardware.sensors@2.X-shared-utils", + ], + shared_libs: [ + "libfmq", + "libpower", + "libbase", + "libbinder_ndk", + "android.hardware.sensors@1.0", + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "android.hardware.sensors-V1-ndk", + ], + export_include_dirs: ["include"], + srcs: [ + "HalProxyAidl.cpp", + ], + visibility: [ + ":__subpackages__", + "//hardware/interfaces/sensors/aidl/multihal:__subpackages__", + "//hardware/interfaces/tests/extension/sensors:__subpackages__", + ], + static_libs: [ + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-multihal", + "libaidlcommonsupport", + ], +} diff --git a/sensors/aidl/default/multihal/HalProxyAidl.cpp b/sensors/aidl/default/multihal/HalProxyAidl.cpp new file mode 100644 index 0000000000..64805e6638 --- /dev/null +++ b/sensors/aidl/default/multihal/HalProxyAidl.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2021 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 "HalProxyAidl.h" +#include +#include +#include +#include "ConvertUtils.h" +#include "EventMessageQueueWrapperAidl.h" +#include "ISensorsCallbackWrapperAidl.h" +#include "WakeLockMessageQueueWrapperAidl.h" +#include "convertV2_1.h" + +using ::aidl::android::hardware::common::fmq::MQDescriptor; +using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; +using ::aidl::android::hardware::sensors::ISensors; +using ::aidl::android::hardware::sensors::ISensorsCallback; +using ::android::hardware::sensors::V2_1::implementation::convertToOldEvent; + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +static binder_status_t resultToBinderStatus(::android::hardware::sensors::V1_0::Result result) { + switch (result) { + case ::android::hardware::sensors::V1_0::Result::OK: + return STATUS_OK; + case ::android::hardware::sensors::V1_0::Result::PERMISSION_DENIED: + return STATUS_PERMISSION_DENIED; + case ::android::hardware::sensors::V1_0::Result::NO_MEMORY: + return STATUS_NO_MEMORY; + case ::android::hardware::sensors::V1_0::Result::BAD_VALUE: + return STATUS_BAD_VALUE; + case ::android::hardware::sensors::V1_0::Result::INVALID_OPERATION: + return STATUS_INVALID_OPERATION; + } +} + +static ::android::hardware::sensors::V1_0::RateLevel convertRateLevel( + ISensors::RateLevel rateLevel) { + switch (rateLevel) { + case ISensors::RateLevel::STOP: + return ::android::hardware::sensors::V1_0::RateLevel::STOP; + case ISensors::RateLevel::NORMAL: + return ::android::hardware::sensors::V1_0::RateLevel::NORMAL; + case ISensors::RateLevel::FAST: + return ::android::hardware::sensors::V1_0::RateLevel::FAST; + case ISensors::RateLevel::VERY_FAST: + return ::android::hardware::sensors::V1_0::RateLevel::VERY_FAST; + } +} + +static ::android::hardware::sensors::V1_0::OperationMode convertOperationMode( + ISensors::OperationMode operationMode) { + switch (operationMode) { + case ISensors::OperationMode::NORMAL: + return ::android::hardware::sensors::V1_0::OperationMode::NORMAL; + case ISensors::OperationMode::DATA_INJECTION: + return ::android::hardware::sensors::V1_0::OperationMode::DATA_INJECTION; + } +} + +static ::android::hardware::sensors::V1_0::SharedMemType convertSharedMemType( + ISensors::SharedMemInfo::SharedMemType sharedMemType) { + switch (sharedMemType) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: + return ::android::hardware::sensors::V1_0::SharedMemType::ASHMEM; + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: + return ::android::hardware::sensors::V1_0::SharedMemType::GRALLOC; + } +} + +static ::android::hardware::sensors::V1_0::SharedMemFormat convertSharedMemFormat( + ISensors::SharedMemInfo::SharedMemFormat sharedMemFormat) { + switch (sharedMemFormat) { + case ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT: + return ::android::hardware::sensors::V1_0::SharedMemFormat::SENSORS_EVENT; + } +} + +static ::android::hardware::sensors::V1_0::SharedMemInfo convertSharedMemInfo( + const ISensors::SharedMemInfo& sharedMemInfo) { + ::android::hardware::sensors::V1_0::SharedMemInfo v1SharedMemInfo; + v1SharedMemInfo.type = convertSharedMemType(sharedMemInfo.type); + v1SharedMemInfo.format = convertSharedMemFormat(sharedMemInfo.format); + v1SharedMemInfo.size = sharedMemInfo.size; + v1SharedMemInfo.memoryHandle = + ::android::hardware::hidl_handle(::android::makeFromAidl(sharedMemInfo.memoryHandle)); + return v1SharedMemInfo; +} + +::ndk::ScopedAStatus HalProxyAidl::activate(int32_t in_sensorHandle, bool in_enabled) { + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::activate(in_sensorHandle, in_enabled))); +} + +::ndk::ScopedAStatus HalProxyAidl::batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs, + int64_t in_maxReportLatencyNs) { + return ndk::ScopedAStatus::fromStatus(resultToBinderStatus( + HalProxy::batch(in_sensorHandle, in_samplingPeriodNs, in_maxReportLatencyNs))); +} + +::ndk::ScopedAStatus HalProxyAidl::configDirectReport(int32_t in_sensorHandle, + int32_t in_channelHandle, + ISensors::RateLevel in_rate, + int32_t* _aidl_return) { + binder_status_t binderStatus; + HalProxy::configDirectReport( + in_sensorHandle, in_channelHandle, convertRateLevel(in_rate), + [&binderStatus, _aidl_return](::android::hardware::sensors::V1_0::Result result, + int32_t reportToken) { + binderStatus = resultToBinderStatus(result); + *_aidl_return = reportToken; + }); + return ndk::ScopedAStatus::fromStatus(binderStatus); +} + +::ndk::ScopedAStatus HalProxyAidl::flush(int32_t in_sensorHandle) { + return ndk::ScopedAStatus::fromStatus(resultToBinderStatus(HalProxy::flush(in_sensorHandle))); +} + +::ndk::ScopedAStatus HalProxyAidl::getSensorsList( + std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) { + for (const auto& sensor : HalProxy::getSensors()) { + _aidl_return->push_back(convertSensorInfo(sensor.second)); + } + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus HalProxyAidl::initialize( + const MQDescriptor<::aidl::android::hardware::sensors::Event, SynchronizedReadWrite>& + in_eventQueueDescriptor, + const MQDescriptor& in_wakeLockDescriptor, + const std::shared_ptr& in_sensorsCallback) { + ::android::sp<::android::hardware::sensors::V2_1::implementation::ISensorsCallbackWrapperBase> + dynamicCallback = new ISensorsCallbackWrapperAidl(in_sensorsCallback); + + auto aidlEventQueue = + std::make_unique<::android::AidlMessageQueue<::aidl::android::hardware::sensors::Event, + SynchronizedReadWrite>>( + in_eventQueueDescriptor, true /* resetPointers */); + std::unique_ptr< + ::android::hardware::sensors::V2_1::implementation::EventMessageQueueWrapperBase> + eventQueue = std::make_unique(aidlEventQueue); + + auto aidlWakeLockQueue = + std::make_unique<::android::AidlMessageQueue>( + in_wakeLockDescriptor, true /* resetPointers */); + std::unique_ptr< + ::android::hardware::sensors::V2_1::implementation::WakeLockMessageQueueWrapperBase> + wakeLockQueue = std::make_unique(aidlWakeLockQueue); + + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(initializeCommon(eventQueue, wakeLockQueue, dynamicCallback))); +} + +::ndk::ScopedAStatus HalProxyAidl::injectSensorData( + const ::aidl::android::hardware::sensors::Event& in_event) { + ::android::hardware::sensors::V2_1::Event hidlEvent; + convertToHidlEvent(in_event, &hidlEvent); + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::injectSensorData(convertToOldEvent(hidlEvent)))); +} + +::ndk::ScopedAStatus HalProxyAidl::registerDirectChannel(const ISensors::SharedMemInfo& in_mem, + int32_t* _aidl_return) { + binder_status_t binderStatus; + ::android::hardware::sensors::V1_0::SharedMemInfo sharedMemInfo = convertSharedMemInfo(in_mem); + + HalProxy::registerDirectChannel( + sharedMemInfo, + [&binderStatus, _aidl_return](::android::hardware::sensors::V1_0::Result result, + int32_t reportToken) { + binderStatus = resultToBinderStatus(result); + *_aidl_return = reportToken; + }); + + native_handle_delete( + const_cast(sharedMemInfo.memoryHandle.getNativeHandle())); + return ndk::ScopedAStatus::fromStatus(binderStatus); +} + +::ndk::ScopedAStatus HalProxyAidl::setOperationMode( + ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) { + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::setOperationMode(convertOperationMode(in_mode)))); +} + +::ndk::ScopedAStatus HalProxyAidl::unregisterDirectChannel(int32_t in_channelHandle) { + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::unregisterDirectChannel(in_channelHandle))); +} + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/ConvertUtils.h b/sensors/aidl/default/multihal/include/ConvertUtils.h new file mode 100644 index 0000000000..09ec0dc144 --- /dev/null +++ b/sensors/aidl/default/multihal/include/ConvertUtils.h @@ -0,0 +1,422 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +static ::aidl::android::hardware::sensors::SensorInfo convertSensorInfo( + const ::android::hardware::sensors::V2_1::SensorInfo& sensorInfo) { + ::aidl::android::hardware::sensors::SensorInfo aidlSensorInfo; + aidlSensorInfo.sensorHandle = sensorInfo.sensorHandle; + aidlSensorInfo.name = sensorInfo.name; + aidlSensorInfo.vendor = sensorInfo.vendor; + aidlSensorInfo.version = sensorInfo.version; + aidlSensorInfo.type = (::aidl::android::hardware::sensors::SensorType)sensorInfo.type; + aidlSensorInfo.typeAsString = sensorInfo.typeAsString; + aidlSensorInfo.maxRange = sensorInfo.maxRange; + aidlSensorInfo.resolution = sensorInfo.resolution; + aidlSensorInfo.power = sensorInfo.power; + aidlSensorInfo.minDelayUs = sensorInfo.minDelay; + aidlSensorInfo.fifoReservedEventCount = sensorInfo.fifoReservedEventCount; + aidlSensorInfo.fifoMaxEventCount = sensorInfo.fifoMaxEventCount; + aidlSensorInfo.requiredPermission = sensorInfo.requiredPermission; + aidlSensorInfo.maxDelayUs = sensorInfo.maxDelay; + aidlSensorInfo.flags = sensorInfo.flags; + return aidlSensorInfo; +} + +static void convertToHidlEvent(const ::aidl::android::hardware::sensors::Event& aidlEvent, + ::android::hardware::sensors::V2_1::Event* hidlEvent) { + hidlEvent->timestamp = aidlEvent.timestamp; + hidlEvent->sensorHandle = aidlEvent.sensorHandle; + hidlEvent->sensorType = (::android::hardware::sensors::V2_1::SensorType)aidlEvent.sensorType; + + switch (aidlEvent.sensorType) { + case ::aidl::android::hardware::sensors::SensorType::META_DATA: + hidlEvent->u.meta.what = + (::android::hardware::sensors::V1_0::MetaDataEventType)aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::meta>() + .what; + break; + case ::aidl::android::hardware::sensors::SensorType::ACCELEROMETER: + case ::aidl::android::hardware::sensors::SensorType::MAGNETIC_FIELD: + case ::aidl::android::hardware::sensors::SensorType::ORIENTATION: + case ::aidl::android::hardware::sensors::SensorType::GYROSCOPE: + case ::aidl::android::hardware::sensors::SensorType::GRAVITY: + case ::aidl::android::hardware::sensors::SensorType::LINEAR_ACCELERATION: + hidlEvent->u.vec3.x = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::vec3>() + .x; + hidlEvent->u.vec3.y = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::vec3>() + .y; + hidlEvent->u.vec3.z = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::vec3>() + .z; + break; + case ::aidl::android::hardware::sensors::SensorType::GAME_ROTATION_VECTOR: + hidlEvent->u.vec4.x = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::vec4>() + .x; + hidlEvent->u.vec4.y = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::vec4>() + .y; + hidlEvent->u.vec4.z = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::vec4>() + .z; + hidlEvent->u.vec4.w = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::vec4>() + .w; + break; + case ::aidl::android::hardware::sensors::SensorType::ROTATION_VECTOR: + case ::aidl::android::hardware::sensors::SensorType::GEOMAGNETIC_ROTATION_VECTOR: + std::copy(aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::data>() + .values.data(), + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload:: + data>() + .values.data() + + 5, + hidlEvent->u.data.data()); + break; + case ::aidl::android::hardware::sensors::SensorType::ACCELEROMETER_UNCALIBRATED: + case ::aidl::android::hardware::sensors::SensorType::MAGNETIC_FIELD_UNCALIBRATED: + case ::aidl::android::hardware::sensors::SensorType::GYROSCOPE_UNCALIBRATED: + hidlEvent->u.uncal.x = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() + .x; + hidlEvent->u.uncal.y = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() + .y; + hidlEvent->u.uncal.z = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() + .z; + hidlEvent->u.uncal.x_bias = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() + .xBias; + hidlEvent->u.uncal.y_bias = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() + .yBias; + hidlEvent->u.uncal.z_bias = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() + .zBias; + break; + case ::aidl::android::hardware::sensors::SensorType::DEVICE_ORIENTATION: + case ::aidl::android::hardware::sensors::SensorType::LIGHT: + case ::aidl::android::hardware::sensors::SensorType::PRESSURE: + case ::aidl::android::hardware::sensors::SensorType::PROXIMITY: + case ::aidl::android::hardware::sensors::SensorType::RELATIVE_HUMIDITY: + case ::aidl::android::hardware::sensors::SensorType::AMBIENT_TEMPERATURE: + case ::aidl::android::hardware::sensors::SensorType::SIGNIFICANT_MOTION: + case ::aidl::android::hardware::sensors::SensorType::STEP_DETECTOR: + case ::aidl::android::hardware::sensors::SensorType::TILT_DETECTOR: + case ::aidl::android::hardware::sensors::SensorType::WAKE_GESTURE: + case ::aidl::android::hardware::sensors::SensorType::GLANCE_GESTURE: + case ::aidl::android::hardware::sensors::SensorType::PICK_UP_GESTURE: + case ::aidl::android::hardware::sensors::SensorType::WRIST_TILT_GESTURE: + case ::aidl::android::hardware::sensors::SensorType::STATIONARY_DETECT: + case ::aidl::android::hardware::sensors::SensorType::MOTION_DETECT: + case ::aidl::android::hardware::sensors::SensorType::HEART_BEAT: + case ::aidl::android::hardware::sensors::SensorType::LOW_LATENCY_OFFBODY_DETECT: + case ::aidl::android::hardware::sensors::SensorType::HINGE_ANGLE: + hidlEvent->u.scalar = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::scalar>(); + break; + case ::aidl::android::hardware::sensors::SensorType::STEP_COUNTER: + hidlEvent->u.stepCount = aidlEvent.payload.get< + ::aidl::android::hardware::sensors::Event::EventPayload::stepCount>(); + break; + case ::aidl::android::hardware::sensors::SensorType::HEART_RATE: + hidlEvent->u.heartRate.bpm = aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event:: + EventPayload::heartRate>() + .bpm; + hidlEvent->u.heartRate.status = + (::android::hardware::sensors::V1_0::SensorStatus)aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload:: + heartRate>() + .status; + break; + case ::aidl::android::hardware::sensors::SensorType::POSE_6DOF: + std::copy(std::begin(aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event:: + EventPayload::pose6DOF>() + .values), + std::end(aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event:: + EventPayload::data>() + .values), + hidlEvent->u.pose6DOF.data()); + break; + case ::aidl::android::hardware::sensors::SensorType::DYNAMIC_SENSOR_META: + hidlEvent->u.dynamic.connected = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::dynamic>() + .connected; + hidlEvent->u.dynamic.sensorHandle = + aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event::EventPayload::dynamic>() + .sensorHandle; + std::copy(std::begin(aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event:: + EventPayload::dynamic>() + .uuid.values), + std::end(aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event:: + EventPayload::dynamic>() + .uuid.values), + hidlEvent->u.dynamic.uuid.data()); + break; + case ::aidl::android::hardware::sensors::SensorType::ADDITIONAL_INFO: { + const AdditionalInfo& additionalInfo = aidlEvent.payload.get< + ::aidl::android::hardware::sensors::Event::EventPayload::additional>(); + hidlEvent->u.additional.type = + (::android::hardware::sensors::V1_0::AdditionalInfoType)additionalInfo.type; + hidlEvent->u.additional.serial = additionalInfo.serial; + + switch (additionalInfo.payload.getTag()) { + case ::aidl::android::hardware::sensors::AdditionalInfo::AdditionalInfoPayload:: + Tag::dataInt32: + std::copy( + std::begin(additionalInfo.payload + .get<::aidl::android::hardware::sensors:: + AdditionalInfo::AdditionalInfoPayload:: + dataInt32>() + .values), + std::end(additionalInfo.payload + .get<::aidl::android::hardware::sensors:: + AdditionalInfo::AdditionalInfoPayload:: + dataInt32>() + .values), + hidlEvent->u.additional.u.data_int32.data()); + break; + case ::aidl::android::hardware::sensors::AdditionalInfo::AdditionalInfoPayload:: + Tag::dataFloat: + std::copy( + std::begin(additionalInfo.payload + .get<::aidl::android::hardware::sensors:: + AdditionalInfo::AdditionalInfoPayload:: + dataFloat>() + .values), + std::end(additionalInfo.payload + .get<::aidl::android::hardware::sensors:: + AdditionalInfo::AdditionalInfoPayload:: + dataFloat>() + .values), + hidlEvent->u.additional.u.data_float.data()); + break; + default: + ALOGE("Invalid sensor additioanl info tag: %d", + additionalInfo.payload.getTag()); + break; + } + break; + } + default: + CHECK_GE((int32_t)aidlEvent.sensorType, + (int32_t)::aidl::android::hardware::sensors::SensorType::DEVICE_PRIVATE_BASE); + std::copy(std::begin(aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event:: + EventPayload::data>() + .values), + std::end(aidlEvent.payload + .get<::aidl::android::hardware::sensors::Event:: + EventPayload::data>() + .values), + hidlEvent->u.data.data()); + break; + } +} + +static void convertToAidlEvent(const ::android::hardware::sensors::V2_1::Event& hidlEvent, + ::aidl::android::hardware::sensors::Event* aidlEvent) { + aidlEvent->timestamp = hidlEvent.timestamp; + aidlEvent->sensorHandle = hidlEvent.sensorHandle; + aidlEvent->sensorType = (::aidl::android::hardware::sensors::SensorType)hidlEvent.sensorType; + switch (hidlEvent.sensorType) { + case ::android::hardware::sensors::V2_1::SensorType::META_DATA: { + ::aidl::android::hardware::sensors::Event::EventPayload::MetaData meta; + meta.what = (::aidl::android::hardware::sensors::Event::EventPayload::MetaData:: + MetaDataEventType)hidlEvent.u.meta.what; + aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::meta>( + meta); + break; + } + case ::android::hardware::sensors::V2_1::SensorType::ACCELEROMETER: + case ::android::hardware::sensors::V2_1::SensorType::MAGNETIC_FIELD: + case ::android::hardware::sensors::V2_1::SensorType::ORIENTATION: + case ::android::hardware::sensors::V2_1::SensorType::GYROSCOPE: + case ::android::hardware::sensors::V2_1::SensorType::GRAVITY: + case ::android::hardware::sensors::V2_1::SensorType::LINEAR_ACCELERATION: { + ::aidl::android::hardware::sensors::Event::EventPayload::Vec3 vec3; + vec3.x = hidlEvent.u.vec3.x; + vec3.y = hidlEvent.u.vec3.y; + vec3.z = hidlEvent.u.vec3.z; + aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::vec3>( + vec3); + break; + } + case ::android::hardware::sensors::V2_1::SensorType::GAME_ROTATION_VECTOR: { + ::aidl::android::hardware::sensors::Event::EventPayload::Vec4 vec4; + vec4.x = hidlEvent.u.vec4.x; + vec4.y = hidlEvent.u.vec4.y; + vec4.z = hidlEvent.u.vec4.z; + vec4.w = hidlEvent.u.vec4.w; + aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::vec4>( + vec4); + break; + } + case ::android::hardware::sensors::V2_1::SensorType::ROTATION_VECTOR: + case ::android::hardware::sensors::V2_1::SensorType::GEOMAGNETIC_ROTATION_VECTOR: { + ::aidl::android::hardware::sensors::Event::EventPayload::Data data; + std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + 5, + std::begin(data.values)); + aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::data>( + data); + break; + } + case ::android::hardware::sensors::V2_1::SensorType::MAGNETIC_FIELD_UNCALIBRATED: + case ::android::hardware::sensors::V2_1::SensorType::GYROSCOPE_UNCALIBRATED: + case ::android::hardware::sensors::V2_1::SensorType::ACCELEROMETER_UNCALIBRATED: { + ::aidl::android::hardware::sensors::Event::EventPayload::Uncal uncal; + uncal.x = hidlEvent.u.uncal.x; + uncal.y = hidlEvent.u.uncal.y; + uncal.z = hidlEvent.u.uncal.z; + uncal.xBias = hidlEvent.u.uncal.x_bias; + uncal.yBias = hidlEvent.u.uncal.y_bias; + uncal.zBias = hidlEvent.u.uncal.z_bias; + aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::uncal>( + uncal); + break; + } + case ::android::hardware::sensors::V2_1::SensorType::DEVICE_ORIENTATION: + case ::android::hardware::sensors::V2_1::SensorType::LIGHT: + case ::android::hardware::sensors::V2_1::SensorType::PRESSURE: + case ::android::hardware::sensors::V2_1::SensorType::PROXIMITY: + case ::android::hardware::sensors::V2_1::SensorType::RELATIVE_HUMIDITY: + case ::android::hardware::sensors::V2_1::SensorType::AMBIENT_TEMPERATURE: + case ::android::hardware::sensors::V2_1::SensorType::SIGNIFICANT_MOTION: + case ::android::hardware::sensors::V2_1::SensorType::STEP_DETECTOR: + case ::android::hardware::sensors::V2_1::SensorType::TILT_DETECTOR: + case ::android::hardware::sensors::V2_1::SensorType::WAKE_GESTURE: + case ::android::hardware::sensors::V2_1::SensorType::GLANCE_GESTURE: + case ::android::hardware::sensors::V2_1::SensorType::PICK_UP_GESTURE: + case ::android::hardware::sensors::V2_1::SensorType::WRIST_TILT_GESTURE: + case ::android::hardware::sensors::V2_1::SensorType::STATIONARY_DETECT: + case ::android::hardware::sensors::V2_1::SensorType::MOTION_DETECT: + case ::android::hardware::sensors::V2_1::SensorType::HEART_BEAT: + case ::android::hardware::sensors::V2_1::SensorType::LOW_LATENCY_OFFBODY_DETECT: + case ::android::hardware::sensors::V2_1::SensorType::HINGE_ANGLE: + aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::scalar>( + hidlEvent.u.scalar); + break; + case ::android::hardware::sensors::V2_1::SensorType::STEP_COUNTER: + aidlEvent->payload + .set<::aidl::android::hardware::sensors::Event::EventPayload::stepCount>( + hidlEvent.u.stepCount); + break; + case ::android::hardware::sensors::V2_1::SensorType::HEART_RATE: { + ::aidl::android::hardware::sensors::Event::EventPayload::HeartRate heartRate; + heartRate.bpm = hidlEvent.u.heartRate.bpm; + heartRate.status = + (::aidl::android::hardware::sensors::SensorStatus)hidlEvent.u.heartRate.status; + aidlEvent->payload + .set<::aidl::android::hardware::sensors::Event::EventPayload::heartRate>( + heartRate); + break; + } + case ::android::hardware::sensors::V2_1::SensorType::POSE_6DOF: { + ::aidl::android::hardware::sensors::Event::EventPayload::Pose6Dof pose6Dof; + std::copy(hidlEvent.u.pose6DOF.data(), + hidlEvent.u.pose6DOF.data() + hidlEvent.u.pose6DOF.size(), + std::begin(pose6Dof.values)); + aidlEvent->payload + .set<::aidl::android::hardware::sensors::Event::EventPayload::pose6DOF>( + pose6Dof); + break; + } + case ::android::hardware::sensors::V2_1::SensorType::DYNAMIC_SENSOR_META: { + ::aidl::android::hardware::sensors::DynamicSensorInfo dynamicSensorInfo; + dynamicSensorInfo.connected = hidlEvent.u.dynamic.connected; + dynamicSensorInfo.sensorHandle = hidlEvent.u.dynamic.sensorHandle; + std::copy(hidlEvent.u.dynamic.uuid.data(), + hidlEvent.u.dynamic.uuid.data() + hidlEvent.u.dynamic.uuid.size(), + std::begin(dynamicSensorInfo.uuid.values)); + aidlEvent->payload + .set<::aidl::android::hardware::sensors::Event::EventPayload::dynamic>( + dynamicSensorInfo); + break; + } + case ::android::hardware::sensors::V2_1::SensorType::ADDITIONAL_INFO: { + ::aidl::android::hardware::sensors::AdditionalInfo additionalInfo; + additionalInfo.type = + (::aidl::android::hardware::sensors::AdditionalInfo::AdditionalInfoType) + hidlEvent.u.additional.type; + additionalInfo.serial = hidlEvent.u.additional.serial; + + ::aidl::android::hardware::sensors::AdditionalInfo::AdditionalInfoPayload::Int32Values + int32Values; + std::copy(hidlEvent.u.additional.u.data_int32.data(), + hidlEvent.u.additional.u.data_int32.data() + + hidlEvent.u.additional.u.data_int32.size(), + std::begin(int32Values.values)); + additionalInfo.payload.set<::aidl::android::hardware::sensors::AdditionalInfo:: + AdditionalInfoPayload::dataInt32>(int32Values); + aidlEvent->payload + .set<::aidl::android::hardware::sensors::Event::EventPayload::additional>( + additionalInfo); + break; + } + default: { + CHECK_GE((int32_t)hidlEvent.sensorType, + (int32_t)::android::hardware::sensors::V2_1::SensorType::DEVICE_PRIVATE_BASE); + ::aidl::android::hardware::sensors::Event::EventPayload::Data data; + std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + hidlEvent.u.data.size(), + std::begin(data.values)); + aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::data>( + data); + break; + } + } +} + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h b/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h new file mode 100644 index 0000000000..3eaa1d4335 --- /dev/null +++ b/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include "ConvertUtils.h" +#include "EventMessageQueueWrapper.h" +#include "ISensorsWrapper.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +class EventMessageQueueWrapperAidl + : public ::android::hardware::sensors::V2_1::implementation::EventMessageQueueWrapperBase { + public: + EventMessageQueueWrapperAidl( + std::unique_ptr<::android::AidlMessageQueue< + ::aidl::android::hardware::sensors::Event, + ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue) + : mQueue(std::move(queue)) {} + + virtual std::atomic* getEventFlagWord() override { + return mQueue->getEventFlagWord(); + } + + virtual size_t availableToRead() override { return mQueue->availableToRead(); } + + size_t availableToWrite() override { return mQueue->availableToWrite(); } + + virtual bool read(::android::hardware::sensors::V2_1::Event* events, + size_t numToRead) override { + bool success = mQueue->read(mIntermediateEventBuffer.data(), numToRead); + for (int i = 0; i < numToRead; ++i) { + convertToHidlEvent(mIntermediateEventBuffer[i], &events[i]); + } + return success; + } + + bool write(const ::android::hardware::sensors::V2_1::Event* events, + size_t numToWrite) override { + for (int i = 0; i < numToWrite; ++i) { + convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); + } + return mQueue->write(mIntermediateEventBuffer.data(), numToWrite); + } + + virtual bool write( + const std::vector<::android::hardware::sensors::V2_1::Event>& events) override { + for (int i = 0; i < events.size(); ++i) { + convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); + } + return mQueue->write(mIntermediateEventBuffer.data(), events.size()); + } + + bool writeBlocking(const ::android::hardware::sensors::V2_1::Event* events, size_t count, + uint32_t readNotification, uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag) override { + for (int i = 0; i < count; ++i) { + convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); + } + return mQueue->writeBlocking(mIntermediateEventBuffer.data(), count, readNotification, + writeNotification, timeOutNanos, evFlag); + } + + size_t getQuantumCount() override { return mQueue->getQuantumCount(); } + + private: + std::unique_ptr<::android::AidlMessageQueue< + ::aidl::android::hardware::sensors::Event, + ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>> + mQueue; + std::array<::aidl::android::hardware::sensors::Event, + ::android::hardware::sensors::V2_1::implementation::MAX_RECEIVE_BUFFER_EVENT_COUNT> + mIntermediateEventBuffer; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/default/multihal/include/HalProxyAidl.h b/sensors/aidl/default/multihal/include/HalProxyAidl.h new file mode 100644 index 0000000000..7401726cf9 --- /dev/null +++ b/sensors/aidl/default/multihal/include/HalProxyAidl.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "HalProxy.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +class HalProxyAidl : public ::android::hardware::sensors::V2_1::implementation::HalProxy, + public ::aidl::android::hardware::sensors::BnSensors { + ::ndk::ScopedAStatus activate(int32_t in_sensorHandle, bool in_enabled) override; + ::ndk::ScopedAStatus batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs, + int64_t in_maxReportLatencyNs) override; + ::ndk::ScopedAStatus configDirectReport( + int32_t in_sensorHandle, int32_t in_channelHandle, + ::aidl::android::hardware::sensors::ISensors::RateLevel in_rate, + int32_t* _aidl_return) override; + ::ndk::ScopedAStatus flush(int32_t in_sensorHandle) override; + ::ndk::ScopedAStatus getSensorsList( + std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) override; + ::ndk::ScopedAStatus initialize( + const ::aidl::android::hardware::common::fmq::MQDescriptor< + ::aidl::android::hardware::sensors::Event, + ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& + in_eventQueueDescriptor, + const ::aidl::android::hardware::common::fmq::MQDescriptor< + int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& + in_wakeLockDescriptor, + const std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback>& + in_sensorsCallback) override; + ::ndk::ScopedAStatus injectSensorData( + const ::aidl::android::hardware::sensors::Event& in_event) override; + ::ndk::ScopedAStatus registerDirectChannel( + const ::aidl::android::hardware::sensors::ISensors::SharedMemInfo& in_mem, + int32_t* _aidl_return) override; + ::ndk::ScopedAStatus setOperationMode( + ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) override; + ::ndk::ScopedAStatus unregisterDirectChannel(int32_t in_channelHandle) override; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h b/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h new file mode 100644 index 0000000000..6ef6c6398d --- /dev/null +++ b/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "ConvertUtils.h" +#include "ISensorsCallbackWrapper.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +static std::vector<::aidl::android::hardware::sensors::SensorInfo> convertToAidlSensorInfos( + const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>& + sensorInfos) { + std::vector<::aidl::android::hardware::sensors::SensorInfo> aidlSensorInfos; + for (const auto& sensorInfo : sensorInfos) { + aidlSensorInfos.push_back(convertSensorInfo(sensorInfo)); + } + return aidlSensorInfos; +} + +class ISensorsCallbackWrapperAidl + : public ::android::hardware::sensors::V2_1::implementation::ISensorsCallbackWrapperBase { + public: + ISensorsCallbackWrapperAidl( + std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> sensorsCallback) + : mSensorsCallback(sensorsCallback) {} + + ::android::hardware::Return onDynamicSensorsConnected( + const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>& + sensorInfos) override { + mSensorsCallback->onDynamicSensorsConnected(convertToAidlSensorInfos(sensorInfos)); + return ::android::hardware::Void(); + } + + ::android::hardware::Return onDynamicSensorsDisconnected( + const ::android::hardware::hidl_vec& sensorHandles) override { + mSensorsCallback->onDynamicSensorsDisconnected(sensorHandles); + return ::android::hardware::Void(); + } + + private: + std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> mSensorsCallback; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h b/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h new file mode 100644 index 0000000000..6be0b69aa3 --- /dev/null +++ b/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include "WakeLockMessageQueueWrapper.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +class WakeLockMessageQueueWrapperAidl + : public ::android::hardware::sensors::V2_1::implementation::WakeLockMessageQueueWrapperBase { + public: + WakeLockMessageQueueWrapperAidl( + std::unique_ptr<::android::AidlMessageQueue< + int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue) + : mQueue(std::move(queue)) {} + + virtual std::atomic* getEventFlagWord() override { + return mQueue->getEventFlagWord(); + } + + bool readBlocking(uint32_t* wakeLocks, size_t numToRead, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag) override { + return mQueue->readBlocking(reinterpret_cast(wakeLocks), numToRead, + readNotification, writeNotification, timeOutNanos, evFlag); + } + + bool write(const uint32_t* wakeLock) override { + return mQueue->write(reinterpret_cast(wakeLock)); + } + + private: + std::unique_ptr<::android::AidlMessageQueue< + int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>> + mQueue; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/multihal/Android.bp b/sensors/aidl/multihal/Android.bp new file mode 100644 index 0000000000..6d35dafd6d --- /dev/null +++ b/sensors/aidl/multihal/Android.bp @@ -0,0 +1,59 @@ +// +// Copyright (C) 2021 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_binary { + name: "android.hardware.sensors-service.multihal", + vendor: true, + relative_install_path: "hw", + srcs: [ + "service.cpp", + ], + header_libs: [ + "android.hardware.sensors@2.X-multihal.header", + "android.hardware.sensors@2.X-shared-utils", + ], + init_rc: ["android.hardware.sensors-service-multihal.rc"], + vintf_fragments: ["android.hardware.sensors-multihal.xml"], + shared_libs: [ + "android.hardware.sensors@2.0-ScopedWakelock", + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "android.hardware.sensors-V1-ndk", + "libbase", + "libcutils", + "libfmq", + "liblog", + "libpower", + "libutils", + "libbinder_ndk", + "libhidlbase", + ], + static_libs: [ + "libaidlcommonsupport", + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-multihal", + "android.hardware.sensors@aidl-multihal", + ], +} diff --git a/sensors/aidl/multihal/OWNERS b/sensors/aidl/multihal/OWNERS new file mode 100644 index 0000000000..e9556700d6 --- /dev/null +++ b/sensors/aidl/multihal/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com \ No newline at end of file diff --git a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml new file mode 100644 index 0000000000..d78edffaf9 --- /dev/null +++ b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml @@ -0,0 +1,23 @@ + + + + + android.hardware.sensors + 1 + ISensors/default + + diff --git a/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc new file mode 100644 index 0000000000..3f91a0a04a --- /dev/null +++ b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc @@ -0,0 +1,7 @@ +service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.multihal + class hal + user system + group system wakelock context_hub + task_profiles ServiceCapacityLow + capabilities BLOCK_SUSPEND + rlimit rtprio 10 10 \ No newline at end of file diff --git a/sensors/aidl/multihal/service.cpp b/sensors/aidl/multihal/service.cpp new file mode 100644 index 0000000000..11c108a395 --- /dev/null +++ b/sensors/aidl/multihal/service.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 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 +#include +#include +#include "HalProxyAidl.h" + +using ::aidl::android::hardware::sensors::implementation::HalProxyAidl; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + + // Make a default multihal sensors service + auto halProxy = ndk::SharedRefBase::make(); + const std::string halProxyName = std::string() + HalProxyAidl::descriptor + "/default"; + binder_status_t status = + AServiceManager_addService(halProxy->asBinder().get(), halProxyName.c_str()); + CHECK_EQ(status, STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp index f5fc066820..73b0594f06 100644 --- a/sensors/common/default/2.X/multihal/HalProxy.cpp +++ b/sensors/common/default/2.X/multihal/HalProxy.cpp @@ -176,7 +176,13 @@ Return HalProxy::initialize_2_1( std::unique_ptr queue = std::make_unique(eventQueue); - return initializeCommon(queue, wakeLockDescriptor, dynamicCallback); + // Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions. + auto hidlWakeLockQueue = + std::make_unique(wakeLockDescriptor, true /* resetPointers */); + std::unique_ptr wakeLockQueue = + std::make_unique(hidlWakeLockQueue); + + return initializeCommon(queue, wakeLockQueue, dynamicCallback); } Return HalProxy::initialize( @@ -192,12 +198,18 @@ Return HalProxy::initialize( std::unique_ptr queue = std::make_unique(eventQueue); - return initializeCommon(queue, wakeLockDescriptor, dynamicCallback); + // Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions. + auto hidlWakeLockQueue = + std::make_unique(wakeLockDescriptor, true /* resetPointers */); + std::unique_ptr wakeLockQueue = + std::make_unique(hidlWakeLockQueue); + + return initializeCommon(queue, wakeLockQueue, dynamicCallback); } Return HalProxy::initializeCommon( std::unique_ptr& eventQueue, - const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + std::unique_ptr& wakeLockQueue, const sp& sensorsCallback) { Result result = Result::OK; @@ -222,8 +234,7 @@ Return HalProxy::initializeCommon( // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP // events have been successfully read and handled by the framework. - mWakeLockQueue = - std::make_unique(wakeLockDescriptor, true /* resetPointers */); + mWakeLockQueue = std::move(wakeLockQueue); if (mEventQueueFlag != nullptr) { EventFlag::deleteEventFlag(&mEventQueueFlag); diff --git a/sensors/common/default/2.X/multihal/include/HalProxy.h b/sensors/common/default/2.X/multihal/include/HalProxy.h index 35d7c8bae1..61745281f8 100644 --- a/sensors/common/default/2.X/multihal/include/HalProxy.h +++ b/sensors/common/default/2.X/multihal/include/HalProxy.h @@ -23,6 +23,7 @@ #include "V2_0/ScopedWakelock.h" #include "V2_0/SubHal.h" #include "V2_1/SubHal.h" +#include "WakeLockMessageQueueWrapper.h" #include "convertV2_1.h" #include @@ -98,10 +99,9 @@ class HalProxy : public V2_0::implementation::IScopedWakelockRefCounter, const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, const sp& sensorsCallback); - Return initializeCommon( - std::unique_ptr& eventQueue, - const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, - const sp& sensorsCallback); + Return initializeCommon(std::unique_ptr& eventQueue, + std::unique_ptr& wakeLockQueue, + const sp& sensorsCallback); Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, int64_t maxReportLatencyNs); @@ -141,6 +141,8 @@ class HalProxy : public V2_0::implementation::IScopedWakelockRefCounter, void decrementRefCountAndMaybeReleaseWakelock(size_t delta, int64_t timeoutStart = -1) override; + const std::map& getSensors() { return mSensors; } + private: using EventMessageQueueV2_1 = MessageQueue; using EventMessageQueueV2_0 = MessageQueue; @@ -154,7 +156,7 @@ class HalProxy : public V2_0::implementation::IScopedWakelockRefCounter, /** * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events */ - std::unique_ptr mWakeLockQueue; + std::unique_ptr mWakeLockQueue; /** * Event Flag to signal to the framework when sensor events are available to be read and to diff --git a/sensors/common/utils/WakeLockMessageQueueWrapper.h b/sensors/common/utils/WakeLockMessageQueueWrapper.h new file mode 100644 index 0000000000..3a219cffbe --- /dev/null +++ b/sensors/common/utils/WakeLockMessageQueueWrapper.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "convertV2_1.h" + +#include +#include +#include +#include +#include + +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace implementation { + +class WakeLockMessageQueueWrapperBase { + public: + virtual ~WakeLockMessageQueueWrapperBase() {} + + virtual std::atomic* getEventFlagWord() = 0; + virtual bool readBlocking(uint32_t* events, size_t numToRead, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag = nullptr) = 0; + virtual bool write(const uint32_t* wakeLock) = 0; +}; + +class WakeLockMessageQueueWrapperHidl : public WakeLockMessageQueueWrapperBase { + public: + WakeLockMessageQueueWrapperHidl( + std::unique_ptr<::android::hardware::MessageQueue>& + queue) + : mQueue(std::move(queue)) {} + + std::atomic* getEventFlagWord() override { return mQueue->getEventFlagWord(); } + + bool readBlocking(uint32_t* wakeLocks, size_t numToRead, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag) override { + return mQueue->readBlocking(wakeLocks, numToRead, readNotification, writeNotification, + timeOutNanos, evFlag); + } + + bool write(const uint32_t* wakeLock) override { return mQueue->write(wakeLock); } + + private: + std::unique_ptr<::android::hardware::MessageQueue> mQueue; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android -- cgit v1.2.3 From cc7409e8f9e95e41590c020e6a56478ac0c7ed85 Mon Sep 17 00:00:00 2001 From: Gabriel Biren Date: Wed, 12 Jan 2022 00:46:38 +0000 Subject: Allow VTS tests to pass on devices without Supplicant AIDL. Bug: 212653303 Bug: 212652735 Bug: 212652340 Test: Run VTS tests on an AOSP build (since AOSP is still using the HIDL interface). Change-Id: I442efb35c4c68a1337cacc952c3fdb338ef2615d --- wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp | 1 + wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp | 1 + wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp index 2f4f06d355..d9d8179626 100644 --- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp +++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp @@ -620,6 +620,7 @@ TEST_P(SupplicantP2pIfaceAidlTest, AddAndRemoveUpnpService) { p2p_iface_->removeUpnpService(0 /* version */, upnpServiceName).isOk()); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceAidlTest); INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantP2pIfaceAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames( ISupplicant::descriptor)), diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp index f51c07f1ad..6e6955fd75 100644 --- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp +++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp @@ -769,6 +769,7 @@ TEST_P(SupplicantStaIfaceAidlTest, StartDppConfiguratorInitiator) { EXPECT_TRUE(sta_iface_->removeDppUri(peer_id).isOk()); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceAidlTest); INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaIfaceAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames( ISupplicant::descriptor)), diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp index 66c88073cc..3d8242b2b9 100644 --- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp +++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp @@ -778,6 +778,7 @@ TEST_P(SupplicantStaNetworkAidlTest, GetWpsNfcConfigurationToken) { EXPECT_NE(retrievedToken.size(), 0); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest); INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames( ISupplicant::descriptor)), -- cgit v1.2.3 From d72ba14c90511a7be5a130c54e6bbdec282f5c8e Mon Sep 17 00:00:00 2001 From: Brian Duddie Date: Fri, 10 Dec 2021 14:24:09 -0800 Subject: Add HEAD_TRACKER sensor type definition This new sensor type supports tracking the orientation and rate of rotation of a user's head, which can be useful for features such as spatial audio. Bug: 210156629 Test: compile only; to be validated in later CLs Change-Id: I861be09d14e208fb992b23554b6c0733e4163f0c --- sensors/aidl/Android.bp | 2 - .../current/android/hardware/sensors/Event.aidl | 11 ++++++ .../android/hardware/sensors/SensorType.aidl | 1 + sensors/aidl/android/hardware/sensors/Event.aidl | 45 ++++++++++++++++++++++ .../aidl/android/hardware/sensors/SensorType.aidl | 33 ++++++++++++++++ 5 files changed, 90 insertions(+), 2 deletions(-) diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp index fd1ac441e2..7324abf50d 100644 --- a/sensors/aidl/Android.bp +++ b/sensors/aidl/Android.bp @@ -1,5 +1,3 @@ -// This is the expected build file, but it may not be right in all cases - aidl_interface { name: "android.hardware.sensors", vendor_available: true, diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl index 186b2be8b3..c92ab1ab0c 100644 --- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl +++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl @@ -51,6 +51,7 @@ parcelable Event { android.hardware.sensors.DynamicSensorInfo dynamic; android.hardware.sensors.AdditionalInfo additional; android.hardware.sensors.Event.EventPayload.Data data; + android.hardware.sensors.Event.EventPayload.HeadTracker headTracker; @FixedSize @VintfStability parcelable Vec4 { float x; @@ -75,6 +76,16 @@ parcelable Event { float zBias; } @FixedSize @VintfStability + parcelable HeadTracker { + float rx; + float ry; + float rz; + float vx; + float vy; + float vz; + int discontinuityCount; + } + @FixedSize @VintfStability parcelable HeartRate { float bpm; android.hardware.sensors.SensorStatus status; diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl index 4f3b5b2e79..3d7ab45cd8 100644 --- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl +++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl @@ -70,5 +70,6 @@ enum SensorType { LOW_LATENCY_OFFBODY_DETECT = 34, ACCELEROMETER_UNCALIBRATED = 35, HINGE_ANGLE = 36, + HEAD_TRACKER = 37, DEVICE_PRIVATE_BASE = 65536, } diff --git a/sensors/aidl/android/hardware/sensors/Event.aidl b/sensors/aidl/android/hardware/sensors/Event.aidl index 6ef9acbbda..fd6a8cc4ba 100644 --- a/sensors/aidl/android/hardware/sensors/Event.aidl +++ b/sensors/aidl/android/hardware/sensors/Event.aidl @@ -127,6 +127,11 @@ parcelable Event { */ Data data; + /** + * SensorType::HEAD_TRACKER + */ + HeadTracker headTracker; + @FixedSize @VintfStability parcelable Vec4 { @@ -156,6 +161,46 @@ parcelable Event { float zBias; } + /** + * Payload of the HEAD_TRACKER sensor type. Note that the axis + * definition of this sensor type differs from the rest of Android. See + * SensorType::HEAD_TRACKER for more information. + */ + @FixedSize + @VintfStability + parcelable HeadTracker { + /** + * An Euler vector (rotation vector, i.e. a vector whose direction + * indicates the axis of rotation and magnitude indicates the angle + * to rotate around that axis) representing the transform from + * the (arbitrary, possibly slowly drifting) reference frame to the + * head frame. Expressed in radians. Magnitude of the vector must be + * in the range [0, pi], while the value of individual axes are + * in the range [-pi, pi]. + */ + float rx; + float ry; + float rz; + + /** + * An Euler vector (rotation vector) representing the angular + * velocity of the head (relative to itself), in radians per second. + * The direction of this vector indicates the axis of rotation, and + * the magnitude indicates the rate of rotation. + */ + float vx; + float vy; + float vz; + + /** + * This value increments (or wraps around to 0) each time the + * reference frame is suddenly and significantly changed, for + * example if an orientation filter algorithm used for determining + * the orientation has had its state reset. + */ + int discontinuityCount; + } + @FixedSize @VintfStability parcelable HeartRate { diff --git a/sensors/aidl/android/hardware/sensors/SensorType.aidl b/sensors/aidl/android/hardware/sensors/SensorType.aidl index 95c7a6a2ad..01e6bee1d5 100644 --- a/sensors/aidl/android/hardware/sensors/SensorType.aidl +++ b/sensors/aidl/android/hardware/sensors/SensorType.aidl @@ -142,6 +142,10 @@ enum SensorType { * The rotation vector symbolizes the orientation of the device relative to * the East-North-Up coordinates frame. * + * Note that despite the name, SensorType::ROTATION_VECTOR uses + * quaternion representation, rather than the rotation vector representation + * (aka Euler vector) seen in SensorType::HEAD_TRACKER. + * * Implement the non-wake-up version of this sensor and implement the * wake-up version if the system possesses a wake up fifo. */ @@ -633,6 +637,35 @@ enum SensorType { */ HINGE_ANGLE = 36, + /** + * HEAD_TRACKER + * reporting-mode: continuous + * + * A sensor of this type measures the orientation of a user's head relative + * to an arbitrary reference frame, and the rate of rotation. + * + * Events produced by this sensor follow a special head-centric coordinate + * frame, where: + * - The X axis crosses through the user's ears, with the positive X + * direction extending out of the user's right ear + * - The Y axis crosses from the back of the user's head through their + * nose, with the positive direction extending out of the nose, and the + * X/Y plane being nominally parallel to the ground when the user is + * upright and looking straight ahead + * - The Z axis crosses from the neck through the top of the user's head, + * with the positive direction extending out from the top of the head + * + * When this sensor type is exposed as a dynamic sensor through a + * communications channel that uses HID, such as Bluetooth or USB, as part + * of a device with audio output capability (e.g. headphones), then the + * DynamicSensorInfo::uuid field shall be set to contents of the HID + * Persistent Unique ID to permit association between the sensor and audio + * device. Accordingly, the HID Persistent Unique ID (Sensors Page 0x20, + * Usage ID 0x302) must be populated as a UUID in binary representation, + * following RFC 4122 byte order. + */ + HEAD_TRACKER = 37, + /** * Base for device manufacturers private sensor types. * These sensor types can't be exposed in the SDK. -- cgit v1.2.3 From 534556391ae153b1e8fdd11b233e2dc6ecd1e530 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Mon, 25 Oct 2021 11:20:33 -0700 Subject: Create NN AIDL adapter This change adds the following adapters: * nn::IDevice -> BnDevice * nn::IPreparedModel -> BnPreparedModel * nn::IBurst -> BnBurst * nn::IBuffer -> BnBuffer Bug: N/A Test: mma Test: locally created a binderized service with this adapter code, which passed VtsHalNeuralnetworksTargetTest Change-Id: I966f65a1e4d75284c050b77f3f40c515e4970130 --- .../utils/include/nnapi/hal/aidl/Conversions.h | 12 +- neuralnetworks/aidl/utils/src/Conversions.cpp | 173 +++++-- neuralnetworks/utils/adapter/Android.bp | 46 -- neuralnetworks/utils/adapter/aidl/Android.bp | 42 ++ .../adapter/aidl/include/nnapi/hal/aidl/Adapter.h | 73 +++ .../adapter/aidl/include/nnapi/hal/aidl/Buffer.h | 47 ++ .../adapter/aidl/include/nnapi/hal/aidl/Burst.h | 72 +++ .../adapter/aidl/include/nnapi/hal/aidl/Device.h | 83 +++ .../aidl/include/nnapi/hal/aidl/PreparedModel.h | 62 +++ neuralnetworks/utils/adapter/aidl/src/Adapter.cpp | 46 ++ neuralnetworks/utils/adapter/aidl/src/Buffer.cpp | 88 ++++ neuralnetworks/utils/adapter/aidl/src/Burst.cpp | 179 +++++++ neuralnetworks/utils/adapter/aidl/src/Device.cpp | 304 +++++++++++ .../utils/adapter/aidl/src/PreparedModel.cpp | 225 +++++++++ neuralnetworks/utils/adapter/hidl/Android.bp | 46 ++ .../utils/adapter/hidl/include/nnapi/hal/Adapter.h | 72 +++ .../utils/adapter/hidl/include/nnapi/hal/Buffer.h | 46 ++ .../utils/adapter/hidl/include/nnapi/hal/Burst.h | 155 ++++++ .../utils/adapter/hidl/include/nnapi/hal/Device.h | 96 ++++ .../adapter/hidl/include/nnapi/hal/PreparedModel.h | 79 +++ neuralnetworks/utils/adapter/hidl/src/Adapter.cpp | 46 ++ neuralnetworks/utils/adapter/hidl/src/Buffer.cpp | 83 +++ neuralnetworks/utils/adapter/hidl/src/Burst.cpp | 259 ++++++++++ neuralnetworks/utils/adapter/hidl/src/Device.cpp | 556 +++++++++++++++++++++ .../utils/adapter/hidl/src/PreparedModel.cpp | 436 ++++++++++++++++ .../utils/adapter/include/nnapi/hal/Adapter.h | 72 --- .../utils/adapter/include/nnapi/hal/Buffer.h | 46 -- .../utils/adapter/include/nnapi/hal/Burst.h | 155 ------ .../utils/adapter/include/nnapi/hal/Device.h | 96 ---- .../adapter/include/nnapi/hal/PreparedModel.h | 79 --- neuralnetworks/utils/adapter/src/Adapter.cpp | 46 -- neuralnetworks/utils/adapter/src/Buffer.cpp | 83 --- neuralnetworks/utils/adapter/src/Burst.cpp | 259 ---------- neuralnetworks/utils/adapter/src/Device.cpp | 556 --------------------- neuralnetworks/utils/adapter/src/PreparedModel.cpp | 436 ---------------- 35 files changed, 3234 insertions(+), 1920 deletions(-) delete mode 100644 neuralnetworks/utils/adapter/Android.bp create mode 100644 neuralnetworks/utils/adapter/aidl/Android.bp create mode 100644 neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h create mode 100644 neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h create mode 100644 neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h create mode 100644 neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h create mode 100644 neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h create mode 100644 neuralnetworks/utils/adapter/aidl/src/Adapter.cpp create mode 100644 neuralnetworks/utils/adapter/aidl/src/Buffer.cpp create mode 100644 neuralnetworks/utils/adapter/aidl/src/Burst.cpp create mode 100644 neuralnetworks/utils/adapter/aidl/src/Device.cpp create mode 100644 neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp create mode 100644 neuralnetworks/utils/adapter/hidl/Android.bp create mode 100644 neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h create mode 100644 neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h create mode 100644 neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h create mode 100644 neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h create mode 100644 neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h create mode 100644 neuralnetworks/utils/adapter/hidl/src/Adapter.cpp create mode 100644 neuralnetworks/utils/adapter/hidl/src/Buffer.cpp create mode 100644 neuralnetworks/utils/adapter/hidl/src/Burst.cpp create mode 100644 neuralnetworks/utils/adapter/hidl/src/Device.cpp create mode 100644 neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp delete mode 100644 neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h delete mode 100644 neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h delete mode 100644 neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h delete mode 100644 neuralnetworks/utils/adapter/include/nnapi/hal/Device.h delete mode 100644 neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h delete mode 100644 neuralnetworks/utils/adapter/src/Adapter.cpp delete mode 100644 neuralnetworks/utils/adapter/src/Buffer.cpp delete mode 100644 neuralnetworks/utils/adapter/src/Burst.cpp delete mode 100644 neuralnetworks/utils/adapter/src/Device.cpp delete mode 100644 neuralnetworks/utils/adapter/src/PreparedModel.cpp diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h index 78433a74e9..477b311598 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h @@ -112,11 +112,15 @@ GeneralResult convert(const aidl_hal::Priority& priority); GeneralResult convert(const aidl_hal::Request& request); GeneralResult convert(const aidl_hal::Timing& timing); GeneralResult convert(const ndk::ScopedFileDescriptor& handle); +GeneralResult convert(const aidl_hal::BufferDesc& bufferDesc); GeneralResult> convert(const std::vector& extension); GeneralResult> convert(const std::vector& memories); GeneralResult> convert( const std::vector& outputShapes); +GeneralResult> convert( + const std::vector& handles); +GeneralResult> convert(const std::vector& roles); GeneralResult> toUnsigned(const std::vector& vec); @@ -129,6 +133,7 @@ namespace nn = ::android::nn; nn::GeneralResult> unvalidatedConvert(const nn::CacheToken& cacheToken); nn::GeneralResult unvalidatedConvert(const nn::BufferDesc& bufferDesc); nn::GeneralResult unvalidatedConvert(const nn::BufferRole& bufferRole); +nn::GeneralResult unvalidatedConvert(const nn::DeviceType& deviceType); nn::GeneralResult unvalidatedConvert(const nn::MeasureTiming& measureTiming); nn::GeneralResult unvalidatedConvert(const nn::SharedMemory& memory); nn::GeneralResult unvalidatedConvert(const nn::OutputShape& outputShape); @@ -154,14 +159,16 @@ nn::GeneralResult unvalidatedConvert(const nn::Request& request); nn::GeneralResult unvalidatedConvert(const nn::Request::Argument& requestArgument); nn::GeneralResult unvalidatedConvert(const nn::Request::MemoryPool& memoryPool); nn::GeneralResult unvalidatedConvert(const nn::Timing& timing); -nn::GeneralResult unvalidatedConvert(const nn::Duration& duration); nn::GeneralResult unvalidatedConvert(const nn::OptionalDuration& optionalDuration); nn::GeneralResult unvalidatedConvert(const nn::OptionalTimePoint& optionalTimePoint); nn::GeneralResult unvalidatedConvert(const nn::SyncFence& syncFence); nn::GeneralResult unvalidatedConvert(const nn::SharedHandle& handle); +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities); +nn::GeneralResult unvalidatedConvert(const nn::Extension& extension); nn::GeneralResult> convert(const nn::CacheToken& cacheToken); nn::GeneralResult convert(const nn::BufferDesc& bufferDesc); +nn::GeneralResult convert(const nn::DeviceType& deviceType); nn::GeneralResult convert(const nn::MeasureTiming& measureTiming); nn::GeneralResult convert(const nn::SharedMemory& memory); nn::GeneralResult convert(const nn::ErrorStatus& errorStatus); @@ -172,6 +179,8 @@ nn::GeneralResult convert(const nn::Request& request); nn::GeneralResult convert(const nn::Timing& timing); nn::GeneralResult convert(const nn::OptionalDuration& optionalDuration); nn::GeneralResult convert(const nn::OptionalTimePoint& optionalTimePoint); +nn::GeneralResult convert(const nn::Capabilities& capabilities); +nn::GeneralResult convert(const nn::Extension& extension); nn::GeneralResult> convert(const std::vector& bufferRoles); nn::GeneralResult> convert( @@ -180,6 +189,7 @@ nn::GeneralResult> convert( const std::vector& handles); nn::GeneralResult> convert( const std::vector& syncFences); +nn::GeneralResult> convert(const std::vector& extensions); nn::GeneralResult> toSigned(const std::vector& vec); diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp index 45628c8e73..113d2da955 100644 --- a/neuralnetworks/aidl/utils/src/Conversions.cpp +++ b/neuralnetworks/aidl/utils/src/Conversions.cpp @@ -551,6 +551,10 @@ GeneralResult convert(const ndk::ScopedFileDescriptor& handle) { return validatedConvert(handle); } +GeneralResult convert(const aidl_hal::BufferDesc& bufferDesc) { + return validatedConvert(bufferDesc); +} + GeneralResult> convert(const std::vector& extension) { return validatedConvert(extension); } @@ -564,6 +568,15 @@ GeneralResult> convert( return validatedConvert(outputShapes); } +GeneralResult> convert( + const std::vector& handles) { + return validatedConvert(handles); +} + +GeneralResult> convert(const std::vector& roles) { + return validatedConvert(roles); +} + GeneralResult> toUnsigned(const std::vector& vec) { if (!std::all_of(vec.begin(), vec.end(), [](int32_t v) { return v >= 0; })) { return NN_ERROR() << "Negative value passed to conversion from signed to unsigned"; @@ -576,42 +589,7 @@ GeneralResult> toUnsigned(const std::vector& vec) namespace aidl::android::hardware::neuralnetworks::utils { namespace { -template -using UnvalidatedConvertOutput = - std::decay_t()).value())>; - -template -nn::GeneralResult>> unvalidatedConvertVec( - const std::vector& arguments) { - std::vector> halObject; - halObject.reserve(arguments.size()); - for (const auto& argument : arguments) { - halObject.push_back(NN_TRY(unvalidatedConvert(argument))); - } - return halObject; -} - -template -nn::GeneralResult>> unvalidatedConvert( - const std::vector& arguments) { - return unvalidatedConvertVec(arguments); -} - -template -nn::GeneralResult> validatedConvert(const Type& canonical) { - NN_TRY(compliantVersion(canonical)); - return utils::unvalidatedConvert(canonical); -} - -template -nn::GeneralResult>> validatedConvert( - const std::vector& arguments) { - std::vector> halObject(arguments.size()); - for (size_t i = 0; i < arguments.size(); ++i) { - halObject[i] = NN_TRY(validatedConvert(arguments[i])); - } - return halObject; -} +using utils::unvalidatedConvert; // Helper template for std::visit template @@ -721,6 +699,74 @@ nn::GeneralResult unvalidatedConvert(const nn::Memory::Unknown& /*memory operator nn::GeneralResult(); } +nn::GeneralResult unvalidatedConvert( + const nn::Capabilities::PerformanceInfo& info) { + return PerformanceInfo{.execTime = info.execTime, .powerUsage = info.powerUsage}; +} + +nn::GeneralResult unvalidatedConvert( + const nn::Capabilities::OperandPerformance& operandPerformance) { + return OperandPerformance{.type = NN_TRY(unvalidatedConvert(operandPerformance.type)), + .info = NN_TRY(unvalidatedConvert(operandPerformance.info))}; +} + +nn::GeneralResult> unvalidatedConvert( + const nn::Capabilities::OperandPerformanceTable& table) { + std::vector operandPerformances; + operandPerformances.reserve(table.asVector().size()); + for (const auto& operandPerformance : table.asVector()) { + operandPerformances.push_back(NN_TRY(unvalidatedConvert(operandPerformance))); + } + return operandPerformances; +} + +nn::GeneralResult unvalidatedConvert( + const nn::Extension::OperandTypeInformation& info) { + return ExtensionOperandTypeInformation{.type = info.type, + .isTensor = info.isTensor, + .byteSize = static_cast(info.byteSize)}; +} + +nn::GeneralResult unvalidatedConvert(const nn::Duration& duration) { + if (duration < nn::Duration::zero()) { + return NN_ERROR() << "Unable to convert invalid (negative) duration"; + } + constexpr std::chrono::nanoseconds::rep kIntMax = std::numeric_limits::max(); + const auto count = duration.count(); + return static_cast(std::min(count, kIntMax)); +} + +template +using UnvalidatedConvertOutput = + std::decay_t()).value())>; + +template +nn::GeneralResult>> unvalidatedConvert( + const std::vector& arguments) { + std::vector> halObject; + halObject.reserve(arguments.size()); + for (const auto& argument : arguments) { + halObject.push_back(NN_TRY(unvalidatedConvert(argument))); + } + return halObject; +} + +template +nn::GeneralResult> validatedConvert(const Type& canonical) { + NN_TRY(compliantVersion(canonical)); + return utils::unvalidatedConvert(canonical); +} + +template +nn::GeneralResult>> validatedConvert( + const std::vector& arguments) { + std::vector> halObject(arguments.size()); + for (size_t i = 0; i < arguments.size(); ++i) { + halObject[i] = NN_TRY(validatedConvert(arguments[i])); + } + return halObject; +} + } // namespace nn::GeneralResult> unvalidatedConvert(const nn::CacheToken& cacheToken) { @@ -743,6 +789,19 @@ nn::GeneralResult unvalidatedConvert(const nn::BufferRole& bufferRol }; } +nn::GeneralResult unvalidatedConvert(const nn::DeviceType& deviceType) { + switch (deviceType) { + case nn::DeviceType::UNKNOWN: + break; + case nn::DeviceType::OTHER: + case nn::DeviceType::CPU: + case nn::DeviceType::GPU: + case nn::DeviceType::ACCELERATOR: + return static_cast(deviceType); + } + return NN_ERROR() << "Invalid DeviceType " << deviceType; +} + nn::GeneralResult unvalidatedConvert(const nn::MeasureTiming& measureTiming) { return measureTiming == nn::MeasureTiming::YES; } @@ -956,15 +1015,6 @@ nn::GeneralResult unvalidatedConvert(const nn::Timing& timing) { }; } -nn::GeneralResult unvalidatedConvert(const nn::Duration& duration) { - if (duration < nn::Duration::zero()) { - return NN_ERROR() << "Unable to convert invalid (negative) duration"; - } - constexpr std::chrono::nanoseconds::rep kIntMax = std::numeric_limits::max(); - const auto count = duration.count(); - return static_cast(std::min(count, kIntMax)); -} - nn::GeneralResult unvalidatedConvert(const nn::OptionalDuration& optionalDuration) { if (!optionalDuration.has_value()) { return kNoTiming; @@ -989,6 +1039,23 @@ nn::GeneralResult unvalidatedConvert(const nn::Shared return ndk::ScopedFileDescriptor(duplicatedFd.release()); } +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities) { + return Capabilities{ + .relaxedFloat32toFloat16PerformanceTensor = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + .relaxedFloat32toFloat16PerformanceScalar = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), + .operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance)), + .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)), + .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)), + }; +} + +nn::GeneralResult unvalidatedConvert(const nn::Extension& extension) { + return Extension{.name = extension.name, + .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes))}; +} + nn::GeneralResult> convert(const nn::CacheToken& cacheToken) { return validatedConvert(cacheToken); } @@ -997,6 +1064,10 @@ nn::GeneralResult convert(const nn::BufferDesc& bufferDesc) { return validatedConvert(bufferDesc); } +nn::GeneralResult convert(const nn::DeviceType& deviceType) { + return validatedConvert(deviceType); +} + nn::GeneralResult convert(const nn::MeasureTiming& measureTiming) { return validatedConvert(measureTiming); } @@ -1037,6 +1108,14 @@ nn::GeneralResult convert(const nn::OptionalTimePoint& outputShapes) { return validatedConvert(outputShapes); } +nn::GeneralResult convert(const nn::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +nn::GeneralResult convert(const nn::Extension& extension) { + return validatedConvert(extension); +} + nn::GeneralResult> convert(const std::vector& bufferRoles) { return validatedConvert(bufferRoles); } @@ -1056,6 +1135,10 @@ nn::GeneralResult> convert( return validatedConvert(syncFences); } +nn::GeneralResult> convert(const std::vector& extensions) { + return validatedConvert(extensions); +} + nn::GeneralResult> toSigned(const std::vector& vec) { if (!std::all_of(vec.begin(), vec.end(), [](uint32_t v) { return v <= std::numeric_limits::max(); })) { diff --git a/neuralnetworks/utils/adapter/Android.bp b/neuralnetworks/utils/adapter/Android.bp deleted file mode 100644 index d073106a5f..0000000000 --- a/neuralnetworks/utils/adapter/Android.bp +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright (C) 2020 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "hardware_interfaces_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["hardware_interfaces_license"], -} - -cc_library_static { - name: "neuralnetworks_utils_hal_adapter", - defaults: ["neuralnetworks_utils_defaults"], - srcs: ["src/*"], - local_include_dirs: ["include/nnapi/hal"], - export_include_dirs: ["include"], - static_libs: [ - "neuralnetworks_types", - "neuralnetworks_utils_hal_1_0", - "neuralnetworks_utils_hal_1_1", - "neuralnetworks_utils_hal_1_2", - "neuralnetworks_utils_hal_1_3", - ], - shared_libs: [ - "android.hardware.neuralnetworks@1.0", - "android.hardware.neuralnetworks@1.1", - "android.hardware.neuralnetworks@1.2", - "android.hardware.neuralnetworks@1.3", - "libfmq", - ], -} diff --git a/neuralnetworks/utils/adapter/aidl/Android.bp b/neuralnetworks/utils/adapter/aidl/Android.bp new file mode 100644 index 0000000000..8269a3d4aa --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/Android.bp @@ -0,0 +1,42 @@ +// +// Copyright (C) 2021 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_library_static { + name: "neuralnetworks_utils_hal_adapter_aidl", + defaults: [ + "neuralnetworks_use_latest_utils_hal_aidl", + "neuralnetworks_utils_defaults", + ], + srcs: ["src/*"], + local_include_dirs: ["include/nnapi/hal/aidl/"], + export_include_dirs: ["include"], + static_libs: [ + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + ], + shared_libs: [ + "libbinder_ndk", + ], +} diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h new file mode 100644 index 0000000000..4c0b3286de --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H + +#include +#include +#include + +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +/** + * A self-contained unit of work to be executed. + */ +using Task = std::function; + +/** + * A type-erased executor which executes a task asynchronously. + * + * This executor is also provided an optional deadline for when the caller expects is the upper + * bound for the amount of time to complete the task. If needed, the Executor can retrieve the + * Application ID (Android User ID) by calling AIBinder_getCallingUid in android/binder_ibinder.h. + */ +using Executor = std::function; + +/** + * Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object. + * + * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache + * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource(). + * + * @param device NNAPI canonical IDevice interface object to be adapted. + * @param executor Type-erased executor to handle executing tasks asynchronously. + * @return AIDL NN HAL IDevice interface object. + */ +std::shared_ptr adapt(::android::nn::SharedDevice device, Executor executor); + +/** + * Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object. + * + * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache + * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource(). + * + * This function uses a default executor, which will execute tasks from a detached thread. + * + * @param device NNAPI canonical IDevice interface object to be adapted. + * @return AIDL NN HAL IDevice interface object. + */ +std::shared_ptr adapt(::android::nn::SharedDevice device); + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h new file mode 100644 index 0000000000..701e43eb01 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H + +#include +#include +#include +#include + +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IBuffer to BnBuffer. +class Buffer : public BnBuffer { + public: + explicit Buffer(::android::nn::SharedBuffer buffer); + + ndk::ScopedAStatus copyFrom(const Memory& src, const std::vector& dimensions) override; + ndk::ScopedAStatus copyTo(const Memory& dst) override; + + private: + const ::android::nn::SharedBuffer kBuffer; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h new file mode 100644 index 0000000000..f2687c4a69 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::Burst to BnBurst. +class Burst : public BnBurst { + public: + // Precondition: burst != nullptr + explicit Burst(::android::nn::SharedBurst burst); + + ndk::ScopedAStatus executeSynchronously(const Request& request, + const std::vector& memoryIdentifierTokens, + bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs, + ExecutionResult* executionResult) override; + ndk::ScopedAStatus releaseMemoryResource(int64_t memoryIdentifierToken) override; + + class ThreadSafeMemoryCache { + public: + using Value = + std::pair<::android::nn::SharedMemory, ::android::nn::IBurst::OptionalCacheHold>; + + Value add(int64_t token, const ::android::nn::SharedMemory& memory, + const ::android::nn::IBurst& burst) const; + void remove(int64_t token) const; + + private: + mutable std::mutex mMutex; + mutable std::unordered_map mCache GUARDED_BY(mMutex); + }; + + private: + const ::android::nn::SharedBurst kBurst; + const ThreadSafeMemoryCache kMemoryCache; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h new file mode 100644 index 0000000000..aa29d63b6b --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H + +#include "nnapi/hal/aidl/Adapter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IDevice to BnDevice. +class Device : public BnDevice { + public: + Device(::android::nn::SharedDevice device, Executor executor); + + ndk::ScopedAStatus allocate(const BufferDesc& desc, + const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles, + DeviceBuffer* buffer) override; + ndk::ScopedAStatus getCapabilities(Capabilities* capabilities) override; + ndk::ScopedAStatus getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) override; + ndk::ScopedAStatus getSupportedExtensions(std::vector* extensions) override; + ndk::ScopedAStatus getSupportedOperations(const Model& model, + std::vector* supported) override; + ndk::ScopedAStatus getType(DeviceType* deviceType) override; + ndk::ScopedAStatus getVersionString(std::string* version) override; + ndk::ScopedAStatus prepareModel( + const Model& model, ExecutionPreference preference, Priority priority, + int64_t deadlineNs, const std::vector& modelCache, + const std::vector& dataCache, + const std::vector& token, + const std::shared_ptr& callback) override; + ndk::ScopedAStatus prepareModelFromCache( + int64_t deadlineNs, const std::vector& modelCache, + const std::vector& dataCache, + const std::vector& token, + const std::shared_ptr& callback) override; + + protected: + const ::android::nn::SharedDevice kDevice; + const Executor kExecutor; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h new file mode 100644 index 0000000000..93e0427426 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H + +#include "nnapi/hal/aidl/Adapter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IPreparedModel to BnPreparedModel. +class PreparedModel : public BnPreparedModel { + public: + explicit PreparedModel(::android::nn::SharedPreparedModel preparedModel); + + ndk::ScopedAStatus executeSynchronously(const Request& request, bool measureTiming, + int64_t deadlineNs, int64_t loopTimeoutDurationNs, + ExecutionResult* executionResult) override; + ndk::ScopedAStatus executeFenced(const Request& request, + const std::vector& waitFor, + bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs, int64_t durationNs, + FencedExecutionResult* executionResult) override; + ndk::ScopedAStatus configureExecutionBurst(std::shared_ptr* burst) override; + + ::android::nn::SharedPreparedModel getUnderlyingPreparedModel() const; + + protected: + const ::android::nn::SharedPreparedModel kPreparedModel; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H diff --git a/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp b/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp new file mode 100644 index 0000000000..d0b56e89cc --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 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 "Adapter.h" + +#include "Device.h" + +#include +#include +#include +#include + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +std::shared_ptr adapt(::android::nn::SharedDevice device, Executor executor) { + return ndk::SharedRefBase::make(std::move(device), std::move(executor)); +} + +std::shared_ptr adapt(::android::nn::SharedDevice device) { + Executor defaultExecutor = [](Task task, ::android::nn::OptionalTimePoint /*deadline*/) { + std::thread(std::move(task)).detach(); + }; + return adapt(std::move(device), std::move(defaultExecutor)); +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp b/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp new file mode 100644 index 0000000000..c15ab659c5 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2021 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 "Buffer.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::adapter { +namespace { + +template +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::GeneralResult> inputToUnsigned(const std::vector& dims) { + auto result = nn::toUnsigned(dims); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::GeneralResult copyTo(const nn::IBuffer& buffer, const Memory& dst) { + const auto nnDst = NN_TRY(convertInput(dst)); + return buffer.copyTo(nnDst); +} + +nn::GeneralResult copyFrom(const nn::IBuffer& buffer, const Memory& src, + const std::vector& dimensions) { + const auto nnSrc = NN_TRY(convertInput(src)); + const auto nnDims = NN_TRY(inputToUnsigned(dimensions)); + return buffer.copyFrom(nnSrc, nnDims); +} + +} // namespace + +Buffer::Buffer(nn::SharedBuffer buffer) : kBuffer(std::move(buffer)) { + CHECK(kBuffer != nullptr); +} + +ndk::ScopedAStatus Buffer::copyTo(const Memory& dst) { + const auto result = adapter::copyTo(*kBuffer, dst); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Buffer::copyFrom(const Memory& src, const std::vector& dimensions) { + const auto result = adapter::copyFrom(*kBuffer, src, dimensions); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/aidl/src/Burst.cpp b/neuralnetworks/utils/adapter/aidl/src/Burst.cpp new file mode 100644 index 0000000000..4fabb20635 --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/Burst.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2021 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 "Burst.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::adapter { +namespace { + +using Value = Burst::ThreadSafeMemoryCache::Value; + +template +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::Duration makeDuration(int64_t durationNs) { + return nn::Duration(std::chrono::nanoseconds(durationNs)); +} + +nn::GeneralResult makeOptionalDuration(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid duration " << durationNs; + } + return durationNs < 0 ? nn::OptionalDuration{} : makeDuration(durationNs); +} + +nn::GeneralResult makeOptionalTimePoint(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs; + } + return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs)); +} + +std::vector ensureAllMemoriesAreCached( + nn::Request* request, const std::vector& memoryIdentifierTokens, + const nn::IBurst& burst, const Burst::ThreadSafeMemoryCache& cache) { + std::vector holds; + holds.reserve(memoryIdentifierTokens.size()); + + for (size_t i = 0; i < memoryIdentifierTokens.size(); ++i) { + const auto& pool = request->pools[i]; + const auto token = memoryIdentifierTokens[i]; + constexpr int64_t kNoToken = -1; + if (token == kNoToken || !std::holds_alternative(pool)) { + continue; + } + + const auto& memory = std::get(pool); + auto [storedMemory, hold] = cache.add(token, memory, burst); + + request->pools[i] = std::move(storedMemory); + holds.push_back(std::move(hold)); + } + + return holds; +} + +nn::ExecutionResult executeSynchronously( + const nn::IBurst& burst, const Burst::ThreadSafeMemoryCache& cache, const Request& request, + const std::vector& memoryIdentifierTokens, bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs) { + if (request.pools.size() != memoryIdentifierTokens.size()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "request.pools.size() != memoryIdentifierTokens.size()"; + } + if (!std::all_of(memoryIdentifierTokens.begin(), memoryIdentifierTokens.end(), + [](int64_t token) { return token >= -1; })) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid memoryIdentifierTokens"; + } + + auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO; + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs)); + + const auto hold = ensureAllMemoriesAreCached(&nnRequest, memoryIdentifierTokens, burst, cache); + + const auto result = + burst.execute(nnRequest, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration); + + if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + const auto& [message, code, outputShapes] = result.error(); + return ExecutionResult{.outputSufficientSize = false, + .outputShapes = utils::convert(outputShapes).value(), + .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}}; + } + + const auto& [outputShapes, timing] = NN_TRY(result); + return ExecutionResult{.outputSufficientSize = true, + .outputShapes = utils::convert(outputShapes).value(), + .timing = utils::convert(timing).value()}; +} + +} // namespace + +Value Burst::ThreadSafeMemoryCache::add(int64_t token, const nn::SharedMemory& memory, + const nn::IBurst& burst) const { + std::lock_guard guard(mMutex); + if (const auto it = mCache.find(token); it != mCache.end()) { + return it->second; + } + auto hold = burst.cacheMemory(memory); + auto [it, _] = mCache.emplace(token, std::make_pair(memory, std::move(hold))); + return it->second; +} + +void Burst::ThreadSafeMemoryCache::remove(int64_t token) const { + std::lock_guard guard(mMutex); + mCache.erase(token); +} + +Burst::Burst(nn::SharedBurst burst) : kBurst(std::move(burst)) { + CHECK(kBurst != nullptr); +} + +ndk::ScopedAStatus Burst::executeSynchronously(const Request& request, + const std::vector& memoryIdentifierTokens, + bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs, + ExecutionResult* executionResult) { + auto result = + adapter::executeSynchronously(*kBurst, kMemoryCache, request, memoryIdentifierTokens, + measureTiming, deadlineNs, loopTimeoutDurationNs); + if (!result.has_value()) { + auto [message, code, _] = std::move(result).error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Burst::releaseMemoryResource(int64_t memoryIdentifierToken) { + if (memoryIdentifierToken < -1) { + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(ErrorStatus::INVALID_ARGUMENT), + "Invalid memoryIdentifierToken"); + } + kMemoryCache.remove(memoryIdentifierToken); + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/aidl/src/Device.cpp b/neuralnetworks/utils/adapter/aidl/src/Device.cpp new file mode 100644 index 0000000000..763be7f3fa --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/Device.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2021 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 "Device.h" + +#include "Adapter.h" +#include "Buffer.h" +#include "PreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::adapter { +namespace { + +template +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::Duration makeDuration(int64_t durationNs) { + return nn::Duration(std::chrono::nanoseconds(durationNs)); +} + +nn::GeneralResult makeOptionalTimePoint(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs; + } + return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs)); +} + +nn::GeneralResult convertCacheToken(const std::vector& token) { + nn::CacheToken nnToken; + if (token.size() != nnToken.size()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid token"; + } + std::copy(token.begin(), token.end(), nnToken.begin()); + return nnToken; +} + +nn::GeneralResult downcast(const IPreparedModelParcel& preparedModel) { + if (preparedModel.preparedModel == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "preparedModel is nullptr"; + } + if (preparedModel.preparedModel->isRemote()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Cannot convert remote models"; + } + + // This static_cast is safe because adapter::PreparedModel is the only class that implements + // the IPreparedModel interface in the adapter service code. + const auto* casted = static_cast(preparedModel.preparedModel.get()); + return casted->getUnderlyingPreparedModel(); +} + +nn::GeneralResult> downcastAll( + const std::vector& preparedModels) { + std::vector canonical; + canonical.reserve(preparedModels.size()); + for (const auto& preparedModel : preparedModels) { + canonical.push_back(NN_TRY(downcast(preparedModel))); + } + return canonical; +} + +nn::GeneralResult allocate(const nn::IDevice& device, const BufferDesc& desc, + const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) { + auto nnDesc = NN_TRY(convertInput(desc)); + auto nnPreparedModels = NN_TRY(downcastAll(preparedModels)); + auto nnInputRoles = NN_TRY(convertInput(inputRoles)); + auto nnOutputRoles = NN_TRY(convertInput(outputRoles)); + + auto buffer = NN_TRY(device.allocate(nnDesc, nnPreparedModels, nnInputRoles, nnOutputRoles)); + CHECK(buffer != nullptr); + + const nn::Request::MemoryDomainToken token = buffer->getToken(); + auto aidlBuffer = ndk::SharedRefBase::make(std::move(buffer)); + return DeviceBuffer{.buffer = std::move(aidlBuffer), .token = static_cast(token)}; +} + +nn::GeneralResult> getSupportedOperations(const nn::IDevice& device, + const Model& model) { + const auto nnModel = NN_TRY(convertInput(model)); + return device.getSupportedOperations(nnModel); +} + +using PrepareModelResult = nn::GeneralResult; + +std::shared_ptr adaptPreparedModel(nn::SharedPreparedModel preparedModel) { + if (preparedModel == nullptr) { + return nullptr; + } + return ndk::SharedRefBase::make(std::move(preparedModel)); +} + +void notify(IPreparedModelCallback* callback, PrepareModelResult result) { + if (!result.has_value()) { + const auto& [message, status] = result.error(); + LOG(ERROR) << message; + const auto aidlCode = utils::convert(status).value_or(ErrorStatus::GENERAL_FAILURE); + callback->notify(aidlCode, nullptr); + } else { + auto preparedModel = std::move(result).value(); + auto aidlPreparedModel = adaptPreparedModel(std::move(preparedModel)); + callback->notify(ErrorStatus::NONE, std::move(aidlPreparedModel)); + } +} + +nn::GeneralResult prepareModel(const nn::SharedDevice& device, const Executor& executor, + const Model& model, ExecutionPreference preference, + Priority priority, int64_t deadlineNs, + const std::vector& modelCache, + const std::vector& dataCache, + const std::vector& token, + const std::shared_ptr& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnModel = NN_TRY(convertInput(model)); + const auto nnPreference = NN_TRY(convertInput(preference)); + const auto nnPriority = NN_TRY(convertInput(priority)); + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + auto nnModelCache = NN_TRY(convertInput(modelCache)); + auto nnDataCache = NN_TRY(convertInput(dataCache)); + const auto nnToken = NN_TRY(convertCacheToken(token)); + + Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline, + nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), + nnToken, callback] { + auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline, + nnModelCache, nnDataCache, nnToken); + notify(callback.get(), std::move(result)); + }; + executor(std::move(task), nnDeadline); + + return {}; +} + +nn::GeneralResult prepareModelFromCache( + const nn::SharedDevice& device, const Executor& executor, int64_t deadlineNs, + const std::vector& modelCache, + const std::vector& dataCache, const std::vector& token, + const std::shared_ptr& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + auto nnModelCache = NN_TRY(convertInput(modelCache)); + auto nnDataCache = NN_TRY(convertInput(dataCache)); + const auto nnToken = NN_TRY(convertCacheToken(token)); + + auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache), + nnDataCache = std::move(nnDataCache), nnToken, callback] { + auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken); + notify(callback.get(), std::move(result)); + }; + executor(std::move(task), nnDeadline); + + return {}; +} + +} // namespace + +Device::Device(::android::nn::SharedDevice device, Executor executor) + : kDevice(std::move(device)), kExecutor(std::move(executor)) { + CHECK(kDevice != nullptr); + CHECK(kExecutor != nullptr); +} + +ndk::ScopedAStatus Device::allocate(const BufferDesc& desc, + const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles, + DeviceBuffer* buffer) { + auto result = adapter::allocate(*kDevice, desc, preparedModels, inputRoles, outputRoles); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *buffer = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getCapabilities(Capabilities* capabilities) { + *capabilities = utils::convert(kDevice->getCapabilities()).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) { + const auto [numModelCache, numDataCache] = kDevice->getNumberOfCacheFilesNeeded(); + *numberOfCacheFiles = NumberOfCacheFiles{.numModelCache = static_cast(numModelCache), + .numDataCache = static_cast(numDataCache)}; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getSupportedExtensions(std::vector* extensions) { + *extensions = utils::convert(kDevice->getSupportedExtensions()).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getSupportedOperations(const Model& model, + std::vector* supported) { + auto result = adapter::getSupportedOperations(*kDevice, model); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *supported = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getType(DeviceType* deviceType) { + *deviceType = utils::convert(kDevice->getType()).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::getVersionString(std::string* version) { + *version = kDevice->getVersionString(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::prepareModel(const Model& model, ExecutionPreference preference, + Priority priority, int64_t deadlineNs, + const std::vector& modelCache, + const std::vector& dataCache, + const std::vector& token, + const std::shared_ptr& callback) { + const auto result = adapter::prepareModel(kDevice, kExecutor, model, preference, priority, + deadlineNs, modelCache, dataCache, token, callback); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + callback->notify(aidlCode, nullptr); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Device::prepareModelFromCache( + int64_t deadlineNs, const std::vector& modelCache, + const std::vector& dataCache, const std::vector& token, + const std::shared_ptr& callback) { + const auto result = adapter::prepareModelFromCache(kDevice, kExecutor, deadlineNs, modelCache, + dataCache, token, callback); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + callback->notify(aidlCode, nullptr); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp new file mode 100644 index 0000000000..71ed1a857b --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2021 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 "PreparedModel.h" + +#include "Burst.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::adapter { +namespace { + +class FencedExecutionCallback : public BnFencedExecutionCallback { + public: + FencedExecutionCallback(nn::ExecuteFencedInfoCallback callback) + : kCallback(std::move(callback)) {} + + ndk::ScopedAStatus getExecutionInfo(Timing* timingLaunched, Timing* timingFenced, + ErrorStatus* errorStatus) override { + const auto result = kCallback(); + if (result.ok()) { + const auto& [nnTimingLaunched, nnTimingFenced] = result.value(); + *timingLaunched = utils::convert(nnTimingLaunched).value(); + *timingFenced = utils::convert(nnTimingFenced).value(); + *errorStatus = ErrorStatus::NONE; + } else { + constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1}; + const auto& [message, code] = result.error(); + LOG(ERROR) << "getExecutionInfo failed with " << code << ": " << message; + const auto aidlStatus = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + *timingLaunched = kNoTiming; + *timingFenced = kNoTiming; + *errorStatus = aidlStatus; + } + return ndk::ScopedAStatus::ok(); + } + + private: + const nn::ExecuteFencedInfoCallback kCallback; +}; + +template +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::GeneralResult> convertSyncFences( + const std::vector& waitFor) { + auto handles = NN_TRY(convertInput(waitFor)); + + constexpr auto valid = [](const nn::SharedHandle& handle) { + return handle != nullptr && handle->ok(); + }; + if (!std::all_of(handles.begin(), handles.end(), valid)) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid sync fence"; + } + + std::vector syncFences; + syncFences.reserve(waitFor.size()); + for (auto& handle : handles) { + syncFences.push_back(nn::SyncFence::create(std::move(handle)).value()); + } + return syncFences; +} + +nn::Duration makeDuration(int64_t durationNs) { + return nn::Duration(std::chrono::nanoseconds(durationNs)); +} + +nn::GeneralResult makeOptionalDuration(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid duration " << durationNs; + } + return durationNs < 0 ? nn::OptionalDuration{} : makeDuration(durationNs); +} + +nn::GeneralResult makeOptionalTimePoint(int64_t durationNs) { + if (durationNs < -1) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs; + } + return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs)); +} + +nn::ExecutionResult executeSynchronously(const nn::IPreparedModel& preparedModel, + const Request& request, + bool measureTiming, int64_t deadlineNs, + int64_t loopTimeoutDurationNs) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO; + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs)); + + const auto result = + preparedModel.execute(nnRequest, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration); + + if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + const auto& [message, code, outputShapes] = result.error(); + LOG(ERROR) << "executeSynchronously failed with " << code << ": " << message; + return ExecutionResult{.outputSufficientSize = false, + .outputShapes = utils::convert(outputShapes).value(), + .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}}; + } + + const auto& [outputShapes, timing] = NN_TRY(result); + return ExecutionResult{.outputSufficientSize = true, + .outputShapes = utils::convert(outputShapes).value(), + .timing = utils::convert(timing).value()}; +} + +nn::GeneralResult executeFenced( + const nn::IPreparedModel& preparedModel, const Request& request, + const std::vector& waitFor, bool measureTiming, + int64_t deadlineNs, int64_t loopTimeoutDurationNs, int64_t durationNs) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor)); + const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO; + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs)); + const auto nnDuration = NN_TRY(makeOptionalDuration(durationNs)); + + auto [syncFence, executeFencedInfoCallback] = NN_TRY(preparedModel.executeFenced( + nnRequest, nnWaitFor, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration, nnDuration)); + + ndk::ScopedFileDescriptor fileDescriptor; + if (syncFence.hasFd()) { + auto uniqueFd = NN_TRY(nn::dupFd(syncFence.getFd())); + fileDescriptor = ndk::ScopedFileDescriptor(uniqueFd.release()); + } + + return FencedExecutionResult{.callback = ndk::SharedRefBase::make( + std::move(executeFencedInfoCallback)), + .syncFence = std::move(fileDescriptor)}; +} + +} // namespace + +PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel) + : kPreparedModel(std::move(preparedModel)) { + CHECK(kPreparedModel != nullptr); +} + +ndk::ScopedAStatus PreparedModel::executeSynchronously(const Request& request, bool measureTiming, + int64_t deadlineNs, + int64_t loopTimeoutDurationNs, + ExecutionResult* executionResult) { + auto result = adapter::executeSynchronously(*kPreparedModel, request, measureTiming, deadlineNs, + loopTimeoutDurationNs); + if (!result.has_value()) { + const auto& [message, code, _] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PreparedModel::executeFenced( + const Request& request, const std::vector& waitFor, + bool measureTiming, int64_t deadlineNs, int64_t loopTimeoutDurationNs, int64_t durationNs, + FencedExecutionResult* executionResult) { + auto result = adapter::executeFenced(*kPreparedModel, request, waitFor, measureTiming, + deadlineNs, loopTimeoutDurationNs, durationNs); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PreparedModel::configureExecutionBurst(std::shared_ptr* burst) { + auto result = kPreparedModel->configureExecutionBurst(); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *burst = ndk::SharedRefBase::make(std::move(result).value()); + return ndk::ScopedAStatus::ok(); +} + +nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const { + return kPreparedModel; +} + +} // namespace aidl::android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/hidl/Android.bp b/neuralnetworks/utils/adapter/hidl/Android.bp new file mode 100644 index 0000000000..d073106a5f --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/Android.bp @@ -0,0 +1,46 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_library_static { + name: "neuralnetworks_utils_hal_adapter", + defaults: ["neuralnetworks_utils_defaults"], + srcs: ["src/*"], + local_include_dirs: ["include/nnapi/hal"], + export_include_dirs: ["include"], + static_libs: [ + "neuralnetworks_types", + "neuralnetworks_utils_hal_1_0", + "neuralnetworks_utils_hal_1_1", + "neuralnetworks_utils_hal_1_2", + "neuralnetworks_utils_hal_1_3", + ], + shared_libs: [ + "android.hardware.neuralnetworks@1.0", + "android.hardware.neuralnetworks@1.1", + "android.hardware.neuralnetworks@1.2", + "android.hardware.neuralnetworks@1.3", + "libfmq", + ], +} diff --git a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h new file mode 100644 index 0000000000..da00a090ed --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H + +#include +#include +#include +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::adapter { + +/** + * A self-contained unit of work to be executed. + */ +using Task = std::function; + +/** + * A type-erased executor which executes a task asynchronously. + * + * This executor is also provided with an Application ID (Android User ID) and an optional deadline + * for when the caller expects is the upper bound for the amount of time to complete the task. + */ +using Executor = std::function; + +/** + * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object. + * + * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache + * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource(). + * + * @param device NNAPI canonical IDevice interface object to be adapted. + * @param executor Type-erased executor to handle executing tasks asynchronously. + * @return HIDL NN HAL IDevice interface object. + */ +sp adapt(nn::SharedDevice device, Executor executor); + +/** + * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object. + * + * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache + * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource(). + * + * This function uses a default executor, which will execute tasks from a detached thread. + * + * @param device NNAPI canonical IDevice interface object to be adapted. + * @return HIDL NN HAL IDevice interface object. + */ +sp adapt(nn::SharedDevice device); + +} // namespace android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H diff --git a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h new file mode 100644 index 0000000000..e53c7d4f09 --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BUFFER_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BUFFER_H + +#include +#include +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IBuffer to V1_3::IBuffer. +class Buffer final : public V1_3::IBuffer { + public: + explicit Buffer(nn::SharedBuffer buffer); + + Return copyTo(const hidl_memory& dst) override; + Return copyFrom(const hidl_memory& src, + const hidl_vec& dimensions) override; + + private: + const nn::SharedBuffer kBuffer; +}; + +} // namespace android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BUFFER_H diff --git a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h new file mode 100644 index 0000000000..a3aa706a0c --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h @@ -0,0 +1,155 @@ +/* + * 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BURST_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BURST_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::adapter { + +/** + * The Burst class is responsible for waiting for and deserializing a request object from a FMQ, + * performing the inference, and serializing the result back across another FMQ. + */ +class Burst : public V1_2::IBurstContext { + struct PrivateConstructorTag {}; + + public: + /** + * Class to cache the memory objects for a burst object. + * + * This class is thread-safe. + */ + class MemoryCache { + public: + // Precondition: burstExecutor != nullptr + // Precondition: burstCallback != nullptr + MemoryCache(nn::SharedBurst burstExecutor, sp burstCallback); + + /** + * Get the cached memory objects corresponding to provided slot identifiers. + * + * If the slot entry is not present in the cache, this class will use V1_2::IBurstCallback + * to retrieve those entries that are not present in the cache, then cache them. + * + * @param slots Identifiers of memory objects to be retrieved. + * @return A vector where each element is the memory object and a ref-counted cache "hold" + * object to preserve the cache entry of the IBurst object as long as the "hold" object + * is alive, otherwise GeneralError. Each element of the vector corresponds to the + * element of slot. + */ + nn::GeneralResult>> + getCacheEntries(const std::vector& slots); + + /** + * Remove an entry from the cache. + * + * @param slot Identifier of the memory object to be removed from the cache. + */ + void removeCacheEntry(int32_t slot); + + private: + nn::GeneralResult ensureCacheEntriesArePresentLocked( + const std::vector& slots) REQUIRES(mMutex); + nn::GeneralResult> + getCacheEntryLocked(int32_t slot) REQUIRES(mMutex); + void addCacheEntryLocked(int32_t slot, nn::SharedMemory memory) REQUIRES(mMutex); + + std::mutex mMutex; + std::map> mCache + GUARDED_BY(mMutex); + nn::SharedBurst kBurstExecutor; + const sp kBurstCallback; + }; + + /** + * Create automated context to manage FMQ-based executions. + * + * This function is intended to be used by a service to automatically: + * 1) Receive data from a provided FMQ + * 2) Execute a model with the given information + * 3) Send the result to the created FMQ + * + * @param callback Callback used to retrieve memories corresponding to unrecognized slots. + * @param requestChannel Input FMQ channel through which the client passes the request to the + * service. + * @param resultChannel Output FMQ channel from which the client can retrieve the result of the + * execution. + * @param burstExecutor Object which maintains a local cache of the memory pools and executes + * using the cached memory pools. + * @param pollingTimeWindow How much time (in microseconds) the Burst is allowed to poll the FMQ + * before waiting on the blocking futex. Polling may result in lower latencies at the + * potential cost of more power usage. + * @return V1_2::IBurstContext Handle to the burst context. + */ + static nn::GeneralResult> create( + const sp& callback, + const MQDescriptorSync& requestChannel, + const MQDescriptorSync& resultChannel, + nn::SharedBurst burstExecutor, + std::chrono::microseconds pollingTimeWindow = std::chrono::microseconds{0}); + + Burst(PrivateConstructorTag tag, const sp& callback, + std::unique_ptr requestChannel, + std::unique_ptr resultChannel, + nn::SharedBurst burstExecutor); + ~Burst(); + + // Used by the NN runtime to preemptively remove any stored memory. See + // V1_2::IBurstContext::freeMemory for more information. + Return freeMemory(int32_t slot) override; + + private: + // Work loop that will continue processing execution requests until the Burst object is freed. + void task(); + + nn::ExecutionResult, V1_2::Timing>> execute( + const V1_0::Request& requestWithoutPools, const std::vector& slotsOfPools, + V1_2::MeasureTiming measure); + + std::thread mWorker; + std::atomic mTeardown{false}; + const sp mCallback; + const std::unique_ptr mRequestChannelReceiver; + const std::unique_ptr mResultChannelSender; + const nn::SharedBurst mBurstExecutor; + MemoryCache mMemoryCache; +}; + +} // namespace android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BURST_H diff --git a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h new file mode 100644 index 0000000000..148d0a0341 --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_DEVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_DEVICE_H + +#include "nnapi/hal/Adapter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::adapter { + +using CacheToken = hidl_array; + +// Class that adapts nn::IDevice to V1_3::IDevice. +class Device final : public V1_3::IDevice { + public: + Device(nn::SharedDevice device, Executor executor); + + Return getCapabilities(getCapabilities_cb cb) override; + Return getCapabilities_1_1(getCapabilities_1_1_cb cb) override; + Return getCapabilities_1_2(getCapabilities_1_2_cb cb) override; + Return getCapabilities_1_3(getCapabilities_1_3_cb cb) override; + Return getVersionString(getVersionString_cb cb) override; + Return getType(getType_cb cb) override; + Return getSupportedExtensions(getSupportedExtensions_cb) override; + Return getSupportedOperations(const V1_0::Model& model, + getSupportedOperations_cb cb) override; + Return getSupportedOperations_1_1(const V1_1::Model& model, + getSupportedOperations_1_1_cb cb) override; + Return getSupportedOperations_1_2(const V1_2::Model& model, + getSupportedOperations_1_2_cb cb) override; + Return getSupportedOperations_1_3(const V1_3::Model& model, + getSupportedOperations_1_3_cb cb) override; + Return getNumberOfCacheFilesNeeded(getNumberOfCacheFilesNeeded_cb cb) override; + Return prepareModel( + const V1_0::Model& model, const sp& callback) override; + Return prepareModel_1_1( + const V1_1::Model& model, V1_1::ExecutionPreference preference, + const sp& callback) override; + Return prepareModel_1_2( + const V1_2::Model& model, V1_1::ExecutionPreference preference, + const hidl_vec& modelCache, const hidl_vec& dataCache, + const CacheToken& token, const sp& callback) override; + Return prepareModel_1_3( + const V1_3::Model& model, V1_1::ExecutionPreference preference, V1_3::Priority priority, + const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, + const hidl_vec& dataCache, const CacheToken& token, + const sp& callback) override; + Return prepareModelFromCache( + const hidl_vec& modelCache, const hidl_vec& dataCache, + const CacheToken& token, const sp& callback) override; + Return prepareModelFromCache_1_3( + const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, + const hidl_vec& dataCache, const CacheToken& token, + const sp& callback) override; + Return getStatus() override; + Return allocate(const V1_3::BufferDesc& desc, + const hidl_vec>& preparedModels, + const hidl_vec& inputRoles, + const hidl_vec& outputRoles, allocate_cb cb) override; + + private: + const nn::SharedDevice kDevice; + const Executor kExecutor; +}; + +} // namespace android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_DEVICE_H diff --git a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h new file mode 100644 index 0000000000..65763b8d19 --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_PREPARED_MODEL_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_PREPARED_MODEL_H + +#include "nnapi/hal/Adapter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IPreparedModel to V1_3::IPreparedModel. +class PreparedModel final : public V1_3::IPreparedModel { + public: + PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId); + + Return execute(const V1_0::Request& request, + const sp& callback) override; + Return execute_1_2(const V1_0::Request& request, V1_2::MeasureTiming measure, + const sp& callback) override; + Return execute_1_3(const V1_3::Request& request, V1_2::MeasureTiming measure, + const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + const sp& callback) override; + Return executeSynchronously(const V1_0::Request& request, V1_2::MeasureTiming measure, + executeSynchronously_cb cb) override; + Return executeSynchronously_1_3(const V1_3::Request& request, V1_2::MeasureTiming measure, + const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + executeSynchronously_1_3_cb cb) override; + Return configureExecutionBurst( + const sp& callback, + const MQDescriptorSync& requestChannel, + const MQDescriptorSync& resultChannel, + configureExecutionBurst_cb cb) override; + Return executeFenced(const V1_3::Request& request, const hidl_vec& waitFor, + V1_2::MeasureTiming measure, const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + const V1_3::OptionalTimeoutDuration& duration, + executeFenced_cb callback) override; + + nn::SharedPreparedModel getUnderlyingPreparedModel() const; + + private: + const nn::SharedPreparedModel kPreparedModel; + const Executor kExecutor; + const uid_t kUserId; +}; + +} // namespace android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_PREPARED_MODEL_H diff --git a/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp new file mode 100644 index 0000000000..d6f53f05a5 --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Adapter.h" + +#include "Device.h" + +#include +#include +#include +#include + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::adapter { + +sp adapt(nn::SharedDevice device, Executor executor) { + return sp::make(std::move(device), std::move(executor)); +} + +sp adapt(nn::SharedDevice device) { + Executor defaultExecutor = [](Task task, uid_t /*uid*/, nn::OptionalTimePoint /*deadline*/) { + std::thread(std::move(task)).detach(); + }; + return adapt(std::move(device), std::move(defaultExecutor)); +} + +} // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/hidl/src/Buffer.cpp b/neuralnetworks/utils/adapter/hidl/src/Buffer.cpp new file mode 100644 index 0000000000..3a04bf6b79 --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/src/Buffer.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Buffer.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::adapter { +namespace { + +template +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::GeneralResult copyTo(const nn::SharedBuffer& buffer, const hidl_memory& dst) { + const auto memory = NN_TRY(convertInput(dst)); + NN_TRY(buffer->copyTo(memory)); + return {}; +} + +nn::GeneralResult copyFrom(const nn::SharedBuffer& buffer, const hidl_memory& src, + const hidl_vec& dimensions) { + const auto memory = NN_TRY(convertInput(src)); + NN_TRY(buffer->copyFrom(memory, dimensions)); + return {}; +} + +} // namespace + +Buffer::Buffer(nn::SharedBuffer buffer) : kBuffer(std::move(buffer)) { + CHECK(kBuffer != nullptr); +} + +Return Buffer::copyTo(const hidl_memory& dst) { + auto result = adapter::copyTo(kBuffer, dst); + if (!result.has_value()) { + const auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::Buffer::copyTo failed with " << code << ": " << message; + return V1_3::utils::convert(code).value(); + } + return V1_3::ErrorStatus::NONE; +} + +Return Buffer::copyFrom(const hidl_memory& src, + const hidl_vec& dimensions) { + auto result = adapter::copyFrom(kBuffer, src, dimensions); + if (!result.has_value()) { + const auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::Buffer::copyFrom failed with " << code << ": " << message; + return V1_3::utils::convert(code).value(); + } + return V1_3::ErrorStatus::NONE; +} + +} // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/hidl/src/Burst.cpp b/neuralnetworks/utils/adapter/hidl/src/Burst.cpp new file mode 100644 index 0000000000..8b2e1dd465 --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/src/Burst.cpp @@ -0,0 +1,259 @@ +/* + * 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 "Burst.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Tracing.h" + +namespace android::hardware::neuralnetworks::adapter { +namespace { + +constexpr V1_2::Timing kTiming = {std::numeric_limits::max(), + std::numeric_limits::max()}; + +nn::GeneralResult> getMemoriesCallback( + V1_0::ErrorStatus status, const hidl_vec& memories) { + HANDLE_STATUS_HIDL(status) << "getting burst memories failed with " << toString(status); + std::vector canonicalMemories; + canonicalMemories.reserve(memories.size()); + for (const auto& memory : memories) { + canonicalMemories.push_back(NN_TRY(nn::convert(memory))); + } + return canonicalMemories; +} + +} // anonymous namespace + +Burst::MemoryCache::MemoryCache(nn::SharedBurst burstExecutor, + sp burstCallback) + : kBurstExecutor(std::move(burstExecutor)), kBurstCallback(std::move(burstCallback)) { + CHECK(kBurstExecutor != nullptr); + CHECK(kBurstCallback != nullptr); +} + +nn::GeneralResult>> +Burst::MemoryCache::getCacheEntries(const std::vector& slots) { + std::lock_guard guard(mMutex); + NN_TRY(ensureCacheEntriesArePresentLocked(slots)); + + std::vector> results; + results.reserve(slots.size()); + for (int32_t slot : slots) { + results.push_back(NN_TRY(getCacheEntryLocked(slot))); + } + + return results; +} + +nn::GeneralResult Burst::MemoryCache::ensureCacheEntriesArePresentLocked( + const std::vector& slots) { + const auto slotIsKnown = [this](int32_t slot) + REQUIRES(mMutex) { return mCache.count(slot) > 0; }; + + // find unique unknown slots + std::vector unknownSlots = slots; + std::sort(unknownSlots.begin(), unknownSlots.end()); + auto unknownSlotsEnd = std::unique(unknownSlots.begin(), unknownSlots.end()); + unknownSlotsEnd = std::remove_if(unknownSlots.begin(), unknownSlotsEnd, slotIsKnown); + unknownSlots.erase(unknownSlotsEnd, unknownSlots.end()); + + // quick-exit if all slots are known + if (unknownSlots.empty()) { + return {}; + } + + auto cb = neuralnetworks::utils::CallbackValue(getMemoriesCallback); + + const auto ret = kBurstCallback->getMemories(unknownSlots, cb); + HANDLE_TRANSPORT_FAILURE(ret); + + auto returnedMemories = NN_TRY(cb.take()); + + if (returnedMemories.size() != unknownSlots.size()) { + return NN_ERROR() << "Burst::MemoryCache::ensureCacheEntriesArePresentLocked: Error " + "retrieving memories -- count mismatch between requested memories (" + << unknownSlots.size() << ") and returned memories (" + << returnedMemories.size() << ")"; + } + + // add memories to unknown slots + for (size_t i = 0; i < unknownSlots.size(); ++i) { + addCacheEntryLocked(unknownSlots[i], std::move(returnedMemories[i])); + } + + return {}; +} + +nn::GeneralResult> +Burst::MemoryCache::getCacheEntryLocked(int32_t slot) { + if (const auto iter = mCache.find(slot); iter != mCache.end()) { + return iter->second; + } + return NN_ERROR() << "Burst::MemoryCache::getCacheEntryLocked failed because slot " << slot + << " is not present in the cache"; +} + +void Burst::MemoryCache::addCacheEntryLocked(int32_t slot, nn::SharedMemory memory) { + auto hold = kBurstExecutor->cacheMemory(memory); + mCache.emplace(slot, std::make_pair(std::move(memory), std::move(hold))); +} + +void Burst::MemoryCache::removeCacheEntry(int32_t slot) { + std::lock_guard guard(mMutex); + mCache.erase(slot); +} + +// Burst methods + +nn::GeneralResult> Burst::create( + const sp& callback, + const MQDescriptorSync& requestChannel, + const MQDescriptorSync& resultChannel, nn::SharedBurst burstExecutor, + std::chrono::microseconds pollingTimeWindow) { + // check inputs + if (callback == nullptr || burstExecutor == nullptr) { + return NN_ERROR() << "Burst::create passed a nullptr"; + } + + // create FMQ objects + auto requestChannelReceiver = + NN_TRY(V1_2::utils::RequestChannelReceiver::create(requestChannel, pollingTimeWindow)); + auto resultChannelSender = NN_TRY(V1_2::utils::ResultChannelSender::create(resultChannel)); + + // check FMQ objects + CHECK(requestChannelReceiver != nullptr); + CHECK(resultChannelSender != nullptr); + + // make and return context + return sp::make(PrivateConstructorTag{}, callback, std::move(requestChannelReceiver), + std::move(resultChannelSender), std::move(burstExecutor)); +} + +Burst::Burst(PrivateConstructorTag /*tag*/, const sp& callback, + std::unique_ptr requestChannel, + std::unique_ptr resultChannel, + nn::SharedBurst burstExecutor) + : mCallback(callback), + mRequestChannelReceiver(std::move(requestChannel)), + mResultChannelSender(std::move(resultChannel)), + mBurstExecutor(std::move(burstExecutor)), + mMemoryCache(mBurstExecutor, mCallback) { + // TODO: highly document the threading behavior of this class + mWorker = std::thread([this] { task(); }); +} + +Burst::~Burst() { + // set teardown flag + mTeardown = true; + mRequestChannelReceiver->invalidate(); + + // wait for task thread to end + mWorker.join(); +} + +Return Burst::freeMemory(int32_t slot) { + mMemoryCache.removeCacheEntry(slot); + return Void(); +} + +void Burst::task() { + // loop until the burst object is being destroyed + while (!mTeardown) { + // receive request + auto arguments = mRequestChannelReceiver->getBlocking(); + + // if the request packet was not properly received, return a generic error and skip the + // execution + // + // if the burst is being torn down, skip the execution so the "task" function can end + if (!arguments.has_value()) { + if (!mTeardown) { + mResultChannelSender->send(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kTiming); + } + continue; + } + + // unpack the arguments; types are Request, std::vector, and V1_2::MeasureTiming, + // respectively + const auto [requestWithoutPools, slotsOfPools, measure] = std::move(arguments).value(); + + auto result = execute(requestWithoutPools, slotsOfPools, measure); + + // return result + if (result.has_value()) { + const auto& [outputShapes, timing] = result.value(); + mResultChannelSender->send(V1_0::ErrorStatus::NONE, outputShapes, timing); + } else { + const auto& [message, code, outputShapes] = result.error(); + LOG(ERROR) << "IBurst::execute failed with " << code << ": " << message; + mResultChannelSender->send(V1_2::utils::convert(code).value(), + V1_2::utils::convert(outputShapes).value(), kTiming); + } + } +} + +nn::ExecutionResult, V1_2::Timing>> Burst::execute( + const V1_0::Request& requestWithoutPools, const std::vector& slotsOfPools, + V1_2::MeasureTiming measure) { + NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, + "Burst getting memory, executing, and returning results"); + + // ensure executor with cache has required memory + const auto cacheEntries = NN_TRY(mMemoryCache.getCacheEntries(slotsOfPools)); + + // convert request, populating its pools + // This code performs an unvalidated convert because the request object without its pools is + // invalid because it is incomplete. Instead, the validation is performed after the memory pools + // have been added to the request. + auto canonicalRequest = NN_TRY(nn::unvalidatedConvert(requestWithoutPools)); + CHECK(canonicalRequest.pools.empty()); + std::transform(cacheEntries.begin(), cacheEntries.end(), + std::back_inserter(canonicalRequest.pools), + [](const auto& cacheEntry) { return cacheEntry.first; }); + NN_TRY(validate(canonicalRequest)); + + nn::MeasureTiming canonicalMeasure = NN_TRY(nn::convert(measure)); + + const auto [outputShapes, timing] = + NN_TRY(mBurstExecutor->execute(canonicalRequest, canonicalMeasure, {}, {})); + + return std::make_pair(NN_TRY(V1_2::utils::convert(outputShapes)), + NN_TRY(V1_2::utils::convert(timing))); +} + +} // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/hidl/src/Device.cpp b/neuralnetworks/utils/adapter/hidl/src/Device.cpp new file mode 100644 index 0000000000..96142c3577 --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/src/Device.cpp @@ -0,0 +1,556 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Device.h" + +#include "Buffer.h" +#include "PreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::adapter { +namespace { + +template +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +using PrepareModelResult = nn::GeneralResult; + +sp adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, + uid_t userId) { + if (preparedModel == nullptr) { + return nullptr; + } + return sp::make(std::move(preparedModel), std::move(executor), userId); +} + +void notify(V1_0::IPreparedModelCallback* callback, nn::ErrorStatus status, + const sp& hidlPreparedModel) { + if (callback != nullptr) { + const auto hidlStatus = V1_0::utils::convert(status).value(); + const auto ret = callback->notify(hidlStatus, hidlPreparedModel); + if (!ret.isOk()) { + LOG(ERROR) << "V1_0::IPreparedModelCallback::notify failed with " << ret.description(); + } + } +} + +void notify(V1_2::IPreparedModelCallback* callback, nn::ErrorStatus status, + const sp& hidlPreparedModel) { + if (callback != nullptr) { + const auto hidlStatus = V1_2::utils::convert(status).value(); + const auto ret = callback->notify_1_2(hidlStatus, hidlPreparedModel); + if (!ret.isOk()) { + LOG(ERROR) << "V1_2::IPreparedModelCallback::notify_1_2 failed with " + << ret.description(); + } + } +} + +void notify(V1_3::IPreparedModelCallback* callback, nn::ErrorStatus status, + const sp& hidlPreparedModel) { + if (callback != nullptr) { + const auto hidlStatus = V1_3::utils::convert(status).value(); + const auto ret = callback->notify_1_3(hidlStatus, hidlPreparedModel); + if (!ret.isOk()) { + LOG(ERROR) << "V1_3::IPreparedModelCallback::notify_1_3 failed with " + << ret.description(); + } + } +} + +template +void notify(CallbackType* callback, PrepareModelResult result, Executor executor, uid_t userId) { + if (!result.has_value()) { + const auto [message, status] = std::move(result).error(); + LOG(ERROR) << message; + notify(callback, status, nullptr); + } else { + auto preparedModel = std::move(result).value(); + auto hidlPreparedModel = + adaptPreparedModel(std::move(preparedModel), std::move(executor), userId); + notify(callback, nn::ErrorStatus::NONE, std::move(hidlPreparedModel)); + } +} + +template +nn::GeneralResult> getSupportedOperations(const nn::SharedDevice& device, + const ModelType& model) { + const auto nnModel = NN_TRY(convertInput(model)); + return NN_TRY(device->getSupportedOperations(nnModel)); +} + +nn::GeneralResult prepareModel(const nn::SharedDevice& device, const Executor& executor, + const V1_0::Model& model, + const sp& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnModel = NN_TRY(convertInput(model)); + + const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); + Task task = [device, nnModel = std::move(nnModel), userId, executor, callback] { + auto result = device->prepareModel(nnModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + notify(callback.get(), std::move(result), executor, userId); + }; + executor(std::move(task), userId, {}); + + return {}; +} + +nn::GeneralResult prepareModel_1_1(const nn::SharedDevice& device, const Executor& executor, + const V1_1::Model& model, + V1_1::ExecutionPreference preference, + const sp& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnModel = NN_TRY(convertInput(model)); + const auto nnPreference = NN_TRY(convertInput(preference)); + + const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); + Task task = [device, nnModel = std::move(nnModel), nnPreference, userId, executor, callback] { + auto result = + device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, {}, {}, {}); + notify(callback.get(), std::move(result), executor, userId); + }; + executor(std::move(task), userId, {}); + + return {}; +} + +nn::GeneralResult prepareModel_1_2(const nn::SharedDevice& device, const Executor& executor, + const V1_2::Model& model, + V1_1::ExecutionPreference preference, + const hidl_vec& modelCache, + const hidl_vec& dataCache, + const CacheToken& token, + const sp& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnModel = NN_TRY(convertInput(model)); + const auto nnPreference = NN_TRY(convertInput(preference)); + auto nnModelCache = NN_TRY(convertInput(modelCache)); + auto nnDataCache = NN_TRY(convertInput(dataCache)); + const auto nnToken = nn::CacheToken(token); + + const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); + Task task = [device, nnModel = std::move(nnModel), nnPreference, + nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), + nnToken, userId, executor, callback] { + auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, + nnModelCache, nnDataCache, nnToken); + notify(callback.get(), std::move(result), executor, userId); + }; + executor(std::move(task), userId, {}); + + return {}; +} + +nn::GeneralResult prepareModel_1_3( + const nn::SharedDevice& device, const Executor& executor, const V1_3::Model& model, + V1_1::ExecutionPreference preference, V1_3::Priority priority, + const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, + const hidl_vec& dataCache, const CacheToken& token, + const sp& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnModel = NN_TRY(convertInput(model)); + const auto nnPreference = NN_TRY(convertInput(preference)); + const auto nnPriority = NN_TRY(convertInput(priority)); + const auto nnDeadline = NN_TRY(convertInput(deadline)); + auto nnModelCache = NN_TRY(convertInput(modelCache)); + auto nnDataCache = NN_TRY(convertInput(dataCache)); + const auto nnToken = nn::CacheToken(token); + + const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); + Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline, + nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), + nnToken, userId, executor, callback] { + auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline, + nnModelCache, nnDataCache, nnToken); + notify(callback.get(), std::move(result), executor, userId); + }; + executor(std::move(task), userId, nnDeadline); + + return {}; +} + +nn::GeneralResult prepareModelFromCache(const nn::SharedDevice& device, + const Executor& executor, + const hidl_vec& modelCache, + const hidl_vec& dataCache, + const CacheToken& token, + const sp& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnModelCache = NN_TRY(convertInput(modelCache)); + auto nnDataCache = NN_TRY(convertInput(dataCache)); + const auto nnToken = nn::CacheToken(token); + + const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); + Task task = [device, nnModelCache = std::move(nnModelCache), + nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] { + auto result = device->prepareModelFromCache({}, nnModelCache, nnDataCache, nnToken); + notify(callback.get(), std::move(result), executor, userId); + }; + executor(std::move(task), userId, {}); + + return {}; +} + +nn::GeneralResult prepareModelFromCache_1_3( + const nn::SharedDevice& device, const Executor& executor, + const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, + const hidl_vec& dataCache, const CacheToken& token, + const sp& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + const auto nnDeadline = NN_TRY(convertInput(deadline)); + auto nnModelCache = NN_TRY(convertInput(modelCache)); + auto nnDataCache = NN_TRY(convertInput(dataCache)); + const auto nnToken = nn::CacheToken(token); + + const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); + auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache), + nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] { + auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken); + notify(callback.get(), std::move(result), executor, userId); + }; + executor(std::move(task), userId, nnDeadline); + + return {}; +} + +nn::GeneralResult downcast(const sp& preparedModel) { + if (preparedModel == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "preparedModel is nullptr"; + } + if (preparedModel->isRemote()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Cannot convert remote models"; + } + + // This static_cast is safe because adapter::PreparedModel is the only class that implements + // the IPreparedModel interface in the adapter service code. + const auto* casted = static_cast(preparedModel.get()); + return casted->getUnderlyingPreparedModel(); +} + +nn::GeneralResult> downcastAll( + const hidl_vec>& preparedModels) { + std::vector canonical; + canonical.reserve(preparedModels.size()); + for (const auto& preparedModel : preparedModels) { + canonical.push_back(NN_TRY(downcast(preparedModel))); + } + return canonical; +} + +nn::GeneralResult, uint32_t>> allocate( + const nn::SharedDevice& device, const V1_3::BufferDesc& desc, + const hidl_vec>& preparedModels, + const hidl_vec& inputRoles, + const hidl_vec& outputRoles) { + auto nnDesc = NN_TRY(convertInput(desc)); + auto nnPreparedModels = NN_TRY(downcastAll(preparedModels)); + auto nnInputRoles = NN_TRY(convertInput(inputRoles)); + auto nnOutputRoles = NN_TRY(convertInput(outputRoles)); + + auto buffer = NN_TRY(device->allocate(nnDesc, nnPreparedModels, nnInputRoles, nnOutputRoles)); + + const nn::Request::MemoryDomainToken token = buffer->getToken(); + auto hidlBuffer = sp::make(std::move(buffer)); + return std::make_pair(std::move(hidlBuffer), static_cast(token)); +} + +} // namespace + +Device::Device(nn::SharedDevice device, Executor executor) + : kDevice(std::move(device)), kExecutor(std::move(executor)) { + CHECK(kDevice != nullptr); + CHECK(kExecutor != nullptr); +} + +Return Device::getCapabilities(getCapabilities_cb cb) { + const auto capabilities = V1_0::utils::convert(kDevice->getCapabilities()).value(); + cb(V1_0::ErrorStatus::NONE, capabilities); + return Void(); +} + +Return Device::getCapabilities_1_1(getCapabilities_1_1_cb cb) { + const auto capabilities = V1_1::utils::convert(kDevice->getCapabilities()).value(); + cb(V1_0::ErrorStatus::NONE, capabilities); + return Void(); +} + +Return Device::getCapabilities_1_2(getCapabilities_1_2_cb cb) { + const auto capabilities = V1_2::utils::convert(kDevice->getCapabilities()).value(); + cb(V1_0::ErrorStatus::NONE, capabilities); + return Void(); +} + +Return Device::getCapabilities_1_3(getCapabilities_1_3_cb cb) { + const auto capabilities = V1_3::utils::convert(kDevice->getCapabilities()).value(); + cb(V1_3::ErrorStatus::NONE, capabilities); + return Void(); +} + +Return Device::getVersionString(getVersionString_cb cb) { + cb(V1_0::ErrorStatus::NONE, kDevice->getVersionString()); + return Void(); +} + +Return Device::getType(getType_cb cb) { + const auto maybeDeviceType = V1_2::utils::convert(kDevice->getType()); + if (!maybeDeviceType.has_value()) { + const auto& [message, code] = maybeDeviceType.error(); + LOG(ERROR) << "adapter::Device::getType failed with " << code << ": " << message; + cb(V1_2::utils::convert(code).value(), {}); + } else { + cb(V1_0::ErrorStatus::NONE, maybeDeviceType.value()); + } + return Void(); +} + +Return Device::getSupportedExtensions(getSupportedExtensions_cb cb) { + const auto maybeSupportedExtensions = V1_2::utils::convert(kDevice->getSupportedExtensions()); + if (!maybeSupportedExtensions.has_value()) { + const auto& [message, code] = maybeSupportedExtensions.error(); + LOG(ERROR) << "adapter::Device::getSupportedExtensions failed with " << code << ": " + << message; + cb(V1_2::utils::convert(code).value(), {}); + } else { + cb(V1_0::ErrorStatus::NONE, maybeSupportedExtensions.value()); + } + return Void(); +} + +Return Device::getSupportedOperations(const V1_0::Model& model, + getSupportedOperations_cb cb) { + const auto result = adapter::getSupportedOperations(kDevice, model); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + LOG(ERROR) << "adapter::Device::getSupportedOperations_1_0 failed with " << code << ": " + << message; + cb(V1_0::utils::convert(code).value(), {}); + } else { + cb(V1_0::ErrorStatus::NONE, result.value()); + } + return Void(); +} + +Return Device::getSupportedOperations_1_1(const V1_1::Model& model, + getSupportedOperations_1_1_cb cb) { + const auto result = adapter::getSupportedOperations(kDevice, model); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + LOG(ERROR) << "adapter::Device::getSupportedOperations_1_1 failed with " << code << ": " + << message; + cb(V1_1::utils::convert(code).value(), {}); + } else { + cb(V1_0::ErrorStatus::NONE, result.value()); + } + return Void(); +} + +Return Device::getSupportedOperations_1_2(const V1_2::Model& model, + getSupportedOperations_1_2_cb cb) { + const auto result = adapter::getSupportedOperations(kDevice, model); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + LOG(ERROR) << "adapter::Device::getSupportedOperations_1_2 failed with " << code << ": " + << message; + cb(V1_2::utils::convert(code).value(), {}); + } else { + cb(V1_0::ErrorStatus::NONE, result.value()); + } + return Void(); +} + +Return Device::getSupportedOperations_1_3(const V1_3::Model& model, + getSupportedOperations_1_3_cb cb) { + const auto result = adapter::getSupportedOperations(kDevice, model); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + LOG(ERROR) << "adapter::Device::getSupportedOperations_1_3 failed with " << code << ": " + << message; + cb(V1_3::utils::convert(code).value(), {}); + } else { + cb(V1_3::ErrorStatus::NONE, result.value()); + } + return Void(); +} + +Return Device::getNumberOfCacheFilesNeeded(getNumberOfCacheFilesNeeded_cb cb) { + const auto [numModelCache, numDataCache] = kDevice->getNumberOfCacheFilesNeeded(); + cb(V1_0::ErrorStatus::NONE, numModelCache, numDataCache); + return Void(); +} + +Return Device::prepareModel(const V1_0::Model& model, + const sp& callback) { + auto result = adapter::prepareModel(kDevice, kExecutor, model, callback); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::Device::prepareModel failed with " << code << ": " << message; + notify(callback.get(), code, nullptr); + return V1_0::utils::convert(code).value(); + } + return V1_0::ErrorStatus::NONE; +} + +Return Device::prepareModel_1_1( + const V1_1::Model& model, V1_1::ExecutionPreference preference, + const sp& callback) { + auto result = adapter::prepareModel_1_1(kDevice, kExecutor, model, preference, callback); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::Device::prepareModel_1_1 failed with " << code << ": " << message; + notify(callback.get(), code, nullptr); + return V1_1::utils::convert(code).value(); + } + return V1_0::ErrorStatus::NONE; +} + +Return Device::prepareModel_1_2( + const V1_2::Model& model, V1_1::ExecutionPreference preference, + const hidl_vec& modelCache, const hidl_vec& dataCache, + const CacheToken& token, const sp& callback) { + auto result = adapter::prepareModel_1_2(kDevice, kExecutor, model, preference, modelCache, + dataCache, token, callback); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::Device::prepareModel_1_2 failed with " << code << ": " << message; + notify(callback.get(), code, nullptr); + return V1_2::utils::convert(code).value(); + } + return V1_0::ErrorStatus::NONE; +} + +Return Device::prepareModel_1_3( + const V1_3::Model& model, V1_1::ExecutionPreference preference, V1_3::Priority priority, + const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, + const hidl_vec& dataCache, const CacheToken& token, + const sp& callback) { + auto result = adapter::prepareModel_1_3(kDevice, kExecutor, model, preference, priority, + deadline, modelCache, dataCache, token, callback); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::Device::prepareModel_1_3 failed with " << code << ": " << message; + notify(callback.get(), code, nullptr); + return V1_3::utils::convert(code).value(); + } + return V1_3::ErrorStatus::NONE; +} + +Return Device::prepareModelFromCache( + const hidl_vec& modelCache, const hidl_vec& dataCache, + const CacheToken& token, const sp& callback) { + auto result = adapter::prepareModelFromCache(kDevice, kExecutor, modelCache, dataCache, token, + callback); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::Device::prepareModelFromCache failed with " << code << ": " + << message; + notify(callback.get(), code, nullptr); + return V1_2::utils::convert(code).value(); + } + return V1_0::ErrorStatus::NONE; +} + +Return Device::prepareModelFromCache_1_3( + const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, + const hidl_vec& dataCache, const CacheToken& token, + const sp& callback) { + auto result = adapter::prepareModelFromCache_1_3(kDevice, kExecutor, deadline, modelCache, + dataCache, token, callback); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::Device::prepareModelFromCache_1_3 failed with " << code << ": " + << message; + notify(callback.get(), code, nullptr); + return V1_3::utils::convert(code).value(); + } + return V1_3::ErrorStatus::NONE; +} + +Return Device::getStatus() { + return V1_0::DeviceStatus::AVAILABLE; +} + +Return Device::allocate(const V1_3::BufferDesc& desc, + const hidl_vec>& preparedModels, + const hidl_vec& inputRoles, + const hidl_vec& outputRoles, allocate_cb cb) { + auto result = adapter::allocate(kDevice, desc, preparedModels, inputRoles, outputRoles); + if (!result.has_value()) { + const auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::Device::allocate failed with " << code << ": " << message; + cb(V1_3::utils::convert(code).value(), nullptr, /*token=*/0); + return Void(); + } + auto [buffer, token] = std::move(result).value(); + cb(V1_3::ErrorStatus::NONE, buffer, token); + return Void(); +} + +} // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp new file mode 100644 index 0000000000..a14e782b9b --- /dev/null +++ b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PreparedModel.h" + +#include "Burst.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::adapter { +namespace { + +template +auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { + auto result = nn::convert(object); + if (!result.has_value()) { + result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return result; +} + +nn::GeneralResult validateRequestForModel(const nn::Request& request, + const nn::Model& model) { + nn::GeneralResult version = nn::validateRequestForModel(request, model); + if (!version.ok()) { + version.error().code = nn::ErrorStatus::INVALID_ARGUMENT; + } + return version; +} + +class FencedExecutionCallback final : public V1_3::IFencedExecutionCallback { + public: + explicit FencedExecutionCallback(const nn::ExecuteFencedInfoCallback& callback) + : kCallback(callback) { + CHECK(callback != nullptr); + } + + Return getExecutionInfo(getExecutionInfo_cb cb) override { + const auto result = kCallback(); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto status = + V1_3::utils::convert(code).value_or(V1_3::ErrorStatus::GENERAL_FAILURE); + LOG(ERROR) << message; + cb(status, V1_2::utils::kNoTiming, V1_2::utils::kNoTiming); + return Void(); + } + const auto [timingLaunched, timingFenced] = result.value(); + const auto hidlTimingLaunched = V1_3::utils::convert(timingLaunched).value(); + const auto hidlTimingFenced = V1_3::utils::convert(timingFenced).value(); + cb(V1_3::ErrorStatus::NONE, hidlTimingLaunched, hidlTimingFenced); + return Void(); + } + + private: + const nn::ExecuteFencedInfoCallback kCallback; +}; + +using ExecutionResult = nn::ExecutionResult, nn::Timing>>; + +void notify(V1_0::IExecutionCallback* callback, nn::ErrorStatus status, + const std::vector& /*outputShapes*/, const nn::Timing& /*timing*/) { + if (callback != nullptr) { + const auto hidlStatus = V1_0::utils::convert(status).value(); + const auto ret = callback->notify(hidlStatus); + if (!ret.isOk()) { + LOG(ERROR) << "V1_0::IExecutionCallback::notify failed with " << ret.description(); + } + } +} + +void notify(V1_2::IExecutionCallback* callback, nn::ErrorStatus status, + const std::vector& outputShapes, const nn::Timing& timing) { + if (callback != nullptr) { + const auto hidlStatus = V1_2::utils::convert(status).value(); + const auto hidlOutputShapes = V1_2::utils::convert(outputShapes).value(); + const auto hidlTiming = V1_2::utils::convert(timing).value(); + const auto ret = callback->notify_1_2(hidlStatus, hidlOutputShapes, hidlTiming); + if (!ret.isOk()) { + LOG(ERROR) << "V1_2::IExecutionCallback::notify_1_2 failed with " << ret.description(); + } + } +} + +void notify(V1_3::IExecutionCallback* callback, nn::ErrorStatus status, + const std::vector& outputShapes, const nn::Timing& timing) { + if (callback != nullptr) { + const auto hidlStatus = V1_3::utils::convert(status).value(); + const auto hidlOutputShapes = V1_3::utils::convert(outputShapes).value(); + const auto hidlTiming = V1_3::utils::convert(timing).value(); + const auto ret = callback->notify_1_3(hidlStatus, hidlOutputShapes, hidlTiming); + if (!ret.isOk()) { + LOG(ERROR) << "V1_3::IExecutionCallback::notify_1_3 failed with " << ret.description(); + } + } +} + +template +void notify(CallbackType* callback, ExecutionResult result) { + if (!result.has_value()) { + const auto [message, status, outputShapes] = std::move(result).error(); + LOG(ERROR) << message; + notify(callback, status, outputShapes, {}); + } else { + const auto [outputShapes, timing] = std::move(result).value(); + notify(callback, nn::ErrorStatus::NONE, outputShapes, timing); + } +} + +nn::GeneralResult execute(const nn::SharedPreparedModel& preparedModel, uid_t userId, + const Executor& executor, const V1_0::Request& request, + const sp& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnRequest = NN_TRY(convertInput(request)); + + const std::any resource = preparedModel->getUnderlyingResource(); + if (const auto* model = std::any_cast(&resource)) { + CHECK(*model != nullptr); + NN_TRY(adapter::validateRequestForModel(nnRequest, **model)); + } + + Task task = [preparedModel, nnRequest = std::move(nnRequest), callback] { + auto result = preparedModel->execute(nnRequest, nn::MeasureTiming::NO, {}, {}); + notify(callback.get(), std::move(result)); + }; + executor(std::move(task), userId, {}); + + return {}; +} + +nn::GeneralResult execute_1_2(const nn::SharedPreparedModel& preparedModel, uid_t userId, + const Executor& executor, const V1_0::Request& request, + V1_2::MeasureTiming measure, + const sp& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasure = NN_TRY(convertInput(measure)); + + const std::any resource = preparedModel->getUnderlyingResource(); + if (const auto* model = std::any_cast(&resource)) { + CHECK(*model != nullptr); + NN_TRY(adapter::validateRequestForModel(nnRequest, **model)); + } + + Task task = [preparedModel, nnRequest = std::move(nnRequest), nnMeasure, callback] { + auto result = preparedModel->execute(nnRequest, nnMeasure, {}, {}); + notify(callback.get(), std::move(result)); + }; + executor(std::move(task), userId, {}); + + return {}; +} + +nn::GeneralResult execute_1_3(const nn::SharedPreparedModel& preparedModel, uid_t userId, + const Executor& executor, const V1_3::Request& request, + V1_2::MeasureTiming measure, + const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + const sp& callback) { + if (callback.get() == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; + } + + auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasure = NN_TRY(convertInput(measure)); + const auto nnDeadline = NN_TRY(convertInput(deadline)); + const auto nnLoopTimeoutDuration = NN_TRY(convertInput(loopTimeoutDuration)); + + const std::any resource = preparedModel->getUnderlyingResource(); + if (const auto* model = std::any_cast(&resource)) { + CHECK(*model != nullptr); + NN_TRY(adapter::validateRequestForModel(nnRequest, **model)); + } + + Task task = [preparedModel, nnRequest = std::move(nnRequest), nnMeasure, nnDeadline, + nnLoopTimeoutDuration, callback] { + auto result = + preparedModel->execute(nnRequest, nnMeasure, nnDeadline, nnLoopTimeoutDuration); + notify(callback.get(), std::move(result)); + }; + executor(std::move(task), userId, nnDeadline); + + return {}; +} + +nn::ExecutionResult, V1_2::Timing>> executeSynchronously( + const nn::SharedPreparedModel& preparedModel, const V1_0::Request& request, + V1_2::MeasureTiming measure) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasure = NN_TRY(convertInput(measure)); + + const auto [outputShapes, timing] = + NN_TRY(preparedModel->execute(nnRequest, nnMeasure, {}, {})); + + auto hidlOutputShapes = NN_TRY(V1_2::utils::convert(outputShapes)); + const auto hidlTiming = NN_TRY(V1_2::utils::convert(timing)); + return std::make_pair(std::move(hidlOutputShapes), hidlTiming); +} + +nn::ExecutionResult, V1_2::Timing>> executeSynchronously_1_3( + const nn::SharedPreparedModel& preparedModel, const V1_3::Request& request, + V1_2::MeasureTiming measure, const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasure = NN_TRY(convertInput(measure)); + const auto nnDeadline = NN_TRY(convertInput(deadline)); + const auto nnLoopTimeoutDuration = NN_TRY(convertInput(loopTimeoutDuration)); + + const auto [outputShapes, timing] = + NN_TRY(preparedModel->execute(nnRequest, nnMeasure, nnDeadline, nnLoopTimeoutDuration)); + + auto hidlOutputShapes = NN_TRY(V1_3::utils::convert(outputShapes)); + const auto hidlTiming = NN_TRY(V1_3::utils::convert(timing)); + return std::make_pair(std::move(hidlOutputShapes), hidlTiming); +} + +nn::GeneralResult> convertSyncFences( + const hidl_vec& handles) { + auto nnHandles = NN_TRY(convertInput(handles)); + std::vector syncFences; + syncFences.reserve(handles.size()); + for (auto&& handle : nnHandles) { + if (auto syncFence = nn::SyncFence::create(std::move(handle)); !syncFence.ok()) { + return nn::error(nn::ErrorStatus::INVALID_ARGUMENT) << std::move(syncFence).error(); + } else { + syncFences.push_back(std::move(syncFence).value()); + } + } + return syncFences; +} + +nn::GeneralResult> configureExecutionBurst( + const nn::SharedPreparedModel& preparedModel, const sp& callback, + const MQDescriptorSync& requestChannel, + const MQDescriptorSync& resultChannel) { + auto burstExecutor = NN_TRY(preparedModel->configureExecutionBurst()); + return Burst::create(callback, requestChannel, resultChannel, std::move(burstExecutor), + V1_2::utils::getBurstServerPollingTimeWindow()); +} + +nn::GeneralResult>> executeFenced( + const nn::SharedPreparedModel& preparedModel, const V1_3::Request& request, + const hidl_vec& waitFor, V1_2::MeasureTiming measure, + const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + const V1_3::OptionalTimeoutDuration& duration) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor)); + const auto nnMeasure = NN_TRY(convertInput(measure)); + const auto nnDeadline = NN_TRY(convertInput(deadline)); + const auto nnLoopTimeoutDuration = NN_TRY(convertInput(loopTimeoutDuration)); + const auto nnDuration = NN_TRY(convertInput(duration)); + + auto [syncFence, executeFencedCallback] = NN_TRY(preparedModel->executeFenced( + nnRequest, nnWaitFor, nnMeasure, nnDeadline, nnLoopTimeoutDuration, nnDuration)); + + auto hidlSyncFence = NN_TRY(V1_3::utils::convert(syncFence.getSharedHandle())); + auto hidlExecuteFencedCallback = sp::make(executeFencedCallback); + return std::make_pair(std::move(hidlSyncFence), std::move(hidlExecuteFencedCallback)); +} + +} // namespace + +PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId) + : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)), kUserId(userId) { + CHECK(kPreparedModel != nullptr); + CHECK(kExecutor != nullptr); +} + +nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const { + return kPreparedModel; +} + +Return PreparedModel::execute(const V1_0::Request& request, + const sp& callback) { + auto result = adapter::execute(kPreparedModel, kUserId, kExecutor, request, callback); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::PreparedModel::execute failed with " << code << ": " << message; + notify(callback.get(), code, {}, {}); + return V1_0::utils::convert(code).value(); + } + return V1_0::ErrorStatus::NONE; +} + +Return PreparedModel::execute_1_2(const V1_0::Request& request, + V1_2::MeasureTiming measure, + const sp& callback) { + auto result = + adapter::execute_1_2(kPreparedModel, kUserId, kExecutor, request, measure, callback); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::PreparedModel::execute_1_2 failed with " << code << ": " << message; + notify(callback.get(), code, {}, {}); + return V1_2::utils::convert(code).value(); + } + return V1_0::ErrorStatus::NONE; +} + +Return PreparedModel::execute_1_3( + const V1_3::Request& request, V1_2::MeasureTiming measure, + const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + const sp& callback) { + auto result = adapter::execute_1_3(kPreparedModel, kUserId, kExecutor, request, measure, + deadline, loopTimeoutDuration, callback); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::PreparedModel::execute_1_3 failed with " << code << ": " << message; + notify(callback.get(), code, {}, {}); + return V1_3::utils::convert(code).value(); + } + return V1_3::ErrorStatus::NONE; +} + +Return PreparedModel::executeSynchronously(const V1_0::Request& request, + V1_2::MeasureTiming measure, + executeSynchronously_cb cb) { + auto result = adapter::executeSynchronously(kPreparedModel, request, measure); + if (!result.has_value()) { + auto [message, code, outputShapes] = std::move(result).error(); + LOG(ERROR) << "adapter::PreparedModel::executeSynchronously failed with " << code << ": " + << message; + cb(V1_2::utils::convert(code).value(), V1_2::utils::convert(outputShapes).value(), + V1_2::utils::kNoTiming); + return Void(); + } + auto [outputShapes, timing] = std::move(result).value(); + cb(V1_0::ErrorStatus::NONE, outputShapes, timing); + return Void(); +} + +Return PreparedModel::executeSynchronously_1_3( + const V1_3::Request& request, V1_2::MeasureTiming measure, + const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, executeSynchronously_1_3_cb cb) { + auto result = adapter::executeSynchronously_1_3(kPreparedModel, request, measure, deadline, + loopTimeoutDuration); + if (!result.has_value()) { + auto [message, code, outputShapes] = std::move(result).error(); + LOG(ERROR) << "adapter::PreparedModel::executeSynchronously_1_3 failed with " << code + << ": " << message; + cb(V1_3::utils::convert(code).value(), V1_3::utils::convert(outputShapes).value(), + V1_2::utils::kNoTiming); + return Void(); + } + auto [outputShapes, timing] = std::move(result).value(); + cb(V1_3::ErrorStatus::NONE, outputShapes, timing); + return Void(); +} + +Return PreparedModel::configureExecutionBurst( + const sp& callback, + const MQDescriptorSync& requestChannel, + const MQDescriptorSync& resultChannel, + configureExecutionBurst_cb cb) { + auto result = adapter::configureExecutionBurst(kPreparedModel, callback, requestChannel, + resultChannel); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::PreparedModel::configureExecutionBurst failed with " << code << ": " + << message; + cb(V1_2::utils::convert(code).value(), nullptr); + return Void(); + } + auto burstContext = std::move(result).value(); + cb(V1_0::ErrorStatus::NONE, std::move(burstContext)); + return Void(); +} + +Return PreparedModel::executeFenced(const V1_3::Request& request, + const hidl_vec& waitFor, + V1_2::MeasureTiming measure, + const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + const V1_3::OptionalTimeoutDuration& duration, + executeFenced_cb callback) { + auto result = adapter::executeFenced(kPreparedModel, request, waitFor, measure, deadline, + loopTimeoutDuration, duration); + if (!result.has_value()) { + auto [message, code] = std::move(result).error(); + LOG(ERROR) << "adapter::PreparedModel::executeFenced failed with " << code << ": " + << message; + callback(V1_3::utils::convert(code).value(), {}, nullptr); + return Void(); + } + auto [syncFence, executeFencedCallback] = std::move(result).value(); + callback(V1_3::ErrorStatus::NONE, syncFence, executeFencedCallback); + return Void(); +} + +} // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h b/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h deleted file mode 100644 index da00a090ed..0000000000 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H -#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H - -#include -#include -#include -#include -#include -#include - -// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface -// lifetimes across processes and for protecting asynchronous calls across HIDL. - -namespace android::hardware::neuralnetworks::adapter { - -/** - * A self-contained unit of work to be executed. - */ -using Task = std::function; - -/** - * A type-erased executor which executes a task asynchronously. - * - * This executor is also provided with an Application ID (Android User ID) and an optional deadline - * for when the caller expects is the upper bound for the amount of time to complete the task. - */ -using Executor = std::function; - -/** - * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object. - * - * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache - * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource(). - * - * @param device NNAPI canonical IDevice interface object to be adapted. - * @param executor Type-erased executor to handle executing tasks asynchronously. - * @return HIDL NN HAL IDevice interface object. - */ -sp adapt(nn::SharedDevice device, Executor executor); - -/** - * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object. - * - * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache - * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource(). - * - * This function uses a default executor, which will execute tasks from a detached thread. - * - * @param device NNAPI canonical IDevice interface object to be adapted. - * @return HIDL NN HAL IDevice interface object. - */ -sp adapt(nn::SharedDevice device); - -} // namespace android::hardware::neuralnetworks::adapter - -#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h b/neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h deleted file mode 100644 index e53c7d4f09..0000000000 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BUFFER_H -#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BUFFER_H - -#include -#include -#include -#include -#include - -// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface -// lifetimes across processes and for protecting asynchronous calls across HIDL. - -namespace android::hardware::neuralnetworks::adapter { - -// Class that adapts nn::IBuffer to V1_3::IBuffer. -class Buffer final : public V1_3::IBuffer { - public: - explicit Buffer(nn::SharedBuffer buffer); - - Return copyTo(const hidl_memory& dst) override; - Return copyFrom(const hidl_memory& src, - const hidl_vec& dimensions) override; - - private: - const nn::SharedBuffer kBuffer; -}; - -} // namespace android::hardware::neuralnetworks::adapter - -#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BUFFER_H diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h b/neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h deleted file mode 100644 index a3aa706a0c..0000000000 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BURST_H -#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BURST_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace android::hardware::neuralnetworks::adapter { - -/** - * The Burst class is responsible for waiting for and deserializing a request object from a FMQ, - * performing the inference, and serializing the result back across another FMQ. - */ -class Burst : public V1_2::IBurstContext { - struct PrivateConstructorTag {}; - - public: - /** - * Class to cache the memory objects for a burst object. - * - * This class is thread-safe. - */ - class MemoryCache { - public: - // Precondition: burstExecutor != nullptr - // Precondition: burstCallback != nullptr - MemoryCache(nn::SharedBurst burstExecutor, sp burstCallback); - - /** - * Get the cached memory objects corresponding to provided slot identifiers. - * - * If the slot entry is not present in the cache, this class will use V1_2::IBurstCallback - * to retrieve those entries that are not present in the cache, then cache them. - * - * @param slots Identifiers of memory objects to be retrieved. - * @return A vector where each element is the memory object and a ref-counted cache "hold" - * object to preserve the cache entry of the IBurst object as long as the "hold" object - * is alive, otherwise GeneralError. Each element of the vector corresponds to the - * element of slot. - */ - nn::GeneralResult>> - getCacheEntries(const std::vector& slots); - - /** - * Remove an entry from the cache. - * - * @param slot Identifier of the memory object to be removed from the cache. - */ - void removeCacheEntry(int32_t slot); - - private: - nn::GeneralResult ensureCacheEntriesArePresentLocked( - const std::vector& slots) REQUIRES(mMutex); - nn::GeneralResult> - getCacheEntryLocked(int32_t slot) REQUIRES(mMutex); - void addCacheEntryLocked(int32_t slot, nn::SharedMemory memory) REQUIRES(mMutex); - - std::mutex mMutex; - std::map> mCache - GUARDED_BY(mMutex); - nn::SharedBurst kBurstExecutor; - const sp kBurstCallback; - }; - - /** - * Create automated context to manage FMQ-based executions. - * - * This function is intended to be used by a service to automatically: - * 1) Receive data from a provided FMQ - * 2) Execute a model with the given information - * 3) Send the result to the created FMQ - * - * @param callback Callback used to retrieve memories corresponding to unrecognized slots. - * @param requestChannel Input FMQ channel through which the client passes the request to the - * service. - * @param resultChannel Output FMQ channel from which the client can retrieve the result of the - * execution. - * @param burstExecutor Object which maintains a local cache of the memory pools and executes - * using the cached memory pools. - * @param pollingTimeWindow How much time (in microseconds) the Burst is allowed to poll the FMQ - * before waiting on the blocking futex. Polling may result in lower latencies at the - * potential cost of more power usage. - * @return V1_2::IBurstContext Handle to the burst context. - */ - static nn::GeneralResult> create( - const sp& callback, - const MQDescriptorSync& requestChannel, - const MQDescriptorSync& resultChannel, - nn::SharedBurst burstExecutor, - std::chrono::microseconds pollingTimeWindow = std::chrono::microseconds{0}); - - Burst(PrivateConstructorTag tag, const sp& callback, - std::unique_ptr requestChannel, - std::unique_ptr resultChannel, - nn::SharedBurst burstExecutor); - ~Burst(); - - // Used by the NN runtime to preemptively remove any stored memory. See - // V1_2::IBurstContext::freeMemory for more information. - Return freeMemory(int32_t slot) override; - - private: - // Work loop that will continue processing execution requests until the Burst object is freed. - void task(); - - nn::ExecutionResult, V1_2::Timing>> execute( - const V1_0::Request& requestWithoutPools, const std::vector& slotsOfPools, - V1_2::MeasureTiming measure); - - std::thread mWorker; - std::atomic mTeardown{false}; - const sp mCallback; - const std::unique_ptr mRequestChannelReceiver; - const std::unique_ptr mResultChannelSender; - const nn::SharedBurst mBurstExecutor; - MemoryCache mMemoryCache; -}; - -} // namespace android::hardware::neuralnetworks::adapter - -#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_BURST_H diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Device.h b/neuralnetworks/utils/adapter/include/nnapi/hal/Device.h deleted file mode 100644 index 148d0a0341..0000000000 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/Device.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_DEVICE_H -#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_DEVICE_H - -#include "nnapi/hal/Adapter.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface -// lifetimes across processes and for protecting asynchronous calls across HIDL. - -namespace android::hardware::neuralnetworks::adapter { - -using CacheToken = hidl_array; - -// Class that adapts nn::IDevice to V1_3::IDevice. -class Device final : public V1_3::IDevice { - public: - Device(nn::SharedDevice device, Executor executor); - - Return getCapabilities(getCapabilities_cb cb) override; - Return getCapabilities_1_1(getCapabilities_1_1_cb cb) override; - Return getCapabilities_1_2(getCapabilities_1_2_cb cb) override; - Return getCapabilities_1_3(getCapabilities_1_3_cb cb) override; - Return getVersionString(getVersionString_cb cb) override; - Return getType(getType_cb cb) override; - Return getSupportedExtensions(getSupportedExtensions_cb) override; - Return getSupportedOperations(const V1_0::Model& model, - getSupportedOperations_cb cb) override; - Return getSupportedOperations_1_1(const V1_1::Model& model, - getSupportedOperations_1_1_cb cb) override; - Return getSupportedOperations_1_2(const V1_2::Model& model, - getSupportedOperations_1_2_cb cb) override; - Return getSupportedOperations_1_3(const V1_3::Model& model, - getSupportedOperations_1_3_cb cb) override; - Return getNumberOfCacheFilesNeeded(getNumberOfCacheFilesNeeded_cb cb) override; - Return prepareModel( - const V1_0::Model& model, const sp& callback) override; - Return prepareModel_1_1( - const V1_1::Model& model, V1_1::ExecutionPreference preference, - const sp& callback) override; - Return prepareModel_1_2( - const V1_2::Model& model, V1_1::ExecutionPreference preference, - const hidl_vec& modelCache, const hidl_vec& dataCache, - const CacheToken& token, const sp& callback) override; - Return prepareModel_1_3( - const V1_3::Model& model, V1_1::ExecutionPreference preference, V1_3::Priority priority, - const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, - const hidl_vec& dataCache, const CacheToken& token, - const sp& callback) override; - Return prepareModelFromCache( - const hidl_vec& modelCache, const hidl_vec& dataCache, - const CacheToken& token, const sp& callback) override; - Return prepareModelFromCache_1_3( - const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, - const hidl_vec& dataCache, const CacheToken& token, - const sp& callback) override; - Return getStatus() override; - Return allocate(const V1_3::BufferDesc& desc, - const hidl_vec>& preparedModels, - const hidl_vec& inputRoles, - const hidl_vec& outputRoles, allocate_cb cb) override; - - private: - const nn::SharedDevice kDevice; - const Executor kExecutor; -}; - -} // namespace android::hardware::neuralnetworks::adapter - -#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_DEVICE_H diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h b/neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h deleted file mode 100644 index 65763b8d19..0000000000 --- a/neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_PREPARED_MODEL_H -#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_PREPARED_MODEL_H - -#include "nnapi/hal/Adapter.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface -// lifetimes across processes and for protecting asynchronous calls across HIDL. - -namespace android::hardware::neuralnetworks::adapter { - -// Class that adapts nn::IPreparedModel to V1_3::IPreparedModel. -class PreparedModel final : public V1_3::IPreparedModel { - public: - PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId); - - Return execute(const V1_0::Request& request, - const sp& callback) override; - Return execute_1_2(const V1_0::Request& request, V1_2::MeasureTiming measure, - const sp& callback) override; - Return execute_1_3(const V1_3::Request& request, V1_2::MeasureTiming measure, - const V1_3::OptionalTimePoint& deadline, - const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, - const sp& callback) override; - Return executeSynchronously(const V1_0::Request& request, V1_2::MeasureTiming measure, - executeSynchronously_cb cb) override; - Return executeSynchronously_1_3(const V1_3::Request& request, V1_2::MeasureTiming measure, - const V1_3::OptionalTimePoint& deadline, - const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, - executeSynchronously_1_3_cb cb) override; - Return configureExecutionBurst( - const sp& callback, - const MQDescriptorSync& requestChannel, - const MQDescriptorSync& resultChannel, - configureExecutionBurst_cb cb) override; - Return executeFenced(const V1_3::Request& request, const hidl_vec& waitFor, - V1_2::MeasureTiming measure, const V1_3::OptionalTimePoint& deadline, - const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, - const V1_3::OptionalTimeoutDuration& duration, - executeFenced_cb callback) override; - - nn::SharedPreparedModel getUnderlyingPreparedModel() const; - - private: - const nn::SharedPreparedModel kPreparedModel; - const Executor kExecutor; - const uid_t kUserId; -}; - -} // namespace android::hardware::neuralnetworks::adapter - -#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_PREPARED_MODEL_H diff --git a/neuralnetworks/utils/adapter/src/Adapter.cpp b/neuralnetworks/utils/adapter/src/Adapter.cpp deleted file mode 100644 index d6f53f05a5..0000000000 --- a/neuralnetworks/utils/adapter/src/Adapter.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Adapter.h" - -#include "Device.h" - -#include -#include -#include -#include - -#include -#include -#include - -// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface -// lifetimes across processes and for protecting asynchronous calls across HIDL. - -namespace android::hardware::neuralnetworks::adapter { - -sp adapt(nn::SharedDevice device, Executor executor) { - return sp::make(std::move(device), std::move(executor)); -} - -sp adapt(nn::SharedDevice device) { - Executor defaultExecutor = [](Task task, uid_t /*uid*/, nn::OptionalTimePoint /*deadline*/) { - std::thread(std::move(task)).detach(); - }; - return adapt(std::move(device), std::move(defaultExecutor)); -} - -} // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/src/Buffer.cpp b/neuralnetworks/utils/adapter/src/Buffer.cpp deleted file mode 100644 index 3a04bf6b79..0000000000 --- a/neuralnetworks/utils/adapter/src/Buffer.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Buffer.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface -// lifetimes across processes and for protecting asynchronous calls across HIDL. - -namespace android::hardware::neuralnetworks::adapter { -namespace { - -template -auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { - auto result = nn::convert(object); - if (!result.has_value()) { - result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; - } - return result; -} - -nn::GeneralResult copyTo(const nn::SharedBuffer& buffer, const hidl_memory& dst) { - const auto memory = NN_TRY(convertInput(dst)); - NN_TRY(buffer->copyTo(memory)); - return {}; -} - -nn::GeneralResult copyFrom(const nn::SharedBuffer& buffer, const hidl_memory& src, - const hidl_vec& dimensions) { - const auto memory = NN_TRY(convertInput(src)); - NN_TRY(buffer->copyFrom(memory, dimensions)); - return {}; -} - -} // namespace - -Buffer::Buffer(nn::SharedBuffer buffer) : kBuffer(std::move(buffer)) { - CHECK(kBuffer != nullptr); -} - -Return Buffer::copyTo(const hidl_memory& dst) { - auto result = adapter::copyTo(kBuffer, dst); - if (!result.has_value()) { - const auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::Buffer::copyTo failed with " << code << ": " << message; - return V1_3::utils::convert(code).value(); - } - return V1_3::ErrorStatus::NONE; -} - -Return Buffer::copyFrom(const hidl_memory& src, - const hidl_vec& dimensions) { - auto result = adapter::copyFrom(kBuffer, src, dimensions); - if (!result.has_value()) { - const auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::Buffer::copyFrom failed with " << code << ": " << message; - return V1_3::utils::convert(code).value(); - } - return V1_3::ErrorStatus::NONE; -} - -} // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/src/Burst.cpp b/neuralnetworks/utils/adapter/src/Burst.cpp deleted file mode 100644 index 8b2e1dd465..0000000000 --- a/neuralnetworks/utils/adapter/src/Burst.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * 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 "Burst.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Tracing.h" - -namespace android::hardware::neuralnetworks::adapter { -namespace { - -constexpr V1_2::Timing kTiming = {std::numeric_limits::max(), - std::numeric_limits::max()}; - -nn::GeneralResult> getMemoriesCallback( - V1_0::ErrorStatus status, const hidl_vec& memories) { - HANDLE_STATUS_HIDL(status) << "getting burst memories failed with " << toString(status); - std::vector canonicalMemories; - canonicalMemories.reserve(memories.size()); - for (const auto& memory : memories) { - canonicalMemories.push_back(NN_TRY(nn::convert(memory))); - } - return canonicalMemories; -} - -} // anonymous namespace - -Burst::MemoryCache::MemoryCache(nn::SharedBurst burstExecutor, - sp burstCallback) - : kBurstExecutor(std::move(burstExecutor)), kBurstCallback(std::move(burstCallback)) { - CHECK(kBurstExecutor != nullptr); - CHECK(kBurstCallback != nullptr); -} - -nn::GeneralResult>> -Burst::MemoryCache::getCacheEntries(const std::vector& slots) { - std::lock_guard guard(mMutex); - NN_TRY(ensureCacheEntriesArePresentLocked(slots)); - - std::vector> results; - results.reserve(slots.size()); - for (int32_t slot : slots) { - results.push_back(NN_TRY(getCacheEntryLocked(slot))); - } - - return results; -} - -nn::GeneralResult Burst::MemoryCache::ensureCacheEntriesArePresentLocked( - const std::vector& slots) { - const auto slotIsKnown = [this](int32_t slot) - REQUIRES(mMutex) { return mCache.count(slot) > 0; }; - - // find unique unknown slots - std::vector unknownSlots = slots; - std::sort(unknownSlots.begin(), unknownSlots.end()); - auto unknownSlotsEnd = std::unique(unknownSlots.begin(), unknownSlots.end()); - unknownSlotsEnd = std::remove_if(unknownSlots.begin(), unknownSlotsEnd, slotIsKnown); - unknownSlots.erase(unknownSlotsEnd, unknownSlots.end()); - - // quick-exit if all slots are known - if (unknownSlots.empty()) { - return {}; - } - - auto cb = neuralnetworks::utils::CallbackValue(getMemoriesCallback); - - const auto ret = kBurstCallback->getMemories(unknownSlots, cb); - HANDLE_TRANSPORT_FAILURE(ret); - - auto returnedMemories = NN_TRY(cb.take()); - - if (returnedMemories.size() != unknownSlots.size()) { - return NN_ERROR() << "Burst::MemoryCache::ensureCacheEntriesArePresentLocked: Error " - "retrieving memories -- count mismatch between requested memories (" - << unknownSlots.size() << ") and returned memories (" - << returnedMemories.size() << ")"; - } - - // add memories to unknown slots - for (size_t i = 0; i < unknownSlots.size(); ++i) { - addCacheEntryLocked(unknownSlots[i], std::move(returnedMemories[i])); - } - - return {}; -} - -nn::GeneralResult> -Burst::MemoryCache::getCacheEntryLocked(int32_t slot) { - if (const auto iter = mCache.find(slot); iter != mCache.end()) { - return iter->second; - } - return NN_ERROR() << "Burst::MemoryCache::getCacheEntryLocked failed because slot " << slot - << " is not present in the cache"; -} - -void Burst::MemoryCache::addCacheEntryLocked(int32_t slot, nn::SharedMemory memory) { - auto hold = kBurstExecutor->cacheMemory(memory); - mCache.emplace(slot, std::make_pair(std::move(memory), std::move(hold))); -} - -void Burst::MemoryCache::removeCacheEntry(int32_t slot) { - std::lock_guard guard(mMutex); - mCache.erase(slot); -} - -// Burst methods - -nn::GeneralResult> Burst::create( - const sp& callback, - const MQDescriptorSync& requestChannel, - const MQDescriptorSync& resultChannel, nn::SharedBurst burstExecutor, - std::chrono::microseconds pollingTimeWindow) { - // check inputs - if (callback == nullptr || burstExecutor == nullptr) { - return NN_ERROR() << "Burst::create passed a nullptr"; - } - - // create FMQ objects - auto requestChannelReceiver = - NN_TRY(V1_2::utils::RequestChannelReceiver::create(requestChannel, pollingTimeWindow)); - auto resultChannelSender = NN_TRY(V1_2::utils::ResultChannelSender::create(resultChannel)); - - // check FMQ objects - CHECK(requestChannelReceiver != nullptr); - CHECK(resultChannelSender != nullptr); - - // make and return context - return sp::make(PrivateConstructorTag{}, callback, std::move(requestChannelReceiver), - std::move(resultChannelSender), std::move(burstExecutor)); -} - -Burst::Burst(PrivateConstructorTag /*tag*/, const sp& callback, - std::unique_ptr requestChannel, - std::unique_ptr resultChannel, - nn::SharedBurst burstExecutor) - : mCallback(callback), - mRequestChannelReceiver(std::move(requestChannel)), - mResultChannelSender(std::move(resultChannel)), - mBurstExecutor(std::move(burstExecutor)), - mMemoryCache(mBurstExecutor, mCallback) { - // TODO: highly document the threading behavior of this class - mWorker = std::thread([this] { task(); }); -} - -Burst::~Burst() { - // set teardown flag - mTeardown = true; - mRequestChannelReceiver->invalidate(); - - // wait for task thread to end - mWorker.join(); -} - -Return Burst::freeMemory(int32_t slot) { - mMemoryCache.removeCacheEntry(slot); - return Void(); -} - -void Burst::task() { - // loop until the burst object is being destroyed - while (!mTeardown) { - // receive request - auto arguments = mRequestChannelReceiver->getBlocking(); - - // if the request packet was not properly received, return a generic error and skip the - // execution - // - // if the burst is being torn down, skip the execution so the "task" function can end - if (!arguments.has_value()) { - if (!mTeardown) { - mResultChannelSender->send(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kTiming); - } - continue; - } - - // unpack the arguments; types are Request, std::vector, and V1_2::MeasureTiming, - // respectively - const auto [requestWithoutPools, slotsOfPools, measure] = std::move(arguments).value(); - - auto result = execute(requestWithoutPools, slotsOfPools, measure); - - // return result - if (result.has_value()) { - const auto& [outputShapes, timing] = result.value(); - mResultChannelSender->send(V1_0::ErrorStatus::NONE, outputShapes, timing); - } else { - const auto& [message, code, outputShapes] = result.error(); - LOG(ERROR) << "IBurst::execute failed with " << code << ": " << message; - mResultChannelSender->send(V1_2::utils::convert(code).value(), - V1_2::utils::convert(outputShapes).value(), kTiming); - } - } -} - -nn::ExecutionResult, V1_2::Timing>> Burst::execute( - const V1_0::Request& requestWithoutPools, const std::vector& slotsOfPools, - V1_2::MeasureTiming measure) { - NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, - "Burst getting memory, executing, and returning results"); - - // ensure executor with cache has required memory - const auto cacheEntries = NN_TRY(mMemoryCache.getCacheEntries(slotsOfPools)); - - // convert request, populating its pools - // This code performs an unvalidated convert because the request object without its pools is - // invalid because it is incomplete. Instead, the validation is performed after the memory pools - // have been added to the request. - auto canonicalRequest = NN_TRY(nn::unvalidatedConvert(requestWithoutPools)); - CHECK(canonicalRequest.pools.empty()); - std::transform(cacheEntries.begin(), cacheEntries.end(), - std::back_inserter(canonicalRequest.pools), - [](const auto& cacheEntry) { return cacheEntry.first; }); - NN_TRY(validate(canonicalRequest)); - - nn::MeasureTiming canonicalMeasure = NN_TRY(nn::convert(measure)); - - const auto [outputShapes, timing] = - NN_TRY(mBurstExecutor->execute(canonicalRequest, canonicalMeasure, {}, {})); - - return std::make_pair(NN_TRY(V1_2::utils::convert(outputShapes)), - NN_TRY(V1_2::utils::convert(timing))); -} - -} // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/src/Device.cpp b/neuralnetworks/utils/adapter/src/Device.cpp deleted file mode 100644 index 96142c3577..0000000000 --- a/neuralnetworks/utils/adapter/src/Device.cpp +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Device.h" - -#include "Buffer.h" -#include "PreparedModel.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface -// lifetimes across processes and for protecting asynchronous calls across HIDL. - -namespace android::hardware::neuralnetworks::adapter { -namespace { - -template -auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { - auto result = nn::convert(object); - if (!result.has_value()) { - result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; - } - return result; -} - -using PrepareModelResult = nn::GeneralResult; - -sp adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, - uid_t userId) { - if (preparedModel == nullptr) { - return nullptr; - } - return sp::make(std::move(preparedModel), std::move(executor), userId); -} - -void notify(V1_0::IPreparedModelCallback* callback, nn::ErrorStatus status, - const sp& hidlPreparedModel) { - if (callback != nullptr) { - const auto hidlStatus = V1_0::utils::convert(status).value(); - const auto ret = callback->notify(hidlStatus, hidlPreparedModel); - if (!ret.isOk()) { - LOG(ERROR) << "V1_0::IPreparedModelCallback::notify failed with " << ret.description(); - } - } -} - -void notify(V1_2::IPreparedModelCallback* callback, nn::ErrorStatus status, - const sp& hidlPreparedModel) { - if (callback != nullptr) { - const auto hidlStatus = V1_2::utils::convert(status).value(); - const auto ret = callback->notify_1_2(hidlStatus, hidlPreparedModel); - if (!ret.isOk()) { - LOG(ERROR) << "V1_2::IPreparedModelCallback::notify_1_2 failed with " - << ret.description(); - } - } -} - -void notify(V1_3::IPreparedModelCallback* callback, nn::ErrorStatus status, - const sp& hidlPreparedModel) { - if (callback != nullptr) { - const auto hidlStatus = V1_3::utils::convert(status).value(); - const auto ret = callback->notify_1_3(hidlStatus, hidlPreparedModel); - if (!ret.isOk()) { - LOG(ERROR) << "V1_3::IPreparedModelCallback::notify_1_3 failed with " - << ret.description(); - } - } -} - -template -void notify(CallbackType* callback, PrepareModelResult result, Executor executor, uid_t userId) { - if (!result.has_value()) { - const auto [message, status] = std::move(result).error(); - LOG(ERROR) << message; - notify(callback, status, nullptr); - } else { - auto preparedModel = std::move(result).value(); - auto hidlPreparedModel = - adaptPreparedModel(std::move(preparedModel), std::move(executor), userId); - notify(callback, nn::ErrorStatus::NONE, std::move(hidlPreparedModel)); - } -} - -template -nn::GeneralResult> getSupportedOperations(const nn::SharedDevice& device, - const ModelType& model) { - const auto nnModel = NN_TRY(convertInput(model)); - return NN_TRY(device->getSupportedOperations(nnModel)); -} - -nn::GeneralResult prepareModel(const nn::SharedDevice& device, const Executor& executor, - const V1_0::Model& model, - const sp& callback) { - if (callback.get() == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; - } - - auto nnModel = NN_TRY(convertInput(model)); - - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - Task task = [device, nnModel = std::move(nnModel), userId, executor, callback] { - auto result = device->prepareModel(nnModel, nn::ExecutionPreference::DEFAULT, - nn::Priority::DEFAULT, {}, {}, {}, {}); - notify(callback.get(), std::move(result), executor, userId); - }; - executor(std::move(task), userId, {}); - - return {}; -} - -nn::GeneralResult prepareModel_1_1(const nn::SharedDevice& device, const Executor& executor, - const V1_1::Model& model, - V1_1::ExecutionPreference preference, - const sp& callback) { - if (callback.get() == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; - } - - auto nnModel = NN_TRY(convertInput(model)); - const auto nnPreference = NN_TRY(convertInput(preference)); - - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - Task task = [device, nnModel = std::move(nnModel), nnPreference, userId, executor, callback] { - auto result = - device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, {}, {}, {}); - notify(callback.get(), std::move(result), executor, userId); - }; - executor(std::move(task), userId, {}); - - return {}; -} - -nn::GeneralResult prepareModel_1_2(const nn::SharedDevice& device, const Executor& executor, - const V1_2::Model& model, - V1_1::ExecutionPreference preference, - const hidl_vec& modelCache, - const hidl_vec& dataCache, - const CacheToken& token, - const sp& callback) { - if (callback.get() == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; - } - - auto nnModel = NN_TRY(convertInput(model)); - const auto nnPreference = NN_TRY(convertInput(preference)); - auto nnModelCache = NN_TRY(convertInput(modelCache)); - auto nnDataCache = NN_TRY(convertInput(dataCache)); - const auto nnToken = nn::CacheToken(token); - - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - Task task = [device, nnModel = std::move(nnModel), nnPreference, - nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), - nnToken, userId, executor, callback] { - auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, - nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); - }; - executor(std::move(task), userId, {}); - - return {}; -} - -nn::GeneralResult prepareModel_1_3( - const nn::SharedDevice& device, const Executor& executor, const V1_3::Model& model, - V1_1::ExecutionPreference preference, V1_3::Priority priority, - const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, - const hidl_vec& dataCache, const CacheToken& token, - const sp& callback) { - if (callback.get() == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; - } - - auto nnModel = NN_TRY(convertInput(model)); - const auto nnPreference = NN_TRY(convertInput(preference)); - const auto nnPriority = NN_TRY(convertInput(priority)); - const auto nnDeadline = NN_TRY(convertInput(deadline)); - auto nnModelCache = NN_TRY(convertInput(modelCache)); - auto nnDataCache = NN_TRY(convertInput(dataCache)); - const auto nnToken = nn::CacheToken(token); - - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline, - nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), - nnToken, userId, executor, callback] { - auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline, - nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); - }; - executor(std::move(task), userId, nnDeadline); - - return {}; -} - -nn::GeneralResult prepareModelFromCache(const nn::SharedDevice& device, - const Executor& executor, - const hidl_vec& modelCache, - const hidl_vec& dataCache, - const CacheToken& token, - const sp& callback) { - if (callback.get() == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; - } - - auto nnModelCache = NN_TRY(convertInput(modelCache)); - auto nnDataCache = NN_TRY(convertInput(dataCache)); - const auto nnToken = nn::CacheToken(token); - - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - Task task = [device, nnModelCache = std::move(nnModelCache), - nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] { - auto result = device->prepareModelFromCache({}, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); - }; - executor(std::move(task), userId, {}); - - return {}; -} - -nn::GeneralResult prepareModelFromCache_1_3( - const nn::SharedDevice& device, const Executor& executor, - const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, - const hidl_vec& dataCache, const CacheToken& token, - const sp& callback) { - if (callback.get() == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; - } - - const auto nnDeadline = NN_TRY(convertInput(deadline)); - auto nnModelCache = NN_TRY(convertInput(modelCache)); - auto nnDataCache = NN_TRY(convertInput(dataCache)); - const auto nnToken = nn::CacheToken(token); - - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache), - nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] { - auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); - }; - executor(std::move(task), userId, nnDeadline); - - return {}; -} - -nn::GeneralResult downcast(const sp& preparedModel) { - if (preparedModel == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "preparedModel is nullptr"; - } - if (preparedModel->isRemote()) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Cannot convert remote models"; - } - - // This static_cast is safe because adapter::PreparedModel is the only class that implements - // the IPreparedModel interface in the adapter service code. - const auto* casted = static_cast(preparedModel.get()); - return casted->getUnderlyingPreparedModel(); -} - -nn::GeneralResult> downcastAll( - const hidl_vec>& preparedModels) { - std::vector canonical; - canonical.reserve(preparedModels.size()); - for (const auto& preparedModel : preparedModels) { - canonical.push_back(NN_TRY(downcast(preparedModel))); - } - return canonical; -} - -nn::GeneralResult, uint32_t>> allocate( - const nn::SharedDevice& device, const V1_3::BufferDesc& desc, - const hidl_vec>& preparedModels, - const hidl_vec& inputRoles, - const hidl_vec& outputRoles) { - auto nnDesc = NN_TRY(convertInput(desc)); - auto nnPreparedModels = NN_TRY(downcastAll(preparedModels)); - auto nnInputRoles = NN_TRY(convertInput(inputRoles)); - auto nnOutputRoles = NN_TRY(convertInput(outputRoles)); - - auto buffer = NN_TRY(device->allocate(nnDesc, nnPreparedModels, nnInputRoles, nnOutputRoles)); - - const nn::Request::MemoryDomainToken token = buffer->getToken(); - auto hidlBuffer = sp::make(std::move(buffer)); - return std::make_pair(std::move(hidlBuffer), static_cast(token)); -} - -} // namespace - -Device::Device(nn::SharedDevice device, Executor executor) - : kDevice(std::move(device)), kExecutor(std::move(executor)) { - CHECK(kDevice != nullptr); - CHECK(kExecutor != nullptr); -} - -Return Device::getCapabilities(getCapabilities_cb cb) { - const auto capabilities = V1_0::utils::convert(kDevice->getCapabilities()).value(); - cb(V1_0::ErrorStatus::NONE, capabilities); - return Void(); -} - -Return Device::getCapabilities_1_1(getCapabilities_1_1_cb cb) { - const auto capabilities = V1_1::utils::convert(kDevice->getCapabilities()).value(); - cb(V1_0::ErrorStatus::NONE, capabilities); - return Void(); -} - -Return Device::getCapabilities_1_2(getCapabilities_1_2_cb cb) { - const auto capabilities = V1_2::utils::convert(kDevice->getCapabilities()).value(); - cb(V1_0::ErrorStatus::NONE, capabilities); - return Void(); -} - -Return Device::getCapabilities_1_3(getCapabilities_1_3_cb cb) { - const auto capabilities = V1_3::utils::convert(kDevice->getCapabilities()).value(); - cb(V1_3::ErrorStatus::NONE, capabilities); - return Void(); -} - -Return Device::getVersionString(getVersionString_cb cb) { - cb(V1_0::ErrorStatus::NONE, kDevice->getVersionString()); - return Void(); -} - -Return Device::getType(getType_cb cb) { - const auto maybeDeviceType = V1_2::utils::convert(kDevice->getType()); - if (!maybeDeviceType.has_value()) { - const auto& [message, code] = maybeDeviceType.error(); - LOG(ERROR) << "adapter::Device::getType failed with " << code << ": " << message; - cb(V1_2::utils::convert(code).value(), {}); - } else { - cb(V1_0::ErrorStatus::NONE, maybeDeviceType.value()); - } - return Void(); -} - -Return Device::getSupportedExtensions(getSupportedExtensions_cb cb) { - const auto maybeSupportedExtensions = V1_2::utils::convert(kDevice->getSupportedExtensions()); - if (!maybeSupportedExtensions.has_value()) { - const auto& [message, code] = maybeSupportedExtensions.error(); - LOG(ERROR) << "adapter::Device::getSupportedExtensions failed with " << code << ": " - << message; - cb(V1_2::utils::convert(code).value(), {}); - } else { - cb(V1_0::ErrorStatus::NONE, maybeSupportedExtensions.value()); - } - return Void(); -} - -Return Device::getSupportedOperations(const V1_0::Model& model, - getSupportedOperations_cb cb) { - const auto result = adapter::getSupportedOperations(kDevice, model); - if (!result.has_value()) { - const auto& [message, code] = result.error(); - LOG(ERROR) << "adapter::Device::getSupportedOperations_1_0 failed with " << code << ": " - << message; - cb(V1_0::utils::convert(code).value(), {}); - } else { - cb(V1_0::ErrorStatus::NONE, result.value()); - } - return Void(); -} - -Return Device::getSupportedOperations_1_1(const V1_1::Model& model, - getSupportedOperations_1_1_cb cb) { - const auto result = adapter::getSupportedOperations(kDevice, model); - if (!result.has_value()) { - const auto& [message, code] = result.error(); - LOG(ERROR) << "adapter::Device::getSupportedOperations_1_1 failed with " << code << ": " - << message; - cb(V1_1::utils::convert(code).value(), {}); - } else { - cb(V1_0::ErrorStatus::NONE, result.value()); - } - return Void(); -} - -Return Device::getSupportedOperations_1_2(const V1_2::Model& model, - getSupportedOperations_1_2_cb cb) { - const auto result = adapter::getSupportedOperations(kDevice, model); - if (!result.has_value()) { - const auto& [message, code] = result.error(); - LOG(ERROR) << "adapter::Device::getSupportedOperations_1_2 failed with " << code << ": " - << message; - cb(V1_2::utils::convert(code).value(), {}); - } else { - cb(V1_0::ErrorStatus::NONE, result.value()); - } - return Void(); -} - -Return Device::getSupportedOperations_1_3(const V1_3::Model& model, - getSupportedOperations_1_3_cb cb) { - const auto result = adapter::getSupportedOperations(kDevice, model); - if (!result.has_value()) { - const auto& [message, code] = result.error(); - LOG(ERROR) << "adapter::Device::getSupportedOperations_1_3 failed with " << code << ": " - << message; - cb(V1_3::utils::convert(code).value(), {}); - } else { - cb(V1_3::ErrorStatus::NONE, result.value()); - } - return Void(); -} - -Return Device::getNumberOfCacheFilesNeeded(getNumberOfCacheFilesNeeded_cb cb) { - const auto [numModelCache, numDataCache] = kDevice->getNumberOfCacheFilesNeeded(); - cb(V1_0::ErrorStatus::NONE, numModelCache, numDataCache); - return Void(); -} - -Return Device::prepareModel(const V1_0::Model& model, - const sp& callback) { - auto result = adapter::prepareModel(kDevice, kExecutor, model, callback); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::Device::prepareModel failed with " << code << ": " << message; - notify(callback.get(), code, nullptr); - return V1_0::utils::convert(code).value(); - } - return V1_0::ErrorStatus::NONE; -} - -Return Device::prepareModel_1_1( - const V1_1::Model& model, V1_1::ExecutionPreference preference, - const sp& callback) { - auto result = adapter::prepareModel_1_1(kDevice, kExecutor, model, preference, callback); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::Device::prepareModel_1_1 failed with " << code << ": " << message; - notify(callback.get(), code, nullptr); - return V1_1::utils::convert(code).value(); - } - return V1_0::ErrorStatus::NONE; -} - -Return Device::prepareModel_1_2( - const V1_2::Model& model, V1_1::ExecutionPreference preference, - const hidl_vec& modelCache, const hidl_vec& dataCache, - const CacheToken& token, const sp& callback) { - auto result = adapter::prepareModel_1_2(kDevice, kExecutor, model, preference, modelCache, - dataCache, token, callback); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::Device::prepareModel_1_2 failed with " << code << ": " << message; - notify(callback.get(), code, nullptr); - return V1_2::utils::convert(code).value(); - } - return V1_0::ErrorStatus::NONE; -} - -Return Device::prepareModel_1_3( - const V1_3::Model& model, V1_1::ExecutionPreference preference, V1_3::Priority priority, - const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, - const hidl_vec& dataCache, const CacheToken& token, - const sp& callback) { - auto result = adapter::prepareModel_1_3(kDevice, kExecutor, model, preference, priority, - deadline, modelCache, dataCache, token, callback); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::Device::prepareModel_1_3 failed with " << code << ": " << message; - notify(callback.get(), code, nullptr); - return V1_3::utils::convert(code).value(); - } - return V1_3::ErrorStatus::NONE; -} - -Return Device::prepareModelFromCache( - const hidl_vec& modelCache, const hidl_vec& dataCache, - const CacheToken& token, const sp& callback) { - auto result = adapter::prepareModelFromCache(kDevice, kExecutor, modelCache, dataCache, token, - callback); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::Device::prepareModelFromCache failed with " << code << ": " - << message; - notify(callback.get(), code, nullptr); - return V1_2::utils::convert(code).value(); - } - return V1_0::ErrorStatus::NONE; -} - -Return Device::prepareModelFromCache_1_3( - const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, - const hidl_vec& dataCache, const CacheToken& token, - const sp& callback) { - auto result = adapter::prepareModelFromCache_1_3(kDevice, kExecutor, deadline, modelCache, - dataCache, token, callback); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::Device::prepareModelFromCache_1_3 failed with " << code << ": " - << message; - notify(callback.get(), code, nullptr); - return V1_3::utils::convert(code).value(); - } - return V1_3::ErrorStatus::NONE; -} - -Return Device::getStatus() { - return V1_0::DeviceStatus::AVAILABLE; -} - -Return Device::allocate(const V1_3::BufferDesc& desc, - const hidl_vec>& preparedModels, - const hidl_vec& inputRoles, - const hidl_vec& outputRoles, allocate_cb cb) { - auto result = adapter::allocate(kDevice, desc, preparedModels, inputRoles, outputRoles); - if (!result.has_value()) { - const auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::Device::allocate failed with " << code << ": " << message; - cb(V1_3::utils::convert(code).value(), nullptr, /*token=*/0); - return Void(); - } - auto [buffer, token] = std::move(result).value(); - cb(V1_3::ErrorStatus::NONE, buffer, token); - return Void(); -} - -} // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/src/PreparedModel.cpp deleted file mode 100644 index a14e782b9b..0000000000 --- a/neuralnetworks/utils/adapter/src/PreparedModel.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "PreparedModel.h" - -#include "Burst.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface -// lifetimes across processes and for protecting asynchronous calls across HIDL. - -namespace android::hardware::neuralnetworks::adapter { -namespace { - -template -auto convertInput(const Type& object) -> decltype(nn::convert(std::declval())) { - auto result = nn::convert(object); - if (!result.has_value()) { - result.error().code = nn::ErrorStatus::INVALID_ARGUMENT; - } - return result; -} - -nn::GeneralResult validateRequestForModel(const nn::Request& request, - const nn::Model& model) { - nn::GeneralResult version = nn::validateRequestForModel(request, model); - if (!version.ok()) { - version.error().code = nn::ErrorStatus::INVALID_ARGUMENT; - } - return version; -} - -class FencedExecutionCallback final : public V1_3::IFencedExecutionCallback { - public: - explicit FencedExecutionCallback(const nn::ExecuteFencedInfoCallback& callback) - : kCallback(callback) { - CHECK(callback != nullptr); - } - - Return getExecutionInfo(getExecutionInfo_cb cb) override { - const auto result = kCallback(); - if (!result.has_value()) { - const auto& [message, code] = result.error(); - const auto status = - V1_3::utils::convert(code).value_or(V1_3::ErrorStatus::GENERAL_FAILURE); - LOG(ERROR) << message; - cb(status, V1_2::utils::kNoTiming, V1_2::utils::kNoTiming); - return Void(); - } - const auto [timingLaunched, timingFenced] = result.value(); - const auto hidlTimingLaunched = V1_3::utils::convert(timingLaunched).value(); - const auto hidlTimingFenced = V1_3::utils::convert(timingFenced).value(); - cb(V1_3::ErrorStatus::NONE, hidlTimingLaunched, hidlTimingFenced); - return Void(); - } - - private: - const nn::ExecuteFencedInfoCallback kCallback; -}; - -using ExecutionResult = nn::ExecutionResult, nn::Timing>>; - -void notify(V1_0::IExecutionCallback* callback, nn::ErrorStatus status, - const std::vector& /*outputShapes*/, const nn::Timing& /*timing*/) { - if (callback != nullptr) { - const auto hidlStatus = V1_0::utils::convert(status).value(); - const auto ret = callback->notify(hidlStatus); - if (!ret.isOk()) { - LOG(ERROR) << "V1_0::IExecutionCallback::notify failed with " << ret.description(); - } - } -} - -void notify(V1_2::IExecutionCallback* callback, nn::ErrorStatus status, - const std::vector& outputShapes, const nn::Timing& timing) { - if (callback != nullptr) { - const auto hidlStatus = V1_2::utils::convert(status).value(); - const auto hidlOutputShapes = V1_2::utils::convert(outputShapes).value(); - const auto hidlTiming = V1_2::utils::convert(timing).value(); - const auto ret = callback->notify_1_2(hidlStatus, hidlOutputShapes, hidlTiming); - if (!ret.isOk()) { - LOG(ERROR) << "V1_2::IExecutionCallback::notify_1_2 failed with " << ret.description(); - } - } -} - -void notify(V1_3::IExecutionCallback* callback, nn::ErrorStatus status, - const std::vector& outputShapes, const nn::Timing& timing) { - if (callback != nullptr) { - const auto hidlStatus = V1_3::utils::convert(status).value(); - const auto hidlOutputShapes = V1_3::utils::convert(outputShapes).value(); - const auto hidlTiming = V1_3::utils::convert(timing).value(); - const auto ret = callback->notify_1_3(hidlStatus, hidlOutputShapes, hidlTiming); - if (!ret.isOk()) { - LOG(ERROR) << "V1_3::IExecutionCallback::notify_1_3 failed with " << ret.description(); - } - } -} - -template -void notify(CallbackType* callback, ExecutionResult result) { - if (!result.has_value()) { - const auto [message, status, outputShapes] = std::move(result).error(); - LOG(ERROR) << message; - notify(callback, status, outputShapes, {}); - } else { - const auto [outputShapes, timing] = std::move(result).value(); - notify(callback, nn::ErrorStatus::NONE, outputShapes, timing); - } -} - -nn::GeneralResult execute(const nn::SharedPreparedModel& preparedModel, uid_t userId, - const Executor& executor, const V1_0::Request& request, - const sp& callback) { - if (callback.get() == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; - } - - auto nnRequest = NN_TRY(convertInput(request)); - - const std::any resource = preparedModel->getUnderlyingResource(); - if (const auto* model = std::any_cast(&resource)) { - CHECK(*model != nullptr); - NN_TRY(adapter::validateRequestForModel(nnRequest, **model)); - } - - Task task = [preparedModel, nnRequest = std::move(nnRequest), callback] { - auto result = preparedModel->execute(nnRequest, nn::MeasureTiming::NO, {}, {}); - notify(callback.get(), std::move(result)); - }; - executor(std::move(task), userId, {}); - - return {}; -} - -nn::GeneralResult execute_1_2(const nn::SharedPreparedModel& preparedModel, uid_t userId, - const Executor& executor, const V1_0::Request& request, - V1_2::MeasureTiming measure, - const sp& callback) { - if (callback.get() == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; - } - - auto nnRequest = NN_TRY(convertInput(request)); - const auto nnMeasure = NN_TRY(convertInput(measure)); - - const std::any resource = preparedModel->getUnderlyingResource(); - if (const auto* model = std::any_cast(&resource)) { - CHECK(*model != nullptr); - NN_TRY(adapter::validateRequestForModel(nnRequest, **model)); - } - - Task task = [preparedModel, nnRequest = std::move(nnRequest), nnMeasure, callback] { - auto result = preparedModel->execute(nnRequest, nnMeasure, {}, {}); - notify(callback.get(), std::move(result)); - }; - executor(std::move(task), userId, {}); - - return {}; -} - -nn::GeneralResult execute_1_3(const nn::SharedPreparedModel& preparedModel, uid_t userId, - const Executor& executor, const V1_3::Request& request, - V1_2::MeasureTiming measure, - const V1_3::OptionalTimePoint& deadline, - const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, - const sp& callback) { - if (callback.get() == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback"; - } - - auto nnRequest = NN_TRY(convertInput(request)); - const auto nnMeasure = NN_TRY(convertInput(measure)); - const auto nnDeadline = NN_TRY(convertInput(deadline)); - const auto nnLoopTimeoutDuration = NN_TRY(convertInput(loopTimeoutDuration)); - - const std::any resource = preparedModel->getUnderlyingResource(); - if (const auto* model = std::any_cast(&resource)) { - CHECK(*model != nullptr); - NN_TRY(adapter::validateRequestForModel(nnRequest, **model)); - } - - Task task = [preparedModel, nnRequest = std::move(nnRequest), nnMeasure, nnDeadline, - nnLoopTimeoutDuration, callback] { - auto result = - preparedModel->execute(nnRequest, nnMeasure, nnDeadline, nnLoopTimeoutDuration); - notify(callback.get(), std::move(result)); - }; - executor(std::move(task), userId, nnDeadline); - - return {}; -} - -nn::ExecutionResult, V1_2::Timing>> executeSynchronously( - const nn::SharedPreparedModel& preparedModel, const V1_0::Request& request, - V1_2::MeasureTiming measure) { - const auto nnRequest = NN_TRY(convertInput(request)); - const auto nnMeasure = NN_TRY(convertInput(measure)); - - const auto [outputShapes, timing] = - NN_TRY(preparedModel->execute(nnRequest, nnMeasure, {}, {})); - - auto hidlOutputShapes = NN_TRY(V1_2::utils::convert(outputShapes)); - const auto hidlTiming = NN_TRY(V1_2::utils::convert(timing)); - return std::make_pair(std::move(hidlOutputShapes), hidlTiming); -} - -nn::ExecutionResult, V1_2::Timing>> executeSynchronously_1_3( - const nn::SharedPreparedModel& preparedModel, const V1_3::Request& request, - V1_2::MeasureTiming measure, const V1_3::OptionalTimePoint& deadline, - const V1_3::OptionalTimeoutDuration& loopTimeoutDuration) { - const auto nnRequest = NN_TRY(convertInput(request)); - const auto nnMeasure = NN_TRY(convertInput(measure)); - const auto nnDeadline = NN_TRY(convertInput(deadline)); - const auto nnLoopTimeoutDuration = NN_TRY(convertInput(loopTimeoutDuration)); - - const auto [outputShapes, timing] = - NN_TRY(preparedModel->execute(nnRequest, nnMeasure, nnDeadline, nnLoopTimeoutDuration)); - - auto hidlOutputShapes = NN_TRY(V1_3::utils::convert(outputShapes)); - const auto hidlTiming = NN_TRY(V1_3::utils::convert(timing)); - return std::make_pair(std::move(hidlOutputShapes), hidlTiming); -} - -nn::GeneralResult> convertSyncFences( - const hidl_vec& handles) { - auto nnHandles = NN_TRY(convertInput(handles)); - std::vector syncFences; - syncFences.reserve(handles.size()); - for (auto&& handle : nnHandles) { - if (auto syncFence = nn::SyncFence::create(std::move(handle)); !syncFence.ok()) { - return nn::error(nn::ErrorStatus::INVALID_ARGUMENT) << std::move(syncFence).error(); - } else { - syncFences.push_back(std::move(syncFence).value()); - } - } - return syncFences; -} - -nn::GeneralResult> configureExecutionBurst( - const nn::SharedPreparedModel& preparedModel, const sp& callback, - const MQDescriptorSync& requestChannel, - const MQDescriptorSync& resultChannel) { - auto burstExecutor = NN_TRY(preparedModel->configureExecutionBurst()); - return Burst::create(callback, requestChannel, resultChannel, std::move(burstExecutor), - V1_2::utils::getBurstServerPollingTimeWindow()); -} - -nn::GeneralResult>> executeFenced( - const nn::SharedPreparedModel& preparedModel, const V1_3::Request& request, - const hidl_vec& waitFor, V1_2::MeasureTiming measure, - const V1_3::OptionalTimePoint& deadline, - const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, - const V1_3::OptionalTimeoutDuration& duration) { - const auto nnRequest = NN_TRY(convertInput(request)); - const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor)); - const auto nnMeasure = NN_TRY(convertInput(measure)); - const auto nnDeadline = NN_TRY(convertInput(deadline)); - const auto nnLoopTimeoutDuration = NN_TRY(convertInput(loopTimeoutDuration)); - const auto nnDuration = NN_TRY(convertInput(duration)); - - auto [syncFence, executeFencedCallback] = NN_TRY(preparedModel->executeFenced( - nnRequest, nnWaitFor, nnMeasure, nnDeadline, nnLoopTimeoutDuration, nnDuration)); - - auto hidlSyncFence = NN_TRY(V1_3::utils::convert(syncFence.getSharedHandle())); - auto hidlExecuteFencedCallback = sp::make(executeFencedCallback); - return std::make_pair(std::move(hidlSyncFence), std::move(hidlExecuteFencedCallback)); -} - -} // namespace - -PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId) - : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)), kUserId(userId) { - CHECK(kPreparedModel != nullptr); - CHECK(kExecutor != nullptr); -} - -nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const { - return kPreparedModel; -} - -Return PreparedModel::execute(const V1_0::Request& request, - const sp& callback) { - auto result = adapter::execute(kPreparedModel, kUserId, kExecutor, request, callback); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::PreparedModel::execute failed with " << code << ": " << message; - notify(callback.get(), code, {}, {}); - return V1_0::utils::convert(code).value(); - } - return V1_0::ErrorStatus::NONE; -} - -Return PreparedModel::execute_1_2(const V1_0::Request& request, - V1_2::MeasureTiming measure, - const sp& callback) { - auto result = - adapter::execute_1_2(kPreparedModel, kUserId, kExecutor, request, measure, callback); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::PreparedModel::execute_1_2 failed with " << code << ": " << message; - notify(callback.get(), code, {}, {}); - return V1_2::utils::convert(code).value(); - } - return V1_0::ErrorStatus::NONE; -} - -Return PreparedModel::execute_1_3( - const V1_3::Request& request, V1_2::MeasureTiming measure, - const V1_3::OptionalTimePoint& deadline, - const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, - const sp& callback) { - auto result = adapter::execute_1_3(kPreparedModel, kUserId, kExecutor, request, measure, - deadline, loopTimeoutDuration, callback); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::PreparedModel::execute_1_3 failed with " << code << ": " << message; - notify(callback.get(), code, {}, {}); - return V1_3::utils::convert(code).value(); - } - return V1_3::ErrorStatus::NONE; -} - -Return PreparedModel::executeSynchronously(const V1_0::Request& request, - V1_2::MeasureTiming measure, - executeSynchronously_cb cb) { - auto result = adapter::executeSynchronously(kPreparedModel, request, measure); - if (!result.has_value()) { - auto [message, code, outputShapes] = std::move(result).error(); - LOG(ERROR) << "adapter::PreparedModel::executeSynchronously failed with " << code << ": " - << message; - cb(V1_2::utils::convert(code).value(), V1_2::utils::convert(outputShapes).value(), - V1_2::utils::kNoTiming); - return Void(); - } - auto [outputShapes, timing] = std::move(result).value(); - cb(V1_0::ErrorStatus::NONE, outputShapes, timing); - return Void(); -} - -Return PreparedModel::executeSynchronously_1_3( - const V1_3::Request& request, V1_2::MeasureTiming measure, - const V1_3::OptionalTimePoint& deadline, - const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, executeSynchronously_1_3_cb cb) { - auto result = adapter::executeSynchronously_1_3(kPreparedModel, request, measure, deadline, - loopTimeoutDuration); - if (!result.has_value()) { - auto [message, code, outputShapes] = std::move(result).error(); - LOG(ERROR) << "adapter::PreparedModel::executeSynchronously_1_3 failed with " << code - << ": " << message; - cb(V1_3::utils::convert(code).value(), V1_3::utils::convert(outputShapes).value(), - V1_2::utils::kNoTiming); - return Void(); - } - auto [outputShapes, timing] = std::move(result).value(); - cb(V1_3::ErrorStatus::NONE, outputShapes, timing); - return Void(); -} - -Return PreparedModel::configureExecutionBurst( - const sp& callback, - const MQDescriptorSync& requestChannel, - const MQDescriptorSync& resultChannel, - configureExecutionBurst_cb cb) { - auto result = adapter::configureExecutionBurst(kPreparedModel, callback, requestChannel, - resultChannel); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::PreparedModel::configureExecutionBurst failed with " << code << ": " - << message; - cb(V1_2::utils::convert(code).value(), nullptr); - return Void(); - } - auto burstContext = std::move(result).value(); - cb(V1_0::ErrorStatus::NONE, std::move(burstContext)); - return Void(); -} - -Return PreparedModel::executeFenced(const V1_3::Request& request, - const hidl_vec& waitFor, - V1_2::MeasureTiming measure, - const V1_3::OptionalTimePoint& deadline, - const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, - const V1_3::OptionalTimeoutDuration& duration, - executeFenced_cb callback) { - auto result = adapter::executeFenced(kPreparedModel, request, waitFor, measure, deadline, - loopTimeoutDuration, duration); - if (!result.has_value()) { - auto [message, code] = std::move(result).error(); - LOG(ERROR) << "adapter::PreparedModel::executeFenced failed with " << code << ": " - << message; - callback(V1_3::utils::convert(code).value(), {}, nullptr); - return Void(); - } - auto [syncFence, executeFencedCallback] = std::move(result).value(); - callback(V1_3::ErrorStatus::NONE, syncFence, executeFencedCallback); - return Void(); -} - -} // namespace android::hardware::neuralnetworks::adapter -- cgit v1.2.3 From becb08fac072a2d5bb18bfaafc61f86e2107fffa Mon Sep 17 00:00:00 2001 From: Changyeon Jo Date: Wed, 12 Jan 2022 06:32:32 +0000 Subject: Update EVS OWNERS Bug: 214143406 Test: Gerrit uploader Change-Id: Ief6351e9609ce11dd85dca815b6833524fead0c7 --- automotive/evs/OWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS index 6fc50248c7..b973e912bf 100644 --- a/automotive/evs/OWNERS +++ b/automotive/evs/OWNERS @@ -1,3 +1,3 @@ +ankitarora@google.com changyeon@google.com -garysungang@google.com -haoxiangl@google.com +jwhpryor@google.com -- cgit v1.2.3 From 594cc78a7b5330210397c004d53e52db9148e297 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Tue, 11 Jan 2022 22:53:49 -0800 Subject: Remove uid from NN HIDL adapter Having the adapter retrieve the uid is redundant because the implementor is already able to get the uid directly themselves with IPCThreadState::self()->getCallingUid(). Bug: N/A Test: mma Change-Id: Ifeffea053cb92556be1aae8b17a94fafa1ac98e0 --- .../utils/adapter/hidl/include/nnapi/hal/Adapter.h | 9 ++-- .../adapter/hidl/include/nnapi/hal/PreparedModel.h | 3 +- neuralnetworks/utils/adapter/hidl/src/Adapter.cpp | 3 +- neuralnetworks/utils/adapter/hidl/src/Device.cpp | 54 +++++++++------------- .../utils/adapter/hidl/src/PreparedModel.cpp | 27 +++++------ 5 files changed, 41 insertions(+), 55 deletions(-) diff --git a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h index da00a090ed..6fba4abe7d 100644 --- a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -37,10 +36,12 @@ using Task = std::function; /** * A type-erased executor which executes a task asynchronously. * - * This executor is also provided with an Application ID (Android User ID) and an optional deadline - * for when the caller expects is the upper bound for the amount of time to complete the task. + * This executor is also provided an optional deadline for when the caller expects is the upper + * bound for the amount of time to complete the task. If needed, the Executor can retrieve the + * Application ID (Android User ID) by calling IPCThreadState::self()->getCallingUid() in + * hwbinder/IPCThreadState.h. */ -using Executor = std::function; +using Executor = std::function; /** * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object. diff --git a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h index 65763b8d19..9482b0d512 100644 --- a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h +++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h @@ -39,7 +39,7 @@ namespace android::hardware::neuralnetworks::adapter { // Class that adapts nn::IPreparedModel to V1_3::IPreparedModel. class PreparedModel final : public V1_3::IPreparedModel { public: - PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId); + PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor); Return execute(const V1_0::Request& request, const sp& callback) override; @@ -71,7 +71,6 @@ class PreparedModel final : public V1_3::IPreparedModel { private: const nn::SharedPreparedModel kPreparedModel; const Executor kExecutor; - const uid_t kUserId; }; } // namespace android::hardware::neuralnetworks::adapter diff --git a/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp index d6f53f05a5..782e815a83 100644 --- a/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp +++ b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -37,7 +36,7 @@ sp adapt(nn::SharedDevice device, Executor executor) { } sp adapt(nn::SharedDevice device) { - Executor defaultExecutor = [](Task task, uid_t /*uid*/, nn::OptionalTimePoint /*deadline*/) { + Executor defaultExecutor = [](Task task, nn::OptionalTimePoint /*deadline*/) { std::thread(std::move(task)).detach(); }; return adapt(std::move(device), std::move(defaultExecutor)); diff --git a/neuralnetworks/utils/adapter/hidl/src/Device.cpp b/neuralnetworks/utils/adapter/hidl/src/Device.cpp index 96142c3577..4993a80a93 100644 --- a/neuralnetworks/utils/adapter/hidl/src/Device.cpp +++ b/neuralnetworks/utils/adapter/hidl/src/Device.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -43,7 +42,6 @@ #include #include #include -#include #include @@ -64,12 +62,11 @@ auto convertInput(const Type& object) -> decltype(nn::convert(std::declval using PrepareModelResult = nn::GeneralResult; -sp adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, - uid_t userId) { +sp adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor) { if (preparedModel == nullptr) { return nullptr; } - return sp::make(std::move(preparedModel), std::move(executor), userId); + return sp::make(std::move(preparedModel), std::move(executor)); } void notify(V1_0::IPreparedModelCallback* callback, nn::ErrorStatus status, @@ -108,15 +105,14 @@ void notify(V1_3::IPreparedModelCallback* callback, nn::ErrorStatus status, } template -void notify(CallbackType* callback, PrepareModelResult result, Executor executor, uid_t userId) { +void notify(CallbackType* callback, PrepareModelResult result, Executor executor) { if (!result.has_value()) { const auto [message, status] = std::move(result).error(); LOG(ERROR) << message; notify(callback, status, nullptr); } else { auto preparedModel = std::move(result).value(); - auto hidlPreparedModel = - adaptPreparedModel(std::move(preparedModel), std::move(executor), userId); + auto hidlPreparedModel = adaptPreparedModel(std::move(preparedModel), std::move(executor)); notify(callback, nn::ErrorStatus::NONE, std::move(hidlPreparedModel)); } } @@ -137,13 +133,12 @@ nn::GeneralResult prepareModel(const nn::SharedDevice& device, const Execu auto nnModel = NN_TRY(convertInput(model)); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - Task task = [device, nnModel = std::move(nnModel), userId, executor, callback] { + Task task = [device, nnModel = std::move(nnModel), executor, callback] { auto result = device->prepareModel(nnModel, nn::ExecutionPreference::DEFAULT, nn::Priority::DEFAULT, {}, {}, {}, {}); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } @@ -159,13 +154,12 @@ nn::GeneralResult prepareModel_1_1(const nn::SharedDevice& device, const E auto nnModel = NN_TRY(convertInput(model)); const auto nnPreference = NN_TRY(convertInput(preference)); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); - Task task = [device, nnModel = std::move(nnModel), nnPreference, userId, executor, callback] { + Task task = [device, nnModel = std::move(nnModel), nnPreference, executor, callback] { auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, {}, {}, {}); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } @@ -187,15 +181,14 @@ nn::GeneralResult prepareModel_1_2(const nn::SharedDevice& device, const E auto nnDataCache = NN_TRY(convertInput(dataCache)); const auto nnToken = nn::CacheToken(token); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); Task task = [device, nnModel = std::move(nnModel), nnPreference, nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), - nnToken, userId, executor, callback] { + nnToken, executor, callback] { auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } @@ -218,15 +211,14 @@ nn::GeneralResult prepareModel_1_3( auto nnDataCache = NN_TRY(convertInput(dataCache)); const auto nnToken = nn::CacheToken(token); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline, nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache), - nnToken, userId, executor, callback] { + nnToken, executor, callback] { auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, nnDeadline); + executor(std::move(task), nnDeadline); return {}; } @@ -245,13 +237,12 @@ nn::GeneralResult prepareModelFromCache(const nn::SharedDevice& device, auto nnDataCache = NN_TRY(convertInput(dataCache)); const auto nnToken = nn::CacheToken(token); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); Task task = [device, nnModelCache = std::move(nnModelCache), - nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] { + nnDataCache = std::move(nnDataCache), nnToken, executor, callback] { auto result = device->prepareModelFromCache({}, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } @@ -270,13 +261,12 @@ nn::GeneralResult prepareModelFromCache_1_3( auto nnDataCache = NN_TRY(convertInput(dataCache)); const auto nnToken = nn::CacheToken(token); - const uid_t userId = hardware::IPCThreadState::self()->getCallingUid(); auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache), - nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] { + nnDataCache = std::move(nnDataCache), nnToken, executor, callback] { auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken); - notify(callback.get(), std::move(result), executor, userId); + notify(callback.get(), std::move(result), executor); }; - executor(std::move(task), userId, nnDeadline); + executor(std::move(task), nnDeadline); return {}; } diff --git a/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp index a14e782b9b..71060d5ca7 100644 --- a/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp +++ b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -37,7 +36,6 @@ #include #include #include -#include #include #include @@ -145,7 +143,7 @@ void notify(CallbackType* callback, ExecutionResult result) { } } -nn::GeneralResult execute(const nn::SharedPreparedModel& preparedModel, uid_t userId, +nn::GeneralResult execute(const nn::SharedPreparedModel& preparedModel, const Executor& executor, const V1_0::Request& request, const sp& callback) { if (callback.get() == nullptr) { @@ -164,12 +162,12 @@ nn::GeneralResult execute(const nn::SharedPreparedModel& preparedModel, ui auto result = preparedModel->execute(nnRequest, nn::MeasureTiming::NO, {}, {}); notify(callback.get(), std::move(result)); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } -nn::GeneralResult execute_1_2(const nn::SharedPreparedModel& preparedModel, uid_t userId, +nn::GeneralResult execute_1_2(const nn::SharedPreparedModel& preparedModel, const Executor& executor, const V1_0::Request& request, V1_2::MeasureTiming measure, const sp& callback) { @@ -190,12 +188,12 @@ nn::GeneralResult execute_1_2(const nn::SharedPreparedModel& preparedModel auto result = preparedModel->execute(nnRequest, nnMeasure, {}, {}); notify(callback.get(), std::move(result)); }; - executor(std::move(task), userId, {}); + executor(std::move(task), {}); return {}; } -nn::GeneralResult execute_1_3(const nn::SharedPreparedModel& preparedModel, uid_t userId, +nn::GeneralResult execute_1_3(const nn::SharedPreparedModel& preparedModel, const Executor& executor, const V1_3::Request& request, V1_2::MeasureTiming measure, const V1_3::OptionalTimePoint& deadline, @@ -222,7 +220,7 @@ nn::GeneralResult execute_1_3(const nn::SharedPreparedModel& preparedModel preparedModel->execute(nnRequest, nnMeasure, nnDeadline, nnLoopTimeoutDuration); notify(callback.get(), std::move(result)); }; - executor(std::move(task), userId, nnDeadline); + executor(std::move(task), nnDeadline); return {}; } @@ -305,8 +303,8 @@ nn::GeneralResult>> ex } // namespace -PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId) - : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)), kUserId(userId) { +PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor) + : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)) { CHECK(kPreparedModel != nullptr); CHECK(kExecutor != nullptr); } @@ -317,7 +315,7 @@ nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const { Return PreparedModel::execute(const V1_0::Request& request, const sp& callback) { - auto result = adapter::execute(kPreparedModel, kUserId, kExecutor, request, callback); + auto result = adapter::execute(kPreparedModel, kExecutor, request, callback); if (!result.has_value()) { auto [message, code] = std::move(result).error(); LOG(ERROR) << "adapter::PreparedModel::execute failed with " << code << ": " << message; @@ -330,8 +328,7 @@ Return PreparedModel::execute(const V1_0::Request& request, Return PreparedModel::execute_1_2(const V1_0::Request& request, V1_2::MeasureTiming measure, const sp& callback) { - auto result = - adapter::execute_1_2(kPreparedModel, kUserId, kExecutor, request, measure, callback); + auto result = adapter::execute_1_2(kPreparedModel, kExecutor, request, measure, callback); if (!result.has_value()) { auto [message, code] = std::move(result).error(); LOG(ERROR) << "adapter::PreparedModel::execute_1_2 failed with " << code << ": " << message; @@ -346,8 +343,8 @@ Return PreparedModel::execute_1_3( const V1_3::OptionalTimePoint& deadline, const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, const sp& callback) { - auto result = adapter::execute_1_3(kPreparedModel, kUserId, kExecutor, request, measure, - deadline, loopTimeoutDuration, callback); + auto result = adapter::execute_1_3(kPreparedModel, kExecutor, request, measure, deadline, + loopTimeoutDuration, callback); if (!result.has_value()) { auto [message, code] = std::move(result).error(); LOG(ERROR) << "adapter::PreparedModel::execute_1_3 failed with " << code << ": " << message; -- cgit v1.2.3 From 629b3a4cf2f36fc5052a0f2e872c7f8c1295fd20 Mon Sep 17 00:00:00 2001 From: Grace Cheng Date: Thu, 6 Jan 2022 12:19:17 +0000 Subject: Implements AIDL VTS direct channel tests Bug: 195593357 Test: Compile, run tests Change-Id: I3e78050fc28c9a0d20cd18788a357bc9b82f2ced --- sensors/aidl/vts/Android.bp | 2 + sensors/aidl/vts/SensorsAidlTestSharedMemory.h | 218 +++++++++++++++++++++++ sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp | 198 +++++++++++++++++++- 3 files changed, 416 insertions(+), 2 deletions(-) create mode 100644 sensors/aidl/vts/SensorsAidlTestSharedMemory.h diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp index 5a519a5a1e..b5a5f15691 100644 --- a/sensors/aidl/vts/Android.bp +++ b/sensors/aidl/vts/Android.bp @@ -34,6 +34,7 @@ cc_test { shared_libs: [ "libbinder", "libbinder_ndk", + "libvndksupport", "libfmq", "android.hardware.common-V2-ndk", "android.hardware.common.fmq-V1-ndk", @@ -41,6 +42,7 @@ cc_test { static_libs: [ "android.hardware.sensors-V1-ndk", "VtsHalSensorsTargetTestUtils", + "libaidlcommonsupport", ], test_suites: [ "general-tests", diff --git a/sensors/aidl/vts/SensorsAidlTestSharedMemory.h b/sensors/aidl/vts/SensorsAidlTestSharedMemory.h new file mode 100644 index 0000000000..4b5916a0d7 --- /dev/null +++ b/sensors/aidl/vts/SensorsAidlTestSharedMemory.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2022 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_SENSORS_AIDL_TEST_SHARED_MEMORY_H +#define ANDROID_SENSORS_AIDL_TEST_SHARED_MEMORY_H + +#include "sensors-vts-utils/GrallocWrapper.h" + +#include +#include +#include + +#include +#include + +#include + +using ::aidl::android::hardware::sensors::BnSensors; +using ::aidl::android::hardware::sensors::Event; +using ::aidl::android::hardware::sensors::ISensors; +using ::aidl::android::hardware::sensors::SensorType; + +template +class SensorsAidlTestSharedMemory { + public: + static SensorsAidlTestSharedMemory* create(ISensors::SharedMemInfo::SharedMemType type, + size_t size) { + constexpr size_t kMaxSize = + 128 * 1024 * 1024; // sensor test should not need more than 128M + if (size == 0 || size >= kMaxSize) { + return nullptr; + } + + auto m = new SensorsAidlTestSharedMemory(type, size); + if (m->mSize != size || m->mBuffer == nullptr) { + delete m; + m = nullptr; + } + return m; + } + + ISensors::SharedMemInfo getSharedMemInfo() const { + ISensors::SharedMemInfo mem = { + .type = mType, + .format = ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT, + .size = static_cast(mSize), + .memoryHandle = android::dupToAidl(mNativeHandle)}; + return mem; + } + char* getBuffer() const { return mBuffer; } + size_t getSize() const { return mSize; } + std::vector parseEvents(int64_t lastCounter = -1, size_t offset = 0) const { + constexpr size_t kEventSize = + static_cast(BnSensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH); + constexpr size_t kOffsetSize = + static_cast(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD); + constexpr size_t kOffsetToken = + static_cast(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN); + constexpr size_t kOffsetType = + static_cast(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE); + constexpr size_t kOffsetAtomicCounter = static_cast( + BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER); + constexpr size_t kOffsetTimestamp = + static_cast(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP); + constexpr size_t kOffsetData = + static_cast(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA); + + std::vector events; + std::vector data(16); + + while (offset + kEventSize <= mSize) { + int64_t atomicCounter = + *reinterpret_cast(mBuffer + offset + kOffsetAtomicCounter); + if (atomicCounter <= lastCounter) { + ALOGV("atomicCounter = %" PRId64 ", lastCounter = %" PRId64, atomicCounter, + lastCounter); + break; + } + + int32_t size = *reinterpret_cast(mBuffer + offset + kOffsetSize); + if (size != kEventSize) { + // unknown error, events parsed may be wrong, remove all + events.clear(); + break; + } + + int32_t token = *reinterpret_cast(mBuffer + offset + kOffsetToken); + int32_t type = *reinterpret_cast(mBuffer + offset + kOffsetType); + int64_t timestamp = *reinterpret_cast(mBuffer + offset + kOffsetTimestamp); + + ALOGV("offset = %zu, cnt %" PRId64 ", token %" PRId32 ", type %" PRId32 + ", timestamp %" PRId64, + offset, atomicCounter, token, type, timestamp); + + Event event = { + .timestamp = timestamp, + .sensorHandle = token, + .sensorType = type, + }; + + event.set(reinterpret_cast(mBuffer + offset + kOffsetData)); + // event.u.data = android::hardware::hidl_array(reinterpret_cast(mBuffer + offset + kOffsetData)); + + events.push_back(event); + + lastCounter = atomicCounter; + offset += kEventSize; + } + + return events; + } + + virtual ~SensorsAidlTestSharedMemory() { + switch (mType) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: { + if (mSize != 0) { + ::munmap(mBuffer, mSize); + mBuffer = nullptr; + + ::native_handle_close(mNativeHandle); + ::native_handle_delete(mNativeHandle); + + mNativeHandle = nullptr; + mSize = 0; + } + break; + } + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: { + if (mSize != 0) { + mGrallocWrapper->freeBuffer(mNativeHandle); + mNativeHandle = nullptr; + mSize = 0; + } + break; + } + default: { + if (mNativeHandle != nullptr || mSize != 0 || mBuffer != nullptr) { + ALOGE("SensorsAidlTestSharedMemory %p not properly destructed: " + "type %d, native handle %p, size %zu, buffer %p", + this, static_cast(mType), mNativeHandle, mSize, mBuffer); + } + break; + } + } + } + + private: + SensorsAidlTestSharedMemory(ISensors::SharedMemInfo::SharedMemType type, size_t size) + : mType(type), mSize(0), mBuffer(nullptr) { + native_handle_t* handle = nullptr; + char* buffer = nullptr; + switch (type) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: { + int fd; + handle = ::native_handle_create(1 /*nFds*/, 0 /*nInts*/); + if (handle != nullptr) { + handle->data[0] = fd = + ::ashmem_create_region("SensorsAidlTestSharedMemory", size); + if (handle->data[0] > 0) { + // memory is pinned by default + buffer = static_cast( + ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + if (buffer != reinterpret_cast(MAP_FAILED)) { + break; + } + ::native_handle_close(handle); + } + ::native_handle_delete(handle); + handle = nullptr; + } + break; + } + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: { + mGrallocWrapper = std::make_unique<::android::GrallocWrapper>(); + if (!mGrallocWrapper->isInitialized()) { + break; + } + + std::pair buf = mGrallocWrapper->allocate(size); + handle = buf.first; + buffer = static_cast(buf.second); + break; + } + default: + break; + } + + if (buffer != nullptr) { + mNativeHandle = handle; + mSize = size; + mBuffer = buffer; + } + } + + ISensors::SharedMemInfo::SharedMemType mType; + native_handle_t* mNativeHandle; + size_t mSize; + char* mBuffer; + std::unique_ptr<::android::GrallocWrapper> mGrallocWrapper; + + DISALLOW_COPY_AND_ASSIGN(SensorsAidlTestSharedMemory); +}; + +#endif // ANDROID_SENSORS_TEST_SHARED_MEMORY_H diff --git a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp index 33645b2a95..608a4b0c4c 100644 --- a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp +++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp @@ -26,6 +26,7 @@ #include #include "SensorsAidlEnvironment.h" +#include "SensorsAidlTestSharedMemory.h" #include "sensors-vts-utils/SensorsVtsEnvironmentBase.h" #include @@ -43,6 +44,9 @@ using aidl::android::hardware::sensors::SensorType; using android::ProcessState; using std::chrono::duration_cast; +constexpr size_t kEventSize = + static_cast(ISensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH); + namespace { static void assertTypeMatchStringType(SensorType type, const std::string& stringType) { @@ -97,6 +101,24 @@ static void assertTypeMatchStringType(SensorType type, const std::string& string } } +bool isDirectChannelTypeSupported(SensorInfo sensor, ISensors::SharedMemInfo::SharedMemType type) { + switch (type) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: + return (sensor.flags & SensorInfo::SENSOR_FLAG_BITS_DIRECT_CHANNEL_ASHMEM) != 0; + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: + return (sensor.flags & SensorInfo::SENSOR_FLAG_BITS_DIRECT_CHANNEL_GRALLOC) != 0; + default: + return false; + } +} + +bool isDirectReportRateSupported(SensorInfo sensor, ISensors::RateLevel rate) { + unsigned int r = static_cast(sensor.flags & + SensorInfo::SENSOR_FLAG_BITS_MASK_DIRECT_REPORT) >> + static_cast(SensorInfo::SENSOR_FLAG_SHIFT_DIRECT_REPORT); + return r >= static_cast(rate); +} + int expectedReportModeForType(SensorType type) { switch (type) { case SensorType::ACCELEROMETER: @@ -286,6 +308,24 @@ class SensorsAidlTest : public testing::TestWithParam { std::vector getOneShotSensors(); std::vector getInjectEventSensors(); + void verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType memType); + + void verifyRegisterDirectChannel( + std::shared_ptr> mem, + int32_t* directChannelHandle, bool supportsSharedMemType, + bool supportsAnyDirectChannel); + + void verifyConfigure(const SensorInfo& sensor, ISensors::SharedMemInfo::SharedMemType memType, + int32_t directChannelHandle, bool directChannelSupported); + + void queryDirectChannelSupport(ISensors::SharedMemInfo::SharedMemType memType, + bool* supportsSharedMemType, bool* supportsAnyDirectChannel); + + void verifyUnregisterDirectChannel(int32_t* directChannelHandle, bool supportsAnyDirectChannel); + + void checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, + ISensors::RateLevel rateLevel, int32_t* reportToken); + inline std::shared_ptr& getSensors() { return mEnvironment->mSensors; } inline SensorsAidlEnvironment* getEnvironment() { return mEnvironment; } @@ -313,6 +353,18 @@ class SensorsAidlTest : public testing::TestWithParam { ndk::ScopedAStatus flush(int32_t sensorHandle) { return getSensors()->flush(sensorHandle); } + ndk::ScopedAStatus registerDirectChannel(const ISensors::SharedMemInfo& mem, + int32_t* aidlReturn); + + ndk::ScopedAStatus unregisterDirectChannel(int32_t* channelHandle) { + return getSensors()->unregisterDirectChannel(*channelHandle); + } + + ndk::ScopedAStatus configDirectReport(int32_t sensorHandle, int32_t channelHandle, + ISensors::RateLevel rate, int32_t* reportToken) { + return getSensors()->configDirectReport(sensorHandle, channelHandle, rate, reportToken); + } + void runSingleFlushTest(const std::vector& sensors, bool activateSensor, int32_t expectedFlushCount, bool expectedResult); @@ -334,6 +386,19 @@ class SensorsAidlTest : public testing::TestWithParam { SensorsAidlEnvironment* mEnvironment; }; +ndk::ScopedAStatus SensorsAidlTest::registerDirectChannel(const ISensors::SharedMemInfo& mem, + int32_t* aidlReturn) { + // If registeration of a channel succeeds, add the handle of channel to a set so that it can be + // unregistered when test fails. Unregister a channel does not remove the handle on purpose. + // Unregistering a channel more than once should not have negative effect. + + ndk::ScopedAStatus status = getSensors()->registerDirectChannel(mem, aidlReturn); + if (status.isOk()) { + mDirectChannelHandles.insert(*aidlReturn); + } + return status; +} + std::vector SensorsAidlTest::getSensorsList() { std::vector sensorInfoList; checkIsOk(getSensors()->getSensorsList(&sensorInfoList)); @@ -850,12 +915,141 @@ TEST_P(SensorsAidlTest, NoStaleEvents) { } } +void SensorsAidlTest::checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, + ISensors::RateLevel rateLevel, int32_t* reportToken) { + ndk::ScopedAStatus status = + configDirectReport(sensor.sensorHandle, directChannelHandle, rateLevel, reportToken); + + SCOPED_TRACE(::testing::Message() + << " handle=0x" << std::hex << std::setw(8) << std::setfill('0') + << sensor.sensorHandle << std::dec << " type=" << static_cast(sensor.type) + << " name=" << sensor.name); + + if (isDirectReportRateSupported(sensor, rateLevel)) { + ASSERT_TRUE(status.isOk()); + if (rateLevel != ISensors::RateLevel::STOP) { + ASSERT_GT(*reportToken, 0); + } else { + ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT); + } + } +} + +void SensorsAidlTest::queryDirectChannelSupport(ISensors::SharedMemInfo::SharedMemType memType, + bool* supportsSharedMemType, + bool* supportsAnyDirectChannel) { + *supportsSharedMemType = false; + *supportsAnyDirectChannel = false; + for (const SensorInfo& curSensor : getSensorsList()) { + if (isDirectChannelTypeSupported(curSensor, memType)) { + *supportsSharedMemType = true; + } + if (isDirectChannelTypeSupported(curSensor, + ISensors::SharedMemInfo::SharedMemType::ASHMEM) || + isDirectChannelTypeSupported(curSensor, + ISensors::SharedMemInfo::SharedMemType::GRALLOC)) { + *supportsAnyDirectChannel = true; + } + + if (*supportsSharedMemType && *supportsAnyDirectChannel) { + break; + } + } +} + +void SensorsAidlTest::verifyRegisterDirectChannel( + std::shared_ptr> mem, + int32_t* directChannelHandle, bool supportsSharedMemType, bool supportsAnyDirectChannel) { + char* buffer = mem->getBuffer(); + size_t size = mem->getSize(); + + if (supportsSharedMemType) { + memset(buffer, 0xff, size); + } + + int32_t channelHandle; + + ::ndk::ScopedAStatus status = registerDirectChannel(mem->getSharedMemInfo(), &channelHandle); + if (supportsSharedMemType) { + ASSERT_TRUE(status.isOk()); + ASSERT_EQ(channelHandle, 0); + } else { + int32_t error = supportsAnyDirectChannel ? EX_ILLEGAL_ARGUMENT : EX_UNSUPPORTED_OPERATION; + ASSERT_EQ(status.getExceptionCode(), error); + ASSERT_EQ(channelHandle, -1); + } + directChannelHandle = &channelHandle; +} + +void SensorsAidlTest::verifyUnregisterDirectChannel(int32_t* channelHandle, + bool supportsAnyDirectChannel) { + int result = supportsAnyDirectChannel ? EX_NONE : EX_UNSUPPORTED_OPERATION; + ndk::ScopedAStatus status = unregisterDirectChannel(channelHandle); + ASSERT_EQ(status.getExceptionCode(), result); +} + +void SensorsAidlTest::verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType memType) { + constexpr size_t kNumEvents = 1; + constexpr size_t kMemSize = kNumEvents * kEventSize; + + std::shared_ptr> mem( + SensorsAidlTestSharedMemory::create(memType, kMemSize)); + ASSERT_NE(mem, nullptr); + + bool supportsSharedMemType; + bool supportsAnyDirectChannel; + queryDirectChannelSupport(memType, &supportsSharedMemType, &supportsAnyDirectChannel); + + for (const SensorInfo& sensor : getSensorsList()) { + int32_t directChannelHandle = 0; + verifyRegisterDirectChannel(mem, &directChannelHandle, supportsSharedMemType, + supportsAnyDirectChannel); + verifyConfigure(sensor, memType, directChannelHandle, supportsAnyDirectChannel); + verifyUnregisterDirectChannel(&directChannelHandle, supportsAnyDirectChannel); + } +} + +void SensorsAidlTest::verifyConfigure(const SensorInfo& sensor, + ISensors::SharedMemInfo::SharedMemType memType, + int32_t directChannelHandle, bool supportsAnyDirectChannel) { + SCOPED_TRACE(::testing::Message() + << " handle=0x" << std::hex << std::setw(8) << std::setfill('0') + << sensor.sensorHandle << std::dec << " type=" << static_cast(sensor.type) + << " name=" << sensor.name); + + int32_t reportToken = 0; + if (isDirectChannelTypeSupported(sensor, memType)) { + // Verify that each rate level is properly supported + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::NORMAL, &reportToken); + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::FAST, &reportToken); + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::VERY_FAST, &reportToken); + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::STOP, &reportToken); + + // Verify that a sensor handle of -1 is only acceptable when using RateLevel::STOP + ndk::ScopedAStatus status = configDirectReport(-1 /* sensorHandle */, directChannelHandle, + ISensors::RateLevel::NORMAL, &reportToken); + ASSERT_EQ(status.getServiceSpecificError(), android::BAD_VALUE); + + status = configDirectReport(-1 /* sensorHandle */, directChannelHandle, + ISensors::RateLevel::STOP, &reportToken); + ASSERT_TRUE(status.isOk()); + } else { + // directChannelHandle will be -1 here, HAL should either reject it as a bad value if there + // is some level of direct channel report, otherwise return INVALID_OPERATION if direct + // channel is not supported at all + int error = supportsAnyDirectChannel ? EX_ILLEGAL_ARGUMENT : EX_UNSUPPORTED_OPERATION; + ndk::ScopedAStatus status = configDirectReport(sensor.sensorHandle, directChannelHandle, + ISensors::RateLevel::NORMAL, &reportToken); + ASSERT_EQ(status.getExceptionCode(), error); + } +} + TEST_P(SensorsAidlTest, DirectChannelAshmem) { - // TODO(b/195593357): Implement this + verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::ASHMEM); } TEST_P(SensorsAidlTest, DirectChannelGralloc) { - // TODO(b/195593357): Implement this + verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::GRALLOC); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SensorsAidlTest); -- cgit v1.2.3 From b3bdf0535c895f610588807976aeca673dba059b Mon Sep 17 00:00:00 2001 From: ramindani Date: Wed, 12 Jan 2022 18:27:05 +0000 Subject: ASSERT error check in brightness test Without ASSERT the next call to take the first element will crash the instrumentation for the tests. BUG: 210151839 Test: atest VtsHalGraphicsComposer3_TargetTest Change-Id: I2c78b9130661e543e62138c064ab15dd79180920 --- .../composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index a591aaa67d..63a6b86696 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -1499,7 +1499,7 @@ TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) { execute(); { const auto errors = mReader.takeErrors(); - EXPECT_EQ(1, errors.size()); + ASSERT_EQ(1, errors.size()); EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode); } @@ -1507,7 +1507,7 @@ TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) { execute(); { const auto errors = mReader.takeErrors(); - EXPECT_EQ(1, errors.size()); + ASSERT_EQ(1, errors.size()); EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode); } } -- cgit v1.2.3 From ec876871eda6d2f5510d0bc5b834a97c271c6db2 Mon Sep 17 00:00:00 2001 From: Hridya Valsaraju Date: Wed, 12 Jan 2022 11:15:42 -0800 Subject: health: vts: Remove hridya@ from OWNERS Test: N/A Bug: N/A Change-Id: I37b12a4e4dcabf09c3ff7188a59482357fe36242 --- health/2.1/vts/OWNERS | 1 - 1 file changed, 1 deletion(-) diff --git a/health/2.1/vts/OWNERS b/health/2.1/vts/OWNERS index 20450ba407..a6803cd82a 100644 --- a/health/2.1/vts/OWNERS +++ b/health/2.1/vts/OWNERS @@ -1,3 +1,2 @@ elsk@google.com -hridya@google.com sspatil@google.com -- cgit v1.2.3 From 13cb0fb2356a23a566fd5cdd1875f686a64878b2 Mon Sep 17 00:00:00 2001 From: Joe Bolinger Date: Fri, 3 Dec 2021 12:45:48 -0800 Subject: Update common and fingerprint AIDL for session logging. This also partially reverts commit 1988b3825bc95a0e7e3bb86bfa5bf70ea5323a61 which unnecessarily froze the interface during a prior interface addition. Bug: 204585936 Bug: 204584403 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: Ibc9934390a487f5bfb9d3678ad65e7b1c3740ae7 --- .../biometrics/common/OperationContext.aidl | 41 +++++++++++++++++ .../biometrics/common/OperationReason.aidl | 40 ++++++++++++++++ .../biometrics/common/OperationContext.aidl | 49 ++++++++++++++++++++ .../biometrics/common/OperationReason.aidl | 37 +++++++++++++++ biometrics/fingerprint/aidl/Android.bp | 7 +-- .../2/.hash | 1 - .../biometrics/fingerprint/AcquiredInfo.aidl | 50 -------------------- .../hardware/biometrics/fingerprint/Error.aidl | 46 ------------------- .../fingerprint/FingerprintSensorType.aidl | 43 ------------------ .../biometrics/fingerprint/IFingerprint.aidl | 39 ---------------- .../hardware/biometrics/fingerprint/ISession.aidl | 51 --------------------- .../biometrics/fingerprint/ISessionCallback.aidl | 53 ---------------------- .../biometrics/fingerprint/SensorLocation.aidl | 42 ----------------- .../biometrics/fingerprint/SensorProps.aidl | 44 ------------------ .../hardware/biometrics/fingerprint/ISession.aidl | 5 ++ .../biometrics/fingerprint/PointerContext.aidl | 43 ++++++++++++++++++ .../hardware/biometrics/fingerprint/ISession.aidl | 29 +++++++++++- .../biometrics/fingerprint/PointerContext.aidl | 41 +++++++++++++++++ biometrics/fingerprint/aidl/default/Android.bp | 2 +- biometrics/fingerprint/aidl/default/Session.cpp | 26 +++++++++++ .../fingerprint/aidl/default/include/Session.h | 16 +++++++ 21 files changed, 328 insertions(+), 377 deletions(-) create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl create mode 100644 biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl create mode 100644 biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISession.aidl delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISessionCallback.aidl delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorProps.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl new file mode 100644 index 0000000000..3a6461ed91 --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.common; +@VintfStability +parcelable OperationContext { + int id = 0; + android.hardware.biometrics.common.OperationReason reason = android.hardware.biometrics.common.OperationReason.UNKNOWN; + boolean isAoD = false; + boolean isCrypto = false; +} diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl new file mode 100644 index 0000000000..3da3a6ab0b --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.common; +@Backing(type="byte") @VintfStability +enum OperationReason { + UNKNOWN = 0, + BIOMETRIC_PROMPT = 1, + KEYGUARD = 2, +} diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl new file mode 100644 index 0000000000..390e6985e4 --- /dev/null +++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 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.biometrics.common; + +import android.hardware.biometrics.common.OperationReason; + +/** + * Additional context associated with an operation. + */ +@VintfStability +parcelable OperationContext { + /** + * An identifier for the logical action that the user is engaged in. These identifiers are + * not guaranteed to be unique. However, the framework will not reuse identifiers within + * short periods of time so they can be made unique, if needed, by appending a timestamp. + * + * Zero if the reason is OperationReason.UNKNOWN. + */ + int id = 0; + + /** + * A logical reason for this operation. + * + * This should be interpreted as a hint to enable optimizations or tracing. The + * framework may choose to use OperationReason.UNKNOWN at any time based on the device's + * policy. + */ + OperationReason reason = OperationReason.UNKNOWN; + + /* Flag indicating that the display is in AoD mode. */ + boolean isAoD = false; + + /** Flag indicating that crypto was requested. */ + boolean isCrypto = false; +} diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl new file mode 100644 index 0000000000..abc25ed663 --- /dev/null +++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2021 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.biometrics.common; + +@VintfStability +@Backing(type="byte") +enum OperationReason { + /** + * A normal operation without an explicit reason. + */ + UNKNOWN, + + /** + * An operation associated with biometric prompt. This may be due to either application or + * system use, but it is not related to KEYGUARD device entry. + */ + BIOMETRIC_PROMPT, + + /** + * An operation associated with device entry. + */ + KEYGUARD, +} diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp index c46150ebe5..c3a056cc2b 100644 --- a/biometrics/fingerprint/aidl/Android.bp +++ b/biometrics/fingerprint/aidl/Android.bp @@ -15,7 +15,7 @@ aidl_interface { ], imports: [ "android.hardware.biometrics.common", - "android.hardware.keymaster", + "android.hardware.keymaster-V3", ], stability: "vintf", backend: { @@ -26,8 +26,5 @@ aidl_interface { enabled: false, }, }, - versions: [ - "1", - "2", - ], + versions: ["1"], } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash deleted file mode 100644 index 411cb751cb..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash +++ /dev/null @@ -1 +0,0 @@ -762eb38ce93ea3c7d39a680949cbdbd2371b3f06 diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl deleted file mode 100644 index c51aa033d4..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.biometrics.fingerprint; -@Backing(type="byte") @VintfStability -enum AcquiredInfo { - UNKNOWN = 0, - GOOD = 1, - PARTIAL = 2, - INSUFFICIENT = 3, - SENSOR_DIRTY = 4, - TOO_SLOW = 5, - TOO_FAST = 6, - VENDOR = 7, - START = 8, - TOO_DARK = 9, - TOO_BRIGHT = 10, - IMMOBILE = 11, - RETRYING_CAPTURE = 12, -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl deleted file mode 100644 index af7bc3c56b..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.biometrics.fingerprint; -@Backing(type="byte") @VintfStability -enum Error { - UNKNOWN = 0, - HW_UNAVAILABLE = 1, - UNABLE_TO_PROCESS = 2, - TIMEOUT = 3, - NO_SPACE = 4, - CANCELED = 5, - UNABLE_TO_REMOVE = 6, - VENDOR = 7, - BAD_CALIBRATION = 8, -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl deleted file mode 100644 index 9c208c4e7c..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.biometrics.fingerprint; -@Backing(type="byte") @VintfStability -enum FingerprintSensorType { - UNKNOWN = 0, - REAR = 1, - UNDER_DISPLAY_ULTRASONIC = 2, - UNDER_DISPLAY_OPTICAL = 3, - POWER_BUTTON = 4, - HOME_BUTTON = 5, -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl deleted file mode 100644 index 5d3df6fbaa..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.biometrics.fingerprint; -@VintfStability -interface IFingerprint { - android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps(); - android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb); -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISession.aidl deleted file mode 100644 index 9934a763e7..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISession.aidl +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.biometrics.fingerprint; -@VintfStability -interface ISession { - void generateChallenge(); - void revokeChallenge(in long challenge); - android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat); - android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId); - android.hardware.biometrics.common.ICancellationSignal detectInteraction(); - void enumerateEnrollments(); - void removeEnrollments(in int[] enrollmentIds); - void getAuthenticatorId(); - void invalidateAuthenticatorId(); - void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat); - void close(); - void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); - void onPointerUp(in int pointerId); - void onUiReady(); -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISessionCallback.aidl deleted file mode 100644 index 3c40ad63bf..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.biometrics.fingerprint; -@VintfStability -interface ISessionCallback { - void onChallengeGenerated(in long challenge); - void onChallengeRevoked(in long challenge); - void onAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfo info, in int vendorCode); - void onError(in android.hardware.biometrics.fingerprint.Error error, in int vendorCode); - void onEnrollmentProgress(in int enrollmentId, int remaining); - void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat); - void onAuthenticationFailed(); - void onLockoutTimed(in long durationMillis); - void onLockoutPermanent(); - void onLockoutCleared(); - void onInteractionDetected(); - void onEnrollmentsEnumerated(in int[] enrollmentIds); - void onEnrollmentsRemoved(in int[] enrollmentIds); - void onAuthenticatorIdRetrieved(in long authenticatorId); - void onAuthenticatorIdInvalidated(in long newAuthenticatorId); - void onSessionClosed(); -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl deleted file mode 100644 index 295fde9f5f..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2021 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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.biometrics.fingerprint; -@VintfStability -parcelable SensorLocation { - int displayId; - int sensorLocationX; - int sensorLocationY; - int sensorRadius; - String display = ""; -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorProps.aidl deleted file mode 100644 index 782d2899d3..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.biometrics.fingerprint; -@VintfStability -parcelable SensorProps { - android.hardware.biometrics.common.CommonProps commonProps; - android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType = android.hardware.biometrics.fingerprint.FingerprintSensorType.UNKNOWN; - android.hardware.biometrics.fingerprint.SensorLocation[] sensorLocations; - boolean supportsNavigationGestures; - boolean supportsDetectInteraction; - boolean halHandlesDisplayTouches; - boolean halControlsIllumination; -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl index 9934a763e7..4e7b3b451e 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl @@ -48,4 +48,9 @@ interface ISession { void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); void onPointerUp(in int pointerId); void onUiReady(); + android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context); + android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.common.OperationContext context); + android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context); + void onPointerDownWithContext(in android.hardware.biometrics.fingerprint.PointerContext context); + void onPointerUpWithContext(in android.hardware.biometrics.fingerprint.PointerContext context); } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl new file mode 100644 index 0000000000..e383330b69 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.fingerprint; +@VintfStability +parcelable PointerContext { + int pointerId = 0; + int x = 0; + int y = 0; + float minor = 0.000000f; + float major = 0.000000f; + boolean isAoD = false; +} diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index f1d96d3039..ea8c6aa869 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -17,6 +17,8 @@ package android.hardware.biometrics.fingerprint; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationContext; +import android.hardware.biometrics.fingerprint.PointerContext; import android.hardware.keymaster.HardwareAuthToken; /** @@ -140,7 +142,7 @@ interface ISession { * * @param hat See above documentation. * @return ICancellationSignal An object that can be used by the framework to cancel this - * operation. + * operation. */ ICancellationSignal enroll(in HardwareAuthToken hat); @@ -234,7 +236,7 @@ interface ISession { * - ISessionCallback#onAcquired * * @return ICancellationSignal An object that can be used by the framework to cancel this - * operation. + * operation. */ ICancellationSignal detectInteraction(); @@ -448,4 +450,27 @@ interface ISession { * HAL, the framework will invoke this operation to notify when the illumination is showing. */ void onUiReady(); + + /** + * These are alternative methods for some operations to allow the HAL to make optional + * optimizations during execution. + * + * HALs may ignore the additional context and treat all *WithContext methods the same as + * the original methods. + */ + + /** See ISession#authenticate(long) */ + ICancellationSignal authenticateWithContext(in long operationId, in OperationContext context); + + /** See ISession#enroll(HardwareAuthToken) */ + ICancellationSignal enrollWithContext(in HardwareAuthToken hat, in OperationContext context); + + /** See ISession#detectInteraction() */ + ICancellationSignal detectInteractionWithContext(in OperationContext context); + + /** See ISession#onPointerDown(int, int, int, float, float) */ + void onPointerDownWithContext(in PointerContext context); + + /** See ISession#onPointerUp(int) */ + void onPointerUpWithContext(in PointerContext context); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl new file mode 100644 index 0000000000..4975175d8c --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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.biometrics.fingerprint; + +/** + * Additional context associated with a pointer event. + */ +@VintfStability +parcelable PointerContext { + /* See android.view.MotionEvent#getPointerId. */ + int pointerId = 0; + + /* The distance in pixels from the left edge of the display. */ + int x = 0; + + /* The distance in pixels from the top edge of the display. */ + int y = 0; + + /* See android.view.MotionEvent#getTouchMinor. */ + float minor = 0f; + + /* See android.view.MotionEvent#getTouchMajor. */ + float major = 0f; + + /* Flag indicating that the display is in AoD mode. */ + boolean isAoD = false; +} diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index d4194a3afb..430bf3cd82 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -25,7 +25,7 @@ cc_binary { "libbase", "libbinder_ndk", "android.hardware.biometrics.fingerprint-V2-ndk", - "android.hardware.biometrics.common-V1-ndk", + "android.hardware.biometrics.common-V2-ndk", ], } diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index ca481e7cf0..8cbcfc77c5 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -244,4 +244,30 @@ ndk::ScopedAStatus Session::onUiReady() { return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::authenticateWithContext( + int64_t operationId, const common::OperationContext& /*context*/, + std::shared_ptr* out) { + return authenticate(operationId, out); +} + +ndk::ScopedAStatus Session::enrollWithContext(const keymaster::HardwareAuthToken& hat, + const common::OperationContext& /*context*/, + std::shared_ptr* out) { + return enroll(hat, out); +} + +ndk::ScopedAStatus Session::detectInteractionWithContext( + const common::OperationContext& /*context*/, + std::shared_ptr* out) { + return detectInteraction(out); +} + +ndk::ScopedAStatus Session::onPointerDownWithContext(const PointerContext& context) { + return onPointerDown(context.pointerId, context.x, context.y, context.minor, context.major); +} + +ndk::ScopedAStatus Session::onPointerUpWithContext(const PointerContext& context) { + return onPointerUp(context.pointerId); +} + } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h index 9e464229e1..584cb27b96 100644 --- a/biometrics/fingerprint/aidl/default/include/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -79,6 +79,22 @@ class Session : public BnSession { ndk::ScopedAStatus onUiReady() override; + ndk::ScopedAStatus authenticateWithContext( + int64_t operationId, const common::OperationContext& context, + std::shared_ptr* out) override; + + ndk::ScopedAStatus enrollWithContext( + const keymaster::HardwareAuthToken& hat, const common::OperationContext& context, + std::shared_ptr* out) override; + + ndk::ScopedAStatus detectInteractionWithContext( + const common::OperationContext& context, + std::shared_ptr* out) override; + + ndk::ScopedAStatus onPointerDownWithContext(const PointerContext& context) override; + + ndk::ScopedAStatus onPointerUpWithContext(const PointerContext& context) override; + bool isClosed(); private: -- cgit v1.2.3 From 5214086d2548d40ec3bf1b9c71d58dc21672c46d Mon Sep 17 00:00:00 2001 From: Gabriel Biren Date: Wed, 12 Jan 2022 18:50:24 +0000 Subject: Update supplicant bitmap comments to clarify that defs.h is a useful reference, but not the main definition for the bitmap values in the interface. Bug: 210904141 Test: N/A since only comments were updated Change-Id: Ib721d6ea0182db50f05ddab10096583481f85413 --- wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl | 2 +- .../aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl | 2 +- wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl | 2 +- .../aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl | 2 +- wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl index e8101ea3af..039d41dc43 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for AuthAlg param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_AUTH_ALG_OPEN). + * the historical values (starting at WPA_AUTH_ALG_OPEN). */ @VintfStability @Backing(type="int") diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl index d5b26adc99..99e9da07f1 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for GroupCipher param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_CIPHER_WEP40). + * the historical values (starting at WPA_CIPHER_WEP40). */ @VintfStability @Backing(type="int") diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl index 322558529e..f0c3345b93 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for KeyMgmt param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_KEY_MGMT_IEEE8021X). + * the historical values (starting at WPA_KEY_MGMT_IEEE8021X). */ @VintfStability @Backing(type="int") diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl index ad134fa240..7179fea9e2 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for PairwiseCipher param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_CIPHER_NONE). + * the historical values (starting at WPA_CIPHER_NONE). */ @VintfStability @Backing(type="int") diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl index 65c832bece..dc3d80bf1f 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl @@ -19,7 +19,7 @@ package android.hardware.wifi.supplicant; /** * Possible mask of values for Proto param. * See /external/wpa_supplicant_8/src/common/defs.h for - * all possible values (starting at WPA_PROTO_WPA). + * the historical values (starting at WPA_PROTO_WPA). */ @VintfStability @Backing(type="int") -- cgit v1.2.3 From 68e4300c72a8646f085b94e309abc5b6edd300e8 Mon Sep 17 00:00:00 2001 From: David Gross Date: Wed, 12 Jan 2022 14:18:36 -0800 Subject: Freeze neuralnetworks AIDL version as v3 for FL7 $ m android.hardware.neuralnetworks-update-api $ m android.hardware.neuralnetworks-freeze-api Bug: 202280925 Test: adb shell NeuralNetworksTest_static Test: atest VtsHalNeuralnetworksTargetTest Change-Id: I2b2755d7376bb847b15b395e280bf352b5b9ef55 --- neuralnetworks/aidl/Android.bp | 1 + .../android.hardware.neuralnetworks/3/.hash | 1 + .../hardware/neuralnetworks/BufferDesc.aidl | 38 ++++++ .../hardware/neuralnetworks/BufferRole.aidl | 40 ++++++ .../hardware/neuralnetworks/Capabilities.aidl | 42 ++++++ .../hardware/neuralnetworks/DataLocation.aidl | 41 ++++++ .../hardware/neuralnetworks/DeviceBuffer.aidl | 39 ++++++ .../hardware/neuralnetworks/DeviceType.aidl | 41 ++++++ .../hardware/neuralnetworks/ErrorStatus.aidl | 46 +++++++ .../neuralnetworks/ExecutionPreference.aidl | 40 ++++++ .../hardware/neuralnetworks/ExecutionResult.aidl | 40 ++++++ .../android/hardware/neuralnetworks/Extension.aidl | 39 ++++++ .../neuralnetworks/ExtensionNameAndPrefix.aidl | 39 ++++++ .../ExtensionOperandTypeInformation.aidl | 40 ++++++ .../neuralnetworks/FencedExecutionResult.aidl | 39 ++++++ .../neuralnetworks/FusedActivationFunc.aidl | 41 ++++++ .../3/android/hardware/neuralnetworks/IBuffer.aidl | 39 ++++++ .../3/android/hardware/neuralnetworks/IBurst.aidl | 39 ++++++ .../3/android/hardware/neuralnetworks/IDevice.aidl | 52 ++++++++ .../neuralnetworks/IFencedExecutionCallback.aidl | 38 ++++++ .../hardware/neuralnetworks/IPreparedModel.aidl | 42 ++++++ .../neuralnetworks/IPreparedModelCallback.aidl | 38 ++++++ .../neuralnetworks/IPreparedModelParcel.aidl | 38 ++++++ .../3/android/hardware/neuralnetworks/Memory.aidl | 40 ++++++ .../3/android/hardware/neuralnetworks/Model.aidl | 43 +++++++ .../neuralnetworks/NumberOfCacheFiles.aidl | 39 ++++++ .../3/android/hardware/neuralnetworks/Operand.aidl | 44 +++++++ .../neuralnetworks/OperandExtraParams.aidl | 39 ++++++ .../hardware/neuralnetworks/OperandLifeTime.aidl | 44 +++++++ .../neuralnetworks/OperandPerformance.aidl | 39 ++++++ .../hardware/neuralnetworks/OperandType.aidl | 53 ++++++++ .../android/hardware/neuralnetworks/Operation.aidl | 40 ++++++ .../hardware/neuralnetworks/OperationType.aidl | 143 +++++++++++++++++++++ .../hardware/neuralnetworks/OutputShape.aidl | 39 ++++++ .../hardware/neuralnetworks/PerformanceInfo.aidl | 39 ++++++ .../android/hardware/neuralnetworks/Priority.aidl | 40 ++++++ .../3/android/hardware/neuralnetworks/Request.aidl | 40 ++++++ .../hardware/neuralnetworks/RequestArgument.aidl | 40 ++++++ .../hardware/neuralnetworks/RequestMemoryPool.aidl | 39 ++++++ .../android/hardware/neuralnetworks/Subgraph.aidl | 41 ++++++ .../neuralnetworks/SymmPerChannelQuantParams.aidl | 39 ++++++ .../3/android/hardware/neuralnetworks/Timing.aidl | 39 ++++++ 42 files changed, 1733 insertions(+) create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp index 065105a7a9..aa4c4b634d 100644 --- a/neuralnetworks/aidl/Android.bp +++ b/neuralnetworks/aidl/Android.bp @@ -38,5 +38,6 @@ aidl_interface { versions: [ "1", "2", + "3", ], } diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash new file mode 100644 index 0000000000..3b9f018381 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash @@ -0,0 +1 @@ +8c2c4ca2327e6f779dad6119c03d832ea4e1def1 diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl new file mode 100644 index 0000000000..05cec76c88 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable BufferDesc { + int[] dimensions; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl new file mode 100644 index 0000000000..10a6b75ac7 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable BufferRole { + int modelIndex; + int ioIndex; + float probability; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl new file mode 100644 index 0000000000..30877c0294 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Capabilities { + android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceScalar; + android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceTensor; + android.hardware.neuralnetworks.OperandPerformance[] operandPerformance; + android.hardware.neuralnetworks.PerformanceInfo ifPerformance; + android.hardware.neuralnetworks.PerformanceInfo whilePerformance; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl new file mode 100644 index 0000000000..db49a38979 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable DataLocation { + int poolIndex; + long offset; + long length; + long padding; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl new file mode 100644 index 0000000000..7cdd6db742 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable DeviceBuffer { + android.hardware.neuralnetworks.IBuffer buffer; + int token; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl new file mode 100644 index 0000000000..82fe8ae3e7 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum DeviceType { + OTHER = 1, + CPU = 2, + GPU = 3, + ACCELERATOR = 4, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl new file mode 100644 index 0000000000..57d5d6e4cd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum ErrorStatus { + NONE = 0, + DEVICE_UNAVAILABLE = 1, + GENERAL_FAILURE = 2, + OUTPUT_INSUFFICIENT_SIZE = 3, + INVALID_ARGUMENT = 4, + MISSED_DEADLINE_TRANSIENT = 5, + MISSED_DEADLINE_PERSISTENT = 6, + RESOURCE_EXHAUSTED_TRANSIENT = 7, + RESOURCE_EXHAUSTED_PERSISTENT = 8, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl new file mode 100644 index 0000000000..4352d8f334 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum ExecutionPreference { + LOW_POWER = 0, + FAST_SINGLE_ANSWER = 1, + SUSTAINED_SPEED = 2, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl new file mode 100644 index 0000000000..44e9922f52 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable ExecutionResult { + boolean outputSufficientSize; + android.hardware.neuralnetworks.OutputShape[] outputShapes; + android.hardware.neuralnetworks.Timing timing; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl new file mode 100644 index 0000000000..c47028d99f --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Extension { + String name; + android.hardware.neuralnetworks.ExtensionOperandTypeInformation[] operandTypes; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl new file mode 100644 index 0000000000..6c287fd460 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable ExtensionNameAndPrefix { + String name; + char prefix; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl new file mode 100644 index 0000000000..a3680aa9dd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable ExtensionOperandTypeInformation { + char type; + boolean isTensor; + int byteSize; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl new file mode 100644 index 0000000000..7952b34632 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable FencedExecutionResult { + android.hardware.neuralnetworks.IFencedExecutionCallback callback; + @nullable ParcelFileDescriptor syncFence; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl new file mode 100644 index 0000000000..7e61bbbdb1 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum FusedActivationFunc { + NONE = 0, + RELU = 1, + RELU1 = 2, + RELU6 = 3, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl new file mode 100644 index 0000000000..f10e7e24ca --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IBuffer { + void copyFrom(in android.hardware.neuralnetworks.Memory src, in int[] dimensions); + void copyTo(in android.hardware.neuralnetworks.Memory dst); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl new file mode 100644 index 0000000000..eb3d0b004a --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IBurst { + android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in long[] memoryIdentifierTokens, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); + void releaseMemoryResource(in long memoryIdentifierToken); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl new file mode 100644 index 0000000000..c9c67f2fcd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IDevice { + android.hardware.neuralnetworks.DeviceBuffer allocate(in android.hardware.neuralnetworks.BufferDesc desc, in android.hardware.neuralnetworks.IPreparedModelParcel[] preparedModels, in android.hardware.neuralnetworks.BufferRole[] inputRoles, in android.hardware.neuralnetworks.BufferRole[] outputRoles); + android.hardware.neuralnetworks.Capabilities getCapabilities(); + android.hardware.neuralnetworks.NumberOfCacheFiles getNumberOfCacheFilesNeeded(); + android.hardware.neuralnetworks.Extension[] getSupportedExtensions(); + boolean[] getSupportedOperations(in android.hardware.neuralnetworks.Model model); + android.hardware.neuralnetworks.DeviceType getType(); + String getVersionString(); + void prepareModel(in android.hardware.neuralnetworks.Model model, in android.hardware.neuralnetworks.ExecutionPreference preference, in android.hardware.neuralnetworks.Priority priority, in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback); + void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback); + const int BYTE_SIZE_OF_CACHE_TOKEN = 32; + const int MAX_NUMBER_OF_CACHE_FILES = 32; + const int EXTENSION_TYPE_HIGH_BITS_PREFIX = 15; + const int EXTENSION_TYPE_LOW_BITS_TYPE = 16; + const int OPERAND_TYPE_BASE_MAX = 65535; + const int OPERATION_TYPE_BASE_MAX = 65535; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl new file mode 100644 index 0000000000..0bfb80ac78 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IFencedExecutionCallback { + android.hardware.neuralnetworks.ErrorStatus getExecutionInfo(out android.hardware.neuralnetworks.Timing timingLaunched, out android.hardware.neuralnetworks.Timing timingFenced); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl new file mode 100644 index 0000000000..fccb5dc98e --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IPreparedModel { + android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); + android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs); + android.hardware.neuralnetworks.IBurst configureExecutionBurst(); + const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000; + const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl new file mode 100644 index 0000000000..e0c763bc2a --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IPreparedModelCallback { + void notify(in android.hardware.neuralnetworks.ErrorStatus status, in android.hardware.neuralnetworks.IPreparedModel preparedModel); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl new file mode 100644 index 0000000000..dbedf12772 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable IPreparedModelParcel { + android.hardware.neuralnetworks.IPreparedModel preparedModel; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl new file mode 100644 index 0000000000..37fa102cf4 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +union Memory { + android.hardware.common.Ashmem ashmem; + android.hardware.common.MappableFile mappableFile; + android.hardware.graphics.common.HardwareBuffer hardwareBuffer; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl new file mode 100644 index 0000000000..30d8dda55d --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Model { + android.hardware.neuralnetworks.Subgraph main; + android.hardware.neuralnetworks.Subgraph[] referenced; + byte[] operandValues; + android.hardware.neuralnetworks.Memory[] pools; + boolean relaxComputationFloat32toFloat16; + android.hardware.neuralnetworks.ExtensionNameAndPrefix[] extensionNameToPrefix; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl new file mode 100644 index 0000000000..9314760a43 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable NumberOfCacheFiles { + int numModelCache; + int numDataCache; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl new file mode 100644 index 0000000000..1d9bdd8446 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Operand { + android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32; + int[] dimensions; + float scale; + int zeroPoint; + android.hardware.neuralnetworks.OperandLifeTime lifetime = android.hardware.neuralnetworks.OperandLifeTime.TEMPORARY_VARIABLE; + android.hardware.neuralnetworks.DataLocation location; + @nullable android.hardware.neuralnetworks.OperandExtraParams extraParams; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl new file mode 100644 index 0000000000..14792cff08 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +union OperandExtraParams { + android.hardware.neuralnetworks.SymmPerChannelQuantParams channelQuant; + byte[] extension; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl new file mode 100644 index 0000000000..40adfb1dd8 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum OperandLifeTime { + TEMPORARY_VARIABLE = 0, + SUBGRAPH_INPUT = 1, + SUBGRAPH_OUTPUT = 2, + CONSTANT_COPY = 3, + CONSTANT_POOL = 4, + NO_VALUE = 5, + SUBGRAPH = 6, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl new file mode 100644 index 0000000000..ebb361b762 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable OperandPerformance { + android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32; + android.hardware.neuralnetworks.PerformanceInfo info; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl new file mode 100644 index 0000000000..9f2c759d38 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum OperandType { + FLOAT32 = 0, + INT32 = 1, + UINT32 = 2, + TENSOR_FLOAT32 = 3, + TENSOR_INT32 = 4, + TENSOR_QUANT8_ASYMM = 5, + BOOL = 6, + TENSOR_QUANT16_SYMM = 7, + TENSOR_FLOAT16 = 8, + TENSOR_BOOL8 = 9, + FLOAT16 = 10, + TENSOR_QUANT8_SYMM_PER_CHANNEL = 11, + TENSOR_QUANT16_ASYMM = 12, + TENSOR_QUANT8_SYMM = 13, + TENSOR_QUANT8_ASYMM_SIGNED = 14, + SUBGRAPH = 15, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl new file mode 100644 index 0000000000..a4a3fbee60 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Operation { + android.hardware.neuralnetworks.OperationType type = android.hardware.neuralnetworks.OperationType.ADD; + int[] inputs; + int[] outputs; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl new file mode 100644 index 0000000000..34506c8860 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum OperationType { + ADD = 0, + AVERAGE_POOL_2D = 1, + CONCATENATION = 2, + CONV_2D = 3, + DEPTHWISE_CONV_2D = 4, + DEPTH_TO_SPACE = 5, + DEQUANTIZE = 6, + EMBEDDING_LOOKUP = 7, + FLOOR = 8, + FULLY_CONNECTED = 9, + HASHTABLE_LOOKUP = 10, + L2_NORMALIZATION = 11, + L2_POOL_2D = 12, + LOCAL_RESPONSE_NORMALIZATION = 13, + LOGISTIC = 14, + LSH_PROJECTION = 15, + LSTM = 16, + MAX_POOL_2D = 17, + MUL = 18, + RELU = 19, + RELU1 = 20, + RELU6 = 21, + RESHAPE = 22, + RESIZE_BILINEAR = 23, + RNN = 24, + SOFTMAX = 25, + SPACE_TO_DEPTH = 26, + SVDF = 27, + TANH = 28, + BATCH_TO_SPACE_ND = 29, + DIV = 30, + MEAN = 31, + PAD = 32, + SPACE_TO_BATCH_ND = 33, + SQUEEZE = 34, + STRIDED_SLICE = 35, + SUB = 36, + TRANSPOSE = 37, + ABS = 38, + ARGMAX = 39, + ARGMIN = 40, + AXIS_ALIGNED_BBOX_TRANSFORM = 41, + BIDIRECTIONAL_SEQUENCE_LSTM = 42, + BIDIRECTIONAL_SEQUENCE_RNN = 43, + BOX_WITH_NMS_LIMIT = 44, + CAST = 45, + CHANNEL_SHUFFLE = 46, + DETECTION_POSTPROCESSING = 47, + EQUAL = 48, + EXP = 49, + EXPAND_DIMS = 50, + GATHER = 51, + GENERATE_PROPOSALS = 52, + GREATER = 53, + GREATER_EQUAL = 54, + GROUPED_CONV_2D = 55, + HEATMAP_MAX_KEYPOINT = 56, + INSTANCE_NORMALIZATION = 57, + LESS = 58, + LESS_EQUAL = 59, + LOG = 60, + LOGICAL_AND = 61, + LOGICAL_NOT = 62, + LOGICAL_OR = 63, + LOG_SOFTMAX = 64, + MAXIMUM = 65, + MINIMUM = 66, + NEG = 67, + NOT_EQUAL = 68, + PAD_V2 = 69, + POW = 70, + PRELU = 71, + QUANTIZE = 72, + QUANTIZED_16BIT_LSTM = 73, + RANDOM_MULTINOMIAL = 74, + REDUCE_ALL = 75, + REDUCE_ANY = 76, + REDUCE_MAX = 77, + REDUCE_MIN = 78, + REDUCE_PROD = 79, + REDUCE_SUM = 80, + ROI_ALIGN = 81, + ROI_POOLING = 82, + RSQRT = 83, + SELECT = 84, + SIN = 85, + SLICE = 86, + SPLIT = 87, + SQRT = 88, + TILE = 89, + TOPK_V2 = 90, + TRANSPOSE_CONV_2D = 91, + UNIDIRECTIONAL_SEQUENCE_LSTM = 92, + UNIDIRECTIONAL_SEQUENCE_RNN = 93, + RESIZE_NEAREST_NEIGHBOR = 94, + QUANTIZED_LSTM = 95, + IF = 96, + WHILE = 97, + ELU = 98, + HARD_SWISH = 99, + FILL = 100, + RANK = 101, + BATCH_MATMUL = 102, + PACK = 103, + MIRROR_PAD = 104, + REVERSE = 105, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl new file mode 100644 index 0000000000..f7335054cf --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable OutputShape { + int[] dimensions; + boolean isSufficient; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl new file mode 100644 index 0000000000..04910f5410 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable PerformanceInfo { + float execTime; + float powerUsage; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl new file mode 100644 index 0000000000..8f357097ab --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum Priority { + LOW = 0, + MEDIUM = 1, + HIGH = 2, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl new file mode 100644 index 0000000000..39ec7a9acd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Request { + android.hardware.neuralnetworks.RequestArgument[] inputs; + android.hardware.neuralnetworks.RequestArgument[] outputs; + android.hardware.neuralnetworks.RequestMemoryPool[] pools; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl new file mode 100644 index 0000000000..e3541c0ece --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable RequestArgument { + boolean hasNoValue; + android.hardware.neuralnetworks.DataLocation location; + int[] dimensions; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl new file mode 100644 index 0000000000..312f5813bc --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +union RequestMemoryPool { + android.hardware.neuralnetworks.Memory pool; + int token; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl new file mode 100644 index 0000000000..b7d44515f4 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Subgraph { + android.hardware.neuralnetworks.Operand[] operands; + android.hardware.neuralnetworks.Operation[] operations; + int[] inputIndexes; + int[] outputIndexes; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl new file mode 100644 index 0000000000..02d68f9ed1 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable SymmPerChannelQuantParams { + float[] scales; + int channelDim; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl new file mode 100644 index 0000000000..bcc83cfbee --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Timing { + long timeOnDeviceNs; + long timeInDriverNs; +} -- cgit v1.2.3 From 687ce13059f60539d8e2dfc1e6ba74c04fb78602 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Tue, 11 Jan 2022 16:42:48 -0800 Subject: Wifi: Uprev wifi HAL to 1.6 This commit uprevs the Wifi vendor HAL to 1.6 Bug: 214108561 Test: atest VtsHalWifiV1_0TargetTest VtsHalWifiNanV1_0TargetTest VtsHalWifiApV1_0TargetTest \ VtsHalWifiV1_1TargetTest \ VtsHalWifiV1_2TargetTest VtsHalWifiNanV1_2TargetTest \ VtsHalWifiV1_3TargetTest \ VtsHalWifiApV1_4TargetTest VtsHalWifiNanV1_4TargetTest VtsHalWifiRttV1_4TargetTest \ VtsHalWifiV1_5TargetTest VtsHalWifiNanV1_5TargetTest VtsHalWifiApV1_5TargetTest Change-Id: I059a5de346e353f7fba1e008ecd9fb4611e66880 --- .../compatibility_matrix.current.xml | 2 +- wifi/1.5/default/Android.bp | 105 - wifi/1.5/default/Android.mk | 198 -- wifi/1.5/default/OWNERS | 2 - wifi/1.5/default/THREADING.README | 35 - .../android.hardware.wifi@1.0-service-lazy.rc | 13 - .../default/android.hardware.wifi@1.0-service.rc | 11 - .../default/android.hardware.wifi@1.0-service.xml | 11 - wifi/1.5/default/hidl_callback_util.h | 124 - wifi/1.5/default/hidl_return_util.h | 120 - wifi/1.5/default/hidl_struct_util.cpp | 3059 -------------------- wifi/1.5/default/hidl_struct_util.h | 227 -- wifi/1.5/default/hidl_sync_util.cpp | 39 - wifi/1.5/default/hidl_sync_util.h | 37 - wifi/1.5/default/ringbuffer.cpp | 59 - wifi/1.5/default/ringbuffer.h | 54 - wifi/1.5/default/service.cpp | 79 - .../default/tests/hidl_struct_util_unit_tests.cpp | 424 --- wifi/1.5/default/tests/main.cpp | 28 - wifi/1.5/default/tests/mock_interface_tool.cpp | 29 - wifi/1.5/default/tests/mock_interface_tool.h | 44 - wifi/1.5/default/tests/mock_wifi_feature_flags.cpp | 35 - wifi/1.5/default/tests/mock_wifi_feature_flags.h | 48 - wifi/1.5/default/tests/mock_wifi_iface_util.cpp | 40 - wifi/1.5/default/tests/mock_wifi_iface_util.h | 54 - wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp | 40 - wifi/1.5/default/tests/mock_wifi_legacy_hal.h | 74 - .../default/tests/mock_wifi_mode_controller.cpp | 37 - wifi/1.5/default/tests/mock_wifi_mode_controller.h | 46 - wifi/1.5/default/tests/ringbuffer_unit_tests.cpp | 97 - wifi/1.5/default/tests/runtests.sh | 26 - wifi/1.5/default/tests/wifi_chip_unit_tests.cpp | 905 ------ .../default/tests/wifi_iface_util_unit_tests.cpp | 101 - .../default/tests/wifi_nan_iface_unit_tests.cpp | 162 -- wifi/1.5/default/wifi.cpp | 304 -- wifi/1.5/default/wifi.h | 111 - wifi/1.5/default/wifi_ap_iface.cpp | 220 -- wifi/1.5/default/wifi_ap_iface.h | 95 - wifi/1.5/default/wifi_chip.cpp | 2065 ------------- wifi/1.5/default/wifi_chip.h | 343 --- wifi/1.5/default/wifi_feature_flags.cpp | 244 -- wifi/1.5/default/wifi_feature_flags.h | 59 - wifi/1.5/default/wifi_iface_util.cpp | 184 -- wifi/1.5/default/wifi_iface_util.h | 91 - wifi/1.5/default/wifi_legacy_hal.cpp | 1725 ----------- wifi/1.5/default/wifi_legacy_hal.h | 763 ----- wifi/1.5/default/wifi_legacy_hal_factory.cpp | 263 -- wifi/1.5/default/wifi_legacy_hal_factory.h | 67 - wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 171 -- wifi/1.5/default/wifi_legacy_hal_stubs.h | 37 - wifi/1.5/default/wifi_mode_controller.cpp | 91 - wifi/1.5/default/wifi_mode_controller.h | 63 - wifi/1.5/default/wifi_nan_iface.cpp | 1003 ------- wifi/1.5/default/wifi_nan_iface.h | 212 -- wifi/1.5/default/wifi_p2p_iface.cpp | 66 - wifi/1.5/default/wifi_p2p_iface.h | 66 - wifi/1.5/default/wifi_rtt_controller.cpp | 351 --- wifi/1.5/default/wifi_rtt_controller.h | 130 - wifi/1.5/default/wifi_sta_iface.cpp | 675 ----- wifi/1.5/default/wifi_sta_iface.h | 187 -- wifi/1.5/default/wifi_status_util.cpp | 112 - wifi/1.5/default/wifi_status_util.h | 45 - wifi/1.6/Android.bp | 32 + wifi/1.6/IWifi.hal | 27 + wifi/1.6/default/Android.bp | 105 + wifi/1.6/default/Android.mk | 202 ++ wifi/1.6/default/OWNERS | 2 + wifi/1.6/default/THREADING.README | 35 + .../android.hardware.wifi@1.0-service-lazy.rc | 13 + .../default/android.hardware.wifi@1.0-service.rc | 12 + .../default/android.hardware.wifi@1.0-service.xml | 11 + wifi/1.6/default/hidl_callback_util.h | 119 + wifi/1.6/default/hidl_return_util.h | 118 + wifi/1.6/default/hidl_struct_util.cpp | 2748 ++++++++++++++++++ wifi/1.6/default/hidl_struct_util.h | 200 ++ wifi/1.6/default/hidl_sync_util.cpp | 39 + wifi/1.6/default/hidl_sync_util.h | 37 + wifi/1.6/default/ringbuffer.cpp | 58 + wifi/1.6/default/ringbuffer.h | 54 + wifi/1.6/default/service.cpp | 71 + .../default/tests/hidl_struct_util_unit_tests.cpp | 385 +++ wifi/1.6/default/tests/main.cpp | 28 + wifi/1.6/default/tests/mock_interface_tool.cpp | 29 + wifi/1.6/default/tests/mock_interface_tool.h | 42 + wifi/1.6/default/tests/mock_wifi_feature_flags.cpp | 35 + wifi/1.6/default/tests/mock_wifi_feature_flags.h | 47 + wifi/1.6/default/tests/mock_wifi_iface_util.cpp | 39 + wifi/1.6/default/tests/mock_wifi_iface_util.h | 50 + wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp | 39 + wifi/1.6/default/tests/mock_wifi_legacy_hal.h | 67 + .../default/tests/mock_wifi_mode_controller.cpp | 37 + wifi/1.6/default/tests/mock_wifi_mode_controller.h | 46 + wifi/1.6/default/tests/ringbuffer_unit_tests.cpp | 97 + wifi/1.6/default/tests/runtests.sh | 26 + wifi/1.6/default/tests/wifi_chip_unit_tests.cpp | 854 ++++++ .../default/tests/wifi_iface_util_unit_tests.cpp | 96 + .../default/tests/wifi_nan_iface_unit_tests.cpp | 132 + wifi/1.6/default/wifi.cpp | 294 ++ wifi/1.6/default/wifi.h | 105 + wifi/1.6/default/wifi_ap_iface.cpp | 204 ++ wifi/1.6/default/wifi_ap_iface.h | 89 + wifi/1.6/default/wifi_chip.cpp | 1903 ++++++++++++ wifi/1.6/default/wifi_chip.h | 294 ++ wifi/1.6/default/wifi_feature_flags.cpp | 239 ++ wifi/1.6/default/wifi_feature_flags.h | 58 + wifi/1.6/default/wifi_iface_util.cpp | 176 ++ wifi/1.6/default/wifi_iface_util.h | 87 + wifi/1.6/default/wifi_legacy_hal.cpp | 1578 ++++++++++ wifi/1.6/default/wifi_legacy_hal.h | 700 +++++ wifi/1.6/default/wifi_legacy_hal_factory.cpp | 254 ++ wifi/1.6/default/wifi_legacy_hal_factory.h | 66 + wifi/1.6/default/wifi_legacy_hal_stubs.cpp | 171 ++ wifi/1.6/default/wifi_legacy_hal_stubs.h | 37 + wifi/1.6/default/wifi_mode_controller.cpp | 89 + wifi/1.6/default/wifi_mode_controller.h | 63 + wifi/1.6/default/wifi_nan_iface.cpp | 905 ++++++ wifi/1.6/default/wifi_nan_iface.h | 174 ++ wifi/1.6/default/wifi_p2p_iface.cpp | 69 + wifi/1.6/default/wifi_p2p_iface.h | 66 + wifi/1.6/default/wifi_rtt_controller.cpp | 311 ++ wifi/1.6/default/wifi_rtt_controller.h | 117 + wifi/1.6/default/wifi_sta_iface.cpp | 583 ++++ wifi/1.6/default/wifi_sta_iface.h | 155 + wifi/1.6/default/wifi_status_util.cpp | 106 + wifi/1.6/default/wifi_status_util.h | 44 + 125 files changed, 14870 insertions(+), 16107 deletions(-) delete mode 100644 wifi/1.5/default/Android.bp delete mode 100644 wifi/1.5/default/Android.mk delete mode 100644 wifi/1.5/default/OWNERS delete mode 100644 wifi/1.5/default/THREADING.README delete mode 100644 wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc delete mode 100644 wifi/1.5/default/android.hardware.wifi@1.0-service.rc delete mode 100644 wifi/1.5/default/android.hardware.wifi@1.0-service.xml delete mode 100644 wifi/1.5/default/hidl_callback_util.h delete mode 100644 wifi/1.5/default/hidl_return_util.h delete mode 100644 wifi/1.5/default/hidl_struct_util.cpp delete mode 100644 wifi/1.5/default/hidl_struct_util.h delete mode 100644 wifi/1.5/default/hidl_sync_util.cpp delete mode 100644 wifi/1.5/default/hidl_sync_util.h delete mode 100644 wifi/1.5/default/ringbuffer.cpp delete mode 100644 wifi/1.5/default/ringbuffer.h delete mode 100644 wifi/1.5/default/service.cpp delete mode 100644 wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp delete mode 100644 wifi/1.5/default/tests/main.cpp delete mode 100644 wifi/1.5/default/tests/mock_interface_tool.cpp delete mode 100644 wifi/1.5/default/tests/mock_interface_tool.h delete mode 100644 wifi/1.5/default/tests/mock_wifi_feature_flags.cpp delete mode 100644 wifi/1.5/default/tests/mock_wifi_feature_flags.h delete mode 100644 wifi/1.5/default/tests/mock_wifi_iface_util.cpp delete mode 100644 wifi/1.5/default/tests/mock_wifi_iface_util.h delete mode 100644 wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp delete mode 100644 wifi/1.5/default/tests/mock_wifi_legacy_hal.h delete mode 100644 wifi/1.5/default/tests/mock_wifi_mode_controller.cpp delete mode 100644 wifi/1.5/default/tests/mock_wifi_mode_controller.h delete mode 100644 wifi/1.5/default/tests/ringbuffer_unit_tests.cpp delete mode 100755 wifi/1.5/default/tests/runtests.sh delete mode 100644 wifi/1.5/default/tests/wifi_chip_unit_tests.cpp delete mode 100644 wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp delete mode 100644 wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp delete mode 100644 wifi/1.5/default/wifi.cpp delete mode 100644 wifi/1.5/default/wifi.h delete mode 100644 wifi/1.5/default/wifi_ap_iface.cpp delete mode 100644 wifi/1.5/default/wifi_ap_iface.h delete mode 100644 wifi/1.5/default/wifi_chip.cpp delete mode 100644 wifi/1.5/default/wifi_chip.h delete mode 100644 wifi/1.5/default/wifi_feature_flags.cpp delete mode 100644 wifi/1.5/default/wifi_feature_flags.h delete mode 100644 wifi/1.5/default/wifi_iface_util.cpp delete mode 100644 wifi/1.5/default/wifi_iface_util.h delete mode 100644 wifi/1.5/default/wifi_legacy_hal.cpp delete mode 100644 wifi/1.5/default/wifi_legacy_hal.h delete mode 100644 wifi/1.5/default/wifi_legacy_hal_factory.cpp delete mode 100644 wifi/1.5/default/wifi_legacy_hal_factory.h delete mode 100644 wifi/1.5/default/wifi_legacy_hal_stubs.cpp delete mode 100644 wifi/1.5/default/wifi_legacy_hal_stubs.h delete mode 100644 wifi/1.5/default/wifi_mode_controller.cpp delete mode 100644 wifi/1.5/default/wifi_mode_controller.h delete mode 100644 wifi/1.5/default/wifi_nan_iface.cpp delete mode 100644 wifi/1.5/default/wifi_nan_iface.h delete mode 100644 wifi/1.5/default/wifi_p2p_iface.cpp delete mode 100644 wifi/1.5/default/wifi_p2p_iface.h delete mode 100644 wifi/1.5/default/wifi_rtt_controller.cpp delete mode 100644 wifi/1.5/default/wifi_rtt_controller.h delete mode 100644 wifi/1.5/default/wifi_sta_iface.cpp delete mode 100644 wifi/1.5/default/wifi_sta_iface.h delete mode 100644 wifi/1.5/default/wifi_status_util.cpp delete mode 100644 wifi/1.5/default/wifi_status_util.h create mode 100644 wifi/1.6/Android.bp create mode 100644 wifi/1.6/IWifi.hal create mode 100644 wifi/1.6/default/Android.bp create mode 100644 wifi/1.6/default/Android.mk create mode 100644 wifi/1.6/default/OWNERS create mode 100644 wifi/1.6/default/THREADING.README create mode 100644 wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc create mode 100644 wifi/1.6/default/android.hardware.wifi@1.0-service.rc create mode 100644 wifi/1.6/default/android.hardware.wifi@1.0-service.xml create mode 100644 wifi/1.6/default/hidl_callback_util.h create mode 100644 wifi/1.6/default/hidl_return_util.h create mode 100644 wifi/1.6/default/hidl_struct_util.cpp create mode 100644 wifi/1.6/default/hidl_struct_util.h create mode 100644 wifi/1.6/default/hidl_sync_util.cpp create mode 100644 wifi/1.6/default/hidl_sync_util.h create mode 100644 wifi/1.6/default/ringbuffer.cpp create mode 100644 wifi/1.6/default/ringbuffer.h create mode 100644 wifi/1.6/default/service.cpp create mode 100644 wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp create mode 100644 wifi/1.6/default/tests/main.cpp create mode 100644 wifi/1.6/default/tests/mock_interface_tool.cpp create mode 100644 wifi/1.6/default/tests/mock_interface_tool.h create mode 100644 wifi/1.6/default/tests/mock_wifi_feature_flags.cpp create mode 100644 wifi/1.6/default/tests/mock_wifi_feature_flags.h create mode 100644 wifi/1.6/default/tests/mock_wifi_iface_util.cpp create mode 100644 wifi/1.6/default/tests/mock_wifi_iface_util.h create mode 100644 wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp create mode 100644 wifi/1.6/default/tests/mock_wifi_legacy_hal.h create mode 100644 wifi/1.6/default/tests/mock_wifi_mode_controller.cpp create mode 100644 wifi/1.6/default/tests/mock_wifi_mode_controller.h create mode 100644 wifi/1.6/default/tests/ringbuffer_unit_tests.cpp create mode 100755 wifi/1.6/default/tests/runtests.sh create mode 100644 wifi/1.6/default/tests/wifi_chip_unit_tests.cpp create mode 100644 wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp create mode 100644 wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp create mode 100644 wifi/1.6/default/wifi.cpp create mode 100644 wifi/1.6/default/wifi.h create mode 100644 wifi/1.6/default/wifi_ap_iface.cpp create mode 100644 wifi/1.6/default/wifi_ap_iface.h create mode 100644 wifi/1.6/default/wifi_chip.cpp create mode 100644 wifi/1.6/default/wifi_chip.h create mode 100644 wifi/1.6/default/wifi_feature_flags.cpp create mode 100644 wifi/1.6/default/wifi_feature_flags.h create mode 100644 wifi/1.6/default/wifi_iface_util.cpp create mode 100644 wifi/1.6/default/wifi_iface_util.h create mode 100644 wifi/1.6/default/wifi_legacy_hal.cpp create mode 100644 wifi/1.6/default/wifi_legacy_hal.h create mode 100644 wifi/1.6/default/wifi_legacy_hal_factory.cpp create mode 100644 wifi/1.6/default/wifi_legacy_hal_factory.h create mode 100644 wifi/1.6/default/wifi_legacy_hal_stubs.cpp create mode 100644 wifi/1.6/default/wifi_legacy_hal_stubs.h create mode 100644 wifi/1.6/default/wifi_mode_controller.cpp create mode 100644 wifi/1.6/default/wifi_mode_controller.h create mode 100644 wifi/1.6/default/wifi_nan_iface.cpp create mode 100644 wifi/1.6/default/wifi_nan_iface.h create mode 100644 wifi/1.6/default/wifi_p2p_iface.cpp create mode 100644 wifi/1.6/default/wifi_p2p_iface.h create mode 100644 wifi/1.6/default/wifi_rtt_controller.cpp create mode 100644 wifi/1.6/default/wifi_rtt_controller.h create mode 100644 wifi/1.6/default/wifi_sta_iface.cpp create mode 100644 wifi/1.6/default/wifi_sta_iface.h create mode 100644 wifi/1.6/default/wifi_status_util.cpp create mode 100644 wifi/1.6/default/wifi_status_util.h diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index cf856889df..aaebb6b813 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -777,7 +777,7 @@ android.hardware.wifi - 1.3-5 + 1.3-6 IWifi default diff --git a/wifi/1.5/default/Android.bp b/wifi/1.5/default/Android.bp deleted file mode 100644 index 6333b6e265..0000000000 --- a/wifi/1.5/default/Android.bp +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (C) 2021 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 { - default_applicable_licenses: ["hardware_interfaces_license"], -} - -filegroup { - name: "android.hardware.wifi@1.0-service_srcs", - srcs: ["service.cpp"], -} - -cc_defaults { - name: "android.hardware.wifi@1.0-service_default", - srcs: [":android.hardware.wifi@1.0-service_srcs"], - relative_install_path: "hw", - soc_specific: true, - shared_libs: [ - "android.hardware.wifi@1.0", - "android.hardware.wifi@1.1", - "android.hardware.wifi@1.2", - "android.hardware.wifi@1.3", - "android.hardware.wifi@1.4", - "android.hardware.wifi@1.5", - "libbase", - "libcutils", - "libhidlbase", - "liblog", - "libnl", - "libutils", - "libwifi-system-iface", - "libxml2", - ], - cppflags: [ - "-Wall", - "-Werror", - "-Wextra", - ], -} - -filegroup { - name: "android.hardware.wifi@1.0-service-lib_srcs", - srcs: [ - "hidl_struct_util.cpp", - "hidl_sync_util.cpp", - "ringbuffer.cpp", - "wifi.cpp", - "wifi_ap_iface.cpp", - "wifi_chip.cpp", - "wifi_feature_flags.cpp", - "wifi_iface_util.cpp", - "wifi_legacy_hal.cpp", - "wifi_legacy_hal_factory.cpp", - "wifi_legacy_hal_stubs.cpp", - "wifi_mode_controller.cpp", - "wifi_nan_iface.cpp", - "wifi_p2p_iface.cpp", - "wifi_rtt_controller.cpp", - "wifi_sta_iface.cpp", - "wifi_status_util.cpp", - ], -} - -cc_defaults { - name: "android.hardware.wifi@1.0-service-lib_defaults", - srcs: [":android.hardware.wifi@1.0-service-lib_srcs"], - relative_install_path: "hw", - soc_specific: true, - shared_libs: [ - "android.hardware.wifi@1.0", - "android.hardware.wifi@1.1", - "android.hardware.wifi@1.2", - "android.hardware.wifi@1.3", - "android.hardware.wifi@1.4", - "android.hardware.wifi@1.5", - "libbase", - "libcutils", - "libhidlbase", - "liblog", - "libnl", - "libutils", - "libwifi-system-iface", - "libxml2", - ], - // Generated by building android.hardware.wifi@1.0-service-lib and printing LOCAL_CPPFLAGS. - cppflags: [ - "-Wall", - "-Werror", - "-Wextra", - "-DWIFI_HIDL_FEATURE_DUAL_INTERFACE", - ], - export_include_dirs: ["."], - include_dirs: ["external/libxml2/include"], -} diff --git a/wifi/1.5/default/Android.mk b/wifi/1.5/default/Android.mk deleted file mode 100644 index 1997b2209f..0000000000 --- a/wifi/1.5/default/Android.mk +++ /dev/null @@ -1,198 +0,0 @@ -# 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. -LOCAL_PATH := $(call my-dir) - -### -### android.hardware.wifi static library -### -include $(CLEAR_VARS) -LOCAL_MODULE := android.hardware.wifi@1.0-service-lib -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE -LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_PROPRIETARY_MODULE := true -LOCAL_CPPFLAGS := -Wall -Werror -Wextra -ifdef WIFI_HAL_INTERFACE_COMBINATIONS -LOCAL_CPPFLAGS += -DWIFI_HAL_INTERFACE_COMBINATIONS="$(WIFI_HAL_INTERFACE_COMBINATIONS)" -endif -ifdef WIFI_HIDL_FEATURE_AWARE -LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_AWARE -endif -ifdef WIFI_HIDL_FEATURE_DUAL_INTERFACE -LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DUAL_INTERFACE -endif -ifdef WIFI_HIDL_FEATURE_DISABLE_AP -LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP -endif -ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION -LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION -endif -ifdef WIFI_AVOID_IFACE_RESET_MAC_CHANGE -LOCAL_CPPFLAGS += -DWIFI_AVOID_IFACE_RESET_MAC_CHANGE -endif -# Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed. -LOCAL_CFLAGS += -Wno-error=implicit-fallthrough -LOCAL_SRC_FILES := \ - hidl_struct_util.cpp \ - hidl_sync_util.cpp \ - ringbuffer.cpp \ - wifi.cpp \ - wifi_ap_iface.cpp \ - wifi_chip.cpp \ - wifi_feature_flags.cpp \ - wifi_iface_util.cpp \ - wifi_legacy_hal.cpp \ - wifi_legacy_hal_factory.cpp \ - wifi_legacy_hal_stubs.cpp \ - wifi_mode_controller.cpp \ - wifi_nan_iface.cpp \ - wifi_p2p_iface.cpp \ - wifi_rtt_controller.cpp \ - wifi_sta_iface.cpp \ - wifi_status_util.cpp -LOCAL_SHARED_LIBRARIES := \ - libbase \ - libcutils \ - libhidlbase \ - liblog \ - libnl \ - libutils \ - libwifi-hal \ - libwifi-system-iface \ - libxml2 \ - android.hardware.wifi@1.0 \ - android.hardware.wifi@1.1 \ - android.hardware.wifi@1.2 \ - android.hardware.wifi@1.3 \ - android.hardware.wifi@1.4 \ - android.hardware.wifi@1.5 -LOCAL_C_INCLUDES += $(TOP)/external/libxml2/include -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) -include $(BUILD_STATIC_LIBRARY) - -### -### android.hardware.wifi daemon -### -include $(CLEAR_VARS) -LOCAL_MODULE := android.hardware.wifi@1.0-service -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE -LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml -LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_PROPRIETARY_MODULE := true -LOCAL_CPPFLAGS := -Wall -Werror -Wextra -LOCAL_SRC_FILES := \ - service.cpp -LOCAL_SHARED_LIBRARIES := \ - libbase \ - libcutils \ - libhidlbase \ - liblog \ - libnl \ - libutils \ - libwifi-hal \ - libwifi-system-iface \ - libxml2 \ - android.hardware.wifi@1.0 \ - android.hardware.wifi@1.1 \ - android.hardware.wifi@1.2 \ - android.hardware.wifi@1.3 \ - android.hardware.wifi@1.4 \ - android.hardware.wifi@1.5 -LOCAL_STATIC_LIBRARIES := \ - android.hardware.wifi@1.0-service-lib -LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc -include $(BUILD_EXECUTABLE) - -### -### android.hardware.wifi daemon -### -include $(CLEAR_VARS) -LOCAL_MODULE := android.hardware.wifi@1.0-service-lazy -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE -LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml -LOCAL_OVERRIDES_MODULES := android.hardware.wifi@1.0-service -LOCAL_CFLAGS := -DLAZY_SERVICE -LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_PROPRIETARY_MODULE := true -LOCAL_CPPFLAGS := -Wall -Werror -Wextra -LOCAL_SRC_FILES := \ - service.cpp -LOCAL_SHARED_LIBRARIES := \ - libbase \ - libcutils \ - libhidlbase \ - liblog \ - libnl \ - libutils \ - libwifi-hal \ - libwifi-system-iface \ - libxml2 \ - android.hardware.wifi@1.0 \ - android.hardware.wifi@1.1 \ - android.hardware.wifi@1.2 \ - android.hardware.wifi@1.3 \ - android.hardware.wifi@1.4 \ - android.hardware.wifi@1.5 -LOCAL_STATIC_LIBRARIES := \ - android.hardware.wifi@1.0-service-lib -LOCAL_INIT_RC := android.hardware.wifi@1.0-service-lazy.rc -include $(BUILD_EXECUTABLE) - -### -### android.hardware.wifi unit tests. -### -include $(CLEAR_VARS) -LOCAL_MODULE := android.hardware.wifi@1.0-service-tests -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE -LOCAL_PROPRIETARY_MODULE := true -LOCAL_CPPFLAGS := -Wall -Werror -Wextra -LOCAL_SRC_FILES := \ - tests/hidl_struct_util_unit_tests.cpp \ - tests/main.cpp \ - tests/mock_interface_tool.cpp \ - tests/mock_wifi_feature_flags.cpp \ - tests/mock_wifi_iface_util.cpp \ - tests/mock_wifi_legacy_hal.cpp \ - tests/mock_wifi_mode_controller.cpp \ - tests/ringbuffer_unit_tests.cpp \ - tests/wifi_nan_iface_unit_tests.cpp \ - tests/wifi_chip_unit_tests.cpp \ - tests/wifi_iface_util_unit_tests.cpp -LOCAL_STATIC_LIBRARIES := \ - libgmock \ - libgtest \ - android.hardware.wifi@1.0 \ - android.hardware.wifi@1.1 \ - android.hardware.wifi@1.2 \ - android.hardware.wifi@1.3 \ - android.hardware.wifi@1.4 \ - android.hardware.wifi@1.5 \ - android.hardware.wifi@1.0-service-lib -LOCAL_SHARED_LIBRARIES := \ - libbase \ - libcutils \ - libhidlbase \ - liblog \ - libnl \ - libutils \ - libwifi-hal \ - libwifi-system-iface -include $(BUILD_NATIVE_TEST) diff --git a/wifi/1.5/default/OWNERS b/wifi/1.5/default/OWNERS deleted file mode 100644 index cf81c79892..0000000000 --- a/wifi/1.5/default/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -arabawy@google.com -etancohen@google.com diff --git a/wifi/1.5/default/THREADING.README b/wifi/1.5/default/THREADING.README deleted file mode 100644 index 8366ca0201..0000000000 --- a/wifi/1.5/default/THREADING.README +++ /dev/null @@ -1,35 +0,0 @@ -Vendor HAL Threading Model -========================== -The vendor HAL service has two threads: -1. HIDL thread: This is the main thread which processes all the incoming HIDL -RPC's. -2. Legacy HAL event loop thread: This is the thread forked off for processing -the legacy HAL event loop (wifi_event_loop()). This thread is used to process -any asynchronous netlink events posted by the driver. Any asynchronous -callbacks passed to the legacy HAL API's are invoked on this thread. - -Synchronization Concerns -======================== -wifi_legacy_hal.cpp has a bunch of global "C" style functions to handle the -legacy callbacks. Each of these "C" style function invokes a corresponding -"std::function" version of the callback which does the actual processing. -The variables holding these "std::function" callbacks are reset from the HIDL -thread when they are no longer used. For example: stopGscan() will reset the -corresponding "on_gscan_*" callback variables which were set when startGscan() -was invoked. This is not thread safe since these callback variables are -accesed from the legacy hal event loop thread as well. - -Synchronization Solution -======================== -Adding a global lock seems to be the most trivial solution to the problem. -a) All of the asynchronous "C" style callbacks will acquire the global lock -before invoking the corresponding "std::function" callback variables. -b) All of the HIDL methods will also acquire the global lock before processing -(in hidl_return_util::validateAndCall()). - -Note: It's important that we only acquire the global lock for asynchronous -callbacks, because there is no guarantee (or documentation to clarify) that the -synchronous callbacks are invoked on the same invocation thread. If that is not -the case in some implementation, we will end up deadlocking the system since the -HIDL thread would have acquired the global lock which is needed by the -synchronous callback executed on the legacy hal event loop thread. diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc deleted file mode 100644 index bc6bb6a7e6..0000000000 --- a/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc +++ /dev/null @@ -1,13 +0,0 @@ -service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service-lazy - interface android.hardware.wifi@1.0::IWifi default - interface android.hardware.wifi@1.1::IWifi default - interface android.hardware.wifi@1.2::IWifi default - interface android.hardware.wifi@1.3::IWifi default - interface android.hardware.wifi@1.4::IWifi default - interface android.hardware.wifi@1.5::IWifi default - oneshot - disabled - class hal - capabilities NET_ADMIN NET_RAW SYS_MODULE - user wifi - group wifi gps diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service.rc b/wifi/1.5/default/android.hardware.wifi@1.0-service.rc deleted file mode 100644 index 05706ef4f4..0000000000 --- a/wifi/1.5/default/android.hardware.wifi@1.0-service.rc +++ /dev/null @@ -1,11 +0,0 @@ -service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service - interface android.hardware.wifi@1.0::IWifi default - interface android.hardware.wifi@1.1::IWifi default - interface android.hardware.wifi@1.2::IWifi default - interface android.hardware.wifi@1.3::IWifi default - interface android.hardware.wifi@1.4::IWifi default - interface android.hardware.wifi@1.5::IWifi default - class hal - capabilities NET_ADMIN NET_RAW SYS_MODULE - user wifi - group wifi gps diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service.xml b/wifi/1.5/default/android.hardware.wifi@1.0-service.xml deleted file mode 100644 index 88dd1e3285..0000000000 --- a/wifi/1.5/default/android.hardware.wifi@1.0-service.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - android.hardware.wifi - hwbinder - 1.5 - - IWifi - default - - - diff --git a/wifi/1.5/default/hidl_callback_util.h b/wifi/1.5/default/hidl_callback_util.h deleted file mode 100644 index d144658750..0000000000 --- a/wifi/1.5/default/hidl_callback_util.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef HIDL_CALLBACK_UTIL_H_ -#define HIDL_CALLBACK_UTIL_H_ - -#include - -#include - -namespace { -// Type of callback invoked by the death handler. -using on_death_cb_function = std::function; - -// Private class used to keep track of death of individual -// callbacks stored in HidlCallbackHandler. -template -class HidlDeathHandler : public android::hardware::hidl_death_recipient { - public: - HidlDeathHandler(const on_death_cb_function& user_cb_function) - : cb_function_(user_cb_function) {} - ~HidlDeathHandler() = default; - - // Death notification for callbacks. - void serviceDied( - uint64_t cookie, - const android::wp& /* who */) - override { - cb_function_(cookie); - } - - private: - on_death_cb_function cb_function_; - - DISALLOW_COPY_AND_ASSIGN(HidlDeathHandler); -}; -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace hidl_callback_util { -template -// Provides a class to manage callbacks for the various HIDL interfaces and -// handle the death of the process hosting each callback. -class HidlCallbackHandler { - public: - HidlCallbackHandler() - : death_handler_(new HidlDeathHandler( - std::bind(&HidlCallbackHandler::onObjectDeath, this, - std::placeholders::_1))) {} - ~HidlCallbackHandler() = default; - - bool addCallback(const sp& cb) { - // TODO(b/33818800): Can't compare proxies yet. So, use the cookie - // (callback proxy's raw pointer) to track the death of individual - // clients. - uint64_t cookie = reinterpret_cast(cb.get()); - if (cb_set_.find(cb) != cb_set_.end()) { - LOG(WARNING) << "Duplicate death notification registration"; - return true; - } - if (!cb->linkToDeath(death_handler_, cookie)) { - LOG(ERROR) << "Failed to register death notification"; - return false; - } - cb_set_.insert(cb); - return true; - } - - const std::set>& getCallbacks() { - return cb_set_; - } - - // Death notification for callbacks. - void onObjectDeath(uint64_t cookie) { - CallbackType* cb = reinterpret_cast(cookie); - const auto& iter = cb_set_.find(cb); - if (iter == cb_set_.end()) { - LOG(ERROR) << "Unknown callback death notification received"; - return; - } - cb_set_.erase(iter); - LOG(DEBUG) << "Dead callback removed from list"; - } - - void invalidate() { - for (const sp& cb : cb_set_) { - if (!cb->unlinkToDeath(death_handler_)) { - LOG(ERROR) << "Failed to deregister death notification"; - } - } - cb_set_.clear(); - } - - private: - std::set> cb_set_; - sp> death_handler_; - - DISALLOW_COPY_AND_ASSIGN(HidlCallbackHandler); -}; - -} // namespace hidl_callback_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android -#endif // HIDL_CALLBACK_UTIL_H_ diff --git a/wifi/1.5/default/hidl_return_util.h b/wifi/1.5/default/hidl_return_util.h deleted file mode 100644 index 4455185283..0000000000 --- a/wifi/1.5/default/hidl_return_util.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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. - */ - -#ifndef HIDL_RETURN_UTIL_H_ -#define HIDL_RETURN_UTIL_H_ - -#include "hidl_sync_util.h" -#include "wifi_status_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace hidl_return_util { -using namespace android::hardware::wifi::V1_0; - -/** - * These utility functions are used to invoke a method on the provided - * HIDL interface object. - * These functions checks if the provided HIDL interface object is valid. - * a) if valid, Invokes the corresponding internal implementation function of - * the HIDL method. It then invokes the HIDL continuation callback with - * the status and any returned values. - * b) if invalid, invokes the HIDL continuation callback with the - * provided error status and default values. - */ -// Use for HIDL methods which return only an instance of WifiStatus. -template -Return validateAndCall( - ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, - const std::function& hidl_cb, Args&&... args) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (obj->isValid()) { - hidl_cb((obj->*work)(std::forward(args)...)); - } else { - hidl_cb(createWifiStatus(status_code_if_invalid)); - } - return Void(); -} - -// Use for HIDL methods which return only an instance of WifiStatus. -// This version passes the global lock acquired to the body of the method. -// Note: Only used by IWifi::stop() currently. -template -Return validateAndCallWithLock( - ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, - const std::function& hidl_cb, Args&&... args) { - auto lock = hidl_sync_util::acquireGlobalLock(); - if (obj->isValid()) { - hidl_cb((obj->*work)(&lock, std::forward(args)...)); - } else { - hidl_cb(createWifiStatus(status_code_if_invalid)); - } - return Void(); -} - -// Use for HIDL methods which return instance of WifiStatus and a single return -// value. -template -Return validateAndCall( - ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, - const std::function& hidl_cb, - Args&&... args) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (obj->isValid()) { - const auto& ret_pair = (obj->*work)(std::forward(args)...); - const WifiStatus& status = std::get<0>(ret_pair); - const auto& ret_value = std::get<1>(ret_pair); - hidl_cb(status, ret_value); - } else { - hidl_cb(createWifiStatus(status_code_if_invalid), - typename std::remove_reference::type()); - } - return Void(); -} - -// Use for HIDL methods which return instance of WifiStatus and 2 return -// values. -template -Return validateAndCall( - ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, - const std::function& hidl_cb, - Args&&... args) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (obj->isValid()) { - const auto& ret_tuple = (obj->*work)(std::forward(args)...); - const WifiStatus& status = std::get<0>(ret_tuple); - const auto& ret_value1 = std::get<1>(ret_tuple); - const auto& ret_value2 = std::get<2>(ret_tuple); - hidl_cb(status, ret_value1, ret_value2); - } else { - hidl_cb(createWifiStatus(status_code_if_invalid), - typename std::remove_reference::type(), - typename std::remove_reference::type()); - } - return Void(); -} - -} // namespace hidl_return_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android -#endif // HIDL_RETURN_UTIL_H_ diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp deleted file mode 100644 index 338a8f13c1..0000000000 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ /dev/null @@ -1,3059 +0,0 @@ -/* - * 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. - */ - -#include -#include - -#include "hidl_struct_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace hidl_struct_util { - -WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl( - legacy_hal::wifi_channel_width type); - -hidl_string safeConvertChar(const char* str, size_t max_len) { - const char* c = str; - size_t size = 0; - while (*c && (unsigned char)*c < 128 && size < max_len) { - ++size; - ++c; - } - return hidl_string(str, size); -} - -IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability( - uint32_t feature) { - using HidlChipCaps = IWifiChip::ChipCapabilityMask; - switch (feature) { - case legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED: - return HidlChipCaps::DEBUG_MEMORY_FIRMWARE_DUMP; - case legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED: - return HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP; - case legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED: - return HidlChipCaps::DEBUG_RING_BUFFER_CONNECT_EVENT; - case legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED: - return HidlChipCaps::DEBUG_RING_BUFFER_POWER_EVENT; - case legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED: - return HidlChipCaps::DEBUG_RING_BUFFER_WAKELOCK_EVENT; - }; - CHECK(false) << "Unknown legacy feature: " << feature; - return {}; -} - -IWifiStaIface::StaIfaceCapabilityMask -convertLegacyLoggerFeatureToHidlStaIfaceCapability(uint32_t feature) { - using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask; - switch (feature) { - case legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED: - return HidlStaIfaceCaps::DEBUG_PACKET_FATE; - }; - CHECK(false) << "Unknown legacy feature: " << feature; - return {}; -} - -V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability( - uint64_t feature) { - using HidlChipCaps = V1_5::IWifiChip::ChipCapabilityMask; - switch (feature) { - case WIFI_FEATURE_SET_TX_POWER_LIMIT: - return HidlChipCaps::SET_TX_POWER_LIMIT; - case WIFI_FEATURE_USE_BODY_HEAD_SAR: - return HidlChipCaps::USE_BODY_HEAD_SAR; - case WIFI_FEATURE_D2D_RTT: - return HidlChipCaps::D2D_RTT; - case WIFI_FEATURE_D2AP_RTT: - return HidlChipCaps::D2AP_RTT; - case WIFI_FEATURE_INFRA_60G: - return HidlChipCaps::WIGIG; - case WIFI_FEATURE_SET_LATENCY_MODE: - return HidlChipCaps::SET_LATENCY_MODE; - case WIFI_FEATURE_P2P_RAND_MAC: - return HidlChipCaps::P2P_RAND_MAC; - }; - CHECK(false) << "Unknown legacy feature: " << feature; - return {}; -} - -IWifiStaIface::StaIfaceCapabilityMask -convertLegacyFeatureToHidlStaIfaceCapability(uint64_t feature) { - using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask; - switch (feature) { - case WIFI_FEATURE_GSCAN: - return HidlStaIfaceCaps::BACKGROUND_SCAN; - case WIFI_FEATURE_LINK_LAYER_STATS: - return HidlStaIfaceCaps::LINK_LAYER_STATS; - case WIFI_FEATURE_RSSI_MONITOR: - return HidlStaIfaceCaps::RSSI_MONITOR; - case WIFI_FEATURE_CONTROL_ROAMING: - return HidlStaIfaceCaps::CONTROL_ROAMING; - case WIFI_FEATURE_IE_WHITELIST: - return HidlStaIfaceCaps::PROBE_IE_WHITELIST; - case WIFI_FEATURE_SCAN_RAND: - return HidlStaIfaceCaps::SCAN_RAND; - case WIFI_FEATURE_INFRA_5G: - return HidlStaIfaceCaps::STA_5G; - case WIFI_FEATURE_HOTSPOT: - return HidlStaIfaceCaps::HOTSPOT; - case WIFI_FEATURE_PNO: - return HidlStaIfaceCaps::PNO; - case WIFI_FEATURE_TDLS: - return HidlStaIfaceCaps::TDLS; - case WIFI_FEATURE_TDLS_OFFCHANNEL: - return HidlStaIfaceCaps::TDLS_OFFCHANNEL; - case WIFI_FEATURE_CONFIG_NDO: - return HidlStaIfaceCaps::ND_OFFLOAD; - case WIFI_FEATURE_MKEEP_ALIVE: - return HidlStaIfaceCaps::KEEP_ALIVE; - }; - CHECK(false) << "Unknown legacy feature: " << feature; - return {}; -} - -bool convertLegacyFeaturesToHidlChipCapabilities( - uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set, - uint32_t* hidl_caps) { - if (!hidl_caps) { - return false; - } - *hidl_caps = {}; - using HidlChipCaps = IWifiChip::ChipCapabilityMask; - for (const auto feature : {legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED, - legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED, - legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED, - legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED, - legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED}) { - if (feature & legacy_logger_feature_set) { - *hidl_caps |= - convertLegacyLoggerFeatureToHidlChipCapability(feature); - } - } - std::vector features = {WIFI_FEATURE_SET_TX_POWER_LIMIT, - WIFI_FEATURE_USE_BODY_HEAD_SAR, - WIFI_FEATURE_D2D_RTT, - WIFI_FEATURE_D2AP_RTT, - WIFI_FEATURE_INFRA_60G, - WIFI_FEATURE_SET_LATENCY_MODE, - WIFI_FEATURE_P2P_RAND_MAC}; - for (const auto feature : features) { - if (feature & legacy_feature_set) { - *hidl_caps |= convertLegacyFeatureToHidlChipCapability(feature); - } - } - - // There are no flags for these 3 in the legacy feature set. Adding them to - // the set because all the current devices support it. - *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA; - *hidl_caps |= HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS; - *hidl_caps |= HidlChipCaps::DEBUG_ERROR_ALERTS; - return true; -} - -WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToHidl( - uint32_t flag) { - switch (flag) { - case WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES: - return WifiDebugRingBufferFlags::HAS_BINARY_ENTRIES; - case WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES: - return WifiDebugRingBufferFlags::HAS_ASCII_ENTRIES; - }; - CHECK(false) << "Unknown legacy flag: " << flag; - return {}; -} - -bool convertLegacyDebugRingBufferStatusToHidl( - const legacy_hal::wifi_ring_buffer_status& legacy_status, - WifiDebugRingBufferStatus* hidl_status) { - if (!hidl_status) { - return false; - } - *hidl_status = {}; - hidl_status->ringName = - safeConvertChar(reinterpret_cast(legacy_status.name), - sizeof(legacy_status.name)); - hidl_status->flags = 0; - for (const auto flag : {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES, - WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) { - if (flag & legacy_status.flags) { - hidl_status->flags |= static_cast< - std::underlying_type::type>( - convertLegacyDebugRingBufferFlagsToHidl(flag)); - } - } - hidl_status->ringId = legacy_status.ring_id; - hidl_status->sizeInBytes = legacy_status.ring_buffer_byte_size; - // Calculate free size of the ring the buffer. We don't need to send the - // exact read/write pointers that were there in the legacy HAL interface. - if (legacy_status.written_bytes >= legacy_status.read_bytes) { - hidl_status->freeSizeInBytes = - legacy_status.ring_buffer_byte_size - - (legacy_status.written_bytes - legacy_status.read_bytes); - } else { - hidl_status->freeSizeInBytes = - legacy_status.read_bytes - legacy_status.written_bytes; - } - hidl_status->verboseLevel = legacy_status.verbose_level; - return true; -} - -bool convertLegacyVectorOfDebugRingBufferStatusToHidl( - const std::vector& legacy_status_vec, - std::vector* hidl_status_vec) { - if (!hidl_status_vec) { - return false; - } - *hidl_status_vec = {}; - for (const auto& legacy_status : legacy_status_vec) { - WifiDebugRingBufferStatus hidl_status; - if (!convertLegacyDebugRingBufferStatusToHidl(legacy_status, - &hidl_status)) { - return false; - } - hidl_status_vec->push_back(hidl_status); - } - return true; -} - -bool convertLegacyWakeReasonStatsToHidl( - const legacy_hal::WakeReasonStats& legacy_stats, - WifiDebugHostWakeReasonStats* hidl_stats) { - if (!hidl_stats) { - return false; - } - *hidl_stats = {}; - hidl_stats->totalCmdEventWakeCnt = - legacy_stats.wake_reason_cnt.total_cmd_event_wake; - hidl_stats->cmdEventWakeCntPerType = legacy_stats.cmd_event_wake_cnt; - hidl_stats->totalDriverFwLocalWakeCnt = - legacy_stats.wake_reason_cnt.total_driver_fw_local_wake; - hidl_stats->driverFwLocalWakeCntPerType = - legacy_stats.driver_fw_local_wake_cnt; - hidl_stats->totalRxPacketWakeCnt = - legacy_stats.wake_reason_cnt.total_rx_data_wake; - hidl_stats->rxPktWakeDetails.rxUnicastCnt = - legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt; - hidl_stats->rxPktWakeDetails.rxMulticastCnt = - legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt; - hidl_stats->rxPktWakeDetails.rxBroadcastCnt = - legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt; - hidl_stats->rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt = - legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info - .ipv4_rx_multicast_addr_cnt; - hidl_stats->rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt = - legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info - .ipv6_rx_multicast_addr_cnt; - hidl_stats->rxMulticastPkWakeDetails.otherRxMulticastAddrCnt = - legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info - .other_rx_multicast_addr_cnt; - hidl_stats->rxIcmpPkWakeDetails.icmpPkt = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt; - hidl_stats->rxIcmpPkWakeDetails.icmp6Pkt = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt; - hidl_stats->rxIcmpPkWakeDetails.icmp6Ra = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra; - hidl_stats->rxIcmpPkWakeDetails.icmp6Na = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na; - hidl_stats->rxIcmpPkWakeDetails.icmp6Ns = - legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns; - return true; -} - -legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( - V1_1::IWifiChip::TxPowerScenario hidl_scenario) { - switch (hidl_scenario) { - // This is the only supported scenario for V1_1 - case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL: - return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL; - }; - CHECK(false); -} - -legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( - V1_2::IWifiChip::TxPowerScenario hidl_scenario) { - switch (hidl_scenario) { - // This is the only supported scenario for V1_1 - case V1_2::IWifiChip::TxPowerScenario::VOICE_CALL: - return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL; - // Those are the supported scenarios for V1_2 - case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF: - return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF; - case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_ON: - return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON; - case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF: - return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF; - case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_ON: - return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON; - }; - CHECK(false); -} - -legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( - V1_3::IWifiChip::LatencyMode hidl_latency_mode) { - switch (hidl_latency_mode) { - case V1_3::IWifiChip::LatencyMode::NORMAL: - return legacy_hal::WIFI_LATENCY_MODE_NORMAL; - case V1_3::IWifiChip::LatencyMode::LOW: - return legacy_hal::WIFI_LATENCY_MODE_LOW; - } - CHECK(false); -} - -bool convertLegacyWifiMacInfoToHidl( - const legacy_hal::WifiMacInfo& legacy_mac_info, - V1_4::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) { - if (!hidl_radio_mode_info) { - return false; - } - *hidl_radio_mode_info = {}; - - hidl_radio_mode_info->radioId = legacy_mac_info.wlan_mac_id; - // Convert from bitmask of bands in the legacy HAL to enum value in - // the HIDL interface. - if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND && - legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND && - legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) { - hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ_6GHZ; - } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND && - legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) { - hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ_6GHZ; - } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND) { - hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_6GHZ; - } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND && - legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) { - hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ; - } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) { - hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ; - } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) { - hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ; - } else { - hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_UNSPECIFIED; - } - std::vector iface_info_vec; - for (const auto& legacy_iface_info : legacy_mac_info.iface_infos) { - V1_2::IWifiChipEventCallback::IfaceInfo iface_info; - iface_info.name = legacy_iface_info.name; - iface_info.channel = legacy_iface_info.channel; - iface_info_vec.push_back(iface_info); - } - hidl_radio_mode_info->ifaceInfos = iface_info_vec; - return true; -} - -uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) { - switch (hidl_band) { - case V1_5::WifiBand::BAND_24GHZ: - return legacy_hal::WLAN_MAC_2_4_BAND; - case V1_5::WifiBand::BAND_5GHZ: - case V1_5::WifiBand::BAND_5GHZ_DFS: - case V1_5::WifiBand::BAND_5GHZ_WITH_DFS: - return legacy_hal::WLAN_MAC_5_0_BAND; - case V1_5::WifiBand::BAND_24GHZ_5GHZ: - case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS: - return (legacy_hal::WLAN_MAC_2_4_BAND | - legacy_hal::WLAN_MAC_5_0_BAND); - case V1_5::WifiBand::BAND_6GHZ: - return legacy_hal::WLAN_MAC_6_0_BAND; - case V1_5::WifiBand::BAND_5GHZ_6GHZ: - return (legacy_hal::WLAN_MAC_5_0_BAND | - legacy_hal::WLAN_MAC_6_0_BAND); - case V1_5::WifiBand::BAND_24GHZ_5GHZ_6GHZ: - case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ: - return (legacy_hal::WLAN_MAC_2_4_BAND | - legacy_hal::WLAN_MAC_5_0_BAND | - legacy_hal::WLAN_MAC_6_0_BAND); - case V1_5::WifiBand::BAND_60GHZ: - return legacy_hal::WLAN_MAC_60_0_BAND; - default: - return ( - legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND | - legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND); - } -} - -uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask) { - uint32_t legacy_iface_mask = 0; - if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_STA) { - legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA); - } - if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP) { - legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP); - } - if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT) { - legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT); - } - if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO) { - legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO); - } - if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_NAN) { - legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN); - } - if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_TDLS) { - legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS); - } - if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_MESH) { - legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH); - } - if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_IBSS) { - legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS); - } - return legacy_iface_mask; -} - -uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) { - uint32_t hidl_iface_mask = 0; - if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) { - hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_STA; - } - if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) { - hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP; - } - if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) { - hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT; - } - if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) { - hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO; - } - if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) { - hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_NAN; - } - if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) { - hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_TDLS; - } - if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) { - hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_MESH; - } - if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) { - hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_IBSS; - } - return hidl_iface_mask; -} - -uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask) { - uint32_t legacy_filter_mask = 0; - if (hidl_filter_mask & - IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) { - legacy_filter_mask |= - legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE; - } - if (hidl_filter_mask & IWifiChip::UsableChannelFilter::CONCURRENCY) { - legacy_filter_mask |= - legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY; - } - return legacy_filter_mask; -} - -bool convertLegacyWifiUsableChannelToHidl( - const legacy_hal::wifi_usable_channel& legacy_usable_channel, - V1_5::WifiUsableChannel* hidl_usable_channel) { - if (!hidl_usable_channel) { - return false; - } - *hidl_usable_channel = {}; - hidl_usable_channel->channel = legacy_usable_channel.freq; - hidl_usable_channel->channelBandwidth = - convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width); - hidl_usable_channel->ifaceModeMask = convertLegacyWifiInterfaceModeToHidl( - legacy_usable_channel.iface_mode_mask); - - return true; -} - -bool convertLegacyWifiUsableChannelsToHidl( - const std::vector& legacy_usable_channels, - std::vector* hidl_usable_channels) { - if (!hidl_usable_channels) { - return false; - } - *hidl_usable_channels = {}; - for (const auto& legacy_usable_channel : legacy_usable_channels) { - V1_5::WifiUsableChannel hidl_usable_channel; - if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel, - &hidl_usable_channel)) { - return false; - } - hidl_usable_channels->push_back(hidl_usable_channel); - } - return true; -} - -bool convertLegacyWifiMacInfosToHidl( - const std::vector& legacy_mac_infos, - std::vector* - hidl_radio_mode_infos) { - if (!hidl_radio_mode_infos) { - return false; - } - *hidl_radio_mode_infos = {}; - - for (const auto& legacy_mac_info : legacy_mac_infos) { - V1_4::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info; - if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info, - &hidl_radio_mode_info)) { - return false; - } - hidl_radio_mode_infos->push_back(hidl_radio_mode_info); - } - return true; -} - -bool convertLegacyFeaturesToHidlStaCapabilities( - uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set, - uint32_t* hidl_caps) { - if (!hidl_caps) { - return false; - } - *hidl_caps = {}; - using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask; - for (const auto feature : {legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED}) { - if (feature & legacy_logger_feature_set) { - *hidl_caps |= - convertLegacyLoggerFeatureToHidlStaIfaceCapability(feature); - } - } - for (const auto feature : - {WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, - WIFI_FEATURE_RSSI_MONITOR, WIFI_FEATURE_CONTROL_ROAMING, - WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND, - WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, - WIFI_FEATURE_TDLS, WIFI_FEATURE_TDLS_OFFCHANNEL, - WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) { - if (feature & legacy_feature_set) { - *hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature); - } - } - // There is no flag for this one in the legacy feature set. Adding it to the - // set because all the current devices support it. - *hidl_caps |= HidlStaIfaceCaps::APF; - return true; -} - -bool convertLegacyApfCapabilitiesToHidl( - const legacy_hal::PacketFilterCapabilities& legacy_caps, - StaApfPacketFilterCapabilities* hidl_caps) { - if (!hidl_caps) { - return false; - } - *hidl_caps = {}; - hidl_caps->version = legacy_caps.version; - hidl_caps->maxLength = legacy_caps.max_len; - return true; -} - -uint8_t convertHidlGscanReportEventFlagToLegacy( - StaBackgroundScanBucketEventReportSchemeMask hidl_flag) { - using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask; - switch (hidl_flag) { - case HidlFlag::EACH_SCAN: - return REPORT_EVENTS_EACH_SCAN; - case HidlFlag::FULL_RESULTS: - return REPORT_EVENTS_FULL_RESULTS; - case HidlFlag::NO_BATCH: - return REPORT_EVENTS_NO_BATCH; - }; - CHECK(false); -} - -StaScanDataFlagMask convertLegacyGscanDataFlagToHidl(uint8_t legacy_flag) { - switch (legacy_flag) { - case legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED: - return StaScanDataFlagMask::INTERRUPTED; - }; - CHECK(false) << "Unknown legacy flag: " << legacy_flag; - // To silence the compiler warning about reaching the end of non-void - // function. - return {}; -} - -bool convertLegacyGscanCapabilitiesToHidl( - const legacy_hal::wifi_gscan_capabilities& legacy_caps, - StaBackgroundScanCapabilities* hidl_caps) { - if (!hidl_caps) { - return false; - } - *hidl_caps = {}; - hidl_caps->maxCacheSize = legacy_caps.max_scan_cache_size; - hidl_caps->maxBuckets = legacy_caps.max_scan_buckets; - hidl_caps->maxApCachePerScan = legacy_caps.max_ap_cache_per_scan; - hidl_caps->maxReportingThreshold = legacy_caps.max_scan_reporting_threshold; - return true; -} - -legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band) { - switch (band) { - case V1_0::WifiBand::BAND_UNSPECIFIED: - return legacy_hal::WIFI_BAND_UNSPECIFIED; - case V1_0::WifiBand::BAND_24GHZ: - return legacy_hal::WIFI_BAND_BG; - case V1_0::WifiBand::BAND_5GHZ: - return legacy_hal::WIFI_BAND_A; - case V1_0::WifiBand::BAND_5GHZ_DFS: - return legacy_hal::WIFI_BAND_A_DFS; - case V1_0::WifiBand::BAND_5GHZ_WITH_DFS: - return legacy_hal::WIFI_BAND_A_WITH_DFS; - case V1_0::WifiBand::BAND_24GHZ_5GHZ: - return legacy_hal::WIFI_BAND_ABG; - case V1_0::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS: - return legacy_hal::WIFI_BAND_ABG_WITH_DFS; - }; - CHECK(false); -} - -bool convertHidlGscanParamsToLegacy( - const StaBackgroundScanParameters& hidl_scan_params, - legacy_hal::wifi_scan_cmd_params* legacy_scan_params) { - if (!legacy_scan_params) { - return false; - } - *legacy_scan_params = {}; - legacy_scan_params->base_period = hidl_scan_params.basePeriodInMs; - legacy_scan_params->max_ap_per_scan = hidl_scan_params.maxApPerScan; - legacy_scan_params->report_threshold_percent = - hidl_scan_params.reportThresholdPercent; - legacy_scan_params->report_threshold_num_scans = - hidl_scan_params.reportThresholdNumScans; - if (hidl_scan_params.buckets.size() > MAX_BUCKETS) { - return false; - } - legacy_scan_params->num_buckets = hidl_scan_params.buckets.size(); - for (uint32_t bucket_idx = 0; bucket_idx < hidl_scan_params.buckets.size(); - bucket_idx++) { - const StaBackgroundScanBucketParameters& hidl_bucket_spec = - hidl_scan_params.buckets[bucket_idx]; - legacy_hal::wifi_scan_bucket_spec& legacy_bucket_spec = - legacy_scan_params->buckets[bucket_idx]; - if (hidl_bucket_spec.bucketIdx >= MAX_BUCKETS) { - return false; - } - legacy_bucket_spec.bucket = hidl_bucket_spec.bucketIdx; - legacy_bucket_spec.band = - convertHidlWifiBandToLegacy(hidl_bucket_spec.band); - legacy_bucket_spec.period = hidl_bucket_spec.periodInMs; - legacy_bucket_spec.max_period = - hidl_bucket_spec.exponentialMaxPeriodInMs; - legacy_bucket_spec.base = hidl_bucket_spec.exponentialBase; - legacy_bucket_spec.step_count = hidl_bucket_spec.exponentialStepCount; - legacy_bucket_spec.report_events = 0; - using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask; - for (const auto flag : {HidlFlag::EACH_SCAN, HidlFlag::FULL_RESULTS, - HidlFlag::NO_BATCH}) { - if (hidl_bucket_spec.eventReportScheme & - static_cast::type>(flag)) { - legacy_bucket_spec.report_events |= - convertHidlGscanReportEventFlagToLegacy(flag); - } - } - if (hidl_bucket_spec.frequencies.size() > MAX_CHANNELS) { - return false; - } - legacy_bucket_spec.num_channels = hidl_bucket_spec.frequencies.size(); - for (uint32_t freq_idx = 0; - freq_idx < hidl_bucket_spec.frequencies.size(); freq_idx++) { - legacy_bucket_spec.channels[freq_idx].channel = - hidl_bucket_spec.frequencies[freq_idx]; - } - } - return true; -} - -bool convertLegacyIeToHidl( - const legacy_hal::wifi_information_element& legacy_ie, - WifiInformationElement* hidl_ie) { - if (!hidl_ie) { - return false; - } - *hidl_ie = {}; - hidl_ie->id = legacy_ie.id; - hidl_ie->data = - std::vector(legacy_ie.data, legacy_ie.data + legacy_ie.len); - return true; -} - -bool convertLegacyIeBlobToHidl(const uint8_t* ie_blob, uint32_t ie_blob_len, - std::vector* hidl_ies) { - if (!ie_blob || !hidl_ies) { - return false; - } - *hidl_ies = {}; - const uint8_t* ies_begin = ie_blob; - const uint8_t* ies_end = ie_blob + ie_blob_len; - const uint8_t* next_ie = ies_begin; - using wifi_ie = legacy_hal::wifi_information_element; - constexpr size_t kIeHeaderLen = sizeof(wifi_ie); - // Each IE should atleast have the header (i.e |id| & |len| fields). - while (next_ie + kIeHeaderLen <= ies_end) { - const wifi_ie& legacy_ie = (*reinterpret_cast(next_ie)); - uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len; - if (next_ie + curr_ie_len > ies_end) { - LOG(ERROR) << "Error parsing IE blob. Next IE: " << (void*)next_ie - << ", Curr IE len: " << curr_ie_len - << ", IEs End: " << (void*)ies_end; - break; - } - WifiInformationElement hidl_ie; - if (!convertLegacyIeToHidl(legacy_ie, &hidl_ie)) { - LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id - << ", len: " << legacy_ie.len; - break; - } - hidl_ies->push_back(std::move(hidl_ie)); - next_ie += curr_ie_len; - } - // Check if the blob has been fully consumed. - if (next_ie != ies_end) { - LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " - << (void*)next_ie << ", IEs End: " << (void*)ies_end; - } - return true; -} - -bool convertLegacyGscanResultToHidl( - const legacy_hal::wifi_scan_result& legacy_scan_result, bool has_ie_data, - StaScanResult* hidl_scan_result) { - if (!hidl_scan_result) { - return false; - } - *hidl_scan_result = {}; - hidl_scan_result->timeStampInUs = legacy_scan_result.ts; - hidl_scan_result->ssid = std::vector( - legacy_scan_result.ssid, - legacy_scan_result.ssid + strnlen(legacy_scan_result.ssid, - sizeof(legacy_scan_result.ssid) - 1)); - memcpy(hidl_scan_result->bssid.data(), legacy_scan_result.bssid, - hidl_scan_result->bssid.size()); - hidl_scan_result->frequency = legacy_scan_result.channel; - hidl_scan_result->rssi = legacy_scan_result.rssi; - hidl_scan_result->beaconPeriodInMs = legacy_scan_result.beacon_period; - hidl_scan_result->capability = legacy_scan_result.capability; - if (has_ie_data) { - std::vector ies; - if (!convertLegacyIeBlobToHidl( - reinterpret_cast(legacy_scan_result.ie_data), - legacy_scan_result.ie_length, &ies)) { - return false; - } - hidl_scan_result->informationElements = std::move(ies); - } - return true; -} - -bool convertLegacyCachedGscanResultsToHidl( - const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result, - StaScanData* hidl_scan_data) { - if (!hidl_scan_data) { - return false; - } - *hidl_scan_data = {}; - hidl_scan_data->flags = 0; - for (const auto flag : {legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED}) { - if (legacy_cached_scan_result.flags & flag) { - hidl_scan_data->flags |= - static_cast::type>( - convertLegacyGscanDataFlagToHidl(flag)); - } - } - hidl_scan_data->bucketsScanned = legacy_cached_scan_result.buckets_scanned; - - CHECK(legacy_cached_scan_result.num_results >= 0 && - legacy_cached_scan_result.num_results <= MAX_AP_CACHE_PER_SCAN); - std::vector hidl_scan_results; - for (int32_t result_idx = 0; - result_idx < legacy_cached_scan_result.num_results; result_idx++) { - StaScanResult hidl_scan_result; - if (!convertLegacyGscanResultToHidl( - legacy_cached_scan_result.results[result_idx], false, - &hidl_scan_result)) { - return false; - } - hidl_scan_results.push_back(hidl_scan_result); - } - hidl_scan_data->results = std::move(hidl_scan_results); - return true; -} - -bool convertLegacyVectorOfCachedGscanResultsToHidl( - const std::vector& - legacy_cached_scan_results, - std::vector* hidl_scan_datas) { - if (!hidl_scan_datas) { - return false; - } - *hidl_scan_datas = {}; - for (const auto& legacy_cached_scan_result : legacy_cached_scan_results) { - StaScanData hidl_scan_data; - if (!convertLegacyCachedGscanResultsToHidl(legacy_cached_scan_result, - &hidl_scan_data)) { - return false; - } - hidl_scan_datas->push_back(hidl_scan_data); - } - return true; -} - -WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToHidl( - legacy_hal::wifi_tx_packet_fate fate) { - switch (fate) { - case legacy_hal::TX_PKT_FATE_ACKED: - return WifiDebugTxPacketFate::ACKED; - case legacy_hal::TX_PKT_FATE_SENT: - return WifiDebugTxPacketFate::SENT; - case legacy_hal::TX_PKT_FATE_FW_QUEUED: - return WifiDebugTxPacketFate::FW_QUEUED; - case legacy_hal::TX_PKT_FATE_FW_DROP_INVALID: - return WifiDebugTxPacketFate::FW_DROP_INVALID; - case legacy_hal::TX_PKT_FATE_FW_DROP_NOBUFS: - return WifiDebugTxPacketFate::FW_DROP_NOBUFS; - case legacy_hal::TX_PKT_FATE_FW_DROP_OTHER: - return WifiDebugTxPacketFate::FW_DROP_OTHER; - case legacy_hal::TX_PKT_FATE_DRV_QUEUED: - return WifiDebugTxPacketFate::DRV_QUEUED; - case legacy_hal::TX_PKT_FATE_DRV_DROP_INVALID: - return WifiDebugTxPacketFate::DRV_DROP_INVALID; - case legacy_hal::TX_PKT_FATE_DRV_DROP_NOBUFS: - return WifiDebugTxPacketFate::DRV_DROP_NOBUFS; - case legacy_hal::TX_PKT_FATE_DRV_DROP_OTHER: - return WifiDebugTxPacketFate::DRV_DROP_OTHER; - }; - CHECK(false) << "Unknown legacy fate type: " << fate; -} - -WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToHidl( - legacy_hal::wifi_rx_packet_fate fate) { - switch (fate) { - case legacy_hal::RX_PKT_FATE_SUCCESS: - return WifiDebugRxPacketFate::SUCCESS; - case legacy_hal::RX_PKT_FATE_FW_QUEUED: - return WifiDebugRxPacketFate::FW_QUEUED; - case legacy_hal::RX_PKT_FATE_FW_DROP_FILTER: - return WifiDebugRxPacketFate::FW_DROP_FILTER; - case legacy_hal::RX_PKT_FATE_FW_DROP_INVALID: - return WifiDebugRxPacketFate::FW_DROP_INVALID; - case legacy_hal::RX_PKT_FATE_FW_DROP_NOBUFS: - return WifiDebugRxPacketFate::FW_DROP_NOBUFS; - case legacy_hal::RX_PKT_FATE_FW_DROP_OTHER: - return WifiDebugRxPacketFate::FW_DROP_OTHER; - case legacy_hal::RX_PKT_FATE_DRV_QUEUED: - return WifiDebugRxPacketFate::DRV_QUEUED; - case legacy_hal::RX_PKT_FATE_DRV_DROP_FILTER: - return WifiDebugRxPacketFate::DRV_DROP_FILTER; - case legacy_hal::RX_PKT_FATE_DRV_DROP_INVALID: - return WifiDebugRxPacketFate::DRV_DROP_INVALID; - case legacy_hal::RX_PKT_FATE_DRV_DROP_NOBUFS: - return WifiDebugRxPacketFate::DRV_DROP_NOBUFS; - case legacy_hal::RX_PKT_FATE_DRV_DROP_OTHER: - return WifiDebugRxPacketFate::DRV_DROP_OTHER; - }; - CHECK(false) << "Unknown legacy fate type: " << fate; -} - -WifiDebugPacketFateFrameType convertLegacyDebugPacketFateFrameTypeToHidl( - legacy_hal::frame_type type) { - switch (type) { - case legacy_hal::FRAME_TYPE_UNKNOWN: - return WifiDebugPacketFateFrameType::UNKNOWN; - case legacy_hal::FRAME_TYPE_ETHERNET_II: - return WifiDebugPacketFateFrameType::ETHERNET_II; - case legacy_hal::FRAME_TYPE_80211_MGMT: - return WifiDebugPacketFateFrameType::MGMT_80211; - }; - CHECK(false) << "Unknown legacy frame type: " << type; -} - -bool convertLegacyDebugPacketFateFrameToHidl( - const legacy_hal::frame_info& legacy_frame, - WifiDebugPacketFateFrameInfo* hidl_frame) { - if (!hidl_frame) { - return false; - } - *hidl_frame = {}; - hidl_frame->frameType = - convertLegacyDebugPacketFateFrameTypeToHidl(legacy_frame.payload_type); - hidl_frame->frameLen = legacy_frame.frame_len; - hidl_frame->driverTimestampUsec = legacy_frame.driver_timestamp_usec; - hidl_frame->firmwareTimestampUsec = legacy_frame.firmware_timestamp_usec; - const uint8_t* frame_begin = reinterpret_cast( - legacy_frame.frame_content.ethernet_ii_bytes); - hidl_frame->frameContent = - std::vector(frame_begin, frame_begin + legacy_frame.frame_len); - return true; -} - -bool convertLegacyDebugTxPacketFateToHidl( - const legacy_hal::wifi_tx_report& legacy_fate, - WifiDebugTxPacketFateReport* hidl_fate) { - if (!hidl_fate) { - return false; - } - *hidl_fate = {}; - hidl_fate->fate = convertLegacyDebugTxPacketFateToHidl(legacy_fate.fate); - return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, - &hidl_fate->frameInfo); -} - -bool convertLegacyVectorOfDebugTxPacketFateToHidl( - const std::vector& legacy_fates, - std::vector* hidl_fates) { - if (!hidl_fates) { - return false; - } - *hidl_fates = {}; - for (const auto& legacy_fate : legacy_fates) { - WifiDebugTxPacketFateReport hidl_fate; - if (!convertLegacyDebugTxPacketFateToHidl(legacy_fate, &hidl_fate)) { - return false; - } - hidl_fates->push_back(hidl_fate); - } - return true; -} - -bool convertLegacyDebugRxPacketFateToHidl( - const legacy_hal::wifi_rx_report& legacy_fate, - WifiDebugRxPacketFateReport* hidl_fate) { - if (!hidl_fate) { - return false; - } - *hidl_fate = {}; - hidl_fate->fate = convertLegacyDebugRxPacketFateToHidl(legacy_fate.fate); - return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, - &hidl_fate->frameInfo); -} - -bool convertLegacyVectorOfDebugRxPacketFateToHidl( - const std::vector& legacy_fates, - std::vector* hidl_fates) { - if (!hidl_fates) { - return false; - } - *hidl_fates = {}; - for (const auto& legacy_fate : legacy_fates) { - WifiDebugRxPacketFateReport hidl_fate; - if (!convertLegacyDebugRxPacketFateToHidl(legacy_fate, &hidl_fate)) { - return false; - } - hidl_fates->push_back(hidl_fate); - } - return true; -} - -bool convertLegacyLinkLayerRadioStatsToHidl( - const legacy_hal::LinkLayerRadioStats& legacy_radio_stat, - V1_5::StaLinkLayerRadioStats* hidl_radio_stat) { - if (!hidl_radio_stat) { - return false; - } - *hidl_radio_stat = {}; - - hidl_radio_stat->radioId = legacy_radio_stat.stats.radio; - hidl_radio_stat->V1_3.V1_0.onTimeInMs = legacy_radio_stat.stats.on_time; - hidl_radio_stat->V1_3.V1_0.txTimeInMs = legacy_radio_stat.stats.tx_time; - hidl_radio_stat->V1_3.V1_0.rxTimeInMs = legacy_radio_stat.stats.rx_time; - hidl_radio_stat->V1_3.V1_0.onTimeInMsForScan = - legacy_radio_stat.stats.on_time_scan; - hidl_radio_stat->V1_3.V1_0.txTimeInMsPerLevel = - legacy_radio_stat.tx_time_per_levels; - hidl_radio_stat->V1_3.onTimeInMsForNanScan = - legacy_radio_stat.stats.on_time_nbd; - hidl_radio_stat->V1_3.onTimeInMsForBgScan = - legacy_radio_stat.stats.on_time_gscan; - hidl_radio_stat->V1_3.onTimeInMsForRoamScan = - legacy_radio_stat.stats.on_time_roam_scan; - hidl_radio_stat->V1_3.onTimeInMsForPnoScan = - legacy_radio_stat.stats.on_time_pno_scan; - hidl_radio_stat->V1_3.onTimeInMsForHs20Scan = - legacy_radio_stat.stats.on_time_hs20; - - std::vector hidl_channel_stats; - - for (const auto& channel_stat : legacy_radio_stat.channel_stats) { - V1_3::WifiChannelStats hidl_channel_stat; - hidl_channel_stat.onTimeInMs = channel_stat.on_time; - hidl_channel_stat.ccaBusyTimeInMs = channel_stat.cca_busy_time; - /* - * TODO once b/119142899 is fixed, - * replace below code with convertLegacyWifiChannelInfoToHidl() - */ - hidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20; - hidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq; - hidl_channel_stat.channel.centerFreq0 = - channel_stat.channel.center_freq0; - hidl_channel_stat.channel.centerFreq1 = - channel_stat.channel.center_freq1; - hidl_channel_stats.push_back(hidl_channel_stat); - } - - hidl_radio_stat->V1_3.channelStats = hidl_channel_stats; - - return true; -} - -bool convertLegacyLinkLayerStatsToHidl( - const legacy_hal::LinkLayerStats& legacy_stats, - StaLinkLayerStats* hidl_stats) { - if (!hidl_stats) { - return false; - } - *hidl_stats = {}; - // iface legacy_stats conversion. - hidl_stats->iface.V1_0.beaconRx = legacy_stats.iface.beacon_rx; - hidl_stats->iface.V1_0.avgRssiMgmt = legacy_stats.iface.rssi_mgmt; - hidl_stats->iface.V1_0.wmeBePktStats.rxMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu; - hidl_stats->iface.V1_0.wmeBePktStats.txMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu; - hidl_stats->iface.V1_0.wmeBePktStats.lostMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost; - hidl_stats->iface.V1_0.wmeBePktStats.retries = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries; - hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMinInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min; - hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max; - hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg; - hidl_stats->iface.wmeBeContentionTimeStats.contentionNumSamples = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples; - hidl_stats->iface.V1_0.wmeBkPktStats.rxMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu; - hidl_stats->iface.V1_0.wmeBkPktStats.txMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu; - hidl_stats->iface.V1_0.wmeBkPktStats.lostMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost; - hidl_stats->iface.V1_0.wmeBkPktStats.retries = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries; - hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMinInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min; - hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max; - hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg; - hidl_stats->iface.wmeBkContentionTimeStats.contentionNumSamples = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples; - hidl_stats->iface.V1_0.wmeViPktStats.rxMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu; - hidl_stats->iface.V1_0.wmeViPktStats.txMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu; - hidl_stats->iface.V1_0.wmeViPktStats.lostMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost; - hidl_stats->iface.V1_0.wmeViPktStats.retries = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries; - hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMinInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min; - hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMaxInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max; - hidl_stats->iface.wmeViContentionTimeStats.contentionTimeAvgInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg; - hidl_stats->iface.wmeViContentionTimeStats.contentionNumSamples = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples; - hidl_stats->iface.V1_0.wmeVoPktStats.rxMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu; - hidl_stats->iface.V1_0.wmeVoPktStats.txMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu; - hidl_stats->iface.V1_0.wmeVoPktStats.lostMpdu = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost; - hidl_stats->iface.V1_0.wmeVoPktStats.retries = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries; - hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMinInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min; - hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max; - hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg; - hidl_stats->iface.wmeVoContentionTimeStats.contentionNumSamples = - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples; - hidl_stats->iface.timeSliceDutyCycleInPercent = - legacy_stats.iface.info.time_slicing_duty_cycle_percent; - // peer info legacy_stats conversion. - std::vector hidl_peers_info_stats; - for (const auto& legacy_peer_info_stats : legacy_stats.peers) { - StaPeerInfo hidl_peer_info_stats; - if (!convertLegacyPeerInfoStatsToHidl(legacy_peer_info_stats, - &hidl_peer_info_stats)) { - return false; - } - hidl_peers_info_stats.push_back(hidl_peer_info_stats); - } - hidl_stats->iface.peers = hidl_peers_info_stats; - // radio legacy_stats conversion. - std::vector hidl_radios_stats; - for (const auto& legacy_radio_stats : legacy_stats.radios) { - V1_5::StaLinkLayerRadioStats hidl_radio_stats; - if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats, - &hidl_radio_stats)) { - return false; - } - hidl_radios_stats.push_back(hidl_radio_stats); - } - hidl_stats->radios = hidl_radios_stats; - // Timestamp in the HAL wrapper here since it's not provided in the legacy - // HAL API. - hidl_stats->timeStampInMs = uptimeMillis(); - return true; -} - -bool convertLegacyPeerInfoStatsToHidl( - const legacy_hal::WifiPeerInfo& legacy_peer_info_stats, - StaPeerInfo* hidl_peer_info_stats) { - if (!hidl_peer_info_stats) { - return false; - } - *hidl_peer_info_stats = {}; - hidl_peer_info_stats->staCount = - legacy_peer_info_stats.peer_info.bssload.sta_count; - hidl_peer_info_stats->chanUtil = - legacy_peer_info_stats.peer_info.bssload.chan_util; - - std::vector hidlRateStats; - for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) { - StaRateStat rateStat; - if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate, - &rateStat.rateInfo)) { - return false; - } - rateStat.txMpdu = legacy_rate_stats.tx_mpdu; - rateStat.rxMpdu = legacy_rate_stats.rx_mpdu; - rateStat.mpduLost = legacy_rate_stats.mpdu_lost; - rateStat.retries = legacy_rate_stats.retries; - hidlRateStats.push_back(rateStat); - } - hidl_peer_info_stats->rateStats = hidlRateStats; - return true; -} - -bool convertLegacyRoamingCapabilitiesToHidl( - const legacy_hal::wifi_roaming_capabilities& legacy_caps, - StaRoamingCapabilities* hidl_caps) { - if (!hidl_caps) { - return false; - } - *hidl_caps = {}; - hidl_caps->maxBlacklistSize = legacy_caps.max_blacklist_size; - hidl_caps->maxWhitelistSize = legacy_caps.max_whitelist_size; - return true; -} - -bool convertHidlRoamingConfigToLegacy( - const StaRoamingConfig& hidl_config, - legacy_hal::wifi_roaming_config* legacy_config) { - if (!legacy_config) { - return false; - } - *legacy_config = {}; - if (hidl_config.bssidBlacklist.size() > MAX_BLACKLIST_BSSID || - hidl_config.ssidWhitelist.size() > MAX_WHITELIST_SSID) { - return false; - } - legacy_config->num_blacklist_bssid = hidl_config.bssidBlacklist.size(); - uint32_t i = 0; - for (const auto& bssid : hidl_config.bssidBlacklist) { - CHECK(bssid.size() == sizeof(legacy_hal::mac_addr)); - memcpy(legacy_config->blacklist_bssid[i++], bssid.data(), bssid.size()); - } - legacy_config->num_whitelist_ssid = hidl_config.ssidWhitelist.size(); - i = 0; - for (const auto& ssid : hidl_config.ssidWhitelist) { - CHECK(ssid.size() <= sizeof(legacy_hal::ssid_t::ssid_str)); - legacy_config->whitelist_ssid[i].length = ssid.size(); - memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data(), - ssid.size()); - i++; - } - return true; -} - -legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy( - StaRoamingState state) { - switch (state) { - case StaRoamingState::ENABLED: - return legacy_hal::ROAMING_ENABLE; - case StaRoamingState::DISABLED: - return legacy_hal::ROAMING_DISABLE; - }; - CHECK(false); -} - -legacy_hal::NanMatchAlg convertHidlNanMatchAlgToLegacy(NanMatchAlg type) { - switch (type) { - case NanMatchAlg::MATCH_ONCE: - return legacy_hal::NAN_MATCH_ALG_MATCH_ONCE; - case NanMatchAlg::MATCH_CONTINUOUS: - return legacy_hal::NAN_MATCH_ALG_MATCH_CONTINUOUS; - case NanMatchAlg::MATCH_NEVER: - return legacy_hal::NAN_MATCH_ALG_MATCH_NEVER; - } - CHECK(false); -} - -legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy( - NanPublishType type) { - switch (type) { - case NanPublishType::UNSOLICITED: - return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED; - case NanPublishType::SOLICITED: - return legacy_hal::NAN_PUBLISH_TYPE_SOLICITED; - case NanPublishType::UNSOLICITED_SOLICITED: - return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED; - } - CHECK(false); -} - -legacy_hal::NanTxType convertHidlNanTxTypeToLegacy(NanTxType type) { - switch (type) { - case NanTxType::BROADCAST: - return legacy_hal::NAN_TX_TYPE_BROADCAST; - case NanTxType::UNICAST: - return legacy_hal::NAN_TX_TYPE_UNICAST; - } - CHECK(false); -} - -legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy( - NanSubscribeType type) { - switch (type) { - case NanSubscribeType::PASSIVE: - return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE; - case NanSubscribeType::ACTIVE: - return legacy_hal::NAN_SUBSCRIBE_TYPE_ACTIVE; - } - CHECK(false); -} - -legacy_hal::NanSRFType convertHidlNanSrfTypeToLegacy(NanSrfType type) { - switch (type) { - case NanSrfType::BLOOM_FILTER: - return legacy_hal::NAN_SRF_ATTR_BLOOM_FILTER; - case NanSrfType::PARTIAL_MAC_ADDR: - return legacy_hal::NAN_SRF_ATTR_PARTIAL_MAC_ADDR; - } - CHECK(false); -} - -legacy_hal::NanDataPathChannelCfg convertHidlNanDataPathChannelCfgToLegacy( - NanDataPathChannelCfg type) { - switch (type) { - case NanDataPathChannelCfg::CHANNEL_NOT_REQUESTED: - return legacy_hal::NAN_DP_CHANNEL_NOT_REQUESTED; - case NanDataPathChannelCfg::REQUEST_CHANNEL_SETUP: - return legacy_hal::NAN_DP_REQUEST_CHANNEL_SETUP; - case NanDataPathChannelCfg::FORCE_CHANNEL_SETUP: - return legacy_hal::NAN_DP_FORCE_CHANNEL_SETUP; - } - CHECK(false); -} - -NanStatusType convertLegacyNanStatusTypeToHidl(legacy_hal::NanStatusType type) { - switch (type) { - case legacy_hal::NAN_STATUS_SUCCESS: - return NanStatusType::SUCCESS; - case legacy_hal::NAN_STATUS_INTERNAL_FAILURE: - return NanStatusType::INTERNAL_FAILURE; - case legacy_hal::NAN_STATUS_PROTOCOL_FAILURE: - return NanStatusType::PROTOCOL_FAILURE; - case legacy_hal::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID: - return NanStatusType::INVALID_SESSION_ID; - case legacy_hal::NAN_STATUS_NO_RESOURCE_AVAILABLE: - return NanStatusType::NO_RESOURCES_AVAILABLE; - case legacy_hal::NAN_STATUS_INVALID_PARAM: - return NanStatusType::INVALID_ARGS; - case legacy_hal::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID: - return NanStatusType::INVALID_PEER_ID; - case legacy_hal::NAN_STATUS_INVALID_NDP_ID: - return NanStatusType::INVALID_NDP_ID; - case legacy_hal::NAN_STATUS_NAN_NOT_ALLOWED: - return NanStatusType::NAN_NOT_ALLOWED; - case legacy_hal::NAN_STATUS_NO_OTA_ACK: - return NanStatusType::NO_OTA_ACK; - case legacy_hal::NAN_STATUS_ALREADY_ENABLED: - return NanStatusType::ALREADY_ENABLED; - case legacy_hal::NAN_STATUS_FOLLOWUP_QUEUE_FULL: - return NanStatusType::FOLLOWUP_TX_QUEUE_FULL; - case legacy_hal::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED: - return NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED; - } - CHECK(false); -} - -void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, - size_t max_len, WifiNanStatus* wifiNanStatus) { - wifiNanStatus->status = convertLegacyNanStatusTypeToHidl(type); - wifiNanStatus->description = safeConvertChar(str, max_len); -} - -bool convertHidlNanEnableRequestToLegacy( - const V1_4::NanEnableRequest& hidl_request, - legacy_hal::NanEnableRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanEnableRequestToLegacy: null legacy_request"; - return false; - } - *legacy_request = {}; - - legacy_request->config_2dot4g_support = 1; - legacy_request->support_2dot4g_val = - hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ]; - legacy_request->config_support_5g = 1; - legacy_request->support_5g_val = - hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ]; - legacy_request->config_hop_count_limit = 1; - legacy_request->hop_count_limit_val = hidl_request.hopCountMax; - legacy_request->master_pref = hidl_request.configParams.masterPref; - legacy_request->discovery_indication_cfg = 0; - legacy_request->discovery_indication_cfg |= - hidl_request.configParams.disableDiscoveryAddressChangeIndication ? 0x1 - : 0x0; - legacy_request->discovery_indication_cfg |= - hidl_request.configParams.disableStartedClusterIndication ? 0x2 : 0x0; - legacy_request->discovery_indication_cfg |= - hidl_request.configParams.disableJoinedClusterIndication ? 0x4 : 0x0; - legacy_request->config_sid_beacon = 1; - if (hidl_request.configParams.numberOfPublishServiceIdsInBeacon > 127) { - LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: " - "numberOfPublishServiceIdsInBeacon > 127"; - return false; - } - legacy_request->sid_beacon_val = - (hidl_request.configParams.includePublishServiceIdsInBeacon ? 0x1 - : 0x0) | - (hidl_request.configParams.numberOfPublishServiceIdsInBeacon << 1); - legacy_request->config_subscribe_sid_beacon = 1; - if (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon > 127) { - LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: " - "numberOfSubscribeServiceIdsInBeacon > 127"; - return false; - } - legacy_request->subscribe_sid_beacon_val = - (hidl_request.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 - : 0x0) | - (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon << 1); - legacy_request->config_rssi_window_size = 1; - legacy_request->rssi_window_size_val = - hidl_request.configParams.rssiWindowSize; - legacy_request->config_disc_mac_addr_randomization = 1; - legacy_request->disc_mac_addr_rand_interval_sec = - hidl_request.configParams.macAddressRandomizationIntervalSec; - legacy_request->config_2dot4g_rssi_close = 1; - if (hidl_request.configParams.bandSpecificConfig.size() != 3) { - LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: " - "bandSpecificConfig.size() != 3"; - return false; - } - legacy_request->rssi_close_2dot4g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .rssiClose; - legacy_request->config_2dot4g_rssi_middle = 1; - legacy_request->rssi_middle_2dot4g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .rssiMiddle; - legacy_request->config_2dot4g_rssi_proximity = 1; - legacy_request->rssi_proximity_2dot4g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .rssiCloseProximity; - legacy_request->config_scan_params = 1; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .scanPeriodSec; - legacy_request->config_dw.config_2dot4g_dw_band = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .validDiscoveryWindowIntervalVal; - legacy_request->config_dw.dw_2dot4g_interval_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .discoveryWindowIntervalVal; - legacy_request->config_5g_rssi_close = 1; - legacy_request->rssi_close_5g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .rssiClose; - legacy_request->config_5g_rssi_middle = 1; - legacy_request->rssi_middle_5g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .rssiMiddle; - legacy_request->config_5g_rssi_close_proximity = 1; - legacy_request->rssi_close_proximity_5g_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .rssiCloseProximity; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .scanPeriodSec; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .scanPeriodSec; - legacy_request->config_dw.config_5g_dw_band = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .validDiscoveryWindowIntervalVal; - legacy_request->config_dw.dw_5g_interval_val = - hidl_request.configParams - .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .discoveryWindowIntervalVal; - if (hidl_request.debugConfigs.validClusterIdVals) { - legacy_request->cluster_low = - hidl_request.debugConfigs.clusterIdBottomRangeVal; - legacy_request->cluster_high = - hidl_request.debugConfigs.clusterIdTopRangeVal; - } else { // need 'else' since not configurable in legacy HAL - legacy_request->cluster_low = 0x0000; - legacy_request->cluster_high = 0xFFFF; - } - legacy_request->config_intf_addr = - hidl_request.debugConfigs.validIntfAddrVal; - memcpy(legacy_request->intf_addr_val, - hidl_request.debugConfigs.intfAddrVal.data(), 6); - legacy_request->config_oui = hidl_request.debugConfigs.validOuiVal; - legacy_request->oui_val = hidl_request.debugConfigs.ouiVal; - legacy_request->config_random_factor_force = - hidl_request.debugConfigs.validRandomFactorForceVal; - legacy_request->random_factor_force_val = - hidl_request.debugConfigs.randomFactorForceVal; - legacy_request->config_hop_count_force = - hidl_request.debugConfigs.validHopCountForceVal; - legacy_request->hop_count_force_val = - hidl_request.debugConfigs.hopCountForceVal; - legacy_request->config_24g_channel = - hidl_request.debugConfigs.validDiscoveryChannelVal; - legacy_request->channel_24g_val = - hidl_request.debugConfigs - .discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; - legacy_request->config_5g_channel = - hidl_request.debugConfigs.validDiscoveryChannelVal; - legacy_request->channel_5g_val = - hidl_request.debugConfigs - .discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; - legacy_request->config_2dot4g_beacons = - hidl_request.debugConfigs.validUseBeaconsInBandVal; - legacy_request->beacon_2dot4g_val = - hidl_request.debugConfigs - .useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; - legacy_request->config_5g_beacons = - hidl_request.debugConfigs.validUseBeaconsInBandVal; - legacy_request->beacon_5g_val = - hidl_request.debugConfigs - .useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; - legacy_request->config_2dot4g_sdf = - hidl_request.debugConfigs.validUseSdfInBandVal; - legacy_request->sdf_2dot4g_val = - hidl_request.debugConfigs - .useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; - legacy_request->config_5g_sdf = - hidl_request.debugConfigs.validUseSdfInBandVal; - legacy_request->sdf_5g_val = - hidl_request.debugConfigs - .useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; - - /* TODO: b/145609058 - * Missing updates needed to legacy_hal::NanEnableRequest and conversion to - * it for 6GHz band */ - - return true; -} - -bool convertHidlNanEnableRequest_1_4ToLegacy( - const V1_4::NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanEnableRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanEnableRequest_1_4ToLegacy: null legacy_request"; - return false; - } - - *legacy_request = {}; - if (!convertHidlNanEnableRequestToLegacy(hidl_request1, legacy_request)) { - return false; - } - - legacy_request->config_discovery_beacon_int = 1; - legacy_request->discovery_beacon_interval = - hidl_request2.V1_2.discoveryBeaconIntervalMs; - legacy_request->config_nss = 1; - legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; - legacy_request->config_dw_early_termination = 1; - legacy_request->enable_dw_termination = - hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; - legacy_request->config_enable_ranging = 1; - legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging; - - return true; -} - -bool convertHidlNanEnableRequest_1_5ToLegacy( - const V1_4::NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanEnableRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanEnableRequest_1_5ToLegacy: null legacy_request"; - return false; - } - - *legacy_request = {}; - if (!convertHidlNanEnableRequest_1_4ToLegacy(hidl_request1, hidl_request2, - legacy_request)) { - return false; - } - - legacy_request->config_enable_instant_mode = 1; - legacy_request->enable_instant_mode = - hidl_request2.enableInstantCommunicationMode; - - return true; -} - -bool convertHidlNanConfigRequest_1_5ToLegacy( - const V1_4::NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanConfigRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanConfigRequest_1_5ToLegacy: null legacy_request"; - return false; - } - - *legacy_request = {}; - if (!convertHidlNanConfigRequest_1_4ToLegacy(hidl_request1, hidl_request2, - legacy_request)) { - return false; - } - - legacy_request->config_enable_instant_mode = 1; - legacy_request->enable_instant_mode = - hidl_request2.enableInstantCommunicationMode; - - return true; -} - -bool convertHidlNanPublishRequestToLegacy( - const NanPublishRequest& hidl_request, - legacy_hal::NanPublishRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanPublishRequestToLegacy: null legacy_request"; - return false; - } - *legacy_request = {}; - - legacy_request->publish_id = hidl_request.baseConfigs.sessionId; - legacy_request->ttl = hidl_request.baseConfigs.ttlSec; - legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod; - legacy_request->publish_count = hidl_request.baseConfigs.discoveryCount; - legacy_request->service_name_len = - hidl_request.baseConfigs.serviceName.size(); - if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { - LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: service_name_len " - "too large"; - return false; - } - memcpy(legacy_request->service_name, - hidl_request.baseConfigs.serviceName.data(), - legacy_request->service_name_len); - legacy_request->publish_match_indicator = convertHidlNanMatchAlgToLegacy( - hidl_request.baseConfigs.discoveryMatchIndicator); - legacy_request->service_specific_info_len = - hidl_request.baseConfigs.serviceSpecificInfo.size(); - if (legacy_request->service_specific_info_len > - NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { - LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " - "service_specific_info_len too large"; - return false; - } - memcpy(legacy_request->service_specific_info, - hidl_request.baseConfigs.serviceSpecificInfo.data(), - legacy_request->service_specific_info_len); - legacy_request->sdea_service_specific_info_len = - hidl_request.baseConfigs.extendedServiceSpecificInfo.size(); - if (legacy_request->sdea_service_specific_info_len > - NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { - LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " - "sdea_service_specific_info_len too large"; - return false; - } - memcpy(legacy_request->sdea_service_specific_info, - hidl_request.baseConfigs.extendedServiceSpecificInfo.data(), - legacy_request->sdea_service_specific_info_len); - legacy_request->rx_match_filter_len = - hidl_request.baseConfigs.rxMatchFilter.size(); - if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { - LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " - "rx_match_filter_len too large"; - return false; - } - memcpy(legacy_request->rx_match_filter, - hidl_request.baseConfigs.rxMatchFilter.data(), - legacy_request->rx_match_filter_len); - legacy_request->tx_match_filter_len = - hidl_request.baseConfigs.txMatchFilter.size(); - if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { - LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " - "tx_match_filter_len too large"; - return false; - } - memcpy(legacy_request->tx_match_filter, - hidl_request.baseConfigs.txMatchFilter.data(), - legacy_request->tx_match_filter_len); - legacy_request->rssi_threshold_flag = - hidl_request.baseConfigs.useRssiThreshold; - legacy_request->recv_indication_cfg = 0; - legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 - : 0x0; - legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0; - legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0; - legacy_request->recv_indication_cfg |= 0x8; - legacy_request->cipher_type = - (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType; - if (hidl_request.baseConfigs.securityConfig.securityType == - NanDataPathSecurityType::PMK) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; - legacy_request->key_info.body.pmk_info.pmk_len = - hidl_request.baseConfigs.securityConfig.pmk.size(); - if (legacy_request->key_info.body.pmk_info.pmk_len != - NAN_PMK_INFO_LEN) { - LOG(ERROR) - << "convertHidlNanPublishRequestToLegacy: invalid pmk_len"; - return false; - } - memcpy(legacy_request->key_info.body.pmk_info.pmk, - hidl_request.baseConfigs.securityConfig.pmk.data(), - legacy_request->key_info.body.pmk_info.pmk_len); - } - if (hidl_request.baseConfigs.securityConfig.securityType == - NanDataPathSecurityType::PASSPHRASE) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; - legacy_request->key_info.body.passphrase_info.passphrase_len = - hidl_request.baseConfigs.securityConfig.passphrase.size(); - if (legacy_request->key_info.body.passphrase_info.passphrase_len < - NAN_SECURITY_MIN_PASSPHRASE_LEN) { - LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " - "passphrase_len too small"; - return false; - } - if (legacy_request->key_info.body.passphrase_info.passphrase_len > - NAN_SECURITY_MAX_PASSPHRASE_LEN) { - LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " - "passphrase_len too large"; - return false; - } - memcpy(legacy_request->key_info.body.passphrase_info.passphrase, - hidl_request.baseConfigs.securityConfig.passphrase.data(), - legacy_request->key_info.body.passphrase_info.passphrase_len); - } - legacy_request->sdea_params.security_cfg = - (hidl_request.baseConfigs.securityConfig.securityType != - NanDataPathSecurityType::OPEN) - ? legacy_hal::NAN_DP_CONFIG_SECURITY - : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; - legacy_request->sdea_params.ranging_state = - hidl_request.baseConfigs.rangingRequired - ? legacy_hal::NAN_RANGING_ENABLE - : legacy_hal::NAN_RANGING_DISABLE; - legacy_request->ranging_cfg.ranging_interval_msec = - hidl_request.baseConfigs.rangingIntervalMsec; - legacy_request->ranging_cfg.config_ranging_indications = - hidl_request.baseConfigs.configRangingIndications; - legacy_request->ranging_cfg.distance_ingress_mm = - hidl_request.baseConfigs.distanceIngressCm * 10; - legacy_request->ranging_cfg.distance_egress_mm = - hidl_request.baseConfigs.distanceEgressCm * 10; - legacy_request->ranging_auto_response = - hidl_request.baseConfigs.rangingRequired - ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE - : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE; - legacy_request->sdea_params.range_report = - legacy_hal::NAN_DISABLE_RANGE_REPORT; - legacy_request->publish_type = - convertHidlNanPublishTypeToLegacy(hidl_request.publishType); - legacy_request->tx_type = convertHidlNanTxTypeToLegacy(hidl_request.txType); - legacy_request->service_responder_policy = - hidl_request.autoAcceptDataPathRequests - ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL - : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE; - - return true; -} - -bool convertHidlNanSubscribeRequestToLegacy( - const NanSubscribeRequest& hidl_request, - legacy_hal::NanSubscribeRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanSubscribeRequestToLegacy: legacy_request is null"; - return false; - } - *legacy_request = {}; - - legacy_request->subscribe_id = hidl_request.baseConfigs.sessionId; - legacy_request->ttl = hidl_request.baseConfigs.ttlSec; - legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod; - legacy_request->subscribe_count = hidl_request.baseConfigs.discoveryCount; - legacy_request->service_name_len = - hidl_request.baseConfigs.serviceName.size(); - if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { - LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " - "service_name_len too large"; - return false; - } - memcpy(legacy_request->service_name, - hidl_request.baseConfigs.serviceName.data(), - legacy_request->service_name_len); - legacy_request->subscribe_match_indicator = convertHidlNanMatchAlgToLegacy( - hidl_request.baseConfigs.discoveryMatchIndicator); - legacy_request->service_specific_info_len = - hidl_request.baseConfigs.serviceSpecificInfo.size(); - if (legacy_request->service_specific_info_len > - NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { - LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " - "service_specific_info_len too large"; - return false; - } - memcpy(legacy_request->service_specific_info, - hidl_request.baseConfigs.serviceSpecificInfo.data(), - legacy_request->service_specific_info_len); - legacy_request->sdea_service_specific_info_len = - hidl_request.baseConfigs.extendedServiceSpecificInfo.size(); - if (legacy_request->sdea_service_specific_info_len > - NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { - LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " - "sdea_service_specific_info_len too large"; - return false; - } - memcpy(legacy_request->sdea_service_specific_info, - hidl_request.baseConfigs.extendedServiceSpecificInfo.data(), - legacy_request->sdea_service_specific_info_len); - legacy_request->rx_match_filter_len = - hidl_request.baseConfigs.rxMatchFilter.size(); - if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { - LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " - "rx_match_filter_len too large"; - return false; - } - memcpy(legacy_request->rx_match_filter, - hidl_request.baseConfigs.rxMatchFilter.data(), - legacy_request->rx_match_filter_len); - legacy_request->tx_match_filter_len = - hidl_request.baseConfigs.txMatchFilter.size(); - if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { - LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " - "tx_match_filter_len too large"; - return false; - } - memcpy(legacy_request->tx_match_filter, - hidl_request.baseConfigs.txMatchFilter.data(), - legacy_request->tx_match_filter_len); - legacy_request->rssi_threshold_flag = - hidl_request.baseConfigs.useRssiThreshold; - legacy_request->recv_indication_cfg = 0; - legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 - : 0x0; - legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0; - legacy_request->recv_indication_cfg |= - hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0; - legacy_request->cipher_type = - (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType; - if (hidl_request.baseConfigs.securityConfig.securityType == - NanDataPathSecurityType::PMK) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; - legacy_request->key_info.body.pmk_info.pmk_len = - hidl_request.baseConfigs.securityConfig.pmk.size(); - if (legacy_request->key_info.body.pmk_info.pmk_len != - NAN_PMK_INFO_LEN) { - LOG(ERROR) - << "convertHidlNanSubscribeRequestToLegacy: invalid pmk_len"; - return false; - } - memcpy(legacy_request->key_info.body.pmk_info.pmk, - hidl_request.baseConfigs.securityConfig.pmk.data(), - legacy_request->key_info.body.pmk_info.pmk_len); - } - if (hidl_request.baseConfigs.securityConfig.securityType == - NanDataPathSecurityType::PASSPHRASE) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; - legacy_request->key_info.body.passphrase_info.passphrase_len = - hidl_request.baseConfigs.securityConfig.passphrase.size(); - if (legacy_request->key_info.body.passphrase_info.passphrase_len < - NAN_SECURITY_MIN_PASSPHRASE_LEN) { - LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " - "passphrase_len too small"; - return false; - } - if (legacy_request->key_info.body.passphrase_info.passphrase_len > - NAN_SECURITY_MAX_PASSPHRASE_LEN) { - LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " - "passphrase_len too large"; - return false; - } - memcpy(legacy_request->key_info.body.passphrase_info.passphrase, - hidl_request.baseConfigs.securityConfig.passphrase.data(), - legacy_request->key_info.body.passphrase_info.passphrase_len); - } - legacy_request->sdea_params.security_cfg = - (hidl_request.baseConfigs.securityConfig.securityType != - NanDataPathSecurityType::OPEN) - ? legacy_hal::NAN_DP_CONFIG_SECURITY - : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; - legacy_request->sdea_params.ranging_state = - hidl_request.baseConfigs.rangingRequired - ? legacy_hal::NAN_RANGING_ENABLE - : legacy_hal::NAN_RANGING_DISABLE; - legacy_request->ranging_cfg.ranging_interval_msec = - hidl_request.baseConfigs.rangingIntervalMsec; - legacy_request->ranging_cfg.config_ranging_indications = - hidl_request.baseConfigs.configRangingIndications; - legacy_request->ranging_cfg.distance_ingress_mm = - hidl_request.baseConfigs.distanceIngressCm * 10; - legacy_request->ranging_cfg.distance_egress_mm = - hidl_request.baseConfigs.distanceEgressCm * 10; - legacy_request->ranging_auto_response = - hidl_request.baseConfigs.rangingRequired - ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE - : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE; - legacy_request->sdea_params.range_report = - legacy_hal::NAN_DISABLE_RANGE_REPORT; - legacy_request->subscribe_type = - convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType); - legacy_request->serviceResponseFilter = - convertHidlNanSrfTypeToLegacy(hidl_request.srfType); - legacy_request->serviceResponseInclude = - hidl_request.srfRespondIfInAddressSet - ? legacy_hal::NAN_SRF_INCLUDE_RESPOND - : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND; - legacy_request->useServiceResponseFilter = - hidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF - : legacy_hal::NAN_DO_NOT_USE_SRF; - legacy_request->ssiRequiredForMatchIndication = - hidl_request.isSsiRequiredForMatch - ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND - : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND; - legacy_request->num_intf_addr_present = hidl_request.intfAddr.size(); - if (legacy_request->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) { - LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " - "num_intf_addr_present - too many"; - return false; - } - for (int i = 0; i < legacy_request->num_intf_addr_present; i++) { - memcpy(legacy_request->intf_addr[i], hidl_request.intfAddr[i].data(), - 6); - } - - return true; -} - -bool convertHidlNanTransmitFollowupRequestToLegacy( - const NanTransmitFollowupRequest& hidl_request, - legacy_hal::NanTransmitFollowupRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: " - "legacy_request is null"; - return false; - } - *legacy_request = {}; - - legacy_request->publish_subscribe_id = hidl_request.discoverySessionId; - legacy_request->requestor_instance_id = hidl_request.peerId; - memcpy(legacy_request->addr, hidl_request.addr.data(), 6); - legacy_request->priority = hidl_request.isHighPriority - ? legacy_hal::NAN_TX_PRIORITY_HIGH - : legacy_hal::NAN_TX_PRIORITY_NORMAL; - legacy_request->dw_or_faw = hidl_request.shouldUseDiscoveryWindow - ? legacy_hal::NAN_TRANSMIT_IN_DW - : legacy_hal::NAN_TRANSMIT_IN_FAW; - legacy_request->service_specific_info_len = - hidl_request.serviceSpecificInfo.size(); - if (legacy_request->service_specific_info_len > - NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { - LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: " - "service_specific_info_len too large"; - return false; - } - memcpy(legacy_request->service_specific_info, - hidl_request.serviceSpecificInfo.data(), - legacy_request->service_specific_info_len); - legacy_request->sdea_service_specific_info_len = - hidl_request.extendedServiceSpecificInfo.size(); - if (legacy_request->sdea_service_specific_info_len > - NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { - LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: " - "sdea_service_specific_info_len too large"; - return false; - } - memcpy(legacy_request->sdea_service_specific_info, - hidl_request.extendedServiceSpecificInfo.data(), - legacy_request->sdea_service_specific_info_len); - legacy_request->recv_indication_cfg = - hidl_request.disableFollowupResultIndication ? 0x1 : 0x0; - - return true; -} - -bool convertHidlNanConfigRequestToLegacy( - const V1_4::NanConfigRequest& hidl_request, - legacy_hal::NanConfigRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) - << "convertHidlNanConfigRequestToLegacy: legacy_request is null"; - return false; - } - *legacy_request = {}; - - // TODO: b/34059183 tracks missing configurations in legacy HAL or uknown - // defaults - legacy_request->master_pref = hidl_request.masterPref; - legacy_request->discovery_indication_cfg = 0; - legacy_request->discovery_indication_cfg |= - hidl_request.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0; - legacy_request->discovery_indication_cfg |= - hidl_request.disableStartedClusterIndication ? 0x2 : 0x0; - legacy_request->discovery_indication_cfg |= - hidl_request.disableJoinedClusterIndication ? 0x4 : 0x0; - legacy_request->config_sid_beacon = 1; - if (hidl_request.numberOfPublishServiceIdsInBeacon > 127) { - LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: " - "numberOfPublishServiceIdsInBeacon > 127"; - return false; - } - legacy_request->sid_beacon = - (hidl_request.includePublishServiceIdsInBeacon ? 0x1 : 0x0) | - (hidl_request.numberOfPublishServiceIdsInBeacon << 1); - legacy_request->config_subscribe_sid_beacon = 1; - if (hidl_request.numberOfSubscribeServiceIdsInBeacon > 127) { - LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: " - "numberOfSubscribeServiceIdsInBeacon > 127"; - return false; - } - legacy_request->subscribe_sid_beacon_val = - (hidl_request.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) | - (hidl_request.numberOfSubscribeServiceIdsInBeacon << 1); - legacy_request->config_rssi_window_size = 1; - legacy_request->rssi_window_size_val = hidl_request.rssiWindowSize; - legacy_request->config_disc_mac_addr_randomization = 1; - legacy_request->disc_mac_addr_rand_interval_sec = - hidl_request.macAddressRandomizationIntervalSec; - /* TODO : missing - legacy_request->config_2dot4g_rssi_close = 1; - legacy_request->rssi_close_2dot4g_val = - hidl_request.bandSpecificConfig[ - (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiClose; - legacy_request->config_2dot4g_rssi_middle = 1; - legacy_request->rssi_middle_2dot4g_val = - hidl_request.bandSpecificConfig[ - (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiMiddle; - legacy_request->config_2dot4g_rssi_proximity = 1; - legacy_request->rssi_proximity_2dot4g_val = - hidl_request.bandSpecificConfig[ - (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiCloseProximity; - */ - legacy_request->config_scan_params = 1; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .scanPeriodSec; - legacy_request->config_dw.config_2dot4g_dw_band = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .validDiscoveryWindowIntervalVal; - legacy_request->config_dw.dw_2dot4g_interval_val = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] - .discoveryWindowIntervalVal; - /* TODO: missing - legacy_request->config_5g_rssi_close = 1; - legacy_request->rssi_close_5g_val = - hidl_request.bandSpecificConfig[ - (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiClose; - legacy_request->config_5g_rssi_middle = 1; - legacy_request->rssi_middle_5g_val = - hidl_request.bandSpecificConfig[ - (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiMiddle; - */ - legacy_request->config_5g_rssi_close_proximity = 1; - legacy_request->rssi_close_proximity_5g_val = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .rssiCloseProximity; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .scanPeriodSec; - legacy_request->scan_params_val - .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .dwellTimeMs; - legacy_request->scan_params_val - .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .scanPeriodSec; - legacy_request->config_dw.config_5g_dw_band = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .validDiscoveryWindowIntervalVal; - legacy_request->config_dw.dw_5g_interval_val = - hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] - .discoveryWindowIntervalVal; - /* TODO: b/145609058 - * Missing updates needed to legacy_hal::NanConfigRequest and conversion to - * it for 6GHz band */ - - return true; -} - -bool convertHidlNanConfigRequest_1_4ToLegacy( - const V1_4::NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanConfigRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) << "convertHidlNanConfigRequest_1_4ToLegacy: legacy_request " - "is null"; - return false; - } - - *legacy_request = {}; - if (!convertHidlNanConfigRequestToLegacy(hidl_request1, legacy_request)) { - return false; - } - - legacy_request->config_discovery_beacon_int = 1; - legacy_request->discovery_beacon_interval = - hidl_request2.V1_2.discoveryBeaconIntervalMs; - legacy_request->config_nss = 1; - legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; - legacy_request->config_dw_early_termination = 1; - legacy_request->enable_dw_termination = - hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; - legacy_request->config_enable_ranging = 1; - legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging; - - return true; -} - -bool convertHidlNanDataPathInitiatorRequestToLegacy( - const NanInitiateDataPathRequest& hidl_request, - legacy_hal::NanDataPathInitiatorRequest* legacy_request) { - if (!legacy_request) { - LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " - "legacy_request is null"; - return false; - } - *legacy_request = {}; - - legacy_request->requestor_instance_id = hidl_request.peerId; - memcpy(legacy_request->peer_disc_mac_addr, - hidl_request.peerDiscMacAddr.data(), 6); - legacy_request->channel_request_type = - convertHidlNanDataPathChannelCfgToLegacy( - hidl_request.channelRequestType); - legacy_request->channel = hidl_request.channel; - if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) { - LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " - "ifaceName too long"; - return false; - } - strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), - IFNAMSIZ + 1); - legacy_request->ndp_cfg.security_cfg = - (hidl_request.securityConfig.securityType != - NanDataPathSecurityType::OPEN) - ? legacy_hal::NAN_DP_CONFIG_SECURITY - : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; - legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size(); - if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) { - LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " - "ndp_app_info_len too large"; - return false; - } - memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(), - legacy_request->app_info.ndp_app_info_len); - legacy_request->cipher_type = - (unsigned int)hidl_request.securityConfig.cipherType; - if (hidl_request.securityConfig.securityType == - NanDataPathSecurityType::PMK) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; - legacy_request->key_info.body.pmk_info.pmk_len = - hidl_request.securityConfig.pmk.size(); - if (legacy_request->key_info.body.pmk_info.pmk_len != - NAN_PMK_INFO_LEN) { - LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " - "invalid pmk_len"; - return false; - } - memcpy(legacy_request->key_info.body.pmk_info.pmk, - hidl_request.securityConfig.pmk.data(), - legacy_request->key_info.body.pmk_info.pmk_len); - } - if (hidl_request.securityConfig.securityType == - NanDataPathSecurityType::PASSPHRASE) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; - legacy_request->key_info.body.passphrase_info.passphrase_len = - hidl_request.securityConfig.passphrase.size(); - if (legacy_request->key_info.body.passphrase_info.passphrase_len < - NAN_SECURITY_MIN_PASSPHRASE_LEN) { - LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " - "passphrase_len too small"; - return false; - } - if (legacy_request->key_info.body.passphrase_info.passphrase_len > - NAN_SECURITY_MAX_PASSPHRASE_LEN) { - LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " - "passphrase_len too large"; - return false; - } - memcpy(legacy_request->key_info.body.passphrase_info.passphrase, - hidl_request.securityConfig.passphrase.data(), - legacy_request->key_info.body.passphrase_info.passphrase_len); - } - legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size(); - if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { - LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " - "service_name_len too large"; - return false; - } - memcpy(legacy_request->service_name, - hidl_request.serviceNameOutOfBand.data(), - legacy_request->service_name_len); - - return true; -} - -bool convertHidlNanDataPathIndicationResponseToLegacy( - const NanRespondToDataPathIndicationRequest& hidl_request, - legacy_hal::NanDataPathIndicationResponse* legacy_request) { - if (!legacy_request) { - LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " - "legacy_request is null"; - return false; - } - *legacy_request = {}; - - legacy_request->rsp_code = hidl_request.acceptRequest - ? legacy_hal::NAN_DP_REQUEST_ACCEPT - : legacy_hal::NAN_DP_REQUEST_REJECT; - legacy_request->ndp_instance_id = hidl_request.ndpInstanceId; - if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) { - LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " - "ifaceName too long"; - return false; - } - strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), - IFNAMSIZ + 1); - legacy_request->ndp_cfg.security_cfg = - (hidl_request.securityConfig.securityType != - NanDataPathSecurityType::OPEN) - ? legacy_hal::NAN_DP_CONFIG_SECURITY - : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; - legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size(); - if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) { - LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " - "ndp_app_info_len too large"; - return false; - } - memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(), - legacy_request->app_info.ndp_app_info_len); - legacy_request->cipher_type = - (unsigned int)hidl_request.securityConfig.cipherType; - if (hidl_request.securityConfig.securityType == - NanDataPathSecurityType::PMK) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; - legacy_request->key_info.body.pmk_info.pmk_len = - hidl_request.securityConfig.pmk.size(); - if (legacy_request->key_info.body.pmk_info.pmk_len != - NAN_PMK_INFO_LEN) { - LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " - "invalid pmk_len"; - return false; - } - memcpy(legacy_request->key_info.body.pmk_info.pmk, - hidl_request.securityConfig.pmk.data(), - legacy_request->key_info.body.pmk_info.pmk_len); - } - if (hidl_request.securityConfig.securityType == - NanDataPathSecurityType::PASSPHRASE) { - legacy_request->key_info.key_type = - legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; - legacy_request->key_info.body.passphrase_info.passphrase_len = - hidl_request.securityConfig.passphrase.size(); - if (legacy_request->key_info.body.passphrase_info.passphrase_len < - NAN_SECURITY_MIN_PASSPHRASE_LEN) { - LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " - "passphrase_len too small"; - return false; - } - if (legacy_request->key_info.body.passphrase_info.passphrase_len > - NAN_SECURITY_MAX_PASSPHRASE_LEN) { - LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " - "passphrase_len too large"; - return false; - } - memcpy(legacy_request->key_info.body.passphrase_info.passphrase, - hidl_request.securityConfig.passphrase.data(), - legacy_request->key_info.body.passphrase_info.passphrase_len); - } - legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size(); - if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { - LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " - "service_name_len too large"; - return false; - } - memcpy(legacy_request->service_name, - hidl_request.serviceNameOutOfBand.data(), - legacy_request->service_name_len); - - return true; -} - -bool convertLegacyNanResponseHeaderToHidl( - const legacy_hal::NanResponseMsg& legacy_response, - WifiNanStatus* wifiNanStatus) { - if (!wifiNanStatus) { - LOG(ERROR) - << "convertLegacyNanResponseHeaderToHidl: wifiNanStatus is null"; - return false; - } - *wifiNanStatus = {}; - - convertToWifiNanStatus(legacy_response.status, legacy_response.nan_error, - sizeof(legacy_response.nan_error), wifiNanStatus); - return true; -} - -bool convertLegacyNanCapabilitiesResponseToHidl( - const legacy_hal::NanCapabilities& legacy_response, - NanCapabilities* hidl_response) { - if (!hidl_response) { - LOG(ERROR) << "convertLegacyNanCapabilitiesResponseToHidl: " - "hidl_response is null"; - return false; - } - *hidl_response = {}; - - hidl_response->V1_0.maxConcurrentClusters = - legacy_response.max_concurrent_nan_clusters; - hidl_response->V1_0.maxPublishes = legacy_response.max_publishes; - hidl_response->V1_0.maxSubscribes = legacy_response.max_subscribes; - hidl_response->V1_0.maxServiceNameLen = - legacy_response.max_service_name_len; - hidl_response->V1_0.maxMatchFilterLen = - legacy_response.max_match_filter_len; - hidl_response->V1_0.maxTotalMatchFilterLen = - legacy_response.max_total_match_filter_len; - hidl_response->V1_0.maxServiceSpecificInfoLen = - legacy_response.max_service_specific_info_len; - hidl_response->V1_0.maxExtendedServiceSpecificInfoLen = - legacy_response.max_sdea_service_specific_info_len; - hidl_response->V1_0.maxNdiInterfaces = legacy_response.max_ndi_interfaces; - hidl_response->V1_0.maxNdpSessions = legacy_response.max_ndp_sessions; - hidl_response->V1_0.maxAppInfoLen = legacy_response.max_app_info_len; - hidl_response->V1_0.maxQueuedTransmitFollowupMsgs = - legacy_response.max_queued_transmit_followup_msgs; - hidl_response->V1_0.maxSubscribeInterfaceAddresses = - legacy_response.max_subscribe_address; - hidl_response->V1_0.supportedCipherSuites = - legacy_response.cipher_suites_supported; - hidl_response->instantCommunicationModeSupportFlag = - legacy_response.is_instant_mode_supported; - - return true; -} - -bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind, - NanMatchInd* hidl_ind) { - if (!hidl_ind) { - LOG(ERROR) << "convertLegacyNanMatchIndToHidl: hidl_ind is null"; - return false; - } - *hidl_ind = {}; - - hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id; - hidl_ind->peerId = legacy_ind.requestor_instance_id; - hidl_ind->addr = hidl_array(legacy_ind.addr); - hidl_ind->serviceSpecificInfo = - std::vector(legacy_ind.service_specific_info, - legacy_ind.service_specific_info + - legacy_ind.service_specific_info_len); - hidl_ind->extendedServiceSpecificInfo = - std::vector(legacy_ind.sdea_service_specific_info, - legacy_ind.sdea_service_specific_info + - legacy_ind.sdea_service_specific_info_len); - hidl_ind->matchFilter = std::vector( - legacy_ind.sdf_match_filter, - legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len); - hidl_ind->matchOccuredInBeaconFlag = legacy_ind.match_occured_flag == 1; - hidl_ind->outOfResourceFlag = legacy_ind.out_of_resource_flag == 1; - hidl_ind->rssiValue = legacy_ind.rssi_value; - hidl_ind->peerCipherType = (NanCipherSuiteType)legacy_ind.peer_cipher_type; - hidl_ind->peerRequiresSecurityEnabledInNdp = - legacy_ind.peer_sdea_params.security_cfg == - legacy_hal::NAN_DP_CONFIG_SECURITY; - hidl_ind->peerRequiresRanging = legacy_ind.peer_sdea_params.ranging_state == - legacy_hal::NAN_RANGING_ENABLE; - hidl_ind->rangingMeasurementInCm = - legacy_ind.range_info.range_measurement_mm / 10; - hidl_ind->rangingIndicationType = legacy_ind.range_info.ranging_event_type; - - return true; -} - -bool convertLegacyNanFollowupIndToHidl( - const legacy_hal::NanFollowupInd& legacy_ind, - NanFollowupReceivedInd* hidl_ind) { - if (!hidl_ind) { - LOG(ERROR) << "convertLegacyNanFollowupIndToHidl: hidl_ind is null"; - return false; - } - *hidl_ind = {}; - - hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id; - hidl_ind->peerId = legacy_ind.requestor_instance_id; - hidl_ind->addr = hidl_array(legacy_ind.addr); - hidl_ind->receivedInFaw = legacy_ind.dw_or_faw == 1; - hidl_ind->serviceSpecificInfo = - std::vector(legacy_ind.service_specific_info, - legacy_ind.service_specific_info + - legacy_ind.service_specific_info_len); - hidl_ind->extendedServiceSpecificInfo = - std::vector(legacy_ind.sdea_service_specific_info, - legacy_ind.sdea_service_specific_info + - legacy_ind.sdea_service_specific_info_len); - - return true; -} - -bool convertLegacyNanDataPathRequestIndToHidl( - const legacy_hal::NanDataPathRequestInd& legacy_ind, - NanDataPathRequestInd* hidl_ind) { - if (!hidl_ind) { - LOG(ERROR) - << "convertLegacyNanDataPathRequestIndToHidl: hidl_ind is null"; - return false; - } - *hidl_ind = {}; - - hidl_ind->discoverySessionId = legacy_ind.service_instance_id; - hidl_ind->peerDiscMacAddr = - hidl_array(legacy_ind.peer_disc_mac_addr); - hidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id; - hidl_ind->securityRequired = - legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY; - hidl_ind->appInfo = - std::vector(legacy_ind.app_info.ndp_app_info, - legacy_ind.app_info.ndp_app_info + - legacy_ind.app_info.ndp_app_info_len); - - return true; -} - -bool convertLegacyNdpChannelInfoToHidl( - const legacy_hal::NanChannelInfo& legacy_struct, - V1_2::NanDataPathChannelInfo* hidl_struct) { - if (!hidl_struct) { - LOG(ERROR) << "convertLegacyNdpChannelInfoToHidl: hidl_struct is null"; - return false; - } - *hidl_struct = {}; - - hidl_struct->channelFreq = legacy_struct.channel; - hidl_struct->channelBandwidth = convertLegacyWifiChannelWidthToHidl( - (legacy_hal::wifi_channel_width)legacy_struct.bandwidth); - hidl_struct->numSpatialStreams = legacy_struct.nss; - - return true; -} - -bool convertLegacyNanDataPathConfirmIndToHidl( - const legacy_hal::NanDataPathConfirmInd& legacy_ind, - V1_2::NanDataPathConfirmInd* hidl_ind) { - if (!hidl_ind) { - LOG(ERROR) - << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null"; - return false; - } - *hidl_ind = {}; - - hidl_ind->V1_0.ndpInstanceId = legacy_ind.ndp_instance_id; - hidl_ind->V1_0.dataPathSetupSuccess = - legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT; - hidl_ind->V1_0.peerNdiMacAddr = - hidl_array(legacy_ind.peer_ndi_mac_addr); - hidl_ind->V1_0.appInfo = - std::vector(legacy_ind.app_info.ndp_app_info, - legacy_ind.app_info.ndp_app_info + - legacy_ind.app_info.ndp_app_info_len); - hidl_ind->V1_0.status.status = - convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code); - hidl_ind->V1_0.status.description = ""; // TODO: b/34059183 - - std::vector channelInfo; - for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { - V1_2::NanDataPathChannelInfo hidl_struct; - if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], - &hidl_struct)) { - return false; - } - channelInfo.push_back(hidl_struct); - } - hidl_ind->channelInfo = channelInfo; - - return true; -} - -bool convertLegacyNanDataPathScheduleUpdateIndToHidl( - const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, - V1_2::NanDataPathScheduleUpdateInd* hidl_ind) { - if (!hidl_ind) { - LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToHidl: " - "hidl_ind is null"; - return false; - } - *hidl_ind = {}; - - hidl_ind->peerDiscoveryAddress = - hidl_array(legacy_ind.peer_mac_addr); - std::vector channelInfo; - for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { - V1_2::NanDataPathChannelInfo hidl_struct; - if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], - &hidl_struct)) { - return false; - } - channelInfo.push_back(hidl_struct); - } - hidl_ind->channelInfo = channelInfo; - std::vector ndpInstanceIds; - for (unsigned int i = 0; i < legacy_ind.num_ndp_instances; ++i) { - ndpInstanceIds.push_back(legacy_ind.ndp_instance_id[i]); - } - hidl_ind->ndpInstanceIds = ndpInstanceIds; - - return true; -} - -legacy_hal::wifi_rtt_type convertHidlRttTypeToLegacy(RttType type) { - switch (type) { - case RttType::ONE_SIDED: - return legacy_hal::RTT_TYPE_1_SIDED; - case RttType::TWO_SIDED: - return legacy_hal::RTT_TYPE_2_SIDED; - }; - CHECK(false); -} - -RttType convertLegacyRttTypeToHidl(legacy_hal::wifi_rtt_type type) { - switch (type) { - case legacy_hal::RTT_TYPE_1_SIDED: - return RttType::ONE_SIDED; - case legacy_hal::RTT_TYPE_2_SIDED: - return RttType::TWO_SIDED; - }; - CHECK(false) << "Unknown legacy type: " << type; -} - -legacy_hal::rtt_peer_type convertHidlRttPeerTypeToLegacy(RttPeerType type) { - switch (type) { - case RttPeerType::AP: - return legacy_hal::RTT_PEER_AP; - case RttPeerType::STA: - return legacy_hal::RTT_PEER_STA; - case RttPeerType::P2P_GO: - return legacy_hal::RTT_PEER_P2P_GO; - case RttPeerType::P2P_CLIENT: - return legacy_hal::RTT_PEER_P2P_CLIENT; - case RttPeerType::NAN: - return legacy_hal::RTT_PEER_NAN; - }; - CHECK(false); -} - -legacy_hal::wifi_channel_width convertHidlWifiChannelWidthToLegacy( - WifiChannelWidthInMhz type) { - switch (type) { - case WifiChannelWidthInMhz::WIDTH_20: - return legacy_hal::WIFI_CHAN_WIDTH_20; - case WifiChannelWidthInMhz::WIDTH_40: - return legacy_hal::WIFI_CHAN_WIDTH_40; - case WifiChannelWidthInMhz::WIDTH_80: - return legacy_hal::WIFI_CHAN_WIDTH_80; - case WifiChannelWidthInMhz::WIDTH_160: - return legacy_hal::WIFI_CHAN_WIDTH_160; - case WifiChannelWidthInMhz::WIDTH_80P80: - return legacy_hal::WIFI_CHAN_WIDTH_80P80; - case WifiChannelWidthInMhz::WIDTH_5: - return legacy_hal::WIFI_CHAN_WIDTH_5; - case WifiChannelWidthInMhz::WIDTH_10: - return legacy_hal::WIFI_CHAN_WIDTH_10; - case WifiChannelWidthInMhz::WIDTH_INVALID: - return legacy_hal::WIFI_CHAN_WIDTH_INVALID; - }; - CHECK(false); -} - -WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl( - legacy_hal::wifi_channel_width type) { - switch (type) { - case legacy_hal::WIFI_CHAN_WIDTH_20: - return WifiChannelWidthInMhz::WIDTH_20; - case legacy_hal::WIFI_CHAN_WIDTH_40: - return WifiChannelWidthInMhz::WIDTH_40; - case legacy_hal::WIFI_CHAN_WIDTH_80: - return WifiChannelWidthInMhz::WIDTH_80; - case legacy_hal::WIFI_CHAN_WIDTH_160: - return WifiChannelWidthInMhz::WIDTH_160; - case legacy_hal::WIFI_CHAN_WIDTH_80P80: - return WifiChannelWidthInMhz::WIDTH_80P80; - case legacy_hal::WIFI_CHAN_WIDTH_5: - return WifiChannelWidthInMhz::WIDTH_5; - case legacy_hal::WIFI_CHAN_WIDTH_10: - return WifiChannelWidthInMhz::WIDTH_10; - default: - return WifiChannelWidthInMhz::WIDTH_INVALID; - }; -} - -legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy( - V1_4::RttPreamble type) { - switch (type) { - case V1_4::RttPreamble::LEGACY: - return legacy_hal::WIFI_RTT_PREAMBLE_LEGACY; - case V1_4::RttPreamble::HT: - return legacy_hal::WIFI_RTT_PREAMBLE_HT; - case V1_4::RttPreamble::VHT: - return legacy_hal::WIFI_RTT_PREAMBLE_VHT; - case V1_4::RttPreamble::HE: - return legacy_hal::WIFI_RTT_PREAMBLE_HE; - }; - CHECK(false); -} - -V1_4::RttPreamble convertLegacyRttPreambleToHidl( - legacy_hal::wifi_rtt_preamble type) { - switch (type) { - case legacy_hal::WIFI_RTT_PREAMBLE_LEGACY: - return V1_4::RttPreamble::LEGACY; - case legacy_hal::WIFI_RTT_PREAMBLE_HT: - return V1_4::RttPreamble::HT; - case legacy_hal::WIFI_RTT_PREAMBLE_VHT: - return V1_4::RttPreamble::VHT; - case legacy_hal::WIFI_RTT_PREAMBLE_HE: - return V1_4::RttPreamble::HE; - }; - CHECK(false) << "Unknown legacy type: " << type; -} - -legacy_hal::wifi_rtt_bw convertHidlRttBwToLegacy(RttBw type) { - switch (type) { - case RttBw::BW_5MHZ: - return legacy_hal::WIFI_RTT_BW_5; - case RttBw::BW_10MHZ: - return legacy_hal::WIFI_RTT_BW_10; - case RttBw::BW_20MHZ: - return legacy_hal::WIFI_RTT_BW_20; - case RttBw::BW_40MHZ: - return legacy_hal::WIFI_RTT_BW_40; - case RttBw::BW_80MHZ: - return legacy_hal::WIFI_RTT_BW_80; - case RttBw::BW_160MHZ: - return legacy_hal::WIFI_RTT_BW_160; - }; - CHECK(false); -} - -RttBw convertLegacyRttBwToHidl(legacy_hal::wifi_rtt_bw type) { - switch (type) { - case legacy_hal::WIFI_RTT_BW_5: - return RttBw::BW_5MHZ; - case legacy_hal::WIFI_RTT_BW_10: - return RttBw::BW_10MHZ; - case legacy_hal::WIFI_RTT_BW_20: - return RttBw::BW_20MHZ; - case legacy_hal::WIFI_RTT_BW_40: - return RttBw::BW_40MHZ; - case legacy_hal::WIFI_RTT_BW_80: - return RttBw::BW_80MHZ; - case legacy_hal::WIFI_RTT_BW_160: - return RttBw::BW_160MHZ; - }; - CHECK(false) << "Unknown legacy type: " << type; -} - -legacy_hal::wifi_motion_pattern convertHidlRttMotionPatternToLegacy( - RttMotionPattern type) { - switch (type) { - case RttMotionPattern::NOT_EXPECTED: - return legacy_hal::WIFI_MOTION_NOT_EXPECTED; - case RttMotionPattern::EXPECTED: - return legacy_hal::WIFI_MOTION_EXPECTED; - case RttMotionPattern::UNKNOWN: - return legacy_hal::WIFI_MOTION_UNKNOWN; - }; - CHECK(false); -} - -V1_4::WifiRatePreamble convertLegacyWifiRatePreambleToHidl(uint8_t preamble) { - switch (preamble) { - case 0: - return V1_4::WifiRatePreamble::OFDM; - case 1: - return V1_4::WifiRatePreamble::CCK; - case 2: - return V1_4::WifiRatePreamble::HT; - case 3: - return V1_4::WifiRatePreamble::VHT; - case 4: - return V1_4::WifiRatePreamble::HE; - default: - return V1_4::WifiRatePreamble::RESERVED; - }; - CHECK(false) << "Unknown legacy preamble: " << preamble; -} - -WifiRateNss convertLegacyWifiRateNssToHidl(uint8_t nss) { - switch (nss) { - case 0: - return WifiRateNss::NSS_1x1; - case 1: - return WifiRateNss::NSS_2x2; - case 2: - return WifiRateNss::NSS_3x3; - case 3: - return WifiRateNss::NSS_4x4; - }; - CHECK(false) << "Unknown legacy nss: " << nss; - return {}; -} - -RttStatus convertLegacyRttStatusToHidl(legacy_hal::wifi_rtt_status status) { - switch (status) { - case legacy_hal::RTT_STATUS_SUCCESS: - return RttStatus::SUCCESS; - case legacy_hal::RTT_STATUS_FAILURE: - return RttStatus::FAILURE; - case legacy_hal::RTT_STATUS_FAIL_NO_RSP: - return RttStatus::FAIL_NO_RSP; - case legacy_hal::RTT_STATUS_FAIL_REJECTED: - return RttStatus::FAIL_REJECTED; - case legacy_hal::RTT_STATUS_FAIL_NOT_SCHEDULED_YET: - return RttStatus::FAIL_NOT_SCHEDULED_YET; - case legacy_hal::RTT_STATUS_FAIL_TM_TIMEOUT: - return RttStatus::FAIL_TM_TIMEOUT; - case legacy_hal::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL: - return RttStatus::FAIL_AP_ON_DIFF_CHANNEL; - case legacy_hal::RTT_STATUS_FAIL_NO_CAPABILITY: - return RttStatus::FAIL_NO_CAPABILITY; - case legacy_hal::RTT_STATUS_ABORTED: - return RttStatus::ABORTED; - case legacy_hal::RTT_STATUS_FAIL_INVALID_TS: - return RttStatus::FAIL_INVALID_TS; - case legacy_hal::RTT_STATUS_FAIL_PROTOCOL: - return RttStatus::FAIL_PROTOCOL; - case legacy_hal::RTT_STATUS_FAIL_SCHEDULE: - return RttStatus::FAIL_SCHEDULE; - case legacy_hal::RTT_STATUS_FAIL_BUSY_TRY_LATER: - return RttStatus::FAIL_BUSY_TRY_LATER; - case legacy_hal::RTT_STATUS_INVALID_REQ: - return RttStatus::INVALID_REQ; - case legacy_hal::RTT_STATUS_NO_WIFI: - return RttStatus::NO_WIFI; - case legacy_hal::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE: - return RttStatus::FAIL_FTM_PARAM_OVERRIDE; - case legacy_hal::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE: - return RttStatus::FAILURE; // TODO: add HIDL enumeration - case legacy_hal::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED: - return RttStatus::FAILURE; // TODO: add HIDL enumeration - }; - CHECK(false) << "Unknown legacy status: " << status; -} - -bool convertHidlWifiChannelInfoToLegacy( - const WifiChannelInfo& hidl_info, - legacy_hal::wifi_channel_info* legacy_info) { - if (!legacy_info) { - return false; - } - *legacy_info = {}; - legacy_info->width = convertHidlWifiChannelWidthToLegacy(hidl_info.width); - legacy_info->center_freq = hidl_info.centerFreq; - legacy_info->center_freq0 = hidl_info.centerFreq0; - legacy_info->center_freq1 = hidl_info.centerFreq1; - return true; -} - -bool convertLegacyWifiChannelInfoToHidl( - const legacy_hal::wifi_channel_info& legacy_info, - WifiChannelInfo* hidl_info) { - if (!hidl_info) { - return false; - } - *hidl_info = {}; - hidl_info->width = convertLegacyWifiChannelWidthToHidl(legacy_info.width); - hidl_info->centerFreq = legacy_info.center_freq; - hidl_info->centerFreq0 = legacy_info.center_freq0; - hidl_info->centerFreq1 = legacy_info.center_freq1; - return true; -} - -bool convertHidlRttConfigToLegacy(const V1_4::RttConfig& hidl_config, - legacy_hal::wifi_rtt_config* legacy_config) { - if (!legacy_config) { - return false; - } - *legacy_config = {}; - CHECK(hidl_config.addr.size() == sizeof(legacy_config->addr)); - memcpy(legacy_config->addr, hidl_config.addr.data(), - hidl_config.addr.size()); - legacy_config->type = convertHidlRttTypeToLegacy(hidl_config.type); - legacy_config->peer = convertHidlRttPeerTypeToLegacy(hidl_config.peer); - if (!convertHidlWifiChannelInfoToLegacy(hidl_config.channel, - &legacy_config->channel)) { - return false; - } - legacy_config->burst_period = hidl_config.burstPeriod; - legacy_config->num_burst = hidl_config.numBurst; - legacy_config->num_frames_per_burst = hidl_config.numFramesPerBurst; - legacy_config->num_retries_per_rtt_frame = - hidl_config.numRetriesPerRttFrame; - legacy_config->num_retries_per_ftmr = hidl_config.numRetriesPerFtmr; - legacy_config->LCI_request = hidl_config.mustRequestLci; - legacy_config->LCR_request = hidl_config.mustRequestLcr; - legacy_config->burst_duration = hidl_config.burstDuration; - legacy_config->preamble = - convertHidlRttPreambleToLegacy(hidl_config.preamble); - legacy_config->bw = convertHidlRttBwToLegacy(hidl_config.bw); - return true; -} - -bool convertHidlVectorOfRttConfigToLegacy( - const std::vector& hidl_configs, - std::vector* legacy_configs) { - if (!legacy_configs) { - return false; - } - *legacy_configs = {}; - for (const auto& hidl_config : hidl_configs) { - legacy_hal::wifi_rtt_config legacy_config; - if (!convertHidlRttConfigToLegacy(hidl_config, &legacy_config)) { - return false; - } - legacy_configs->push_back(legacy_config); - } - return true; -} - -bool convertHidlRttLciInformationToLegacy( - const RttLciInformation& hidl_info, - legacy_hal::wifi_lci_information* legacy_info) { - if (!legacy_info) { - return false; - } - *legacy_info = {}; - legacy_info->latitude = hidl_info.latitude; - legacy_info->longitude = hidl_info.longitude; - legacy_info->altitude = hidl_info.altitude; - legacy_info->latitude_unc = hidl_info.latitudeUnc; - legacy_info->longitude_unc = hidl_info.longitudeUnc; - legacy_info->altitude_unc = hidl_info.altitudeUnc; - legacy_info->motion_pattern = - convertHidlRttMotionPatternToLegacy(hidl_info.motionPattern); - legacy_info->floor = hidl_info.floor; - legacy_info->height_above_floor = hidl_info.heightAboveFloor; - legacy_info->height_unc = hidl_info.heightUnc; - return true; -} - -bool convertHidlRttLcrInformationToLegacy( - const RttLcrInformation& hidl_info, - legacy_hal::wifi_lcr_information* legacy_info) { - if (!legacy_info) { - return false; - } - *legacy_info = {}; - CHECK(hidl_info.countryCode.size() == sizeof(legacy_info->country_code)); - memcpy(legacy_info->country_code, hidl_info.countryCode.data(), - hidl_info.countryCode.size()); - if (hidl_info.civicInfo.size() > sizeof(legacy_info->civic_info)) { - return false; - } - legacy_info->length = hidl_info.civicInfo.size(); - memcpy(legacy_info->civic_info, hidl_info.civicInfo.c_str(), - hidl_info.civicInfo.size()); - return true; -} - -bool convertHidlRttResponderToLegacy( - const V1_4::RttResponder& hidl_responder, - legacy_hal::wifi_rtt_responder* legacy_responder) { - if (!legacy_responder) { - return false; - } - *legacy_responder = {}; - if (!convertHidlWifiChannelInfoToLegacy(hidl_responder.channel, - &legacy_responder->channel)) { - return false; - } - legacy_responder->preamble = - convertHidlRttPreambleToLegacy(hidl_responder.preamble); - return true; -} - -bool convertLegacyRttResponderToHidl( - const legacy_hal::wifi_rtt_responder& legacy_responder, - V1_4::RttResponder* hidl_responder) { - if (!hidl_responder) { - return false; - } - *hidl_responder = {}; - if (!convertLegacyWifiChannelInfoToHidl(legacy_responder.channel, - &hidl_responder->channel)) { - return false; - } - hidl_responder->preamble = - convertLegacyRttPreambleToHidl(legacy_responder.preamble); - return true; -} - -bool convertLegacyRttCapabilitiesToHidl( - const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, - V1_4::RttCapabilities* hidl_capabilities) { - if (!hidl_capabilities) { - return false; - } - *hidl_capabilities = {}; - hidl_capabilities->rttOneSidedSupported = - legacy_capabilities.rtt_one_sided_supported; - hidl_capabilities->rttFtmSupported = legacy_capabilities.rtt_ftm_supported; - hidl_capabilities->lciSupported = legacy_capabilities.lci_support; - hidl_capabilities->lcrSupported = legacy_capabilities.lcr_support; - hidl_capabilities->responderSupported = - legacy_capabilities.responder_supported; - hidl_capabilities->preambleSupport = 0; - for (const auto flag : - {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, - legacy_hal::WIFI_RTT_PREAMBLE_HT, legacy_hal::WIFI_RTT_PREAMBLE_VHT, - legacy_hal::WIFI_RTT_PREAMBLE_HE}) { - if (legacy_capabilities.preamble_support & flag) { - hidl_capabilities->preambleSupport |= - static_cast::type>( - convertLegacyRttPreambleToHidl(flag)); - } - } - hidl_capabilities->bwSupport = 0; - for (const auto flag : - {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, - legacy_hal::WIFI_RTT_BW_20, legacy_hal::WIFI_RTT_BW_40, - legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160}) { - if (legacy_capabilities.bw_support & flag) { - hidl_capabilities->bwSupport |= - static_cast::type>( - convertLegacyRttBwToHidl(flag)); - } - } - hidl_capabilities->mcVersion = legacy_capabilities.mc_version; - return true; -} - -bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate, - V1_4::WifiRateInfo* hidl_rate) { - if (!hidl_rate) { - return false; - } - *hidl_rate = {}; - hidl_rate->preamble = - convertLegacyWifiRatePreambleToHidl(legacy_rate.preamble); - hidl_rate->nss = convertLegacyWifiRateNssToHidl(legacy_rate.nss); - hidl_rate->bw = convertLegacyWifiChannelWidthToHidl( - static_cast(legacy_rate.bw)); - hidl_rate->rateMcsIdx = legacy_rate.rateMcsIdx; - hidl_rate->bitRateInKbps = legacy_rate.bitrate; - return true; -} - -bool convertLegacyRttResultToHidl( - const legacy_hal::wifi_rtt_result& legacy_result, - V1_4::RttResult* hidl_result) { - if (!hidl_result) { - return false; - } - *hidl_result = {}; - CHECK(sizeof(legacy_result.addr) == hidl_result->addr.size()); - memcpy(hidl_result->addr.data(), legacy_result.addr, - sizeof(legacy_result.addr)); - hidl_result->burstNum = legacy_result.burst_num; - hidl_result->measurementNumber = legacy_result.measurement_number; - hidl_result->successNumber = legacy_result.success_number; - hidl_result->numberPerBurstPeer = legacy_result.number_per_burst_peer; - hidl_result->status = convertLegacyRttStatusToHidl(legacy_result.status); - hidl_result->retryAfterDuration = legacy_result.retry_after_duration; - hidl_result->type = convertLegacyRttTypeToHidl(legacy_result.type); - hidl_result->rssi = legacy_result.rssi; - hidl_result->rssiSpread = legacy_result.rssi_spread; - if (!convertLegacyWifiRateInfoToHidl(legacy_result.tx_rate, - &hidl_result->txRate)) { - return false; - } - if (!convertLegacyWifiRateInfoToHidl(legacy_result.rx_rate, - &hidl_result->rxRate)) { - return false; - } - hidl_result->rtt = legacy_result.rtt; - hidl_result->rttSd = legacy_result.rtt_sd; - hidl_result->rttSpread = legacy_result.rtt_spread; - hidl_result->distanceInMm = legacy_result.distance_mm; - hidl_result->distanceSdInMm = legacy_result.distance_sd_mm; - hidl_result->distanceSpreadInMm = legacy_result.distance_spread_mm; - hidl_result->timeStampInUs = legacy_result.ts; - hidl_result->burstDurationInMs = legacy_result.burst_duration; - hidl_result->negotiatedBurstNum = legacy_result.negotiated_burst_num; - if (legacy_result.LCI && - !convertLegacyIeToHidl(*legacy_result.LCI, &hidl_result->lci)) { - return false; - } - if (legacy_result.LCR && - !convertLegacyIeToHidl(*legacy_result.LCR, &hidl_result->lcr)) { - return false; - } - return true; -} - -bool convertLegacyVectorOfRttResultToHidl( - const std::vector& legacy_results, - std::vector* hidl_results) { - if (!hidl_results) { - return false; - } - *hidl_results = {}; - for (const auto legacy_result : legacy_results) { - V1_4::RttResult hidl_result; - if (!convertLegacyRttResultToHidl(*legacy_result, &hidl_result)) { - return false; - } - hidl_results->push_back(hidl_result); - } - return true; -} - -legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy( - IfaceType hidl_interface_type) { - switch (hidl_interface_type) { - case IfaceType::STA: - return legacy_hal::WIFI_INTERFACE_TYPE_STA; - case IfaceType::AP: - return legacy_hal::WIFI_INTERFACE_TYPE_AP; - case IfaceType::P2P: - return legacy_hal::WIFI_INTERFACE_TYPE_P2P; - case IfaceType::NAN: - return legacy_hal::WIFI_INTERFACE_TYPE_NAN; - } - CHECK(false); -} - -legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy( - IWifiChip::MultiStaUseCase use_case) { - switch (use_case) { - case IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY: - return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY; - case IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED: - return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED; - } - CHECK(false); -} - -bool convertHidlCoexUnsafeChannelToLegacy( - const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel, - legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) { - if (!legacy_unsafe_channel) { - return false; - } - *legacy_unsafe_channel = {}; - switch (hidl_unsafe_channel.band) { - case WifiBand::BAND_24GHZ: - legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND; - break; - case WifiBand::BAND_5GHZ: - legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND; - break; - default: - return false; - }; - legacy_unsafe_channel->channel = hidl_unsafe_channel.channel; - legacy_unsafe_channel->power_cap_dbm = hidl_unsafe_channel.powerCapDbm; - return true; -} - -bool convertHidlVectorOfCoexUnsafeChannelToLegacy( - const std::vector& hidl_unsafe_channels, - std::vector* legacy_unsafe_channels) { - if (!legacy_unsafe_channels) { - return false; - } - *legacy_unsafe_channels = {}; - for (const auto& hidl_unsafe_channel : hidl_unsafe_channels) { - legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel; - if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy( - hidl_unsafe_channel, &legacy_unsafe_channel)) { - return false; - } - legacy_unsafe_channels->push_back(legacy_unsafe_channel); - } - return true; -} - -} // namespace hidl_struct_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h deleted file mode 100644 index 352f213664..0000000000 --- a/wifi/1.5/default/hidl_struct_util.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 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. - */ - -#ifndef HIDL_STRUCT_UTIL_H_ -#define HIDL_STRUCT_UTIL_H_ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wifi_legacy_hal.h" - -/** - * This file contains a bunch of functions to convert structs from the legacy - * HAL to HIDL and vice versa. - * TODO(b/32093047): Add unit tests for these conversion methods in the VTS test - * suite. - */ -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace hidl_struct_util { -using namespace android::hardware::wifi::V1_0; - -// Chip conversion methods. -bool convertLegacyFeaturesToHidlChipCapabilities( - uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set, - uint32_t* hidl_caps); -bool convertLegacyDebugRingBufferStatusToHidl( - const legacy_hal::wifi_ring_buffer_status& legacy_status, - WifiDebugRingBufferStatus* hidl_status); -bool convertLegacyVectorOfDebugRingBufferStatusToHidl( - const std::vector& legacy_status_vec, - std::vector* hidl_status_vec); -bool convertLegacyWakeReasonStatsToHidl( - const legacy_hal::WakeReasonStats& legacy_stats, - WifiDebugHostWakeReasonStats* hidl_stats); -legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( - V1_1::IWifiChip::TxPowerScenario hidl_scenario); -legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( - V1_3::IWifiChip::LatencyMode hidl_latency_mode); -legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( - V1_2::IWifiChip::TxPowerScenario hidl_scenario); -bool convertLegacyWifiMacInfosToHidl( - const std::vector& legacy_mac_infos, - std::vector* - hidl_radio_mode_infos); -legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy( - IfaceType hidl_interface_type); -legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy( - IWifiChip::MultiStaUseCase use_case); -bool convertHidlCoexUnsafeChannelToLegacy( - const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel, - legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel); -bool convertHidlVectorOfCoexUnsafeChannelToLegacy( - const std::vector& hidl_unsafe_channels, - std::vector* legacy_unsafe_channels); - -// STA iface conversion methods. -bool convertLegacyFeaturesToHidlStaCapabilities( - uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set, - uint32_t* hidl_caps); -bool convertLegacyApfCapabilitiesToHidl( - const legacy_hal::PacketFilterCapabilities& legacy_caps, - StaApfPacketFilterCapabilities* hidl_caps); -bool convertLegacyGscanCapabilitiesToHidl( - const legacy_hal::wifi_gscan_capabilities& legacy_caps, - StaBackgroundScanCapabilities* hidl_caps); -legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band); -bool convertHidlGscanParamsToLegacy( - const StaBackgroundScanParameters& hidl_scan_params, - legacy_hal::wifi_scan_cmd_params* legacy_scan_params); -// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11 -// Information Elements (IEs) -bool convertLegacyGscanResultToHidl( - const legacy_hal::wifi_scan_result& legacy_scan_result, bool has_ie_data, - StaScanResult* hidl_scan_result); -// |cached_results| is assumed to not include IEs. -bool convertLegacyVectorOfCachedGscanResultsToHidl( - const std::vector& - legacy_cached_scan_results, - std::vector* hidl_scan_datas); -bool convertLegacyLinkLayerStatsToHidl( - const legacy_hal::LinkLayerStats& legacy_stats, - StaLinkLayerStats* hidl_stats); -bool convertLegacyRoamingCapabilitiesToHidl( - const legacy_hal::wifi_roaming_capabilities& legacy_caps, - StaRoamingCapabilities* hidl_caps); -bool convertHidlRoamingConfigToLegacy( - const StaRoamingConfig& hidl_config, - legacy_hal::wifi_roaming_config* legacy_config); -legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy( - StaRoamingState state); -bool convertLegacyVectorOfDebugTxPacketFateToHidl( - const std::vector& legacy_fates, - std::vector* hidl_fates); -bool convertLegacyVectorOfDebugRxPacketFateToHidl( - const std::vector& legacy_fates, - std::vector* hidl_fates); - -// NAN iface conversion methods. -void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, - size_t max_len, WifiNanStatus* wifiNanStatus); -bool convertHidlNanEnableRequestToLegacy( - const V1_4::NanEnableRequest& hidl_request, - legacy_hal::NanEnableRequest* legacy_request); -bool convertHidlNanConfigRequestToLegacy( - const V1_4::NanConfigRequest& hidl_request, - legacy_hal::NanConfigRequest* legacy_request); -bool convertHidlNanEnableRequest_1_4ToLegacy( - const V1_4::NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanEnableRequest* legacy_request); -bool convertHidlNanConfigRequest_1_4ToLegacy( - const V1_4::NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanConfigRequest* legacy_request); -bool convertHidlNanEnableRequest_1_5ToLegacy( - const V1_4::NanEnableRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanEnableRequest* legacy_request); -bool convertHidlNanConfigRequest_1_5ToLegacy( - const V1_4::NanConfigRequest& hidl_request1, - const NanConfigRequestSupplemental& hidl_request2, - legacy_hal::NanConfigRequest* legacy_request); -bool convertHidlNanPublishRequestToLegacy( - const NanPublishRequest& hidl_request, - legacy_hal::NanPublishRequest* legacy_request); -bool convertHidlNanSubscribeRequestToLegacy( - const NanSubscribeRequest& hidl_request, - legacy_hal::NanSubscribeRequest* legacy_request); -bool convertHidlNanTransmitFollowupRequestToLegacy( - const NanTransmitFollowupRequest& hidl_request, - legacy_hal::NanTransmitFollowupRequest* legacy_request); -bool convertHidlNanDataPathInitiatorRequestToLegacy( - const NanInitiateDataPathRequest& hidl_request, - legacy_hal::NanDataPathInitiatorRequest* legacy_request); -bool convertHidlNanDataPathIndicationResponseToLegacy( - const NanRespondToDataPathIndicationRequest& hidl_response, - legacy_hal::NanDataPathIndicationResponse* legacy_response); -bool convertLegacyNanResponseHeaderToHidl( - const legacy_hal::NanResponseMsg& legacy_response, - WifiNanStatus* wifiNanStatus); -bool convertLegacyNanCapabilitiesResponseToHidl( - const legacy_hal::NanCapabilities& legacy_response, - NanCapabilities* hidl_response); -bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind, - NanMatchInd* hidl_ind); -bool convertLegacyNanFollowupIndToHidl( - const legacy_hal::NanFollowupInd& legacy_ind, - NanFollowupReceivedInd* hidl_ind); -bool convertLegacyNanDataPathRequestIndToHidl( - const legacy_hal::NanDataPathRequestInd& legacy_ind, - NanDataPathRequestInd* hidl_ind); -bool convertLegacyNanDataPathConfirmIndToHidl( - const legacy_hal::NanDataPathConfirmInd& legacy_ind, - V1_2::NanDataPathConfirmInd* hidl_ind); -bool convertLegacyNanDataPathScheduleUpdateIndToHidl( - const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, - V1_2::NanDataPathScheduleUpdateInd* hidl_ind); - -// RTT controller conversion methods. -bool convertHidlVectorOfRttConfigToLegacy( - const std::vector& hidl_configs, - std::vector* legacy_configs); -bool convertHidlRttLciInformationToLegacy( - const RttLciInformation& hidl_info, - legacy_hal::wifi_lci_information* legacy_info); -bool convertHidlRttLcrInformationToLegacy( - const RttLcrInformation& hidl_info, - legacy_hal::wifi_lcr_information* legacy_info); -bool convertHidlRttResponderToLegacy( - const V1_4::RttResponder& hidl_responder, - legacy_hal::wifi_rtt_responder* legacy_responder); -bool convertHidlWifiChannelInfoToLegacy( - const WifiChannelInfo& hidl_info, - legacy_hal::wifi_channel_info* legacy_info); -bool convertLegacyRttResponderToHidl( - const legacy_hal::wifi_rtt_responder& legacy_responder, - V1_4::RttResponder* hidl_responder); -bool convertLegacyRttCapabilitiesToHidl( - const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, - V1_4::RttCapabilities* hidl_capabilities); -bool convertLegacyVectorOfRttResultToHidl( - const std::vector& legacy_results, - std::vector* hidl_results); -uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band); -uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask); -uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask); -bool convertLegacyWifiUsableChannelsToHidl( - const std::vector& legacy_usable_channels, - std::vector* hidl_usable_channels); -bool convertLegacyPeerInfoStatsToHidl( - const legacy_hal::WifiPeerInfo& legacy_peer_info_stats, - StaPeerInfo* hidl_peer_info_stats); -bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate, - V1_4::WifiRateInfo* hidl_rate); -} // namespace hidl_struct_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // HIDL_STRUCT_UTIL_H_ diff --git a/wifi/1.5/default/hidl_sync_util.cpp b/wifi/1.5/default/hidl_sync_util.cpp deleted file mode 100644 index 93eefe9560..0000000000 --- a/wifi/1.5/default/hidl_sync_util.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#include "hidl_sync_util.h" - -namespace { -std::recursive_mutex g_mutex; -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace hidl_sync_util { - -std::unique_lock acquireGlobalLock() { - return std::unique_lock{g_mutex}; -} - -} // namespace hidl_sync_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/hidl_sync_util.h b/wifi/1.5/default/hidl_sync_util.h deleted file mode 100644 index e706f4cd87..0000000000 --- a/wifi/1.5/default/hidl_sync_util.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - */ - -#ifndef HIDL_SYNC_UTIL_H_ -#define HIDL_SYNC_UTIL_H_ - -#include - -// Utility that provides a global lock to synchronize access between -// the HIDL thread and the legacy HAL's event loop. -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace hidl_sync_util { -std::unique_lock acquireGlobalLock(); -} // namespace hidl_sync_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android -#endif // HIDL_SYNC_UTIL_H_ diff --git a/wifi/1.5/default/ringbuffer.cpp b/wifi/1.5/default/ringbuffer.cpp deleted file mode 100644 index f554111e61..0000000000 --- a/wifi/1.5/default/ringbuffer.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ - -#include - -#include "ringbuffer.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { - -Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {} - -void Ringbuffer::append(const std::vector& input) { - if (input.size() == 0) { - return; - } - if (input.size() > maxSize_) { - LOG(INFO) << "Oversized message of " << input.size() - << " bytes is dropped"; - return; - } - data_.push_back(input); - size_ += input.size() * sizeof(input[0]); - while (size_ > maxSize_) { - size_ -= data_.front().size() * sizeof(data_.front()[0]); - data_.pop_front(); - } -} - -const std::list>& Ringbuffer::getData() const { - return data_; -} - -void Ringbuffer::clear() { - data_.clear(); - size_ = 0; -} - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/ringbuffer.h b/wifi/1.5/default/ringbuffer.h deleted file mode 100644 index 03fb37a6a2..0000000000 --- a/wifi/1.5/default/ringbuffer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 RINGBUFFER_H_ -#define RINGBUFFER_H_ - -#include -#include - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { - -/** - * Ringbuffer object used to store debug data. - */ -class Ringbuffer { - public: - explicit Ringbuffer(size_t maxSize); - - // Appends the data buffer and deletes from the front until buffer is - // within |maxSize_|. - void append(const std::vector& input); - const std::list>& getData() const; - void clear(); - - private: - std::list> data_; - size_t size_; - size_t maxSize_; -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // RINGBUFFER_H_ diff --git a/wifi/1.5/default/service.cpp b/wifi/1.5/default/service.cpp deleted file mode 100644 index 3de49b29bb..0000000000 --- a/wifi/1.5/default/service.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include "wifi.h" -#include "wifi_feature_flags.h" -#include "wifi_legacy_hal.h" -#include "wifi_legacy_hal_factory.h" -#include "wifi_mode_controller.h" - -using android::hardware::configureRpcThreadpool; -using android::hardware::joinRpcThreadpool; -using android::hardware::LazyServiceRegistrar; -using android::hardware::wifi::V1_5::implementation::feature_flags:: - WifiFeatureFlags; -using android::hardware::wifi::V1_5::implementation::legacy_hal::WifiLegacyHal; -using android::hardware::wifi::V1_5::implementation::legacy_hal:: - WifiLegacyHalFactory; -using android::hardware::wifi::V1_5::implementation::mode_controller:: - WifiModeController; - -#ifdef LAZY_SERVICE -const bool kLazyService = true; -#else -const bool kLazyService = false; -#endif - -int main(int /*argc*/, char** argv) { - signal(SIGPIPE, SIG_IGN); - android::base::InitLogging( - argv, android::base::LogdLogger(android::base::SYSTEM)); - LOG(INFO) << "Wifi Hal is booting up..."; - - configureRpcThreadpool(1, true /* callerWillJoin */); - - const auto iface_tool = - std::make_shared(); - const auto legacy_hal_factory = - std::make_shared(iface_tool); - - // Setup hwbinder service - android::sp service = - new android::hardware::wifi::V1_5::implementation::Wifi( - iface_tool, legacy_hal_factory, - std::make_shared(), - std::make_shared()); - if (kLazyService) { - auto registrar = LazyServiceRegistrar::getInstance(); - CHECK_EQ(registrar.registerService(service), android::NO_ERROR) - << "Failed to register wifi HAL"; - } else { - CHECK_EQ(service->registerAsService(), android::NO_ERROR) - << "Failed to register wifi HAL"; - } - - joinRpcThreadpool(); - - LOG(INFO) << "Wifi Hal is terminating..."; - return 0; -} diff --git a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp deleted file mode 100644 index 4b4ebd6138..0000000000 --- a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (C) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#undef NAN -#include "hidl_struct_util.h" - -using testing::Test; - -namespace { -constexpr uint32_t kMacId1 = 1; -constexpr uint32_t kMacId2 = 2; -constexpr uint32_t kIfaceChannel1 = 3; -constexpr uint32_t kIfaceChannel2 = 5; -constexpr char kIfaceName1[] = "wlan0"; -constexpr char kIfaceName2[] = "wlan1"; -} // namespace -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; -using ::android::hardware::wifi::V1_0::WifiChannelWidthInMhz; - -class HidlStructUtilTest : public Test {}; - -TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) { - std::vector legacy_mac_infos; - legacy_hal::WifiMacInfo legacy_mac_info1 = { - .wlan_mac_id = kMacId1, - .mac_band = - legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND}; - legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, - .channel = kIfaceChannel1}; - legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, - .channel = kIfaceChannel2}; - legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); - legacy_mac_info1.iface_infos.push_back(legacy_iface_info2); - legacy_mac_infos.push_back(legacy_mac_info1); - - std::vector - hidl_radio_mode_infos; - ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl( - legacy_mac_infos, &hidl_radio_mode_infos)); - - ASSERT_EQ(1u, hidl_radio_mode_infos.size()); - auto hidl_radio_mode_info1 = hidl_radio_mode_infos[0]; - EXPECT_EQ(legacy_mac_info1.wlan_mac_id, hidl_radio_mode_info1.radioId); - EXPECT_EQ(V1_4::WifiBand::BAND_24GHZ_5GHZ, hidl_radio_mode_info1.bandInfo); - ASSERT_EQ(2u, hidl_radio_mode_info1.ifaceInfos.size()); - auto hidl_iface_info1 = hidl_radio_mode_info1.ifaceInfos[0]; - EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); - EXPECT_EQ(static_cast(legacy_iface_info1.channel), - hidl_iface_info1.channel); - auto hidl_iface_info2 = hidl_radio_mode_info1.ifaceInfos[1]; - EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); - EXPECT_EQ(static_cast(legacy_iface_info2.channel), - hidl_iface_info2.channel); -} - -TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) { - std::vector legacy_mac_infos; - legacy_hal::WifiMacInfo legacy_mac_info1 = { - .wlan_mac_id = kMacId1, .mac_band = legacy_hal::WLAN_MAC_5_0_BAND}; - legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, - .channel = kIfaceChannel1}; - legacy_hal::WifiMacInfo legacy_mac_info2 = { - .wlan_mac_id = kMacId2, .mac_band = legacy_hal::WLAN_MAC_2_4_BAND}; - legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, - .channel = kIfaceChannel2}; - legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); - legacy_mac_infos.push_back(legacy_mac_info1); - legacy_mac_info2.iface_infos.push_back(legacy_iface_info2); - legacy_mac_infos.push_back(legacy_mac_info2); - - std::vector - hidl_radio_mode_infos; - ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl( - legacy_mac_infos, &hidl_radio_mode_infos)); - - ASSERT_EQ(2u, hidl_radio_mode_infos.size()); - - // Find mac info 1. - const auto hidl_radio_mode_info1 = - std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), - [&legacy_mac_info1]( - const V1_4::IWifiChipEventCallback::RadioModeInfo& x) { - return x.radioId == legacy_mac_info1.wlan_mac_id; - }); - ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1); - EXPECT_EQ(V1_4::WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo); - ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size()); - auto hidl_iface_info1 = hidl_radio_mode_info1->ifaceInfos[0]; - EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); - EXPECT_EQ(static_cast(legacy_iface_info1.channel), - hidl_iface_info1.channel); - - // Find mac info 2. - const auto hidl_radio_mode_info2 = - std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), - [&legacy_mac_info2]( - const V1_4::IWifiChipEventCallback::RadioModeInfo& x) { - return x.radioId == legacy_mac_info2.wlan_mac_id; - }); - ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2); - EXPECT_EQ(V1_4::WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo); - ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size()); - auto hidl_iface_info2 = hidl_radio_mode_info2->ifaceInfos[0]; - EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); - EXPECT_EQ(static_cast(legacy_iface_info2.channel), - hidl_iface_info2.channel); -} - -TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { - legacy_hal::LinkLayerStats legacy_stats{}; - legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); - legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); - legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{}); - legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{}); - legacy_stats.iface.beacon_rx = rand(); - legacy_stats.iface.rssi_mgmt = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = - rand(); - - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = - rand(); - - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = - rand(); - - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand(); - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = - rand(); - - legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand(); - legacy_stats.iface.num_peers = 1; - - for (auto& radio : legacy_stats.radios) { - radio.stats.radio = rand(); - radio.stats.on_time = rand(); - radio.stats.tx_time = rand(); - radio.stats.rx_time = rand(); - radio.stats.on_time_scan = rand(); - radio.stats.on_time_nbd = rand(); - radio.stats.on_time_gscan = rand(); - radio.stats.on_time_roam_scan = rand(); - radio.stats.on_time_pno_scan = rand(); - radio.stats.on_time_hs20 = rand(); - for (int i = 0; i < 4; i++) { - radio.tx_time_per_levels.push_back(rand()); - } - - legacy_hal::wifi_channel_stat channel_stat1 = { - .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0}, - .on_time = 0x1111, - .cca_busy_time = 0x55, - }; - legacy_hal::wifi_channel_stat channel_stat2 = { - .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0}, - .on_time = 0x2222, - .cca_busy_time = 0x66, - }; - radio.channel_stats.push_back(channel_stat1); - radio.channel_stats.push_back(channel_stat2); - } - - for (auto& peer : legacy_stats.peers) { - peer.peer_info.bssload.sta_count = rand(); - peer.peer_info.bssload.chan_util = rand(); - wifi_rate_stat rate_stat1 = { - .rate = {3, 1, 2, 5, 0, 0}, - .tx_mpdu = 0, - .rx_mpdu = 1, - .mpdu_lost = 2, - .retries = 3, - .retries_short = 4, - .retries_long = 5, - }; - wifi_rate_stat rate_stat2 = { - .rate = {2, 2, 1, 6, 0, 1}, - .tx_mpdu = 6, - .rx_mpdu = 7, - .mpdu_lost = 8, - .retries = 9, - .retries_short = 10, - .retries_long = 11, - }; - peer.rate_stats.push_back(rate_stat1); - peer.rate_stats.push_back(rate_stat2); - } - - V1_5::StaLinkLayerStats converted{}; - hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, - &converted); - EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.V1_0.beaconRx); - EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.V1_0.avgRssiMgmt); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu, - converted.iface.V1_0.wmeBePktStats.rxMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu, - converted.iface.V1_0.wmeBePktStats.txMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost, - converted.iface.V1_0.wmeBePktStats.lostMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries, - converted.iface.V1_0.wmeBePktStats.retries); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min, - converted.iface.wmeBeContentionTimeStats.contentionTimeMinInUsec); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max, - converted.iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg, - converted.iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec); - EXPECT_EQ( - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples, - converted.iface.wmeBeContentionTimeStats.contentionNumSamples); - - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu, - converted.iface.V1_0.wmeBkPktStats.rxMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu, - converted.iface.V1_0.wmeBkPktStats.txMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost, - converted.iface.V1_0.wmeBkPktStats.lostMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries, - converted.iface.V1_0.wmeBkPktStats.retries); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min, - converted.iface.wmeBkContentionTimeStats.contentionTimeMinInUsec); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max, - converted.iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg, - converted.iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec); - EXPECT_EQ( - legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples, - converted.iface.wmeBkContentionTimeStats.contentionNumSamples); - - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu, - converted.iface.V1_0.wmeViPktStats.rxMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu, - converted.iface.V1_0.wmeViPktStats.txMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost, - converted.iface.V1_0.wmeViPktStats.lostMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries, - converted.iface.V1_0.wmeViPktStats.retries); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min, - converted.iface.wmeViContentionTimeStats.contentionTimeMinInUsec); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max, - converted.iface.wmeViContentionTimeStats.contentionTimeMaxInUsec); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg, - converted.iface.wmeViContentionTimeStats.contentionTimeAvgInUsec); - EXPECT_EQ( - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples, - converted.iface.wmeViContentionTimeStats.contentionNumSamples); - - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu, - converted.iface.V1_0.wmeVoPktStats.rxMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu, - converted.iface.V1_0.wmeVoPktStats.txMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost, - converted.iface.V1_0.wmeVoPktStats.lostMpdu); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries, - converted.iface.V1_0.wmeVoPktStats.retries); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min, - converted.iface.wmeVoContentionTimeStats.contentionTimeMinInUsec); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max, - converted.iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec); - EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg, - converted.iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec); - EXPECT_EQ( - legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples, - converted.iface.wmeVoContentionTimeStats.contentionNumSamples); - - EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent, - converted.iface.timeSliceDutyCycleInPercent); - - EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size()); - for (size_t i = 0; i < legacy_stats.radios.size(); i++) { - EXPECT_EQ(legacy_stats.radios[i].stats.radio, - converted.radios[i].radioId); - EXPECT_EQ(legacy_stats.radios[i].stats.on_time, - converted.radios[i].V1_3.V1_0.onTimeInMs); - EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, - converted.radios[i].V1_3.V1_0.txTimeInMs); - EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, - converted.radios[i].V1_3.V1_0.rxTimeInMs); - EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan, - converted.radios[i].V1_3.V1_0.onTimeInMsForScan); - EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(), - converted.radios[i].V1_3.V1_0.txTimeInMsPerLevel.size()); - for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); - j++) { - EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j], - converted.radios[i].V1_3.V1_0.txTimeInMsPerLevel[j]); - } - EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd, - converted.radios[i].V1_3.onTimeInMsForNanScan); - EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan, - converted.radios[i].V1_3.onTimeInMsForBgScan); - EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan, - converted.radios[i].V1_3.onTimeInMsForRoamScan); - EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan, - converted.radios[i].V1_3.onTimeInMsForPnoScan); - EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20, - converted.radios[i].V1_3.onTimeInMsForHs20Scan); - EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(), - converted.radios[i].V1_3.channelStats.size()); - for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); - k++) { - auto& legacy_channel_st = legacy_stats.radios[i].channel_stats[k]; - EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20, - converted.radios[i].V1_3.channelStats[k].channel.width); - EXPECT_EQ( - WifiChannelInMhz(legacy_channel_st.channel.center_freq), - converted.radios[i].V1_3.channelStats[k].channel.centerFreq); - EXPECT_EQ( - WifiChannelInMhz(legacy_channel_st.channel.center_freq0), - converted.radios[i].V1_3.channelStats[k].channel.centerFreq0); - EXPECT_EQ( - WifiChannelInMhz(legacy_channel_st.channel.center_freq1), - converted.radios[i].V1_3.channelStats[k].channel.centerFreq1); - EXPECT_EQ(legacy_channel_st.cca_busy_time, - converted.radios[i].V1_3.channelStats[k].ccaBusyTimeInMs); - EXPECT_EQ(legacy_channel_st.on_time, - converted.radios[i].V1_3.channelStats[k].onTimeInMs); - } - } - - EXPECT_EQ(legacy_stats.peers.size(), converted.iface.peers.size()); - for (size_t i = 0; i < legacy_stats.peers.size(); i++) { - EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.sta_count, - converted.iface.peers[i].staCount); - EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.chan_util, - converted.iface.peers[i].chanUtil); - for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) { - EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble, - (uint32_t)converted.iface.peers[i] - .rateStats[j] - .rateInfo.preamble); - EXPECT_EQ( - legacy_stats.peers[i].rate_stats[j].rate.nss, - (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss); - EXPECT_EQ( - legacy_stats.peers[i].rate_stats[j].rate.bw, - (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw); - EXPECT_EQ( - legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx, - converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx); - EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu, - converted.iface.peers[i].rateStats[j].txMpdu); - EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu, - converted.iface.peers[i].rateStats[j].rxMpdu); - EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].mpdu_lost, - converted.iface.peers[i].rateStats[j].mpduLost); - EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].retries, - converted.iface.peers[i].rateStats[j].retries); - } - } -} - -TEST_F(HidlStructUtilTest, CanConvertLegacyFeaturesToHidl) { - using HidlChipCaps = V1_3::IWifiChip::ChipCapabilityMask; - - uint32_t hidle_caps; - - uint32_t legacy_feature_set = - WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE; - uint32_t legacy_logger_feature_set = - legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; - - ASSERT_TRUE(hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities( - legacy_feature_set, legacy_logger_feature_set, &hidle_caps)); - - EXPECT_EQ(HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA | - HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS | - HidlChipCaps::DEBUG_ERROR_ALERTS | HidlChipCaps::D2D_RTT | - HidlChipCaps::SET_LATENCY_MODE | - HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP, - hidle_caps); -} -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/tests/main.cpp b/wifi/1.5/default/tests/main.cpp deleted file mode 100644 index 9aac837242..0000000000 --- a/wifi/1.5/default/tests/main.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - ::testing::InitGoogleMock(&argc, argv); - // Force ourselves to always log to stderr - android::base::InitLogging(argv, android::base::StderrLogger); - return RUN_ALL_TESTS(); -} diff --git a/wifi/1.5/default/tests/mock_interface_tool.cpp b/wifi/1.5/default/tests/mock_interface_tool.cpp deleted file mode 100644 index b99a16446c..0000000000 --- a/wifi/1.5/default/tests/mock_interface_tool.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 -#include -#include - -#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 -#include "mock_interface_tool.h" - -namespace android { -namespace wifi_system { - -MockInterfaceTool::MockInterfaceTool() {} - -} // namespace wifi_system -} // namespace android diff --git a/wifi/1.5/default/tests/mock_interface_tool.h b/wifi/1.5/default/tests/mock_interface_tool.h deleted file mode 100644 index 0f17551f96..0000000000 --- a/wifi/1.5/default/tests/mock_interface_tool.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 MOCK_INTERFACE_TOOL_H -#define MOCK_INTERFACE_TOOL_H - -#include -#include - -namespace android { -namespace wifi_system { - -class MockInterfaceTool : public InterfaceTool { - public: - MockInterfaceTool(); - - MOCK_METHOD1(GetUpState, bool(const char* if_name)); - MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up)); - MOCK_METHOD1(SetWifiUpState, bool(bool request_up)); - MOCK_METHOD2(SetMacAddress, - bool(const char* if_name, - const std::array& address)); - MOCK_METHOD1(GetFactoryMacAddress, - std::array(const char* if_name)); - -}; // class MockInterfaceTool - -} // namespace wifi_system -} // namespace android - -#endif // MOCK_INTERFACE_TOOL_H diff --git a/wifi/1.5/default/tests/mock_wifi_feature_flags.cpp b/wifi/1.5/default/tests/mock_wifi_feature_flags.cpp deleted file mode 100644 index 2f66ba121b..0000000000 --- a/wifi/1.5/default/tests/mock_wifi_feature_flags.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "mock_wifi_feature_flags.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace feature_flags { - -MockWifiFeatureFlags::MockWifiFeatureFlags() {} - -} // namespace feature_flags -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_feature_flags.h b/wifi/1.5/default/tests/mock_wifi_feature_flags.h deleted file mode 100644 index c3877edd60..0000000000 --- a/wifi/1.5/default/tests/mock_wifi_feature_flags.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MOCK_WIFI_FEATURE_FLAGS_H_ -#define MOCK_WIFI_FEATURE_FLAGS_H_ - -#include -#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 - -#include "wifi_feature_flags.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace feature_flags { - -class MockWifiFeatureFlags : public WifiFeatureFlags { - public: - MockWifiFeatureFlags(); - - MOCK_METHOD1(getChipModes, - std::vector(bool is_primary)); - MOCK_METHOD0(isApMacRandomizationDisabled, bool()); -}; - -} // namespace feature_flags -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // MOCK_WIFI_FEATURE_FLAGS_H_ diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp b/wifi/1.5/default/tests/mock_wifi_iface_util.cpp deleted file mode 100644 index b101c4ac34..0000000000 --- a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 -#include -#include - -#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 -#include "mock_wifi_iface_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace iface_util { - -MockWifiIfaceUtil::MockWifiIfaceUtil( - const std::weak_ptr iface_tool, - const std::weak_ptr legacy_hal) - : WifiIfaceUtil(iface_tool, legacy_hal) {} -} // namespace iface_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.h b/wifi/1.5/default/tests/mock_wifi_iface_util.h deleted file mode 100644 index 6d5f59ce53..0000000000 --- a/wifi/1.5/default/tests/mock_wifi_iface_util.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 MOCK_WIFI_IFACE_UTIL_H_ -#define MOCK_WIFI_IFACE_UTIL_H_ - -#include - -#include "wifi_iface_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace iface_util { - -class MockWifiIfaceUtil : public WifiIfaceUtil { - public: - MockWifiIfaceUtil( - const std::weak_ptr iface_tool, - const std::weak_ptr legacy_hal); - MOCK_METHOD1(getFactoryMacAddress, - std::array(const std::string&)); - MOCK_METHOD2(setMacAddress, - bool(const std::string&, const std::array&)); - MOCK_METHOD0(getOrCreateRandomMacAddress, std::array()); - MOCK_METHOD2(registerIfaceEventHandlers, - void(const std::string&, IfaceEventHandlers)); - MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&)); - MOCK_METHOD2(setUpState, bool(const std::string&, bool)); - MOCK_METHOD1(ifNameToIndex, unsigned(const std::string&)); -}; -} // namespace iface_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // MOCK_WIFI_IFACE_UTIL_H_ diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp deleted file mode 100644 index d13c5568b3..0000000000 --- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 -#include "mock_wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace legacy_hal { - -MockWifiLegacyHal::MockWifiLegacyHal( - const std::weak_ptr iface_tool, - const wifi_hal_fn& fn, bool is_primary) - : WifiLegacyHal(iface_tool, fn, is_primary) {} -} // namespace legacy_hal -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h deleted file mode 100644 index 826b35f8dd..0000000000 --- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MOCK_WIFI_LEGACY_HAL_H_ -#define MOCK_WIFI_LEGACY_HAL_H_ - -#include - -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace legacy_hal { - -class MockWifiLegacyHal : public WifiLegacyHal { - public: - MockWifiLegacyHal( - const std::weak_ptr iface_tool, - const wifi_hal_fn& fn, bool is_primary); - MOCK_METHOD0(initialize, wifi_error()); - MOCK_METHOD0(start, wifi_error()); - MOCK_METHOD2(stop, wifi_error(std::unique_lock*, - const std::function&)); - MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool)); - MOCK_METHOD2(registerRadioModeChangeCallbackHandler, - wifi_error(const std::string&, - const on_radio_mode_change_callback&)); - MOCK_METHOD1(getFirmwareVersion, std::pair( - const std::string& iface_name)); - MOCK_METHOD1(getDriverVersion, std::pair( - const std::string& iface_name)); - - MOCK_METHOD2(selectTxPowerScenario, - wifi_error(const std::string& iface_name, - wifi_power_scenario scenario)); - MOCK_METHOD1(resetTxPowerScenario, - wifi_error(const std::string& iface_name)); - MOCK_METHOD2(nanRegisterCallbackHandlers, - wifi_error(const std::string&, const NanCallbackHandlers&)); - MOCK_METHOD2(nanDisableRequest, - wifi_error(const std::string&, transaction_id)); - MOCK_METHOD3(nanDataInterfaceDelete, - wifi_error(const std::string&, transaction_id, - const std::string&)); - MOCK_METHOD2(createVirtualInterface, - wifi_error(const std::string& ifname, - wifi_interface_type iftype)); - MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname)); - MOCK_METHOD0(waitForDriverReady, wifi_error()); -}; -} // namespace legacy_hal -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // MOCK_WIFI_LEGACY_HAL_H_ diff --git a/wifi/1.5/default/tests/mock_wifi_mode_controller.cpp b/wifi/1.5/default/tests/mock_wifi_mode_controller.cpp deleted file mode 100644 index e7ab22a01b..0000000000 --- a/wifi/1.5/default/tests/mock_wifi_mode_controller.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 -#include "mock_wifi_mode_controller.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace mode_controller { - -MockWifiModeController::MockWifiModeController() : WifiModeController() {} -} // namespace mode_controller -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/tests/mock_wifi_mode_controller.h b/wifi/1.5/default/tests/mock_wifi_mode_controller.h deleted file mode 100644 index b9151f18b4..0000000000 --- a/wifi/1.5/default/tests/mock_wifi_mode_controller.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MOCK_WIFI_MODE_CONTROLLER_H_ -#define MOCK_WIFI_MODE_CONTROLLER_H_ - -#include - -#include "wifi_mode_controller.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace mode_controller { - -class MockWifiModeController : public WifiModeController { - public: - MockWifiModeController(); - MOCK_METHOD0(initialize, bool()); - MOCK_METHOD1(changeFirmwareMode, bool(IfaceType)); - MOCK_METHOD1(isFirmwareModeChangeNeeded, bool(IfaceType)); - MOCK_METHOD0(deinitialize, bool()); -}; -} // namespace mode_controller -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // MOCK_WIFI_MODE_CONTROLLER_H_ diff --git a/wifi/1.5/default/tests/ringbuffer_unit_tests.cpp b/wifi/1.5/default/tests/ringbuffer_unit_tests.cpp deleted file mode 100644 index 6fd34ee29c..0000000000 --- a/wifi/1.5/default/tests/ringbuffer_unit_tests.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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. - */ - -#include - -#include "ringbuffer.h" - -using testing::Return; -using testing::Test; - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { - -class RingbufferTest : public Test { - public: - const uint32_t maxBufferSize_ = 10; - Ringbuffer buffer_{maxBufferSize_}; -}; - -TEST_F(RingbufferTest, CreateEmptyBuffer) { - ASSERT_TRUE(buffer_.getData().empty()); -} - -TEST_F(RingbufferTest, CanUseFullBufferCapacity) { - const std::vector input(maxBufferSize_ / 2, '0'); - const std::vector input2(maxBufferSize_ / 2, '1'); - buffer_.append(input); - buffer_.append(input2); - ASSERT_EQ(2u, buffer_.getData().size()); - EXPECT_EQ(input, buffer_.getData().front()); - EXPECT_EQ(input2, buffer_.getData().back()); -} - -TEST_F(RingbufferTest, OldDataIsRemovedOnOverflow) { - const std::vector input(maxBufferSize_ / 2, '0'); - const std::vector input2(maxBufferSize_ / 2, '1'); - const std::vector input3 = {'G'}; - buffer_.append(input); - buffer_.append(input2); - buffer_.append(input3); - ASSERT_EQ(2u, buffer_.getData().size()); - EXPECT_EQ(input2, buffer_.getData().front()); - EXPECT_EQ(input3, buffer_.getData().back()); -} - -TEST_F(RingbufferTest, MultipleOldDataIsRemovedOnOverflow) { - const std::vector input(maxBufferSize_ / 2, '0'); - const std::vector input2(maxBufferSize_ / 2, '1'); - const std::vector input3(maxBufferSize_, '2'); - buffer_.append(input); - buffer_.append(input2); - buffer_.append(input3); - ASSERT_EQ(1u, buffer_.getData().size()); - EXPECT_EQ(input3, buffer_.getData().front()); -} - -TEST_F(RingbufferTest, AppendingEmptyBufferDoesNotAddGarbage) { - const std::vector input = {}; - buffer_.append(input); - ASSERT_TRUE(buffer_.getData().empty()); -} - -TEST_F(RingbufferTest, OversizedAppendIsDropped) { - const std::vector input(maxBufferSize_ + 1, '0'); - buffer_.append(input); - ASSERT_TRUE(buffer_.getData().empty()); -} - -TEST_F(RingbufferTest, OversizedAppendDoesNotDropExistingData) { - const std::vector input(maxBufferSize_, '0'); - const std::vector input2(maxBufferSize_ + 1, '1'); - buffer_.append(input); - buffer_.append(input2); - ASSERT_EQ(1u, buffer_.getData().size()); - EXPECT_EQ(input, buffer_.getData().front()); -} -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/tests/runtests.sh b/wifi/1.5/default/tests/runtests.sh deleted file mode 100755 index 6bce3ef8c4..0000000000 --- a/wifi/1.5/default/tests/runtests.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -# Copyright(C) 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0(the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http:// www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -if [ -z $ANDROID_BUILD_TOP ]; then - echo "You need to source and lunch before you can use this script" - exit 1 -fi -set -e - -$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode android.hardware.wifi@1.0-service-tests -adb root -adb sync data -adb shell /data/nativetest64/vendor/android.hardware.wifi@1.0-service-tests/android.hardware.wifi@1.0-service-tests diff --git a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp deleted file mode 100644 index 0ad6f3e821..0000000000 --- a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp +++ /dev/null @@ -1,905 +0,0 @@ -/* - * Copyright (C) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 -#include "wifi_chip.h" - -#include "mock_interface_tool.h" -#include "mock_wifi_feature_flags.h" -#include "mock_wifi_iface_util.h" -#include "mock_wifi_legacy_hal.h" -#include "mock_wifi_mode_controller.h" - -using testing::NiceMock; -using testing::Return; -using testing::Test; - -namespace { -using android::hardware::wifi::V1_0::ChipId; - -constexpr ChipId kFakeChipId = 5; -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { - -class WifiChipTest : public Test { - protected: - void setupV1IfaceCombination() { - // clang-format off - const hidl_vec combinationsSta = { - {{{{IfaceType::STA}, 1}, {{IfaceType::P2P}, 1}}} - }; - const hidl_vec combinationsAp = { - {{{{IfaceType::AP}, 1}}} - }; - const std::vector modes = { - {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}, - {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} - }; - // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); - } - - void setupV1_AwareIfaceCombination() { - // clang-format off - const hidl_vec combinationsSta = { - {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} - }; - const hidl_vec combinationsAp = { - {{{{IfaceType::AP}, 1}}} - }; - const std::vector modes = { - {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}, - {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} - }; - // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); - } - - void setupV1_AwareDisabledApIfaceCombination() { - // clang-format off - const hidl_vec combinationsSta = { - {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} - }; - const std::vector modes = { - {feature_flags::chip_mode_ids::kV1Sta, combinationsSta} - }; - // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); - } - - void setupV2_AwareIfaceCombination() { - // clang-format off - const hidl_vec combinations = { - {{{{IfaceType::STA}, 1}, {{IfaceType::AP}, 1}}}, - {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} - }; - const std::vector modes = { - {feature_flags::chip_mode_ids::kV3, combinations} - }; - // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); - } - - void setupV2_AwareDisabledApIfaceCombination() { - // clang-format off - const hidl_vec combinations = { - {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} - }; - const std::vector modes = { - {feature_flags::chip_mode_ids::kV3, combinations} - }; - // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); - } - - void setup_MultiIfaceCombination() { - // clang-format off - const hidl_vec combinations = { - {{{{IfaceType::STA}, 3}, {{IfaceType::AP}, 1}}} - }; - const std::vector modes = { - {feature_flags::chip_mode_ids::kV3, combinations} - }; - // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes(true)) - .WillRepeatedly(testing::Return(modes)); - } - - void assertNumberOfModes(uint32_t num_modes) { - chip_->getAvailableModes( - [num_modes](const WifiStatus& status, - const std::vector& modes) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - // V2_Aware has 1 mode of operation. - ASSERT_EQ(num_modes, modes.size()); - }); - } - - void findModeAndConfigureForIfaceType(const IfaceType& type) { - // This should be aligned with kInvalidModeId in wifi_chip.cpp. - ChipModeId mode_id = UINT32_MAX; - chip_->getAvailableModes( - [&mode_id, &type](const WifiStatus& status, - const std::vector& modes) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - for (const auto& mode : modes) { - for (const auto& combination : mode.availableCombinations) { - for (const auto& limit : combination.limits) { - if (limit.types.end() != - std::find(limit.types.begin(), - limit.types.end(), type)) { - mode_id = mode.id; - } - } - } - } - }); - ASSERT_NE(UINT32_MAX, mode_id); - - chip_->configureChip(mode_id, [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); - } - - // Returns an empty string on error. - std::string createIface(const IfaceType& type) { - std::string iface_name; - if (type == IfaceType::AP) { - chip_->createApIface( - [&iface_name](const WifiStatus& status, - const sp& iface) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(iface.get(), nullptr); - iface->getName([&iface_name](const WifiStatus& status, - const hidl_string& name) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - iface_name = name.c_str(); - }); - } - }); - } else if (type == IfaceType::NAN) { - chip_->createNanIface( - [&iface_name]( - const WifiStatus& status, - const sp& - iface) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(iface.get(), nullptr); - iface->getName([&iface_name](const WifiStatus& status, - const hidl_string& name) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - iface_name = name.c_str(); - }); - } - }); - } else if (type == IfaceType::P2P) { - chip_->createP2pIface( - [&iface_name](const WifiStatus& status, - const sp& iface) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(iface.get(), nullptr); - iface->getName([&iface_name](const WifiStatus& status, - const hidl_string& name) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - iface_name = name.c_str(); - }); - } - }); - } else if (type == IfaceType::STA) { - chip_->createStaIface( - [&iface_name](const WifiStatus& status, - const sp& iface) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(iface.get(), nullptr); - iface->getName([&iface_name](const WifiStatus& status, - const hidl_string& name) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - iface_name = name.c_str(); - }); - } - }); - } - return iface_name; - } - - void removeIface(const IfaceType& type, const std::string& iface_name) { - if (type == IfaceType::AP) { - chip_->removeApIface(iface_name, [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); - } else if (type == IfaceType::NAN) { - chip_->removeNanIface(iface_name, [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); - } else if (type == IfaceType::P2P) { - chip_->removeP2pIface(iface_name, [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); - } else if (type == IfaceType::STA) { - chip_->removeStaIface(iface_name, [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); - } - } - - bool createRttController() { - bool success = false; - chip_->createRttController_1_4( - NULL, [&success](const WifiStatus& status, - const sp& rtt) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(rtt.get(), nullptr); - success = true; - } - }); - return success; - } - - static void subsystemRestartHandler(const std::string& /*error*/) {} - - sp chip_; - ChipId chip_id_ = kFakeChipId; - legacy_hal::wifi_hal_fn fake_func_table_; - std::shared_ptr> iface_tool_{ - new NiceMock}; - std::shared_ptr> legacy_hal_{ - new NiceMock(iface_tool_, - fake_func_table_, true)}; - std::shared_ptr> - mode_controller_{new NiceMock}; - std::shared_ptr> iface_util_{ - new NiceMock(iface_tool_, legacy_hal_)}; - std::shared_ptr> - feature_flags_{new NiceMock}; - - public: - void SetUp() override { - chip_ = - new WifiChip(chip_id_, true, legacy_hal_, mode_controller_, - iface_util_, feature_flags_, subsystemRestartHandler); - - EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_)) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(*legacy_hal_, start()) - .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS)); - } - - void TearDown() override { - // Restore default system iface names (This should ideally be using a - // mock). - property_set("wifi.interface", "wlan0"); - property_set("wifi.concurrent.interface", "wlan1"); - property_set("wifi.aware.interface", nullptr); - } -}; - -////////// V1 Iface Combinations //////////// -// Mode 1 - STA + P2P -// Mode 2 - AP -class WifiChipV1IfaceCombinationTest : public WifiChipTest { - public: - void SetUp() override { - setupV1IfaceCombination(); - WifiChipTest::SetUp(); - // V1 has 2 modes of operation. - assertNumberOfModes(2u); - } -}; - -TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); -} - -TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateNan_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_TRUE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateAp_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_TRUE(createIface(IfaceType::AP).empty()); -} - -TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); -} - -TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateSta_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_TRUE(createIface(IfaceType::STA).empty()); -} - -TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateP2p_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_TRUE(createIface(IfaceType::STA).empty()); -} - -TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateNan_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_TRUE(createIface(IfaceType::NAN).empty()); -} - -////////// V1 + Aware Iface Combinations //////////// -// Mode 1 - STA + P2P/NAN -// Mode 2 - AP -class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest { - public: - void SetUp() override { - setupV1_AwareIfaceCombination(); - WifiChipTest::SetUp(); - // V1_Aware has 2 modes of operation. - assertNumberOfModes(2u); - } -}; - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateNan_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateAp_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_TRUE(createIface(IfaceType::AP).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaP2p_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaNan_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_FALSE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaP2PNan_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); - ASSERT_TRUE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - const auto p2p_iface_name = createIface(IfaceType::P2P); - ASSERT_FALSE(p2p_iface_name.empty()); - ASSERT_TRUE(createIface(IfaceType::NAN).empty()); - - // After removing P2P iface, NAN iface creation should succeed. - removeIface(IfaceType::P2P, p2p_iface_name); - ASSERT_FALSE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, - StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - const auto nan_iface_name = createIface(IfaceType::NAN); - ASSERT_FALSE(nan_iface_name.empty()); - ASSERT_TRUE(createIface(IfaceType::P2P).empty()); - - // After removing NAN iface, P2P iface creation should succeed. - removeIface(IfaceType::NAN, nan_iface_name); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateSta_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_TRUE(createIface(IfaceType::STA).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateP2p_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_TRUE(createIface(IfaceType::STA).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateNan_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_TRUE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_TRUE(createRttController()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_TRUE(createRttController()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowApToSta) { - findModeAndConfigureForIfaceType(IfaceType::AP); - const auto ap_iface_name = createIface(IfaceType::AP); - ASSERT_FALSE(ap_iface_name.empty()); - ASSERT_FALSE(createRttController()); - - removeIface(IfaceType::AP, ap_iface_name); - - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_TRUE(createRttController()); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); - chip_->selectTxPowerScenario_1_2( - V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, - [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); -} - -TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); - EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); - chip_->selectTxPowerScenario_1_2( - V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, - [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); -} - -////////// V2 + Aware Iface Combinations //////////// -// Mode 1 - STA + STA/AP -// - STA + P2P/NAN -class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest { - public: - void SetUp() override { - setupV2_AwareIfaceCombination(); - WifiChipTest::SetUp(); - // V2_Aware has 1 mode of operation. - assertNumberOfModes(1u); - } -}; - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateP2p_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNan_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateAp_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - ASSERT_TRUE(createIface(IfaceType::STA).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApSta_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - CreateSta_AfterStaApRemove_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - const auto sta_iface_name = createIface(IfaceType::STA); - ASSERT_FALSE(sta_iface_name.empty()); - const auto ap_iface_name = createIface(IfaceType::AP); - ASSERT_FALSE(ap_iface_name.empty()); - - ASSERT_TRUE(createIface(IfaceType::STA).empty()); - - // After removing AP & STA iface, STA iface creation should succeed. - removeIface(IfaceType::STA, sta_iface_name); - removeIface(IfaceType::AP, ap_iface_name); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_FALSE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2PNan_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); - ASSERT_TRUE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - CreateStaNan_AfterP2pRemove_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - const auto p2p_iface_name = createIface(IfaceType::P2P); - ASSERT_FALSE(p2p_iface_name.empty()); - ASSERT_TRUE(createIface(IfaceType::NAN).empty()); - - // After removing P2P iface, NAN iface creation should succeed. - removeIface(IfaceType::P2P, p2p_iface_name); - ASSERT_FALSE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - CreateStaP2p_AfterNanRemove_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - const auto nan_iface_name = createIface(IfaceType::NAN); - ASSERT_FALSE(nan_iface_name.empty()); - ASSERT_TRUE(createIface(IfaceType::P2P).empty()); - - // After removing NAN iface, P2P iface creation should succeed. - removeIface(IfaceType::NAN, nan_iface_name); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApNan_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_FALSE(createIface(IfaceType::AP).empty()); - ASSERT_TRUE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApP2p_ShouldFail) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_FALSE(createIface(IfaceType::AP).empty()); - ASSERT_TRUE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - const auto p2p_iface_name = createIface(IfaceType::P2P); - ASSERT_FALSE(p2p_iface_name.empty()); - ASSERT_TRUE(createIface(IfaceType::NAN).empty()); - - // After removing P2P iface, NAN iface creation should succeed. - removeIface(IfaceType::P2P, p2p_iface_name); - ASSERT_FALSE(createIface(IfaceType::NAN).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - const auto nan_iface_name = createIface(IfaceType::NAN); - ASSERT_FALSE(nan_iface_name.empty()); - ASSERT_TRUE(createIface(IfaceType::P2P).empty()); - - // After removing NAN iface, P2P iface creation should succeed. - removeIface(IfaceType::NAN, nan_iface_name); - ASSERT_FALSE(createIface(IfaceType::P2P).empty()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - CreateStaAp_EnsureDifferentIfaceNames) { - findModeAndConfigureForIfaceType(IfaceType::AP); - const auto sta_iface_name = createIface(IfaceType::STA); - const auto ap_iface_name = createIface(IfaceType::AP); - ASSERT_FALSE(sta_iface_name.empty()); - ASSERT_FALSE(ap_iface_name.empty()); - ASSERT_NE(sta_iface_name, ap_iface_name); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_TRUE(createRttController()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_TRUE(createRttController()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlow) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_FALSE(createIface(IfaceType::AP).empty()); - ASSERT_TRUE(createRttController()); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); - chip_->selectTxPowerScenario_1_2( - V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, - [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) { - findModeAndConfigureForIfaceType(IfaceType::AP); - ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); - EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); - chip_->selectTxPowerScenario_1_2( - V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, - [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - InvalidateAndRemoveNanOnStaRemove) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - - // Create NAN iface - ASSERT_EQ(createIface(IfaceType::NAN), "wlan0"); - - // We should have 1 nan iface. - chip_->getNanIfaceNames( - [](const WifiStatus& status, const hidl_vec& iface_names) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - ASSERT_EQ(iface_names.size(), 1u); - ASSERT_EQ(iface_names[0], "wlan0"); - }); - // Retrieve the exact iface object. - sp nan_iface; - chip_->getNanIface( - "wlan0", - [&nan_iface]( - const WifiStatus& status, - const sp& iface) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - ASSERT_NE(iface.get(), nullptr); - nan_iface = iface; - }); - - // Remove the STA iface. - removeIface(IfaceType::STA, "wlan0"); - // We should have 0 nan iface now. - chip_->getNanIfaceNames( - [](const WifiStatus& status, const hidl_vec& iface_names) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - ASSERT_EQ(iface_names.size(), 0u); - }); - // Any operation on the nan iface object should return error now. - nan_iface->getName( - [](const WifiStatus& status, const std::string& /* iface_name */) { - ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code); - }); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, - InvalidateAndRemoveRttControllerOnStaRemove) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - - // Create RTT controller - sp rtt_controller; - chip_->createRttController_1_4( - NULL, [&rtt_controller](const WifiStatus& status, - const sp& rtt) { - if (WifiStatusCode::SUCCESS == status.code) { - ASSERT_NE(rtt.get(), nullptr); - rtt_controller = rtt; - } - }); - - // Remove the STA iface. - removeIface(IfaceType::STA, "wlan0"); - - // Any operation on the rtt controller object should return error now. - rtt_controller->getBoundIface( - [](const WifiStatus& status, const sp& /* iface */) { - ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - status.code); - }); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) { - property_set("wifi.aware.interface", nullptr); - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - ASSERT_EQ(createIface(IfaceType::NAN), "wlan0"); - removeIface(IfaceType::NAN, "wlan0"); - EXPECT_CALL(*iface_util_, setUpState(testing::_, testing::_)).Times(0); -} - -TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithDedicatedNanIface) { - property_set("wifi.aware.interface", "aware0"); - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - EXPECT_CALL(*iface_util_, ifNameToIndex("aware0")) - .WillOnce(testing::Return(4)); - EXPECT_CALL(*iface_util_, setUpState("aware0", true)) - .WillOnce(testing::Return(true)); - ASSERT_EQ(createIface(IfaceType::NAN), "aware0"); - - EXPECT_CALL(*iface_util_, setUpState("aware0", false)) - .WillOnce(testing::Return(true)); - removeIface(IfaceType::NAN, "aware0"); -} - -////////// V1 Iface Combinations when AP creation is disabled ////////// -class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest { - public: - void SetUp() override { - setupV1_AwareDisabledApIfaceCombination(); - WifiChipTest::SetUp(); - } -}; - -TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, - StaMode_CreateSta_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_TRUE(createIface(IfaceType::AP).empty()); -} - -////////// V2 Iface Combinations when AP creation is disabled ////////// -class WifiChipV2_AwareDisabledApIfaceCombinationTest : public WifiChipTest { - public: - void SetUp() override { - setupV2_AwareDisabledApIfaceCombination(); - WifiChipTest::SetUp(); - } -}; - -TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, - CreateSta_ShouldSucceed) { - findModeAndConfigureForIfaceType(IfaceType::STA); - ASSERT_FALSE(createIface(IfaceType::STA).empty()); - ASSERT_TRUE(createIface(IfaceType::AP).empty()); -} - -////////// Hypothetical Iface Combination with multiple ifaces ////////// -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), "bad0"); - ASSERT_EQ(createIface(IfaceType::STA), "bad1"); - 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"); -} - -TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) { - findModeAndConfigureForIfaceType(IfaceType::STA); - // First AP will be slotted to wlan1. - ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); - // First STA will be slotted to wlan0. - ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); - // All further STA will be slotted to the remaining free indices. - ASSERT_EQ(createIface(IfaceType::STA), "wlan2"); - ASSERT_EQ(createIface(IfaceType::STA), "wlan3"); -} -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp deleted file mode 100644 index 8b67bb80c8..0000000000 --- a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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 -#include -#include - -#undef NAN -#include "wifi_iface_util.h" - -#include "mock_interface_tool.h" -#include "mock_wifi_legacy_hal.h" - -using testing::NiceMock; -using testing::Test; - -namespace { -constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02; -constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc}; -constexpr char kIfaceName[] = "test-wlan0"; - -bool isValidUnicastLocallyAssignedMacAddress( - const std::array& mac_address) { - uint8_t first_byte = mac_address[0]; - return (first_byte & 0x3) == kValidUnicastLocallyAssignedMacAddressMask; -} -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace iface_util { -class WifiIfaceUtilTest : public Test { - protected: - std::shared_ptr> iface_tool_{ - new NiceMock}; - legacy_hal::wifi_hal_fn fake_func_table_; - std::shared_ptr> legacy_hal_{ - new NiceMock(iface_tool_, - fake_func_table_, true)}; - WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_); -}; - -TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) { - auto mac_address = iface_util_->getOrCreateRandomMacAddress(); - ASSERT_TRUE(isValidUnicastLocallyAssignedMacAddress(mac_address)); - - // All further calls should return the same MAC address. - ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress()); - ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress()); -} - -TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) { - std::array mac_address = {}; - std::copy(std::begin(kMacAddress), std::end(kMacAddress), - std::begin(mac_address)); - EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_)) - .WillRepeatedly(testing::Return(true)); - EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_)) - .WillRepeatedly(testing::Return(true)); - - // Register for iface state toggle events. - bool callback_invoked = false; - iface_util::IfaceEventHandlers event_handlers = {}; - event_handlers.on_state_toggle_off_on = - [&callback_invoked](const std::string& /* iface_name */) { - callback_invoked = true; - }; - iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers); - // Invoke setMacAddress and ensure that the cb is invoked. - ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address)); - ASSERT_TRUE(callback_invoked); - - // Unregister for iface state toggle events. - callback_invoked = false; - iface_util_->unregisterIfaceEventHandlers(kIfaceName); - // Invoke setMacAddress and ensure that the cb is not invoked. - ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address)); - ASSERT_FALSE(callback_invoked); -} -} // namespace iface_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp deleted file mode 100644 index 32da55ec2b..0000000000 --- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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 -#include -#include -#include - -#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 -#include "wifi_nan_iface.h" - -#include "mock_interface_tool.h" -#include "mock_wifi_feature_flags.h" -#include "mock_wifi_iface_util.h" -#include "mock_wifi_legacy_hal.h" - -using testing::NiceMock; -using testing::Return; -using testing::Test; - -namespace { -constexpr char kIfaceName[] = "mockWlan0"; -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { - -using android::hardware::wifi::V1_2::NanDataPathConfirmInd; - -bool CaptureIfaceEventHandlers( - const std::string& /* iface_name*/, - iface_util::IfaceEventHandlers in_iface_event_handlers, - iface_util::IfaceEventHandlers* out_iface_event_handlers) { - *out_iface_event_handlers = in_iface_event_handlers; - return true; -} - -class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback { - public: - MockNanIfaceEventCallback() = default; - - MOCK_METHOD3( - notifyCapabilitiesResponse, - Return(uint16_t, const WifiNanStatus&, - const android::hardware::wifi::V1_0::NanCapabilities&)); - MOCK_METHOD2(notifyEnableResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyConfigResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyDisableResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD3(notifyStartPublishResponse, - Return(uint16_t, const WifiNanStatus&, uint8_t)); - MOCK_METHOD2(notifyStopPublishResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD3(notifyStartSubscribeResponse, - Return(uint16_t, const WifiNanStatus&, uint8_t)); - MOCK_METHOD2(notifyStopSubscribeResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyTransmitFollowupResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyCreateDataInterfaceResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyDeleteDataInterfaceResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD3(notifyInitiateDataPathResponse, - Return(uint16_t, const WifiNanStatus&, uint32_t)); - MOCK_METHOD2(notifyRespondToDataPathIndicationResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD2(notifyTerminateDataPathResponse, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD1(eventClusterEvent, Return(const NanClusterEventInd&)); - MOCK_METHOD1(eventDisabled, Return(const WifiNanStatus&)); - MOCK_METHOD2(eventPublishTerminated, - Return(uint8_t, const WifiNanStatus&)); - MOCK_METHOD2(eventSubscribeTerminated, - Return(uint8_t, const WifiNanStatus&)); - MOCK_METHOD1(eventMatch, Return(const NanMatchInd&)); - MOCK_METHOD2(eventMatchExpired, Return(uint8_t, uint32_t)); - MOCK_METHOD1(eventFollowupReceived, - Return(const NanFollowupReceivedInd&)); - MOCK_METHOD2(eventTransmitFollowup, - Return(uint16_t, const WifiNanStatus&)); - MOCK_METHOD1(eventDataPathRequest, - Return(const NanDataPathRequestInd&)); - MOCK_METHOD1( - eventDataPathConfirm, - Return( - const android::hardware::wifi::V1_0::NanDataPathConfirmInd&)); - MOCK_METHOD1(eventDataPathTerminated, Return(uint32_t)); - MOCK_METHOD1(eventDataPathConfirm_1_2, - Return(const NanDataPathConfirmInd&)); - MOCK_METHOD1(eventDataPathScheduleUpdate, - Return(const NanDataPathScheduleUpdateInd&)); - MOCK_METHOD3(notifyCapabilitiesResponse_1_5, - Return(uint16_t, const WifiNanStatus&, - const NanCapabilities&)); -}; - -class WifiNanIfaceTest : public Test { - protected: - legacy_hal::wifi_hal_fn fake_func_table_; - std::shared_ptr> iface_tool_{ - new NiceMock}; - std::shared_ptr> legacy_hal_{ - new NiceMock(iface_tool_, - fake_func_table_, true)}; - std::shared_ptr> iface_util_{ - new NiceMock(iface_tool_, legacy_hal_)}; -}; - -TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) { - iface_util::IfaceEventHandlers captured_iface_event_handlers = {}; - EXPECT_CALL(*legacy_hal_, - nanRegisterCallbackHandlers(testing::_, testing::_)) - .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); - EXPECT_CALL(*iface_util_, - registerIfaceEventHandlers(testing::_, testing::_)) - .WillOnce(testing::Invoke( - bind(CaptureIfaceEventHandlers, std::placeholders::_1, - std::placeholders::_2, &captured_iface_event_handlers))); - sp nan_iface = - new WifiNanIface(kIfaceName, false, legacy_hal_, iface_util_); - - // Register a mock nan event callback. - sp> mock_event_callback{ - new NiceMock}; - nan_iface->registerEventCallback( - mock_event_callback, [](const WifiStatus& status) { - ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); - }); - // Ensure that the eventDisabled() function in mock callback will be - // invoked. - WifiNanStatus expected_nan_status = { - NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""}; - EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status)) - .Times(1); - - // Trigger the iface state toggle callback. - captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName); -} -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp deleted file mode 100644 index a85b242a8a..0000000000 --- a/wifi/1.5/default/wifi.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/* - * 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. - */ - -#include - -#include "hidl_return_util.h" -#include "wifi.h" -#include "wifi_status_util.h" - -namespace { -// Starting Chip ID, will be assigned to primary chip -static constexpr android::hardware::wifi::V1_0::ChipId kPrimaryChipId = 0; -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using hidl_return_util::validateAndCall; -using hidl_return_util::validateAndCallWithLock; - -Wifi::Wifi( - const std::shared_ptr iface_tool, - const std::shared_ptr legacy_hal_factory, - const std::shared_ptr mode_controller, - const std::shared_ptr feature_flags) - : iface_tool_(iface_tool), - legacy_hal_factory_(legacy_hal_factory), - mode_controller_(mode_controller), - feature_flags_(feature_flags), - run_state_(RunState::STOPPED) {} - -bool Wifi::isValid() { - // This object is always valid. - return true; -} - -Return Wifi::registerEventCallback( - const sp& event_callback, - registerEventCallback_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::registerEventCallbackInternal, hidl_status_cb, - event_callback); -} - -Return Wifi::registerEventCallback_1_5( - const sp& event_callback, - registerEventCallback_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::registerEventCallbackInternal_1_5, - hidl_status_cb, event_callback); -} - -Return Wifi::isStarted() { return run_state_ != RunState::STOPPED; } - -Return Wifi::start(start_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::startInternal, hidl_status_cb); -} - -Return Wifi::stop(stop_cb hidl_status_cb) { - return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::stopInternal, hidl_status_cb); -} - -Return Wifi::getChipIds(getChipIds_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::getChipIdsInternal, hidl_status_cb); -} - -Return Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, - &Wifi::getChipInternal, hidl_status_cb, chip_id); -} - -Return Wifi::debug(const hidl_handle& handle, - const hidl_vec&) { - LOG(INFO) << "-----------Debug is called----------------"; - if (chips_.size() == 0) { - return Void(); - } - - for (sp chip : chips_) { - if (!chip.get()) continue; - - chip->debug(handle, {}); - } - return Void(); -} - -WifiStatus Wifi::registerEventCallbackInternal( - const sp& event_callback __unused) { - // Deprecated support for this callback. - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus Wifi::registerEventCallbackInternal_1_5( - const sp& event_callback) { - if (!event_cb_handler_.addCallback(event_callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus Wifi::startInternal() { - if (run_state_ == RunState::STARTED) { - return createWifiStatus(WifiStatusCode::SUCCESS); - } else if (run_state_ == RunState::STOPPING) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, - "HAL is stopping"); - } - WifiStatus wifi_status = initializeModeControllerAndLegacyHal(); - if (wifi_status.code == WifiStatusCode::SUCCESS) { - // Register the callback for subsystem restart - const auto& on_subsystem_restart_callback = - [this](const std::string& error) { - WifiStatus wifi_status = - createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - LOG(INFO) << "Attempting to invoke onSubsystemRestart " - "callback"; - if (!callback->onSubsystemRestart(wifi_status).isOk()) { - LOG(ERROR) - << "Failed to invoke onSubsystemRestart callback"; - } else { - LOG(INFO) << "Succeeded to invoke onSubsystemRestart " - "callback"; - } - } - }; - - // Create the chip instance once the HAL is started. - android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId; - for (auto& hal : legacy_hals_) { - chips_.push_back(new WifiChip( - chipId, chipId == kPrimaryChipId, hal, mode_controller_, - std::make_shared(iface_tool_, hal), - feature_flags_, on_subsystem_restart_callback)); - chipId++; - } - run_state_ = RunState::STARTED; - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onStart().isOk()) { - LOG(ERROR) << "Failed to invoke onStart callback"; - }; - } - LOG(INFO) << "Wifi HAL started"; - } else { - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onFailure(wifi_status).isOk()) { - LOG(ERROR) << "Failed to invoke onFailure callback"; - } - } - LOG(ERROR) << "Wifi HAL start failed"; - // Clear the event callback objects since the HAL start failed. - event_cb_handler_.invalidate(); - } - return wifi_status; -} - -WifiStatus Wifi::stopInternal( - /* NONNULL */ std::unique_lock* lock) { - if (run_state_ == RunState::STOPPED) { - return createWifiStatus(WifiStatusCode::SUCCESS); - } else if (run_state_ == RunState::STOPPING) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, - "HAL is stopping"); - } - // Clear the chip object and its child objects since the HAL is now - // stopped. - for (auto& chip : chips_) { - if (chip.get()) { - chip->invalidate(); - chip.clear(); - } - } - chips_.clear(); - WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock); - if (wifi_status.code == WifiStatusCode::SUCCESS) { - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onStop().isOk()) { - LOG(ERROR) << "Failed to invoke onStop callback"; - }; - } - LOG(INFO) << "Wifi HAL stopped"; - } else { - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onFailure(wifi_status).isOk()) { - LOG(ERROR) << "Failed to invoke onFailure callback"; - } - } - LOG(ERROR) << "Wifi HAL stop failed"; - } - // Clear the event callback objects since the HAL is now stopped. - event_cb_handler_.invalidate(); - return wifi_status; -} - -std::pair> Wifi::getChipIdsInternal() { - std::vector chip_ids; - - for (auto& chip : chips_) { - ChipId chip_id = getChipIdFromWifiChip(chip); - if (chip_id != UINT32_MAX) chip_ids.emplace_back(chip_id); - } - return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)}; -} - -std::pair> Wifi::getChipInternal( - ChipId chip_id) { - for (auto& chip : chips_) { - ChipId cand_id = getChipIdFromWifiChip(chip); - if ((cand_id != UINT32_MAX) && (cand_id == chip_id)) - return {createWifiStatus(WifiStatusCode::SUCCESS), chip}; - } - - return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; -} - -WifiStatus Wifi::initializeModeControllerAndLegacyHal() { - if (!mode_controller_->initialize()) { - LOG(ERROR) << "Failed to initialize firmware mode controller"; - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - - legacy_hals_ = legacy_hal_factory_->getHals(); - if (legacy_hals_.empty()) - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - int index = 0; // for failure log - for (auto& hal : legacy_hals_) { - legacy_hal::wifi_error legacy_status = hal->initialize(); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - // Currently WifiLegacyHal::initialize does not allocate extra mem, - // only initializes the function table. If this changes, need to - // implement WifiLegacyHal::deinitialize and deinitalize the - // HALs already initialized - LOG(ERROR) << "Failed to initialize legacy HAL index: " << index - << " error: " << legacyErrorToString(legacy_status); - return createWifiStatusFromLegacyError(legacy_status); - } - index++; - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController( - /* NONNULL */ std::unique_lock* lock) { - legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS; - int index = 0; - - run_state_ = RunState::STOPPING; - for (auto& hal : legacy_hals_) { - legacy_hal::wifi_error tmp = hal->stop(lock, [&]() {}); - if (tmp != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to stop legacy HAL index: " << index - << " error: " << legacyErrorToString(legacy_status); - legacy_status = tmp; - } - index++; - } - run_state_ = RunState::STOPPED; - - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "One or more legacy HALs failed to stop"; - return createWifiStatusFromLegacyError(legacy_status); - } - if (!mode_controller_->deinitialize()) { - LOG(ERROR) << "Failed to deinitialize firmware mode controller"; - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -ChipId Wifi::getChipIdFromWifiChip(sp& chip) { - ChipId chip_id = UINT32_MAX; - if (chip.get()) { - chip->getId([&](WifiStatus status, uint32_t id) { - if (status.code == WifiStatusCode::SUCCESS) { - chip_id = id; - } - }); - } - - return chip_id; -} -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi.h b/wifi/1.5/default/wifi.h deleted file mode 100644 index c94ef3f4cf..0000000000 --- a/wifi/1.5/default/wifi.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_H_ -#define WIFI_H_ - -// HACK: NAN is a macro defined in math.h, which can be included in various -// headers. This wifi HAL uses an enum called NAN, which does not compile when -// the macro is defined. Undefine NAN to work around it. -#undef NAN -#include - -#include -#include -#include - -#include "hidl_callback_util.h" -#include "wifi_chip.h" -#include "wifi_feature_flags.h" -#include "wifi_legacy_hal.h" -#include "wifi_legacy_hal_factory.h" -#include "wifi_mode_controller.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { - -/** - * Root HIDL interface object used to control the Wifi HAL. - */ -class Wifi : public V1_5::IWifi { - public: - Wifi(const std::shared_ptr iface_tool, - const std::shared_ptr - legacy_hal_factory, - const std::shared_ptr - mode_controller, - const std::shared_ptr feature_flags); - - bool isValid(); - - // HIDL methods exposed. - Return registerEventCallback( - const sp& event_callback, - registerEventCallback_cb hidl_status_cb) override; - Return registerEventCallback_1_5( - const sp& event_callback, - registerEventCallback_1_5_cb hidl_status_cb) override; - Return isStarted() override; - Return start(start_cb hidl_status_cb) override; - Return stop(stop_cb hidl_status_cb) override; - Return getChipIds(getChipIds_cb hidl_status_cb) override; - Return getChip(ChipId chip_id, getChip_cb hidl_status_cb) override; - Return debug(const hidl_handle& handle, - const hidl_vec& options) override; - - private: - enum class RunState { STOPPED, STARTED, STOPPING }; - - // Corresponding worker functions for the HIDL methods. - WifiStatus registerEventCallbackInternal( - const sp& event_callback __unused); - WifiStatus registerEventCallbackInternal_1_5( - const sp& event_callback); - WifiStatus startInternal(); - WifiStatus stopInternal(std::unique_lock* lock); - std::pair> getChipIdsInternal(); - std::pair> getChipInternal(ChipId chip_id); - - WifiStatus initializeModeControllerAndLegacyHal(); - WifiStatus stopLegacyHalAndDeinitializeModeController( - std::unique_lock* lock); - ChipId getChipIdFromWifiChip(sp& chip); - - // Instance is created in this root level |IWifi| HIDL interface object - // and shared with all the child HIDL interface objects. - std::shared_ptr iface_tool_; - std::shared_ptr legacy_hal_factory_; - std::shared_ptr mode_controller_; - std::vector> legacy_hals_; - std::shared_ptr feature_flags_; - RunState run_state_; - std::vector> chips_; - hidl_callback_util::HidlCallbackHandler - event_cb_handler_; - - DISALLOW_COPY_AND_ASSIGN(Wifi); -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_H_ diff --git a/wifi/1.5/default/wifi_ap_iface.cpp b/wifi/1.5/default/wifi_ap_iface.cpp deleted file mode 100644 index 1ae7905f74..0000000000 --- a/wifi/1.5/default/wifi_ap_iface.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 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. - */ - -#include - -#include "hidl_return_util.h" -#include "hidl_struct_util.h" -#include "wifi_ap_iface.h" -#include "wifi_status_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using hidl_return_util::validateAndCall; - -WifiApIface::WifiApIface( - const std::string& ifname, const std::vector& instances, - const std::weak_ptr legacy_hal, - const std::weak_ptr iface_util) - : ifname_(ifname), - instances_(instances), - legacy_hal_(legacy_hal), - iface_util_(iface_util), - is_valid_(true) {} - -void WifiApIface::invalidate() { - legacy_hal_.reset(); - is_valid_ = false; -} - -bool WifiApIface::isValid() { return is_valid_; } - -std::string WifiApIface::getName() { return ifname_; } - -void WifiApIface::removeInstance(std::string instance) { - instances_.erase( - std::remove(instances_.begin(), instances_.end(), instance), - instances_.end()); -} - -Return WifiApIface::getName(getName_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::getNameInternal, hidl_status_cb); -} - -Return WifiApIface::getType(getType_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::getTypeInternal, hidl_status_cb); -} - -Return WifiApIface::setCountryCode(const hidl_array& code, - setCountryCode_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::setCountryCodeInternal, hidl_status_cb, - code); -} - -Return WifiApIface::getValidFrequenciesForBand( - V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::getValidFrequenciesForBandInternal, - hidl_status_cb, band); -} - -Return WifiApIface::setMacAddress(const hidl_array& mac, - setMacAddress_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::setMacAddressInternal, hidl_status_cb, - mac); -} - -Return WifiApIface::getFactoryMacAddress( - getFactoryMacAddress_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::getFactoryMacAddressInternal, - hidl_status_cb, - instances_.size() > 0 ? instances_[0] : ifname_); -} - -Return WifiApIface::resetToFactoryMacAddress( - resetToFactoryMacAddress_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::resetToFactoryMacAddressInternal, - hidl_status_cb); -} - -Return WifiApIface::getBridgedInstances( - getBridgedInstances_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiApIface::getBridgedInstancesInternal, - hidl_status_cb); -} - -std::pair WifiApIface::getNameInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; -} - -std::pair WifiApIface::getTypeInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::AP}; -} - -WifiStatus WifiApIface::setCountryCodeInternal( - const std::array& code) { - legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode( - instances_.size() > 0 ? instances_[0] : ifname_, code); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair> -WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) { - static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), - "Size mismatch"); - legacy_hal::wifi_error legacy_status; - std::vector valid_frequencies; - std::tie(legacy_status, valid_frequencies) = - legacy_hal_.lock()->getValidFrequenciesForBand( - instances_.size() > 0 ? instances_[0] : ifname_, - hidl_struct_util::convertHidlWifiBandToLegacy(band)); - return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies}; -} - -WifiStatus WifiApIface::setMacAddressInternal( - const std::array& mac) { - // Support random MAC up to 2 interfaces - if (instances_.size() == 2) { - int rbyte = 1; - for (auto const& intf : instances_) { - std::array rmac = mac; - // reverse the bits to avoid collision - rmac[rbyte] = 0xff - rmac[rbyte]; - if (!iface_util_.lock()->setMacAddress(intf, rmac)) { - LOG(INFO) << "Failed to set random mac address on " << intf; - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - rbyte++; - } - } - // It also needs to set mac address for bridged interface, otherwise the mac - // address of bridged interface will be changed after one of instance - // down. - if (!iface_util_.lock()->setMacAddress(ifname_, mac)) { - LOG(ERROR) << "Fail to config MAC for interface " << ifname_; - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -std::pair> -WifiApIface::getFactoryMacAddressInternal(const std::string& ifaceName) { - std::array mac = - iface_util_.lock()->getFactoryMacAddress(ifaceName); - if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && - mac[4] == 0 && mac[5] == 0) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; -} - -WifiStatus WifiApIface::resetToFactoryMacAddressInternal() { - std::pair> getMacResult; - if (instances_.size() == 2) { - for (auto const& intf : instances_) { - getMacResult = getFactoryMacAddressInternal(intf); - LOG(DEBUG) << "Reset MAC to factory MAC on " << intf; - if (getMacResult.first.code != WifiStatusCode::SUCCESS || - !iface_util_.lock()->setMacAddress(intf, getMacResult.second)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - } - // It needs to set mac address for bridged interface, otherwise the mac - // address of the bridged interface will be changed after one of the - // instance down. Thus we are generating a random MAC address for the - // bridged interface even if we got the request to reset the Factory - // MAC. Since the bridged interface is an internal interface for the - // operation of bpf and others networking operation. - if (!iface_util_.lock()->setMacAddress( - ifname_, iface_util_.lock()->createRandomMacAddress())) { - LOG(ERROR) << "Fail to config MAC for bridged interface " - << ifname_; - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - } else { - getMacResult = getFactoryMacAddressInternal(ifname_); - LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_; - if (getMacResult.first.code != WifiStatusCode::SUCCESS || - !iface_util_.lock()->setMacAddress(ifname_, getMacResult.second)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -std::pair> -WifiApIface::getBridgedInstancesInternal() { - std::vector instances; - for (const auto& instance_name : instances_) { - instances.push_back(instance_name); - } - return {createWifiStatus(WifiStatusCode::SUCCESS), instances}; -} -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_ap_iface.h b/wifi/1.5/default/wifi_ap_iface.h deleted file mode 100644 index 8f8387deae..0000000000 --- a/wifi/1.5/default/wifi_ap_iface.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_AP_IFACE_H_ -#define WIFI_AP_IFACE_H_ - -#include -#include - -#include "wifi_iface_util.h" -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; - -/** - * HIDL interface object used to control a AP Iface instance. - */ -class WifiApIface : public V1_5::IWifiApIface { - public: - WifiApIface(const std::string& ifname, - const std::vector& instances, - const std::weak_ptr legacy_hal, - const std::weak_ptr iface_util); - // Refer to |WifiChip::invalidate()|. - void invalidate(); - bool isValid(); - std::string getName(); - void removeInstance(std::string instance); - - // HIDL methods exposed. - Return getName(getName_cb hidl_status_cb) override; - Return getType(getType_cb hidl_status_cb) override; - Return setCountryCode(const hidl_array& code, - setCountryCode_cb hidl_status_cb) override; - Return getValidFrequenciesForBand( - V1_0::WifiBand band, - getValidFrequenciesForBand_cb hidl_status_cb) override; - Return setMacAddress(const hidl_array& mac, - setMacAddress_cb hidl_status_cb) override; - Return getFactoryMacAddress( - getFactoryMacAddress_cb hidl_status_cb) override; - Return resetToFactoryMacAddress( - resetToFactoryMacAddress_cb hidl_status_cb) override; - - Return getBridgedInstances( - getBridgedInstances_cb hidl_status_cb) override; - - private: - // Corresponding worker functions for the HIDL methods. - std::pair getNameInternal(); - std::pair getTypeInternal(); - WifiStatus setCountryCodeInternal(const std::array& code); - std::pair> - getValidFrequenciesForBandInternal(V1_0::WifiBand band); - WifiStatus setMacAddressInternal(const std::array& mac); - std::pair> getFactoryMacAddressInternal( - const std::string& ifaceName); - WifiStatus resetToFactoryMacAddressInternal(); - std::pair> - getBridgedInstancesInternal(); - - std::string ifname_; - std::vector instances_; - std::weak_ptr legacy_hal_; - std::weak_ptr iface_util_; - bool is_valid_; - - DISALLOW_COPY_AND_ASSIGN(WifiApIface); -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_AP_IFACE_H_ diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp deleted file mode 100644 index 6bdff42149..0000000000 --- a/wifi/1.5/default/wifi_chip.cpp +++ /dev/null @@ -1,2065 +0,0 @@ -/* - * 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. - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include "hidl_return_util.h" -#include "hidl_struct_util.h" -#include "wifi_chip.h" -#include "wifi_status_util.h" - -#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-" - -namespace { -using android::sp; -using android::base::unique_fd; -using android::hardware::hidl_string; -using android::hardware::hidl_vec; -using android::hardware::wifi::V1_0::ChipModeId; -using android::hardware::wifi::V1_0::IfaceType; -using android::hardware::wifi::V1_0::IWifiChip; - -constexpr char kCpioMagic[] = "070701"; -constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3; -constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10; -constexpr uint32_t kMaxRingBufferFileNum = 20; -constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/"; -constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface"; -constexpr char kNoActiveWlanIfaceNamePropertyValue[] = ""; -constexpr unsigned kMaxWlanIfaces = 5; -constexpr char kApBridgeIfacePrefix[] = "ap_br_"; - -template -void invalidateAndClear(std::vector>& ifaces, sp iface) { - iface->invalidate(); - ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), - ifaces.end()); -} - -template -void invalidateAndClearAll(std::vector>& ifaces) { - for (const auto& iface : ifaces) { - iface->invalidate(); - } - ifaces.clear(); -} - -template -std::vector getNames(std::vector>& ifaces) { - std::vector names; - for (const auto& iface : ifaces) { - names.emplace_back(iface->getName()); - } - return names; -} - -template -sp findUsingName(std::vector>& ifaces, - const std::string& name) { - std::vector names; - for (const auto& iface : ifaces) { - if (name == iface->getName()) { - return iface; - } - } - return nullptr; -} - -std::string getWlanIfaceName(unsigned idx) { - if (idx >= kMaxWlanIfaces) { - CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces; - return {}; - } - - std::array buffer; - if (idx == 0 || idx == 1) { - const char* altPropName = - (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface"; - auto res = property_get(altPropName, buffer.data(), nullptr); - if (res > 0) 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(); - - return "wlan" + std::to_string(idx); -} - -// Returns the dedicated iface name if defined. -// Returns two ifaces in bridged mode. -std::vector getPredefinedApIfaceNames(bool is_bridged) { - std::vector ifnames; - std::array buffer; - buffer.fill(0); - if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == - 0) { - return ifnames; - } - ifnames.push_back(buffer.data()); - if (is_bridged) { - buffer.fill(0); - if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), - nullptr) == 0) { - return ifnames; - } - ifnames.push_back(buffer.data()); - } - return ifnames; -} - -std::string getPredefinedP2pIfaceName() { - std::array primaryIfaceName; - char p2pParentIfname[100]; - std::string p2pDevIfName = ""; - std::array buffer; - property_get("wifi.direct.interface", buffer.data(), "p2p0"); - if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, - strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) { - /* Get the p2p parent interface name from p2p device interface name set - * in property */ - strncpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX), - strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)); - if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), - nullptr) == 0) { - return buffer.data(); - } - /* Check if the parent interface derived from p2p device interface name - * is active */ - if (strncmp(p2pParentIfname, primaryIfaceName.data(), - strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != - 0) { - /* - * Update the predefined p2p device interface parent interface name - * with current active wlan interface - */ - p2pDevIfName += P2P_MGMT_DEVICE_PREFIX; - p2pDevIfName += primaryIfaceName.data(); - LOG(INFO) << "update the p2p device interface name to " - << p2pDevIfName.c_str(); - return p2pDevIfName; - } - } - return buffer.data(); -} - -// Returns the dedicated iface name if one is defined. -std::string getPredefinedNanIfaceName() { - std::array buffer; - if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) { - return {}; - } - return buffer.data(); -} - -void setActiveWlanIfaceNameProperty(const std::string& ifname) { - auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data()); - if (res != 0) { - PLOG(ERROR) << "Failed to set active wlan iface name property"; - } -} - -// delete files that meet either conditions: -// 1. older than a predefined time in the wifi tombstone dir. -// 2. Files in excess to a predefined amount, starting from the oldest ones -bool removeOldFilesInternal() { - time_t now = time(0); - const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds; - std::unique_ptr dir_dump( - opendir(kTombstoneFolderPath), closedir); - if (!dir_dump) { - PLOG(ERROR) << "Failed to open directory"; - return false; - } - struct dirent* dp; - bool success = true; - std::list> valid_files; - while ((dp = readdir(dir_dump.get()))) { - if (dp->d_type != DT_REG) { - continue; - } - std::string cur_file_name(dp->d_name); - struct stat cur_file_stat; - std::string cur_file_path = kTombstoneFolderPath + cur_file_name; - if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) { - PLOG(ERROR) << "Failed to get file stat for " << cur_file_path; - success = false; - continue; - } - const time_t cur_file_time = cur_file_stat.st_mtime; - valid_files.push_back( - std::pair(cur_file_time, cur_file_path)); - } - valid_files.sort(); // sort the list of files by last modified time from - // small to big. - uint32_t cur_file_count = valid_files.size(); - for (auto cur_file : valid_files) { - if (cur_file_count > kMaxRingBufferFileNum || - cur_file.first < delete_files_before) { - if (unlink(cur_file.second.c_str()) != 0) { - PLOG(ERROR) << "Error deleting file"; - success = false; - } - cur_file_count--; - } else { - break; - } - } - return success; -} - -// Helper function for |cpioArchiveFilesInDir| -bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, - size_t file_name_len) { - std::array read_buf; - ssize_t llen = - sprintf(read_buf.data(), - "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X", - kCpioMagic, static_cast(st.st_ino), st.st_mode, st.st_uid, - st.st_gid, static_cast(st.st_nlink), - static_cast(st.st_mtime), static_cast(st.st_size), - major(st.st_dev), minor(st.st_dev), major(st.st_rdev), - minor(st.st_rdev), static_cast(file_name_len), 0); - if (write(out_fd, read_buf.data(), llen) == -1) { - PLOG(ERROR) << "Error writing cpio header to file " << file_name; - return false; - } - if (write(out_fd, file_name, file_name_len) == -1) { - PLOG(ERROR) << "Error writing filename to file " << file_name; - return false; - } - - // NUL Pad header up to 4 multiple bytes. - llen = (llen + file_name_len) % 4; - if (llen != 0) { - const uint32_t zero = 0; - if (write(out_fd, &zero, 4 - llen) == -1) { - PLOG(ERROR) << "Error padding 0s to file " << file_name; - return false; - } - } - return true; -} - -// Helper function for |cpioArchiveFilesInDir| -size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) { - // writing content of file - std::array read_buf; - ssize_t llen = st.st_size; - size_t n_error = 0; - while (llen > 0) { - ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size()); - if (bytes_read == -1) { - PLOG(ERROR) << "Error reading file"; - return ++n_error; - } - llen -= bytes_read; - if (write(out_fd, read_buf.data(), bytes_read) == -1) { - PLOG(ERROR) << "Error writing data to file"; - return ++n_error; - } - if (bytes_read == 0) { // this should never happen, but just in case - // to unstuck from while loop - PLOG(ERROR) << "Unexpected read result"; - n_error++; - break; - } - } - llen = st.st_size % 4; - if (llen != 0) { - const uint32_t zero = 0; - if (write(out_fd, &zero, 4 - llen) == -1) { - PLOG(ERROR) << "Error padding 0s to file"; - return ++n_error; - } - } - return n_error; -} - -// Helper function for |cpioArchiveFilesInDir| -bool cpioWriteFileTrailer(int out_fd) { - std::array read_buf; - read_buf.fill(0); - if (write(out_fd, read_buf.data(), - sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1, - 0x0b, 0) + - 4) == -1) { - PLOG(ERROR) << "Error writing trailing bytes"; - return false; - } - return true; -} - -// Archives all files in |input_dir| and writes result into |out_fd| -// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive" -// portion -size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) { - struct dirent* dp; - size_t n_error = 0; - std::unique_ptr dir_dump(opendir(input_dir), - closedir); - if (!dir_dump) { - PLOG(ERROR) << "Failed to open directory"; - return ++n_error; - } - while ((dp = readdir(dir_dump.get()))) { - if (dp->d_type != DT_REG) { - continue; - } - std::string cur_file_name(dp->d_name); - struct stat st; - const std::string cur_file_path = kTombstoneFolderPath + cur_file_name; - if (stat(cur_file_path.c_str(), &st) == -1) { - PLOG(ERROR) << "Failed to get file stat for " << cur_file_path; - n_error++; - continue; - } - const int fd_read = open(cur_file_path.c_str(), O_RDONLY); - if (fd_read == -1) { - PLOG(ERROR) << "Failed to open file " << cur_file_path; - n_error++; - continue; - } - std::string file_name_with_last_modified_time = - cur_file_name + "-" + std::to_string(st.st_mtime); - // string.size() does not include the null terminator. The cpio FreeBSD - // file header expects the null character to be included in the length. - const size_t file_name_len = - file_name_with_last_modified_time.size() + 1; - unique_fd file_auto_closer(fd_read); - if (!cpioWriteHeader(out_fd, st, - file_name_with_last_modified_time.c_str(), - file_name_len)) { - return ++n_error; - } - size_t write_error = cpioWriteFileContent(fd_read, out_fd, st); - if (write_error) { - return n_error + write_error; - } - } - if (!cpioWriteFileTrailer(out_fd)) { - return ++n_error; - } - return n_error; -} - -// Helper function to create a non-const char*. -std::vector makeCharVec(const std::string& str) { - std::vector vec(str.size() + 1); - vec.assign(str.begin(), str.end()); - vec.push_back('\0'); - return vec; -} - -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using hidl_return_util::validateAndCall; -using hidl_return_util::validateAndCallWithLock; - -WifiChip::WifiChip( - ChipId chip_id, bool is_primary, - const std::weak_ptr legacy_hal, - const std::weak_ptr mode_controller, - const std::shared_ptr iface_util, - const std::weak_ptr feature_flags, - const std::function& handler) - : chip_id_(chip_id), - legacy_hal_(legacy_hal), - mode_controller_(mode_controller), - iface_util_(iface_util), - is_valid_(true), - current_mode_id_(feature_flags::chip_mode_ids::kInvalid), - modes_(feature_flags.lock()->getChipModes(is_primary)), - debug_ring_buffer_cb_registered_(false), - subsystemCallbackHandler_(handler) { - setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue); -} - -void WifiChip::invalidate() { - if (!writeRingbufferFilesInternal()) { - LOG(ERROR) << "Error writing files to flash"; - } - invalidateAndRemoveAllIfaces(); - setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue); - legacy_hal_.reset(); - event_cb_handler_.invalidate(); - is_valid_ = false; -} - -bool WifiChip::isValid() { return is_valid_; } - -std::set> WifiChip::getEventCallbacks() { - return event_cb_handler_.getCallbacks(); -} - -Return WifiChip::getId(getId_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getIdInternal, hidl_status_cb); -} - -// Deprecated support for this callback -Return WifiChip::registerEventCallback( - const sp& event_callback, - registerEventCallback_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::registerEventCallbackInternal, - hidl_status_cb, event_callback); -} - -Return WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getCapabilitiesInternal, hidl_status_cb); -} - -Return WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getAvailableModesInternal, - hidl_status_cb); -} - -Return WifiChip::configureChip(ChipModeId mode_id, - configureChip_cb hidl_status_cb) { - return validateAndCallWithLock( - this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::configureChipInternal, hidl_status_cb, mode_id); -} - -Return WifiChip::getMode(getMode_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getModeInternal, hidl_status_cb); -} - -Return WifiChip::requestChipDebugInfo( - requestChipDebugInfo_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::requestChipDebugInfoInternal, - hidl_status_cb); -} - -Return WifiChip::requestDriverDebugDump( - requestDriverDebugDump_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::requestDriverDebugDumpInternal, - hidl_status_cb); -} - -Return WifiChip::requestFirmwareDebugDump( - requestFirmwareDebugDump_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::requestFirmwareDebugDumpInternal, - hidl_status_cb); -} - -Return WifiChip::createApIface(createApIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createApIfaceInternal, hidl_status_cb); -} - -Return WifiChip::createBridgedApIface( - createBridgedApIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createBridgedApIfaceInternal, - hidl_status_cb); -} - -Return WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getApIfaceNamesInternal, hidl_status_cb); -} - -Return WifiChip::getApIface(const hidl_string& ifname, - getApIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getApIfaceInternal, hidl_status_cb, - ifname); -} - -Return WifiChip::removeApIface(const hidl_string& ifname, - removeApIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeApIfaceInternal, hidl_status_cb, - ifname); -} - -Return WifiChip::removeIfaceInstanceFromBridgedApIface( - const hidl_string& ifname, const hidl_string& ifInstanceName, - removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, - hidl_status_cb, ifname, ifInstanceName); -} - -Return WifiChip::createNanIface(createNanIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createNanIfaceInternal, hidl_status_cb); -} - -Return WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getNanIfaceNamesInternal, hidl_status_cb); -} - -Return WifiChip::getNanIface(const hidl_string& ifname, - getNanIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getNanIfaceInternal, hidl_status_cb, - ifname); -} - -Return WifiChip::removeNanIface(const hidl_string& ifname, - removeNanIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeNanIfaceInternal, hidl_status_cb, - ifname); -} - -Return WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createP2pIfaceInternal, hidl_status_cb); -} - -Return WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb); -} - -Return WifiChip::getP2pIface(const hidl_string& ifname, - getP2pIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getP2pIfaceInternal, hidl_status_cb, - ifname); -} - -Return WifiChip::removeP2pIface(const hidl_string& ifname, - removeP2pIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeP2pIfaceInternal, hidl_status_cb, - ifname); -} - -Return WifiChip::createStaIface(createStaIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createStaIfaceInternal, hidl_status_cb); -} - -Return WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getStaIfaceNamesInternal, hidl_status_cb); -} - -Return WifiChip::getStaIface(const hidl_string& ifname, - getStaIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getStaIfaceInternal, hidl_status_cb, - ifname); -} - -Return WifiChip::removeStaIface(const hidl_string& ifname, - removeStaIface_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::removeStaIfaceInternal, hidl_status_cb, - ifname); -} - -Return WifiChip::createRttController( - const sp& bound_iface, createRttController_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createRttControllerInternal, - hidl_status_cb, bound_iface); -} - -Return WifiChip::getDebugRingBuffersStatus( - getDebugRingBuffersStatus_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getDebugRingBuffersStatusInternal, - hidl_status_cb); -} - -Return WifiChip::startLoggingToDebugRingBuffer( - const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, - uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes, - startLoggingToDebugRingBuffer_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::startLoggingToDebugRingBufferInternal, - hidl_status_cb, ring_name, verbose_level, - max_interval_in_sec, min_data_size_in_bytes); -} - -Return WifiChip::forceDumpToDebugRingBuffer( - const hidl_string& ring_name, - forceDumpToDebugRingBuffer_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::forceDumpToDebugRingBufferInternal, - hidl_status_cb, ring_name); -} - -Return WifiChip::flushRingBufferToFile( - flushRingBufferToFile_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::flushRingBufferToFileInternal, - hidl_status_cb); -} - -Return WifiChip::stopLoggingToDebugRingBuffer( - stopLoggingToDebugRingBuffer_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::stopLoggingToDebugRingBufferInternal, - hidl_status_cb); -} - -Return WifiChip::getDebugHostWakeReasonStats( - getDebugHostWakeReasonStats_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getDebugHostWakeReasonStatsInternal, - hidl_status_cb); -} - -Return WifiChip::enableDebugErrorAlerts( - bool enable, enableDebugErrorAlerts_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::enableDebugErrorAlertsInternal, - hidl_status_cb, enable); -} - -Return WifiChip::selectTxPowerScenario( - V1_1::IWifiChip::TxPowerScenario scenario, - selectTxPowerScenario_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::selectTxPowerScenarioInternal, - hidl_status_cb, scenario); -} - -Return WifiChip::resetTxPowerScenario( - resetTxPowerScenario_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::resetTxPowerScenarioInternal, - hidl_status_cb); -} - -Return WifiChip::setLatencyMode(LatencyMode mode, - setLatencyMode_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::setLatencyModeInternal, hidl_status_cb, - mode); -} - -Return WifiChip::registerEventCallback_1_2( - const sp& event_callback, - registerEventCallback_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::registerEventCallbackInternal_1_2, - hidl_status_cb, event_callback); -} - -Return WifiChip::selectTxPowerScenario_1_2( - TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::selectTxPowerScenarioInternal_1_2, - hidl_status_cb, scenario); -} - -Return WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getCapabilitiesInternal_1_3, - hidl_status_cb); -} - -Return WifiChip::getCapabilities_1_5( - getCapabilities_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getCapabilitiesInternal_1_5, - hidl_status_cb); -} - -Return WifiChip::debug(const hidl_handle& handle, - const hidl_vec&) { - if (handle != nullptr && handle->numFds >= 1) { - { - std::unique_lock lk(lock_t); - for (const auto& item : ringbuffer_map_) { - forceDumpToDebugRingBufferInternal(item.first); - } - // unique_lock unlocked here - } - usleep(100 * 1000); // sleep for 100 milliseconds to wait for - // ringbuffer updates. - int fd = handle->data[0]; - if (!writeRingbufferFilesInternal()) { - LOG(ERROR) << "Error writing files to flash"; - } - uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath); - if (n_error != 0) { - LOG(ERROR) << n_error << " errors occured in cpio function"; - } - fsync(fd); - } else { - LOG(ERROR) << "File handle error"; - } - return Void(); -} - -Return WifiChip::createRttController_1_4( - const sp& bound_iface, - createRttController_1_4_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::createRttControllerInternal_1_4, - hidl_status_cb, bound_iface); -} - -Return WifiChip::registerEventCallback_1_4( - const sp& event_callback, - registerEventCallback_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::registerEventCallbackInternal_1_4, - hidl_status_cb, event_callback); -} - -Return WifiChip::setMultiStaPrimaryConnection( - const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::setMultiStaPrimaryConnectionInternal, - hidl_status_cb, ifname); -} - -Return WifiChip::setMultiStaUseCase( - MultiStaUseCase use_case, setMultiStaUseCase_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::setMultiStaUseCaseInternal, - hidl_status_cb, use_case); -} - -Return WifiChip::setCoexUnsafeChannels( - const hidl_vec& unsafeChannels, - hidl_bitfield restrictions, - setCoexUnsafeChannels_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::setCoexUnsafeChannelsInternal, - hidl_status_cb, unsafeChannels, restrictions); -} - -Return WifiChip::setCountryCode(const hidl_array& code, - setCountryCode_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiChip::setCountryCodeInternal, hidl_status_cb, - code); -} - -Return WifiChip::getUsableChannels( - WifiBand band, hidl_bitfield ifaceModeMask, - hidl_bitfield filterMask, - getUsableChannels_cb _hidl_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::getUsableChannelsInternal, _hidl_cb, band, - ifaceModeMask, filterMask); -} - -Return WifiChip::triggerSubsystemRestart( - triggerSubsystemRestart_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, - &WifiChip::triggerSubsystemRestartInternal, - hidl_status_cb); -} - -void WifiChip::invalidateAndRemoveAllIfaces() { - invalidateAndClearBridgedApAll(); - invalidateAndClearAll(ap_ifaces_); - invalidateAndClearAll(nan_ifaces_); - invalidateAndClearAll(p2p_ifaces_); - invalidateAndClearAll(sta_ifaces_); - // Since all the ifaces are invalid now, all RTT controller objects - // using those ifaces also need to be invalidated. - for (const auto& rtt : rtt_controllers_) { - rtt->invalidate(); - } - rtt_controllers_.clear(); -} - -void WifiChip::invalidateAndRemoveDependencies( - const std::string& removed_iface_name) { - for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) { - auto nan_iface = *it; - if (nan_iface->getName() == removed_iface_name) { - nan_iface->invalidate(); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback - ->onIfaceRemoved(IfaceType::NAN, removed_iface_name) - .isOk()) { - LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; - } - } - it = nan_ifaces_.erase(it); - } else { - ++it; - } - } - - for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) { - auto rtt = *it; - if (rtt->getIfaceName() == removed_iface_name) { - rtt->invalidate(); - it = rtt_controllers_.erase(it); - } else { - ++it; - } - } -} - -std::pair WifiChip::getIdInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_}; -} - -WifiStatus WifiChip::registerEventCallbackInternal( - const sp& /* event_callback */) { - // Deprecated support for this callback. - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -std::pair WifiChip::getCapabilitiesInternal() { - // Deprecated support for this callback. - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0}; -} - -std::pair> -WifiChip::getAvailableModesInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), modes_}; -} - -WifiStatus WifiChip::configureChipInternal( - /* NONNULL */ std::unique_lock* lock, - ChipModeId mode_id) { - if (!isValidModeId(mode_id)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - if (mode_id == current_mode_id_) { - LOG(DEBUG) << "Already in the specified mode " << mode_id; - return createWifiStatus(WifiStatusCode::SUCCESS); - } - WifiStatus status = handleChipConfiguration(lock, mode_id); - if (status.code != WifiStatusCode::SUCCESS) { - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onChipReconfigureFailure(status).isOk()) { - LOG(ERROR) - << "Failed to invoke onChipReconfigureFailure callback"; - } - } - return status; - } - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onChipReconfigured(mode_id).isOk()) { - LOG(ERROR) << "Failed to invoke onChipReconfigured callback"; - } - } - current_mode_id_ = mode_id; - LOG(INFO) << "Configured chip in mode " << mode_id; - setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); - - legacy_hal_.lock()->registerSubsystemRestartCallbackHandler( - subsystemCallbackHandler_); - - return status; -} - -std::pair WifiChip::getModeInternal() { - if (!isValidModeId(current_mode_id_)) { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), - current_mode_id_}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_}; -} - -std::pair -WifiChip::requestChipDebugInfoInternal() { - V1_4::IWifiChip::ChipDebugInfo result; - legacy_hal::wifi_error legacy_status; - std::string driver_desc; - const auto ifname = getFirstActiveWlanIfaceName(); - std::tie(legacy_status, driver_desc) = - legacy_hal_.lock()->getDriverVersion(ifname); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to get driver version: " - << legacyErrorToString(legacy_status); - WifiStatus status = createWifiStatusFromLegacyError( - legacy_status, "failed to get driver version"); - return {status, result}; - } - result.driverDescription = driver_desc.c_str(); - - std::string firmware_desc; - std::tie(legacy_status, firmware_desc) = - legacy_hal_.lock()->getFirmwareVersion(ifname); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to get firmware version: " - << legacyErrorToString(legacy_status); - WifiStatus status = createWifiStatusFromLegacyError( - legacy_status, "failed to get firmware version"); - return {status, result}; - } - result.firmwareDescription = firmware_desc.c_str(); - - return {createWifiStatus(WifiStatusCode::SUCCESS), result}; -} - -std::pair> -WifiChip::requestDriverDebugDumpInternal() { - legacy_hal::wifi_error legacy_status; - std::vector driver_dump; - std::tie(legacy_status, driver_dump) = - legacy_hal_.lock()->requestDriverMemoryDump( - getFirstActiveWlanIfaceName()); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to get driver debug dump: " - << legacyErrorToString(legacy_status); - return {createWifiStatusFromLegacyError(legacy_status), - std::vector()}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump}; -} - -std::pair> -WifiChip::requestFirmwareDebugDumpInternal() { - legacy_hal::wifi_error legacy_status; - std::vector firmware_dump; - std::tie(legacy_status, firmware_dump) = - legacy_hal_.lock()->requestFirmwareMemoryDump( - getFirstActiveWlanIfaceName()); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to get firmware debug dump: " - << legacyErrorToString(legacy_status); - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump}; -} - -WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) { - legacy_hal::wifi_error legacy_status; - legacy_status = legacy_hal_.lock()->createVirtualInterface( - apVirtIf, - hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP)); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to add interface: " << apVirtIf << " " - << legacyErrorToString(legacy_status); - return createWifiStatusFromLegacyError(legacy_status); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -sp WifiChip::newWifiApIface(std::string& ifname) { - std::vector ap_instances; - for (auto const& it : br_ifaces_ap_instances_) { - if (it.first == ifname) { - ap_instances = it.second; - } - } - sp iface = - new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_); - ap_ifaces_.push_back(iface); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) { - LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; - } - } - setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); - return iface; -} - -std::pair> -WifiChip::createApIfaceInternal() { - if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - std::string ifname = allocateApIfaceName(); - WifiStatus status = createVirtualApInterface(ifname); - if (status.code != WifiStatusCode::SUCCESS) { - return {status, {}}; - } - sp iface = newWifiApIface(ifname); - return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; -} - -std::pair> -WifiChip::createBridgedApIfaceInternal() { - if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - std::vector ap_instances = allocateBridgedApInstanceNames(); - if (ap_instances.size() < 2) { - LOG(ERROR) << "Fail to allocate two instances"; - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0]; - for (int i = 0; i < 2; i++) { - WifiStatus status = createVirtualApInterface(ap_instances[i]); - if (status.code != WifiStatusCode::SUCCESS) { - if (i != 0) { // The failure happened when creating second virtual - // iface. - legacy_hal_.lock()->deleteVirtualInterface( - ap_instances.front()); // Remove the first virtual iface. - } - return {status, {}}; - } - } - br_ifaces_ap_instances_[br_ifname] = ap_instances; - if (!iface_util_->createBridge(br_ifname)) { - LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str(); - invalidateAndClearBridgedAp(br_ifname); - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - for (auto const& instance : ap_instances) { - // Bind ap instance interface to AP bridge - if (!iface_util_->addIfaceToBridge(br_ifname, instance)) { - LOG(ERROR) << "Failed add if to Bridge - if_name=" - << instance.c_str(); - invalidateAndClearBridgedAp(br_ifname); - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - } - sp iface = newWifiApIface(br_ifname); - return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; -} - -std::pair> -WifiChip::getApIfaceNamesInternal() { - if (ap_ifaces_.empty()) { - return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)}; -} - -std::pair> WifiChip::getApIfaceInternal( - const std::string& ifname) { - const auto iface = findUsingName(ap_ifaces_, ifname); - if (!iface.get()) { - return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; -} - -WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { - const auto iface = findUsingName(ap_ifaces_, ifname); - if (!iface.get()) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - // Invalidate & remove any dependent objects first. - // Note: This is probably not required because we never create - // nan/rtt objects over AP iface. But, there is no harm to do it - // here and not make that assumption all over the place. - invalidateAndRemoveDependencies(ifname); - // Clear the bridge interface and the iface instance. - invalidateAndClearBridgedAp(ifname); - invalidateAndClear(ap_ifaces_, iface); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) { - LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; - } - } - setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( - const std::string& ifname, const std::string& ifInstanceName) { - const auto iface = findUsingName(ap_ifaces_, ifname); - if (!iface.get() || ifInstanceName.empty()) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - // Requires to remove one of the instance in bridge mode - for (auto const& it : br_ifaces_ap_instances_) { - if (it.first == ifname) { - std::vector ap_instances = it.second; - for (auto const& iface : ap_instances) { - if (iface == ifInstanceName) { - if (!iface_util_->removeIfaceFromBridge(it.first, iface)) { - LOG(ERROR) - << "Failed to remove interface: " << ifInstanceName - << " from " << ifname; - return createWifiStatus( - WifiStatusCode::ERROR_NOT_AVAILABLE); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->deleteVirtualInterface(iface); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to del interface: " << iface - << " " << legacyErrorToString(legacy_status); - return createWifiStatusFromLegacyError(legacy_status); - } - ap_instances.erase( - std::remove(ap_instances.begin(), ap_instances.end(), - ifInstanceName), - ap_instances.end()); - br_ifaces_ap_instances_[ifname] = ap_instances; - break; - } - } - break; - } - } - iface->removeInstance(ifInstanceName); - setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); - - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -std::pair> -WifiChip::createNanIfaceInternal() { - if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - bool is_dedicated_iface = true; - std::string ifname = getPredefinedNanIfaceName(); - if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) { - // Use the first shared STA iface (wlan0) if a dedicated aware iface is - // not defined. - ifname = getFirstActiveWlanIfaceName(); - is_dedicated_iface = false; - } - sp iface = - new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_); - nan_ifaces_.push_back(iface); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) { - LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; - } - } - return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; -} - -std::pair> -WifiChip::getNanIfaceNamesInternal() { - if (nan_ifaces_.empty()) { - return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)}; -} - -std::pair> WifiChip::getNanIfaceInternal( - const std::string& ifname) { - const auto iface = findUsingName(nan_ifaces_, ifname); - if (!iface.get()) { - return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; -} - -WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) { - const auto iface = findUsingName(nan_ifaces_, ifname); - if (!iface.get()) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - invalidateAndClear(nan_ifaces_, iface); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) { - LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; - } - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -std::pair> WifiChip::createP2pIfaceInternal() { - if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - std::string ifname = getPredefinedP2pIfaceName(); - sp iface = new WifiP2pIface(ifname, legacy_hal_); - p2p_ifaces_.push_back(iface); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) { - LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; - } - } - return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; -} - -std::pair> -WifiChip::getP2pIfaceNamesInternal() { - if (p2p_ifaces_.empty()) { - return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)}; -} - -std::pair> WifiChip::getP2pIfaceInternal( - const std::string& ifname) { - const auto iface = findUsingName(p2p_ifaces_, ifname); - if (!iface.get()) { - return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; -} - -WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) { - const auto iface = findUsingName(p2p_ifaces_, ifname); - if (!iface.get()) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - invalidateAndClear(p2p_ifaces_, iface); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) { - LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; - } - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -std::pair> -WifiChip::createStaIfaceInternal() { - if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - std::string ifname = allocateStaIfaceName(); - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->createVirtualInterface( - ifname, - hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA)); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to add interface: " << ifname << " " - << legacyErrorToString(legacy_status); - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - sp iface = new WifiStaIface(ifname, legacy_hal_, iface_util_); - sta_ifaces_.push_back(iface); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) { - LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; - } - } - setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); - return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; -} - -std::pair> -WifiChip::getStaIfaceNamesInternal() { - if (sta_ifaces_.empty()) { - return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)}; -} - -std::pair> WifiChip::getStaIfaceInternal( - const std::string& ifname) { - const auto iface = findUsingName(sta_ifaces_, ifname); - if (!iface.get()) { - return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; -} - -WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) { - const auto iface = findUsingName(sta_ifaces_, ifname); - if (!iface.get()) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - // Invalidate & remove any dependent objects first. - invalidateAndRemoveDependencies(ifname); - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->deleteVirtualInterface(ifname); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to remove interface: " << ifname << " " - << legacyErrorToString(legacy_status); - } - invalidateAndClear(sta_ifaces_, iface); - for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) { - LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; - } - } - setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -std::pair> -WifiChip::createRttControllerInternal(const sp& /*bound_iface*/) { - LOG(ERROR) << "createRttController is not supported on this HAL"; - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; -} - -std::pair> -WifiChip::getDebugRingBuffersStatusInternal() { - legacy_hal::wifi_error legacy_status; - std::vector - legacy_ring_buffer_status_vec; - std::tie(legacy_status, legacy_ring_buffer_status_vec) = - legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName()); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - std::vector hidl_ring_buffer_status_vec; - if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl( - legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), - hidl_ring_buffer_status_vec}; -} - -WifiStatus WifiChip::startLoggingToDebugRingBufferInternal( - const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, - uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) { - WifiStatus status = registerDebugRingBufferCallback(); - if (status.code != WifiStatusCode::SUCCESS) { - return status; - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startRingBufferLogging( - getFirstActiveWlanIfaceName(), ring_name, - static_cast< - std::underlying_type::type>( - verbose_level), - max_interval_in_sec, min_data_size_in_bytes); - ringbuffer_map_.insert(std::pair( - ring_name, Ringbuffer(kMaxBufferSizeBytes))); - // if verbose logging enabled, turn up HAL daemon logging as well. - if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) { - android::base::SetMinimumLogSeverity(android::base::DEBUG); - } else { - android::base::SetMinimumLogSeverity(android::base::VERBOSE); - } - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::forceDumpToDebugRingBufferInternal( - const hidl_string& ring_name) { - WifiStatus status = registerDebugRingBufferCallback(); - if (status.code != WifiStatusCode::SUCCESS) { - return status; - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), - ring_name); - - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::flushRingBufferToFileInternal() { - if (!writeRingbufferFilesInternal()) { - LOG(ERROR) << "Error writing files to flash"; - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->deregisterRingBufferCallbackHandler( - getFirstActiveWlanIfaceName()); - if (legacy_status == legacy_hal::WIFI_SUCCESS) { - debug_ring_buffer_cb_registered_ = false; - } - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair -WifiChip::getDebugHostWakeReasonStatsInternal() { - legacy_hal::wifi_error legacy_status; - legacy_hal::WakeReasonStats legacy_stats; - std::tie(legacy_status, legacy_stats) = - legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName()); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - WifiDebugHostWakeReasonStats hidl_stats; - if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, - &hidl_stats)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats}; -} - -WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) { - legacy_hal::wifi_error legacy_status; - if (enable) { - android::wp weak_ptr_this(this); - const auto& on_alert_callback = [weak_ptr_this]( - int32_t error_code, - std::vector debug_data) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onDebugErrorAlert(error_code, debug_data) - .isOk()) { - LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback"; - } - } - }; - legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler( - getFirstActiveWlanIfaceName(), on_alert_callback); - } else { - legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler( - getFirstActiveWlanIfaceName()); - } - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::selectTxPowerScenarioInternal( - V1_1::IWifiChip::TxPowerScenario scenario) { - auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( - getFirstActiveWlanIfaceName(), - hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario)); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::resetTxPowerScenarioInternal() { - auto legacy_status = - legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName()); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) { - auto legacy_status = legacy_hal_.lock()->setLatencyMode( - getFirstActiveWlanIfaceName(), - hidl_struct_util::convertHidlLatencyModeToLegacy(mode)); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::registerEventCallbackInternal_1_2( - const sp& /* event_callback */) { - // Deprecated support for this callback. - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2( - TxPowerScenario scenario) { - auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( - getFirstActiveWlanIfaceName(), - hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario)); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair WifiChip::getCapabilitiesInternal_1_3() { - // Deprecated support for this callback. - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0}; -} - -std::pair WifiChip::getCapabilitiesInternal_1_5() { - legacy_hal::wifi_error legacy_status; - uint64_t legacy_feature_set; - uint32_t legacy_logger_feature_set; - const auto ifname = getFirstActiveWlanIfaceName(); - std::tie(legacy_status, legacy_feature_set) = - 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(ifname); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - // some devices don't support querying logger feature set - legacy_logger_feature_set = 0; - } - uint32_t hidl_caps; - if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities( - legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; -} - -std::pair> -WifiChip::createRttControllerInternal_1_4(const sp& bound_iface) { - if (sta_ifaces_.size() == 0 && - !canCurrentModeSupportIfaceOfType(IfaceType::STA)) { - LOG(ERROR) - << "createRttControllerInternal_1_4: Chip cannot support STAs " - "(and RTT by extension)"; - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - sp rtt = new WifiRttController( - getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_); - rtt_controllers_.emplace_back(rtt); - return {createWifiStatus(WifiStatusCode::SUCCESS), rtt}; -} - -WifiStatus WifiChip::registerEventCallbackInternal_1_4( - const sp& event_callback) { - if (!event_cb_handler_.addCallback(event_callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal( - const std::string& ifname) { - auto legacy_status = - legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) { - auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase( - hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case)); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::setCoexUnsafeChannelsInternal( - std::vector unsafe_channels, uint32_t restrictions) { - std::vector legacy_unsafe_channels; - if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy( - unsafe_channels, &legacy_unsafe_channels)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - uint32_t legacy_restrictions = 0; - if (restrictions & CoexRestriction::WIFI_DIRECT) { - legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT; - } - if (restrictions & CoexRestriction::SOFTAP) { - legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP; - } - if (restrictions & CoexRestriction::WIFI_AWARE) { - legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE; - } - auto legacy_status = legacy_hal_.lock()->setCoexUnsafeChannels( - legacy_unsafe_channels, legacy_restrictions); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::setCountryCodeInternal(const std::array& code) { - auto legacy_status = - legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair> -WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask, - uint32_t filterMask) { - legacy_hal::wifi_error legacy_status; - std::vector legacy_usable_channels; - std::tie(legacy_status, legacy_usable_channels) = - legacy_hal_.lock()->getUsableChannels( - hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band), - hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask), - hidl_struct_util::convertHidlUsableChannelFilterToLegacy( - filterMask)); - - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - std::vector hidl_usable_channels; - if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl( - legacy_usable_channels, &hidl_usable_channels)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels}; -} - -WifiStatus WifiChip::triggerSubsystemRestartInternal() { - auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart(); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::handleChipConfiguration( - /* NONNULL */ std::unique_lock* lock, - ChipModeId mode_id) { - // If the chip is already configured in a different mode, stop - // the legacy HAL and then start it after firmware mode change. - if (isValidModeId(current_mode_id_)) { - LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ - << " to mode " << mode_id; - invalidateAndRemoveAllIfaces(); - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->stop(lock, []() {}); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to stop legacy HAL: " - << legacyErrorToString(legacy_status); - return createWifiStatusFromLegacyError(legacy_status); - } - } - // Firmware mode change not needed for V2 devices. - bool success = true; - if (mode_id == feature_flags::chip_mode_ids::kV1Sta) { - success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA); - } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) { - success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP); - } - if (!success) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start(); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to start legacy HAL: " - << legacyErrorToString(legacy_status); - return createWifiStatusFromLegacyError(legacy_status); - } - // Every time the HAL is restarted, we need to register the - // radio mode change callback. - WifiStatus status = registerRadioModeChangeCallback(); - if (status.code != WifiStatusCode::SUCCESS) { - // This probably is not a critical failure? - LOG(ERROR) << "Failed to register radio mode change callback"; - } - // Extract and save the version information into property. - std::pair version_info; - version_info = WifiChip::requestChipDebugInfoInternal(); - if (WifiStatusCode::SUCCESS == version_info.first.code) { - property_set("vendor.wlan.firmware.version", - version_info.second.firmwareDescription.c_str()); - property_set("vendor.wlan.driver.version", - version_info.second.driverDescription.c_str()); - } - - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiChip::registerDebugRingBufferCallback() { - if (debug_ring_buffer_cb_registered_) { - return createWifiStatus(WifiStatusCode::SUCCESS); - } - - android::wp weak_ptr_this(this); - const auto& on_ring_buffer_data_callback = - [weak_ptr_this](const std::string& name, - const std::vector& data, - const legacy_hal::wifi_ring_buffer_status& status) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiDebugRingBufferStatus hidl_status; - if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl( - status, &hidl_status)) { - LOG(ERROR) << "Error converting ring buffer status"; - return; - } - { - std::unique_lock lk(shared_ptr_this->lock_t); - const auto& target = - shared_ptr_this->ringbuffer_map_.find(name); - if (target != shared_ptr_this->ringbuffer_map_.end()) { - Ringbuffer& cur_buffer = target->second; - cur_buffer.append(data); - } else { - LOG(ERROR) << "Ringname " << name << " not found"; - return; - } - // unique_lock unlocked here - } - }; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->registerRingBufferCallbackHandler( - getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback); - - if (legacy_status == legacy_hal::WIFI_SUCCESS) { - debug_ring_buffer_cb_registered_ = true; - } - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiChip::registerRadioModeChangeCallback() { - android::wp weak_ptr_this(this); - const auto& on_radio_mode_change_callback = - [weak_ptr_this](const std::vector& mac_infos) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - std::vector - hidl_radio_mode_infos; - if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl( - mac_infos, &hidl_radio_mode_infos)) { - LOG(ERROR) << "Error converting wifi mac info"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos) - .isOk()) { - LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4" - << " callback on: " << toString(callback); - } - } - }; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->registerRadioModeChangeCallbackHandler( - getFirstActiveWlanIfaceName(), on_radio_mode_change_callback); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::vector -WifiChip::getCurrentModeIfaceCombinations() { - if (!isValidModeId(current_mode_id_)) { - LOG(ERROR) << "Chip not configured in a mode yet"; - return {}; - } - for (const auto& mode : modes_) { - if (mode.id == current_mode_id_) { - return mode.availableCombinations; - } - } - CHECK(0) << "Expected to find iface combinations for current mode!"; - return {}; -} - -// Returns a map indexed by IfaceType with the number of ifaces currently -// created of the corresponding type. -std::map WifiChip::getCurrentIfaceCombination() { - std::map iface_counts; - iface_counts[IfaceType::AP] = ap_ifaces_.size(); - iface_counts[IfaceType::NAN] = nan_ifaces_.size(); - iface_counts[IfaceType::P2P] = p2p_ifaces_.size(); - iface_counts[IfaceType::STA] = sta_ifaces_.size(); - return iface_counts; -} - -// This expands the provided iface combinations to a more parseable -// form. Returns a vector of available combinations possible with the number -// of ifaces of each type in the combination. -// This method is a port of HalDeviceManager.expandIfaceCombos() from framework. -std::vector> WifiChip::expandIfaceCombinations( - const V1_4::IWifiChip::ChipIfaceCombination& combination) { - uint32_t num_expanded_combos = 1; - for (const auto& limit : combination.limits) { - for (uint32_t i = 0; i < limit.maxIfaces; i++) { - num_expanded_combos *= limit.types.size(); - } - } - - // Allocate the vector of expanded combos and reset all iface counts to 0 - // in each combo. - std::vector> expanded_combos; - expanded_combos.resize(num_expanded_combos); - for (auto& expanded_combo : expanded_combos) { - for (const auto type : - {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { - expanded_combo[type] = 0; - } - } - uint32_t span = num_expanded_combos; - for (const auto& limit : combination.limits) { - for (uint32_t i = 0; i < limit.maxIfaces; i++) { - span /= limit.types.size(); - for (uint32_t k = 0; k < num_expanded_combos; ++k) { - const auto iface_type = - limit.types[(k / span) % limit.types.size()]; - expanded_combos[k][iface_type]++; - } - } - } - return expanded_combos; -} - -bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( - const std::map& expanded_combo, - IfaceType requested_type) { - const auto current_combo = getCurrentIfaceCombination(); - - // Check if we have space for 1 more iface of |type| in this combo - for (const auto type : - {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { - size_t num_ifaces_needed = current_combo.at(type); - if (type == requested_type) { - num_ifaces_needed++; - } - size_t num_ifaces_allowed = expanded_combo.at(type); - if (num_ifaces_needed > num_ifaces_allowed) { - return false; - } - } - return true; -} - -// This method does the following: -// a) Enumerate all possible iface combos by expanding the current -// ChipIfaceCombination. -// b) Check if the requested iface type can be added to the current mode -// with the iface combination that is already active. -bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces( - IfaceType requested_type) { - if (!isValidModeId(current_mode_id_)) { - LOG(ERROR) << "Chip not configured in a mode yet"; - return false; - } - const auto combinations = getCurrentModeIfaceCombinations(); - for (const auto& combination : combinations) { - const auto expanded_combos = expandIfaceCombinations(combination); - for (const auto& expanded_combo : expanded_combos) { - if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( - expanded_combo, requested_type)) { - return true; - } - } - } - return false; -} - -// Note: This does not consider ifaces already active. It only checks if the -// provided expanded iface combination can support the requested combo. -bool WifiChip::canExpandedIfaceComboSupportIfaceCombo( - const std::map& expanded_combo, - const std::map& req_combo) { - // Check if we have space for 1 more iface of |type| in this combo - for (const auto type : - {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { - if (req_combo.count(type) == 0) { - // Iface of "type" not in the req_combo. - continue; - } - size_t num_ifaces_needed = req_combo.at(type); - size_t num_ifaces_allowed = expanded_combo.at(type); - if (num_ifaces_needed > num_ifaces_allowed) { - return false; - } - } - return true; -} -// This method does the following: -// a) Enumerate all possible iface combos by expanding the current -// ChipIfaceCombination. -// b) Check if the requested iface combo can be added to the current mode. -// Note: This does not consider ifaces already active. It only checks if the -// current mode can support the requested combo. -bool WifiChip::canCurrentModeSupportIfaceCombo( - const std::map& req_combo) { - if (!isValidModeId(current_mode_id_)) { - LOG(ERROR) << "Chip not configured in a mode yet"; - return false; - } - const auto combinations = getCurrentModeIfaceCombinations(); - for (const auto& combination : combinations) { - const auto expanded_combos = expandIfaceCombinations(combination); - for (const auto& expanded_combo : expanded_combos) { - if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo, - req_combo)) { - return true; - } - } - } - return false; -} - -// This method does the following: -// a) Enumerate all possible iface combos by expanding the current -// ChipIfaceCombination. -// b) Check if the requested iface type can be added to the current mode. -bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) { - // Check if we can support at least 1 iface of type. - std::map req_iface_combo; - req_iface_combo[requested_type] = 1; - return canCurrentModeSupportIfaceCombo(req_iface_combo); -} - -bool WifiChip::isValidModeId(ChipModeId mode_id) { - for (const auto& mode : modes_) { - if (mode.id == mode_id) { - return true; - } - } - return false; -} - -bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() { - // Check if we can support at least 1 STA & 1 AP concurrently. - std::map req_iface_combo; - req_iface_combo[IfaceType::AP] = 1; - req_iface_combo[IfaceType::STA] = 1; - return canCurrentModeSupportIfaceCombo(req_iface_combo); -} - -bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() { - // Check if we can support at least 2 STA concurrently. - std::map req_iface_combo; - req_iface_combo[IfaceType::STA] = 2; - return canCurrentModeSupportIfaceCombo(req_iface_combo); -} - -std::string WifiChip::getFirstActiveWlanIfaceName() { - if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName(); - if (ap_ifaces_.size() > 0) { - // If the first active wlan iface is bridged iface. - // Return first instance name. - for (auto const& it : br_ifaces_ap_instances_) { - if (it.first == ap_ifaces_[0]->getName()) { - return it.second[0]; - } - } - return ap_ifaces_[0]->getName(); - } - // This could happen if the chip call is made before any STA/AP - // iface is created. Default to wlan0 for such cases. - LOG(WARNING) << "No active wlan interfaces in use! Using default"; - return getWlanIfaceNameWithType(IfaceType::STA, 0); -} - -// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx| -// not already in use. -// Note: This doesn't check the actual presence of these interfaces. -std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, - uint32_t start_idx) { - for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) { - const auto ifname = getWlanIfaceNameWithType(type, idx); - if (findUsingNameFromBridgedApInstances(ifname)) continue; - 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(false) << "All wlan interfaces in use already!"; - return {}; -} - -uint32_t WifiChip::startIdxOfApIface() { - if (isDualStaConcurrencyAllowedInCurrentMode()) { - // When the HAL support dual STAs, AP should start with idx 2. - return 2; - } else if (isStaApConcurrencyAllowedInCurrentMode()) { - // When the HAL support STA + AP but it doesn't support dual STAs. - // AP should start with idx 1. - return 1; - } - // No concurrency support. - return 0; -} - -// AP iface names start with idx 1 for modes supporting -// concurrent STA and not dual AP, else start with idx 0. -std::string WifiChip::allocateApIfaceName() { - // Check if we have a dedicated iface for AP. - std::vector ifnames = getPredefinedApIfaceNames(false); - if (!ifnames.empty()) { - return ifnames[0]; - } - return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface()); -} - -std::vector WifiChip::allocateBridgedApInstanceNames() { - // Check if we have a dedicated iface for AP. - std::vector instances = getPredefinedApIfaceNames(true); - if (instances.size() == 2) { - return instances; - } else { - int num_ifaces_need_to_allocate = 2 - instances.size(); - for (int i = 0; i < num_ifaces_need_to_allocate; i++) { - std::string instance_name = allocateApOrStaIfaceName( - IfaceType::AP, startIdxOfApIface() + i); - if (!instance_name.empty()) { - instances.push_back(instance_name); - } - } - } - return instances; -} - -// STA iface names start with idx 0. -// Primary STA iface will always be 0. -std::string WifiChip::allocateStaIfaceName() { - return allocateApOrStaIfaceName(IfaceType::STA, 0); -} - -bool WifiChip::writeRingbufferFilesInternal() { - if (!removeOldFilesInternal()) { - LOG(ERROR) << "Error occurred while deleting old tombstone files"; - return false; - } - // write ringbuffers to file - { - std::unique_lock lk(lock_t); - for (auto& item : ringbuffer_map_) { - Ringbuffer& cur_buffer = item.second; - if (cur_buffer.getData().empty()) { - continue; - } - const std::string file_path_raw = - kTombstoneFolderPath + item.first + "XXXXXXXXXX"; - const int dump_fd = mkstemp(makeCharVec(file_path_raw).data()); - if (dump_fd == -1) { - PLOG(ERROR) << "create file failed"; - return false; - } - unique_fd file_auto_closer(dump_fd); - for (const auto& cur_block : cur_buffer.getData()) { - if (write(dump_fd, cur_block.data(), - sizeof(cur_block[0]) * cur_block.size()) == -1) { - PLOG(ERROR) << "Error writing to file"; - } - } - cur_buffer.clear(); - } - // unique_lock unlocked here - } - return true; -} - -std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) { - std::string ifname; - - // let the legacy hal override the interface name - legacy_hal::wifi_error err = - legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname); - if (err == legacy_hal::WIFI_SUCCESS) return ifname; - - return getWlanIfaceName(idx); -} - -void WifiChip::invalidateAndClearBridgedApAll() { - for (auto const& it : br_ifaces_ap_instances_) { - for (auto const& iface : it.second) { - iface_util_->removeIfaceFromBridge(it.first, iface); - legacy_hal_.lock()->deleteVirtualInterface(iface); - } - iface_util_->deleteBridge(it.first); - } - br_ifaces_ap_instances_.clear(); -} - -void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) { - if (br_name.empty()) return; - // delete managed interfaces - for (auto const& it : br_ifaces_ap_instances_) { - if (it.first == br_name) { - for (auto const& iface : it.second) { - iface_util_->removeIfaceFromBridge(br_name, iface); - legacy_hal_.lock()->deleteVirtualInterface(iface); - } - iface_util_->deleteBridge(br_name); - br_ifaces_ap_instances_.erase(br_name); - break; - } - } - return; -} - -bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) { - for (auto const& it : br_ifaces_ap_instances_) { - if (it.first == name) { - return true; - } - for (auto const& iface : it.second) { - if (iface == name) { - return true; - } - } - } - return false; -} - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h deleted file mode 100644 index bd40ead35a..0000000000 --- a/wifi/1.5/default/wifi_chip.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_CHIP_H_ -#define WIFI_CHIP_H_ - -#include -#include -#include - -#include -#include -#include - -#include "hidl_callback_util.h" -#include "ringbuffer.h" -#include "wifi_ap_iface.h" -#include "wifi_feature_flags.h" -#include "wifi_legacy_hal.h" -#include "wifi_mode_controller.h" -#include "wifi_nan_iface.h" -#include "wifi_p2p_iface.h" -#include "wifi_rtt_controller.h" -#include "wifi_sta_iface.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; - -/** - * HIDL interface object used to control a Wifi HAL chip instance. - * Since there is only a single chip instance used today, there is no - * identifying handle information stored here. - */ -class WifiChip : public V1_5::IWifiChip { - public: - WifiChip(ChipId chip_id, bool is_primary, - const std::weak_ptr legacy_hal, - const std::weak_ptr - mode_controller, - const std::shared_ptr iface_util, - const std::weak_ptr feature_flags, - const std::function& - subsystemCallbackHandler); - // HIDL does not provide a built-in mechanism to let the server invalidate - // a HIDL interface object after creation. If any client process holds onto - // a reference to the object in their context, any method calls on that - // reference will continue to be directed to the server. - // - // However Wifi HAL needs to control the lifetime of these objects. So, add - // a public |invalidate| method to |WifiChip| and it's child objects. This - // will be used to mark an object invalid when either: - // a) Wifi HAL is stopped, or - // b) Wifi Chip is reconfigured. - // - // All HIDL method implementations should check if the object is still - // marked valid before processing them. - void invalidate(); - bool isValid(); - std::set> getEventCallbacks(); - - // HIDL methods exposed. - Return getId(getId_cb hidl_status_cb) override; - // Deprecated support for this callback - Return registerEventCallback( - const sp& event_callback, - registerEventCallback_cb hidl_status_cb) override; - Return getCapabilities(getCapabilities_cb hidl_status_cb) override; - Return getAvailableModes( - getAvailableModes_cb hidl_status_cb) override; - Return configureChip(ChipModeId mode_id, - configureChip_cb hidl_status_cb) override; - Return getMode(getMode_cb hidl_status_cb) override; - Return requestChipDebugInfo( - requestChipDebugInfo_cb hidl_status_cb) override; - Return requestDriverDebugDump( - requestDriverDebugDump_cb hidl_status_cb) override; - Return requestFirmwareDebugDump( - requestFirmwareDebugDump_cb hidl_status_cb) override; - Return createApIface(createApIface_cb hidl_status_cb) override; - Return createBridgedApIface( - createBridgedApIface_cb hidl_status_cb) override; - Return getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override; - Return getApIface(const hidl_string& ifname, - getApIface_cb hidl_status_cb) override; - Return removeApIface(const hidl_string& ifname, - removeApIface_cb hidl_status_cb) override; - Return removeIfaceInstanceFromBridgedApIface( - const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName, - removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override; - Return createNanIface(createNanIface_cb hidl_status_cb) override; - Return getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override; - Return getNanIface(const hidl_string& ifname, - getNanIface_cb hidl_status_cb) override; - Return removeNanIface(const hidl_string& ifname, - removeNanIface_cb hidl_status_cb) override; - Return createP2pIface(createP2pIface_cb hidl_status_cb) override; - Return getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) override; - Return getP2pIface(const hidl_string& ifname, - getP2pIface_cb hidl_status_cb) override; - Return removeP2pIface(const hidl_string& ifname, - removeP2pIface_cb hidl_status_cb) override; - Return createStaIface(createStaIface_cb hidl_status_cb) override; - Return getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) override; - Return getStaIface(const hidl_string& ifname, - getStaIface_cb hidl_status_cb) override; - Return removeStaIface(const hidl_string& ifname, - removeStaIface_cb hidl_status_cb) override; - Return createRttController( - const sp& bound_iface, - createRttController_cb hidl_status_cb) override; - Return getDebugRingBuffersStatus( - getDebugRingBuffersStatus_cb hidl_status_cb) override; - Return startLoggingToDebugRingBuffer( - const hidl_string& ring_name, - WifiDebugRingBufferVerboseLevel verbose_level, - uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes, - startLoggingToDebugRingBuffer_cb hidl_status_cb) override; - Return forceDumpToDebugRingBuffer( - const hidl_string& ring_name, - forceDumpToDebugRingBuffer_cb hidl_status_cb) override; - Return flushRingBufferToFile( - flushRingBufferToFile_cb hidl_status_cb) override; - Return stopLoggingToDebugRingBuffer( - stopLoggingToDebugRingBuffer_cb hidl_status_cb) override; - Return getDebugHostWakeReasonStats( - getDebugHostWakeReasonStats_cb hidl_status_cb) override; - Return enableDebugErrorAlerts( - bool enable, enableDebugErrorAlerts_cb hidl_status_cb) override; - Return selectTxPowerScenario( - V1_1::IWifiChip::TxPowerScenario scenario, - selectTxPowerScenario_cb hidl_status_cb) override; - Return resetTxPowerScenario( - resetTxPowerScenario_cb hidl_status_cb) override; - Return setLatencyMode(LatencyMode mode, - setLatencyMode_cb hidl_status_cb) override; - Return registerEventCallback_1_2( - const sp& event_callback, - registerEventCallback_1_2_cb hidl_status_cb) override; - Return selectTxPowerScenario_1_2( - TxPowerScenario scenario, - selectTxPowerScenario_cb hidl_status_cb) override; - Return getCapabilities_1_3( - getCapabilities_cb hidl_status_cb) override; - Return getCapabilities_1_5( - getCapabilities_1_5_cb hidl_status_cb) override; - Return debug(const hidl_handle& handle, - const hidl_vec& options) override; - Return createRttController_1_4( - const sp& bound_iface, - createRttController_1_4_cb hidl_status_cb) override; - Return registerEventCallback_1_4( - const sp& event_callback, - registerEventCallback_1_4_cb hidl_status_cb) override; - Return setMultiStaPrimaryConnection( - const hidl_string& ifname, - setMultiStaPrimaryConnection_cb hidl_status_cb) override; - Return setMultiStaUseCase( - MultiStaUseCase use_case, - setMultiStaUseCase_cb hidl_status_cb) override; - Return setCoexUnsafeChannels( - const hidl_vec& unsafe_channels, - hidl_bitfield restrictions, - setCoexUnsafeChannels_cb hidl_status_cb) override; - Return setCountryCode(const hidl_array& code, - setCountryCode_cb _hidl_cb) override; - Return getUsableChannels( - WifiBand band, hidl_bitfield ifaceModeMask, - hidl_bitfield filterMask, - getUsableChannels_cb _hidl_cb) override; - Return triggerSubsystemRestart( - triggerSubsystemRestart_cb hidl_status_cb) override; - - private: - void invalidateAndRemoveAllIfaces(); - // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are - // invalidated & removed. - void invalidateAndRemoveDependencies(const std::string& removed_iface_name); - - // Corresponding worker functions for the HIDL methods. - std::pair getIdInternal(); - // Deprecated support for this callback - WifiStatus registerEventCallbackInternal( - const sp& event_callback); - std::pair getCapabilitiesInternal(); - std::pair> getAvailableModesInternal(); - WifiStatus configureChipInternal( - std::unique_lock* lock, ChipModeId mode_id); - std::pair getModeInternal(); - std::pair - requestChipDebugInfoInternal(); - std::pair> - requestDriverDebugDumpInternal(); - std::pair> - requestFirmwareDebugDumpInternal(); - sp newWifiApIface(std::string& ifname); - WifiStatus createVirtualApInterface(const std::string& apVirtIf); - std::pair> createApIfaceInternal(); - std::pair> - createBridgedApIfaceInternal(); - std::pair> getApIfaceNamesInternal(); - std::pair> getApIfaceInternal( - const std::string& ifname); - WifiStatus removeApIfaceInternal(const std::string& ifname); - WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal( - const std::string& brIfaceName, const std::string& ifInstanceName); - std::pair> createNanIfaceInternal(); - std::pair> getNanIfaceNamesInternal(); - std::pair> getNanIfaceInternal( - const std::string& ifname); - WifiStatus removeNanIfaceInternal(const std::string& ifname); - std::pair> createP2pIfaceInternal(); - std::pair> getP2pIfaceNamesInternal(); - std::pair> getP2pIfaceInternal( - const std::string& ifname); - WifiStatus removeP2pIfaceInternal(const std::string& ifname); - std::pair> createStaIfaceInternal(); - std::pair> getStaIfaceNamesInternal(); - std::pair> getStaIfaceInternal( - const std::string& ifname); - WifiStatus removeStaIfaceInternal(const std::string& ifname); - std::pair> - createRttControllerInternal(const sp& bound_iface); - std::pair> - getDebugRingBuffersStatusInternal(); - WifiStatus startLoggingToDebugRingBufferInternal( - const hidl_string& ring_name, - WifiDebugRingBufferVerboseLevel verbose_level, - uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes); - WifiStatus forceDumpToDebugRingBufferInternal(const hidl_string& ring_name); - WifiStatus flushRingBufferToFileInternal(); - WifiStatus stopLoggingToDebugRingBufferInternal(); - std::pair - getDebugHostWakeReasonStatsInternal(); - WifiStatus enableDebugErrorAlertsInternal(bool enable); - WifiStatus selectTxPowerScenarioInternal( - V1_1::IWifiChip::TxPowerScenario scenario); - WifiStatus resetTxPowerScenarioInternal(); - WifiStatus setLatencyModeInternal(LatencyMode mode); - WifiStatus registerEventCallbackInternal_1_2( - const sp& event_callback); - WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario); - std::pair getCapabilitiesInternal_1_3(); - std::pair getCapabilitiesInternal_1_5(); - std::pair> - createRttControllerInternal_1_4(const sp& bound_iface); - WifiStatus registerEventCallbackInternal_1_4( - const sp& event_callback); - WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname); - WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case); - WifiStatus setCoexUnsafeChannelsInternal( - std::vector unsafe_channels, uint32_t restrictions); - WifiStatus setCountryCodeInternal(const std::array& code); - std::pair> - getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask, - uint32_t filterMask); - WifiStatus handleChipConfiguration( - std::unique_lock* lock, ChipModeId mode_id); - WifiStatus registerDebugRingBufferCallback(); - WifiStatus registerRadioModeChangeCallback(); - - std::vector - getCurrentModeIfaceCombinations(); - std::map getCurrentIfaceCombination(); - std::vector> expandIfaceCombinations( - const V1_4::IWifiChip::ChipIfaceCombination& combination); - bool canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( - const std::map& expanded_combo, - IfaceType requested_type); - bool canCurrentModeSupportIfaceOfTypeWithCurrentIfaces( - IfaceType requested_type); - bool canExpandedIfaceComboSupportIfaceCombo( - const std::map& expanded_combo, - const std::map& req_combo); - bool canCurrentModeSupportIfaceCombo( - const std::map& req_combo); - bool canCurrentModeSupportIfaceOfType(IfaceType requested_type); - bool isValidModeId(ChipModeId mode_id); - bool isStaApConcurrencyAllowedInCurrentMode(); - bool isDualStaConcurrencyAllowedInCurrentMode(); - uint32_t startIdxOfApIface(); - std::string getFirstActiveWlanIfaceName(); - std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx); - std::string allocateApIfaceName(); - std::vector allocateBridgedApInstanceNames(); - std::string allocateStaIfaceName(); - bool writeRingbufferFilesInternal(); - std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx); - void invalidateAndClearBridgedApAll(); - void invalidateAndClearBridgedAp(const std::string& br_name); - bool findUsingNameFromBridgedApInstances(const std::string& name); - WifiStatus triggerSubsystemRestartInternal(); - - ChipId chip_id_; - std::weak_ptr legacy_hal_; - std::weak_ptr mode_controller_; - std::shared_ptr iface_util_; - std::vector> ap_ifaces_; - std::vector> nan_ifaces_; - std::vector> p2p_ifaces_; - std::vector> sta_ifaces_; - std::vector> rtt_controllers_; - std::map ringbuffer_map_; - bool is_valid_; - // Members pertaining to chip configuration. - uint32_t current_mode_id_; - std::mutex lock_t; - std::vector modes_; - // The legacy ring buffer callback API has only a global callback - // registration mechanism. Use this to check if we have already - // registered a callback. - bool debug_ring_buffer_cb_registered_; - hidl_callback_util::HidlCallbackHandler - event_cb_handler_; - - const std::function subsystemCallbackHandler_; - std::map> br_ifaces_ap_instances_; - DISALLOW_COPY_AND_ASSIGN(WifiChip); -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_CHIP_H_ diff --git a/wifi/1.5/default/wifi_feature_flags.cpp b/wifi/1.5/default/wifi_feature_flags.cpp deleted file mode 100644 index 70ce55a70e..0000000000 --- a/wifi/1.5/default/wifi_feature_flags.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - * 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. - */ - -#include - -#include -#include - -#include "wifi_feature_flags.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace feature_flags { - -using V1_0::ChipModeId; -using V1_0::IfaceType; -using V1_0::IWifiChip; - -/* The chip may either have a single mode supporting any number of combinations, - * or a fixed dual-mode (so it involves firmware loading to switch between - * modes) setting. If there is a need to support more modes, it needs to be - * implemented manually in WiFi HAL (see changeFirmwareMode in - * WifiChip::handleChipConfiguration). - * - * Supported combinations are defined in device's makefile, for example: - * WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}}, - * WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}} - * What means: - * Interface combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface - * operations. - * Interface combination 2: 1 STA and 2 AP concurrent iface operations. - * - * For backward compatibility, the following makefile flags can be used to - * generate combinations list: - * - WIFI_HIDL_FEATURE_DUAL_INTERFACE - * - WIFI_HIDL_FEATURE_DISABLE_AP - * - WIFI_HIDL_FEATURE_AWARE - * However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided. - * With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with - * two interface combinations: - * Interface Combination 1: Will support 1 STA and 1 P2P or NAN (optional) - * concurrent iface operations. - * Interface Combination 2: Will support 1 STA and 1 AP concurrent - * iface operations. - * - * The only dual-mode configuration supported is for alternating STA and AP - * mode, that may involve firmware reloading. In such case, there are 2 separate - * modes of operation with 1 interface combination each: - * Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional) - * concurrent iface operations. - * Mode 2 (AP mode): Will support 1 AP iface operation. - * - * If Aware is enabled, the iface combination will be modified to support either - * P2P or NAN in place of just P2P. - */ -// clang-format off -#ifdef WIFI_HAL_INTERFACE_COMBINATIONS -constexpr ChipModeId kMainModeId = chip_mode_ids::kV3; -#elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE) -// former V2 (fixed dual interface) setup expressed as V3 -constexpr ChipModeId kMainModeId = chip_mode_ids::kV3; -# ifdef WIFI_HIDL_FEATURE_DISABLE_AP -# ifdef WIFI_HIDL_FEATURE_AWARE -// 1 STA + 1 of (P2P or NAN) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}} -# else -// 1 STA + 1 P2P -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}} -# endif -# else -# ifdef WIFI_HIDL_FEATURE_AWARE -// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P, NAN}, 1}} -# else -// (1 STA + 1 AP) or (1 STA + 1 P2P) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ - {{{STA}, 1}, {{P2P}, 1}} -# endif -# endif -#else -// V1 (fixed single interface, dual-mode chip) -constexpr ChipModeId kMainModeId = chip_mode_ids::kV1Sta; -# ifdef WIFI_HIDL_FEATURE_AWARE -// 1 STA + 1 of (P2P or NAN) -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}} -# else -// 1 STA + 1 P2P -# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}} -# endif - -# ifndef WIFI_HIDL_FEATURE_DISABLE_AP -# define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}} -# endif -#endif -// clang-format on - -/** - * Helper class to convert a collection of combination limits to a combination. - * - * The main point here is to simplify the syntax required by - * WIFI_HAL_INTERFACE_COMBINATIONS. - */ -struct ChipIfaceCombination - : public hidl_vec { - ChipIfaceCombination( - const std::initializer_list list) - : hidl_vec(list) {} - - operator IWifiChip::ChipIfaceCombination() const { return {*this}; } - - static hidl_vec make_vec( - const std::initializer_list list) { - return hidl_vec( // - std::begin(list), std::end(list)); - } -}; - -#define STA IfaceType::STA -#define AP IfaceType::AP -#define P2P IfaceType::P2P -#define NAN IfaceType::NAN -static const std::vector kChipModesPrimary{ - {kMainModeId, - ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})}, -#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP - {chip_mode_ids::kV1Ap, - ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})}, -#endif -}; - -static const std::vector kChipModesSecondary{ -#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP - {chip_mode_ids::kV3, ChipIfaceCombination::make_vec( - {WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})}, -#endif -}; - -constexpr char kDebugPresetInterfaceCombinationIdxProperty[] = - "persist.vendor.debug.wifi.hal.preset_interface_combination_idx"; -// List of pre-defined interface combinations that can be enabled at runtime via -// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the -// corresponding index value. -static const std::vector>> kDebugChipModes{ - // Legacy combination - No STA/AP concurrencies. - // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN)) - {"No STA/AP Concurrency", - {{kMainModeId, - ChipIfaceCombination::make_vec({{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}}, - - // STA + AP concurrency - // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) - {"STA + AP Concurrency", - {{kMainModeId, ChipIfaceCombination::make_vec( - {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}}, - - // STA + STA concurrency - // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN)) - {"Dual STA Concurrency", - {{kMainModeId, ChipIfaceCombination::make_vec( - {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}, - - // AP + AP + STA concurrency - // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN)) - {"Dual AP Concurrency", - {{kMainModeId, ChipIfaceCombination::make_vec( - {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}}, - - // STA + STA concurrency and AP + AP + STA concurrency - // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN)) - {"Dual STA & Dual AP Concurrency", - {{kMainModeId, ChipIfaceCombination::make_vec( - {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}, - - // STA + STA concurrency - // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA)) - {"Dual STA or STA plus single other interface", - {{kMainModeId, - ChipIfaceCombination::make_vec({{{{STA}, 1}, {{P2P, NAN, AP}, 1}}, {{{STA}, 2}}})}}}}; - -#undef STA -#undef AP -#undef P2P -#undef NAN - -#ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION -#pragma message \ - "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \ - "'config_wifi_ap_randomization_supported' in " \ - "frameworks/base/core/res/res/values/config.xml in the device overlay " \ - "instead" -#endif // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION - -WifiFeatureFlags::WifiFeatureFlags() {} - -std::vector WifiFeatureFlags::getChipModesForPrimary() { - std::array buffer; - auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, - buffer.data(), nullptr); - // Debug propety not set, use the device preset interface combination. - if (res <= 0) return kChipModesPrimary; - - // Debug propety set, use one of the debug preset interface combination. - unsigned long idx = std::stoul(buffer.data()); - if (idx >= kDebugChipModes.size()) { - LOG(ERROR) << "Invalid index set in property: " - << kDebugPresetInterfaceCombinationIdxProperty; - return kChipModesPrimary; - } - std::string name; - std::vector chip_modes; - std::tie(name, chip_modes) = kDebugChipModes[idx]; - LOG(INFO) << "Using debug chip mode: <" << name << "> set via property: " - << kDebugPresetInterfaceCombinationIdxProperty; - return chip_modes; -} - -std::vector WifiFeatureFlags::getChipModes( - bool is_primary) { - return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary; -} - -} // namespace feature_flags -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_feature_flags.h b/wifi/1.5/default/wifi_feature_flags.h deleted file mode 100644 index 7d561fc949..0000000000 --- a/wifi/1.5/default/wifi_feature_flags.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_FEATURE_FLAGS_H_ -#define WIFI_FEATURE_FLAGS_H_ - -#include - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace feature_flags { - -namespace chip_mode_ids { -// These mode ID's should be unique (even across combo versions). Refer to -// handleChipConfiguration() for it's usage. -constexpr V1_0::ChipModeId kInvalid = UINT32_MAX; -// Mode ID's for V1 -constexpr V1_0::ChipModeId kV1Sta = 0; -constexpr V1_0::ChipModeId kV1Ap = 1; -// Mode ID for V3 -constexpr V1_0::ChipModeId kV3 = 3; -} // namespace chip_mode_ids - -class WifiFeatureFlags { - public: - WifiFeatureFlags(); - virtual ~WifiFeatureFlags() = default; - - virtual std::vector getChipModes( - bool is_primary); - - private: - std::vector getChipModesForPrimary(); -}; - -} // namespace feature_flags -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_FEATURE_FLAGS_H_ diff --git a/wifi/1.5/default/wifi_iface_util.cpp b/wifi/1.5/default/wifi_iface_util.cpp deleted file mode 100644 index 0977026698..0000000000 --- a/wifi/1.5/default/wifi_iface_util.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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 -#include -#include -#include -#include - -#include -#include -#include - -#undef NAN -#include "wifi_iface_util.h" - -namespace { -// Constants to set the local bit & clear the multicast bit. -constexpr uint8_t kMacAddressMulticastMask = 0x01; -constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02; -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace iface_util { - -WifiIfaceUtil::WifiIfaceUtil( - const std::weak_ptr iface_tool, - const std::weak_ptr legacy_hal) - : iface_tool_(iface_tool), - legacy_hal_(legacy_hal), - random_mac_address_(nullptr), - event_handlers_map_() {} - -std::array WifiIfaceUtil::getFactoryMacAddress( - const std::string& iface_name) { - return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str()); -} - -bool WifiIfaceUtil::setMacAddress(const std::string& iface_name, - const std::array& mac) { -#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE - legacy_hal::wifi_error legacy_status; - uint64_t legacy_feature_set; - std::tie(legacy_status, legacy_feature_set) = - legacy_hal_.lock()->getSupportedFeatureSet(iface_name); - - if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) && - !iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) { - LOG(ERROR) << "SetUpState(false) failed."; - return false; - } -#endif - bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac); -#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE - if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) && - !iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) { - LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready."; - // Wait for driver ready and try to set iface UP again - if (legacy_hal_.lock()->waitForDriverReady() != - legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "SetUpState(true) wait for driver ready failed."; - return false; - } - if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) { - LOG(ERROR) << "SetUpState(true) failed after retry."; - return false; - } - } -#endif - IfaceEventHandlers event_handlers = {}; - const auto it = event_handlers_map_.find(iface_name); - if (it != event_handlers_map_.end()) { - event_handlers = it->second; - } - if (event_handlers.on_state_toggle_off_on != nullptr) { - event_handlers.on_state_toggle_off_on(iface_name); - } - if (!success) { - LOG(ERROR) << "SetMacAddress failed on " << iface_name; - } else { - LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name; - } - return success; -} - -std::array WifiIfaceUtil::getOrCreateRandomMacAddress() { - if (random_mac_address_) { - return *random_mac_address_.get(); - } - random_mac_address_ = - std::make_unique>(createRandomMacAddress()); - return *random_mac_address_.get(); -} - -void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name, - IfaceEventHandlers handlers) { - event_handlers_map_[iface_name] = handlers; -} - -void WifiIfaceUtil::unregisterIfaceEventHandlers( - const std::string& iface_name) { - event_handlers_map_.erase(iface_name); -} - -std::array WifiIfaceUtil::createRandomMacAddress() { - std::array address = {}; - std::random_device rd; - std::default_random_engine engine(rd()); - std::uniform_int_distribution dist( - std::numeric_limits::min(), - std::numeric_limits::max()); - for (size_t i = 0; i < address.size(); i++) { - address[i] = dist(engine); - } - // Set the local bit and clear the multicast bit. - address[0] |= kMacAddressLocallyAssignedMask; - address[0] &= ~kMacAddressMulticastMask; - return address; -} - -bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) { - if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) { - LOG(ERROR) << "SetUpState to " << request_up << " failed"; - return false; - } - return true; -} - -unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) { - return if_nametoindex(iface_name.c_str()); -} - -bool WifiIfaceUtil::createBridge(const std::string& br_name) { - if (!iface_tool_.lock()->createBridge(br_name)) { - return false; - } - - if (!iface_tool_.lock()->SetUpState(br_name.c_str(), true)) { - LOG(ERROR) << "bridge SetUpState(true) failed."; - } - return true; -} - -bool WifiIfaceUtil::deleteBridge(const std::string& br_name) { - if (!iface_tool_.lock()->SetUpState(br_name.c_str(), false)) { - LOG(INFO) << "SetUpState(false) failed for bridge=" << br_name.c_str(); - } - - return iface_tool_.lock()->deleteBridge(br_name); -} - -bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, - const std::string& if_name) { - return iface_tool_.lock()->addIfaceToBridge(br_name, if_name); -} - -bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, - const std::string& if_name) { - return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name); -} - -} // namespace iface_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_iface_util.h b/wifi/1.5/default/wifi_iface_util.h deleted file mode 100644 index 544f575d41..0000000000 --- a/wifi/1.5/default/wifi_iface_util.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 WIFI_IFACE_UTIL_H_ -#define WIFI_IFACE_UTIL_H_ - -#include - -#include - -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace iface_util { - -// Iface event handlers. -struct IfaceEventHandlers { - // Callback to be invoked when the iface is set down & up for MAC address - // change. - std::function on_state_toggle_off_on; -}; - -/** - * Util class for common iface operations. - */ -class WifiIfaceUtil { - public: - WifiIfaceUtil(const std::weak_ptr iface_tool, - const std::weak_ptr legacy_hal); - virtual ~WifiIfaceUtil() = default; - - virtual std::array getFactoryMacAddress( - const std::string& iface_name); - virtual bool setMacAddress(const std::string& iface_name, - const std::array& mac); - // Get or create a random MAC address. The MAC address returned from - // this method will remain the same throughout the lifetime of the HAL - // daemon. (So, changes on every reboot) - virtual std::array getOrCreateRandomMacAddress(); - - // Register for any iface event callbacks for the provided interface. - virtual void registerIfaceEventHandlers(const std::string& iface_name, - IfaceEventHandlers handlers); - virtual void unregisterIfaceEventHandlers(const std::string& iface_name); - virtual bool setUpState(const std::string& iface_name, bool request_up); - virtual unsigned ifNameToIndex(const std::string& iface_name); - - virtual bool createBridge(const std::string& br_name); - - virtual bool deleteBridge(const std::string& br_name); - - virtual bool addIfaceToBridge(const std::string& br_name, - const std::string& if_name); - - virtual bool removeIfaceFromBridge(const std::string& br_name, - const std::string& if_name); - // Get a random MAC address. - virtual std::array createRandomMacAddress(); - - private: - std::weak_ptr iface_tool_; - std::weak_ptr legacy_hal_; - std::unique_ptr> random_mac_address_; - std::map event_handlers_map_; -}; - -} // namespace iface_util -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_IFACE_UTIL_H_ diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp deleted file mode 100644 index 5074252d3d..0000000000 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ /dev/null @@ -1,1725 +0,0 @@ -/* - * 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. - */ - -#include -#include - -#include -#include -#include - -#include "hidl_sync_util.h" -#include "wifi_legacy_hal.h" -#include "wifi_legacy_hal_stubs.h" - -namespace { -// Constants ported over from the legacy HAL calling code -// (com_android_server_wifi_WifiNative.cpp). This will all be thrown -// away when this shim layer is replaced by the real vendor -// implementation. -static constexpr uint32_t kMaxVersionStringLength = 256; -static constexpr uint32_t kMaxCachedGscanResults = 64; -static constexpr uint32_t kMaxGscanFrequenciesForBand = 64; -static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128; -static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32; -static constexpr uint32_t kMaxRingBuffers = 10; -static constexpr uint32_t kMaxWifiUsableChannels = 256; -// need a long timeout (1000ms) for chips that unload their driver. -static constexpr uint32_t kMaxStopCompleteWaitMs = 1000; -static constexpr char kDriverPropName[] = "wlan.driver.status"; - -// Helper function to create a non-const char* for legacy Hal API's. -std::vector makeCharVec(const std::string& str) { - std::vector vec(str.size() + 1); - vec.assign(str.begin(), str.end()); - vec.push_back('\0'); - return vec; -} -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace legacy_hal { - -// Legacy HAL functions accept "C" style function pointers, so use global -// functions to pass to the legacy HAL function and store the corresponding -// std::function methods to be invoked. -// -// Callback to be invoked once |stop| is complete -std::function on_stop_complete_internal_callback; -void onAsyncStopComplete(wifi_handle handle) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_stop_complete_internal_callback) { - on_stop_complete_internal_callback(handle); - // Invalidate this callback since we don't want this firing again. - on_stop_complete_internal_callback = nullptr; - } -} - -// Callback to be invoked for driver dump. -std::function on_driver_memory_dump_internal_callback; -void onSyncDriverMemoryDump(char* buffer, int buffer_size) { - if (on_driver_memory_dump_internal_callback) { - on_driver_memory_dump_internal_callback(buffer, buffer_size); - } -} - -// Callback to be invoked for firmware dump. -std::function on_firmware_memory_dump_internal_callback; -void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) { - if (on_firmware_memory_dump_internal_callback) { - on_firmware_memory_dump_internal_callback(buffer, buffer_size); - } -} - -// Callback to be invoked for Gscan events. -std::function - on_gscan_event_internal_callback; -void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_gscan_event_internal_callback) { - on_gscan_event_internal_callback(id, event); - } -} - -// Callback to be invoked for Gscan full results. -std::function - on_gscan_full_result_internal_callback; -void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result, - uint32_t buckets_scanned) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_gscan_full_result_internal_callback) { - on_gscan_full_result_internal_callback(id, result, buckets_scanned); - } -} - -// Callback to be invoked for link layer stats results. -std::function - on_link_layer_stats_result_internal_callback; -void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, - int num_radios, wifi_radio_stat* radio_stat) { - if (on_link_layer_stats_result_internal_callback) { - on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, - radio_stat); - } -} - -// Callback to be invoked for rssi threshold breach. -std::function - on_rssi_threshold_breached_internal_callback; -void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, - int8_t rssi) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_rssi_threshold_breached_internal_callback) { - on_rssi_threshold_breached_internal_callback(id, bssid, rssi); - } -} - -// Callback to be invoked for ring buffer data indication. -std::function - on_ring_buffer_data_internal_callback; -void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size, - wifi_ring_buffer_status* status) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_ring_buffer_data_internal_callback) { - on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, - status); - } -} - -// Callback to be invoked for error alert indication. -std::function - on_error_alert_internal_callback; -void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, - int err_code) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_error_alert_internal_callback) { - on_error_alert_internal_callback(id, buffer, buffer_size, err_code); - } -} - -// Callback to be invoked for radio mode change indication. -std::function - on_radio_mode_change_internal_callback; -void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, - wifi_mac_info* mac_infos) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_radio_mode_change_internal_callback) { - on_radio_mode_change_internal_callback(id, num_macs, mac_infos); - } -} - -// Callback to be invoked to report subsystem restart -std::function on_subsystem_restart_internal_callback; -void onAsyncSubsystemRestart(const char* error) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_subsystem_restart_internal_callback) { - on_subsystem_restart_internal_callback(error); - } -} - -// Callback to be invoked for rtt results results. -std::function - on_rtt_results_internal_callback; -void onAsyncRttResults(wifi_request_id id, unsigned num_results, - wifi_rtt_result* rtt_results[]) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_rtt_results_internal_callback) { - on_rtt_results_internal_callback(id, num_results, rtt_results); - on_rtt_results_internal_callback = nullptr; - } -} - -// Callbacks for the various NAN operations. -// NOTE: These have very little conversions to perform before invoking the user -// callbacks. -// So, handle all of them here directly to avoid adding an unnecessary layer. -std::function - on_nan_notify_response_user_callback; -void onAysncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_notify_response_user_callback && msg) { - on_nan_notify_response_user_callback(id, *msg); - } -} - -std::function - on_nan_event_publish_replied_user_callback; -void onAysncNanEventPublishReplied(NanPublishRepliedInd* /* event */) { - LOG(ERROR) << "onAysncNanEventPublishReplied triggered"; -} - -std::function - on_nan_event_publish_terminated_user_callback; -void onAysncNanEventPublishTerminated(NanPublishTerminatedInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_publish_terminated_user_callback && event) { - on_nan_event_publish_terminated_user_callback(*event); - } -} - -std::function on_nan_event_match_user_callback; -void onAysncNanEventMatch(NanMatchInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_match_user_callback && event) { - on_nan_event_match_user_callback(*event); - } -} - -std::function - on_nan_event_match_expired_user_callback; -void onAysncNanEventMatchExpired(NanMatchExpiredInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_match_expired_user_callback && event) { - on_nan_event_match_expired_user_callback(*event); - } -} - -std::function - on_nan_event_subscribe_terminated_user_callback; -void onAysncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_subscribe_terminated_user_callback && event) { - on_nan_event_subscribe_terminated_user_callback(*event); - } -} - -std::function on_nan_event_followup_user_callback; -void onAysncNanEventFollowup(NanFollowupInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_followup_user_callback && event) { - on_nan_event_followup_user_callback(*event); - } -} - -std::function - on_nan_event_disc_eng_event_user_callback; -void onAysncNanEventDiscEngEvent(NanDiscEngEventInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_disc_eng_event_user_callback && event) { - on_nan_event_disc_eng_event_user_callback(*event); - } -} - -std::function on_nan_event_disabled_user_callback; -void onAysncNanEventDisabled(NanDisabledInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_disabled_user_callback && event) { - on_nan_event_disabled_user_callback(*event); - } -} - -std::function on_nan_event_tca_user_callback; -void onAysncNanEventTca(NanTCAInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_tca_user_callback && event) { - on_nan_event_tca_user_callback(*event); - } -} - -std::function - on_nan_event_beacon_sdf_payload_user_callback; -void onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_beacon_sdf_payload_user_callback && event) { - on_nan_event_beacon_sdf_payload_user_callback(*event); - } -} - -std::function - on_nan_event_data_path_request_user_callback; -void onAysncNanEventDataPathRequest(NanDataPathRequestInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_data_path_request_user_callback && event) { - on_nan_event_data_path_request_user_callback(*event); - } -} -std::function - on_nan_event_data_path_confirm_user_callback; -void onAysncNanEventDataPathConfirm(NanDataPathConfirmInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_data_path_confirm_user_callback && event) { - on_nan_event_data_path_confirm_user_callback(*event); - } -} - -std::function - on_nan_event_data_path_end_user_callback; -void onAysncNanEventDataPathEnd(NanDataPathEndInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_data_path_end_user_callback && event) { - on_nan_event_data_path_end_user_callback(*event); - } -} - -std::function - on_nan_event_transmit_follow_up_user_callback; -void onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_transmit_follow_up_user_callback && event) { - on_nan_event_transmit_follow_up_user_callback(*event); - } -} - -std::function - on_nan_event_range_request_user_callback; -void onAysncNanEventRangeRequest(NanRangeRequestInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_range_request_user_callback && event) { - on_nan_event_range_request_user_callback(*event); - } -} - -std::function - on_nan_event_range_report_user_callback; -void onAysncNanEventRangeReport(NanRangeReportInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_range_report_user_callback && event) { - on_nan_event_range_report_user_callback(*event); - } -} - -std::function - on_nan_event_schedule_update_user_callback; -void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_nan_event_schedule_update_user_callback && event) { - on_nan_event_schedule_update_user_callback(*event); - } -} - -// Callbacks for the various TWT operations. -std::function - on_twt_event_setup_response_callback; -void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_twt_event_setup_response_callback && event) { - on_twt_event_setup_response_callback(*event); - } -} - -std::function - on_twt_event_teardown_completion_callback; -void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_twt_event_teardown_completion_callback && event) { - on_twt_event_teardown_completion_callback(*event); - } -} - -std::function - on_twt_event_info_frame_received_callback; -void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_twt_event_info_frame_received_callback && event) { - on_twt_event_info_frame_received_callback(*event); - } -} - -std::function on_twt_event_device_notify_callback; -void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) { - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (on_twt_event_device_notify_callback && event) { - on_twt_event_device_notify_callback(*event); - } -} - -// End of the free-standing "C" style callbacks. - -WifiLegacyHal::WifiLegacyHal( - const std::weak_ptr iface_tool, - const wifi_hal_fn& fn, bool is_primary) - : global_func_table_(fn), - global_handle_(nullptr), - awaiting_event_loop_termination_(false), - is_started_(false), - iface_tool_(iface_tool), - is_primary_(is_primary) {} - -wifi_error WifiLegacyHal::initialize() { - LOG(DEBUG) << "Initialize legacy HAL"; - // this now does nothing, since HAL function table is provided - // to the constructor - return WIFI_SUCCESS; -} - -wifi_error WifiLegacyHal::start() { - // Ensure that we're starting in a good state. - CHECK(global_func_table_.wifi_initialize && !global_handle_ && - iface_name_to_handle_.empty() && !awaiting_event_loop_termination_); - if (is_started_) { - LOG(DEBUG) << "Legacy HAL already started"; - return WIFI_SUCCESS; - } - LOG(DEBUG) << "Waiting for the driver ready"; - wifi_error status = global_func_table_.wifi_wait_for_driver_ready(); - if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) { - LOG(ERROR) << "Failed or timed out awaiting driver ready"; - return status; - } - - if (is_primary_) { - property_set(kDriverPropName, "ok"); - - if (!iface_tool_.lock()->SetWifiUpState(true)) { - LOG(ERROR) << "Failed to set WiFi interface up"; - return WIFI_ERROR_UNKNOWN; - } - } - - LOG(DEBUG) << "Starting legacy HAL"; - status = global_func_table_.wifi_initialize(&global_handle_); - if (status != WIFI_SUCCESS || !global_handle_) { - LOG(ERROR) << "Failed to retrieve global handle"; - return status; - } - std::thread(&WifiLegacyHal::runEventLoop, this).detach(); - status = retrieveIfaceHandles(); - if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) { - LOG(ERROR) << "Failed to retrieve wlan interface handle"; - return status; - } - LOG(DEBUG) << "Legacy HAL start complete"; - is_started_ = true; - return WIFI_SUCCESS; -} - -wifi_error WifiLegacyHal::stop( - /* NONNULL */ std::unique_lock* lock, - const std::function& on_stop_complete_user_callback) { - if (!is_started_) { - LOG(DEBUG) << "Legacy HAL already stopped"; - on_stop_complete_user_callback(); - return WIFI_SUCCESS; - } - LOG(DEBUG) << "Stopping legacy HAL"; - on_stop_complete_internal_callback = [on_stop_complete_user_callback, - this](wifi_handle handle) { - CHECK_EQ(global_handle_, handle) << "Handle mismatch"; - LOG(INFO) << "Legacy HAL stop complete callback received"; - // Invalidate all the internal pointers now that the HAL is - // stopped. - invalidate(); - if (is_primary_) iface_tool_.lock()->SetWifiUpState(false); - on_stop_complete_user_callback(); - is_started_ = false; - }; - awaiting_event_loop_termination_ = true; - global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete); - const auto status = stop_wait_cv_.wait_for( - *lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs), - [this] { return !awaiting_event_loop_termination_; }); - if (!status) { - LOG(ERROR) << "Legacy HAL stop failed or timed out"; - return WIFI_ERROR_UNKNOWN; - } - LOG(DEBUG) << "Legacy HAL stop complete"; - return WIFI_SUCCESS; -} - -bool WifiLegacyHal::isStarted() { return is_started_; } - -wifi_error WifiLegacyHal::waitForDriverReady() { - return global_func_table_.wifi_wait_for_driver_ready(); -} - -std::pair WifiLegacyHal::getDriverVersion( - const std::string& iface_name) { - std::array buffer; - buffer.fill(0); - wifi_error status = global_func_table_.wifi_get_driver_version( - getIfaceHandle(iface_name), buffer.data(), buffer.size()); - return {status, buffer.data()}; -} - -std::pair WifiLegacyHal::getFirmwareVersion( - const std::string& iface_name) { - std::array buffer; - buffer.fill(0); - wifi_error status = global_func_table_.wifi_get_firmware_version( - getIfaceHandle(iface_name), buffer.data(), buffer.size()); - return {status, buffer.data()}; -} - -std::pair> -WifiLegacyHal::requestDriverMemoryDump(const std::string& iface_name) { - std::vector driver_dump; - on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, - int buffer_size) { - driver_dump.insert(driver_dump.end(), - reinterpret_cast(buffer), - reinterpret_cast(buffer) + buffer_size); - }; - wifi_error status = global_func_table_.wifi_get_driver_memory_dump( - getIfaceHandle(iface_name), {onSyncDriverMemoryDump}); - on_driver_memory_dump_internal_callback = nullptr; - return {status, std::move(driver_dump)}; -} - -std::pair> -WifiLegacyHal::requestFirmwareMemoryDump(const std::string& iface_name) { - std::vector firmware_dump; - on_firmware_memory_dump_internal_callback = - [&firmware_dump](char* buffer, int buffer_size) { - firmware_dump.insert( - firmware_dump.end(), reinterpret_cast(buffer), - reinterpret_cast(buffer) + buffer_size); - }; - wifi_error status = global_func_table_.wifi_get_firmware_memory_dump( - getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump}); - on_firmware_memory_dump_internal_callback = nullptr; - return {status, std::move(firmware_dump)}; -} - -std::pair WifiLegacyHal::getSupportedFeatureSet( - const std::string& iface_name) { - feature_set set = 0, chip_set = 0; - wifi_error status = WIFI_SUCCESS; - - static_assert(sizeof(set) == sizeof(uint64_t), - "Some feature_flags can not be represented in output"); - wifi_interface_handle iface_handle = getIfaceHandle(iface_name); - - global_func_table_.wifi_get_chip_feature_set( - global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */ - - if (iface_handle) { - status = global_func_table_.wifi_get_supported_feature_set(iface_handle, - &set); - } - return {status, static_cast(set | chip_set)}; -} - -std::pair -WifiLegacyHal::getPacketFilterCapabilities(const std::string& iface_name) { - PacketFilterCapabilities caps; - wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities( - getIfaceHandle(iface_name), &caps.version, &caps.max_len); - return {status, caps}; -} - -wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name, - const std::vector& program) { - return global_func_table_.wifi_set_packet_filter( - getIfaceHandle(iface_name), program.data(), program.size()); -} - -std::pair> -WifiLegacyHal::readApfPacketFilterData(const std::string& iface_name) { - PacketFilterCapabilities caps; - wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities( - getIfaceHandle(iface_name), &caps.version, &caps.max_len); - if (status != WIFI_SUCCESS) { - return {status, {}}; - } - - // Size the buffer to read the entire program & work memory. - std::vector buffer(caps.max_len); - - status = global_func_table_.wifi_read_packet_filter( - getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), - buffer.size()); - return {status, move(buffer)}; -} - -std::pair -WifiLegacyHal::getGscanCapabilities(const std::string& iface_name) { - wifi_gscan_capabilities caps; - wifi_error status = global_func_table_.wifi_get_gscan_capabilities( - getIfaceHandle(iface_name), &caps); - return {status, caps}; -} - -wifi_error WifiLegacyHal::startGscan( - const std::string& iface_name, wifi_request_id id, - const wifi_scan_cmd_params& params, - const std::function& on_failure_user_callback, - const on_gscan_results_callback& on_results_user_callback, - const on_gscan_full_result_callback& on_full_result_user_callback) { - // If there is already an ongoing background scan, reject new scan requests. - if (on_gscan_event_internal_callback || - on_gscan_full_result_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - - // This callback will be used to either trigger |on_results_user_callback| - // or |on_failure_user_callback|. - on_gscan_event_internal_callback = - [iface_name, on_failure_user_callback, on_results_user_callback, this]( - wifi_request_id id, wifi_scan_event event) { - switch (event) { - case WIFI_SCAN_RESULTS_AVAILABLE: - case WIFI_SCAN_THRESHOLD_NUM_SCANS: - case WIFI_SCAN_THRESHOLD_PERCENT: { - wifi_error status; - std::vector cached_scan_results; - std::tie(status, cached_scan_results) = - getGscanCachedResults(iface_name); - if (status == WIFI_SUCCESS) { - on_results_user_callback(id, cached_scan_results); - return; - } - FALLTHROUGH_INTENDED; - } - // Fall through if failed. Failure to retrieve cached scan - // results should trigger a background scan failure. - case WIFI_SCAN_FAILED: - on_failure_user_callback(id); - on_gscan_event_internal_callback = nullptr; - on_gscan_full_result_internal_callback = nullptr; - return; - } - LOG(FATAL) << "Unexpected gscan event received: " << event; - }; - - on_gscan_full_result_internal_callback = [on_full_result_user_callback]( - wifi_request_id id, - wifi_scan_result* result, - uint32_t buckets_scanned) { - if (result) { - on_full_result_user_callback(id, result, buckets_scanned); - } - }; - - wifi_scan_result_handler handler = {onAsyncGscanFullResult, - onAsyncGscanEvent}; - wifi_error status = global_func_table_.wifi_start_gscan( - id, getIfaceHandle(iface_name), params, handler); - if (status != WIFI_SUCCESS) { - on_gscan_event_internal_callback = nullptr; - on_gscan_full_result_internal_callback = nullptr; - } - return status; -} - -wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, - wifi_request_id id) { - // If there is no an ongoing background scan, reject stop requests. - // TODO(b/32337212): This needs to be handled by the HIDL object because we - // need to return the NOT_STARTED error code. - if (!on_gscan_event_internal_callback && - !on_gscan_full_result_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - wifi_error status = - global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name)); - // If the request Id is wrong, don't stop the ongoing background scan. Any - // other error should be treated as the end of background scan. - if (status != WIFI_ERROR_INVALID_REQUEST_ID) { - on_gscan_event_internal_callback = nullptr; - on_gscan_full_result_internal_callback = nullptr; - } - return status; -} - -std::pair> -WifiLegacyHal::getValidFrequenciesForBand(const std::string& iface_name, - wifi_band band) { - static_assert(sizeof(uint32_t) >= sizeof(wifi_channel), - "Wifi Channel cannot be represented in output"); - std::vector freqs; - freqs.resize(kMaxGscanFrequenciesForBand); - int32_t num_freqs = 0; - wifi_error status = global_func_table_.wifi_get_valid_channels( - getIfaceHandle(iface_name), band, freqs.size(), - reinterpret_cast(freqs.data()), &num_freqs); - CHECK(num_freqs >= 0 && - static_cast(num_freqs) <= kMaxGscanFrequenciesForBand); - freqs.resize(num_freqs); - return {status, std::move(freqs)}; -} - -wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, - bool dfs_on) { - return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), - dfs_on ? 0 : 1); -} - -wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, - bool debug) { - wifi_link_layer_params params; - params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold; - params.aggressive_statistics_gathering = debug; - return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), - params); -} - -wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) { - // TODO: Do we care about these responses? - uint32_t clear_mask_rsp; - uint8_t stop_rsp; - return global_func_table_.wifi_clear_link_stats( - getIfaceHandle(iface_name), 0xFFFFFFFF, &clear_mask_rsp, 1, &stop_rsp); -} - -std::pair WifiLegacyHal::getLinkLayerStats( - const std::string& iface_name) { - LinkLayerStats link_stats{}; - LinkLayerStats* link_stats_ptr = &link_stats; - - on_link_layer_stats_result_internal_callback = - [&link_stats_ptr](wifi_request_id /* id */, - wifi_iface_stat* iface_stats_ptr, int num_radios, - wifi_radio_stat* radio_stats_ptr) { - wifi_radio_stat* l_radio_stats_ptr; - wifi_peer_info* l_peer_info_stats_ptr; - - if (iface_stats_ptr != nullptr) { - link_stats_ptr->iface = *iface_stats_ptr; - l_peer_info_stats_ptr = iface_stats_ptr->peer_info; - for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) { - WifiPeerInfo peer; - peer.peer_info = *l_peer_info_stats_ptr; - if (l_peer_info_stats_ptr->num_rate > 0) { - /* Copy the rate stats */ - peer.rate_stats.assign( - l_peer_info_stats_ptr->rate_stats, - l_peer_info_stats_ptr->rate_stats + - l_peer_info_stats_ptr->num_rate); - } - peer.peer_info.num_rate = 0; - link_stats_ptr->peers.push_back(peer); - l_peer_info_stats_ptr = - (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + - sizeof(wifi_peer_info) + - (sizeof(wifi_rate_stat) * - l_peer_info_stats_ptr->num_rate)); - } - link_stats_ptr->iface.num_peers = 0; - } else { - LOG(ERROR) << "Invalid iface stats in link layer stats"; - } - if (num_radios <= 0 || radio_stats_ptr == nullptr) { - LOG(ERROR) << "Invalid radio stats in link layer stats"; - return; - } - l_radio_stats_ptr = radio_stats_ptr; - for (int i = 0; i < num_radios; i++) { - LinkLayerRadioStats radio; - - radio.stats = *l_radio_stats_ptr; - // Copy over the tx level array to the separate vector. - if (l_radio_stats_ptr->num_tx_levels > 0 && - l_radio_stats_ptr->tx_time_per_levels != nullptr) { - radio.tx_time_per_levels.assign( - l_radio_stats_ptr->tx_time_per_levels, - l_radio_stats_ptr->tx_time_per_levels + - l_radio_stats_ptr->num_tx_levels); - } - radio.stats.num_tx_levels = 0; - radio.stats.tx_time_per_levels = nullptr; - /* Copy over the channel stat to separate vector */ - if (l_radio_stats_ptr->num_channels > 0) { - /* Copy the channel stats */ - radio.channel_stats.assign( - l_radio_stats_ptr->channels, - l_radio_stats_ptr->channels + - l_radio_stats_ptr->num_channels); - } - link_stats_ptr->radios.push_back(radio); - l_radio_stats_ptr = - (wifi_radio_stat*)((u8*)l_radio_stats_ptr + - sizeof(wifi_radio_stat) + - (sizeof(wifi_channel_stat) * - l_radio_stats_ptr->num_channels)); - } - }; - - wifi_error status = global_func_table_.wifi_get_link_stats( - 0, getIfaceHandle(iface_name), {onSyncLinkLayerStatsResult}); - on_link_layer_stats_result_internal_callback = nullptr; - return {status, link_stats}; -} - -wifi_error WifiLegacyHal::startRssiMonitoring( - const std::string& iface_name, wifi_request_id id, int8_t max_rssi, - int8_t min_rssi, - const on_rssi_threshold_breached_callback& - on_threshold_breached_user_callback) { - if (on_rssi_threshold_breached_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - on_rssi_threshold_breached_internal_callback = - [on_threshold_breached_user_callback](wifi_request_id id, - uint8_t* bssid_ptr, int8_t rssi) { - if (!bssid_ptr) { - return; - } - std::array bssid_arr; - // |bssid_ptr| pointer is assumed to have 6 bytes for the mac - // address. - std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr)); - on_threshold_breached_user_callback(id, bssid_arr, rssi); - }; - wifi_error status = global_func_table_.wifi_start_rssi_monitoring( - id, getIfaceHandle(iface_name), max_rssi, min_rssi, - {onAsyncRssiThresholdBreached}); - if (status != WIFI_SUCCESS) { - on_rssi_threshold_breached_internal_callback = nullptr; - } - return status; -} - -wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, - wifi_request_id id) { - if (!on_rssi_threshold_breached_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - wifi_error status = global_func_table_.wifi_stop_rssi_monitoring( - id, getIfaceHandle(iface_name)); - // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any - // other error should be treated as the end of background scan. - if (status != WIFI_ERROR_INVALID_REQUEST_ID) { - on_rssi_threshold_breached_internal_callback = nullptr; - } - return status; -} - -std::pair -WifiLegacyHal::getRoamingCapabilities(const std::string& iface_name) { - wifi_roaming_capabilities caps; - wifi_error status = global_func_table_.wifi_get_roaming_capabilities( - getIfaceHandle(iface_name), &caps); - return {status, caps}; -} - -wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name, - const wifi_roaming_config& config) { - wifi_roaming_config config_internal = config; - return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), - &config_internal); -} - -wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name, - fw_roaming_state_t state) { - return global_func_table_.wifi_enable_firmware_roaming( - getIfaceHandle(iface_name), state); -} - -wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, - bool enable) { - return global_func_table_.wifi_configure_nd_offload( - getIfaceHandle(iface_name), enable); -} - -wifi_error WifiLegacyHal::startSendingOffloadedPacket( - const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type, - const std::vector& ip_packet_data, - const std::array& src_address, - const std::array& dst_address, uint32_t period_in_ms) { - std::vector ip_packet_data_internal(ip_packet_data); - std::vector src_address_internal( - src_address.data(), src_address.data() + src_address.size()); - std::vector dst_address_internal( - dst_address.data(), dst_address.data() + dst_address.size()); - return global_func_table_.wifi_start_sending_offloaded_packet( - cmd_id, getIfaceHandle(iface_name), ether_type, - ip_packet_data_internal.data(), ip_packet_data_internal.size(), - src_address_internal.data(), dst_address_internal.data(), period_in_ms); -} - -wifi_error WifiLegacyHal::stopSendingOffloadedPacket( - const std::string& iface_name, uint32_t cmd_id) { - return global_func_table_.wifi_stop_sending_offloaded_packet( - cmd_id, getIfaceHandle(iface_name)); -} - -wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name, - wifi_power_scenario scenario) { - return global_func_table_.wifi_select_tx_power_scenario( - getIfaceHandle(iface_name), scenario); -} - -wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) { - return global_func_table_.wifi_reset_tx_power_scenario( - getIfaceHandle(iface_name)); -} - -wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, - wifi_latency_mode mode) { - return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), - mode); -} - -wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode, - uint32_t completion_window) { - return global_func_table_.wifi_set_thermal_mitigation_mode( - global_handle_, mode, completion_window); -} - -wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping( - uint32_t start, uint32_t end, uint32_t access_category) { - return global_func_table_.wifi_map_dscp_access_category( - global_handle_, start, end, access_category); -} - -wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() { - return global_func_table_.wifi_reset_dscp_mapping(global_handle_); -} - -std::pair WifiLegacyHal::getLoggerSupportedFeatureSet( - const std::string& iface_name) { - uint32_t supported_feature_flags = 0; - wifi_error status = WIFI_SUCCESS; - - wifi_interface_handle iface_handle = getIfaceHandle(iface_name); - - if (iface_handle) { - status = global_func_table_.wifi_get_logger_supported_feature_set( - iface_handle, &supported_feature_flags); - } - return {status, supported_feature_flags}; -} - -wifi_error WifiLegacyHal::startPktFateMonitoring( - const std::string& iface_name) { - return global_func_table_.wifi_start_pkt_fate_monitoring( - getIfaceHandle(iface_name)); -} - -std::pair> WifiLegacyHal::getTxPktFates( - const std::string& iface_name) { - std::vector tx_pkt_fates; - tx_pkt_fates.resize(MAX_FATE_LOG_LEN); - size_t num_fates = 0; - wifi_error status = global_func_table_.wifi_get_tx_pkt_fates( - getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), - &num_fates); - CHECK(num_fates <= MAX_FATE_LOG_LEN); - tx_pkt_fates.resize(num_fates); - return {status, std::move(tx_pkt_fates)}; -} - -std::pair> WifiLegacyHal::getRxPktFates( - const std::string& iface_name) { - std::vector rx_pkt_fates; - rx_pkt_fates.resize(MAX_FATE_LOG_LEN); - size_t num_fates = 0; - wifi_error status = global_func_table_.wifi_get_rx_pkt_fates( - getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), - &num_fates); - CHECK(num_fates <= MAX_FATE_LOG_LEN); - rx_pkt_fates.resize(num_fates); - return {status, std::move(rx_pkt_fates)}; -} - -std::pair WifiLegacyHal::getWakeReasonStats( - const std::string& iface_name) { - WakeReasonStats stats; - stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize); - stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize); - - // This legacy struct needs separate memory to store the variable sized wake - // reason types. - stats.wake_reason_cnt.cmd_event_wake_cnt = - reinterpret_cast(stats.cmd_event_wake_cnt.data()); - stats.wake_reason_cnt.cmd_event_wake_cnt_sz = - stats.cmd_event_wake_cnt.size(); - stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0; - stats.wake_reason_cnt.driver_fw_local_wake_cnt = - reinterpret_cast(stats.driver_fw_local_wake_cnt.data()); - stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = - stats.driver_fw_local_wake_cnt.size(); - stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0; - - wifi_error status = global_func_table_.wifi_get_wake_reason_stats( - getIfaceHandle(iface_name), &stats.wake_reason_cnt); - - CHECK( - stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 && - static_cast(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <= - kMaxWakeReasonStatsArraySize); - stats.cmd_event_wake_cnt.resize( - stats.wake_reason_cnt.cmd_event_wake_cnt_used); - stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr; - - CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 && - static_cast( - stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <= - kMaxWakeReasonStatsArraySize); - stats.driver_fw_local_wake_cnt.resize( - stats.wake_reason_cnt.driver_fw_local_wake_cnt_used); - stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr; - - return {status, stats}; -} - -wifi_error WifiLegacyHal::registerRingBufferCallbackHandler( - const std::string& iface_name, - const on_ring_buffer_data_callback& on_user_data_callback) { - if (on_ring_buffer_data_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - on_ring_buffer_data_internal_callback = - [on_user_data_callback](char* ring_name, char* buffer, int buffer_size, - wifi_ring_buffer_status* status) { - if (status && buffer) { - std::vector buffer_vector( - reinterpret_cast(buffer), - reinterpret_cast(buffer) + buffer_size); - on_user_data_callback(ring_name, buffer_vector, *status); - } - }; - wifi_error status = global_func_table_.wifi_set_log_handler( - 0, getIfaceHandle(iface_name), {onAsyncRingBufferData}); - if (status != WIFI_SUCCESS) { - on_ring_buffer_data_internal_callback = nullptr; - } - return status; -} - -wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler( - const std::string& iface_name) { - if (!on_ring_buffer_data_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - on_ring_buffer_data_internal_callback = nullptr; - return global_func_table_.wifi_reset_log_handler( - 0, getIfaceHandle(iface_name)); -} - -std::pair> -WifiLegacyHal::getRingBuffersStatus(const std::string& iface_name) { - std::vector ring_buffers_status; - ring_buffers_status.resize(kMaxRingBuffers); - uint32_t num_rings = kMaxRingBuffers; - wifi_error status = global_func_table_.wifi_get_ring_buffers_status( - getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data()); - CHECK(num_rings <= kMaxRingBuffers); - ring_buffers_status.resize(num_rings); - return {status, std::move(ring_buffers_status)}; -} - -wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name, - const std::string& ring_name, - uint32_t verbose_level, - uint32_t max_interval_sec, - uint32_t min_data_size) { - return global_func_table_.wifi_start_logging( - getIfaceHandle(iface_name), verbose_level, 0, max_interval_sec, - min_data_size, makeCharVec(ring_name).data()); -} - -wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name, - const std::string& ring_name) { - return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name), - makeCharVec(ring_name).data()); -} - -wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler( - const std::string& iface_name, - const on_error_alert_callback& on_user_alert_callback) { - if (on_error_alert_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - on_error_alert_internal_callback = [on_user_alert_callback]( - wifi_request_id id, char* buffer, - int buffer_size, int err_code) { - if (buffer) { - CHECK(id == 0); - on_user_alert_callback( - err_code, - std::vector( - reinterpret_cast(buffer), - reinterpret_cast(buffer) + buffer_size)); - } - }; - wifi_error status = global_func_table_.wifi_set_alert_handler( - 0, getIfaceHandle(iface_name), {onAsyncErrorAlert}); - if (status != WIFI_SUCCESS) { - on_error_alert_internal_callback = nullptr; - } - return status; -} - -wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler( - const std::string& iface_name) { - if (!on_error_alert_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - on_error_alert_internal_callback = nullptr; - return global_func_table_.wifi_reset_alert_handler( - 0, getIfaceHandle(iface_name)); -} - -wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler( - const std::string& iface_name, - const on_radio_mode_change_callback& on_user_change_callback) { - if (on_radio_mode_change_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - on_radio_mode_change_internal_callback = [on_user_change_callback]( - wifi_request_id /* id */, - uint32_t num_macs, - wifi_mac_info* mac_infos_arr) { - if (num_macs > 0 && mac_infos_arr) { - std::vector mac_infos_vec; - for (uint32_t i = 0; i < num_macs; i++) { - WifiMacInfo mac_info; - mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id; - mac_info.mac_band = mac_infos_arr[i].mac_band; - for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) { - WifiIfaceInfo iface_info; - iface_info.name = mac_infos_arr[i].iface_info[j].iface_name; - iface_info.channel = mac_infos_arr[i].iface_info[j].channel; - mac_info.iface_infos.push_back(iface_info); - } - mac_infos_vec.push_back(mac_info); - } - on_user_change_callback(mac_infos_vec); - } - }; - wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler( - 0, getIfaceHandle(iface_name), {onAsyncRadioModeChange}); - if (status != WIFI_SUCCESS) { - on_radio_mode_change_internal_callback = nullptr; - } - return status; -} - -wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler( - const on_subsystem_restart_callback& on_restart_callback) { - if (on_subsystem_restart_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - on_subsystem_restart_internal_callback = - [on_restart_callback](const char* error) { - on_restart_callback(error); - }; - wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler( - global_handle_, {onAsyncSubsystemRestart}); - if (status != WIFI_SUCCESS) { - on_subsystem_restart_internal_callback = nullptr; - } - return status; -} - -wifi_error WifiLegacyHal::startRttRangeRequest( - const std::string& iface_name, wifi_request_id id, - const std::vector& rtt_configs, - const on_rtt_results_callback& on_results_user_callback) { - if (on_rtt_results_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - - on_rtt_results_internal_callback = - [on_results_user_callback](wifi_request_id id, unsigned num_results, - wifi_rtt_result* rtt_results[]) { - if (num_results > 0 && !rtt_results) { - LOG(ERROR) << "Unexpected nullptr in RTT results"; - return; - } - std::vector rtt_results_vec; - std::copy_if(rtt_results, rtt_results + num_results, - back_inserter(rtt_results_vec), - [](wifi_rtt_result* rtt_result) { - return rtt_result != nullptr; - }); - on_results_user_callback(id, rtt_results_vec); - }; - - std::vector rtt_configs_internal(rtt_configs); - wifi_error status = global_func_table_.wifi_rtt_range_request( - id, getIfaceHandle(iface_name), rtt_configs.size(), - rtt_configs_internal.data(), {onAsyncRttResults}); - if (status != WIFI_SUCCESS) { - on_rtt_results_internal_callback = nullptr; - } - return status; -} - -wifi_error WifiLegacyHal::cancelRttRangeRequest( - const std::string& iface_name, wifi_request_id id, - const std::vector>& mac_addrs) { - if (!on_rtt_results_internal_callback) { - return WIFI_ERROR_NOT_AVAILABLE; - } - static_assert(sizeof(mac_addr) == sizeof(std::array), - "MAC address size mismatch"); - // TODO: How do we handle partial cancels (i.e only a subset of enabled mac - // addressed are cancelled). - std::vector> mac_addrs_internal(mac_addrs); - wifi_error status = global_func_table_.wifi_rtt_range_cancel( - id, getIfaceHandle(iface_name), mac_addrs.size(), - reinterpret_cast(mac_addrs_internal.data())); - // If the request Id is wrong, don't stop the ongoing range request. Any - // other error should be treated as the end of rtt ranging. - if (status != WIFI_ERROR_INVALID_REQUEST_ID) { - on_rtt_results_internal_callback = nullptr; - } - return status; -} - -std::pair WifiLegacyHal::getRttCapabilities( - const std::string& iface_name) { - wifi_rtt_capabilities rtt_caps; - wifi_error status = global_func_table_.wifi_get_rtt_capabilities( - getIfaceHandle(iface_name), &rtt_caps); - return {status, rtt_caps}; -} - -std::pair WifiLegacyHal::getRttResponderInfo( - const std::string& iface_name) { - wifi_rtt_responder rtt_responder; - wifi_error status = global_func_table_.wifi_rtt_get_responder_info( - getIfaceHandle(iface_name), &rtt_responder); - return {status, rtt_responder}; -} - -wifi_error WifiLegacyHal::enableRttResponder( - const std::string& iface_name, wifi_request_id id, - const wifi_channel_info& channel_hint, uint32_t max_duration_secs, - const wifi_rtt_responder& info) { - wifi_rtt_responder info_internal(info); - return global_func_table_.wifi_enable_responder( - id, getIfaceHandle(iface_name), channel_hint, max_duration_secs, - &info_internal); -} - -wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, - wifi_request_id id) { - return global_func_table_.wifi_disable_responder( - id, getIfaceHandle(iface_name)); -} - -wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, - wifi_request_id id, - const wifi_lci_information& info) { - wifi_lci_information info_internal(info); - return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), - &info_internal); -} - -wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, - wifi_request_id id, - const wifi_lcr_information& info) { - wifi_lcr_information info_internal(info); - return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), - &info_internal); -} - -wifi_error WifiLegacyHal::nanRegisterCallbackHandlers( - const std::string& iface_name, const NanCallbackHandlers& user_callbacks) { - on_nan_notify_response_user_callback = user_callbacks.on_notify_response; - on_nan_event_publish_terminated_user_callback = - user_callbacks.on_event_publish_terminated; - on_nan_event_match_user_callback = user_callbacks.on_event_match; - on_nan_event_match_expired_user_callback = - user_callbacks.on_event_match_expired; - on_nan_event_subscribe_terminated_user_callback = - user_callbacks.on_event_subscribe_terminated; - on_nan_event_followup_user_callback = user_callbacks.on_event_followup; - on_nan_event_disc_eng_event_user_callback = - user_callbacks.on_event_disc_eng_event; - on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled; - on_nan_event_tca_user_callback = user_callbacks.on_event_tca; - on_nan_event_beacon_sdf_payload_user_callback = - user_callbacks.on_event_beacon_sdf_payload; - on_nan_event_data_path_request_user_callback = - user_callbacks.on_event_data_path_request; - on_nan_event_data_path_confirm_user_callback = - user_callbacks.on_event_data_path_confirm; - on_nan_event_data_path_end_user_callback = - user_callbacks.on_event_data_path_end; - on_nan_event_transmit_follow_up_user_callback = - user_callbacks.on_event_transmit_follow_up; - on_nan_event_range_request_user_callback = - user_callbacks.on_event_range_request; - on_nan_event_range_report_user_callback = - user_callbacks.on_event_range_report; - on_nan_event_schedule_update_user_callback = - user_callbacks.on_event_schedule_update; - - return global_func_table_.wifi_nan_register_handler( - getIfaceHandle(iface_name), - {onAysncNanNotifyResponse, onAysncNanEventPublishReplied, - onAysncNanEventPublishTerminated, onAysncNanEventMatch, - onAysncNanEventMatchExpired, onAysncNanEventSubscribeTerminated, - onAysncNanEventFollowup, onAysncNanEventDiscEngEvent, - onAysncNanEventDisabled, onAysncNanEventTca, - onAysncNanEventBeaconSdfPayload, onAysncNanEventDataPathRequest, - onAysncNanEventDataPathConfirm, onAysncNanEventDataPathEnd, - onAysncNanEventTransmitFollowUp, onAysncNanEventRangeRequest, - onAysncNanEventRangeReport, onAsyncNanEventScheduleUpdate}); -} - -wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, - transaction_id id, - const NanEnableRequest& msg) { - NanEnableRequest msg_internal(msg); - return global_func_table_.wifi_nan_enable_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, - transaction_id id) { - return global_func_table_.wifi_nan_disable_request( - id, getIfaceHandle(iface_name)); -} - -wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, - transaction_id id, - const NanPublishRequest& msg) { - NanPublishRequest msg_internal(msg); - return global_func_table_.wifi_nan_publish_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanPublishCancelRequest( - const std::string& iface_name, transaction_id id, - const NanPublishCancelRequest& msg) { - NanPublishCancelRequest msg_internal(msg); - return global_func_table_.wifi_nan_publish_cancel_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, - transaction_id id, - const NanSubscribeRequest& msg) { - NanSubscribeRequest msg_internal(msg); - return global_func_table_.wifi_nan_subscribe_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanSubscribeCancelRequest( - const std::string& iface_name, transaction_id id, - const NanSubscribeCancelRequest& msg) { - NanSubscribeCancelRequest msg_internal(msg); - return global_func_table_.wifi_nan_subscribe_cancel_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanTransmitFollowupRequest( - const std::string& iface_name, transaction_id id, - const NanTransmitFollowupRequest& msg) { - NanTransmitFollowupRequest msg_internal(msg); - return global_func_table_.wifi_nan_transmit_followup_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, - transaction_id id, - const NanStatsRequest& msg) { - NanStatsRequest msg_internal(msg); - return global_func_table_.wifi_nan_stats_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, - transaction_id id, - const NanConfigRequest& msg) { - NanConfigRequest msg_internal(msg); - return global_func_table_.wifi_nan_config_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, - transaction_id id, - const NanTCARequest& msg) { - NanTCARequest msg_internal(msg); - return global_func_table_.wifi_nan_tca_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest( - const std::string& iface_name, transaction_id id, - const NanBeaconSdfPayloadRequest& msg) { - NanBeaconSdfPayloadRequest msg_internal(msg); - return global_func_table_.wifi_nan_beacon_sdf_payload_request( - id, getIfaceHandle(iface_name), &msg_internal); -} - -std::pair WifiLegacyHal::nanGetVersion() { - NanVersion version; - wifi_error status = - global_func_table_.wifi_nan_get_version(global_handle_, &version); - return {status, version}; -} - -wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, - transaction_id id) { - return global_func_table_.wifi_nan_get_capabilities( - id, getIfaceHandle(iface_name)); -} - -wifi_error WifiLegacyHal::nanDataInterfaceCreate( - const std::string& iface_name, transaction_id id, - const std::string& data_iface_name) { - return global_func_table_.wifi_nan_data_interface_create( - id, getIfaceHandle(iface_name), makeCharVec(data_iface_name).data()); -} - -wifi_error WifiLegacyHal::nanDataInterfaceDelete( - const std::string& iface_name, transaction_id id, - const std::string& data_iface_name) { - return global_func_table_.wifi_nan_data_interface_delete( - id, getIfaceHandle(iface_name), makeCharVec(data_iface_name).data()); -} - -wifi_error WifiLegacyHal::nanDataRequestInitiator( - const std::string& iface_name, transaction_id id, - const NanDataPathInitiatorRequest& msg) { - NanDataPathInitiatorRequest msg_internal(msg); - return global_func_table_.wifi_nan_data_request_initiator( - id, getIfaceHandle(iface_name), &msg_internal); -} - -wifi_error WifiLegacyHal::nanDataIndicationResponse( - const std::string& iface_name, transaction_id id, - const NanDataPathIndicationResponse& msg) { - NanDataPathIndicationResponse msg_internal(msg); - return global_func_table_.wifi_nan_data_indication_response( - id, getIfaceHandle(iface_name), &msg_internal); -} - -typedef struct { - u8 num_ndp_instances; - NanDataPathId ndp_instance_id; -} NanDataPathEndSingleNdpIdRequest; - -wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, - transaction_id id, - uint32_t ndpInstanceId) { - NanDataPathEndSingleNdpIdRequest msg; - msg.num_ndp_instances = 1; - msg.ndp_instance_id = ndpInstanceId; - wifi_error status = global_func_table_.wifi_nan_data_end( - id, getIfaceHandle(iface_name), (NanDataPathEndRequest*)&msg); - return status; -} - -wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name, - std::array code) { - std::string code_str(code.data(), code.data() + code.size()); - return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), - code_str.c_str()); -} - -wifi_error WifiLegacyHal::retrieveIfaceHandles() { - wifi_interface_handle* iface_handles = nullptr; - int num_iface_handles = 0; - wifi_error status = global_func_table_.wifi_get_ifaces( - global_handle_, &num_iface_handles, &iface_handles); - if (status != WIFI_SUCCESS) { - LOG(ERROR) << "Failed to enumerate interface handles"; - return status; - } - iface_name_to_handle_.clear(); - for (int i = 0; i < num_iface_handles; ++i) { - std::array iface_name_arr = {}; - status = global_func_table_.wifi_get_iface_name( - iface_handles[i], iface_name_arr.data(), iface_name_arr.size()); - if (status != WIFI_SUCCESS) { - LOG(WARNING) << "Failed to get interface handle name"; - continue; - } - // Assuming the interface name is null terminated since the legacy HAL - // API does not return a size. - std::string iface_name(iface_name_arr.data()); - LOG(INFO) << "Adding interface handle for " << iface_name; - iface_name_to_handle_[iface_name] = iface_handles[i]; - } - return WIFI_SUCCESS; -} - -wifi_interface_handle WifiLegacyHal::getIfaceHandle( - const std::string& iface_name) { - const auto iface_handle_iter = iface_name_to_handle_.find(iface_name); - if (iface_handle_iter == iface_name_to_handle_.end()) { - LOG(ERROR) << "Unknown iface name: " << iface_name; - return nullptr; - } - return iface_handle_iter->second; -} - -void WifiLegacyHal::runEventLoop() { - LOG(DEBUG) << "Starting legacy HAL event loop"; - global_func_table_.wifi_event_loop(global_handle_); - const auto lock = hidl_sync_util::acquireGlobalLock(); - if (!awaiting_event_loop_termination_) { - LOG(FATAL) - << "Legacy HAL event loop terminated, but HAL was not stopping"; - } - LOG(DEBUG) << "Legacy HAL event loop terminated"; - awaiting_event_loop_termination_ = false; - stop_wait_cv_.notify_one(); -} - -std::pair> -WifiLegacyHal::getGscanCachedResults(const std::string& iface_name) { - std::vector cached_scan_results; - cached_scan_results.resize(kMaxCachedGscanResults); - int32_t num_results = 0; - wifi_error status = global_func_table_.wifi_get_cached_gscan_results( - getIfaceHandle(iface_name), true /* always flush */, - cached_scan_results.size(), cached_scan_results.data(), &num_results); - CHECK(num_results >= 0 && - static_cast(num_results) <= kMaxCachedGscanResults); - cached_scan_results.resize(num_results); - // Check for invalid IE lengths in these cached scan results and correct it. - for (auto& cached_scan_result : cached_scan_results) { - int num_scan_results = cached_scan_result.num_results; - for (int i = 0; i < num_scan_results; i++) { - auto& scan_result = cached_scan_result.results[i]; - if (scan_result.ie_length > 0) { - LOG(DEBUG) << "Cached scan result has non-zero IE length " - << scan_result.ie_length; - scan_result.ie_length = 0; - } - } - } - return {status, std::move(cached_scan_results)}; -} - -wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname, - wifi_interface_type iftype) { - // Create the interface if it doesn't exist. If interface already exist, - // Vendor Hal should return WIFI_SUCCESS. - wifi_error status = global_func_table_.wifi_virtual_interface_create( - global_handle_, ifname.c_str(), iftype); - return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status); -} - -wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) { - // Delete the interface if it was created dynamically. - wifi_error status = global_func_table_.wifi_virtual_interface_delete( - global_handle_, ifname.c_str()); - return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status); -} - -wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus( - const std::string& ifname, wifi_error status) { - if (status == WIFI_SUCCESS) { - // refresh list of handlers now. - status = retrieveIfaceHandles(); - } else if (status == WIFI_ERROR_NOT_SUPPORTED) { - // Vendor hal does not implement this API. Such vendor implementations - // are expected to create / delete interface by other means. - - // check if interface exists. - if (if_nametoindex(ifname.c_str())) { - status = retrieveIfaceHandles(); - } - } - return status; -} - -wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, - std::string& ifname) { - std::array buffer; - - wifi_error res = global_func_table_.wifi_get_supported_iface_name( - global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size()); - if (res == WIFI_SUCCESS) ifname = buffer.data(); - - return res; -} - -wifi_error WifiLegacyHal::multiStaSetPrimaryConnection( - const std::string& ifname) { - return global_func_table_.wifi_multi_sta_set_primary_connection( - global_handle_, getIfaceHandle(ifname)); -} - -wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) { - return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, - use_case); -} - -wifi_error WifiLegacyHal::setCoexUnsafeChannels( - std::vector unsafe_channels, - uint32_t restrictions) { - return global_func_table_.wifi_set_coex_unsafe_channels( - global_handle_, unsafe_channels.size(), unsafe_channels.data(), - restrictions); -} - -wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, - wifi_voip_mode mode) { - return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), - mode); -} - -wifi_error WifiLegacyHal::twtRegisterHandler( - const std::string& iface_name, const TwtCallbackHandlers& user_callbacks) { - on_twt_event_setup_response_callback = user_callbacks.on_setup_response; - on_twt_event_teardown_completion_callback = - user_callbacks.on_teardown_completion; - on_twt_event_info_frame_received_callback = - user_callbacks.on_info_frame_received; - on_twt_event_device_notify_callback = user_callbacks.on_device_notify; - - return global_func_table_.wifi_twt_register_handler( - getIfaceHandle(iface_name), - {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion, - onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify}); -} - -std::pair WifiLegacyHal::twtGetCapability( - const std::string& iface_name) { - TwtCapabilitySet capSet; - wifi_error status = global_func_table_.wifi_twt_get_capability( - getIfaceHandle(iface_name), &capSet); - return {status, capSet}; -} - -wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name, - const TwtSetupRequest& msg) { - TwtSetupRequest msgInternal(msg); - return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), - &msgInternal); -} - -wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name, - const TwtTeardownRequest& msg) { - TwtTeardownRequest msgInternal(msg); - return global_func_table_.wifi_twt_teardown_request( - getIfaceHandle(iface_name), &msgInternal); -} - -wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name, - const TwtInfoFrameRequest& msg) { - TwtInfoFrameRequest msgInternal(msg); - return global_func_table_.wifi_twt_info_frame_request( - getIfaceHandle(iface_name), &msgInternal); -} - -std::pair WifiLegacyHal::twtGetStats( - const std::string& iface_name, uint8_t configId) { - TwtStats stats; - wifi_error status = global_func_table_.wifi_twt_get_stats( - getIfaceHandle(iface_name), configId, &stats); - return {status, stats}; -} - -wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, - uint8_t configId) { - return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), - configId); -} - -wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, - uint32_t multiplier) { - return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), - multiplier); -} - -std::pair> -WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask, - uint32_t filter_mask) { - std::vector channels; - channels.resize(kMaxWifiUsableChannels); - uint32_t size = 0; - wifi_error status = global_func_table_.wifi_get_usable_channels( - global_handle_, band_mask, iface_mode_mask, filter_mask, - channels.size(), &size, - reinterpret_cast(channels.data())); - CHECK(size >= 0 && size <= kMaxWifiUsableChannels); - channels.resize(size); - return {status, std::move(channels)}; -} - -wifi_error WifiLegacyHal::triggerSubsystemRestart() { - return global_func_table_.wifi_trigger_subsystem_restart(global_handle_); -} - -void WifiLegacyHal::invalidate() { - global_handle_ = nullptr; - iface_name_to_handle_.clear(); - on_driver_memory_dump_internal_callback = nullptr; - on_firmware_memory_dump_internal_callback = nullptr; - on_gscan_event_internal_callback = nullptr; - on_gscan_full_result_internal_callback = nullptr; - on_link_layer_stats_result_internal_callback = nullptr; - on_rssi_threshold_breached_internal_callback = nullptr; - on_ring_buffer_data_internal_callback = nullptr; - on_error_alert_internal_callback = nullptr; - on_radio_mode_change_internal_callback = nullptr; - on_subsystem_restart_internal_callback = nullptr; - on_rtt_results_internal_callback = nullptr; - on_nan_notify_response_user_callback = nullptr; - on_nan_event_publish_terminated_user_callback = nullptr; - on_nan_event_match_user_callback = nullptr; - on_nan_event_match_expired_user_callback = nullptr; - on_nan_event_subscribe_terminated_user_callback = nullptr; - on_nan_event_followup_user_callback = nullptr; - on_nan_event_disc_eng_event_user_callback = nullptr; - on_nan_event_disabled_user_callback = nullptr; - on_nan_event_tca_user_callback = nullptr; - on_nan_event_beacon_sdf_payload_user_callback = nullptr; - on_nan_event_data_path_request_user_callback = nullptr; - on_nan_event_data_path_confirm_user_callback = nullptr; - on_nan_event_data_path_end_user_callback = nullptr; - on_nan_event_transmit_follow_up_user_callback = nullptr; - on_nan_event_range_request_user_callback = nullptr; - on_nan_event_range_report_user_callback = nullptr; - on_nan_event_schedule_update_user_callback = nullptr; - on_twt_event_setup_response_callback = nullptr; - on_twt_event_teardown_completion_callback = nullptr; - on_twt_event_info_frame_received_callback = nullptr; - on_twt_event_device_notify_callback = nullptr; -} - -} // namespace legacy_hal -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h deleted file mode 100644 index 2bb7631efa..0000000000 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ /dev/null @@ -1,763 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_LEGACY_HAL_H_ -#define WIFI_LEGACY_HAL_H_ - -#include -#include -#include -#include -#include - -#include -#include - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -// This is in a separate namespace to prevent typename conflicts between -// the legacy HAL types and the HIDL interface types. -namespace legacy_hal { -// Import all the types defined inside the legacy HAL header files into this -// namespace. -using ::frame_info; -using ::frame_type; -using ::FRAME_TYPE_80211_MGMT; -using ::FRAME_TYPE_ETHERNET_II; -using ::FRAME_TYPE_UNKNOWN; -using ::fw_roaming_state_t; -using ::mac_addr; -using ::NAN_CHANNEL_24G_BAND; -using ::NAN_CHANNEL_5G_BAND_HIGH; -using ::NAN_CHANNEL_5G_BAND_LOW; -using ::NAN_DISABLE_RANGE_REPORT; -using ::NAN_DO_NOT_USE_SRF; -using ::NAN_DP_CHANNEL_NOT_REQUESTED; -using ::NAN_DP_CONFIG_NO_SECURITY; -using ::NAN_DP_CONFIG_SECURITY; -using ::NAN_DP_END; -using ::NAN_DP_FORCE_CHANNEL_SETUP; -using ::NAN_DP_INITIATOR_RESPONSE; -using ::NAN_DP_INTERFACE_CREATE; -using ::NAN_DP_INTERFACE_DELETE; -using ::NAN_DP_REQUEST_ACCEPT; -using ::NAN_DP_REQUEST_CHANNEL_SETUP; -using ::NAN_DP_REQUEST_REJECT; -using ::NAN_DP_RESPONDER_RESPONSE; -using ::NAN_GET_CAPABILITIES; -using ::NAN_MATCH_ALG_MATCH_CONTINUOUS; -using ::NAN_MATCH_ALG_MATCH_NEVER; -using ::NAN_MATCH_ALG_MATCH_ONCE; -using ::NAN_PUBLISH_TYPE_SOLICITED; -using ::NAN_PUBLISH_TYPE_UNSOLICITED; -using ::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED; -using ::NAN_RANGING_AUTO_RESPONSE_DISABLE; -using ::NAN_RANGING_AUTO_RESPONSE_ENABLE; -using ::NAN_RANGING_DISABLE; -using ::NAN_RANGING_ENABLE; -using ::NAN_RESPONSE_BEACON_SDF_PAYLOAD; -using ::NAN_RESPONSE_CONFIG; -using ::NAN_RESPONSE_DISABLED; -using ::NAN_RESPONSE_ENABLED; -using ::NAN_RESPONSE_ERROR; -using ::NAN_RESPONSE_PUBLISH; -using ::NAN_RESPONSE_PUBLISH_CANCEL; -using ::NAN_RESPONSE_STATS; -using ::NAN_RESPONSE_SUBSCRIBE; -using ::NAN_RESPONSE_SUBSCRIBE_CANCEL; -using ::NAN_RESPONSE_TCA; -using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP; -using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE; -using ::NAN_SECURITY_KEY_INPUT_PMK; -using ::NAN_SERVICE_ACCEPT_POLICY_ALL; -using ::NAN_SERVICE_ACCEPT_POLICY_NONE; -using ::NAN_SRF_ATTR_BLOOM_FILTER; -using ::NAN_SRF_ATTR_PARTIAL_MAC_ADDR; -using ::NAN_SRF_INCLUDE_DO_NOT_RESPOND; -using ::NAN_SRF_INCLUDE_RESPOND; -using ::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND; -using ::NAN_SSI_REQUIRED_IN_MATCH_IND; -using ::NAN_STATUS_ALREADY_ENABLED; -using ::NAN_STATUS_FOLLOWUP_QUEUE_FULL; -using ::NAN_STATUS_INTERNAL_FAILURE; -using ::NAN_STATUS_INVALID_NDP_ID; -using ::NAN_STATUS_INVALID_PARAM; -using ::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID; -using ::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID; -using ::NAN_STATUS_NAN_NOT_ALLOWED; -using ::NAN_STATUS_NO_OTA_ACK; -using ::NAN_STATUS_NO_RESOURCE_AVAILABLE; -using ::NAN_STATUS_PROTOCOL_FAILURE; -using ::NAN_STATUS_SUCCESS; -using ::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED; -using ::NAN_SUBSCRIBE_TYPE_ACTIVE; -using ::NAN_SUBSCRIBE_TYPE_PASSIVE; -using ::NAN_TRANSMIT_IN_DW; -using ::NAN_TRANSMIT_IN_FAW; -using ::NAN_TX_PRIORITY_HIGH; -using ::NAN_TX_PRIORITY_NORMAL; -using ::NAN_TX_TYPE_BROADCAST; -using ::NAN_TX_TYPE_UNICAST; -using ::NAN_USE_SRF; -using ::NanBeaconSdfPayloadInd; -using ::NanCapabilities; -using ::NanChannelInfo; -using ::NanConfigRequest; -using ::NanDataPathChannelCfg; -using ::NanDataPathConfirmInd; -using ::NanDataPathEndInd; -using ::NanDataPathIndicationResponse; -using ::NanDataPathInitiatorRequest; -using ::NanDataPathRequestInd; -using ::NanDataPathScheduleUpdateInd; -using ::NanDisabledInd; -using ::NanDiscEngEventInd; -using ::NanEnableRequest; -using ::NanFollowupInd; -using ::NanMatchAlg; -using ::NanMatchExpiredInd; -using ::NanMatchInd; -using ::NanPublishCancelRequest; -using ::NanPublishRequest; -using ::NanPublishTerminatedInd; -using ::NanPublishType; -using ::NanRangeReportInd; -using ::NanRangeRequestInd; -using ::NanResponseMsg; -using ::NanSRFType; -using ::NanStatusType; -using ::NanSubscribeCancelRequest; -using ::NanSubscribeRequest; -using ::NanSubscribeTerminatedInd; -using ::NanSubscribeType; -using ::NanTransmitFollowupInd; -using ::NanTransmitFollowupRequest; -using ::NanTxType; -using ::ROAMING_DISABLE; -using ::ROAMING_ENABLE; -using ::RTT_PEER_AP; -using ::RTT_PEER_NAN; -using ::RTT_PEER_P2P_CLIENT; -using ::RTT_PEER_P2P_GO; -using ::RTT_PEER_STA; -using ::rtt_peer_type; -using ::RTT_STATUS_ABORTED; -using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL; -using ::RTT_STATUS_FAIL_BUSY_TRY_LATER; -using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE; -using ::RTT_STATUS_FAIL_INVALID_TS; -using ::RTT_STATUS_FAIL_NO_CAPABILITY; -using ::RTT_STATUS_FAIL_NO_RSP; -using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET; -using ::RTT_STATUS_FAIL_PROTOCOL; -using ::RTT_STATUS_FAIL_REJECTED; -using ::RTT_STATUS_FAIL_SCHEDULE; -using ::RTT_STATUS_FAIL_TM_TIMEOUT; -using ::RTT_STATUS_FAILURE; -using ::RTT_STATUS_INVALID_REQ; -using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED; -using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE; -using ::RTT_STATUS_NO_WIFI; -using ::RTT_STATUS_SUCCESS; -using ::RTT_TYPE_1_SIDED; -using ::RTT_TYPE_2_SIDED; -using ::RX_PKT_FATE_DRV_DROP_FILTER; -using ::RX_PKT_FATE_DRV_DROP_INVALID; -using ::RX_PKT_FATE_DRV_DROP_NOBUFS; -using ::RX_PKT_FATE_DRV_DROP_OTHER; -using ::RX_PKT_FATE_DRV_QUEUED; -using ::RX_PKT_FATE_FW_DROP_FILTER; -using ::RX_PKT_FATE_FW_DROP_INVALID; -using ::RX_PKT_FATE_FW_DROP_NOBUFS; -using ::RX_PKT_FATE_FW_DROP_OTHER; -using ::RX_PKT_FATE_FW_QUEUED; -using ::RX_PKT_FATE_SUCCESS; -using ::ssid_t; -using ::transaction_id; -using ::TX_PKT_FATE_ACKED; -using ::TX_PKT_FATE_DRV_DROP_INVALID; -using ::TX_PKT_FATE_DRV_DROP_NOBUFS; -using ::TX_PKT_FATE_DRV_DROP_OTHER; -using ::TX_PKT_FATE_DRV_QUEUED; -using ::TX_PKT_FATE_FW_DROP_INVALID; -using ::TX_PKT_FATE_FW_DROP_NOBUFS; -using ::TX_PKT_FATE_FW_DROP_OTHER; -using ::TX_PKT_FATE_FW_QUEUED; -using ::TX_PKT_FATE_SENT; -using ::WIFI_AC_BE; -using ::WIFI_AC_BK; -using ::WIFI_AC_VI; -using ::WIFI_AC_VO; -using ::wifi_band; -using ::WIFI_BAND_A; -using ::WIFI_BAND_A_DFS; -using ::WIFI_BAND_A_WITH_DFS; -using ::WIFI_BAND_ABG; -using ::WIFI_BAND_ABG_WITH_DFS; -using ::WIFI_BAND_BG; -using ::WIFI_BAND_UNSPECIFIED; -using ::wifi_cached_scan_results; -using ::WIFI_CHAN_WIDTH_10; -using ::WIFI_CHAN_WIDTH_160; -using ::WIFI_CHAN_WIDTH_20; -using ::WIFI_CHAN_WIDTH_40; -using ::WIFI_CHAN_WIDTH_5; -using ::WIFI_CHAN_WIDTH_80; -using ::WIFI_CHAN_WIDTH_80P80; -using ::WIFI_CHAN_WIDTH_INVALID; -using ::wifi_channel_info; -using ::wifi_channel_stat; -using ::wifi_channel_width; -using ::wifi_coex_restriction; -using ::wifi_coex_unsafe_channel; -using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED; -using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY; -using ::wifi_error; -using ::WIFI_ERROR_BUSY; -using ::WIFI_ERROR_INVALID_ARGS; -using ::WIFI_ERROR_INVALID_REQUEST_ID; -using ::WIFI_ERROR_NONE; -using ::WIFI_ERROR_NOT_AVAILABLE; -using ::WIFI_ERROR_NOT_SUPPORTED; -using ::WIFI_ERROR_OUT_OF_MEMORY; -using ::WIFI_ERROR_TIMED_OUT; -using ::WIFI_ERROR_TOO_MANY_REQUESTS; -using ::WIFI_ERROR_UNINITIALIZED; -using ::WIFI_ERROR_UNKNOWN; -using ::wifi_gscan_capabilities; -using ::wifi_hal_fn; -using ::wifi_information_element; -using ::WIFI_INTERFACE_IBSS; -using ::WIFI_INTERFACE_MESH; -using ::wifi_interface_mode; -using ::WIFI_INTERFACE_NAN; -using ::WIFI_INTERFACE_P2P_CLIENT; -using ::WIFI_INTERFACE_P2P_GO; -using ::WIFI_INTERFACE_SOFTAP; -using ::WIFI_INTERFACE_STA; -using ::WIFI_INTERFACE_TDLS; -using ::wifi_interface_type; -using ::WIFI_INTERFACE_TYPE_AP; -using ::WIFI_INTERFACE_TYPE_NAN; -using ::WIFI_INTERFACE_TYPE_P2P; -using ::WIFI_INTERFACE_TYPE_STA; -using ::WIFI_INTERFACE_UNKNOWN; -using ::wifi_latency_mode; -using ::WIFI_LATENCY_MODE_LOW; -using ::WIFI_LATENCY_MODE_NORMAL; -using ::wifi_lci_information; -using ::wifi_lcr_information; -using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED; -using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; -using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED; -using ::WIFI_LOGGER_PACKET_FATE_SUPPORTED; -using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED; -using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED; -using ::WIFI_MOTION_EXPECTED; -using ::WIFI_MOTION_NOT_EXPECTED; -using ::wifi_motion_pattern; -using ::WIFI_MOTION_UNKNOWN; -using ::wifi_multi_sta_use_case; -using ::wifi_power_scenario; -using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF; -using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON; -using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF; -using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON; -using ::WIFI_POWER_SCENARIO_VOICE_CALL; -using ::wifi_rate; -using ::wifi_request_id; -using ::wifi_ring_buffer_status; -using ::wifi_roaming_capabilities; -using ::wifi_roaming_config; -using ::wifi_rtt_bw; -using ::WIFI_RTT_BW_10; -using ::WIFI_RTT_BW_160; -using ::WIFI_RTT_BW_20; -using ::WIFI_RTT_BW_40; -using ::WIFI_RTT_BW_5; -using ::WIFI_RTT_BW_80; -using ::wifi_rtt_capabilities; -using ::wifi_rtt_config; -using ::wifi_rtt_preamble; -using ::WIFI_RTT_PREAMBLE_HE; -using ::WIFI_RTT_PREAMBLE_HT; -using ::WIFI_RTT_PREAMBLE_LEGACY; -using ::WIFI_RTT_PREAMBLE_VHT; -using ::wifi_rtt_responder; -using ::wifi_rtt_result; -using ::wifi_rtt_status; -using ::wifi_rtt_type; -using ::wifi_rx_packet_fate; -using ::wifi_rx_report; -using ::wifi_scan_bucket_spec; -using ::wifi_scan_cmd_params; -using ::WIFI_SCAN_FLAG_INTERRUPTED; -using ::wifi_scan_result; -using ::WIFI_SUCCESS; -using ::wifi_tx_packet_fate; -using ::wifi_tx_report; -using ::wifi_usable_channel; -using ::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE; -using ::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY; -using ::WLAN_MAC_2_4_BAND; -using ::WLAN_MAC_5_0_BAND; -using ::WLAN_MAC_60_0_BAND; -using ::WLAN_MAC_6_0_BAND; - -// APF capabilities supported by the iface. -struct PacketFilterCapabilities { - uint32_t version; - uint32_t max_len; -}; - -// WARNING: We don't care about the variable sized members of either -// |wifi_iface_stat|, |wifi_radio_stat| structures. So, using the pragma -// to escape the compiler warnings regarding this. -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wgnu-variable-sized-type-not-at-end" -// The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in -// |wifi_radio_stat| structure in the legacy HAL API. Separate that out -// into a separate return element to avoid passing pointers around. -struct LinkLayerRadioStats { - wifi_radio_stat stats; - std::vector tx_time_per_levels; - std::vector channel_stats; -}; - -struct WifiPeerInfo { - wifi_peer_info peer_info; - std::vector rate_stats; -}; - -struct LinkLayerStats { - wifi_iface_stat iface; - std::vector radios; - std::vector peers; -}; -#pragma GCC diagnostic pop - -// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and -// |WLAN_DRIVER_WAKE_REASON_CNT.driver_fw_local_wake_cnt| stats is provided -// as a pointer in |WLAN_DRIVER_WAKE_REASON_CNT| structure in the legacy HAL -// API. Separate that out into a separate return elements to avoid passing -// pointers around. -struct WakeReasonStats { - WLAN_DRIVER_WAKE_REASON_CNT wake_reason_cnt; - std::vector cmd_event_wake_cnt; - std::vector driver_fw_local_wake_cnt; -}; - -// NAN response and event callbacks struct. -struct NanCallbackHandlers { - // NotifyResponse invoked to notify the status of the Request. - std::function - on_notify_response; - // Various event callbacks. - std::function - on_event_publish_terminated; - std::function on_event_match; - std::function on_event_match_expired; - std::function - on_event_subscribe_terminated; - std::function on_event_followup; - std::function on_event_disc_eng_event; - std::function on_event_disabled; - std::function on_event_tca; - std::function - on_event_beacon_sdf_payload; - std::function - on_event_data_path_request; - std::function - on_event_data_path_confirm; - std::function on_event_data_path_end; - std::function - on_event_transmit_follow_up; - std::function on_event_range_request; - std::function on_event_range_report; - std::function - on_event_schedule_update; -}; - -// Full scan results contain IE info and are hence passed by reference, to -// preserve the variable length array member |ie_data|. Callee must not retain -// the pointer. -using on_gscan_full_result_callback = - std::function; -// These scan results don't contain any IE info, so no need to pass by -// reference. -using on_gscan_results_callback = std::function&)>; - -// Invoked when the rssi value breaches the thresholds set. -using on_rssi_threshold_breached_callback = - std::function, int8_t)>; - -// Callback for RTT range request results. -// Rtt results contain IE info and are hence passed by reference, to -// preserve the |LCI| and |LCR| pointers. Callee must not retain -// the pointer. -using on_rtt_results_callback = std::function&)>; - -// Callback for ring buffer data. -using on_ring_buffer_data_callback = - std::function&, - const wifi_ring_buffer_status&)>; - -// Callback for alerts. -using on_error_alert_callback = - std::function&)>; - -// Callback for subsystem restart -using on_subsystem_restart_callback = std::function; - -// Struct for the mac info from the legacy HAL. This is a cleaner version -// of the |wifi_mac_info| & |wifi_iface_info|. -typedef struct { - std::string name; - wifi_channel channel; -} WifiIfaceInfo; - -typedef struct { - uint32_t wlan_mac_id; - /* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */ - uint32_t mac_band; - /* Represents the connected Wi-Fi interfaces associated with each MAC */ - std::vector iface_infos; -} WifiMacInfo; - -// Callback for radio mode change -using on_radio_mode_change_callback = - std::function&)>; - -// TWT response and event callbacks struct. -struct TwtCallbackHandlers { - // Callback for TWT setup response - std::function on_setup_response; - // Callback for TWT teardown completion - std::function on_teardown_completion; - // Callback for TWT info frame received event - std::function on_info_frame_received; - // Callback for TWT notification from the device - std::function on_device_notify; -}; - -/** - * Class that encapsulates all legacy HAL interactions. - * This class manages the lifetime of the event loop thread used by legacy HAL. - * - * Note: There will only be a single instance of this class created in the Wifi - * object and will be valid for the lifetime of the process. - */ -class WifiLegacyHal { - public: - WifiLegacyHal(const std::weak_ptr iface_tool, - const wifi_hal_fn& fn, bool is_primary); - virtual ~WifiLegacyHal() = default; - - // Initialize the legacy HAL function table. - virtual wifi_error initialize(); - // Start the legacy HAL and the event looper thread. - virtual wifi_error start(); - // Deinitialize the legacy HAL and wait for the event loop thread to exit - // using a predefined timeout. - virtual wifi_error stop(std::unique_lock* lock, - const std::function& on_complete_callback); - virtual wifi_error waitForDriverReady(); - // Checks if legacy HAL has successfully started - bool isStarted(); - // Wrappers for all the functions in the legacy HAL function table. - virtual std::pair getDriverVersion( - const std::string& iface_name); - virtual std::pair getFirmwareVersion( - const std::string& iface_name); - std::pair> requestDriverMemoryDump( - const std::string& iface_name); - std::pair> requestFirmwareMemoryDump( - const std::string& iface_name); - std::pair getSupportedFeatureSet( - const std::string& iface_name); - // APF functions. - std::pair getPacketFilterCapabilities( - const std::string& iface_name); - wifi_error setPacketFilter(const std::string& iface_name, - const std::vector& program); - std::pair> readApfPacketFilterData( - const std::string& iface_name); - // Gscan functions. - std::pair getGscanCapabilities( - const std::string& iface_name); - // These API's provides a simplified interface over the legacy Gscan API's: - // a) All scan events from the legacy HAL API other than the - // |WIFI_SCAN_FAILED| are treated as notification of results. - // This method then retrieves the cached scan results from the legacy - // HAL API and triggers the externally provided - // |on_results_user_callback| on success. - // b) |WIFI_SCAN_FAILED| scan event or failure to retrieve cached scan - // results - // triggers the externally provided |on_failure_user_callback|. - // c) Full scan result event triggers the externally provided - // |on_full_result_user_callback|. - wifi_error startGscan( - const std::string& iface_name, wifi_request_id id, - const wifi_scan_cmd_params& params, - const std::function& on_failure_callback, - const on_gscan_results_callback& on_results_callback, - const on_gscan_full_result_callback& on_full_result_callback); - wifi_error stopGscan(const std::string& iface_name, wifi_request_id id); - std::pair> getValidFrequenciesForBand( - const std::string& iface_name, wifi_band band); - virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on); - // Link layer stats functions. - wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug); - wifi_error disableLinkLayerStats(const std::string& iface_name); - std::pair getLinkLayerStats( - const std::string& iface_name); - // RSSI monitor functions. - wifi_error startRssiMonitoring(const std::string& iface_name, - wifi_request_id id, int8_t max_rssi, - int8_t min_rssi, - const on_rssi_threshold_breached_callback& - on_threshold_breached_callback); - wifi_error stopRssiMonitoring(const std::string& iface_name, - wifi_request_id id); - std::pair getRoamingCapabilities( - const std::string& iface_name); - wifi_error configureRoaming(const std::string& iface_name, - const wifi_roaming_config& config); - wifi_error enableFirmwareRoaming(const std::string& iface_name, - fw_roaming_state_t state); - wifi_error configureNdOffload(const std::string& iface_name, bool enable); - wifi_error startSendingOffloadedPacket( - const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type, - const std::vector& ip_packet_data, - const std::array& src_address, - const std::array& dst_address, uint32_t period_in_ms); - wifi_error stopSendingOffloadedPacket(const std::string& iface_name, - uint32_t cmd_id); - virtual wifi_error selectTxPowerScenario(const std::string& iface_name, - wifi_power_scenario scenario); - virtual wifi_error resetTxPowerScenario(const std::string& iface_name); - wifi_error setLatencyMode(const std::string& iface_name, - wifi_latency_mode mode); - wifi_error setThermalMitigationMode(wifi_thermal_mode mode, - uint32_t completion_window); - wifi_error setDscpToAccessCategoryMapping(uint32_t start, uint32_t end, - uint32_t access_category); - wifi_error resetDscpToAccessCategoryMapping(); - // Logger/debug functions. - std::pair getLoggerSupportedFeatureSet( - const std::string& iface_name); - wifi_error startPktFateMonitoring(const std::string& iface_name); - std::pair> getTxPktFates( - const std::string& iface_name); - std::pair> getRxPktFates( - const std::string& iface_name); - std::pair getWakeReasonStats( - const std::string& iface_name); - wifi_error registerRingBufferCallbackHandler( - const std::string& iface_name, - const on_ring_buffer_data_callback& on_data_callback); - wifi_error deregisterRingBufferCallbackHandler( - const std::string& iface_name); - wifi_error registerSubsystemRestartCallbackHandler( - const on_subsystem_restart_callback& on_restart_callback); - std::pair> - getRingBuffersStatus(const std::string& iface_name); - wifi_error startRingBufferLogging(const std::string& iface_name, - const std::string& ring_name, - uint32_t verbose_level, - uint32_t max_interval_sec, - uint32_t min_data_size); - wifi_error getRingBufferData(const std::string& iface_name, - const std::string& ring_name); - wifi_error registerErrorAlertCallbackHandler( - const std::string& iface_name, - const on_error_alert_callback& on_alert_callback); - wifi_error deregisterErrorAlertCallbackHandler( - const std::string& iface_name); - // Radio mode functions. - virtual wifi_error registerRadioModeChangeCallbackHandler( - const std::string& iface_name, - const on_radio_mode_change_callback& on_user_change_callback); - // RTT functions. - wifi_error startRttRangeRequest( - const std::string& iface_name, wifi_request_id id, - const std::vector& rtt_configs, - const on_rtt_results_callback& on_results_callback); - wifi_error cancelRttRangeRequest( - const std::string& iface_name, wifi_request_id id, - const std::vector>& mac_addrs); - std::pair getRttCapabilities( - const std::string& iface_name); - std::pair getRttResponderInfo( - const std::string& iface_name); - wifi_error enableRttResponder(const std::string& iface_name, - wifi_request_id id, - const wifi_channel_info& channel_hint, - uint32_t max_duration_secs, - const wifi_rtt_responder& info); - wifi_error disableRttResponder(const std::string& iface_name, - wifi_request_id id); - wifi_error setRttLci(const std::string& iface_name, wifi_request_id id, - const wifi_lci_information& info); - wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id, - const wifi_lcr_information& info); - // NAN functions. - virtual wifi_error nanRegisterCallbackHandlers( - const std::string& iface_name, const NanCallbackHandlers& callbacks); - wifi_error nanEnableRequest(const std::string& iface_name, - transaction_id id, const NanEnableRequest& msg); - virtual wifi_error nanDisableRequest(const std::string& iface_name, - transaction_id id); - wifi_error nanPublishRequest(const std::string& iface_name, - transaction_id id, - const NanPublishRequest& msg); - wifi_error nanPublishCancelRequest(const std::string& iface_name, - transaction_id id, - const NanPublishCancelRequest& msg); - wifi_error nanSubscribeRequest(const std::string& iface_name, - transaction_id id, - const NanSubscribeRequest& msg); - wifi_error nanSubscribeCancelRequest(const std::string& iface_name, - transaction_id id, - const NanSubscribeCancelRequest& msg); - wifi_error nanTransmitFollowupRequest( - const std::string& iface_name, transaction_id id, - const NanTransmitFollowupRequest& msg); - wifi_error nanStatsRequest(const std::string& iface_name, transaction_id id, - const NanStatsRequest& msg); - wifi_error nanConfigRequest(const std::string& iface_name, - transaction_id id, const NanConfigRequest& msg); - wifi_error nanTcaRequest(const std::string& iface_name, transaction_id id, - const NanTCARequest& msg); - wifi_error nanBeaconSdfPayloadRequest( - const std::string& iface_name, transaction_id id, - const NanBeaconSdfPayloadRequest& msg); - std::pair nanGetVersion(); - wifi_error nanGetCapabilities(const std::string& iface_name, - transaction_id id); - wifi_error nanDataInterfaceCreate(const std::string& iface_name, - transaction_id id, - const std::string& data_iface_name); - virtual wifi_error nanDataInterfaceDelete( - const std::string& iface_name, transaction_id id, - const std::string& data_iface_name); - wifi_error nanDataRequestInitiator(const std::string& iface_name, - transaction_id id, - const NanDataPathInitiatorRequest& msg); - wifi_error nanDataIndicationResponse( - const std::string& iface_name, transaction_id id, - const NanDataPathIndicationResponse& msg); - wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, - uint32_t ndpInstanceId); - // AP functions. - wifi_error setCountryCode(const std::string& iface_name, - std::array code); - - // interface functions. - virtual wifi_error createVirtualInterface(const std::string& ifname, - wifi_interface_type iftype); - virtual wifi_error deleteVirtualInterface(const std::string& ifname); - wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname); - - // STA + STA functions - virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname); - virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case); - - // Coex functions. - virtual wifi_error setCoexUnsafeChannels( - std::vector unsafe_channels, - uint32_t restrictions); - - wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode); - - wifi_error twtRegisterHandler(const std::string& iface_name, - const TwtCallbackHandlers& handler); - - std::pair twtGetCapability( - const std::string& iface_name); - - wifi_error twtSetupRequest(const std::string& iface_name, - const TwtSetupRequest& msg); - - wifi_error twtTearDownRequest(const std::string& iface_name, - const TwtTeardownRequest& msg); - - wifi_error twtInfoFrameRequest(const std::string& iface_name, - const TwtInfoFrameRequest& msg); - - std::pair twtGetStats(const std::string& iface_name, - uint8_t configId); - - wifi_error twtClearStats(const std::string& iface_name, uint8_t configId); - - wifi_error setDtimConfig(const std::string& iface_name, - uint32_t multiplier); - - // Retrieve the list of usable channels in the requested bands - // for the requested modes - std::pair> getUsableChannels( - uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask); - - wifi_error triggerSubsystemRestart(); - - private: - // Retrieve interface handles for all the available interfaces. - wifi_error retrieveIfaceHandles(); - wifi_interface_handle getIfaceHandle(const std::string& iface_name); - // Run the legacy HAL event loop thread. - void runEventLoop(); - // Retrieve the cached gscan results to pass the results back to the - // external callbacks. - std::pair> - getGscanCachedResults(const std::string& iface_name); - void invalidate(); - // Handles wifi (error) status of Virtual interface create/delete - wifi_error handleVirtualInterfaceCreateOrDeleteStatus( - const std::string& ifname, wifi_error status); - - // Global function table of legacy HAL. - wifi_hal_fn global_func_table_; - // Opaque handle to be used for all global operations. - wifi_handle global_handle_; - // Map of interface name to handle that is to be used for all interface - // specific operations. - std::map iface_name_to_handle_; - // Flag to indicate if we have initiated the cleanup of legacy HAL. - std::atomic awaiting_event_loop_termination_; - std::condition_variable_any stop_wait_cv_; - // Flag to indicate if the legacy HAL has been started. - bool is_started_; - std::weak_ptr iface_tool_; - // flag to indicate if this HAL is for the primary chip. This is used - // in order to avoid some hard-coded behavior used with older HALs, - // such as bring wlan0 interface up/down on start/stop HAL. - // it may be removed once vendor HALs are updated. - bool is_primary_; -}; - -} // namespace legacy_hal -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_LEGACY_HAL_H_ diff --git a/wifi/1.5/default/wifi_legacy_hal_factory.cpp b/wifi/1.5/default/wifi_legacy_hal_factory.cpp deleted file mode 100644 index fbaa284f56..0000000000 --- a/wifi/1.5/default/wifi_legacy_hal_factory.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "wifi_legacy_hal_factory.h" -#include "wifi_legacy_hal_stubs.h" - -namespace { -static constexpr char kVendorHalsDescPath[] = "/vendor/etc/wifi/vendor_hals"; -static constexpr char kVendorHalsDescExt[] = ".xml"; -static constexpr uint32_t kVendorHalsDescVersion = 1; - -bool isDirectory(struct dirent* entryPtr) { - bool isDir = false; - if (entryPtr->d_type != DT_UNKNOWN && entryPtr->d_type != DT_LNK) { - isDir = (entryPtr->d_type == DT_DIR); - } else { - struct stat entryStat; - stat(entryPtr->d_name, &entryStat); - isDir = S_ISDIR(entryStat.st_mode); - } - return isDir; -} - -bool isFileExtension(const char* name, const char* ext) { - if (name == NULL) return false; - if (ext == NULL) return false; - - size_t extLen = strlen(ext); - size_t nameLen = strlen(name); - - if (extLen > nameLen) return false; - - if (strncmp(name + nameLen - extLen, ext, extLen) != 0) return false; - - return true; -} -}; // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace legacy_hal { - -WifiLegacyHalFactory::WifiLegacyHalFactory( - const std::weak_ptr iface_tool) - : iface_tool_(iface_tool) {} - -std::vector> WifiLegacyHalFactory::getHals() { - if (legacy_hals_.empty()) { - if (!initVendorHalDescriptorFromLinked()) - initVendorHalsDescriptorList(); - for (auto& desc : descs_) { - std::shared_ptr hal = - std::make_shared(iface_tool_, desc.fn, - desc.primary); - legacy_hals_.push_back(hal); - } - } - - return legacy_hals_; -} - -bool WifiLegacyHalFactory::initVendorHalDescriptorFromLinked() { - wifi_hal_lib_desc desc; - - if (!initLinkedHalFunctionTable(&desc.fn)) return false; - - desc.primary = true; - desc.handle = NULL; - descs_.push_back(desc); - return true; -} - -bool WifiLegacyHalFactory::initLinkedHalFunctionTable(wifi_hal_fn* hal_fn) { - init_wifi_vendor_hal_func_table_t initfn; - - initfn = (init_wifi_vendor_hal_func_table_t)dlsym( - RTLD_DEFAULT, "init_wifi_vendor_hal_func_table"); - if (!initfn) { - LOG(INFO) << "no vendor HAL library linked, will try dynamic load"; - return false; - } - - if (!initHalFuncTableWithStubs(hal_fn)) { - LOG(ERROR) << "Can not initialize the basic function pointer table"; - return false; - } - - if (initfn(hal_fn) != WIFI_SUCCESS) { - LOG(ERROR) << "Can not initialize the vendor function pointer table"; - return false; - } - - return true; -} - -/* - * Overall structure of the HAL descriptor XML schema - * - * - * - * /vendor/lib64/libwifi-hal-qcom.so - * 1 - * - */ -void WifiLegacyHalFactory::initVendorHalsDescriptorList() { - xmlDocPtr xml; - xmlNodePtr node, cnode; - char* version; - std::string path; - xmlChar* value; - wifi_hal_lib_desc desc; - - LOG(INFO) << "processing vendor HALs descriptions in " - << kVendorHalsDescPath; - DIR* dirPtr = ::opendir(kVendorHalsDescPath); - if (dirPtr == NULL) { - LOG(ERROR) << "failed to open " << kVendorHalsDescPath; - return; - } - for (struct dirent* entryPtr = ::readdir(dirPtr); entryPtr != NULL; - entryPtr = ::readdir(dirPtr)) { - if (isDirectory(entryPtr)) continue; - - if (!isFileExtension(entryPtr->d_name, kVendorHalsDescExt)) - continue; // only process .xml files - - LOG(INFO) << "processing config file: " << entryPtr->d_name; - - std::string fullPath(kVendorHalsDescPath); - fullPath.append("/"); - fullPath.append(entryPtr->d_name); - xml = xmlReadFile(fullPath.c_str(), "UTF-8", XML_PARSE_RECOVER); - if (!xml) { - LOG(ERROR) << "failed to parse: " << entryPtr->d_name - << " skipping..."; - continue; - } - node = xmlDocGetRootElement(xml); - if (!node) { - LOG(ERROR) << "empty config file: " << entryPtr->d_name - << " skipping..."; - goto skip; - } - if (xmlStrcmp(node->name, BAD_CAST "WifiVendorHal")) { - LOG(ERROR) << "bad config, root element not WifiVendorHal: " - << entryPtr->d_name << " skipping..."; - goto skip; - } - version = (char*)xmlGetProp(node, BAD_CAST "version"); - if (!version || strtoul(version, NULL, 0) != kVendorHalsDescVersion) { - LOG(ERROR) << "conf file: " << entryPtr->d_name - << "must have version: " << kVendorHalsDescVersion - << ", skipping..."; - goto skip; - } - cnode = node->children; - path.clear(); - desc.primary = false; - while (cnode) { - if (!xmlStrcmp(cnode->name, BAD_CAST "path")) { - value = xmlNodeListGetString(xml, cnode->children, 1); - if (value) path = (char*)value; - xmlFree(value); - } else if (!xmlStrcmp(cnode->name, BAD_CAST "primary")) { - value = xmlNodeListGetString(xml, cnode->children, 1); - desc.primary = !xmlStrcmp(value, BAD_CAST "1"); - xmlFree(value); - } - cnode = cnode->next; - } - if (path.empty()) { - LOG(ERROR) << "hal library path not provided in: " - << entryPtr->d_name << ", skipping..."; - goto skip; - } - if (loadVendorHalLib(path, desc)) { - if (desc.primary) - descs_.insert(descs_.begin(), desc); - else - descs_.push_back(desc); - } - skip: - xmlFreeDoc(xml); - } - ::closedir(dirPtr); -} - -bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, - wifi_hal_lib_desc& desc) { - void* h = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL); - init_wifi_vendor_hal_func_table_t initfn; - wifi_error res; - - if (!h) { - LOG(ERROR) << "failed to open vendor hal library: " << path; - return false; - } - initfn = (init_wifi_vendor_hal_func_table_t)dlsym( - h, "init_wifi_vendor_hal_func_table"); - if (!initfn) { - LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path; - goto out_err; - } - - if (!initHalFuncTableWithStubs(&desc.fn)) { - LOG(ERROR) << "Can not initialize the basic function pointer table"; - goto out_err; - } - res = initfn(&desc.fn); - if (res != WIFI_SUCCESS) { - LOG(ERROR) << "failed to initialize the vendor func table in: " << path - << " error: " << res; - goto out_err; - } - - res = desc.fn.wifi_early_initialize(); - // vendor HALs which do not implement early_initialize will return - // WIFI_ERROR_NOT_SUPPORTED, treat this as success. - if (res != WIFI_SUCCESS && res != WIFI_ERROR_NOT_SUPPORTED) { - LOG(ERROR) << "early initialization failed in: " << path - << " error: " << res; - goto out_err; - } - - desc.handle = h; - return true; -out_err: - dlclose(h); - return false; -} - -} // namespace legacy_hal -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal_factory.h b/wifi/1.5/default/wifi_legacy_hal_factory.h deleted file mode 100644 index e3440faff2..0000000000 --- a/wifi/1.5/default/wifi_legacy_hal_factory.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WIFI_LEGACY_HAL_FACTORY_H_ -#define WIFI_LEGACY_HAL_FACTORY_H_ - -#include - -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -// This is in a separate namespace to prevent typename conflicts between -// the legacy HAL types and the HIDL interface types. -namespace legacy_hal { -/** - * Class that creates WifiLegacyHal objects for vendor HALs in the system. - */ -class WifiLegacyHalFactory { - public: - WifiLegacyHalFactory( - const std::weak_ptr iface_tool); - virtual ~WifiLegacyHalFactory() = default; - - std::vector> getHals(); - - private: - typedef struct { - wifi_hal_fn fn; - bool primary; - void* handle; - } wifi_hal_lib_desc; - - bool initVendorHalDescriptorFromLinked(); - void initVendorHalsDescriptorList(); - bool initLinkedHalFunctionTable(wifi_hal_fn* hal_fn); - bool loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc); - - std::weak_ptr iface_tool_; - std::vector descs_; - std::vector> legacy_hals_; -}; - -} // namespace legacy_hal -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_LEGACY_HAL_FACTORY_H_ diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp deleted file mode 100644 index dd860d6920..0000000000 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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. - */ - -#include "wifi_legacy_hal_stubs.h" - -// TODO: Remove these stubs from HalTool in libwifi-system. -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace legacy_hal { -template -struct stubFunction; - -template -struct stubFunction { - static constexpr R invoke(Args...) { return WIFI_ERROR_NOT_SUPPORTED; } -}; -template -struct stubFunction { - static constexpr void invoke(Args...) {} -}; - -template -void populateStubFor(T* val) { - *val = &stubFunction::invoke; -} - -bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { - if (hal_fn == nullptr) { - return false; - } - populateStubFor(&hal_fn->wifi_initialize); - populateStubFor(&hal_fn->wifi_wait_for_driver_ready); - populateStubFor(&hal_fn->wifi_cleanup); - populateStubFor(&hal_fn->wifi_event_loop); - populateStubFor(&hal_fn->wifi_get_error_info); - populateStubFor(&hal_fn->wifi_get_supported_feature_set); - populateStubFor(&hal_fn->wifi_get_concurrency_matrix); - populateStubFor(&hal_fn->wifi_set_scanning_mac_oui); - populateStubFor(&hal_fn->wifi_get_supported_channels); - populateStubFor(&hal_fn->wifi_is_epr_supported); - populateStubFor(&hal_fn->wifi_get_ifaces); - populateStubFor(&hal_fn->wifi_get_iface_name); - populateStubFor(&hal_fn->wifi_set_iface_event_handler); - populateStubFor(&hal_fn->wifi_reset_iface_event_handler); - populateStubFor(&hal_fn->wifi_start_gscan); - populateStubFor(&hal_fn->wifi_stop_gscan); - populateStubFor(&hal_fn->wifi_get_cached_gscan_results); - populateStubFor(&hal_fn->wifi_set_bssid_hotlist); - populateStubFor(&hal_fn->wifi_reset_bssid_hotlist); - populateStubFor(&hal_fn->wifi_set_significant_change_handler); - populateStubFor(&hal_fn->wifi_reset_significant_change_handler); - populateStubFor(&hal_fn->wifi_get_gscan_capabilities); - populateStubFor(&hal_fn->wifi_set_link_stats); - populateStubFor(&hal_fn->wifi_get_link_stats); - populateStubFor(&hal_fn->wifi_clear_link_stats); - populateStubFor(&hal_fn->wifi_get_valid_channels); - populateStubFor(&hal_fn->wifi_rtt_range_request); - populateStubFor(&hal_fn->wifi_rtt_range_cancel); - populateStubFor(&hal_fn->wifi_get_rtt_capabilities); - populateStubFor(&hal_fn->wifi_rtt_get_responder_info); - populateStubFor(&hal_fn->wifi_enable_responder); - populateStubFor(&hal_fn->wifi_disable_responder); - populateStubFor(&hal_fn->wifi_set_nodfs_flag); - populateStubFor(&hal_fn->wifi_start_logging); - populateStubFor(&hal_fn->wifi_set_epno_list); - populateStubFor(&hal_fn->wifi_reset_epno_list); - populateStubFor(&hal_fn->wifi_set_country_code); - populateStubFor(&hal_fn->wifi_get_firmware_memory_dump); - populateStubFor(&hal_fn->wifi_set_log_handler); - populateStubFor(&hal_fn->wifi_reset_log_handler); - populateStubFor(&hal_fn->wifi_set_alert_handler); - populateStubFor(&hal_fn->wifi_reset_alert_handler); - populateStubFor(&hal_fn->wifi_get_firmware_version); - populateStubFor(&hal_fn->wifi_get_ring_buffers_status); - populateStubFor(&hal_fn->wifi_get_logger_supported_feature_set); - populateStubFor(&hal_fn->wifi_get_ring_data); - populateStubFor(&hal_fn->wifi_enable_tdls); - populateStubFor(&hal_fn->wifi_disable_tdls); - populateStubFor(&hal_fn->wifi_get_tdls_status); - populateStubFor(&hal_fn->wifi_get_tdls_capabilities); - populateStubFor(&hal_fn->wifi_get_driver_version); - populateStubFor(&hal_fn->wifi_set_passpoint_list); - populateStubFor(&hal_fn->wifi_reset_passpoint_list); - populateStubFor(&hal_fn->wifi_set_lci); - populateStubFor(&hal_fn->wifi_set_lcr); - populateStubFor(&hal_fn->wifi_start_sending_offloaded_packet); - populateStubFor(&hal_fn->wifi_stop_sending_offloaded_packet); - populateStubFor(&hal_fn->wifi_start_rssi_monitoring); - populateStubFor(&hal_fn->wifi_stop_rssi_monitoring); - populateStubFor(&hal_fn->wifi_get_wake_reason_stats); - populateStubFor(&hal_fn->wifi_configure_nd_offload); - populateStubFor(&hal_fn->wifi_get_driver_memory_dump); - populateStubFor(&hal_fn->wifi_start_pkt_fate_monitoring); - populateStubFor(&hal_fn->wifi_get_tx_pkt_fates); - populateStubFor(&hal_fn->wifi_get_rx_pkt_fates); - populateStubFor(&hal_fn->wifi_nan_enable_request); - populateStubFor(&hal_fn->wifi_nan_disable_request); - populateStubFor(&hal_fn->wifi_nan_publish_request); - populateStubFor(&hal_fn->wifi_nan_publish_cancel_request); - populateStubFor(&hal_fn->wifi_nan_subscribe_request); - populateStubFor(&hal_fn->wifi_nan_subscribe_cancel_request); - populateStubFor(&hal_fn->wifi_nan_transmit_followup_request); - populateStubFor(&hal_fn->wifi_nan_stats_request); - populateStubFor(&hal_fn->wifi_nan_config_request); - populateStubFor(&hal_fn->wifi_nan_tca_request); - populateStubFor(&hal_fn->wifi_nan_beacon_sdf_payload_request); - populateStubFor(&hal_fn->wifi_nan_register_handler); - populateStubFor(&hal_fn->wifi_nan_get_version); - populateStubFor(&hal_fn->wifi_nan_get_capabilities); - populateStubFor(&hal_fn->wifi_nan_data_interface_create); - populateStubFor(&hal_fn->wifi_nan_data_interface_delete); - populateStubFor(&hal_fn->wifi_nan_data_request_initiator); - populateStubFor(&hal_fn->wifi_nan_data_indication_response); - populateStubFor(&hal_fn->wifi_nan_data_end); - populateStubFor(&hal_fn->wifi_get_packet_filter_capabilities); - populateStubFor(&hal_fn->wifi_set_packet_filter); - populateStubFor(&hal_fn->wifi_read_packet_filter); - populateStubFor(&hal_fn->wifi_get_roaming_capabilities); - populateStubFor(&hal_fn->wifi_enable_firmware_roaming); - populateStubFor(&hal_fn->wifi_configure_roaming); - populateStubFor(&hal_fn->wifi_select_tx_power_scenario); - populateStubFor(&hal_fn->wifi_reset_tx_power_scenario); - populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler); - populateStubFor(&hal_fn->wifi_set_latency_mode); - populateStubFor(&hal_fn->wifi_set_thermal_mitigation_mode); - populateStubFor(&hal_fn->wifi_virtual_interface_create); - populateStubFor(&hal_fn->wifi_virtual_interface_delete); - populateStubFor(&hal_fn->wifi_map_dscp_access_category); - populateStubFor(&hal_fn->wifi_reset_dscp_mapping); - populateStubFor(&hal_fn->wifi_set_subsystem_restart_handler); - populateStubFor(&hal_fn->wifi_get_supported_iface_name); - populateStubFor(&hal_fn->wifi_early_initialize); - populateStubFor(&hal_fn->wifi_get_chip_feature_set); - populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection); - populateStubFor(&hal_fn->wifi_multi_sta_set_use_case); - populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels); - populateStubFor(&hal_fn->wifi_set_voip_mode); - populateStubFor(&hal_fn->wifi_twt_register_handler); - populateStubFor(&hal_fn->wifi_twt_get_capability); - populateStubFor(&hal_fn->wifi_twt_setup_request); - populateStubFor(&hal_fn->wifi_twt_teardown_request); - populateStubFor(&hal_fn->wifi_twt_info_frame_request); - populateStubFor(&hal_fn->wifi_twt_get_stats); - populateStubFor(&hal_fn->wifi_twt_clear_stats); - populateStubFor(&hal_fn->wifi_set_dtim_config); - populateStubFor(&hal_fn->wifi_get_usable_channels); - populateStubFor(&hal_fn->wifi_trigger_subsystem_restart); - return true; -} -} // namespace legacy_hal -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.h b/wifi/1.5/default/wifi_legacy_hal_stubs.h deleted file mode 100644 index 480389b0ce..0000000000 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_LEGACY_HAL_STUBS_H_ -#define WIFI_LEGACY_HAL_STUBS_H_ - -#include - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace legacy_hal { - -bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn); -} // namespace legacy_hal -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_LEGACY_HAL_STUBS_H_ diff --git a/wifi/1.5/default/wifi_mode_controller.cpp b/wifi/1.5/default/wifi_mode_controller.cpp deleted file mode 100644 index b1db8b3725..0000000000 --- a/wifi/1.5/default/wifi_mode_controller.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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. - */ - -#include -#include -#include - -#include "wifi_mode_controller.h" - -using android::hardware::wifi::V1_0::IfaceType; -using android::wifi_hal::DriverTool; - -namespace { -int convertIfaceTypeToFirmwareMode(IfaceType type) { - int mode; - switch (type) { - case IfaceType::AP: - mode = DriverTool::kFirmwareModeAp; - break; - case IfaceType::P2P: - mode = DriverTool::kFirmwareModeP2p; - break; - case IfaceType::NAN: - // NAN is exposed in STA mode currently. - mode = DriverTool::kFirmwareModeSta; - break; - case IfaceType::STA: - mode = DriverTool::kFirmwareModeSta; - break; - } - return mode; -} -} // namespace - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace mode_controller { - -WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {} - -bool WifiModeController::isFirmwareModeChangeNeeded(IfaceType type) { - return driver_tool_->IsFirmwareModeChangeNeeded( - convertIfaceTypeToFirmwareMode(type)); -} - -bool WifiModeController::initialize() { - if (!driver_tool_->LoadDriver()) { - LOG(ERROR) << "Failed to load WiFi driver"; - return false; - } - return true; -} - -bool WifiModeController::changeFirmwareMode(IfaceType type) { - if (!driver_tool_->ChangeFirmwareMode( - convertIfaceTypeToFirmwareMode(type))) { - LOG(ERROR) << "Failed to change firmware mode"; - return false; - } - return true; -} - -bool WifiModeController::deinitialize() { - if (!driver_tool_->UnloadDriver()) { - LOG(ERROR) << "Failed to unload WiFi driver"; - return false; - } - return true; -} -} // namespace mode_controller -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_mode_controller.h b/wifi/1.5/default/wifi_mode_controller.h deleted file mode 100644 index 2eeca78c8b..0000000000 --- a/wifi/1.5/default/wifi_mode_controller.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_MODE_CONTROLLER_H_ -#define WIFI_MODE_CONTROLLER_H_ - -#include - -#include - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -namespace mode_controller { -using namespace android::hardware::wifi::V1_0; - -/** - * Class that encapsulates all firmware mode configuration. - * This class will perform the necessary firmware reloads to put the chip in the - * required state (essentially a wrapper over DriverTool). - */ -class WifiModeController { - public: - WifiModeController(); - virtual ~WifiModeController() = default; - - // Checks if a firmware mode change is necessary to support the specified - // iface type operations. - virtual bool isFirmwareModeChangeNeeded(IfaceType type); - virtual bool initialize(); - // Change the firmware mode to support the specified iface type operations. - virtual bool changeFirmwareMode(IfaceType type); - // Unload the driver. This should be invoked whenever |IWifi.stop()| is - // invoked. - virtual bool deinitialize(); - - private: - std::unique_ptr driver_tool_; -}; - -} // namespace mode_controller -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_MODE_CONTROLLER_H_ diff --git a/wifi/1.5/default/wifi_nan_iface.cpp b/wifi/1.5/default/wifi_nan_iface.cpp deleted file mode 100644 index 0cc6cd5fce..0000000000 --- a/wifi/1.5/default/wifi_nan_iface.cpp +++ /dev/null @@ -1,1003 +0,0 @@ -/* - * 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. - */ - -#include - -#include "hidl_return_util.h" -#include "hidl_struct_util.h" -#include "wifi_nan_iface.h" -#include "wifi_status_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using hidl_return_util::validateAndCall; - -WifiNanIface::WifiNanIface( - const std::string& ifname, bool is_dedicated_iface, - const std::weak_ptr legacy_hal, - const std::weak_ptr iface_util) - : ifname_(ifname), - is_dedicated_iface_(is_dedicated_iface), - legacy_hal_(legacy_hal), - iface_util_(iface_util), - is_valid_(true) { - if (is_dedicated_iface_) { - // If using a dedicated iface, set the iface up first. - if (!iface_util_.lock()->setUpState(ifname_, true)) { - // Fatal failure, invalidate the iface object. - invalidate(); - return; - } - } - // Register all the callbacks here. these should be valid for the lifetime - // of the object. Whenever the mode changes legacy HAL will remove - // all of these callbacks. - legacy_hal::NanCallbackHandlers callback_handlers; - android::wp weak_ptr_this(this); - - // Callback for response. - callback_handlers - .on_notify_response = [weak_ptr_this]( - legacy_hal::transaction_id id, - const legacy_hal::NanResponseMsg& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus wifiNanStatus; - if (!hidl_struct_util::convertLegacyNanResponseHeaderToHidl( - msg, &wifiNanStatus)) { - LOG(ERROR) << "Failed to convert nan response header"; - return; - } - - switch (msg.response_type) { - case legacy_hal::NAN_RESPONSE_ENABLED: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback->notifyEnableResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_DISABLED: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback->notifyDisableResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_PUBLISH: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyStartPublishResponse( - id, wifiNanStatus, - msg.body.publish_response.publish_id) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback->notifyStopPublishResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyTransmitFollowupResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_SUBSCRIBE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyStartSubscribeResponse( - id, wifiNanStatus, - msg.body.subscribe_response.subscribe_id) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyStopSubscribeResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_CONFIG: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback->notifyConfigResponse(id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_GET_CAPABILITIES: { - NanCapabilities hidl_struct; - if (!hidl_struct_util:: - convertLegacyNanCapabilitiesResponseToHidl( - msg.body.nan_capabilities, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - for (const auto& callback : - shared_ptr_this->getEventCallbacks_1_5()) { - if (!callback - ->notifyCapabilitiesResponse_1_5(id, wifiNanStatus, - hidl_struct) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_INTERFACE_CREATE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyCreateDataInterfaceResponse(id, - wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_INTERFACE_DELETE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyDeleteDataInterfaceResponse(id, - wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_INITIATOR_RESPONSE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyInitiateDataPathResponse( - id, wifiNanStatus, - msg.body.data_request_response.ndp_instance_id) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_RESPONDER_RESPONSE: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyRespondToDataPathIndicationResponse( - id, wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_DP_END: { - for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { - if (!callback - ->notifyTerminateDataPathResponse(id, - wifiNanStatus) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - break; - } - case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD: - /* fall through */ - case legacy_hal::NAN_RESPONSE_TCA: - /* fall through */ - case legacy_hal::NAN_RESPONSE_STATS: - /* fall through */ - case legacy_hal::NAN_RESPONSE_ERROR: - /* fall through */ - default: - LOG(ERROR) << "Unknown or unhandled response type: " - << msg.response_type; - return; - } - }; - - callback_handlers.on_event_disc_eng_event = - [weak_ptr_this](const legacy_hal::NanDiscEngEventInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - NanClusterEventInd hidl_struct; - // event types defined identically - hence can be cast - hidl_struct.eventType = (NanClusterEventType)msg.event_type; - hidl_struct.addr = msg.data.mac_addr.addr; - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventClusterEvent(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_disabled = - [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus status; - hidl_struct_util::convertToWifiNanStatus( - msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status); - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventDisabled(status).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_publish_terminated = - [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus status; - hidl_struct_util::convertToWifiNanStatus( - msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status); - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventPublishTerminated(msg.publish_id, status) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_subscribe_terminated = - [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus status; - hidl_struct_util::convertToWifiNanStatus( - msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status); - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback - ->eventSubscribeTerminated(msg.subscribe_id, status) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_match = - [weak_ptr_this](const legacy_hal::NanMatchInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - NanMatchInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanMatchIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventMatch(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_match_expired = - [weak_ptr_this](const legacy_hal::NanMatchExpiredInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback - ->eventMatchExpired(msg.publish_subscribe_id, - msg.requestor_instance_id) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_followup = - [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - NanFollowupReceivedInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanFollowupIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventFollowupReceived(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_transmit_follow_up = - [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - WifiNanStatus status; - hidl_struct_util::convertToWifiNanStatus( - msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status); - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventTransmitFollowup(msg.id, status).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_data_path_request = - [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - NanDataPathRequestInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanDataPathRequestIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventDataPathRequest(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_data_path_confirm = - [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - V1_2::NanDataPathConfirmInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanDataPathConfirmIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : - shared_ptr_this->getEventCallbacks_1_2()) { - if (!callback->eventDataPathConfirm_1_2(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - callback_handlers.on_event_data_path_end = - [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - for (int i = 0; i < msg.num_ndp_instances; ++i) { - if (!callback - ->eventDataPathTerminated(msg.ndp_instance_id[i]) - .isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - } - }; - - callback_handlers.on_event_beacon_sdf_payload = - [weak_ptr_this](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) { - LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called"; - }; - - callback_handlers.on_event_range_request = - [weak_ptr_this](const legacy_hal::NanRangeRequestInd& /* msg */) { - LOG(ERROR) << "on_event_range_request - should not be called"; - }; - - callback_handlers.on_event_range_report = - [weak_ptr_this](const legacy_hal::NanRangeReportInd& /* msg */) { - LOG(ERROR) << "on_event_range_report - should not be called"; - }; - - callback_handlers - .on_event_schedule_update = [weak_ptr_this]( - const legacy_hal:: - NanDataPathScheduleUpdateInd& msg) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - V1_2::NanDataPathScheduleUpdateInd hidl_struct; - if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl( - msg, &hidl_struct)) { - LOG(ERROR) << "Failed to convert nan capabilities response"; - return; - } - - for (const auto& callback : shared_ptr_this->getEventCallbacks_1_2()) { - if (!callback->eventDataPathScheduleUpdate(hidl_struct).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, - callback_handlers); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to register nan callbacks. Invalidating object"; - invalidate(); - } - - // Register for iface state toggle events. - iface_util::IfaceEventHandlers event_handlers = {}; - event_handlers.on_state_toggle_off_on = - [weak_ptr_this](const std::string& /* iface_name */) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - // Tell framework that NAN has been disabled. - WifiNanStatus status = { - NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""}; - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->eventDisabled(status).isOk()) { - LOG(ERROR) << "Failed to invoke the callback"; - } - } - }; - iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers); -} - -void WifiNanIface::invalidate() { - if (!isValid()) { - return; - } - // send commands to HAL to actually disable and destroy interfaces - legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF); - legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0"); - legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1"); - iface_util_.lock()->unregisterIfaceEventHandlers(ifname_); - legacy_hal_.reset(); - event_cb_handler_.invalidate(); - event_cb_handler_1_2_.invalidate(); - event_cb_handler_1_5_.invalidate(); - is_valid_ = false; - if (is_dedicated_iface_) { - // If using a dedicated iface, set the iface down. - iface_util_.lock()->setUpState(ifname_, false); - } -} - -bool WifiNanIface::isValid() { return is_valid_; } - -std::string WifiNanIface::getName() { return ifname_; } - -std::set> -WifiNanIface::getEventCallbacks() { - return event_cb_handler_.getCallbacks(); -} - -std::set> -WifiNanIface::getEventCallbacks_1_2() { - return event_cb_handler_1_2_.getCallbacks(); -} - -std::set> WifiNanIface::getEventCallbacks_1_5() { - return event_cb_handler_1_5_.getCallbacks(); -} - -Return WifiNanIface::getName(getName_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::getNameInternal, hidl_status_cb); -} - -Return WifiNanIface::getType(getType_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::getTypeInternal, hidl_status_cb); -} - -Return WifiNanIface::registerEventCallback( - const sp& callback, - registerEventCallback_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::registerEventCallbackInternal, - hidl_status_cb, callback); -} - -Return WifiNanIface::getCapabilitiesRequest( - uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::getCapabilitiesRequestInternal, - hidl_status_cb, cmd_id); -} - -Return WifiNanIface::enableRequest(uint16_t cmd_id, - const V1_0::NanEnableRequest& msg, - enableRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::enableRequestInternal, hidl_status_cb, - cmd_id, msg); -} - -Return WifiNanIface::configRequest(uint16_t cmd_id, - const V1_0::NanConfigRequest& msg, - configRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::configRequestInternal, hidl_status_cb, - cmd_id, msg); -} - -Return WifiNanIface::disableRequest(uint16_t cmd_id, - disableRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::disableRequestInternal, - hidl_status_cb, cmd_id); -} - -Return WifiNanIface::startPublishRequest( - uint16_t cmd_id, const NanPublishRequest& msg, - startPublishRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::startPublishRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return WifiNanIface::stopPublishRequest( - uint16_t cmd_id, uint8_t sessionId, stopPublishRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::stopPublishRequestInternal, - hidl_status_cb, cmd_id, sessionId); -} - -Return WifiNanIface::startSubscribeRequest( - uint16_t cmd_id, const NanSubscribeRequest& msg, - startSubscribeRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::startSubscribeRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return WifiNanIface::stopSubscribeRequest( - uint16_t cmd_id, uint8_t sessionId, - stopSubscribeRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::stopSubscribeRequestInternal, - hidl_status_cb, cmd_id, sessionId); -} - -Return WifiNanIface::transmitFollowupRequest( - uint16_t cmd_id, const NanTransmitFollowupRequest& msg, - transmitFollowupRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::transmitFollowupRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return WifiNanIface::createDataInterfaceRequest( - uint16_t cmd_id, const hidl_string& iface_name, - createDataInterfaceRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::createDataInterfaceRequestInternal, - hidl_status_cb, cmd_id, iface_name); -} - -Return WifiNanIface::deleteDataInterfaceRequest( - uint16_t cmd_id, const hidl_string& iface_name, - deleteDataInterfaceRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::deleteDataInterfaceRequestInternal, - hidl_status_cb, cmd_id, iface_name); -} - -Return WifiNanIface::initiateDataPathRequest( - uint16_t cmd_id, const NanInitiateDataPathRequest& msg, - initiateDataPathRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::initiateDataPathRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return WifiNanIface::respondToDataPathIndicationRequest( - uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg, - respondToDataPathIndicationRequest_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::respondToDataPathIndicationRequestInternal, - hidl_status_cb, cmd_id, msg); -} - -Return WifiNanIface::terminateDataPathRequest( - uint16_t cmd_id, uint32_t ndpInstanceId, - terminateDataPathRequest_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::terminateDataPathRequestInternal, - hidl_status_cb, cmd_id, ndpInstanceId); -} - -Return WifiNanIface::registerEventCallback_1_2( - const sp& callback, - registerEventCallback_1_2_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::registerEventCallback_1_2Internal, - hidl_status_cb, callback); -} - -Return WifiNanIface::enableRequest_1_2( - uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - enableRequest_1_2_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::enableRequest_1_2Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return WifiNanIface::configRequest_1_2( - uint16_t cmd_id, const V1_0::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - configRequest_1_2_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::configRequest_1_2Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return WifiNanIface::enableRequest_1_4( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - enableRequest_1_4_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::enableRequest_1_4Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return WifiNanIface::configRequest_1_4( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - configRequest_1_4_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::configRequest_1_4Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return WifiNanIface::registerEventCallback_1_5( - const sp& callback, - registerEventCallback_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::registerEventCallback_1_5Internal, - hidl_status_cb, callback); -} - -Return WifiNanIface::enableRequest_1_5( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2, - enableRequest_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::enableRequest_1_5Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return WifiNanIface::configRequest_1_5( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const NanConfigRequestSupplemental& msg2, - configRequest_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::configRequest_1_5Internal, - hidl_status_cb, cmd_id, msg1, msg2); -} - -Return WifiNanIface::getCapabilitiesRequest_1_5( - uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiNanIface::getCapabilitiesRequest_1_5Internal, - hidl_status_cb, cmd_id); -} - -std::pair WifiNanIface::getNameInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; -} - -std::pair WifiNanIface::getTypeInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::NAN}; -} - -WifiStatus WifiNanIface::registerEventCallbackInternal( - const sp& callback) { - if (!event_cb_handler_.addCallback(callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::enableRequestInternal( - uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::configRequestInternal( - uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::disableRequestInternal(uint16_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::startPublishRequestInternal( - uint16_t cmd_id, const NanPublishRequest& msg) { - legacy_hal::NanPublishRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanPublishRequestToLegacy(msg, - &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::stopPublishRequestInternal(uint16_t cmd_id, - uint8_t sessionId) { - legacy_hal::NanPublishCancelRequest legacy_msg; - legacy_msg.publish_id = sessionId; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::startSubscribeRequestInternal( - uint16_t cmd_id, const NanSubscribeRequest& msg) { - legacy_hal::NanSubscribeRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanSubscribeRequestToLegacy( - msg, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::stopSubscribeRequestInternal(uint16_t cmd_id, - uint8_t sessionId) { - legacy_hal::NanSubscribeCancelRequest legacy_msg; - legacy_msg.subscribe_id = sessionId; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::transmitFollowupRequestInternal( - uint16_t cmd_id, const NanTransmitFollowupRequest& msg) { - legacy_hal::NanTransmitFollowupRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanTransmitFollowupRequestToLegacy( - msg, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::createDataInterfaceRequestInternal( - uint16_t cmd_id, const std::string& iface_name) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name); - return createWifiStatusFromLegacyError(legacy_status); -} -WifiStatus WifiNanIface::deleteDataInterfaceRequestInternal( - uint16_t cmd_id, const std::string& iface_name) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name); - return createWifiStatusFromLegacyError(legacy_status); -} -WifiStatus WifiNanIface::initiateDataPathRequestInternal( - uint16_t cmd_id, const NanInitiateDataPathRequest& msg) { - legacy_hal::NanDataPathInitiatorRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequestToLegacy( - msg, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} -WifiStatus WifiNanIface::respondToDataPathIndicationRequestInternal( - uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg) { - legacy_hal::NanDataPathIndicationResponse legacy_msg; - if (!hidl_struct_util::convertHidlNanDataPathIndicationResponseToLegacy( - msg, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, - legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} -WifiStatus WifiNanIface::terminateDataPathRequestInternal( - uint16_t cmd_id, uint32_t ndpInstanceId) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::registerEventCallback_1_2Internal( - const sp& callback) { - sp callback_1_0 = callback; - if (!event_cb_handler_.addCallback(callback_1_0)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - if (!event_cb_handler_1_2_.addCallback(callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiNanIface::enableRequest_1_2Internal( - uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /* msg2 */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::configRequest_1_2Internal( - uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /* msg2 */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::enableRequest_1_4Internal( - uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /* msg2 */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::configRequest_1_4Internal( - uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /* msg2 */) { - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiNanIface::registerEventCallback_1_5Internal( - const sp& callback) { - sp callback_1_0 = callback; - if (!event_cb_handler_.addCallback(callback_1_0)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - sp callback_1_2 = callback; - if (!event_cb_handler_1_2_.addCallback(callback_1_2)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - if (!event_cb_handler_1_5_.addCallback(callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::enableRequest_1_5Internal( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2) { - legacy_hal::NanEnableRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanEnableRequest_1_5ToLegacy( - msg1, msg2, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiNanIface::configRequest_1_5Internal( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const NanConfigRequestSupplemental& msg2) { - legacy_hal::NanConfigRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanConfigRequest_1_5ToLegacy( - msg1, msg2, &legacy_msg)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg); - return createWifiStatusFromLegacyError(legacy_status); -} - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_nan_iface.h b/wifi/1.5/default/wifi_nan_iface.h deleted file mode 100644 index fb9c047ff6..0000000000 --- a/wifi/1.5/default/wifi_nan_iface.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_NAN_IFACE_H_ -#define WIFI_NAN_IFACE_H_ - -#include -#include -#include - -#include "hidl_callback_util.h" -#include "wifi_iface_util.h" -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; -using namespace android::hardware::wifi::V1_2; - -/** - * HIDL interface object used to control a NAN Iface instance. - */ -class WifiNanIface : public V1_5::IWifiNanIface { - public: - WifiNanIface(const std::string& ifname, bool is_dedicated_iface, - const std::weak_ptr legacy_hal, - const std::weak_ptr iface_util); - // Refer to |WifiChip::invalidate()|. - void invalidate(); - bool isValid(); - std::string getName(); - - // HIDL methods exposed. - Return getName(getName_cb hidl_status_cb) override; - Return getType(getType_cb hidl_status_cb) override; - Return registerEventCallback( - const sp& callback, - registerEventCallback_cb hidl_status_cb) override; - Return getCapabilitiesRequest( - uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override; - Return enableRequest(uint16_t cmd_id, - const V1_0::NanEnableRequest& msg, - enableRequest_cb hidl_status_cb) override; - Return configRequest(uint16_t cmd_id, - const V1_0::NanConfigRequest& msg, - configRequest_cb hidl_status_cb) override; - Return disableRequest(uint16_t cmd_id, - disableRequest_cb hidl_status_cb) override; - Return startPublishRequest( - uint16_t cmd_id, const NanPublishRequest& msg, - startPublishRequest_cb hidl_status_cb) override; - Return stopPublishRequest( - uint16_t cmd_id, uint8_t sessionId, - stopPublishRequest_cb hidl_status_cb) override; - Return startSubscribeRequest( - uint16_t cmd_id, const NanSubscribeRequest& msg, - startSubscribeRequest_cb hidl_status_cb) override; - Return stopSubscribeRequest( - uint16_t cmd_id, uint8_t sessionId, - stopSubscribeRequest_cb hidl_status_cb) override; - Return transmitFollowupRequest( - uint16_t cmd_id, const NanTransmitFollowupRequest& msg, - transmitFollowupRequest_cb hidl_status_cb) override; - Return createDataInterfaceRequest( - uint16_t cmd_id, const hidl_string& iface_name, - createDataInterfaceRequest_cb hidl_status_cb) override; - Return deleteDataInterfaceRequest( - uint16_t cmd_id, const hidl_string& iface_name, - deleteDataInterfaceRequest_cb hidl_status_cb) override; - Return initiateDataPathRequest( - uint16_t cmd_id, const NanInitiateDataPathRequest& msg, - initiateDataPathRequest_cb hidl_status_cb) override; - Return respondToDataPathIndicationRequest( - uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg, - respondToDataPathIndicationRequest_cb hidl_status_cb) override; - Return terminateDataPathRequest( - uint16_t cmd_id, uint32_t ndpInstanceId, - terminateDataPathRequest_cb hidl_status_cb) override; - - Return registerEventCallback_1_2( - const sp& callback, - registerEventCallback_1_2_cb hidl_status_cb) override; - Return enableRequest_1_2( - uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - enableRequest_1_2_cb hidl_status_cb) override; - Return configRequest_1_2( - uint16_t cmd_id, const V1_0::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - configRequest_1_2_cb hidl_status_cb) override; - Return enableRequest_1_4( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - enableRequest_1_4_cb hidl_status_cb) override; - Return configRequest_1_4( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2, - configRequest_1_4_cb hidl_status_cb) override; - Return registerEventCallback_1_5( - const sp& callback, - registerEventCallback_1_5_cb hidl_status_cb) override; - Return enableRequest_1_5( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2, - enableRequest_1_4_cb hidl_status_cb) override; - Return configRequest_1_5( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const NanConfigRequestSupplemental& msg2, - configRequest_1_4_cb hidl_status_cb) override; - Return getCapabilitiesRequest_1_5( - uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override; - - private: - // Corresponding worker functions for the HIDL methods. - std::pair getNameInternal(); - std::pair getTypeInternal(); - WifiStatus registerEventCallbackInternal( - const sp& callback); - WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id); - WifiStatus enableRequestInternal(uint16_t cmd_id, - const V1_0::NanEnableRequest& msg); - WifiStatus configRequestInternal(uint16_t cmd_id, - const V1_0::NanConfigRequest& msg); - WifiStatus disableRequestInternal(uint16_t cmd_id); - WifiStatus startPublishRequestInternal(uint16_t cmd_id, - const NanPublishRequest& msg); - WifiStatus stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId); - WifiStatus startSubscribeRequestInternal(uint16_t cmd_id, - const NanSubscribeRequest& msg); - WifiStatus stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId); - WifiStatus transmitFollowupRequestInternal( - uint16_t cmd_id, const NanTransmitFollowupRequest& msg); - WifiStatus createDataInterfaceRequestInternal( - uint16_t cmd_id, const std::string& iface_name); - WifiStatus deleteDataInterfaceRequestInternal( - uint16_t cmd_id, const std::string& iface_name); - WifiStatus initiateDataPathRequestInternal( - uint16_t cmd_id, const NanInitiateDataPathRequest& msg); - WifiStatus respondToDataPathIndicationRequestInternal( - uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg); - WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id, - uint32_t ndpInstanceId); - - WifiStatus registerEventCallback_1_2Internal( - const sp& callback); - WifiStatus enableRequest_1_2Internal( - uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2); - WifiStatus configRequest_1_2Internal( - uint16_t cmd_id, const V1_0::NanConfigRequest& msg, - const V1_2::NanConfigRequestSupplemental& msg2); - WifiStatus enableRequest_1_4Internal( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2); - WifiStatus configRequest_1_4Internal( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg, - const V1_2::NanConfigRequestSupplemental& msg2); - WifiStatus registerEventCallback_1_5Internal( - const sp& callback); - WifiStatus enableRequest_1_5Internal( - uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, - const NanConfigRequestSupplemental& msg2); - WifiStatus configRequest_1_5Internal( - uint16_t cmd_id, const V1_4::NanConfigRequest& msg, - const NanConfigRequestSupplemental& msg2); - WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id); - - // all 1_0 and descendant callbacks - std::set> getEventCallbacks(); - // all 1_2 and descendant callbacks - std::set> getEventCallbacks_1_2(); - // all 1_5 and descendant callbacks - std::set> getEventCallbacks_1_5(); - - std::string ifname_; - bool is_dedicated_iface_; - std::weak_ptr legacy_hal_; - std::weak_ptr iface_util_; - bool is_valid_; - hidl_callback_util::HidlCallbackHandler - event_cb_handler_; - hidl_callback_util::HidlCallbackHandler - event_cb_handler_1_2_; - hidl_callback_util::HidlCallbackHandler - event_cb_handler_1_5_; - - DISALLOW_COPY_AND_ASSIGN(WifiNanIface); -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_NAN_IFACE_H_ diff --git a/wifi/1.5/default/wifi_p2p_iface.cpp b/wifi/1.5/default/wifi_p2p_iface.cpp deleted file mode 100644 index b8893da153..0000000000 --- a/wifi/1.5/default/wifi_p2p_iface.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - */ - -#include - -#include "hidl_return_util.h" -#include "wifi_p2p_iface.h" -#include "wifi_status_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using hidl_return_util::validateAndCall; - -WifiP2pIface::WifiP2pIface( - const std::string& ifname, - const std::weak_ptr legacy_hal) - : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {} - -void WifiP2pIface::invalidate() { - legacy_hal_.reset(); - is_valid_ = false; -} - -bool WifiP2pIface::isValid() { return is_valid_; } - -std::string WifiP2pIface::getName() { return ifname_; } - -Return WifiP2pIface::getName(getName_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiP2pIface::getNameInternal, hidl_status_cb); -} - -Return WifiP2pIface::getType(getType_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiP2pIface::getTypeInternal, hidl_status_cb); -} - -std::pair WifiP2pIface::getNameInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; -} - -std::pair WifiP2pIface::getTypeInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::P2P}; -} - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_p2p_iface.h b/wifi/1.5/default/wifi_p2p_iface.h deleted file mode 100644 index c1adc50278..0000000000 --- a/wifi/1.5/default/wifi_p2p_iface.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_P2P_IFACE_H_ -#define WIFI_P2P_IFACE_H_ - -#include -#include - -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; - -/** - * HIDL interface object used to control a P2P Iface instance. - */ -class WifiP2pIface : public V1_0::IWifiP2pIface { - public: - WifiP2pIface(const std::string& ifname, - const std::weak_ptr legacy_hal); - // Refer to |WifiChip::invalidate()|. - void invalidate(); - bool isValid(); - std::string getName(); - - // HIDL methods exposed. - Return getName(getName_cb hidl_status_cb) override; - Return getType(getType_cb hidl_status_cb) override; - - private: - // Corresponding worker functions for the HIDL methods. - std::pair getNameInternal(); - std::pair getTypeInternal(); - - std::string ifname_; - std::weak_ptr legacy_hal_; - bool is_valid_; - - DISALLOW_COPY_AND_ASSIGN(WifiP2pIface); -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_P2P_IFACE_H_ diff --git a/wifi/1.5/default/wifi_rtt_controller.cpp b/wifi/1.5/default/wifi_rtt_controller.cpp deleted file mode 100644 index a0f9969033..0000000000 --- a/wifi/1.5/default/wifi_rtt_controller.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* - * 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. - */ - -#include - -#include "hidl_return_util.h" -#include "hidl_struct_util.h" -#include "wifi_rtt_controller.h" -#include "wifi_status_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using hidl_return_util::validateAndCall; - -WifiRttController::WifiRttController( - const std::string& iface_name, const sp& bound_iface, - const std::weak_ptr legacy_hal) - : ifname_(iface_name), - bound_iface_(bound_iface), - legacy_hal_(legacy_hal), - is_valid_(true) {} - -void WifiRttController::invalidate() { - legacy_hal_.reset(); - event_callbacks_.clear(); - is_valid_ = false; -} - -bool WifiRttController::isValid() { return is_valid_; } - -std::vector> -WifiRttController::getEventCallbacks() { - return event_callbacks_; -} - -std::string WifiRttController::getIfaceName() { return ifname_; } - -Return WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getBoundIfaceInternal, hidl_status_cb); -} - -Return WifiRttController::registerEventCallback( - const sp& callback, - registerEventCallback_cb hidl_status_cb) { - return validateAndCall(this, - WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::registerEventCallbackInternal, - hidl_status_cb, callback); -} - -Return WifiRttController::rangeRequest( - uint32_t cmd_id, const hidl_vec& rtt_configs, - rangeRequest_cb hidl_status_cb) { - return validateAndCall(this, - WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::rangeRequestInternal, - hidl_status_cb, cmd_id, rtt_configs); -} - -Return WifiRttController::rangeCancel( - uint32_t cmd_id, const hidl_vec>& addrs, - rangeCancel_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::rangeCancelInternal, hidl_status_cb, cmd_id, addrs); -} - -Return WifiRttController::getCapabilities( - getCapabilities_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getCapabilitiesInternal, hidl_status_cb); -} - -Return WifiRttController::setLci(uint32_t cmd_id, - const RttLciInformation& lci, - setLci_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::setLciInternal, hidl_status_cb, cmd_id, lci); -} - -Return WifiRttController::setLcr(uint32_t cmd_id, - const RttLcrInformation& lcr, - setLcr_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::setLcrInternal, hidl_status_cb, cmd_id, lcr); -} - -Return WifiRttController::getResponderInfo( - getResponderInfo_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getResponderInfoInternal, hidl_status_cb); -} - -Return WifiRttController::enableResponder( - uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const V1_0::RttResponder& info, - enableResponder_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::enableResponderInternal, hidl_status_cb, cmd_id, - channel_hint, max_duration_seconds, info); -} - -Return WifiRttController::disableResponder( - uint32_t cmd_id, disableResponder_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::disableResponderInternal, hidl_status_cb, cmd_id); -} - -Return WifiRttController::registerEventCallback_1_4( - const sp& callback, - registerEventCallback_1_4_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::registerEventCallbackInternal_1_4, hidl_status_cb, - callback); -} - -Return WifiRttController::rangeRequest_1_4( - uint32_t cmd_id, const hidl_vec& rtt_configs, - rangeRequest_1_4_cb hidl_status_cb) { - return validateAndCall(this, - WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::rangeRequestInternal_1_4, - hidl_status_cb, cmd_id, rtt_configs); -} - -Return WifiRttController::getCapabilities_1_4( - getCapabilities_1_4_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getCapabilitiesInternal_1_4, hidl_status_cb); -} - -Return WifiRttController::getResponderInfo_1_4( - getResponderInfo_1_4_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::getResponderInfoInternal_1_4, hidl_status_cb); -} - -Return WifiRttController::enableResponder_1_4( - uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const V1_4::RttResponder& info, - enableResponder_1_4_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, - &WifiRttController::enableResponderInternal_1_4, hidl_status_cb, cmd_id, - channel_hint, max_duration_seconds, info); -} - -std::pair> -WifiRttController::getBoundIfaceInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_}; -} - -WifiStatus WifiRttController::registerEventCallbackInternal( - const sp& /* callback */) { - // Deprecated support for this api - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiRttController::rangeRequestInternal( - uint32_t /* cmd_id */, - const std::vector& /* rtt_configs */) { - // Deprecated support for this api - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiRttController::rangeCancelInternal( - uint32_t cmd_id, const std::vector>& addrs) { - std::vector> legacy_addrs; - for (const auto& addr : addrs) { - legacy_addrs.push_back(addr); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, - legacy_addrs); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair -WifiRttController::getCapabilitiesInternal() { - // Deprecated support for this api - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; -} - -WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id, - const RttLciInformation& lci) { - legacy_hal::wifi_lci_information legacy_lci; - if (!hidl_struct_util::convertHidlRttLciInformationToLegacy(lci, - &legacy_lci)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiRttController::setLcrInternal(uint32_t cmd_id, - const RttLcrInformation& lcr) { - legacy_hal::wifi_lcr_information legacy_lcr; - if (!hidl_struct_util::convertHidlRttLcrInformationToLegacy(lcr, - &legacy_lcr)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair -WifiRttController::getResponderInfoInternal() { - // Deprecated support for this api - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; -} - -WifiStatus WifiRttController::enableResponderInternal( - uint32_t /* cmd_id */, const WifiChannelInfo& /* channel_hint */, - uint32_t /* max_duration_seconds */, const V1_0::RttResponder& /* info */) { - // Deprecated support for this api - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)}; -} - -WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiRttController::registerEventCallbackInternal_1_4( - const sp& callback) { - // TODO(b/31632518): remove the callback when the client is destroyed - event_callbacks_.emplace_back(callback); - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -WifiStatus WifiRttController::rangeRequestInternal_1_4( - uint32_t cmd_id, const std::vector& rtt_configs) { - std::vector legacy_configs; - if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy( - rtt_configs, &legacy_configs)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - android::wp weak_ptr_this(this); - const auto& on_results_callback = - [weak_ptr_this]( - legacy_hal::wifi_request_id id, - const std::vector& results) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - std::vector hidl_results; - if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl( - results, &hidl_results)) { - LOG(ERROR) << "Failed to convert rtt results to HIDL structs"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - callback->onResults_1_4(id, hidl_results); - } - }; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startRttRangeRequest( - ifname_, cmd_id, legacy_configs, on_results_callback); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair -WifiRttController::getCapabilitiesInternal_1_4() { - legacy_hal::wifi_error legacy_status; - legacy_hal::wifi_rtt_capabilities legacy_caps; - std::tie(legacy_status, legacy_caps) = - legacy_hal_.lock()->getRttCapabilities(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - V1_4::RttCapabilities hidl_caps; - if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps, - &hidl_caps)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; -} - -std::pair -WifiRttController::getResponderInfoInternal_1_4() { - legacy_hal::wifi_error legacy_status; - legacy_hal::wifi_rtt_responder legacy_responder; - std::tie(legacy_status, legacy_responder) = - legacy_hal_.lock()->getRttResponderInfo(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - V1_4::RttResponder hidl_responder; - if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder, - &hidl_responder)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder}; -} - -WifiStatus WifiRttController::enableResponderInternal_1_4( - uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const V1_4::RttResponder& info) { - legacy_hal::wifi_channel_info legacy_channel_info; - if (!hidl_struct_util::convertHidlWifiChannelInfoToLegacy( - channel_hint, &legacy_channel_info)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_rtt_responder legacy_responder; - if (!hidl_struct_util::convertHidlRttResponderToLegacy(info, - &legacy_responder)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->enableRttResponder( - ifname_, cmd_id, legacy_channel_info, max_duration_seconds, - legacy_responder); - return createWifiStatusFromLegacyError(legacy_status); -} -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_rtt_controller.h b/wifi/1.5/default/wifi_rtt_controller.h deleted file mode 100644 index 9ac3e06fcc..0000000000 --- a/wifi/1.5/default/wifi_rtt_controller.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_RTT_CONTROLLER_H_ -#define WIFI_RTT_CONTROLLER_H_ - -#include -#include -#include -#include - -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { - -/** - * HIDL interface object used to control all RTT operations. - */ -class WifiRttController : public V1_4::IWifiRttController { - public: - WifiRttController( - const std::string& iface_name, const sp& bound_iface, - const std::weak_ptr legacy_hal); - // Refer to |WifiChip::invalidate()|. - void invalidate(); - bool isValid(); - std::vector> getEventCallbacks(); - std::string getIfaceName(); - - // HIDL methods exposed. - Return getBoundIface(getBoundIface_cb hidl_status_cb) override; - Return registerEventCallback( - const sp& callback, - registerEventCallback_cb hidl_status_cb) override; - Return rangeRequest(uint32_t cmd_id, - const hidl_vec& rtt_configs, - rangeRequest_cb hidl_status_cb) override; - Return rangeCancel(uint32_t cmd_id, - const hidl_vec>& addrs, - rangeCancel_cb hidl_status_cb) override; - Return getCapabilities(getCapabilities_cb hidl_status_cb) override; - Return setLci(uint32_t cmd_id, const RttLciInformation& lci, - setLci_cb hidl_status_cb) override; - Return setLcr(uint32_t cmd_id, const RttLcrInformation& lcr, - setLcr_cb hidl_status_cb) override; - Return getResponderInfo(getResponderInfo_cb hidl_status_cb) override; - Return enableResponder(uint32_t cmd_id, - const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, - const V1_0::RttResponder& info, - enableResponder_cb hidl_status_cb) override; - Return disableResponder(uint32_t cmd_id, - disableResponder_cb hidl_status_cb) override; - Return registerEventCallback_1_4( - const sp& callback, - registerEventCallback_1_4_cb hidl_status_cb) override; - Return rangeRequest_1_4(uint32_t cmd_id, - const hidl_vec& rtt_configs, - rangeRequest_1_4_cb hidl_status_cb) override; - Return getCapabilities_1_4( - getCapabilities_1_4_cb hidl_status_cb) override; - Return getResponderInfo_1_4( - getResponderInfo_1_4_cb hidl_status_cb) override; - Return enableResponder_1_4( - uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const V1_4::RttResponder& info, - enableResponder_1_4_cb hidl_status_cb) override; - - private: - // Corresponding worker functions for the HIDL methods. - std::pair> getBoundIfaceInternal(); - WifiStatus registerEventCallbackInternal( - const sp& callback); - WifiStatus rangeRequestInternal( - uint32_t cmd_id, const std::vector& rtt_configs); - WifiStatus rangeCancelInternal( - uint32_t cmd_id, const std::vector>& addrs); - std::pair getCapabilitiesInternal(); - WifiStatus setLciInternal(uint32_t cmd_id, const RttLciInformation& lci); - WifiStatus setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr); - std::pair getResponderInfoInternal(); - WifiStatus enableResponderInternal(uint32_t cmd_id, - const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, - const V1_0::RttResponder& info); - WifiStatus disableResponderInternal(uint32_t cmd_id); - WifiStatus registerEventCallbackInternal_1_4( - const sp& callback); - WifiStatus rangeRequestInternal_1_4( - uint32_t cmd_id, const std::vector& rtt_configs); - std::pair getCapabilitiesInternal_1_4(); - std::pair getResponderInfoInternal_1_4(); - WifiStatus enableResponderInternal_1_4(uint32_t cmd_id, - const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, - const V1_4::RttResponder& info); - - std::string ifname_; - sp bound_iface_; - std::weak_ptr legacy_hal_; - std::vector> event_callbacks_; - bool is_valid_; - - DISALLOW_COPY_AND_ASSIGN(WifiRttController); -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_RTT_CONTROLLER_H_ diff --git a/wifi/1.5/default/wifi_sta_iface.cpp b/wifi/1.5/default/wifi_sta_iface.cpp deleted file mode 100644 index 92c9fe4392..0000000000 --- a/wifi/1.5/default/wifi_sta_iface.cpp +++ /dev/null @@ -1,675 +0,0 @@ -/* - * 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. - */ - -#include - -#include "hidl_return_util.h" -#include "hidl_struct_util.h" -#include "wifi_sta_iface.h" -#include "wifi_status_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using hidl_return_util::validateAndCall; - -WifiStaIface::WifiStaIface( - const std::string& ifname, - const std::weak_ptr legacy_hal, - const std::weak_ptr iface_util) - : ifname_(ifname), - legacy_hal_(legacy_hal), - iface_util_(iface_util), - is_valid_(true) { - // Turn on DFS channel usage for STA iface. - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->setDfsFlag(ifname_, true); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) - << "Failed to set DFS flag; DFS channels may be unavailable."; - } -} - -void WifiStaIface::invalidate() { - legacy_hal_.reset(); - event_cb_handler_.invalidate(); - is_valid_ = false; -} - -bool WifiStaIface::isValid() { return is_valid_; } - -std::string WifiStaIface::getName() { return ifname_; } - -std::set> WifiStaIface::getEventCallbacks() { - return event_cb_handler_.getCallbacks(); -} - -Return WifiStaIface::getName(getName_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getNameInternal, hidl_status_cb); -} - -Return WifiStaIface::getType(getType_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getTypeInternal, hidl_status_cb); -} - -Return WifiStaIface::registerEventCallback( - const sp& callback, - registerEventCallback_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::registerEventCallbackInternal, - hidl_status_cb, callback); -} - -Return WifiStaIface::getCapabilities(getCapabilities_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getCapabilitiesInternal, - hidl_status_cb); -} - -Return WifiStaIface::getApfPacketFilterCapabilities( - getApfPacketFilterCapabilities_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getApfPacketFilterCapabilitiesInternal, hidl_status_cb); -} - -Return WifiStaIface::installApfPacketFilter( - uint32_t cmd_id, const hidl_vec& program, - installApfPacketFilter_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::installApfPacketFilterInternal, - hidl_status_cb, cmd_id, program); -} - -Return WifiStaIface::readApfPacketFilterData( - readApfPacketFilterData_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::readApfPacketFilterDataInternal, - hidl_status_cb); -} - -Return WifiStaIface::getBackgroundScanCapabilities( - getBackgroundScanCapabilities_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getBackgroundScanCapabilitiesInternal, - hidl_status_cb); -} - -Return WifiStaIface::getValidFrequenciesForBand( - V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getValidFrequenciesForBandInternal, - hidl_status_cb, band); -} - -Return WifiStaIface::startBackgroundScan( - uint32_t cmd_id, const StaBackgroundScanParameters& params, - startBackgroundScan_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::startBackgroundScanInternal, - hidl_status_cb, cmd_id, params); -} - -Return WifiStaIface::stopBackgroundScan( - uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::stopBackgroundScanInternal, - hidl_status_cb, cmd_id); -} - -Return WifiStaIface::enableLinkLayerStatsCollection( - bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::enableLinkLayerStatsCollectionInternal, hidl_status_cb, - debug); -} - -Return WifiStaIface::disableLinkLayerStatsCollection( - disableLinkLayerStatsCollection_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::disableLinkLayerStatsCollectionInternal, hidl_status_cb); -} - -Return WifiStaIface::getLinkLayerStats( - getLinkLayerStats_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getLinkLayerStatsInternal, - hidl_status_cb); -} - -Return WifiStaIface::getLinkLayerStats_1_3( - getLinkLayerStats_1_3_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getLinkLayerStatsInternal_1_3, - hidl_status_cb); -} - -Return WifiStaIface::getLinkLayerStats_1_5( - getLinkLayerStats_1_5_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getLinkLayerStatsInternal_1_5, - hidl_status_cb); -} - -Return WifiStaIface::startRssiMonitoring( - uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, - startRssiMonitoring_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::startRssiMonitoringInternal, - hidl_status_cb, cmd_id, max_rssi, min_rssi); -} - -Return WifiStaIface::stopRssiMonitoring( - uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::stopRssiMonitoringInternal, - hidl_status_cb, cmd_id); -} - -Return WifiStaIface::getRoamingCapabilities( - getRoamingCapabilities_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getRoamingCapabilitiesInternal, - hidl_status_cb); -} - -Return WifiStaIface::configureRoaming( - const StaRoamingConfig& config, configureRoaming_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::configureRoamingInternal, - hidl_status_cb, config); -} - -Return WifiStaIface::setRoamingState(StaRoamingState state, - setRoamingState_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::setRoamingStateInternal, - hidl_status_cb, state); -} - -Return WifiStaIface::enableNdOffload(bool enable, - enableNdOffload_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::enableNdOffloadInternal, - hidl_status_cb, enable); -} - -Return WifiStaIface::startSendingKeepAlivePackets( - uint32_t cmd_id, const hidl_vec& ip_packet_data, - uint16_t ether_type, const hidl_array& src_address, - const hidl_array& dst_address, uint32_t period_in_ms, - startSendingKeepAlivePackets_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::startSendingKeepAlivePacketsInternal, - hidl_status_cb, cmd_id, ip_packet_data, ether_type, - src_address, dst_address, period_in_ms); -} - -Return WifiStaIface::stopSendingKeepAlivePackets( - uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::stopSendingKeepAlivePacketsInternal, - hidl_status_cb, cmd_id); -} - -Return WifiStaIface::setScanningMacOui( - const hidl_array& oui, setScanningMacOui_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::setScanningMacOuiInternal, - hidl_status_cb, oui); -} - -Return WifiStaIface::startDebugPacketFateMonitoring( - startDebugPacketFateMonitoring_cb hidl_status_cb) { - return validateAndCall( - this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::startDebugPacketFateMonitoringInternal, hidl_status_cb); -} - -Return WifiStaIface::getDebugTxPacketFates( - getDebugTxPacketFates_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getDebugTxPacketFatesInternal, - hidl_status_cb); -} - -Return WifiStaIface::getDebugRxPacketFates( - getDebugRxPacketFates_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getDebugRxPacketFatesInternal, - hidl_status_cb); -} - -Return WifiStaIface::setMacAddress(const hidl_array& mac, - setMacAddress_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::setMacAddressInternal, hidl_status_cb, - mac); -} - -Return WifiStaIface::getFactoryMacAddress( - getFactoryMacAddress_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::getFactoryMacAddressInternal, - hidl_status_cb); -} - -Return WifiStaIface::setScanMode(bool enable, - setScanMode_cb hidl_status_cb) { - return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, - &WifiStaIface::setScanModeInternal, hidl_status_cb, - enable); -} - -std::pair WifiStaIface::getNameInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; -} - -std::pair WifiStaIface::getTypeInternal() { - return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::STA}; -} - -WifiStatus WifiStaIface::registerEventCallbackInternal( - const sp& callback) { - if (!event_cb_handler_.addCallback(callback)) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -std::pair WifiStaIface::getCapabilitiesInternal() { - legacy_hal::wifi_error legacy_status; - uint64_t legacy_feature_set; - std::tie(legacy_status, legacy_feature_set) = - legacy_hal_.lock()->getSupportedFeatureSet(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), 0}; - } - uint32_t legacy_logger_feature_set; - std::tie(legacy_status, legacy_logger_feature_set) = - 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; - } - uint32_t hidl_caps; - if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities( - legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; -} - -std::pair -WifiStaIface::getApfPacketFilterCapabilitiesInternal() { - legacy_hal::wifi_error legacy_status; - legacy_hal::PacketFilterCapabilities legacy_caps; - std::tie(legacy_status, legacy_caps) = - legacy_hal_.lock()->getPacketFilterCapabilities(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - StaApfPacketFilterCapabilities hidl_caps; - if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps, - &hidl_caps)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; -} - -WifiStatus WifiStaIface::installApfPacketFilterInternal( - uint32_t /* cmd_id */, const std::vector& program) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->setPacketFilter(ifname_, program); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair> -WifiStaIface::readApfPacketFilterDataInternal() { - const std::pair> - legacy_status_and_data = - legacy_hal_.lock()->readApfPacketFilterData(ifname_); - return {createWifiStatusFromLegacyError(legacy_status_and_data.first), - std::move(legacy_status_and_data.second)}; -} - -std::pair -WifiStaIface::getBackgroundScanCapabilitiesInternal() { - legacy_hal::wifi_error legacy_status; - legacy_hal::wifi_gscan_capabilities legacy_caps; - std::tie(legacy_status, legacy_caps) = - legacy_hal_.lock()->getGscanCapabilities(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - StaBackgroundScanCapabilities hidl_caps; - if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps, - &hidl_caps)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; -} - -std::pair> -WifiStaIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) { - static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), - "Size mismatch"); - legacy_hal::wifi_error legacy_status; - std::vector valid_frequencies; - std::tie(legacy_status, valid_frequencies) = - legacy_hal_.lock()->getValidFrequenciesForBand( - ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band)); - return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies}; -} - -WifiStatus WifiStaIface::startBackgroundScanInternal( - uint32_t cmd_id, const StaBackgroundScanParameters& params) { - legacy_hal::wifi_scan_cmd_params legacy_params; - if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params, - &legacy_params)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - android::wp weak_ptr_this(this); - const auto& on_failure_callback = - [weak_ptr_this](legacy_hal::wifi_request_id id) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onBackgroundScanFailure(id).isOk()) { - LOG(ERROR) - << "Failed to invoke onBackgroundScanFailure callback"; - } - } - }; - const auto& on_results_callback = - [weak_ptr_this]( - legacy_hal::wifi_request_id id, - const std::vector& results) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - std::vector hidl_scan_datas; - if (!hidl_struct_util:: - convertLegacyVectorOfCachedGscanResultsToHidl( - results, &hidl_scan_datas)) { - LOG(ERROR) << "Failed to convert scan results to HIDL structs"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onBackgroundScanResults(id, hidl_scan_datas) - .isOk()) { - LOG(ERROR) - << "Failed to invoke onBackgroundScanResults callback"; - } - } - }; - const auto& on_full_result_callback = [weak_ptr_this]( - legacy_hal::wifi_request_id id, - const legacy_hal:: - wifi_scan_result* result, - uint32_t buckets_scanned) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - StaScanResult hidl_scan_result; - if (!hidl_struct_util::convertLegacyGscanResultToHidl( - *result, true, &hidl_scan_result)) { - LOG(ERROR) << "Failed to convert full scan results to HIDL structs"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback - ->onBackgroundFullScanResult(id, buckets_scanned, - hidl_scan_result) - .isOk()) { - LOG(ERROR) - << "Failed to invoke onBackgroundFullScanResult callback"; - } - } - }; - legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startGscan( - ifname_, cmd_id, legacy_params, on_failure_callback, - on_results_callback, on_full_result_callback); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiStaIface::stopBackgroundScanInternal(uint32_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->stopGscan(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->disableLinkLayerStats(ifname_); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair -WifiStaIface::getLinkLayerStatsInternal() { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; -} - -std::pair -WifiStaIface::getLinkLayerStatsInternal_1_3() { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; -} - -std::pair -WifiStaIface::getLinkLayerStatsInternal_1_5() { - legacy_hal::wifi_error legacy_status; - legacy_hal::LinkLayerStats legacy_stats; - std::tie(legacy_status, legacy_stats) = - legacy_hal_.lock()->getLinkLayerStats(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - V1_5::StaLinkLayerStats hidl_stats; - if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, - &hidl_stats)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats}; -} - -WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id, - int32_t max_rssi, - int32_t min_rssi) { - android::wp weak_ptr_this(this); - const auto& on_threshold_breached_callback = - [weak_ptr_this](legacy_hal::wifi_request_id id, - std::array bssid, int8_t rssi) { - const auto shared_ptr_this = weak_ptr_this.promote(); - if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { - LOG(ERROR) << "Callback invoked on an invalid object"; - return; - } - for (const auto& callback : shared_ptr_this->getEventCallbacks()) { - if (!callback->onRssiThresholdBreached(id, bssid, rssi) - .isOk()) { - LOG(ERROR) - << "Failed to invoke onRssiThresholdBreached callback"; - } - } - }; - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startRssiMonitoring(ifname_, cmd_id, max_rssi, - min_rssi, - on_threshold_breached_callback); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiStaIface::stopRssiMonitoringInternal(uint32_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair -WifiStaIface::getRoamingCapabilitiesInternal() { - legacy_hal::wifi_error legacy_status; - legacy_hal::wifi_roaming_capabilities legacy_caps; - std::tie(legacy_status, legacy_caps) = - legacy_hal_.lock()->getRoamingCapabilities(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - StaRoamingCapabilities hidl_caps; - if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps, - &hidl_caps)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; -} - -WifiStatus WifiStaIface::configureRoamingInternal( - const StaRoamingConfig& config) { - legacy_hal::wifi_roaming_config legacy_config; - if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config, - &legacy_config)) { - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); - } - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->configureRoaming(ifname_, legacy_config); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->enableFirmwareRoaming( - ifname_, hidl_struct_util::convertHidlRoamingStateToLegacy(state)); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->configureNdOffload(ifname_, enable); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal( - uint32_t cmd_id, const std::vector& ip_packet_data, - uint16_t ether_type, const std::array& src_address, - const std::array& dst_address, uint32_t period_in_ms) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startSendingOffloadedPacket( - ifname_, cmd_id, ether_type, ip_packet_data, src_address, - dst_address, period_in_ms); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(uint32_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); -} - -WifiStatus WifiStaIface::setScanningMacOuiInternal( - const std::array& /* oui */) { - // deprecated. - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->startPktFateMonitoring(ifname_); - return createWifiStatusFromLegacyError(legacy_status); -} - -std::pair> -WifiStaIface::getDebugTxPacketFatesInternal() { - legacy_hal::wifi_error legacy_status; - std::vector legacy_fates; - std::tie(legacy_status, legacy_fates) = - legacy_hal_.lock()->getTxPktFates(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - std::vector hidl_fates; - if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl( - legacy_fates, &hidl_fates)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates}; -} - -std::pair> -WifiStaIface::getDebugRxPacketFatesInternal() { - legacy_hal::wifi_error legacy_status; - std::vector legacy_fates; - std::tie(legacy_status, legacy_fates) = - legacy_hal_.lock()->getRxPktFates(ifname_); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - return {createWifiStatusFromLegacyError(legacy_status), {}}; - } - std::vector hidl_fates; - if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl( - legacy_fates, &hidl_fates)) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates}; -} - -WifiStatus WifiStaIface::setMacAddressInternal( - const std::array& mac) { - bool status = iface_util_.lock()->setMacAddress(ifname_, mac); - if (!status) { - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); - } - return createWifiStatus(WifiStatusCode::SUCCESS); -} - -std::pair> -WifiStaIface::getFactoryMacAddressInternal() { - std::array mac = - iface_util_.lock()->getFactoryMacAddress(ifname_); - if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && - mac[4] == 0 && mac[5] == 0) { - return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; -} - -WifiStatus WifiStaIface::setScanModeInternal(bool enable) { - // OEM's need to implement this on their devices if needed. - LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported"; - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); -} - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_sta_iface.h b/wifi/1.5/default/wifi_sta_iface.h deleted file mode 100644 index f9058b8af1..0000000000 --- a/wifi/1.5/default/wifi_sta_iface.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_STA_IFACE_H_ -#define WIFI_STA_IFACE_H_ - -#include -#include -#include - -#include "hidl_callback_util.h" -#include "wifi_iface_util.h" -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; - -/** - * HIDL interface object used to control a STA Iface instance. - */ -class WifiStaIface : public V1_5::IWifiStaIface { - public: - WifiStaIface(const std::string& ifname, - const std::weak_ptr legacy_hal, - const std::weak_ptr iface_util); - // Refer to |WifiChip::invalidate()|. - void invalidate(); - bool isValid(); - std::set> getEventCallbacks(); - std::string getName(); - - // HIDL methods exposed. - Return getName(getName_cb hidl_status_cb) override; - Return getType(getType_cb hidl_status_cb) override; - Return registerEventCallback( - const sp& callback, - registerEventCallback_cb hidl_status_cb) override; - Return getCapabilities(getCapabilities_cb hidl_status_cb) override; - Return getApfPacketFilterCapabilities( - getApfPacketFilterCapabilities_cb hidl_status_cb) override; - Return installApfPacketFilter( - uint32_t cmd_id, const hidl_vec& program, - installApfPacketFilter_cb hidl_status_cb) override; - Return readApfPacketFilterData( - readApfPacketFilterData_cb hidl_status_cb) override; - Return getBackgroundScanCapabilities( - getBackgroundScanCapabilities_cb hidl_status_cb) override; - Return getValidFrequenciesForBand( - V1_0::WifiBand band, - getValidFrequenciesForBand_cb hidl_status_cb) override; - Return startBackgroundScan( - uint32_t cmd_id, const StaBackgroundScanParameters& params, - startBackgroundScan_cb hidl_status_cb) override; - Return stopBackgroundScan( - uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) override; - Return enableLinkLayerStatsCollection( - bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) override; - Return disableLinkLayerStatsCollection( - disableLinkLayerStatsCollection_cb hidl_status_cb) override; - Return getLinkLayerStats( - getLinkLayerStats_cb hidl_status_cb) override; - Return getLinkLayerStats_1_3( - getLinkLayerStats_1_3_cb hidl_status_cb) override; - Return getLinkLayerStats_1_5( - getLinkLayerStats_1_5_cb hidl_status_cb) override; - Return startRssiMonitoring( - uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, - startRssiMonitoring_cb hidl_status_cb) override; - Return stopRssiMonitoring( - uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override; - Return getRoamingCapabilities( - getRoamingCapabilities_cb hidl_status_cb) override; - Return configureRoaming(const StaRoamingConfig& config, - configureRoaming_cb hidl_status_cb) override; - Return setRoamingState(StaRoamingState state, - setRoamingState_cb hidl_status_cb) override; - Return enableNdOffload(bool enable, - enableNdOffload_cb hidl_status_cb) override; - Return startSendingKeepAlivePackets( - uint32_t cmd_id, const hidl_vec& ip_packet_data, - uint16_t ether_type, const hidl_array& src_address, - const hidl_array& dst_address, uint32_t period_in_ms, - startSendingKeepAlivePackets_cb hidl_status_cb) override; - Return stopSendingKeepAlivePackets( - uint32_t cmd_id, - stopSendingKeepAlivePackets_cb hidl_status_cb) override; - Return setScanningMacOui( - const hidl_array& oui, - setScanningMacOui_cb hidl_status_cb) override; - Return startDebugPacketFateMonitoring( - startDebugPacketFateMonitoring_cb hidl_status_cb) override; - Return getDebugTxPacketFates( - getDebugTxPacketFates_cb hidl_status_cb) override; - Return getDebugRxPacketFates( - getDebugRxPacketFates_cb hidl_status_cb) override; - Return setMacAddress(const hidl_array& mac, - setMacAddress_cb hidl_status_cb) override; - Return getFactoryMacAddress( - getFactoryMacAddress_cb hidl_status_cb) override; - Return setScanMode(bool enable, - setScanMode_cb hidl_status_cb) override; - - private: - // Corresponding worker functions for the HIDL methods. - std::pair getNameInternal(); - std::pair getTypeInternal(); - WifiStatus registerEventCallbackInternal( - const sp& callback); - std::pair getCapabilitiesInternal(); - std::pair - getApfPacketFilterCapabilitiesInternal(); - WifiStatus installApfPacketFilterInternal( - uint32_t cmd_id, const std::vector& program); - std::pair> - readApfPacketFilterDataInternal(); - std::pair - getBackgroundScanCapabilitiesInternal(); - std::pair> - getValidFrequenciesForBandInternal(V1_0::WifiBand band); - WifiStatus startBackgroundScanInternal( - uint32_t cmd_id, const StaBackgroundScanParameters& params); - WifiStatus stopBackgroundScanInternal(uint32_t cmd_id); - WifiStatus enableLinkLayerStatsCollectionInternal(bool debug); - WifiStatus disableLinkLayerStatsCollectionInternal(); - std::pair getLinkLayerStatsInternal(); - std::pair - getLinkLayerStatsInternal_1_3(); - std::pair - getLinkLayerStatsInternal_1_5(); - WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, - int32_t min_rssi); - WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id); - std::pair - getRoamingCapabilitiesInternal(); - WifiStatus configureRoamingInternal(const StaRoamingConfig& config); - WifiStatus setRoamingStateInternal(StaRoamingState state); - WifiStatus enableNdOffloadInternal(bool enable); - WifiStatus startSendingKeepAlivePacketsInternal( - uint32_t cmd_id, const std::vector& ip_packet_data, - uint16_t ether_type, const std::array& src_address, - const std::array& dst_address, uint32_t period_in_ms); - WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id); - WifiStatus setScanningMacOuiInternal(const std::array& oui); - WifiStatus startDebugPacketFateMonitoringInternal(); - std::pair> - getDebugTxPacketFatesInternal(); - std::pair> - getDebugRxPacketFatesInternal(); - WifiStatus setMacAddressInternal(const std::array& mac); - std::pair> - getFactoryMacAddressInternal(); - WifiStatus setScanModeInternal(bool enable); - - std::string ifname_; - std::weak_ptr legacy_hal_; - std::weak_ptr iface_util_; - bool is_valid_; - hidl_callback_util::HidlCallbackHandler - event_cb_handler_; - - DISALLOW_COPY_AND_ASSIGN(WifiStaIface); -}; - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_STA_IFACE_H_ diff --git a/wifi/1.5/default/wifi_status_util.cpp b/wifi/1.5/default/wifi_status_util.cpp deleted file mode 100644 index eb8c8694db..0000000000 --- a/wifi/1.5/default/wifi_status_util.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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. - */ - -#include "wifi_status_util.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { - -std::string legacyErrorToString(legacy_hal::wifi_error error) { - switch (error) { - case legacy_hal::WIFI_SUCCESS: - return "SUCCESS"; - case legacy_hal::WIFI_ERROR_UNINITIALIZED: - return "UNINITIALIZED"; - case legacy_hal::WIFI_ERROR_NOT_AVAILABLE: - return "NOT_AVAILABLE"; - case legacy_hal::WIFI_ERROR_NOT_SUPPORTED: - return "NOT_SUPPORTED"; - case legacy_hal::WIFI_ERROR_INVALID_ARGS: - return "INVALID_ARGS"; - case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID: - return "INVALID_REQUEST_ID"; - case legacy_hal::WIFI_ERROR_TIMED_OUT: - return "TIMED_OUT"; - case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS: - return "TOO_MANY_REQUESTS"; - case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY: - return "OUT_OF_MEMORY"; - case legacy_hal::WIFI_ERROR_BUSY: - return "BUSY"; - case legacy_hal::WIFI_ERROR_UNKNOWN: - return "UNKNOWN"; - default: - return "UNKNOWN ERROR"; - } -} - -WifiStatus createWifiStatus(WifiStatusCode code, - const std::string& description) { - return {code, description}; -} - -WifiStatus createWifiStatus(WifiStatusCode code) { - return createWifiStatus(code, ""); -} - -WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, - const std::string& desc) { - switch (error) { - case legacy_hal::WIFI_ERROR_UNINITIALIZED: - case legacy_hal::WIFI_ERROR_NOT_AVAILABLE: - return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, desc); - - case legacy_hal::WIFI_ERROR_NOT_SUPPORTED: - return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED, desc); - - case legacy_hal::WIFI_ERROR_INVALID_ARGS: - case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID: - return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS, desc); - - case legacy_hal::WIFI_ERROR_TIMED_OUT: - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, - desc + ", timed out"); - - case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS: - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, - desc + ", too many requests"); - - case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY: - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, - desc + ", out of memory"); - - case legacy_hal::WIFI_ERROR_BUSY: - return createWifiStatus(WifiStatusCode::ERROR_BUSY); - - case legacy_hal::WIFI_ERROR_NONE: - return createWifiStatus(WifiStatusCode::SUCCESS, desc); - - case legacy_hal::WIFI_ERROR_UNKNOWN: - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown"); - - default: - return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, - "unknown error"); - } -} - -WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) { - return createWifiStatusFromLegacyError(error, ""); -} - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android diff --git a/wifi/1.5/default/wifi_status_util.h b/wifi/1.5/default/wifi_status_util.h deleted file mode 100644 index 68f21689c5..0000000000 --- a/wifi/1.5/default/wifi_status_util.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - */ - -#ifndef WIFI_STATUS_UTIL_H_ -#define WIFI_STATUS_UTIL_H_ - -#include - -#include "wifi_legacy_hal.h" - -namespace android { -namespace hardware { -namespace wifi { -namespace V1_5 { -namespace implementation { -using namespace android::hardware::wifi::V1_0; - -std::string legacyErrorToString(legacy_hal::wifi_error error); -WifiStatus createWifiStatus(WifiStatusCode code, - const std::string& description); -WifiStatus createWifiStatus(WifiStatusCode code); -WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, - const std::string& description); -WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error); - -} // namespace implementation -} // namespace V1_5 -} // namespace wifi -} // namespace hardware -} // namespace android - -#endif // WIFI_STATUS_UTIL_H_ diff --git a/wifi/1.6/Android.bp b/wifi/1.6/Android.bp new file mode 100644 index 0000000000..d293c73a79 --- /dev/null +++ b/wifi/1.6/Android.bp @@ -0,0 +1,32 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +hidl_interface { + name: "android.hardware.wifi@1.6", + root: "android.hardware", + srcs: [ + "IWifi.hal", + ], + interfaces: [ + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", + "android.hidl.base@1.0", + ], + gen_java: true, + apex_available: [ + "//apex_available:platform", + "com.android.wifi", + ], +} diff --git a/wifi/1.6/IWifi.hal b/wifi/1.6/IWifi.hal new file mode 100644 index 0000000000..0123e6ca83 --- /dev/null +++ b/wifi/1.6/IWifi.hal @@ -0,0 +1,27 @@ +/* + * Copyright 2022 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.wifi@1.6; + +import @1.5::IWifi; + +/** + * This is the root of the HAL module and is the interface returned when + * loading an implementation of the Wi-Fi HAL. There must be at most one + * module loaded in the system. + * IWifi.getChip() must return @1.5::IWifiChip + */ +interface IWifi extends @1.5::IWifi {}; diff --git a/wifi/1.6/default/Android.bp b/wifi/1.6/default/Android.bp new file mode 100644 index 0000000000..6333b6e265 --- /dev/null +++ b/wifi/1.6/default/Android.bp @@ -0,0 +1,105 @@ +// Copyright (C) 2021 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 { + default_applicable_licenses: ["hardware_interfaces_license"], +} + +filegroup { + name: "android.hardware.wifi@1.0-service_srcs", + srcs: ["service.cpp"], +} + +cc_defaults { + name: "android.hardware.wifi@1.0-service_default", + srcs: [":android.hardware.wifi@1.0-service_srcs"], + relative_install_path: "hw", + soc_specific: true, + shared_libs: [ + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", + "libbase", + "libcutils", + "libhidlbase", + "liblog", + "libnl", + "libutils", + "libwifi-system-iface", + "libxml2", + ], + cppflags: [ + "-Wall", + "-Werror", + "-Wextra", + ], +} + +filegroup { + name: "android.hardware.wifi@1.0-service-lib_srcs", + srcs: [ + "hidl_struct_util.cpp", + "hidl_sync_util.cpp", + "ringbuffer.cpp", + "wifi.cpp", + "wifi_ap_iface.cpp", + "wifi_chip.cpp", + "wifi_feature_flags.cpp", + "wifi_iface_util.cpp", + "wifi_legacy_hal.cpp", + "wifi_legacy_hal_factory.cpp", + "wifi_legacy_hal_stubs.cpp", + "wifi_mode_controller.cpp", + "wifi_nan_iface.cpp", + "wifi_p2p_iface.cpp", + "wifi_rtt_controller.cpp", + "wifi_sta_iface.cpp", + "wifi_status_util.cpp", + ], +} + +cc_defaults { + name: "android.hardware.wifi@1.0-service-lib_defaults", + srcs: [":android.hardware.wifi@1.0-service-lib_srcs"], + relative_install_path: "hw", + soc_specific: true, + shared_libs: [ + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", + "libbase", + "libcutils", + "libhidlbase", + "liblog", + "libnl", + "libutils", + "libwifi-system-iface", + "libxml2", + ], + // Generated by building android.hardware.wifi@1.0-service-lib and printing LOCAL_CPPFLAGS. + cppflags: [ + "-Wall", + "-Werror", + "-Wextra", + "-DWIFI_HIDL_FEATURE_DUAL_INTERFACE", + ], + export_include_dirs: ["."], + include_dirs: ["external/libxml2/include"], +} diff --git a/wifi/1.6/default/Android.mk b/wifi/1.6/default/Android.mk new file mode 100644 index 0000000000..ca1c022db1 --- /dev/null +++ b/wifi/1.6/default/Android.mk @@ -0,0 +1,202 @@ +# 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. +LOCAL_PATH := $(call my-dir) + +### +### android.hardware.wifi static library +### +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.wifi@1.0-service-lib +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_PROPRIETARY_MODULE := true +LOCAL_CPPFLAGS := -Wall -Werror -Wextra +ifdef WIFI_HAL_INTERFACE_COMBINATIONS +LOCAL_CPPFLAGS += -DWIFI_HAL_INTERFACE_COMBINATIONS="$(WIFI_HAL_INTERFACE_COMBINATIONS)" +endif +ifdef WIFI_HIDL_FEATURE_AWARE +LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_AWARE +endif +ifdef WIFI_HIDL_FEATURE_DUAL_INTERFACE +LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DUAL_INTERFACE +endif +ifdef WIFI_HIDL_FEATURE_DISABLE_AP +LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP +endif +ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION +LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION +endif +ifdef WIFI_AVOID_IFACE_RESET_MAC_CHANGE +LOCAL_CPPFLAGS += -DWIFI_AVOID_IFACE_RESET_MAC_CHANGE +endif +# Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed. +LOCAL_CFLAGS += -Wno-error=implicit-fallthrough +LOCAL_SRC_FILES := \ + hidl_struct_util.cpp \ + hidl_sync_util.cpp \ + ringbuffer.cpp \ + wifi.cpp \ + wifi_ap_iface.cpp \ + wifi_chip.cpp \ + wifi_feature_flags.cpp \ + wifi_iface_util.cpp \ + wifi_legacy_hal.cpp \ + wifi_legacy_hal_factory.cpp \ + wifi_legacy_hal_stubs.cpp \ + wifi_mode_controller.cpp \ + wifi_nan_iface.cpp \ + wifi_p2p_iface.cpp \ + wifi_rtt_controller.cpp \ + wifi_sta_iface.cpp \ + wifi_status_util.cpp +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libcutils \ + libhidlbase \ + liblog \ + libnl \ + libutils \ + libwifi-hal \ + libwifi-system-iface \ + libxml2 \ + android.hardware.wifi@1.0 \ + android.hardware.wifi@1.1 \ + android.hardware.wifi@1.2 \ + android.hardware.wifi@1.3 \ + android.hardware.wifi@1.4 \ + android.hardware.wifi@1.5 \ + android.hardware.wifi@1.6 +LOCAL_C_INCLUDES += $(TOP)/external/libxml2/include +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) +include $(BUILD_STATIC_LIBRARY) + +### +### android.hardware.wifi daemon +### +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.wifi@1.0-service +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE +LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_PROPRIETARY_MODULE := true +LOCAL_CPPFLAGS := -Wall -Werror -Wextra +LOCAL_SRC_FILES := \ + service.cpp +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libcutils \ + libhidlbase \ + liblog \ + libnl \ + libutils \ + libwifi-hal \ + libwifi-system-iface \ + libxml2 \ + android.hardware.wifi@1.0 \ + android.hardware.wifi@1.1 \ + android.hardware.wifi@1.2 \ + android.hardware.wifi@1.3 \ + android.hardware.wifi@1.4 \ + android.hardware.wifi@1.5 \ + android.hardware.wifi@1.6 +LOCAL_STATIC_LIBRARIES := \ + android.hardware.wifi@1.0-service-lib +LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc +include $(BUILD_EXECUTABLE) + +### +### android.hardware.wifi daemon +### +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.wifi@1.0-service-lazy +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE +LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml +LOCAL_OVERRIDES_MODULES := android.hardware.wifi@1.0-service +LOCAL_CFLAGS := -DLAZY_SERVICE +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_PROPRIETARY_MODULE := true +LOCAL_CPPFLAGS := -Wall -Werror -Wextra +LOCAL_SRC_FILES := \ + service.cpp +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libcutils \ + libhidlbase \ + liblog \ + libnl \ + libutils \ + libwifi-hal \ + libwifi-system-iface \ + libxml2 \ + android.hardware.wifi@1.0 \ + android.hardware.wifi@1.1 \ + android.hardware.wifi@1.2 \ + android.hardware.wifi@1.3 \ + android.hardware.wifi@1.4 \ + android.hardware.wifi@1.5 \ + android.hardware.wifi@1.6 +LOCAL_STATIC_LIBRARIES := \ + android.hardware.wifi@1.0-service-lib +LOCAL_INIT_RC := android.hardware.wifi@1.0-service-lazy.rc +include $(BUILD_EXECUTABLE) + +### +### android.hardware.wifi unit tests. +### +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.wifi@1.0-service-tests +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE +LOCAL_PROPRIETARY_MODULE := true +LOCAL_CPPFLAGS := -Wall -Werror -Wextra +LOCAL_SRC_FILES := \ + tests/hidl_struct_util_unit_tests.cpp \ + tests/main.cpp \ + tests/mock_interface_tool.cpp \ + tests/mock_wifi_feature_flags.cpp \ + tests/mock_wifi_iface_util.cpp \ + tests/mock_wifi_legacy_hal.cpp \ + tests/mock_wifi_mode_controller.cpp \ + tests/ringbuffer_unit_tests.cpp \ + tests/wifi_nan_iface_unit_tests.cpp \ + tests/wifi_chip_unit_tests.cpp \ + tests/wifi_iface_util_unit_tests.cpp +LOCAL_STATIC_LIBRARIES := \ + libgmock \ + libgtest \ + android.hardware.wifi@1.0 \ + android.hardware.wifi@1.1 \ + android.hardware.wifi@1.2 \ + android.hardware.wifi@1.3 \ + android.hardware.wifi@1.4 \ + android.hardware.wifi@1.5 \ + android.hardware.wifi@1.6 \ + android.hardware.wifi@1.0-service-lib +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libcutils \ + libhidlbase \ + liblog \ + libnl \ + libutils \ + libwifi-hal \ + libwifi-system-iface +include $(BUILD_NATIVE_TEST) diff --git a/wifi/1.6/default/OWNERS b/wifi/1.6/default/OWNERS new file mode 100644 index 0000000000..cf81c79892 --- /dev/null +++ b/wifi/1.6/default/OWNERS @@ -0,0 +1,2 @@ +arabawy@google.com +etancohen@google.com diff --git a/wifi/1.6/default/THREADING.README b/wifi/1.6/default/THREADING.README new file mode 100644 index 0000000000..8366ca0201 --- /dev/null +++ b/wifi/1.6/default/THREADING.README @@ -0,0 +1,35 @@ +Vendor HAL Threading Model +========================== +The vendor HAL service has two threads: +1. HIDL thread: This is the main thread which processes all the incoming HIDL +RPC's. +2. Legacy HAL event loop thread: This is the thread forked off for processing +the legacy HAL event loop (wifi_event_loop()). This thread is used to process +any asynchronous netlink events posted by the driver. Any asynchronous +callbacks passed to the legacy HAL API's are invoked on this thread. + +Synchronization Concerns +======================== +wifi_legacy_hal.cpp has a bunch of global "C" style functions to handle the +legacy callbacks. Each of these "C" style function invokes a corresponding +"std::function" version of the callback which does the actual processing. +The variables holding these "std::function" callbacks are reset from the HIDL +thread when they are no longer used. For example: stopGscan() will reset the +corresponding "on_gscan_*" callback variables which were set when startGscan() +was invoked. This is not thread safe since these callback variables are +accesed from the legacy hal event loop thread as well. + +Synchronization Solution +======================== +Adding a global lock seems to be the most trivial solution to the problem. +a) All of the asynchronous "C" style callbacks will acquire the global lock +before invoking the corresponding "std::function" callback variables. +b) All of the HIDL methods will also acquire the global lock before processing +(in hidl_return_util::validateAndCall()). + +Note: It's important that we only acquire the global lock for asynchronous +callbacks, because there is no guarantee (or documentation to clarify) that the +synchronous callbacks are invoked on the same invocation thread. If that is not +the case in some implementation, we will end up deadlocking the system since the +HIDL thread would have acquired the global lock which is needed by the +synchronous callback executed on the legacy hal event loop thread. diff --git a/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc new file mode 100644 index 0000000000..bc6bb6a7e6 --- /dev/null +++ b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc @@ -0,0 +1,13 @@ +service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service-lazy + interface android.hardware.wifi@1.0::IWifi default + interface android.hardware.wifi@1.1::IWifi default + interface android.hardware.wifi@1.2::IWifi default + interface android.hardware.wifi@1.3::IWifi default + interface android.hardware.wifi@1.4::IWifi default + interface android.hardware.wifi@1.5::IWifi default + oneshot + disabled + class hal + capabilities NET_ADMIN NET_RAW SYS_MODULE + user wifi + group wifi gps diff --git a/wifi/1.6/default/android.hardware.wifi@1.0-service.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service.rc new file mode 100644 index 0000000000..18f40d0bb5 --- /dev/null +++ b/wifi/1.6/default/android.hardware.wifi@1.0-service.rc @@ -0,0 +1,12 @@ +service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service + interface android.hardware.wifi@1.0::IWifi default + interface android.hardware.wifi@1.1::IWifi default + interface android.hardware.wifi@1.2::IWifi default + interface android.hardware.wifi@1.3::IWifi default + interface android.hardware.wifi@1.4::IWifi default + interface android.hardware.wifi@1.5::IWifi default + interface android.hardware.wifi@1.6::IWifi default + class hal + capabilities NET_ADMIN NET_RAW SYS_MODULE + user wifi + group wifi gps diff --git a/wifi/1.6/default/android.hardware.wifi@1.0-service.xml b/wifi/1.6/default/android.hardware.wifi@1.0-service.xml new file mode 100644 index 0000000000..771fbaaf42 --- /dev/null +++ b/wifi/1.6/default/android.hardware.wifi@1.0-service.xml @@ -0,0 +1,11 @@ + + + android.hardware.wifi + hwbinder + 1.6 + + IWifi + default + + + diff --git a/wifi/1.6/default/hidl_callback_util.h b/wifi/1.6/default/hidl_callback_util.h new file mode 100644 index 0000000000..3ac54c1666 --- /dev/null +++ b/wifi/1.6/default/hidl_callback_util.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HIDL_CALLBACK_UTIL_H_ +#define HIDL_CALLBACK_UTIL_H_ + +#include + +#include + +namespace { +// Type of callback invoked by the death handler. +using on_death_cb_function = std::function; + +// Private class used to keep track of death of individual +// callbacks stored in HidlCallbackHandler. +template +class HidlDeathHandler : public android::hardware::hidl_death_recipient { + public: + HidlDeathHandler(const on_death_cb_function& user_cb_function) + : cb_function_(user_cb_function) {} + ~HidlDeathHandler() = default; + + // Death notification for callbacks. + void serviceDied(uint64_t cookie, + const android::wp& /* who */) override { + cb_function_(cookie); + } + + private: + on_death_cb_function cb_function_; + + DISALLOW_COPY_AND_ASSIGN(HidlDeathHandler); +}; +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace hidl_callback_util { +template +// Provides a class to manage callbacks for the various HIDL interfaces and +// handle the death of the process hosting each callback. +class HidlCallbackHandler { + public: + HidlCallbackHandler() + : death_handler_(new HidlDeathHandler( + std::bind(&HidlCallbackHandler::onObjectDeath, this, std::placeholders::_1))) {} + ~HidlCallbackHandler() = default; + + bool addCallback(const sp& cb) { + // TODO(b/33818800): Can't compare proxies yet. So, use the cookie + // (callback proxy's raw pointer) to track the death of individual + // clients. + uint64_t cookie = reinterpret_cast(cb.get()); + if (cb_set_.find(cb) != cb_set_.end()) { + LOG(WARNING) << "Duplicate death notification registration"; + return true; + } + if (!cb->linkToDeath(death_handler_, cookie)) { + LOG(ERROR) << "Failed to register death notification"; + return false; + } + cb_set_.insert(cb); + return true; + } + + const std::set>& getCallbacks() { return cb_set_; } + + // Death notification for callbacks. + void onObjectDeath(uint64_t cookie) { + CallbackType* cb = reinterpret_cast(cookie); + const auto& iter = cb_set_.find(cb); + if (iter == cb_set_.end()) { + LOG(ERROR) << "Unknown callback death notification received"; + return; + } + cb_set_.erase(iter); + LOG(DEBUG) << "Dead callback removed from list"; + } + + void invalidate() { + for (const sp& cb : cb_set_) { + if (!cb->unlinkToDeath(death_handler_)) { + LOG(ERROR) << "Failed to deregister death notification"; + } + } + cb_set_.clear(); + } + + private: + std::set> cb_set_; + sp> death_handler_; + + DISALLOW_COPY_AND_ASSIGN(HidlCallbackHandler); +}; + +} // namespace hidl_callback_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android +#endif // HIDL_CALLBACK_UTIL_H_ diff --git a/wifi/1.6/default/hidl_return_util.h b/wifi/1.6/default/hidl_return_util.h new file mode 100644 index 0000000000..a0efac2c57 --- /dev/null +++ b/wifi/1.6/default/hidl_return_util.h @@ -0,0 +1,118 @@ +/* + * 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. + */ + +#ifndef HIDL_RETURN_UTIL_H_ +#define HIDL_RETURN_UTIL_H_ + +#include "hidl_sync_util.h" +#include "wifi_status_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace hidl_return_util { +using namespace android::hardware::wifi::V1_0; + +/** + * These utility functions are used to invoke a method on the provided + * HIDL interface object. + * These functions checks if the provided HIDL interface object is valid. + * a) if valid, Invokes the corresponding internal implementation function of + * the HIDL method. It then invokes the HIDL continuation callback with + * the status and any returned values. + * b) if invalid, invokes the HIDL continuation callback with the + * provided error status and default values. + */ +// Use for HIDL methods which return only an instance of WifiStatus. +template +Return validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, + const std::function& hidl_cb, + Args&&... args) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (obj->isValid()) { + hidl_cb((obj->*work)(std::forward(args)...)); + } else { + hidl_cb(createWifiStatus(status_code_if_invalid)); + } + return Void(); +} + +// Use for HIDL methods which return only an instance of WifiStatus. +// This version passes the global lock acquired to the body of the method. +// Note: Only used by IWifi::stop() currently. +template +Return validateAndCallWithLock(ObjT* obj, WifiStatusCode status_code_if_invalid, + WorkFuncT&& work, + const std::function& hidl_cb, + Args&&... args) { + auto lock = hidl_sync_util::acquireGlobalLock(); + if (obj->isValid()) { + hidl_cb((obj->*work)(&lock, std::forward(args)...)); + } else { + hidl_cb(createWifiStatus(status_code_if_invalid)); + } + return Void(); +} + +// Use for HIDL methods which return instance of WifiStatus and a single return +// value. +template +Return validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, + const std::function& hidl_cb, + Args&&... args) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (obj->isValid()) { + const auto& ret_pair = (obj->*work)(std::forward(args)...); + const WifiStatus& status = std::get<0>(ret_pair); + const auto& ret_value = std::get<1>(ret_pair); + hidl_cb(status, ret_value); + } else { + hidl_cb(createWifiStatus(status_code_if_invalid), + typename std::remove_reference::type()); + } + return Void(); +} + +// Use for HIDL methods which return instance of WifiStatus and 2 return +// values. +template +Return validateAndCall( + ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work, + const std::function& hidl_cb, Args&&... args) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (obj->isValid()) { + const auto& ret_tuple = (obj->*work)(std::forward(args)...); + const WifiStatus& status = std::get<0>(ret_tuple); + const auto& ret_value1 = std::get<1>(ret_tuple); + const auto& ret_value2 = std::get<2>(ret_tuple); + hidl_cb(status, ret_value1, ret_value2); + } else { + hidl_cb(createWifiStatus(status_code_if_invalid), + typename std::remove_reference::type(), + typename std::remove_reference::type()); + } + return Void(); +} + +} // namespace hidl_return_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android +#endif // HIDL_RETURN_UTIL_H_ diff --git a/wifi/1.6/default/hidl_struct_util.cpp b/wifi/1.6/default/hidl_struct_util.cpp new file mode 100644 index 0000000000..3489c9e4d3 --- /dev/null +++ b/wifi/1.6/default/hidl_struct_util.cpp @@ -0,0 +1,2748 @@ +/* + * 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. + */ + +#include +#include + +#include "hidl_struct_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace hidl_struct_util { + +using V1_5::NanConfigRequestSupplemental; + +WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(legacy_hal::wifi_channel_width type); + +hidl_string safeConvertChar(const char* str, size_t max_len) { + const char* c = str; + size_t size = 0; + while (*c && (unsigned char)*c < 128 && size < max_len) { + ++size; + ++c; + } + return hidl_string(str, size); +} + +IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability(uint32_t feature) { + using HidlChipCaps = IWifiChip::ChipCapabilityMask; + switch (feature) { + case legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED: + return HidlChipCaps::DEBUG_MEMORY_FIRMWARE_DUMP; + case legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED: + return HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP; + case legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED: + return HidlChipCaps::DEBUG_RING_BUFFER_CONNECT_EVENT; + case legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED: + return HidlChipCaps::DEBUG_RING_BUFFER_POWER_EVENT; + case legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED: + return HidlChipCaps::DEBUG_RING_BUFFER_WAKELOCK_EVENT; + }; + CHECK(false) << "Unknown legacy feature: " << feature; + return {}; +} + +IWifiStaIface::StaIfaceCapabilityMask convertLegacyLoggerFeatureToHidlStaIfaceCapability( + uint32_t feature) { + using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask; + switch (feature) { + case legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED: + return HidlStaIfaceCaps::DEBUG_PACKET_FATE; + }; + CHECK(false) << "Unknown legacy feature: " << feature; + return {}; +} + +V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability(uint64_t feature) { + using HidlChipCaps = V1_5::IWifiChip::ChipCapabilityMask; + switch (feature) { + case WIFI_FEATURE_SET_TX_POWER_LIMIT: + return HidlChipCaps::SET_TX_POWER_LIMIT; + case WIFI_FEATURE_USE_BODY_HEAD_SAR: + return HidlChipCaps::USE_BODY_HEAD_SAR; + case WIFI_FEATURE_D2D_RTT: + return HidlChipCaps::D2D_RTT; + case WIFI_FEATURE_D2AP_RTT: + return HidlChipCaps::D2AP_RTT; + case WIFI_FEATURE_INFRA_60G: + return HidlChipCaps::WIGIG; + case WIFI_FEATURE_SET_LATENCY_MODE: + return HidlChipCaps::SET_LATENCY_MODE; + case WIFI_FEATURE_P2P_RAND_MAC: + return HidlChipCaps::P2P_RAND_MAC; + }; + CHECK(false) << "Unknown legacy feature: " << feature; + return {}; +} + +IWifiStaIface::StaIfaceCapabilityMask convertLegacyFeatureToHidlStaIfaceCapability( + uint64_t feature) { + using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask; + switch (feature) { + case WIFI_FEATURE_GSCAN: + return HidlStaIfaceCaps::BACKGROUND_SCAN; + case WIFI_FEATURE_LINK_LAYER_STATS: + return HidlStaIfaceCaps::LINK_LAYER_STATS; + case WIFI_FEATURE_RSSI_MONITOR: + return HidlStaIfaceCaps::RSSI_MONITOR; + case WIFI_FEATURE_CONTROL_ROAMING: + return HidlStaIfaceCaps::CONTROL_ROAMING; + case WIFI_FEATURE_IE_WHITELIST: + return HidlStaIfaceCaps::PROBE_IE_WHITELIST; + case WIFI_FEATURE_SCAN_RAND: + return HidlStaIfaceCaps::SCAN_RAND; + case WIFI_FEATURE_INFRA_5G: + return HidlStaIfaceCaps::STA_5G; + case WIFI_FEATURE_HOTSPOT: + return HidlStaIfaceCaps::HOTSPOT; + case WIFI_FEATURE_PNO: + return HidlStaIfaceCaps::PNO; + case WIFI_FEATURE_TDLS: + return HidlStaIfaceCaps::TDLS; + case WIFI_FEATURE_TDLS_OFFCHANNEL: + return HidlStaIfaceCaps::TDLS_OFFCHANNEL; + case WIFI_FEATURE_CONFIG_NDO: + return HidlStaIfaceCaps::ND_OFFLOAD; + case WIFI_FEATURE_MKEEP_ALIVE: + return HidlStaIfaceCaps::KEEP_ALIVE; + }; + CHECK(false) << "Unknown legacy feature: " << feature; + return {}; +} + +bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set, + uint32_t legacy_logger_feature_set, + uint32_t* hidl_caps) { + if (!hidl_caps) { + return false; + } + *hidl_caps = {}; + using HidlChipCaps = IWifiChip::ChipCapabilityMask; + for (const auto feature : {legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED, + legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED, + legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED, + legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED, + legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED}) { + if (feature & legacy_logger_feature_set) { + *hidl_caps |= convertLegacyLoggerFeatureToHidlChipCapability(feature); + } + } + std::vector features = {WIFI_FEATURE_SET_TX_POWER_LIMIT, + WIFI_FEATURE_USE_BODY_HEAD_SAR, + WIFI_FEATURE_D2D_RTT, + WIFI_FEATURE_D2AP_RTT, + WIFI_FEATURE_INFRA_60G, + WIFI_FEATURE_SET_LATENCY_MODE, + WIFI_FEATURE_P2P_RAND_MAC}; + for (const auto feature : features) { + if (feature & legacy_feature_set) { + *hidl_caps |= convertLegacyFeatureToHidlChipCapability(feature); + } + } + + // There are no flags for these 3 in the legacy feature set. Adding them to + // the set because all the current devices support it. + *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA; + *hidl_caps |= HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS; + *hidl_caps |= HidlChipCaps::DEBUG_ERROR_ALERTS; + return true; +} + +WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToHidl(uint32_t flag) { + switch (flag) { + case WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES: + return WifiDebugRingBufferFlags::HAS_BINARY_ENTRIES; + case WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES: + return WifiDebugRingBufferFlags::HAS_ASCII_ENTRIES; + }; + CHECK(false) << "Unknown legacy flag: " << flag; + return {}; +} + +bool convertLegacyDebugRingBufferStatusToHidl( + const legacy_hal::wifi_ring_buffer_status& legacy_status, + WifiDebugRingBufferStatus* hidl_status) { + if (!hidl_status) { + return false; + } + *hidl_status = {}; + hidl_status->ringName = safeConvertChar(reinterpret_cast(legacy_status.name), + sizeof(legacy_status.name)); + hidl_status->flags = 0; + for (const auto flag : + {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES, WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) { + if (flag & legacy_status.flags) { + hidl_status->flags |= static_cast::type>( + convertLegacyDebugRingBufferFlagsToHidl(flag)); + } + } + hidl_status->ringId = legacy_status.ring_id; + hidl_status->sizeInBytes = legacy_status.ring_buffer_byte_size; + // Calculate free size of the ring the buffer. We don't need to send the + // exact read/write pointers that were there in the legacy HAL interface. + if (legacy_status.written_bytes >= legacy_status.read_bytes) { + hidl_status->freeSizeInBytes = legacy_status.ring_buffer_byte_size - + (legacy_status.written_bytes - legacy_status.read_bytes); + } else { + hidl_status->freeSizeInBytes = legacy_status.read_bytes - legacy_status.written_bytes; + } + hidl_status->verboseLevel = legacy_status.verbose_level; + return true; +} + +bool convertLegacyVectorOfDebugRingBufferStatusToHidl( + const std::vector& legacy_status_vec, + std::vector* hidl_status_vec) { + if (!hidl_status_vec) { + return false; + } + *hidl_status_vec = {}; + for (const auto& legacy_status : legacy_status_vec) { + WifiDebugRingBufferStatus hidl_status; + if (!convertLegacyDebugRingBufferStatusToHidl(legacy_status, &hidl_status)) { + return false; + } + hidl_status_vec->push_back(hidl_status); + } + return true; +} + +bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats, + WifiDebugHostWakeReasonStats* hidl_stats) { + if (!hidl_stats) { + return false; + } + *hidl_stats = {}; + hidl_stats->totalCmdEventWakeCnt = legacy_stats.wake_reason_cnt.total_cmd_event_wake; + hidl_stats->cmdEventWakeCntPerType = legacy_stats.cmd_event_wake_cnt; + hidl_stats->totalDriverFwLocalWakeCnt = legacy_stats.wake_reason_cnt.total_driver_fw_local_wake; + hidl_stats->driverFwLocalWakeCntPerType = legacy_stats.driver_fw_local_wake_cnt; + hidl_stats->totalRxPacketWakeCnt = legacy_stats.wake_reason_cnt.total_rx_data_wake; + hidl_stats->rxPktWakeDetails.rxUnicastCnt = + legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt; + hidl_stats->rxPktWakeDetails.rxMulticastCnt = + legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt; + hidl_stats->rxPktWakeDetails.rxBroadcastCnt = + legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt; + hidl_stats->rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt = + legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt; + hidl_stats->rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt = + legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt; + hidl_stats->rxMulticastPkWakeDetails.otherRxMulticastAddrCnt = + legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt; + hidl_stats->rxIcmpPkWakeDetails.icmpPkt = + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt; + hidl_stats->rxIcmpPkWakeDetails.icmp6Pkt = + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt; + hidl_stats->rxIcmpPkWakeDetails.icmp6Ra = + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra; + hidl_stats->rxIcmpPkWakeDetails.icmp6Na = + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na; + hidl_stats->rxIcmpPkWakeDetails.icmp6Ns = + legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns; + return true; +} + +legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( + V1_1::IWifiChip::TxPowerScenario hidl_scenario) { + switch (hidl_scenario) { + // This is the only supported scenario for V1_1 + case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL: + return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL; + }; + CHECK(false); +} + +legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( + V1_2::IWifiChip::TxPowerScenario hidl_scenario) { + switch (hidl_scenario) { + // This is the only supported scenario for V1_1 + case V1_2::IWifiChip::TxPowerScenario::VOICE_CALL: + return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL; + // Those are the supported scenarios for V1_2 + case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF: + return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF; + case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_ON: + return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON; + case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF: + return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF; + case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_ON: + return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON; + }; + CHECK(false); +} + +legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( + V1_3::IWifiChip::LatencyMode hidl_latency_mode) { + switch (hidl_latency_mode) { + case V1_3::IWifiChip::LatencyMode::NORMAL: + return legacy_hal::WIFI_LATENCY_MODE_NORMAL; + case V1_3::IWifiChip::LatencyMode::LOW: + return legacy_hal::WIFI_LATENCY_MODE_LOW; + } + CHECK(false); +} + +bool convertLegacyWifiMacInfoToHidl( + const legacy_hal::WifiMacInfo& legacy_mac_info, + V1_4::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) { + if (!hidl_radio_mode_info) { + return false; + } + *hidl_radio_mode_info = {}; + + hidl_radio_mode_info->radioId = legacy_mac_info.wlan_mac_id; + // Convert from bitmask of bands in the legacy HAL to enum value in + // the HIDL interface. + if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND && + legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND && + legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) { + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ_6GHZ; + } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND && + legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) { + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ_6GHZ; + } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND) { + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_6GHZ; + } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND && + legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) { + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ; + } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) { + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ; + } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) { + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ; + } else { + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_UNSPECIFIED; + } + std::vector iface_info_vec; + for (const auto& legacy_iface_info : legacy_mac_info.iface_infos) { + V1_2::IWifiChipEventCallback::IfaceInfo iface_info; + iface_info.name = legacy_iface_info.name; + iface_info.channel = legacy_iface_info.channel; + iface_info_vec.push_back(iface_info); + } + hidl_radio_mode_info->ifaceInfos = iface_info_vec; + return true; +} + +uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) { + switch (hidl_band) { + case V1_5::WifiBand::BAND_24GHZ: + return legacy_hal::WLAN_MAC_2_4_BAND; + case V1_5::WifiBand::BAND_5GHZ: + case V1_5::WifiBand::BAND_5GHZ_DFS: + case V1_5::WifiBand::BAND_5GHZ_WITH_DFS: + return legacy_hal::WLAN_MAC_5_0_BAND; + case V1_5::WifiBand::BAND_24GHZ_5GHZ: + case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS: + return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND); + case V1_5::WifiBand::BAND_6GHZ: + return legacy_hal::WLAN_MAC_6_0_BAND; + case V1_5::WifiBand::BAND_5GHZ_6GHZ: + return (legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_6_0_BAND); + case V1_5::WifiBand::BAND_24GHZ_5GHZ_6GHZ: + case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ: + return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND | + legacy_hal::WLAN_MAC_6_0_BAND); + case V1_5::WifiBand::BAND_60GHZ: + return legacy_hal::WLAN_MAC_60_0_BAND; + default: + return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND | + legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND); + } +} + +uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask) { + uint32_t legacy_iface_mask = 0; + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_STA) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_NAN) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_TDLS) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_MESH) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_IBSS) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS); + } + return legacy_iface_mask; +} + +uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) { + uint32_t hidl_iface_mask = 0; + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_STA; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_NAN; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_TDLS; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_MESH; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_IBSS; + } + return hidl_iface_mask; +} + +uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask) { + uint32_t legacy_filter_mask = 0; + if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) { + legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE; + } + if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CONCURRENCY) { + legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY; + } + return legacy_filter_mask; +} + +bool convertLegacyWifiUsableChannelToHidl( + const legacy_hal::wifi_usable_channel& legacy_usable_channel, + V1_5::WifiUsableChannel* hidl_usable_channel) { + if (!hidl_usable_channel) { + return false; + } + *hidl_usable_channel = {}; + hidl_usable_channel->channel = legacy_usable_channel.freq; + hidl_usable_channel->channelBandwidth = + convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width); + hidl_usable_channel->ifaceModeMask = + convertLegacyWifiInterfaceModeToHidl(legacy_usable_channel.iface_mode_mask); + + return true; +} + +bool convertLegacyWifiUsableChannelsToHidl( + const std::vector& legacy_usable_channels, + std::vector* hidl_usable_channels) { + if (!hidl_usable_channels) { + return false; + } + *hidl_usable_channels = {}; + for (const auto& legacy_usable_channel : legacy_usable_channels) { + V1_5::WifiUsableChannel hidl_usable_channel; + if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel, &hidl_usable_channel)) { + return false; + } + hidl_usable_channels->push_back(hidl_usable_channel); + } + return true; +} + +bool convertLegacyWifiMacInfosToHidl( + const std::vector& legacy_mac_infos, + std::vector* hidl_radio_mode_infos) { + if (!hidl_radio_mode_infos) { + return false; + } + *hidl_radio_mode_infos = {}; + + for (const auto& legacy_mac_info : legacy_mac_infos) { + V1_4::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info; + if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info, &hidl_radio_mode_info)) { + return false; + } + hidl_radio_mode_infos->push_back(hidl_radio_mode_info); + } + return true; +} + +bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set, + uint32_t legacy_logger_feature_set, + uint32_t* hidl_caps) { + if (!hidl_caps) { + return false; + } + *hidl_caps = {}; + using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask; + for (const auto feature : {legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED}) { + if (feature & legacy_logger_feature_set) { + *hidl_caps |= convertLegacyLoggerFeatureToHidlStaIfaceCapability(feature); + } + } + for (const auto feature : + {WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, WIFI_FEATURE_RSSI_MONITOR, + WIFI_FEATURE_CONTROL_ROAMING, WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND, + WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, WIFI_FEATURE_TDLS, + WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) { + if (feature & legacy_feature_set) { + *hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature); + } + } + // There is no flag for this one in the legacy feature set. Adding it to the + // set because all the current devices support it. + *hidl_caps |= HidlStaIfaceCaps::APF; + return true; +} + +bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps, + StaApfPacketFilterCapabilities* hidl_caps) { + if (!hidl_caps) { + return false; + } + *hidl_caps = {}; + hidl_caps->version = legacy_caps.version; + hidl_caps->maxLength = legacy_caps.max_len; + return true; +} + +uint8_t convertHidlGscanReportEventFlagToLegacy( + StaBackgroundScanBucketEventReportSchemeMask hidl_flag) { + using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask; + switch (hidl_flag) { + case HidlFlag::EACH_SCAN: + return REPORT_EVENTS_EACH_SCAN; + case HidlFlag::FULL_RESULTS: + return REPORT_EVENTS_FULL_RESULTS; + case HidlFlag::NO_BATCH: + return REPORT_EVENTS_NO_BATCH; + }; + CHECK(false); +} + +StaScanDataFlagMask convertLegacyGscanDataFlagToHidl(uint8_t legacy_flag) { + switch (legacy_flag) { + case legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED: + return StaScanDataFlagMask::INTERRUPTED; + }; + CHECK(false) << "Unknown legacy flag: " << legacy_flag; + // To silence the compiler warning about reaching the end of non-void + // function. + return {}; +} + +bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps, + StaBackgroundScanCapabilities* hidl_caps) { + if (!hidl_caps) { + return false; + } + *hidl_caps = {}; + hidl_caps->maxCacheSize = legacy_caps.max_scan_cache_size; + hidl_caps->maxBuckets = legacy_caps.max_scan_buckets; + hidl_caps->maxApCachePerScan = legacy_caps.max_ap_cache_per_scan; + hidl_caps->maxReportingThreshold = legacy_caps.max_scan_reporting_threshold; + return true; +} + +legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band) { + switch (band) { + case V1_0::WifiBand::BAND_UNSPECIFIED: + return legacy_hal::WIFI_BAND_UNSPECIFIED; + case V1_0::WifiBand::BAND_24GHZ: + return legacy_hal::WIFI_BAND_BG; + case V1_0::WifiBand::BAND_5GHZ: + return legacy_hal::WIFI_BAND_A; + case V1_0::WifiBand::BAND_5GHZ_DFS: + return legacy_hal::WIFI_BAND_A_DFS; + case V1_0::WifiBand::BAND_5GHZ_WITH_DFS: + return legacy_hal::WIFI_BAND_A_WITH_DFS; + case V1_0::WifiBand::BAND_24GHZ_5GHZ: + return legacy_hal::WIFI_BAND_ABG; + case V1_0::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS: + return legacy_hal::WIFI_BAND_ABG_WITH_DFS; + }; + CHECK(false); +} + +bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params, + legacy_hal::wifi_scan_cmd_params* legacy_scan_params) { + if (!legacy_scan_params) { + return false; + } + *legacy_scan_params = {}; + legacy_scan_params->base_period = hidl_scan_params.basePeriodInMs; + legacy_scan_params->max_ap_per_scan = hidl_scan_params.maxApPerScan; + legacy_scan_params->report_threshold_percent = hidl_scan_params.reportThresholdPercent; + legacy_scan_params->report_threshold_num_scans = hidl_scan_params.reportThresholdNumScans; + if (hidl_scan_params.buckets.size() > MAX_BUCKETS) { + return false; + } + legacy_scan_params->num_buckets = hidl_scan_params.buckets.size(); + for (uint32_t bucket_idx = 0; bucket_idx < hidl_scan_params.buckets.size(); bucket_idx++) { + const StaBackgroundScanBucketParameters& hidl_bucket_spec = + hidl_scan_params.buckets[bucket_idx]; + legacy_hal::wifi_scan_bucket_spec& legacy_bucket_spec = + legacy_scan_params->buckets[bucket_idx]; + if (hidl_bucket_spec.bucketIdx >= MAX_BUCKETS) { + return false; + } + legacy_bucket_spec.bucket = hidl_bucket_spec.bucketIdx; + legacy_bucket_spec.band = convertHidlWifiBandToLegacy(hidl_bucket_spec.band); + legacy_bucket_spec.period = hidl_bucket_spec.periodInMs; + legacy_bucket_spec.max_period = hidl_bucket_spec.exponentialMaxPeriodInMs; + legacy_bucket_spec.base = hidl_bucket_spec.exponentialBase; + legacy_bucket_spec.step_count = hidl_bucket_spec.exponentialStepCount; + legacy_bucket_spec.report_events = 0; + using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask; + for (const auto flag : {HidlFlag::EACH_SCAN, HidlFlag::FULL_RESULTS, HidlFlag::NO_BATCH}) { + if (hidl_bucket_spec.eventReportScheme & + static_cast::type>(flag)) { + legacy_bucket_spec.report_events |= convertHidlGscanReportEventFlagToLegacy(flag); + } + } + if (hidl_bucket_spec.frequencies.size() > MAX_CHANNELS) { + return false; + } + legacy_bucket_spec.num_channels = hidl_bucket_spec.frequencies.size(); + for (uint32_t freq_idx = 0; freq_idx < hidl_bucket_spec.frequencies.size(); freq_idx++) { + legacy_bucket_spec.channels[freq_idx].channel = hidl_bucket_spec.frequencies[freq_idx]; + } + } + return true; +} + +bool convertLegacyIeToHidl(const legacy_hal::wifi_information_element& legacy_ie, + WifiInformationElement* hidl_ie) { + if (!hidl_ie) { + return false; + } + *hidl_ie = {}; + hidl_ie->id = legacy_ie.id; + hidl_ie->data = std::vector(legacy_ie.data, legacy_ie.data + legacy_ie.len); + return true; +} + +bool convertLegacyIeBlobToHidl(const uint8_t* ie_blob, uint32_t ie_blob_len, + std::vector* hidl_ies) { + if (!ie_blob || !hidl_ies) { + return false; + } + *hidl_ies = {}; + const uint8_t* ies_begin = ie_blob; + const uint8_t* ies_end = ie_blob + ie_blob_len; + const uint8_t* next_ie = ies_begin; + using wifi_ie = legacy_hal::wifi_information_element; + constexpr size_t kIeHeaderLen = sizeof(wifi_ie); + // Each IE should atleast have the header (i.e |id| & |len| fields). + while (next_ie + kIeHeaderLen <= ies_end) { + const wifi_ie& legacy_ie = (*reinterpret_cast(next_ie)); + uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len; + if (next_ie + curr_ie_len > ies_end) { + LOG(ERROR) << "Error parsing IE blob. Next IE: " << (void*)next_ie + << ", Curr IE len: " << curr_ie_len << ", IEs End: " << (void*)ies_end; + break; + } + WifiInformationElement hidl_ie; + if (!convertLegacyIeToHidl(legacy_ie, &hidl_ie)) { + LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id << ", len: " << legacy_ie.len; + break; + } + hidl_ies->push_back(std::move(hidl_ie)); + next_ie += curr_ie_len; + } + // Check if the blob has been fully consumed. + if (next_ie != ies_end) { + LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " << (void*)next_ie + << ", IEs End: " << (void*)ies_end; + } + return true; +} + +bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result, + bool has_ie_data, StaScanResult* hidl_scan_result) { + if (!hidl_scan_result) { + return false; + } + *hidl_scan_result = {}; + hidl_scan_result->timeStampInUs = legacy_scan_result.ts; + hidl_scan_result->ssid = std::vector( + legacy_scan_result.ssid, + legacy_scan_result.ssid + + strnlen(legacy_scan_result.ssid, sizeof(legacy_scan_result.ssid) - 1)); + memcpy(hidl_scan_result->bssid.data(), legacy_scan_result.bssid, + hidl_scan_result->bssid.size()); + hidl_scan_result->frequency = legacy_scan_result.channel; + hidl_scan_result->rssi = legacy_scan_result.rssi; + hidl_scan_result->beaconPeriodInMs = legacy_scan_result.beacon_period; + hidl_scan_result->capability = legacy_scan_result.capability; + if (has_ie_data) { + std::vector ies; + if (!convertLegacyIeBlobToHidl(reinterpret_cast(legacy_scan_result.ie_data), + legacy_scan_result.ie_length, &ies)) { + return false; + } + hidl_scan_result->informationElements = std::move(ies); + } + return true; +} + +bool convertLegacyCachedGscanResultsToHidl( + const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result, + StaScanData* hidl_scan_data) { + if (!hidl_scan_data) { + return false; + } + *hidl_scan_data = {}; + hidl_scan_data->flags = 0; + for (const auto flag : {legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED}) { + if (legacy_cached_scan_result.flags & flag) { + hidl_scan_data->flags |= static_cast::type>( + convertLegacyGscanDataFlagToHidl(flag)); + } + } + hidl_scan_data->bucketsScanned = legacy_cached_scan_result.buckets_scanned; + + CHECK(legacy_cached_scan_result.num_results >= 0 && + legacy_cached_scan_result.num_results <= MAX_AP_CACHE_PER_SCAN); + std::vector hidl_scan_results; + for (int32_t result_idx = 0; result_idx < legacy_cached_scan_result.num_results; result_idx++) { + StaScanResult hidl_scan_result; + if (!convertLegacyGscanResultToHidl(legacy_cached_scan_result.results[result_idx], false, + &hidl_scan_result)) { + return false; + } + hidl_scan_results.push_back(hidl_scan_result); + } + hidl_scan_data->results = std::move(hidl_scan_results); + return true; +} + +bool convertLegacyVectorOfCachedGscanResultsToHidl( + const std::vector& legacy_cached_scan_results, + std::vector* hidl_scan_datas) { + if (!hidl_scan_datas) { + return false; + } + *hidl_scan_datas = {}; + for (const auto& legacy_cached_scan_result : legacy_cached_scan_results) { + StaScanData hidl_scan_data; + if (!convertLegacyCachedGscanResultsToHidl(legacy_cached_scan_result, &hidl_scan_data)) { + return false; + } + hidl_scan_datas->push_back(hidl_scan_data); + } + return true; +} + +WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToHidl(legacy_hal::wifi_tx_packet_fate fate) { + switch (fate) { + case legacy_hal::TX_PKT_FATE_ACKED: + return WifiDebugTxPacketFate::ACKED; + case legacy_hal::TX_PKT_FATE_SENT: + return WifiDebugTxPacketFate::SENT; + case legacy_hal::TX_PKT_FATE_FW_QUEUED: + return WifiDebugTxPacketFate::FW_QUEUED; + case legacy_hal::TX_PKT_FATE_FW_DROP_INVALID: + return WifiDebugTxPacketFate::FW_DROP_INVALID; + case legacy_hal::TX_PKT_FATE_FW_DROP_NOBUFS: + return WifiDebugTxPacketFate::FW_DROP_NOBUFS; + case legacy_hal::TX_PKT_FATE_FW_DROP_OTHER: + return WifiDebugTxPacketFate::FW_DROP_OTHER; + case legacy_hal::TX_PKT_FATE_DRV_QUEUED: + return WifiDebugTxPacketFate::DRV_QUEUED; + case legacy_hal::TX_PKT_FATE_DRV_DROP_INVALID: + return WifiDebugTxPacketFate::DRV_DROP_INVALID; + case legacy_hal::TX_PKT_FATE_DRV_DROP_NOBUFS: + return WifiDebugTxPacketFate::DRV_DROP_NOBUFS; + case legacy_hal::TX_PKT_FATE_DRV_DROP_OTHER: + return WifiDebugTxPacketFate::DRV_DROP_OTHER; + }; + CHECK(false) << "Unknown legacy fate type: " << fate; +} + +WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToHidl(legacy_hal::wifi_rx_packet_fate fate) { + switch (fate) { + case legacy_hal::RX_PKT_FATE_SUCCESS: + return WifiDebugRxPacketFate::SUCCESS; + case legacy_hal::RX_PKT_FATE_FW_QUEUED: + return WifiDebugRxPacketFate::FW_QUEUED; + case legacy_hal::RX_PKT_FATE_FW_DROP_FILTER: + return WifiDebugRxPacketFate::FW_DROP_FILTER; + case legacy_hal::RX_PKT_FATE_FW_DROP_INVALID: + return WifiDebugRxPacketFate::FW_DROP_INVALID; + case legacy_hal::RX_PKT_FATE_FW_DROP_NOBUFS: + return WifiDebugRxPacketFate::FW_DROP_NOBUFS; + case legacy_hal::RX_PKT_FATE_FW_DROP_OTHER: + return WifiDebugRxPacketFate::FW_DROP_OTHER; + case legacy_hal::RX_PKT_FATE_DRV_QUEUED: + return WifiDebugRxPacketFate::DRV_QUEUED; + case legacy_hal::RX_PKT_FATE_DRV_DROP_FILTER: + return WifiDebugRxPacketFate::DRV_DROP_FILTER; + case legacy_hal::RX_PKT_FATE_DRV_DROP_INVALID: + return WifiDebugRxPacketFate::DRV_DROP_INVALID; + case legacy_hal::RX_PKT_FATE_DRV_DROP_NOBUFS: + return WifiDebugRxPacketFate::DRV_DROP_NOBUFS; + case legacy_hal::RX_PKT_FATE_DRV_DROP_OTHER: + return WifiDebugRxPacketFate::DRV_DROP_OTHER; + }; + CHECK(false) << "Unknown legacy fate type: " << fate; +} + +WifiDebugPacketFateFrameType convertLegacyDebugPacketFateFrameTypeToHidl( + legacy_hal::frame_type type) { + switch (type) { + case legacy_hal::FRAME_TYPE_UNKNOWN: + return WifiDebugPacketFateFrameType::UNKNOWN; + case legacy_hal::FRAME_TYPE_ETHERNET_II: + return WifiDebugPacketFateFrameType::ETHERNET_II; + case legacy_hal::FRAME_TYPE_80211_MGMT: + return WifiDebugPacketFateFrameType::MGMT_80211; + }; + CHECK(false) << "Unknown legacy frame type: " << type; +} + +bool convertLegacyDebugPacketFateFrameToHidl(const legacy_hal::frame_info& legacy_frame, + WifiDebugPacketFateFrameInfo* hidl_frame) { + if (!hidl_frame) { + return false; + } + *hidl_frame = {}; + hidl_frame->frameType = convertLegacyDebugPacketFateFrameTypeToHidl(legacy_frame.payload_type); + hidl_frame->frameLen = legacy_frame.frame_len; + hidl_frame->driverTimestampUsec = legacy_frame.driver_timestamp_usec; + hidl_frame->firmwareTimestampUsec = legacy_frame.firmware_timestamp_usec; + const uint8_t* frame_begin = + reinterpret_cast(legacy_frame.frame_content.ethernet_ii_bytes); + hidl_frame->frameContent = + std::vector(frame_begin, frame_begin + legacy_frame.frame_len); + return true; +} + +bool convertLegacyDebugTxPacketFateToHidl(const legacy_hal::wifi_tx_report& legacy_fate, + WifiDebugTxPacketFateReport* hidl_fate) { + if (!hidl_fate) { + return false; + } + *hidl_fate = {}; + hidl_fate->fate = convertLegacyDebugTxPacketFateToHidl(legacy_fate.fate); + return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo); +} + +bool convertLegacyVectorOfDebugTxPacketFateToHidl( + const std::vector& legacy_fates, + std::vector* hidl_fates) { + if (!hidl_fates) { + return false; + } + *hidl_fates = {}; + for (const auto& legacy_fate : legacy_fates) { + WifiDebugTxPacketFateReport hidl_fate; + if (!convertLegacyDebugTxPacketFateToHidl(legacy_fate, &hidl_fate)) { + return false; + } + hidl_fates->push_back(hidl_fate); + } + return true; +} + +bool convertLegacyDebugRxPacketFateToHidl(const legacy_hal::wifi_rx_report& legacy_fate, + WifiDebugRxPacketFateReport* hidl_fate) { + if (!hidl_fate) { + return false; + } + *hidl_fate = {}; + hidl_fate->fate = convertLegacyDebugRxPacketFateToHidl(legacy_fate.fate); + return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo); +} + +bool convertLegacyVectorOfDebugRxPacketFateToHidl( + const std::vector& legacy_fates, + std::vector* hidl_fates) { + if (!hidl_fates) { + return false; + } + *hidl_fates = {}; + for (const auto& legacy_fate : legacy_fates) { + WifiDebugRxPacketFateReport hidl_fate; + if (!convertLegacyDebugRxPacketFateToHidl(legacy_fate, &hidl_fate)) { + return false; + } + hidl_fates->push_back(hidl_fate); + } + return true; +} + +bool convertLegacyLinkLayerRadioStatsToHidl( + const legacy_hal::LinkLayerRadioStats& legacy_radio_stat, + V1_5::StaLinkLayerRadioStats* hidl_radio_stat) { + if (!hidl_radio_stat) { + return false; + } + *hidl_radio_stat = {}; + + hidl_radio_stat->radioId = legacy_radio_stat.stats.radio; + hidl_radio_stat->V1_3.V1_0.onTimeInMs = legacy_radio_stat.stats.on_time; + hidl_radio_stat->V1_3.V1_0.txTimeInMs = legacy_radio_stat.stats.tx_time; + hidl_radio_stat->V1_3.V1_0.rxTimeInMs = legacy_radio_stat.stats.rx_time; + hidl_radio_stat->V1_3.V1_0.onTimeInMsForScan = legacy_radio_stat.stats.on_time_scan; + hidl_radio_stat->V1_3.V1_0.txTimeInMsPerLevel = legacy_radio_stat.tx_time_per_levels; + hidl_radio_stat->V1_3.onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd; + hidl_radio_stat->V1_3.onTimeInMsForBgScan = legacy_radio_stat.stats.on_time_gscan; + hidl_radio_stat->V1_3.onTimeInMsForRoamScan = legacy_radio_stat.stats.on_time_roam_scan; + hidl_radio_stat->V1_3.onTimeInMsForPnoScan = legacy_radio_stat.stats.on_time_pno_scan; + hidl_radio_stat->V1_3.onTimeInMsForHs20Scan = legacy_radio_stat.stats.on_time_hs20; + + std::vector hidl_channel_stats; + + for (const auto& channel_stat : legacy_radio_stat.channel_stats) { + V1_3::WifiChannelStats hidl_channel_stat; + hidl_channel_stat.onTimeInMs = channel_stat.on_time; + hidl_channel_stat.ccaBusyTimeInMs = channel_stat.cca_busy_time; + /* + * TODO once b/119142899 is fixed, + * replace below code with convertLegacyWifiChannelInfoToHidl() + */ + hidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20; + hidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq; + hidl_channel_stat.channel.centerFreq0 = channel_stat.channel.center_freq0; + hidl_channel_stat.channel.centerFreq1 = channel_stat.channel.center_freq1; + hidl_channel_stats.push_back(hidl_channel_stat); + } + + hidl_radio_stat->V1_3.channelStats = hidl_channel_stats; + + return true; +} + +bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats, + V1_5::StaLinkLayerStats* hidl_stats) { + if (!hidl_stats) { + return false; + } + *hidl_stats = {}; + // iface legacy_stats conversion. + hidl_stats->iface.V1_0.beaconRx = legacy_stats.iface.beacon_rx; + hidl_stats->iface.V1_0.avgRssiMgmt = legacy_stats.iface.rssi_mgmt; + hidl_stats->iface.V1_0.wmeBePktStats.rxMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu; + hidl_stats->iface.V1_0.wmeBePktStats.txMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu; + hidl_stats->iface.V1_0.wmeBePktStats.lostMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost; + hidl_stats->iface.V1_0.wmeBePktStats.retries = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries; + hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMinInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min; + hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max; + hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg; + hidl_stats->iface.wmeBeContentionTimeStats.contentionNumSamples = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples; + hidl_stats->iface.V1_0.wmeBkPktStats.rxMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu; + hidl_stats->iface.V1_0.wmeBkPktStats.txMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu; + hidl_stats->iface.V1_0.wmeBkPktStats.lostMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost; + hidl_stats->iface.V1_0.wmeBkPktStats.retries = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries; + hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMinInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min; + hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max; + hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg; + hidl_stats->iface.wmeBkContentionTimeStats.contentionNumSamples = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples; + hidl_stats->iface.V1_0.wmeViPktStats.rxMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu; + hidl_stats->iface.V1_0.wmeViPktStats.txMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu; + hidl_stats->iface.V1_0.wmeViPktStats.lostMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost; + hidl_stats->iface.V1_0.wmeViPktStats.retries = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries; + hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMinInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min; + hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMaxInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max; + hidl_stats->iface.wmeViContentionTimeStats.contentionTimeAvgInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg; + hidl_stats->iface.wmeViContentionTimeStats.contentionNumSamples = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples; + hidl_stats->iface.V1_0.wmeVoPktStats.rxMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu; + hidl_stats->iface.V1_0.wmeVoPktStats.txMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu; + hidl_stats->iface.V1_0.wmeVoPktStats.lostMpdu = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost; + hidl_stats->iface.V1_0.wmeVoPktStats.retries = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries; + hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMinInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min; + hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max; + hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg; + hidl_stats->iface.wmeVoContentionTimeStats.contentionNumSamples = + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples; + hidl_stats->iface.timeSliceDutyCycleInPercent = + legacy_stats.iface.info.time_slicing_duty_cycle_percent; + // peer info legacy_stats conversion. + std::vector hidl_peers_info_stats; + for (const auto& legacy_peer_info_stats : legacy_stats.peers) { + V1_5::StaPeerInfo hidl_peer_info_stats; + if (!convertLegacyPeerInfoStatsToHidl(legacy_peer_info_stats, &hidl_peer_info_stats)) { + return false; + } + hidl_peers_info_stats.push_back(hidl_peer_info_stats); + } + hidl_stats->iface.peers = hidl_peers_info_stats; + // radio legacy_stats conversion. + std::vector hidl_radios_stats; + for (const auto& legacy_radio_stats : legacy_stats.radios) { + V1_5::StaLinkLayerRadioStats hidl_radio_stats; + if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats, &hidl_radio_stats)) { + return false; + } + hidl_radios_stats.push_back(hidl_radio_stats); + } + hidl_stats->radios = hidl_radios_stats; + // Timestamp in the HAL wrapper here since it's not provided in the legacy + // HAL API. + hidl_stats->timeStampInMs = uptimeMillis(); + return true; +} + +bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats, + V1_5::StaPeerInfo* hidl_peer_info_stats) { + if (!hidl_peer_info_stats) { + return false; + } + *hidl_peer_info_stats = {}; + hidl_peer_info_stats->staCount = legacy_peer_info_stats.peer_info.bssload.sta_count; + hidl_peer_info_stats->chanUtil = legacy_peer_info_stats.peer_info.bssload.chan_util; + + std::vector hidlRateStats; + for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) { + V1_5::StaRateStat rateStat; + if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate, &rateStat.rateInfo)) { + return false; + } + rateStat.txMpdu = legacy_rate_stats.tx_mpdu; + rateStat.rxMpdu = legacy_rate_stats.rx_mpdu; + rateStat.mpduLost = legacy_rate_stats.mpdu_lost; + rateStat.retries = legacy_rate_stats.retries; + hidlRateStats.push_back(rateStat); + } + hidl_peer_info_stats->rateStats = hidlRateStats; + return true; +} + +bool convertLegacyRoamingCapabilitiesToHidl( + const legacy_hal::wifi_roaming_capabilities& legacy_caps, + StaRoamingCapabilities* hidl_caps) { + if (!hidl_caps) { + return false; + } + *hidl_caps = {}; + hidl_caps->maxBlacklistSize = legacy_caps.max_blacklist_size; + hidl_caps->maxWhitelistSize = legacy_caps.max_whitelist_size; + return true; +} + +bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config, + legacy_hal::wifi_roaming_config* legacy_config) { + if (!legacy_config) { + return false; + } + *legacy_config = {}; + if (hidl_config.bssidBlacklist.size() > MAX_BLACKLIST_BSSID || + hidl_config.ssidWhitelist.size() > MAX_WHITELIST_SSID) { + return false; + } + legacy_config->num_blacklist_bssid = hidl_config.bssidBlacklist.size(); + uint32_t i = 0; + for (const auto& bssid : hidl_config.bssidBlacklist) { + CHECK(bssid.size() == sizeof(legacy_hal::mac_addr)); + memcpy(legacy_config->blacklist_bssid[i++], bssid.data(), bssid.size()); + } + legacy_config->num_whitelist_ssid = hidl_config.ssidWhitelist.size(); + i = 0; + for (const auto& ssid : hidl_config.ssidWhitelist) { + CHECK(ssid.size() <= sizeof(legacy_hal::ssid_t::ssid_str)); + legacy_config->whitelist_ssid[i].length = ssid.size(); + memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data(), ssid.size()); + i++; + } + return true; +} + +legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state) { + switch (state) { + case StaRoamingState::ENABLED: + return legacy_hal::ROAMING_ENABLE; + case StaRoamingState::DISABLED: + return legacy_hal::ROAMING_DISABLE; + }; + CHECK(false); +} + +legacy_hal::NanMatchAlg convertHidlNanMatchAlgToLegacy(NanMatchAlg type) { + switch (type) { + case NanMatchAlg::MATCH_ONCE: + return legacy_hal::NAN_MATCH_ALG_MATCH_ONCE; + case NanMatchAlg::MATCH_CONTINUOUS: + return legacy_hal::NAN_MATCH_ALG_MATCH_CONTINUOUS; + case NanMatchAlg::MATCH_NEVER: + return legacy_hal::NAN_MATCH_ALG_MATCH_NEVER; + } + CHECK(false); +} + +legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy(NanPublishType type) { + switch (type) { + case NanPublishType::UNSOLICITED: + return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED; + case NanPublishType::SOLICITED: + return legacy_hal::NAN_PUBLISH_TYPE_SOLICITED; + case NanPublishType::UNSOLICITED_SOLICITED: + return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED; + } + CHECK(false); +} + +legacy_hal::NanTxType convertHidlNanTxTypeToLegacy(NanTxType type) { + switch (type) { + case NanTxType::BROADCAST: + return legacy_hal::NAN_TX_TYPE_BROADCAST; + case NanTxType::UNICAST: + return legacy_hal::NAN_TX_TYPE_UNICAST; + } + CHECK(false); +} + +legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy(NanSubscribeType type) { + switch (type) { + case NanSubscribeType::PASSIVE: + return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE; + case NanSubscribeType::ACTIVE: + return legacy_hal::NAN_SUBSCRIBE_TYPE_ACTIVE; + } + CHECK(false); +} + +legacy_hal::NanSRFType convertHidlNanSrfTypeToLegacy(NanSrfType type) { + switch (type) { + case NanSrfType::BLOOM_FILTER: + return legacy_hal::NAN_SRF_ATTR_BLOOM_FILTER; + case NanSrfType::PARTIAL_MAC_ADDR: + return legacy_hal::NAN_SRF_ATTR_PARTIAL_MAC_ADDR; + } + CHECK(false); +} + +legacy_hal::NanDataPathChannelCfg convertHidlNanDataPathChannelCfgToLegacy( + NanDataPathChannelCfg type) { + switch (type) { + case NanDataPathChannelCfg::CHANNEL_NOT_REQUESTED: + return legacy_hal::NAN_DP_CHANNEL_NOT_REQUESTED; + case NanDataPathChannelCfg::REQUEST_CHANNEL_SETUP: + return legacy_hal::NAN_DP_REQUEST_CHANNEL_SETUP; + case NanDataPathChannelCfg::FORCE_CHANNEL_SETUP: + return legacy_hal::NAN_DP_FORCE_CHANNEL_SETUP; + } + CHECK(false); +} + +NanStatusType convertLegacyNanStatusTypeToHidl(legacy_hal::NanStatusType type) { + switch (type) { + case legacy_hal::NAN_STATUS_SUCCESS: + return NanStatusType::SUCCESS; + case legacy_hal::NAN_STATUS_INTERNAL_FAILURE: + return NanStatusType::INTERNAL_FAILURE; + case legacy_hal::NAN_STATUS_PROTOCOL_FAILURE: + return NanStatusType::PROTOCOL_FAILURE; + case legacy_hal::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID: + return NanStatusType::INVALID_SESSION_ID; + case legacy_hal::NAN_STATUS_NO_RESOURCE_AVAILABLE: + return NanStatusType::NO_RESOURCES_AVAILABLE; + case legacy_hal::NAN_STATUS_INVALID_PARAM: + return NanStatusType::INVALID_ARGS; + case legacy_hal::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID: + return NanStatusType::INVALID_PEER_ID; + case legacy_hal::NAN_STATUS_INVALID_NDP_ID: + return NanStatusType::INVALID_NDP_ID; + case legacy_hal::NAN_STATUS_NAN_NOT_ALLOWED: + return NanStatusType::NAN_NOT_ALLOWED; + case legacy_hal::NAN_STATUS_NO_OTA_ACK: + return NanStatusType::NO_OTA_ACK; + case legacy_hal::NAN_STATUS_ALREADY_ENABLED: + return NanStatusType::ALREADY_ENABLED; + case legacy_hal::NAN_STATUS_FOLLOWUP_QUEUE_FULL: + return NanStatusType::FOLLOWUP_TX_QUEUE_FULL; + case legacy_hal::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED: + return NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED; + } + CHECK(false); +} + +void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len, + WifiNanStatus* wifiNanStatus) { + wifiNanStatus->status = convertLegacyNanStatusTypeToHidl(type); + wifiNanStatus->description = safeConvertChar(str, max_len); +} + +bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request, + legacy_hal::NanEnableRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: null legacy_request"; + return false; + } + *legacy_request = {}; + + legacy_request->config_2dot4g_support = 1; + legacy_request->support_2dot4g_val = + hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ]; + legacy_request->config_support_5g = 1; + legacy_request->support_5g_val = + hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ]; + legacy_request->config_hop_count_limit = 1; + legacy_request->hop_count_limit_val = hidl_request.hopCountMax; + legacy_request->master_pref = hidl_request.configParams.masterPref; + legacy_request->discovery_indication_cfg = 0; + legacy_request->discovery_indication_cfg |= + hidl_request.configParams.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0; + legacy_request->discovery_indication_cfg |= + hidl_request.configParams.disableStartedClusterIndication ? 0x2 : 0x0; + legacy_request->discovery_indication_cfg |= + hidl_request.configParams.disableJoinedClusterIndication ? 0x4 : 0x0; + legacy_request->config_sid_beacon = 1; + if (hidl_request.configParams.numberOfPublishServiceIdsInBeacon > 127) { + LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: " + "numberOfPublishServiceIdsInBeacon > 127"; + return false; + } + legacy_request->sid_beacon_val = + (hidl_request.configParams.includePublishServiceIdsInBeacon ? 0x1 : 0x0) | + (hidl_request.configParams.numberOfPublishServiceIdsInBeacon << 1); + legacy_request->config_subscribe_sid_beacon = 1; + if (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon > 127) { + LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: " + "numberOfSubscribeServiceIdsInBeacon > 127"; + return false; + } + legacy_request->subscribe_sid_beacon_val = + (hidl_request.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) | + (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon << 1); + legacy_request->config_rssi_window_size = 1; + legacy_request->rssi_window_size_val = hidl_request.configParams.rssiWindowSize; + legacy_request->config_disc_mac_addr_randomization = 1; + legacy_request->disc_mac_addr_rand_interval_sec = + hidl_request.configParams.macAddressRandomizationIntervalSec; + legacy_request->config_2dot4g_rssi_close = 1; + if (hidl_request.configParams.bandSpecificConfig.size() != 3) { + LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: " + "bandSpecificConfig.size() != 3"; + return false; + } + legacy_request->rssi_close_2dot4g_val = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .rssiClose; + legacy_request->config_2dot4g_rssi_middle = 1; + legacy_request->rssi_middle_2dot4g_val = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .rssiMiddle; + legacy_request->config_2dot4g_rssi_proximity = 1; + legacy_request->rssi_proximity_2dot4g_val = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .rssiCloseProximity; + legacy_request->config_scan_params = 1; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .scanPeriodSec; + legacy_request->config_dw.config_2dot4g_dw_band = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .validDiscoveryWindowIntervalVal; + legacy_request->config_dw.dw_2dot4g_interval_val = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .discoveryWindowIntervalVal; + legacy_request->config_5g_rssi_close = 1; + legacy_request->rssi_close_5g_val = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .rssiClose; + legacy_request->config_5g_rssi_middle = 1; + legacy_request->rssi_middle_5g_val = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .rssiMiddle; + legacy_request->config_5g_rssi_close_proximity = 1; + legacy_request->rssi_close_proximity_5g_val = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .rssiCloseProximity; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .scanPeriodSec; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .scanPeriodSec; + legacy_request->config_dw.config_5g_dw_band = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .validDiscoveryWindowIntervalVal; + legacy_request->config_dw.dw_5g_interval_val = + hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .discoveryWindowIntervalVal; + if (hidl_request.debugConfigs.validClusterIdVals) { + legacy_request->cluster_low = hidl_request.debugConfigs.clusterIdBottomRangeVal; + legacy_request->cluster_high = hidl_request.debugConfigs.clusterIdTopRangeVal; + } else { // need 'else' since not configurable in legacy HAL + legacy_request->cluster_low = 0x0000; + legacy_request->cluster_high = 0xFFFF; + } + legacy_request->config_intf_addr = hidl_request.debugConfigs.validIntfAddrVal; + memcpy(legacy_request->intf_addr_val, hidl_request.debugConfigs.intfAddrVal.data(), 6); + legacy_request->config_oui = hidl_request.debugConfigs.validOuiVal; + legacy_request->oui_val = hidl_request.debugConfigs.ouiVal; + legacy_request->config_random_factor_force = + hidl_request.debugConfigs.validRandomFactorForceVal; + legacy_request->random_factor_force_val = hidl_request.debugConfigs.randomFactorForceVal; + legacy_request->config_hop_count_force = hidl_request.debugConfigs.validHopCountForceVal; + legacy_request->hop_count_force_val = hidl_request.debugConfigs.hopCountForceVal; + legacy_request->config_24g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal; + legacy_request->channel_24g_val = + hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; + legacy_request->config_5g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal; + legacy_request->channel_5g_val = + hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; + legacy_request->config_2dot4g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal; + legacy_request->beacon_2dot4g_val = + hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; + legacy_request->config_5g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal; + legacy_request->beacon_5g_val = + hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; + legacy_request->config_2dot4g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal; + legacy_request->sdf_2dot4g_val = + hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ]; + legacy_request->config_5g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal; + legacy_request->sdf_5g_val = + hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ]; + + /* TODO: b/145609058 + * Missing updates needed to legacy_hal::NanEnableRequest and conversion to + * it for 6GHz band */ + + return true; +} + +bool convertHidlNanEnableRequest_1_4ToLegacy(const V1_4::NanEnableRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanEnableRequest_1_4ToLegacy: null legacy_request"; + return false; + } + + *legacy_request = {}; + if (!convertHidlNanEnableRequestToLegacy(hidl_request1, legacy_request)) { + return false; + } + + legacy_request->config_discovery_beacon_int = 1; + legacy_request->discovery_beacon_interval = hidl_request2.V1_2.discoveryBeaconIntervalMs; + legacy_request->config_nss = 1; + legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; + legacy_request->config_dw_early_termination = 1; + legacy_request->enable_dw_termination = + hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; + legacy_request->config_enable_ranging = 1; + legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging; + + return true; +} + +bool convertHidlNanEnableRequest_1_5ToLegacy(const V1_4::NanEnableRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanEnableRequest_1_5ToLegacy: null legacy_request"; + return false; + } + + *legacy_request = {}; + if (!convertHidlNanEnableRequest_1_4ToLegacy(hidl_request1, hidl_request2, legacy_request)) { + return false; + } + + legacy_request->config_enable_instant_mode = 1; + legacy_request->enable_instant_mode = hidl_request2.enableInstantCommunicationMode; + + return true; +} + +bool convertHidlNanConfigRequest_1_5ToLegacy(const V1_4::NanConfigRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanConfigRequest_1_5ToLegacy: null legacy_request"; + return false; + } + + *legacy_request = {}; + if (!convertHidlNanConfigRequest_1_4ToLegacy(hidl_request1, hidl_request2, legacy_request)) { + return false; + } + + legacy_request->config_enable_instant_mode = 1; + legacy_request->enable_instant_mode = hidl_request2.enableInstantCommunicationMode; + + return true; +} + +bool convertHidlNanPublishRequestToLegacy(const NanPublishRequest& hidl_request, + legacy_hal::NanPublishRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: null legacy_request"; + return false; + } + *legacy_request = {}; + + legacy_request->publish_id = hidl_request.baseConfigs.sessionId; + legacy_request->ttl = hidl_request.baseConfigs.ttlSec; + legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod; + legacy_request->publish_count = hidl_request.baseConfigs.discoveryCount; + legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size(); + if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: service_name_len " + "too large"; + return false; + } + memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(), + legacy_request->service_name_len); + legacy_request->publish_match_indicator = + convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator); + legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size(); + if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " + "service_specific_info_len too large"; + return false; + } + memcpy(legacy_request->service_specific_info, + hidl_request.baseConfigs.serviceSpecificInfo.data(), + legacy_request->service_specific_info_len); + legacy_request->sdea_service_specific_info_len = + hidl_request.baseConfigs.extendedServiceSpecificInfo.size(); + if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " + "sdea_service_specific_info_len too large"; + return false; + } + memcpy(legacy_request->sdea_service_specific_info, + hidl_request.baseConfigs.extendedServiceSpecificInfo.data(), + legacy_request->sdea_service_specific_info_len); + legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size(); + if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " + "rx_match_filter_len too large"; + return false; + } + memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(), + legacy_request->rx_match_filter_len); + legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size(); + if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " + "tx_match_filter_len too large"; + return false; + } + memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(), + legacy_request->tx_match_filter_len); + legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold; + legacy_request->recv_indication_cfg = 0; + legacy_request->recv_indication_cfg |= + hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0; + legacy_request->recv_indication_cfg |= + hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0; + legacy_request->recv_indication_cfg |= + hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0; + legacy_request->recv_indication_cfg |= 0x8; + legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType; + if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; + legacy_request->key_info.body.pmk_info.pmk_len = + hidl_request.baseConfigs.securityConfig.pmk.size(); + if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: invalid pmk_len"; + return false; + } + memcpy(legacy_request->key_info.body.pmk_info.pmk, + hidl_request.baseConfigs.securityConfig.pmk.data(), + legacy_request->key_info.body.pmk_info.pmk_len); + } + if (hidl_request.baseConfigs.securityConfig.securityType == + NanDataPathSecurityType::PASSPHRASE) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; + legacy_request->key_info.body.passphrase_info.passphrase_len = + hidl_request.baseConfigs.securityConfig.passphrase.size(); + if (legacy_request->key_info.body.passphrase_info.passphrase_len < + NAN_SECURITY_MIN_PASSPHRASE_LEN) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " + "passphrase_len too small"; + return false; + } + if (legacy_request->key_info.body.passphrase_info.passphrase_len > + NAN_SECURITY_MAX_PASSPHRASE_LEN) { + LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: " + "passphrase_len too large"; + return false; + } + memcpy(legacy_request->key_info.body.passphrase_info.passphrase, + hidl_request.baseConfigs.securityConfig.passphrase.data(), + legacy_request->key_info.body.passphrase_info.passphrase_len); + } + legacy_request->sdea_params.security_cfg = + (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN) + ? legacy_hal::NAN_DP_CONFIG_SECURITY + : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; + legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired + ? legacy_hal::NAN_RANGING_ENABLE + : legacy_hal::NAN_RANGING_DISABLE; + legacy_request->ranging_cfg.ranging_interval_msec = + hidl_request.baseConfigs.rangingIntervalMsec; + legacy_request->ranging_cfg.config_ranging_indications = + hidl_request.baseConfigs.configRangingIndications; + legacy_request->ranging_cfg.distance_ingress_mm = + hidl_request.baseConfigs.distanceIngressCm * 10; + legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10; + legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired + ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE + : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE; + legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT; + legacy_request->publish_type = convertHidlNanPublishTypeToLegacy(hidl_request.publishType); + legacy_request->tx_type = convertHidlNanTxTypeToLegacy(hidl_request.txType); + legacy_request->service_responder_policy = hidl_request.autoAcceptDataPathRequests + ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL + : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE; + + return true; +} + +bool convertHidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& hidl_request, + legacy_hal::NanSubscribeRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: legacy_request is null"; + return false; + } + *legacy_request = {}; + + legacy_request->subscribe_id = hidl_request.baseConfigs.sessionId; + legacy_request->ttl = hidl_request.baseConfigs.ttlSec; + legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod; + legacy_request->subscribe_count = hidl_request.baseConfigs.discoveryCount; + legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size(); + if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " + "service_name_len too large"; + return false; + } + memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(), + legacy_request->service_name_len); + legacy_request->subscribe_match_indicator = + convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator); + legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size(); + if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " + "service_specific_info_len too large"; + return false; + } + memcpy(legacy_request->service_specific_info, + hidl_request.baseConfigs.serviceSpecificInfo.data(), + legacy_request->service_specific_info_len); + legacy_request->sdea_service_specific_info_len = + hidl_request.baseConfigs.extendedServiceSpecificInfo.size(); + if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " + "sdea_service_specific_info_len too large"; + return false; + } + memcpy(legacy_request->sdea_service_specific_info, + hidl_request.baseConfigs.extendedServiceSpecificInfo.data(), + legacy_request->sdea_service_specific_info_len); + legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size(); + if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " + "rx_match_filter_len too large"; + return false; + } + memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(), + legacy_request->rx_match_filter_len); + legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size(); + if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " + "tx_match_filter_len too large"; + return false; + } + memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(), + legacy_request->tx_match_filter_len); + legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold; + legacy_request->recv_indication_cfg = 0; + legacy_request->recv_indication_cfg |= + hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0; + legacy_request->recv_indication_cfg |= + hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0; + legacy_request->recv_indication_cfg |= + hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0; + legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType; + if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; + legacy_request->key_info.body.pmk_info.pmk_len = + hidl_request.baseConfigs.securityConfig.pmk.size(); + if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: invalid pmk_len"; + return false; + } + memcpy(legacy_request->key_info.body.pmk_info.pmk, + hidl_request.baseConfigs.securityConfig.pmk.data(), + legacy_request->key_info.body.pmk_info.pmk_len); + } + if (hidl_request.baseConfigs.securityConfig.securityType == + NanDataPathSecurityType::PASSPHRASE) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; + legacy_request->key_info.body.passphrase_info.passphrase_len = + hidl_request.baseConfigs.securityConfig.passphrase.size(); + if (legacy_request->key_info.body.passphrase_info.passphrase_len < + NAN_SECURITY_MIN_PASSPHRASE_LEN) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " + "passphrase_len too small"; + return false; + } + if (legacy_request->key_info.body.passphrase_info.passphrase_len > + NAN_SECURITY_MAX_PASSPHRASE_LEN) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " + "passphrase_len too large"; + return false; + } + memcpy(legacy_request->key_info.body.passphrase_info.passphrase, + hidl_request.baseConfigs.securityConfig.passphrase.data(), + legacy_request->key_info.body.passphrase_info.passphrase_len); + } + legacy_request->sdea_params.security_cfg = + (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN) + ? legacy_hal::NAN_DP_CONFIG_SECURITY + : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; + legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired + ? legacy_hal::NAN_RANGING_ENABLE + : legacy_hal::NAN_RANGING_DISABLE; + legacy_request->ranging_cfg.ranging_interval_msec = + hidl_request.baseConfigs.rangingIntervalMsec; + legacy_request->ranging_cfg.config_ranging_indications = + hidl_request.baseConfigs.configRangingIndications; + legacy_request->ranging_cfg.distance_ingress_mm = + hidl_request.baseConfigs.distanceIngressCm * 10; + legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10; + legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired + ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE + : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE; + legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT; + legacy_request->subscribe_type = + convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType); + legacy_request->serviceResponseFilter = convertHidlNanSrfTypeToLegacy(hidl_request.srfType); + legacy_request->serviceResponseInclude = hidl_request.srfRespondIfInAddressSet + ? legacy_hal::NAN_SRF_INCLUDE_RESPOND + : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND; + legacy_request->useServiceResponseFilter = + hidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF : legacy_hal::NAN_DO_NOT_USE_SRF; + legacy_request->ssiRequiredForMatchIndication = + hidl_request.isSsiRequiredForMatch ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND + : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND; + legacy_request->num_intf_addr_present = hidl_request.intfAddr.size(); + if (legacy_request->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) { + LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: " + "num_intf_addr_present - too many"; + return false; + } + for (int i = 0; i < legacy_request->num_intf_addr_present; i++) { + memcpy(legacy_request->intf_addr[i], hidl_request.intfAddr[i].data(), 6); + } + + return true; +} + +bool convertHidlNanTransmitFollowupRequestToLegacy( + const NanTransmitFollowupRequest& hidl_request, + legacy_hal::NanTransmitFollowupRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: " + "legacy_request is null"; + return false; + } + *legacy_request = {}; + + legacy_request->publish_subscribe_id = hidl_request.discoverySessionId; + legacy_request->requestor_instance_id = hidl_request.peerId; + memcpy(legacy_request->addr, hidl_request.addr.data(), 6); + legacy_request->priority = hidl_request.isHighPriority ? legacy_hal::NAN_TX_PRIORITY_HIGH + : legacy_hal::NAN_TX_PRIORITY_NORMAL; + legacy_request->dw_or_faw = hidl_request.shouldUseDiscoveryWindow + ? legacy_hal::NAN_TRANSMIT_IN_DW + : legacy_hal::NAN_TRANSMIT_IN_FAW; + legacy_request->service_specific_info_len = hidl_request.serviceSpecificInfo.size(); + if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { + LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: " + "service_specific_info_len too large"; + return false; + } + memcpy(legacy_request->service_specific_info, hidl_request.serviceSpecificInfo.data(), + legacy_request->service_specific_info_len); + legacy_request->sdea_service_specific_info_len = + hidl_request.extendedServiceSpecificInfo.size(); + if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { + LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: " + "sdea_service_specific_info_len too large"; + return false; + } + memcpy(legacy_request->sdea_service_specific_info, + hidl_request.extendedServiceSpecificInfo.data(), + legacy_request->sdea_service_specific_info_len); + legacy_request->recv_indication_cfg = hidl_request.disableFollowupResultIndication ? 0x1 : 0x0; + + return true; +} + +bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request, + legacy_hal::NanConfigRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: legacy_request is null"; + return false; + } + *legacy_request = {}; + + // TODO: b/34059183 tracks missing configurations in legacy HAL or uknown + // defaults + legacy_request->master_pref = hidl_request.masterPref; + legacy_request->discovery_indication_cfg = 0; + legacy_request->discovery_indication_cfg |= + hidl_request.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0; + legacy_request->discovery_indication_cfg |= + hidl_request.disableStartedClusterIndication ? 0x2 : 0x0; + legacy_request->discovery_indication_cfg |= + hidl_request.disableJoinedClusterIndication ? 0x4 : 0x0; + legacy_request->config_sid_beacon = 1; + if (hidl_request.numberOfPublishServiceIdsInBeacon > 127) { + LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: " + "numberOfPublishServiceIdsInBeacon > 127"; + return false; + } + legacy_request->sid_beacon = (hidl_request.includePublishServiceIdsInBeacon ? 0x1 : 0x0) | + (hidl_request.numberOfPublishServiceIdsInBeacon << 1); + legacy_request->config_subscribe_sid_beacon = 1; + if (hidl_request.numberOfSubscribeServiceIdsInBeacon > 127) { + LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: " + "numberOfSubscribeServiceIdsInBeacon > 127"; + return false; + } + legacy_request->subscribe_sid_beacon_val = + (hidl_request.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) | + (hidl_request.numberOfSubscribeServiceIdsInBeacon << 1); + legacy_request->config_rssi_window_size = 1; + legacy_request->rssi_window_size_val = hidl_request.rssiWindowSize; + legacy_request->config_disc_mac_addr_randomization = 1; + legacy_request->disc_mac_addr_rand_interval_sec = + hidl_request.macAddressRandomizationIntervalSec; + /* TODO : missing + legacy_request->config_2dot4g_rssi_close = 1; + legacy_request->rssi_close_2dot4g_val = + hidl_request.bandSpecificConfig[ + (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiClose; + legacy_request->config_2dot4g_rssi_middle = 1; + legacy_request->rssi_middle_2dot4g_val = + hidl_request.bandSpecificConfig[ + (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiMiddle; + legacy_request->config_2dot4g_rssi_proximity = 1; + legacy_request->rssi_proximity_2dot4g_val = + hidl_request.bandSpecificConfig[ + (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiCloseProximity; + */ + legacy_request->config_scan_params = 1; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].scanPeriodSec; + legacy_request->config_dw.config_2dot4g_dw_band = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .validDiscoveryWindowIntervalVal; + legacy_request->config_dw.dw_2dot4g_interval_val = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ] + .discoveryWindowIntervalVal; + /* TODO: missing + legacy_request->config_5g_rssi_close = 1; + legacy_request->rssi_close_5g_val = + hidl_request.bandSpecificConfig[ + (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiClose; + legacy_request->config_5g_rssi_middle = 1; + legacy_request->rssi_middle_5g_val = + hidl_request.bandSpecificConfig[ + (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiMiddle; + */ + legacy_request->config_5g_rssi_close_proximity = 1; + legacy_request->rssi_close_proximity_5g_val = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].rssiCloseProximity; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec; + legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs; + legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec; + legacy_request->config_dw.config_5g_dw_band = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .validDiscoveryWindowIntervalVal; + legacy_request->config_dw.dw_5g_interval_val = + hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ] + .discoveryWindowIntervalVal; + /* TODO: b/145609058 + * Missing updates needed to legacy_hal::NanConfigRequest and conversion to + * it for 6GHz band */ + + return true; +} + +bool convertHidlNanConfigRequest_1_4ToLegacy(const V1_4::NanConfigRequest& hidl_request1, + const NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanConfigRequest_1_4ToLegacy: legacy_request " + "is null"; + return false; + } + + *legacy_request = {}; + if (!convertHidlNanConfigRequestToLegacy(hidl_request1, legacy_request)) { + return false; + } + + legacy_request->config_discovery_beacon_int = 1; + legacy_request->discovery_beacon_interval = hidl_request2.V1_2.discoveryBeaconIntervalMs; + legacy_request->config_nss = 1; + legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; + legacy_request->config_dw_early_termination = 1; + legacy_request->enable_dw_termination = + hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; + legacy_request->config_enable_ranging = 1; + legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging; + + return true; +} + +bool convertHidlNanDataPathInitiatorRequestToLegacy( + const NanInitiateDataPathRequest& hidl_request, + legacy_hal::NanDataPathInitiatorRequest* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " + "legacy_request is null"; + return false; + } + *legacy_request = {}; + + legacy_request->requestor_instance_id = hidl_request.peerId; + memcpy(legacy_request->peer_disc_mac_addr, hidl_request.peerDiscMacAddr.data(), 6); + legacy_request->channel_request_type = + convertHidlNanDataPathChannelCfgToLegacy(hidl_request.channelRequestType); + legacy_request->channel = hidl_request.channel; + if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) { + LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " + "ifaceName too long"; + return false; + } + strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1); + legacy_request->ndp_cfg.security_cfg = + (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN) + ? legacy_hal::NAN_DP_CONFIG_SECURITY + : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; + legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size(); + if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) { + LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " + "ndp_app_info_len too large"; + return false; + } + memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(), + legacy_request->app_info.ndp_app_info_len); + legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType; + if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; + legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size(); + if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { + LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " + "invalid pmk_len"; + return false; + } + memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(), + legacy_request->key_info.body.pmk_info.pmk_len); + } + if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; + legacy_request->key_info.body.passphrase_info.passphrase_len = + hidl_request.securityConfig.passphrase.size(); + if (legacy_request->key_info.body.passphrase_info.passphrase_len < + NAN_SECURITY_MIN_PASSPHRASE_LEN) { + LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " + "passphrase_len too small"; + return false; + } + if (legacy_request->key_info.body.passphrase_info.passphrase_len > + NAN_SECURITY_MAX_PASSPHRASE_LEN) { + LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " + "passphrase_len too large"; + return false; + } + memcpy(legacy_request->key_info.body.passphrase_info.passphrase, + hidl_request.securityConfig.passphrase.data(), + legacy_request->key_info.body.passphrase_info.passphrase_len); + } + legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size(); + if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { + LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: " + "service_name_len too large"; + return false; + } + memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(), + legacy_request->service_name_len); + + return true; +} + +bool convertHidlNanDataPathIndicationResponseToLegacy( + const NanRespondToDataPathIndicationRequest& hidl_request, + legacy_hal::NanDataPathIndicationResponse* legacy_request) { + if (!legacy_request) { + LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " + "legacy_request is null"; + return false; + } + *legacy_request = {}; + + legacy_request->rsp_code = hidl_request.acceptRequest ? legacy_hal::NAN_DP_REQUEST_ACCEPT + : legacy_hal::NAN_DP_REQUEST_REJECT; + legacy_request->ndp_instance_id = hidl_request.ndpInstanceId; + if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) { + LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " + "ifaceName too long"; + return false; + } + strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1); + legacy_request->ndp_cfg.security_cfg = + (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN) + ? legacy_hal::NAN_DP_CONFIG_SECURITY + : legacy_hal::NAN_DP_CONFIG_NO_SECURITY; + legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size(); + if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) { + LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " + "ndp_app_info_len too large"; + return false; + } + memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(), + legacy_request->app_info.ndp_app_info_len); + legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType; + if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK; + legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size(); + if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { + LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " + "invalid pmk_len"; + return false; + } + memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(), + legacy_request->key_info.body.pmk_info.pmk_len); + } + if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) { + legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE; + legacy_request->key_info.body.passphrase_info.passphrase_len = + hidl_request.securityConfig.passphrase.size(); + if (legacy_request->key_info.body.passphrase_info.passphrase_len < + NAN_SECURITY_MIN_PASSPHRASE_LEN) { + LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " + "passphrase_len too small"; + return false; + } + if (legacy_request->key_info.body.passphrase_info.passphrase_len > + NAN_SECURITY_MAX_PASSPHRASE_LEN) { + LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " + "passphrase_len too large"; + return false; + } + memcpy(legacy_request->key_info.body.passphrase_info.passphrase, + hidl_request.securityConfig.passphrase.data(), + legacy_request->key_info.body.passphrase_info.passphrase_len); + } + legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size(); + if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) { + LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: " + "service_name_len too large"; + return false; + } + memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(), + legacy_request->service_name_len); + + return true; +} + +bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response, + WifiNanStatus* wifiNanStatus) { + if (!wifiNanStatus) { + LOG(ERROR) << "convertLegacyNanResponseHeaderToHidl: wifiNanStatus is null"; + return false; + } + *wifiNanStatus = {}; + + convertToWifiNanStatus(legacy_response.status, legacy_response.nan_error, + sizeof(legacy_response.nan_error), wifiNanStatus); + return true; +} + +bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response, + V1_5::NanCapabilities* hidl_response) { + if (!hidl_response) { + LOG(ERROR) << "convertLegacyNanCapabilitiesResponseToHidl: " + "hidl_response is null"; + return false; + } + *hidl_response = {}; + + hidl_response->V1_0.maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters; + hidl_response->V1_0.maxPublishes = legacy_response.max_publishes; + hidl_response->V1_0.maxSubscribes = legacy_response.max_subscribes; + hidl_response->V1_0.maxServiceNameLen = legacy_response.max_service_name_len; + hidl_response->V1_0.maxMatchFilterLen = legacy_response.max_match_filter_len; + hidl_response->V1_0.maxTotalMatchFilterLen = legacy_response.max_total_match_filter_len; + hidl_response->V1_0.maxServiceSpecificInfoLen = legacy_response.max_service_specific_info_len; + hidl_response->V1_0.maxExtendedServiceSpecificInfoLen = + legacy_response.max_sdea_service_specific_info_len; + hidl_response->V1_0.maxNdiInterfaces = legacy_response.max_ndi_interfaces; + hidl_response->V1_0.maxNdpSessions = legacy_response.max_ndp_sessions; + hidl_response->V1_0.maxAppInfoLen = legacy_response.max_app_info_len; + hidl_response->V1_0.maxQueuedTransmitFollowupMsgs = + legacy_response.max_queued_transmit_followup_msgs; + hidl_response->V1_0.maxSubscribeInterfaceAddresses = legacy_response.max_subscribe_address; + hidl_response->V1_0.supportedCipherSuites = legacy_response.cipher_suites_supported; + hidl_response->instantCommunicationModeSupportFlag = legacy_response.is_instant_mode_supported; + + return true; +} + +bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind, + NanMatchInd* hidl_ind) { + if (!hidl_ind) { + LOG(ERROR) << "convertLegacyNanMatchIndToHidl: hidl_ind is null"; + return false; + } + *hidl_ind = {}; + + hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id; + hidl_ind->peerId = legacy_ind.requestor_instance_id; + hidl_ind->addr = hidl_array(legacy_ind.addr); + hidl_ind->serviceSpecificInfo = std::vector( + legacy_ind.service_specific_info, + legacy_ind.service_specific_info + legacy_ind.service_specific_info_len); + hidl_ind->extendedServiceSpecificInfo = std::vector( + legacy_ind.sdea_service_specific_info, + legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len); + hidl_ind->matchFilter = + std::vector(legacy_ind.sdf_match_filter, + legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len); + hidl_ind->matchOccuredInBeaconFlag = legacy_ind.match_occured_flag == 1; + hidl_ind->outOfResourceFlag = legacy_ind.out_of_resource_flag == 1; + hidl_ind->rssiValue = legacy_ind.rssi_value; + hidl_ind->peerCipherType = (NanCipherSuiteType)legacy_ind.peer_cipher_type; + hidl_ind->peerRequiresSecurityEnabledInNdp = + legacy_ind.peer_sdea_params.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY; + hidl_ind->peerRequiresRanging = + legacy_ind.peer_sdea_params.ranging_state == legacy_hal::NAN_RANGING_ENABLE; + hidl_ind->rangingMeasurementInCm = legacy_ind.range_info.range_measurement_mm / 10; + hidl_ind->rangingIndicationType = legacy_ind.range_info.ranging_event_type; + + return true; +} + +bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind, + NanFollowupReceivedInd* hidl_ind) { + if (!hidl_ind) { + LOG(ERROR) << "convertLegacyNanFollowupIndToHidl: hidl_ind is null"; + return false; + } + *hidl_ind = {}; + + hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id; + hidl_ind->peerId = legacy_ind.requestor_instance_id; + hidl_ind->addr = hidl_array(legacy_ind.addr); + hidl_ind->receivedInFaw = legacy_ind.dw_or_faw == 1; + hidl_ind->serviceSpecificInfo = std::vector( + legacy_ind.service_specific_info, + legacy_ind.service_specific_info + legacy_ind.service_specific_info_len); + hidl_ind->extendedServiceSpecificInfo = std::vector( + legacy_ind.sdea_service_specific_info, + legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len); + + return true; +} + +bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind, + NanDataPathRequestInd* hidl_ind) { + if (!hidl_ind) { + LOG(ERROR) << "convertLegacyNanDataPathRequestIndToHidl: hidl_ind is null"; + return false; + } + *hidl_ind = {}; + + hidl_ind->discoverySessionId = legacy_ind.service_instance_id; + hidl_ind->peerDiscMacAddr = hidl_array(legacy_ind.peer_disc_mac_addr); + hidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id; + hidl_ind->securityRequired = + legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY; + hidl_ind->appInfo = std::vector( + legacy_ind.app_info.ndp_app_info, + legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len); + + return true; +} + +bool convertLegacyNdpChannelInfoToHidl(const legacy_hal::NanChannelInfo& legacy_struct, + V1_2::NanDataPathChannelInfo* hidl_struct) { + if (!hidl_struct) { + LOG(ERROR) << "convertLegacyNdpChannelInfoToHidl: hidl_struct is null"; + return false; + } + *hidl_struct = {}; + + hidl_struct->channelFreq = legacy_struct.channel; + hidl_struct->channelBandwidth = convertLegacyWifiChannelWidthToHidl( + (legacy_hal::wifi_channel_width)legacy_struct.bandwidth); + hidl_struct->numSpatialStreams = legacy_struct.nss; + + return true; +} + +bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind, + V1_2::NanDataPathConfirmInd* hidl_ind) { + if (!hidl_ind) { + LOG(ERROR) << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null"; + return false; + } + *hidl_ind = {}; + + hidl_ind->V1_0.ndpInstanceId = legacy_ind.ndp_instance_id; + hidl_ind->V1_0.dataPathSetupSuccess = legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT; + hidl_ind->V1_0.peerNdiMacAddr = hidl_array(legacy_ind.peer_ndi_mac_addr); + hidl_ind->V1_0.appInfo = std::vector( + legacy_ind.app_info.ndp_app_info, + legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len); + hidl_ind->V1_0.status.status = convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code); + hidl_ind->V1_0.status.description = ""; // TODO: b/34059183 + + std::vector channelInfo; + for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { + V1_2::NanDataPathChannelInfo hidl_struct; + if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) { + return false; + } + channelInfo.push_back(hidl_struct); + } + hidl_ind->channelInfo = channelInfo; + + return true; +} + +bool convertLegacyNanDataPathScheduleUpdateIndToHidl( + const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, + V1_2::NanDataPathScheduleUpdateInd* hidl_ind) { + if (!hidl_ind) { + LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToHidl: " + "hidl_ind is null"; + return false; + } + *hidl_ind = {}; + + hidl_ind->peerDiscoveryAddress = hidl_array(legacy_ind.peer_mac_addr); + std::vector channelInfo; + for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) { + V1_2::NanDataPathChannelInfo hidl_struct; + if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) { + return false; + } + channelInfo.push_back(hidl_struct); + } + hidl_ind->channelInfo = channelInfo; + std::vector ndpInstanceIds; + for (unsigned int i = 0; i < legacy_ind.num_ndp_instances; ++i) { + ndpInstanceIds.push_back(legacy_ind.ndp_instance_id[i]); + } + hidl_ind->ndpInstanceIds = ndpInstanceIds; + + return true; +} + +legacy_hal::wifi_rtt_type convertHidlRttTypeToLegacy(RttType type) { + switch (type) { + case RttType::ONE_SIDED: + return legacy_hal::RTT_TYPE_1_SIDED; + case RttType::TWO_SIDED: + return legacy_hal::RTT_TYPE_2_SIDED; + }; + CHECK(false); +} + +RttType convertLegacyRttTypeToHidl(legacy_hal::wifi_rtt_type type) { + switch (type) { + case legacy_hal::RTT_TYPE_1_SIDED: + return RttType::ONE_SIDED; + case legacy_hal::RTT_TYPE_2_SIDED: + return RttType::TWO_SIDED; + }; + CHECK(false) << "Unknown legacy type: " << type; +} + +legacy_hal::rtt_peer_type convertHidlRttPeerTypeToLegacy(RttPeerType type) { + switch (type) { + case RttPeerType::AP: + return legacy_hal::RTT_PEER_AP; + case RttPeerType::STA: + return legacy_hal::RTT_PEER_STA; + case RttPeerType::P2P_GO: + return legacy_hal::RTT_PEER_P2P_GO; + case RttPeerType::P2P_CLIENT: + return legacy_hal::RTT_PEER_P2P_CLIENT; + case RttPeerType::NAN: + return legacy_hal::RTT_PEER_NAN; + }; + CHECK(false); +} + +legacy_hal::wifi_channel_width convertHidlWifiChannelWidthToLegacy(WifiChannelWidthInMhz type) { + switch (type) { + case WifiChannelWidthInMhz::WIDTH_20: + return legacy_hal::WIFI_CHAN_WIDTH_20; + case WifiChannelWidthInMhz::WIDTH_40: + return legacy_hal::WIFI_CHAN_WIDTH_40; + case WifiChannelWidthInMhz::WIDTH_80: + return legacy_hal::WIFI_CHAN_WIDTH_80; + case WifiChannelWidthInMhz::WIDTH_160: + return legacy_hal::WIFI_CHAN_WIDTH_160; + case WifiChannelWidthInMhz::WIDTH_80P80: + return legacy_hal::WIFI_CHAN_WIDTH_80P80; + case WifiChannelWidthInMhz::WIDTH_5: + return legacy_hal::WIFI_CHAN_WIDTH_5; + case WifiChannelWidthInMhz::WIDTH_10: + return legacy_hal::WIFI_CHAN_WIDTH_10; + case WifiChannelWidthInMhz::WIDTH_INVALID: + return legacy_hal::WIFI_CHAN_WIDTH_INVALID; + }; + CHECK(false); +} + +WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(legacy_hal::wifi_channel_width type) { + switch (type) { + case legacy_hal::WIFI_CHAN_WIDTH_20: + return WifiChannelWidthInMhz::WIDTH_20; + case legacy_hal::WIFI_CHAN_WIDTH_40: + return WifiChannelWidthInMhz::WIDTH_40; + case legacy_hal::WIFI_CHAN_WIDTH_80: + return WifiChannelWidthInMhz::WIDTH_80; + case legacy_hal::WIFI_CHAN_WIDTH_160: + return WifiChannelWidthInMhz::WIDTH_160; + case legacy_hal::WIFI_CHAN_WIDTH_80P80: + return WifiChannelWidthInMhz::WIDTH_80P80; + case legacy_hal::WIFI_CHAN_WIDTH_5: + return WifiChannelWidthInMhz::WIDTH_5; + case legacy_hal::WIFI_CHAN_WIDTH_10: + return WifiChannelWidthInMhz::WIDTH_10; + default: + return WifiChannelWidthInMhz::WIDTH_INVALID; + }; +} + +legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy(V1_4::RttPreamble type) { + switch (type) { + case V1_4::RttPreamble::LEGACY: + return legacy_hal::WIFI_RTT_PREAMBLE_LEGACY; + case V1_4::RttPreamble::HT: + return legacy_hal::WIFI_RTT_PREAMBLE_HT; + case V1_4::RttPreamble::VHT: + return legacy_hal::WIFI_RTT_PREAMBLE_VHT; + case V1_4::RttPreamble::HE: + return legacy_hal::WIFI_RTT_PREAMBLE_HE; + }; + CHECK(false); +} + +V1_4::RttPreamble convertLegacyRttPreambleToHidl(legacy_hal::wifi_rtt_preamble type) { + switch (type) { + case legacy_hal::WIFI_RTT_PREAMBLE_LEGACY: + return V1_4::RttPreamble::LEGACY; + case legacy_hal::WIFI_RTT_PREAMBLE_HT: + return V1_4::RttPreamble::HT; + case legacy_hal::WIFI_RTT_PREAMBLE_VHT: + return V1_4::RttPreamble::VHT; + case legacy_hal::WIFI_RTT_PREAMBLE_HE: + return V1_4::RttPreamble::HE; + }; + CHECK(false) << "Unknown legacy type: " << type; +} + +legacy_hal::wifi_rtt_bw convertHidlRttBwToLegacy(RttBw type) { + switch (type) { + case RttBw::BW_5MHZ: + return legacy_hal::WIFI_RTT_BW_5; + case RttBw::BW_10MHZ: + return legacy_hal::WIFI_RTT_BW_10; + case RttBw::BW_20MHZ: + return legacy_hal::WIFI_RTT_BW_20; + case RttBw::BW_40MHZ: + return legacy_hal::WIFI_RTT_BW_40; + case RttBw::BW_80MHZ: + return legacy_hal::WIFI_RTT_BW_80; + case RttBw::BW_160MHZ: + return legacy_hal::WIFI_RTT_BW_160; + }; + CHECK(false); +} + +RttBw convertLegacyRttBwToHidl(legacy_hal::wifi_rtt_bw type) { + switch (type) { + case legacy_hal::WIFI_RTT_BW_5: + return RttBw::BW_5MHZ; + case legacy_hal::WIFI_RTT_BW_10: + return RttBw::BW_10MHZ; + case legacy_hal::WIFI_RTT_BW_20: + return RttBw::BW_20MHZ; + case legacy_hal::WIFI_RTT_BW_40: + return RttBw::BW_40MHZ; + case legacy_hal::WIFI_RTT_BW_80: + return RttBw::BW_80MHZ; + case legacy_hal::WIFI_RTT_BW_160: + return RttBw::BW_160MHZ; + }; + CHECK(false) << "Unknown legacy type: " << type; +} + +legacy_hal::wifi_motion_pattern convertHidlRttMotionPatternToLegacy(RttMotionPattern type) { + switch (type) { + case RttMotionPattern::NOT_EXPECTED: + return legacy_hal::WIFI_MOTION_NOT_EXPECTED; + case RttMotionPattern::EXPECTED: + return legacy_hal::WIFI_MOTION_EXPECTED; + case RttMotionPattern::UNKNOWN: + return legacy_hal::WIFI_MOTION_UNKNOWN; + }; + CHECK(false); +} + +V1_4::WifiRatePreamble convertLegacyWifiRatePreambleToHidl(uint8_t preamble) { + switch (preamble) { + case 0: + return V1_4::WifiRatePreamble::OFDM; + case 1: + return V1_4::WifiRatePreamble::CCK; + case 2: + return V1_4::WifiRatePreamble::HT; + case 3: + return V1_4::WifiRatePreamble::VHT; + case 4: + return V1_4::WifiRatePreamble::HE; + default: + return V1_4::WifiRatePreamble::RESERVED; + }; + CHECK(false) << "Unknown legacy preamble: " << preamble; +} + +WifiRateNss convertLegacyWifiRateNssToHidl(uint8_t nss) { + switch (nss) { + case 0: + return WifiRateNss::NSS_1x1; + case 1: + return WifiRateNss::NSS_2x2; + case 2: + return WifiRateNss::NSS_3x3; + case 3: + return WifiRateNss::NSS_4x4; + }; + CHECK(false) << "Unknown legacy nss: " << nss; + return {}; +} + +RttStatus convertLegacyRttStatusToHidl(legacy_hal::wifi_rtt_status status) { + switch (status) { + case legacy_hal::RTT_STATUS_SUCCESS: + return RttStatus::SUCCESS; + case legacy_hal::RTT_STATUS_FAILURE: + return RttStatus::FAILURE; + case legacy_hal::RTT_STATUS_FAIL_NO_RSP: + return RttStatus::FAIL_NO_RSP; + case legacy_hal::RTT_STATUS_FAIL_REJECTED: + return RttStatus::FAIL_REJECTED; + case legacy_hal::RTT_STATUS_FAIL_NOT_SCHEDULED_YET: + return RttStatus::FAIL_NOT_SCHEDULED_YET; + case legacy_hal::RTT_STATUS_FAIL_TM_TIMEOUT: + return RttStatus::FAIL_TM_TIMEOUT; + case legacy_hal::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL: + return RttStatus::FAIL_AP_ON_DIFF_CHANNEL; + case legacy_hal::RTT_STATUS_FAIL_NO_CAPABILITY: + return RttStatus::FAIL_NO_CAPABILITY; + case legacy_hal::RTT_STATUS_ABORTED: + return RttStatus::ABORTED; + case legacy_hal::RTT_STATUS_FAIL_INVALID_TS: + return RttStatus::FAIL_INVALID_TS; + case legacy_hal::RTT_STATUS_FAIL_PROTOCOL: + return RttStatus::FAIL_PROTOCOL; + case legacy_hal::RTT_STATUS_FAIL_SCHEDULE: + return RttStatus::FAIL_SCHEDULE; + case legacy_hal::RTT_STATUS_FAIL_BUSY_TRY_LATER: + return RttStatus::FAIL_BUSY_TRY_LATER; + case legacy_hal::RTT_STATUS_INVALID_REQ: + return RttStatus::INVALID_REQ; + case legacy_hal::RTT_STATUS_NO_WIFI: + return RttStatus::NO_WIFI; + case legacy_hal::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE: + return RttStatus::FAIL_FTM_PARAM_OVERRIDE; + case legacy_hal::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE: + return RttStatus::FAILURE; // TODO: add HIDL enumeration + case legacy_hal::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED: + return RttStatus::FAILURE; // TODO: add HIDL enumeration + }; + CHECK(false) << "Unknown legacy status: " << status; +} + +bool convertHidlWifiChannelInfoToLegacy(const WifiChannelInfo& hidl_info, + legacy_hal::wifi_channel_info* legacy_info) { + if (!legacy_info) { + return false; + } + *legacy_info = {}; + legacy_info->width = convertHidlWifiChannelWidthToLegacy(hidl_info.width); + legacy_info->center_freq = hidl_info.centerFreq; + legacy_info->center_freq0 = hidl_info.centerFreq0; + legacy_info->center_freq1 = hidl_info.centerFreq1; + return true; +} + +bool convertLegacyWifiChannelInfoToHidl(const legacy_hal::wifi_channel_info& legacy_info, + WifiChannelInfo* hidl_info) { + if (!hidl_info) { + return false; + } + *hidl_info = {}; + hidl_info->width = convertLegacyWifiChannelWidthToHidl(legacy_info.width); + hidl_info->centerFreq = legacy_info.center_freq; + hidl_info->centerFreq0 = legacy_info.center_freq0; + hidl_info->centerFreq1 = legacy_info.center_freq1; + return true; +} + +bool convertHidlRttConfigToLegacy(const V1_4::RttConfig& hidl_config, + legacy_hal::wifi_rtt_config* legacy_config) { + if (!legacy_config) { + return false; + } + *legacy_config = {}; + CHECK(hidl_config.addr.size() == sizeof(legacy_config->addr)); + memcpy(legacy_config->addr, hidl_config.addr.data(), hidl_config.addr.size()); + legacy_config->type = convertHidlRttTypeToLegacy(hidl_config.type); + legacy_config->peer = convertHidlRttPeerTypeToLegacy(hidl_config.peer); + if (!convertHidlWifiChannelInfoToLegacy(hidl_config.channel, &legacy_config->channel)) { + return false; + } + legacy_config->burst_period = hidl_config.burstPeriod; + legacy_config->num_burst = hidl_config.numBurst; + legacy_config->num_frames_per_burst = hidl_config.numFramesPerBurst; + legacy_config->num_retries_per_rtt_frame = hidl_config.numRetriesPerRttFrame; + legacy_config->num_retries_per_ftmr = hidl_config.numRetriesPerFtmr; + legacy_config->LCI_request = hidl_config.mustRequestLci; + legacy_config->LCR_request = hidl_config.mustRequestLcr; + legacy_config->burst_duration = hidl_config.burstDuration; + legacy_config->preamble = convertHidlRttPreambleToLegacy(hidl_config.preamble); + legacy_config->bw = convertHidlRttBwToLegacy(hidl_config.bw); + return true; +} + +bool convertHidlVectorOfRttConfigToLegacy( + const std::vector& hidl_configs, + std::vector* legacy_configs) { + if (!legacy_configs) { + return false; + } + *legacy_configs = {}; + for (const auto& hidl_config : hidl_configs) { + legacy_hal::wifi_rtt_config legacy_config; + if (!convertHidlRttConfigToLegacy(hidl_config, &legacy_config)) { + return false; + } + legacy_configs->push_back(legacy_config); + } + return true; +} + +bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info, + legacy_hal::wifi_lci_information* legacy_info) { + if (!legacy_info) { + return false; + } + *legacy_info = {}; + legacy_info->latitude = hidl_info.latitude; + legacy_info->longitude = hidl_info.longitude; + legacy_info->altitude = hidl_info.altitude; + legacy_info->latitude_unc = hidl_info.latitudeUnc; + legacy_info->longitude_unc = hidl_info.longitudeUnc; + legacy_info->altitude_unc = hidl_info.altitudeUnc; + legacy_info->motion_pattern = convertHidlRttMotionPatternToLegacy(hidl_info.motionPattern); + legacy_info->floor = hidl_info.floor; + legacy_info->height_above_floor = hidl_info.heightAboveFloor; + legacy_info->height_unc = hidl_info.heightUnc; + return true; +} + +bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info, + legacy_hal::wifi_lcr_information* legacy_info) { + if (!legacy_info) { + return false; + } + *legacy_info = {}; + CHECK(hidl_info.countryCode.size() == sizeof(legacy_info->country_code)); + memcpy(legacy_info->country_code, hidl_info.countryCode.data(), hidl_info.countryCode.size()); + if (hidl_info.civicInfo.size() > sizeof(legacy_info->civic_info)) { + return false; + } + legacy_info->length = hidl_info.civicInfo.size(); + memcpy(legacy_info->civic_info, hidl_info.civicInfo.c_str(), hidl_info.civicInfo.size()); + return true; +} + +bool convertHidlRttResponderToLegacy(const V1_4::RttResponder& hidl_responder, + legacy_hal::wifi_rtt_responder* legacy_responder) { + if (!legacy_responder) { + return false; + } + *legacy_responder = {}; + if (!convertHidlWifiChannelInfoToLegacy(hidl_responder.channel, &legacy_responder->channel)) { + return false; + } + legacy_responder->preamble = convertHidlRttPreambleToLegacy(hidl_responder.preamble); + return true; +} + +bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder, + V1_4::RttResponder* hidl_responder) { + if (!hidl_responder) { + return false; + } + *hidl_responder = {}; + if (!convertLegacyWifiChannelInfoToHidl(legacy_responder.channel, &hidl_responder->channel)) { + return false; + } + hidl_responder->preamble = convertLegacyRttPreambleToHidl(legacy_responder.preamble); + return true; +} + +bool convertLegacyRttCapabilitiesToHidl( + const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, + V1_4::RttCapabilities* hidl_capabilities) { + if (!hidl_capabilities) { + return false; + } + *hidl_capabilities = {}; + hidl_capabilities->rttOneSidedSupported = legacy_capabilities.rtt_one_sided_supported; + hidl_capabilities->rttFtmSupported = legacy_capabilities.rtt_ftm_supported; + hidl_capabilities->lciSupported = legacy_capabilities.lci_support; + hidl_capabilities->lcrSupported = legacy_capabilities.lcr_support; + hidl_capabilities->responderSupported = legacy_capabilities.responder_supported; + hidl_capabilities->preambleSupport = 0; + for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT, + legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE}) { + if (legacy_capabilities.preamble_support & flag) { + hidl_capabilities->preambleSupport |= + static_cast::type>( + convertLegacyRttPreambleToHidl(flag)); + } + } + hidl_capabilities->bwSupport = 0; + for (const auto flag : + {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20, + legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160}) { + if (legacy_capabilities.bw_support & flag) { + hidl_capabilities->bwSupport |= + static_cast::type>(convertLegacyRttBwToHidl(flag)); + } + } + hidl_capabilities->mcVersion = legacy_capabilities.mc_version; + return true; +} + +bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate, + V1_4::WifiRateInfo* hidl_rate) { + if (!hidl_rate) { + return false; + } + *hidl_rate = {}; + hidl_rate->preamble = convertLegacyWifiRatePreambleToHidl(legacy_rate.preamble); + hidl_rate->nss = convertLegacyWifiRateNssToHidl(legacy_rate.nss); + hidl_rate->bw = convertLegacyWifiChannelWidthToHidl( + static_cast(legacy_rate.bw)); + hidl_rate->rateMcsIdx = legacy_rate.rateMcsIdx; + hidl_rate->bitRateInKbps = legacy_rate.bitrate; + return true; +} + +bool convertLegacyRttResultToHidl(const legacy_hal::wifi_rtt_result& legacy_result, + V1_4::RttResult* hidl_result) { + if (!hidl_result) { + return false; + } + *hidl_result = {}; + CHECK(sizeof(legacy_result.addr) == hidl_result->addr.size()); + memcpy(hidl_result->addr.data(), legacy_result.addr, sizeof(legacy_result.addr)); + hidl_result->burstNum = legacy_result.burst_num; + hidl_result->measurementNumber = legacy_result.measurement_number; + hidl_result->successNumber = legacy_result.success_number; + hidl_result->numberPerBurstPeer = legacy_result.number_per_burst_peer; + hidl_result->status = convertLegacyRttStatusToHidl(legacy_result.status); + hidl_result->retryAfterDuration = legacy_result.retry_after_duration; + hidl_result->type = convertLegacyRttTypeToHidl(legacy_result.type); + hidl_result->rssi = legacy_result.rssi; + hidl_result->rssiSpread = legacy_result.rssi_spread; + if (!convertLegacyWifiRateInfoToHidl(legacy_result.tx_rate, &hidl_result->txRate)) { + return false; + } + if (!convertLegacyWifiRateInfoToHidl(legacy_result.rx_rate, &hidl_result->rxRate)) { + return false; + } + hidl_result->rtt = legacy_result.rtt; + hidl_result->rttSd = legacy_result.rtt_sd; + hidl_result->rttSpread = legacy_result.rtt_spread; + hidl_result->distanceInMm = legacy_result.distance_mm; + hidl_result->distanceSdInMm = legacy_result.distance_sd_mm; + hidl_result->distanceSpreadInMm = legacy_result.distance_spread_mm; + hidl_result->timeStampInUs = legacy_result.ts; + hidl_result->burstDurationInMs = legacy_result.burst_duration; + hidl_result->negotiatedBurstNum = legacy_result.negotiated_burst_num; + if (legacy_result.LCI && !convertLegacyIeToHidl(*legacy_result.LCI, &hidl_result->lci)) { + return false; + } + if (legacy_result.LCR && !convertLegacyIeToHidl(*legacy_result.LCR, &hidl_result->lcr)) { + return false; + } + return true; +} + +bool convertLegacyVectorOfRttResultToHidl( + const std::vector& legacy_results, + std::vector* hidl_results) { + if (!hidl_results) { + return false; + } + *hidl_results = {}; + for (const auto legacy_result : legacy_results) { + V1_4::RttResult hidl_result; + if (!convertLegacyRttResultToHidl(*legacy_result, &hidl_result)) { + return false; + } + hidl_results->push_back(hidl_result); + } + return true; +} + +legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type) { + switch (hidl_interface_type) { + case IfaceType::STA: + return legacy_hal::WIFI_INTERFACE_TYPE_STA; + case IfaceType::AP: + return legacy_hal::WIFI_INTERFACE_TYPE_AP; + case IfaceType::P2P: + return legacy_hal::WIFI_INTERFACE_TYPE_P2P; + case IfaceType::NAN: + return legacy_hal::WIFI_INTERFACE_TYPE_NAN; + } + CHECK(false); +} + +legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy( + V1_5::IWifiChip::MultiStaUseCase use_case) { + switch (use_case) { + case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY: + return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY; + case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED: + return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED; + } + CHECK(false); +} + +bool convertHidlCoexUnsafeChannelToLegacy( + const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel, + legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) { + if (!legacy_unsafe_channel) { + return false; + } + *legacy_unsafe_channel = {}; + switch (hidl_unsafe_channel.band) { + case V1_5::WifiBand::BAND_24GHZ: + legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND; + break; + case V1_5::WifiBand::BAND_5GHZ: + legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND; + break; + default: + return false; + }; + legacy_unsafe_channel->channel = hidl_unsafe_channel.channel; + legacy_unsafe_channel->power_cap_dbm = hidl_unsafe_channel.powerCapDbm; + return true; +} + +bool convertHidlVectorOfCoexUnsafeChannelToLegacy( + const std::vector& hidl_unsafe_channels, + std::vector* legacy_unsafe_channels) { + if (!legacy_unsafe_channels) { + return false; + } + *legacy_unsafe_channels = {}; + for (const auto& hidl_unsafe_channel : hidl_unsafe_channels) { + legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel; + if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy(hidl_unsafe_channel, + &legacy_unsafe_channel)) { + return false; + } + legacy_unsafe_channels->push_back(legacy_unsafe_channel); + } + return true; +} + +} // namespace hidl_struct_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/hidl_struct_util.h b/wifi/1.6/default/hidl_struct_util.h new file mode 100644 index 0000000000..15a3205847 --- /dev/null +++ b/wifi/1.6/default/hidl_struct_util.h @@ -0,0 +1,200 @@ +/* + * 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. + */ + +#ifndef HIDL_STRUCT_UTIL_H_ +#define HIDL_STRUCT_UTIL_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wifi_legacy_hal.h" + +/** + * This file contains a bunch of functions to convert structs from the legacy + * HAL to HIDL and vice versa. + * TODO(b/32093047): Add unit tests for these conversion methods in the VTS test + * suite. + */ +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace hidl_struct_util { +using namespace android::hardware::wifi::V1_0; + +// Chip conversion methods. +bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set, + uint32_t legacy_logger_feature_set, + uint32_t* hidl_caps); +bool convertLegacyDebugRingBufferStatusToHidl( + const legacy_hal::wifi_ring_buffer_status& legacy_status, + WifiDebugRingBufferStatus* hidl_status); +bool convertLegacyVectorOfDebugRingBufferStatusToHidl( + const std::vector& legacy_status_vec, + std::vector* hidl_status_vec); +bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats, + WifiDebugHostWakeReasonStats* hidl_stats); +legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy( + V1_1::IWifiChip::TxPowerScenario hidl_scenario); +legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( + V1_3::IWifiChip::LatencyMode hidl_latency_mode); +legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( + V1_2::IWifiChip::TxPowerScenario hidl_scenario); +bool convertLegacyWifiMacInfosToHidl( + const std::vector& legacy_mac_infos, + std::vector* hidl_radio_mode_infos); +legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type); +legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy( + V1_5::IWifiChip::MultiStaUseCase use_case); +bool convertHidlCoexUnsafeChannelToLegacy( + const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel, + legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel); +bool convertHidlVectorOfCoexUnsafeChannelToLegacy( + const std::vector& hidl_unsafe_channels, + std::vector* legacy_unsafe_channels); + +// STA iface conversion methods. +bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set, + uint32_t legacy_logger_feature_set, + uint32_t* hidl_caps); +bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps, + StaApfPacketFilterCapabilities* hidl_caps); +bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps, + StaBackgroundScanCapabilities* hidl_caps); +legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band); +bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params, + legacy_hal::wifi_scan_cmd_params* legacy_scan_params); +// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11 +// Information Elements (IEs) +bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result, + bool has_ie_data, StaScanResult* hidl_scan_result); +// |cached_results| is assumed to not include IEs. +bool convertLegacyVectorOfCachedGscanResultsToHidl( + const std::vector& legacy_cached_scan_results, + std::vector* hidl_scan_datas); +bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats, + V1_5::StaLinkLayerStats* hidl_stats); +bool convertLegacyRoamingCapabilitiesToHidl( + const legacy_hal::wifi_roaming_capabilities& legacy_caps, + StaRoamingCapabilities* hidl_caps); +bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config, + legacy_hal::wifi_roaming_config* legacy_config); +legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state); +bool convertLegacyVectorOfDebugTxPacketFateToHidl( + const std::vector& legacy_fates, + std::vector* hidl_fates); +bool convertLegacyVectorOfDebugRxPacketFateToHidl( + const std::vector& legacy_fates, + std::vector* hidl_fates); + +// NAN iface conversion methods. +void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len, + WifiNanStatus* wifiNanStatus); +bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request, + legacy_hal::NanEnableRequest* legacy_request); +bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request, + legacy_hal::NanConfigRequest* legacy_request); +bool convertHidlNanEnableRequest_1_4ToLegacy( + const V1_4::NanEnableRequest& hidl_request1, + const V1_5::NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request); +bool convertHidlNanConfigRequest_1_4ToLegacy( + const V1_4::NanConfigRequest& hidl_request1, + const V1_5::NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request); +bool convertHidlNanEnableRequest_1_5ToLegacy( + const V1_4::NanEnableRequest& hidl_request1, + const V1_5::NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanEnableRequest* legacy_request); +bool convertHidlNanConfigRequest_1_5ToLegacy( + const V1_4::NanConfigRequest& hidl_request1, + const V1_5::NanConfigRequestSupplemental& hidl_request2, + legacy_hal::NanConfigRequest* legacy_request); +bool convertHidlNanPublishRequestToLegacy(const NanPublishRequest& hidl_request, + legacy_hal::NanPublishRequest* legacy_request); +bool convertHidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& hidl_request, + legacy_hal::NanSubscribeRequest* legacy_request); +bool convertHidlNanTransmitFollowupRequestToLegacy( + const NanTransmitFollowupRequest& hidl_request, + legacy_hal::NanTransmitFollowupRequest* legacy_request); +bool convertHidlNanDataPathInitiatorRequestToLegacy( + const NanInitiateDataPathRequest& hidl_request, + legacy_hal::NanDataPathInitiatorRequest* legacy_request); +bool convertHidlNanDataPathIndicationResponseToLegacy( + const NanRespondToDataPathIndicationRequest& hidl_response, + legacy_hal::NanDataPathIndicationResponse* legacy_response); +bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response, + WifiNanStatus* wifiNanStatus); +bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response, + V1_5::NanCapabilities* hidl_response); +bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind, + NanMatchInd* hidl_ind); +bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind, + NanFollowupReceivedInd* hidl_ind); +bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind, + NanDataPathRequestInd* hidl_ind); +bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind, + V1_2::NanDataPathConfirmInd* hidl_ind); +bool convertLegacyNanDataPathScheduleUpdateIndToHidl( + const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind, + V1_2::NanDataPathScheduleUpdateInd* hidl_ind); + +// RTT controller conversion methods. +bool convertHidlVectorOfRttConfigToLegacy(const std::vector& hidl_configs, + std::vector* legacy_configs); +bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info, + legacy_hal::wifi_lci_information* legacy_info); +bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info, + legacy_hal::wifi_lcr_information* legacy_info); +bool convertHidlRttResponderToLegacy(const V1_4::RttResponder& hidl_responder, + legacy_hal::wifi_rtt_responder* legacy_responder); +bool convertHidlWifiChannelInfoToLegacy(const WifiChannelInfo& hidl_info, + legacy_hal::wifi_channel_info* legacy_info); +bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder, + V1_4::RttResponder* hidl_responder); +bool convertLegacyRttCapabilitiesToHidl( + const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, + V1_4::RttCapabilities* hidl_capabilities); +bool convertLegacyVectorOfRttResultToHidl( + const std::vector& legacy_results, + std::vector* hidl_results); +uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band); +uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask); +uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask); +bool convertLegacyWifiUsableChannelsToHidl( + const std::vector& legacy_usable_channels, + std::vector* hidl_usable_channels); +bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats, + V1_5::StaPeerInfo* hidl_peer_info_stats); +bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate, + V1_4::WifiRateInfo* hidl_rate); +} // namespace hidl_struct_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // HIDL_STRUCT_UTIL_H_ diff --git a/wifi/1.6/default/hidl_sync_util.cpp b/wifi/1.6/default/hidl_sync_util.cpp new file mode 100644 index 0000000000..358d95e668 --- /dev/null +++ b/wifi/1.6/default/hidl_sync_util.cpp @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#include "hidl_sync_util.h" + +namespace { +std::recursive_mutex g_mutex; +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace hidl_sync_util { + +std::unique_lock acquireGlobalLock() { + return std::unique_lock{g_mutex}; +} + +} // namespace hidl_sync_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/hidl_sync_util.h b/wifi/1.6/default/hidl_sync_util.h new file mode 100644 index 0000000000..2c1c37b0ad --- /dev/null +++ b/wifi/1.6/default/hidl_sync_util.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#ifndef HIDL_SYNC_UTIL_H_ +#define HIDL_SYNC_UTIL_H_ + +#include + +// Utility that provides a global lock to synchronize access between +// the HIDL thread and the legacy HAL's event loop. +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace hidl_sync_util { +std::unique_lock acquireGlobalLock(); +} // namespace hidl_sync_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android +#endif // HIDL_SYNC_UTIL_H_ diff --git a/wifi/1.6/default/ringbuffer.cpp b/wifi/1.6/default/ringbuffer.cpp new file mode 100644 index 0000000000..6d4ed843c3 --- /dev/null +++ b/wifi/1.6/default/ringbuffer.cpp @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#include + +#include "ringbuffer.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { + +Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {} + +void Ringbuffer::append(const std::vector& input) { + if (input.size() == 0) { + return; + } + if (input.size() > maxSize_) { + LOG(INFO) << "Oversized message of " << input.size() << " bytes is dropped"; + return; + } + data_.push_back(input); + size_ += input.size() * sizeof(input[0]); + while (size_ > maxSize_) { + size_ -= data_.front().size() * sizeof(data_.front()[0]); + data_.pop_front(); + } +} + +const std::list>& Ringbuffer::getData() const { + return data_; +} + +void Ringbuffer::clear() { + data_.clear(); + size_ = 0; +} + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/ringbuffer.h b/wifi/1.6/default/ringbuffer.h new file mode 100644 index 0000000000..8571a9f3d4 --- /dev/null +++ b/wifi/1.6/default/ringbuffer.h @@ -0,0 +1,54 @@ +/* + * 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 RINGBUFFER_H_ +#define RINGBUFFER_H_ + +#include +#include + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { + +/** + * Ringbuffer object used to store debug data. + */ +class Ringbuffer { + public: + explicit Ringbuffer(size_t maxSize); + + // Appends the data buffer and deletes from the front until buffer is + // within |maxSize_|. + void append(const std::vector& input); + const std::list>& getData() const; + void clear(); + + private: + std::list> data_; + size_t size_; + size_t maxSize_; +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // RINGBUFFER_H_ diff --git a/wifi/1.6/default/service.cpp b/wifi/1.6/default/service.cpp new file mode 100644 index 0000000000..c874d8b199 --- /dev/null +++ b/wifi/1.6/default/service.cpp @@ -0,0 +1,71 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "wifi.h" +#include "wifi_feature_flags.h" +#include "wifi_legacy_hal.h" +#include "wifi_legacy_hal_factory.h" +#include "wifi_mode_controller.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::LazyServiceRegistrar; +using android::hardware::wifi::V1_6::implementation::feature_flags::WifiFeatureFlags; +using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHal; +using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHalFactory; +using android::hardware::wifi::V1_6::implementation::mode_controller::WifiModeController; + +#ifdef LAZY_SERVICE +const bool kLazyService = true; +#else +const bool kLazyService = false; +#endif + +int main(int /*argc*/, char** argv) { + signal(SIGPIPE, SIG_IGN); + android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM)); + LOG(INFO) << "Wifi Hal is booting up..."; + + configureRpcThreadpool(1, true /* callerWillJoin */); + + const auto iface_tool = std::make_shared(); + const auto legacy_hal_factory = std::make_shared(iface_tool); + + // Setup hwbinder service + android::sp service = + new android::hardware::wifi::V1_6::implementation::Wifi( + iface_tool, legacy_hal_factory, std::make_shared(), + std::make_shared()); + if (kLazyService) { + auto registrar = LazyServiceRegistrar::getInstance(); + CHECK_EQ(registrar.registerService(service), android::NO_ERROR) + << "Failed to register wifi HAL"; + } else { + CHECK_EQ(service->registerAsService(), android::NO_ERROR) << "Failed to register wifi HAL"; + } + + joinRpcThreadpool(); + + LOG(INFO) << "Wifi Hal is terminating..."; + return 0; +} diff --git a/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp new file mode 100644 index 0000000000..1182a58dbd --- /dev/null +++ b/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp @@ -0,0 +1,385 @@ +/* + * Copyright (C) 2017, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#undef NAN +#include "hidl_struct_util.h" + +using testing::Test; + +namespace { +constexpr uint32_t kMacId1 = 1; +constexpr uint32_t kMacId2 = 2; +constexpr uint32_t kIfaceChannel1 = 3; +constexpr uint32_t kIfaceChannel2 = 5; +constexpr char kIfaceName1[] = "wlan0"; +constexpr char kIfaceName2[] = "wlan1"; +} // namespace +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; +using ::android::hardware::wifi::V1_0::WifiChannelWidthInMhz; + +class HidlStructUtilTest : public Test {}; + +TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) { + std::vector legacy_mac_infos; + legacy_hal::WifiMacInfo legacy_mac_info1 = { + .wlan_mac_id = kMacId1, + .mac_band = legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND}; + legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1}; + legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2}; + legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); + legacy_mac_info1.iface_infos.push_back(legacy_iface_info2); + legacy_mac_infos.push_back(legacy_mac_info1); + + std::vector hidl_radio_mode_infos; + ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(legacy_mac_infos, + &hidl_radio_mode_infos)); + + ASSERT_EQ(1u, hidl_radio_mode_infos.size()); + auto hidl_radio_mode_info1 = hidl_radio_mode_infos[0]; + EXPECT_EQ(legacy_mac_info1.wlan_mac_id, hidl_radio_mode_info1.radioId); + EXPECT_EQ(V1_4::WifiBand::BAND_24GHZ_5GHZ, hidl_radio_mode_info1.bandInfo); + ASSERT_EQ(2u, hidl_radio_mode_info1.ifaceInfos.size()); + auto hidl_iface_info1 = hidl_radio_mode_info1.ifaceInfos[0]; + EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); + EXPECT_EQ(static_cast(legacy_iface_info1.channel), hidl_iface_info1.channel); + auto hidl_iface_info2 = hidl_radio_mode_info1.ifaceInfos[1]; + EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); + EXPECT_EQ(static_cast(legacy_iface_info2.channel), hidl_iface_info2.channel); +} + +TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) { + std::vector legacy_mac_infos; + legacy_hal::WifiMacInfo legacy_mac_info1 = {.wlan_mac_id = kMacId1, + .mac_band = legacy_hal::WLAN_MAC_5_0_BAND}; + legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1}; + legacy_hal::WifiMacInfo legacy_mac_info2 = {.wlan_mac_id = kMacId2, + .mac_band = legacy_hal::WLAN_MAC_2_4_BAND}; + legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2}; + legacy_mac_info1.iface_infos.push_back(legacy_iface_info1); + legacy_mac_infos.push_back(legacy_mac_info1); + legacy_mac_info2.iface_infos.push_back(legacy_iface_info2); + legacy_mac_infos.push_back(legacy_mac_info2); + + std::vector hidl_radio_mode_infos; + ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(legacy_mac_infos, + &hidl_radio_mode_infos)); + + ASSERT_EQ(2u, hidl_radio_mode_infos.size()); + + // Find mac info 1. + const auto hidl_radio_mode_info1 = + std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), + [&legacy_mac_info1](const V1_4::IWifiChipEventCallback::RadioModeInfo& x) { + return x.radioId == legacy_mac_info1.wlan_mac_id; + }); + ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1); + EXPECT_EQ(V1_4::WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo); + ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size()); + auto hidl_iface_info1 = hidl_radio_mode_info1->ifaceInfos[0]; + EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name); + EXPECT_EQ(static_cast(legacy_iface_info1.channel), hidl_iface_info1.channel); + + // Find mac info 2. + const auto hidl_radio_mode_info2 = + std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(), + [&legacy_mac_info2](const V1_4::IWifiChipEventCallback::RadioModeInfo& x) { + return x.radioId == legacy_mac_info2.wlan_mac_id; + }); + ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2); + EXPECT_EQ(V1_4::WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo); + ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size()); + auto hidl_iface_info2 = hidl_radio_mode_info2->ifaceInfos[0]; + EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name); + EXPECT_EQ(static_cast(legacy_iface_info2.channel), hidl_iface_info2.channel); +} + +TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { + legacy_hal::LinkLayerStats legacy_stats{}; + legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); + legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); + legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{}); + legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{}); + legacy_stats.iface.beacon_rx = rand(); + legacy_stats.iface.rssi_mgmt = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand(); + + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand(); + + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand(); + + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand(); + + legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand(); + legacy_stats.iface.num_peers = 1; + + for (auto& radio : legacy_stats.radios) { + radio.stats.radio = rand(); + radio.stats.on_time = rand(); + radio.stats.tx_time = rand(); + radio.stats.rx_time = rand(); + radio.stats.on_time_scan = rand(); + radio.stats.on_time_nbd = rand(); + radio.stats.on_time_gscan = rand(); + radio.stats.on_time_roam_scan = rand(); + radio.stats.on_time_pno_scan = rand(); + radio.stats.on_time_hs20 = rand(); + for (int i = 0; i < 4; i++) { + radio.tx_time_per_levels.push_back(rand()); + } + + legacy_hal::wifi_channel_stat channel_stat1 = { + .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0}, + .on_time = 0x1111, + .cca_busy_time = 0x55, + }; + legacy_hal::wifi_channel_stat channel_stat2 = { + .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0}, + .on_time = 0x2222, + .cca_busy_time = 0x66, + }; + radio.channel_stats.push_back(channel_stat1); + radio.channel_stats.push_back(channel_stat2); + } + + for (auto& peer : legacy_stats.peers) { + peer.peer_info.bssload.sta_count = rand(); + peer.peer_info.bssload.chan_util = rand(); + wifi_rate_stat rate_stat1 = { + .rate = {3, 1, 2, 5, 0, 0}, + .tx_mpdu = 0, + .rx_mpdu = 1, + .mpdu_lost = 2, + .retries = 3, + .retries_short = 4, + .retries_long = 5, + }; + wifi_rate_stat rate_stat2 = { + .rate = {2, 2, 1, 6, 0, 1}, + .tx_mpdu = 6, + .rx_mpdu = 7, + .mpdu_lost = 8, + .retries = 9, + .retries_short = 10, + .retries_long = 11, + }; + peer.rate_stats.push_back(rate_stat1); + peer.rate_stats.push_back(rate_stat2); + } + + V1_5::StaLinkLayerStats converted{}; + hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &converted); + EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.V1_0.beaconRx); + EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.V1_0.avgRssiMgmt); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu, + converted.iface.V1_0.wmeBePktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu, + converted.iface.V1_0.wmeBePktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost, + converted.iface.V1_0.wmeBePktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries, + converted.iface.V1_0.wmeBePktStats.retries); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min, + converted.iface.wmeBeContentionTimeStats.contentionTimeMinInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max, + converted.iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg, + converted.iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples, + converted.iface.wmeBeContentionTimeStats.contentionNumSamples); + + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu, + converted.iface.V1_0.wmeBkPktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu, + converted.iface.V1_0.wmeBkPktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost, + converted.iface.V1_0.wmeBkPktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries, + converted.iface.V1_0.wmeBkPktStats.retries); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min, + converted.iface.wmeBkContentionTimeStats.contentionTimeMinInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max, + converted.iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg, + converted.iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples, + converted.iface.wmeBkContentionTimeStats.contentionNumSamples); + + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu, + converted.iface.V1_0.wmeViPktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu, + converted.iface.V1_0.wmeViPktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost, + converted.iface.V1_0.wmeViPktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries, + converted.iface.V1_0.wmeViPktStats.retries); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min, + converted.iface.wmeViContentionTimeStats.contentionTimeMinInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max, + converted.iface.wmeViContentionTimeStats.contentionTimeMaxInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg, + converted.iface.wmeViContentionTimeStats.contentionTimeAvgInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples, + converted.iface.wmeViContentionTimeStats.contentionNumSamples); + + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu, + converted.iface.V1_0.wmeVoPktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu, + converted.iface.V1_0.wmeVoPktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost, + converted.iface.V1_0.wmeVoPktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries, + converted.iface.V1_0.wmeVoPktStats.retries); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min, + converted.iface.wmeVoContentionTimeStats.contentionTimeMinInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max, + converted.iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg, + converted.iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples, + converted.iface.wmeVoContentionTimeStats.contentionNumSamples); + + EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent, + converted.iface.timeSliceDutyCycleInPercent); + + EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size()); + for (size_t i = 0; i < legacy_stats.radios.size(); i++) { + EXPECT_EQ(legacy_stats.radios[i].stats.radio, converted.radios[i].radioId); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time, converted.radios[i].V1_3.V1_0.onTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, converted.radios[i].V1_3.V1_0.txTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, converted.radios[i].V1_3.V1_0.rxTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan, + converted.radios[i].V1_3.V1_0.onTimeInMsForScan); + EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(), + converted.radios[i].V1_3.V1_0.txTimeInMsPerLevel.size()); + for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); j++) { + EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j], + converted.radios[i].V1_3.V1_0.txTimeInMsPerLevel[j]); + } + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd, + converted.radios[i].V1_3.onTimeInMsForNanScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan, + converted.radios[i].V1_3.onTimeInMsForBgScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan, + converted.radios[i].V1_3.onTimeInMsForRoamScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan, + converted.radios[i].V1_3.onTimeInMsForPnoScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20, + converted.radios[i].V1_3.onTimeInMsForHs20Scan); + EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(), + converted.radios[i].V1_3.channelStats.size()); + for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); k++) { + auto& legacy_channel_st = legacy_stats.radios[i].channel_stats[k]; + EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20, + converted.radios[i].V1_3.channelStats[k].channel.width); + EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq), + converted.radios[i].V1_3.channelStats[k].channel.centerFreq); + EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq0), + converted.radios[i].V1_3.channelStats[k].channel.centerFreq0); + EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq1), + converted.radios[i].V1_3.channelStats[k].channel.centerFreq1); + EXPECT_EQ(legacy_channel_st.cca_busy_time, + converted.radios[i].V1_3.channelStats[k].ccaBusyTimeInMs); + EXPECT_EQ(legacy_channel_st.on_time, + converted.radios[i].V1_3.channelStats[k].onTimeInMs); + } + } + + EXPECT_EQ(legacy_stats.peers.size(), converted.iface.peers.size()); + for (size_t i = 0; i < legacy_stats.peers.size(); i++) { + EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.sta_count, + converted.iface.peers[i].staCount); + EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.chan_util, + converted.iface.peers[i].chanUtil); + for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) { + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble, + (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.preamble); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.nss, + (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.bw, + (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx, + converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu, + converted.iface.peers[i].rateStats[j].txMpdu); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu, + converted.iface.peers[i].rateStats[j].rxMpdu); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].mpdu_lost, + converted.iface.peers[i].rateStats[j].mpduLost); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].retries, + converted.iface.peers[i].rateStats[j].retries); + } + } +} + +TEST_F(HidlStructUtilTest, CanConvertLegacyFeaturesToHidl) { + using HidlChipCaps = V1_3::IWifiChip::ChipCapabilityMask; + + uint32_t hidle_caps; + + uint32_t legacy_feature_set = WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE; + uint32_t legacy_logger_feature_set = legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; + + ASSERT_TRUE(hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities( + legacy_feature_set, legacy_logger_feature_set, &hidle_caps)); + + EXPECT_EQ(HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA | + HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS | + HidlChipCaps::DEBUG_ERROR_ALERTS | HidlChipCaps::D2D_RTT | + HidlChipCaps::SET_LATENCY_MODE | HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP, + hidle_caps); +} +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/tests/main.cpp b/wifi/1.6/default/tests/main.cpp new file mode 100644 index 0000000000..9aac837242 --- /dev/null +++ b/wifi/1.6/default/tests/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ::testing::InitGoogleMock(&argc, argv); + // Force ourselves to always log to stderr + android::base::InitLogging(argv, android::base::StderrLogger); + return RUN_ALL_TESTS(); +} diff --git a/wifi/1.6/default/tests/mock_interface_tool.cpp b/wifi/1.6/default/tests/mock_interface_tool.cpp new file mode 100644 index 0000000000..b99a16446c --- /dev/null +++ b/wifi/1.6/default/tests/mock_interface_tool.cpp @@ -0,0 +1,29 @@ +/* + * 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 +#include +#include + +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 +#include "mock_interface_tool.h" + +namespace android { +namespace wifi_system { + +MockInterfaceTool::MockInterfaceTool() {} + +} // namespace wifi_system +} // namespace android diff --git a/wifi/1.6/default/tests/mock_interface_tool.h b/wifi/1.6/default/tests/mock_interface_tool.h new file mode 100644 index 0000000000..7ce3992c7e --- /dev/null +++ b/wifi/1.6/default/tests/mock_interface_tool.h @@ -0,0 +1,42 @@ +/* + * 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 MOCK_INTERFACE_TOOL_H +#define MOCK_INTERFACE_TOOL_H + +#include +#include + +namespace android { +namespace wifi_system { + +class MockInterfaceTool : public InterfaceTool { + public: + MockInterfaceTool(); + + MOCK_METHOD1(GetUpState, bool(const char* if_name)); + MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up)); + MOCK_METHOD1(SetWifiUpState, bool(bool request_up)); + MOCK_METHOD2(SetMacAddress, + bool(const char* if_name, const std::array& address)); + MOCK_METHOD1(GetFactoryMacAddress, std::array(const char* if_name)); + +}; // class MockInterfaceTool + +} // namespace wifi_system +} // namespace android + +#endif // MOCK_INTERFACE_TOOL_H diff --git a/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp b/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp new file mode 100644 index 0000000000..d10b74c3a0 --- /dev/null +++ b/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "mock_wifi_feature_flags.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace feature_flags { + +MockWifiFeatureFlags::MockWifiFeatureFlags() {} + +} // namespace feature_flags +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/tests/mock_wifi_feature_flags.h b/wifi/1.6/default/tests/mock_wifi_feature_flags.h new file mode 100644 index 0000000000..fa3600a4b1 --- /dev/null +++ b/wifi/1.6/default/tests/mock_wifi_feature_flags.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_WIFI_FEATURE_FLAGS_H_ +#define MOCK_WIFI_FEATURE_FLAGS_H_ + +#include +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 + +#include "wifi_feature_flags.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace feature_flags { + +class MockWifiFeatureFlags : public WifiFeatureFlags { + public: + MockWifiFeatureFlags(); + + MOCK_METHOD1(getChipModes, std::vector(bool is_primary)); + MOCK_METHOD0(isApMacRandomizationDisabled, bool()); +}; + +} // namespace feature_flags +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // MOCK_WIFI_FEATURE_FLAGS_H_ diff --git a/wifi/1.6/default/tests/mock_wifi_iface_util.cpp b/wifi/1.6/default/tests/mock_wifi_iface_util.cpp new file mode 100644 index 0000000000..24b16cb469 --- /dev/null +++ b/wifi/1.6/default/tests/mock_wifi_iface_util.cpp @@ -0,0 +1,39 @@ +/* + * 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 +#include +#include + +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 +#include "mock_wifi_iface_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace iface_util { + +MockWifiIfaceUtil::MockWifiIfaceUtil(const std::weak_ptr iface_tool, + const std::weak_ptr legacy_hal) + : WifiIfaceUtil(iface_tool, legacy_hal) {} +} // namespace iface_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/tests/mock_wifi_iface_util.h b/wifi/1.6/default/tests/mock_wifi_iface_util.h new file mode 100644 index 0000000000..2701c36d76 --- /dev/null +++ b/wifi/1.6/default/tests/mock_wifi_iface_util.h @@ -0,0 +1,50 @@ +/* + * 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 MOCK_WIFI_IFACE_UTIL_H_ +#define MOCK_WIFI_IFACE_UTIL_H_ + +#include + +#include "wifi_iface_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace iface_util { + +class MockWifiIfaceUtil : public WifiIfaceUtil { + public: + MockWifiIfaceUtil(const std::weak_ptr iface_tool, + const std::weak_ptr legacy_hal); + MOCK_METHOD1(getFactoryMacAddress, std::array(const std::string&)); + MOCK_METHOD2(setMacAddress, bool(const std::string&, const std::array&)); + MOCK_METHOD0(getOrCreateRandomMacAddress, std::array()); + MOCK_METHOD2(registerIfaceEventHandlers, void(const std::string&, IfaceEventHandlers)); + MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&)); + MOCK_METHOD2(setUpState, bool(const std::string&, bool)); + MOCK_METHOD1(ifNameToIndex, unsigned(const std::string&)); +}; +} // namespace iface_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // MOCK_WIFI_IFACE_UTIL_H_ diff --git a/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp new file mode 100644 index 0000000000..2c558612e3 --- /dev/null +++ b/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 +#include "mock_wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace legacy_hal { + +MockWifiLegacyHal::MockWifiLegacyHal(const std::weak_ptr iface_tool, + const wifi_hal_fn& fn, bool is_primary) + : WifiLegacyHal(iface_tool, fn, is_primary) {} +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/tests/mock_wifi_legacy_hal.h b/wifi/1.6/default/tests/mock_wifi_legacy_hal.h new file mode 100644 index 0000000000..b1f53273ba --- /dev/null +++ b/wifi/1.6/default/tests/mock_wifi_legacy_hal.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_WIFI_LEGACY_HAL_H_ +#define MOCK_WIFI_LEGACY_HAL_H_ + +#include + +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace legacy_hal { + +class MockWifiLegacyHal : public WifiLegacyHal { + public: + MockWifiLegacyHal(const std::weak_ptr iface_tool, + const wifi_hal_fn& fn, bool is_primary); + MOCK_METHOD0(initialize, wifi_error()); + MOCK_METHOD0(start, wifi_error()); + MOCK_METHOD2(stop, + wifi_error(std::unique_lock*, const std::function&)); + MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool)); + MOCK_METHOD2(registerRadioModeChangeCallbackHandler, + wifi_error(const std::string&, const on_radio_mode_change_callback&)); + MOCK_METHOD1(getFirmwareVersion, + std::pair(const std::string& iface_name)); + MOCK_METHOD1(getDriverVersion, + std::pair(const std::string& iface_name)); + + MOCK_METHOD2(selectTxPowerScenario, + wifi_error(const std::string& iface_name, wifi_power_scenario scenario)); + MOCK_METHOD1(resetTxPowerScenario, wifi_error(const std::string& iface_name)); + MOCK_METHOD2(nanRegisterCallbackHandlers, + wifi_error(const std::string&, const NanCallbackHandlers&)); + MOCK_METHOD2(nanDisableRequest, wifi_error(const std::string&, transaction_id)); + MOCK_METHOD3(nanDataInterfaceDelete, + wifi_error(const std::string&, transaction_id, const std::string&)); + MOCK_METHOD2(createVirtualInterface, + wifi_error(const std::string& ifname, wifi_interface_type iftype)); + MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname)); + MOCK_METHOD0(waitForDriverReady, wifi_error()); +}; +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // MOCK_WIFI_LEGACY_HAL_H_ diff --git a/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp b/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp new file mode 100644 index 0000000000..446f8296f8 --- /dev/null +++ b/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 +#include "mock_wifi_mode_controller.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace mode_controller { + +MockWifiModeController::MockWifiModeController() : WifiModeController() {} +} // namespace mode_controller +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/tests/mock_wifi_mode_controller.h b/wifi/1.6/default/tests/mock_wifi_mode_controller.h new file mode 100644 index 0000000000..addcc81591 --- /dev/null +++ b/wifi/1.6/default/tests/mock_wifi_mode_controller.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_WIFI_MODE_CONTROLLER_H_ +#define MOCK_WIFI_MODE_CONTROLLER_H_ + +#include + +#include "wifi_mode_controller.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace mode_controller { + +class MockWifiModeController : public WifiModeController { + public: + MockWifiModeController(); + MOCK_METHOD0(initialize, bool()); + MOCK_METHOD1(changeFirmwareMode, bool(IfaceType)); + MOCK_METHOD1(isFirmwareModeChangeNeeded, bool(IfaceType)); + MOCK_METHOD0(deinitialize, bool()); +}; +} // namespace mode_controller +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // MOCK_WIFI_MODE_CONTROLLER_H_ diff --git a/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp b/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp new file mode 100644 index 0000000000..eb86194ff0 --- /dev/null +++ b/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp @@ -0,0 +1,97 @@ +/* + * 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. + */ + +#include + +#include "ringbuffer.h" + +using testing::Return; +using testing::Test; + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { + +class RingbufferTest : public Test { + public: + const uint32_t maxBufferSize_ = 10; + Ringbuffer buffer_{maxBufferSize_}; +}; + +TEST_F(RingbufferTest, CreateEmptyBuffer) { + ASSERT_TRUE(buffer_.getData().empty()); +} + +TEST_F(RingbufferTest, CanUseFullBufferCapacity) { + const std::vector input(maxBufferSize_ / 2, '0'); + const std::vector input2(maxBufferSize_ / 2, '1'); + buffer_.append(input); + buffer_.append(input2); + ASSERT_EQ(2u, buffer_.getData().size()); + EXPECT_EQ(input, buffer_.getData().front()); + EXPECT_EQ(input2, buffer_.getData().back()); +} + +TEST_F(RingbufferTest, OldDataIsRemovedOnOverflow) { + const std::vector input(maxBufferSize_ / 2, '0'); + const std::vector input2(maxBufferSize_ / 2, '1'); + const std::vector input3 = {'G'}; + buffer_.append(input); + buffer_.append(input2); + buffer_.append(input3); + ASSERT_EQ(2u, buffer_.getData().size()); + EXPECT_EQ(input2, buffer_.getData().front()); + EXPECT_EQ(input3, buffer_.getData().back()); +} + +TEST_F(RingbufferTest, MultipleOldDataIsRemovedOnOverflow) { + const std::vector input(maxBufferSize_ / 2, '0'); + const std::vector input2(maxBufferSize_ / 2, '1'); + const std::vector input3(maxBufferSize_, '2'); + buffer_.append(input); + buffer_.append(input2); + buffer_.append(input3); + ASSERT_EQ(1u, buffer_.getData().size()); + EXPECT_EQ(input3, buffer_.getData().front()); +} + +TEST_F(RingbufferTest, AppendingEmptyBufferDoesNotAddGarbage) { + const std::vector input = {}; + buffer_.append(input); + ASSERT_TRUE(buffer_.getData().empty()); +} + +TEST_F(RingbufferTest, OversizedAppendIsDropped) { + const std::vector input(maxBufferSize_ + 1, '0'); + buffer_.append(input); + ASSERT_TRUE(buffer_.getData().empty()); +} + +TEST_F(RingbufferTest, OversizedAppendDoesNotDropExistingData) { + const std::vector input(maxBufferSize_, '0'); + const std::vector input2(maxBufferSize_ + 1, '1'); + buffer_.append(input); + buffer_.append(input2); + ASSERT_EQ(1u, buffer_.getData().size()); + EXPECT_EQ(input, buffer_.getData().front()); +} +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/tests/runtests.sh b/wifi/1.6/default/tests/runtests.sh new file mode 100755 index 0000000000..6bce3ef8c4 --- /dev/null +++ b/wifi/1.6/default/tests/runtests.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# Copyright(C) 2017 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0(the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http:// www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if [ -z $ANDROID_BUILD_TOP ]; then + echo "You need to source and lunch before you can use this script" + exit 1 +fi +set -e + +$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode android.hardware.wifi@1.0-service-tests +adb root +adb sync data +adb shell /data/nativetest64/vendor/android.hardware.wifi@1.0-service-tests/android.hardware.wifi@1.0-service-tests diff --git a/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp new file mode 100644 index 0000000000..53904116cf --- /dev/null +++ b/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp @@ -0,0 +1,854 @@ +/* + * Copyright (C) 2017, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 +#include "wifi_chip.h" + +#include "mock_interface_tool.h" +#include "mock_wifi_feature_flags.h" +#include "mock_wifi_iface_util.h" +#include "mock_wifi_legacy_hal.h" +#include "mock_wifi_mode_controller.h" + +using testing::NiceMock; +using testing::Return; +using testing::Test; + +namespace { +using android::hardware::wifi::V1_0::ChipId; + +constexpr ChipId kFakeChipId = 5; +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { + +class WifiChipTest : public Test { + protected: + void setupV1IfaceCombination() { + // clang-format off + const hidl_vec combinationsSta = { + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P}, 1}}} + }; + const hidl_vec combinationsAp = { + {{{{IfaceType::AP}, 1}}} + }; + const std::vector modes = { + {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}, + {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); + } + + void setupV1_AwareIfaceCombination() { + // clang-format off + const hidl_vec combinationsSta = { + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} + }; + const hidl_vec combinationsAp = { + {{{{IfaceType::AP}, 1}}} + }; + const std::vector modes = { + {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}, + {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); + } + + void setupV1_AwareDisabledApIfaceCombination() { + // clang-format off + const hidl_vec combinationsSta = { + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} + }; + const std::vector modes = { + {feature_flags::chip_mode_ids::kV1Sta, combinationsSta} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); + } + + void setupV2_AwareIfaceCombination() { + // clang-format off + const hidl_vec combinations = { + {{{{IfaceType::STA}, 1}, {{IfaceType::AP}, 1}}}, + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} + }; + const std::vector modes = { + {feature_flags::chip_mode_ids::kV3, combinations} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); + } + + void setupV2_AwareDisabledApIfaceCombination() { + // clang-format off + const hidl_vec combinations = { + {{{{IfaceType::STA}, 1}, {{IfaceType::P2P, IfaceType::NAN}, 1}}} + }; + const std::vector modes = { + {feature_flags::chip_mode_ids::kV3, combinations} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); + } + + void setup_MultiIfaceCombination() { + // clang-format off + const hidl_vec combinations = { + {{{{IfaceType::STA}, 3}, {{IfaceType::AP}, 1}}} + }; + const std::vector modes = { + {feature_flags::chip_mode_ids::kV3, combinations} + }; + // clang-format on + EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes)); + } + + void assertNumberOfModes(uint32_t num_modes) { + chip_->getAvailableModes([num_modes](const WifiStatus& status, + const std::vector& modes) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + // V2_Aware has 1 mode of operation. + ASSERT_EQ(num_modes, modes.size()); + }); + } + + void findModeAndConfigureForIfaceType(const IfaceType& type) { + // This should be aligned with kInvalidModeId in wifi_chip.cpp. + ChipModeId mode_id = UINT32_MAX; + chip_->getAvailableModes([&mode_id, &type](const WifiStatus& status, + const std::vector& modes) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + for (const auto& mode : modes) { + for (const auto& combination : mode.availableCombinations) { + for (const auto& limit : combination.limits) { + if (limit.types.end() != + std::find(limit.types.begin(), limit.types.end(), type)) { + mode_id = mode.id; + } + } + } + } + }); + ASSERT_NE(UINT32_MAX, mode_id); + + chip_->configureChip(mode_id, [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); + } + + // Returns an empty string on error. + std::string createIface(const IfaceType& type) { + std::string iface_name; + if (type == IfaceType::AP) { + chip_->createApIface( + [&iface_name](const WifiStatus& status, const sp& iface) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(iface.get(), nullptr); + iface->getName([&iface_name](const WifiStatus& status, + const hidl_string& name) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + iface_name = name.c_str(); + }); + } + }); + } else if (type == IfaceType::NAN) { + chip_->createNanIface( + [&iface_name](const WifiStatus& status, + const sp& iface) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(iface.get(), nullptr); + iface->getName([&iface_name](const WifiStatus& status, + const hidl_string& name) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + iface_name = name.c_str(); + }); + } + }); + } else if (type == IfaceType::P2P) { + chip_->createP2pIface( + [&iface_name](const WifiStatus& status, const sp& iface) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(iface.get(), nullptr); + iface->getName([&iface_name](const WifiStatus& status, + const hidl_string& name) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + iface_name = name.c_str(); + }); + } + }); + } else if (type == IfaceType::STA) { + chip_->createStaIface( + [&iface_name](const WifiStatus& status, const sp& iface) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(iface.get(), nullptr); + iface->getName([&iface_name](const WifiStatus& status, + const hidl_string& name) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + iface_name = name.c_str(); + }); + } + }); + } + return iface_name; + } + + void removeIface(const IfaceType& type, const std::string& iface_name) { + if (type == IfaceType::AP) { + chip_->removeApIface(iface_name, [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); + } else if (type == IfaceType::NAN) { + chip_->removeNanIface(iface_name, [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); + } else if (type == IfaceType::P2P) { + chip_->removeP2pIface(iface_name, [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); + } else if (type == IfaceType::STA) { + chip_->removeStaIface(iface_name, [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); + } + } + + bool createRttController() { + bool success = false; + chip_->createRttController_1_4( + NULL, [&success](const WifiStatus& status, const sp& rtt) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(rtt.get(), nullptr); + success = true; + } + }); + return success; + } + + static void subsystemRestartHandler(const std::string& /*error*/) {} + + sp chip_; + ChipId chip_id_ = kFakeChipId; + legacy_hal::wifi_hal_fn fake_func_table_; + std::shared_ptr> iface_tool_{ + new NiceMock}; + std::shared_ptr> legacy_hal_{ + new NiceMock(iface_tool_, fake_func_table_, true)}; + std::shared_ptr> mode_controller_{ + new NiceMock}; + std::shared_ptr> iface_util_{ + new NiceMock(iface_tool_, legacy_hal_)}; + std::shared_ptr> feature_flags_{ + new NiceMock}; + + public: + void SetUp() override { + chip_ = new WifiChip(chip_id_, true, legacy_hal_, mode_controller_, iface_util_, + feature_flags_, subsystemRestartHandler); + + EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_)) + .WillRepeatedly(testing::Return(true)); + EXPECT_CALL(*legacy_hal_, start()) + .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS)); + } + + void TearDown() override { + // Restore default system iface names (This should ideally be using a + // mock). + property_set("wifi.interface", "wlan0"); + property_set("wifi.concurrent.interface", "wlan1"); + property_set("wifi.aware.interface", nullptr); + } +}; + +////////// V1 Iface Combinations //////////// +// Mode 1 - STA + P2P +// Mode 2 - AP +class WifiChipV1IfaceCombinationTest : public WifiChipTest { + public: + void SetUp() override { + setupV1IfaceCombination(); + WifiChipTest::SetUp(); + // V1 has 2 modes of operation. + assertNumberOfModes(2u); + } +}; + +TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); +} + +TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateNan_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_TRUE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateAp_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_TRUE(createIface(IfaceType::AP).empty()); +} + +TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); +} + +TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateSta_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_TRUE(createIface(IfaceType::STA).empty()); +} + +TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateP2p_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_TRUE(createIface(IfaceType::STA).empty()); +} + +TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateNan_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_TRUE(createIface(IfaceType::NAN).empty()); +} + +////////// V1 + Aware Iface Combinations //////////// +// Mode 1 - STA + P2P/NAN +// Mode 2 - AP +class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest { + public: + void SetUp() override { + setupV1_AwareIfaceCombination(); + WifiChipTest::SetUp(); + // V1_Aware has 2 modes of operation. + assertNumberOfModes(2u); + } +}; + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateNan_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateAp_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_TRUE(createIface(IfaceType::AP).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2PNan_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); + ASSERT_TRUE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + const auto p2p_iface_name = createIface(IfaceType::P2P); + ASSERT_FALSE(p2p_iface_name.empty()); + ASSERT_TRUE(createIface(IfaceType::NAN).empty()); + + // After removing P2P iface, NAN iface creation should succeed. + removeIface(IfaceType::P2P, p2p_iface_name); + ASSERT_FALSE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + const auto nan_iface_name = createIface(IfaceType::NAN); + ASSERT_FALSE(nan_iface_name.empty()); + ASSERT_TRUE(createIface(IfaceType::P2P).empty()); + + // After removing NAN iface, P2P iface creation should succeed. + removeIface(IfaceType::NAN, nan_iface_name); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateSta_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_TRUE(createIface(IfaceType::STA).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateP2p_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_TRUE(createIface(IfaceType::STA).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateNan_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_TRUE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowApToSta) { + findModeAndConfigureForIfaceType(IfaceType::AP); + const auto ap_iface_name = createIface(IfaceType::AP); + ASSERT_FALSE(ap_iface_name.empty()); + ASSERT_FALSE(createRttController()); + + removeIface(IfaceType::AP, ap_iface_name); + + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + chip_->selectTxPowerScenario_1_2( + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); }); +} + +TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::AP), "wlan0"); + EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + chip_->selectTxPowerScenario_1_2( + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); }); +} + +////////// V2 + Aware Iface Combinations //////////// +// Mode 1 - STA + STA/AP +// - STA + P2P/NAN +class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest { + public: + void SetUp() override { + setupV2_AwareIfaceCombination(); + WifiChipTest::SetUp(); + // V2_Aware has 1 mode of operation. + assertNumberOfModes(1u); + } +}; + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateP2p_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNan_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateAp_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + ASSERT_TRUE(createIface(IfaceType::STA).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApSta_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_AfterStaApRemove_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + const auto sta_iface_name = createIface(IfaceType::STA); + ASSERT_FALSE(sta_iface_name.empty()); + const auto ap_iface_name = createIface(IfaceType::AP); + ASSERT_FALSE(ap_iface_name.empty()); + + ASSERT_TRUE(createIface(IfaceType::STA).empty()); + + // After removing AP & STA iface, STA iface creation should succeed. + removeIface(IfaceType::STA, sta_iface_name); + removeIface(IfaceType::AP, ap_iface_name); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2PNan_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); + ASSERT_TRUE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_AfterP2pRemove_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + const auto p2p_iface_name = createIface(IfaceType::P2P); + ASSERT_FALSE(p2p_iface_name.empty()); + ASSERT_TRUE(createIface(IfaceType::NAN).empty()); + + // After removing P2P iface, NAN iface creation should succeed. + removeIface(IfaceType::P2P, p2p_iface_name); + ASSERT_FALSE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_AfterNanRemove_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + const auto nan_iface_name = createIface(IfaceType::NAN); + ASSERT_FALSE(nan_iface_name.empty()); + ASSERT_TRUE(createIface(IfaceType::P2P).empty()); + + // After removing NAN iface, P2P iface creation should succeed. + removeIface(IfaceType::NAN, nan_iface_name); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApNan_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_FALSE(createIface(IfaceType::AP).empty()); + ASSERT_TRUE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApP2p_ShouldFail) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_FALSE(createIface(IfaceType::AP).empty()); + ASSERT_TRUE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + const auto p2p_iface_name = createIface(IfaceType::P2P); + ASSERT_FALSE(p2p_iface_name.empty()); + ASSERT_TRUE(createIface(IfaceType::NAN).empty()); + + // After removing P2P iface, NAN iface creation should succeed. + removeIface(IfaceType::P2P, p2p_iface_name); + ASSERT_FALSE(createIface(IfaceType::NAN).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + const auto nan_iface_name = createIface(IfaceType::NAN); + ASSERT_FALSE(nan_iface_name.empty()); + ASSERT_TRUE(createIface(IfaceType::P2P).empty()); + + // After removing NAN iface, P2P iface creation should succeed. + removeIface(IfaceType::NAN, nan_iface_name); + ASSERT_FALSE(createIface(IfaceType::P2P).empty()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_EnsureDifferentIfaceNames) { + findModeAndConfigureForIfaceType(IfaceType::AP); + const auto sta_iface_name = createIface(IfaceType::STA); + const auto ap_iface_name = createIface(IfaceType::AP); + ASSERT_FALSE(sta_iface_name.empty()); + ASSERT_FALSE(ap_iface_name.empty()); + ASSERT_NE(sta_iface_name, ap_iface_name); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlow) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_FALSE(createIface(IfaceType::AP).empty()); + ASSERT_TRUE(createRttController()); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + chip_->selectTxPowerScenario_1_2( + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); }); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) { + findModeAndConfigureForIfaceType(IfaceType::AP); + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); + EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + chip_->selectTxPowerScenario_1_2( + V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF, + [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); }); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveNanOnStaRemove) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + + // Create NAN iface + ASSERT_EQ(createIface(IfaceType::NAN), "wlan0"); + + // We should have 1 nan iface. + chip_->getNanIfaceNames([](const WifiStatus& status, const hidl_vec& iface_names) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + ASSERT_EQ(iface_names.size(), 1u); + ASSERT_EQ(iface_names[0], "wlan0"); + }); + // Retrieve the exact iface object. + sp nan_iface; + chip_->getNanIface("wlan0", + [&nan_iface](const WifiStatus& status, + const sp& iface) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + ASSERT_NE(iface.get(), nullptr); + nan_iface = iface; + }); + + // Remove the STA iface. + removeIface(IfaceType::STA, "wlan0"); + // We should have 0 nan iface now. + chip_->getNanIfaceNames([](const WifiStatus& status, const hidl_vec& iface_names) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + ASSERT_EQ(iface_names.size(), 0u); + }); + // Any operation on the nan iface object should return error now. + nan_iface->getName([](const WifiStatus& status, const std::string& /* iface_name */) { + ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code); + }); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveRttControllerOnStaRemove) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + + // Create RTT controller + sp rtt_controller; + chip_->createRttController_1_4( + NULL, [&rtt_controller](const WifiStatus& status, const sp& rtt) { + if (WifiStatusCode::SUCCESS == status.code) { + ASSERT_NE(rtt.get(), nullptr); + rtt_controller = rtt; + } + }); + + // Remove the STA iface. + removeIface(IfaceType::STA, "wlan0"); + + // Any operation on the rtt controller object should return error now. + rtt_controller->getBoundIface([](const WifiStatus& status, const sp& /* iface */) { + ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, status.code); + }); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) { + property_set("wifi.aware.interface", nullptr); + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + ASSERT_EQ(createIface(IfaceType::NAN), "wlan0"); + removeIface(IfaceType::NAN, "wlan0"); + EXPECT_CALL(*iface_util_, setUpState(testing::_, testing::_)).Times(0); +} + +TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithDedicatedNanIface) { + property_set("wifi.aware.interface", "aware0"); + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + EXPECT_CALL(*iface_util_, ifNameToIndex("aware0")).WillOnce(testing::Return(4)); + EXPECT_CALL(*iface_util_, setUpState("aware0", true)).WillOnce(testing::Return(true)); + ASSERT_EQ(createIface(IfaceType::NAN), "aware0"); + + EXPECT_CALL(*iface_util_, setUpState("aware0", false)).WillOnce(testing::Return(true)); + removeIface(IfaceType::NAN, "aware0"); +} + +////////// V1 Iface Combinations when AP creation is disabled ////////// +class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest { + public: + void SetUp() override { + setupV1_AwareDisabledApIfaceCombination(); + WifiChipTest::SetUp(); + } +}; + +TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_TRUE(createIface(IfaceType::AP).empty()); +} + +////////// V2 Iface Combinations when AP creation is disabled ////////// +class WifiChipV2_AwareDisabledApIfaceCombinationTest : public WifiChipTest { + public: + void SetUp() override { + setupV2_AwareDisabledApIfaceCombination(); + WifiChipTest::SetUp(); + } +}; + +TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, CreateSta_ShouldSucceed) { + findModeAndConfigureForIfaceType(IfaceType::STA); + ASSERT_FALSE(createIface(IfaceType::STA).empty()); + ASSERT_TRUE(createIface(IfaceType::AP).empty()); +} + +////////// Hypothetical Iface Combination with multiple ifaces ////////// +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), "bad0"); + ASSERT_EQ(createIface(IfaceType::STA), "bad1"); + 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"); +} + +TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) { + findModeAndConfigureForIfaceType(IfaceType::STA); + // First AP will be slotted to wlan1. + ASSERT_EQ(createIface(IfaceType::AP), "wlan1"); + // First STA will be slotted to wlan0. + ASSERT_EQ(createIface(IfaceType::STA), "wlan0"); + // All further STA will be slotted to the remaining free indices. + ASSERT_EQ(createIface(IfaceType::STA), "wlan2"); + ASSERT_EQ(createIface(IfaceType::STA), "wlan3"); +} +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp new file mode 100644 index 0000000000..cc9a3340a5 --- /dev/null +++ b/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp @@ -0,0 +1,96 @@ +/* + * 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 +#include +#include + +#undef NAN +#include "wifi_iface_util.h" + +#include "mock_interface_tool.h" +#include "mock_wifi_legacy_hal.h" + +using testing::NiceMock; +using testing::Test; + +namespace { +constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02; +constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc}; +constexpr char kIfaceName[] = "test-wlan0"; + +bool isValidUnicastLocallyAssignedMacAddress(const std::array& mac_address) { + uint8_t first_byte = mac_address[0]; + return (first_byte & 0x3) == kValidUnicastLocallyAssignedMacAddressMask; +} +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace iface_util { +class WifiIfaceUtilTest : public Test { + protected: + std::shared_ptr> iface_tool_{ + new NiceMock}; + legacy_hal::wifi_hal_fn fake_func_table_; + std::shared_ptr> legacy_hal_{ + new NiceMock(iface_tool_, fake_func_table_, true)}; + WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_); +}; + +TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) { + auto mac_address = iface_util_->getOrCreateRandomMacAddress(); + ASSERT_TRUE(isValidUnicastLocallyAssignedMacAddress(mac_address)); + + // All further calls should return the same MAC address. + ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress()); + ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress()); +} + +TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) { + std::array mac_address = {}; + std::copy(std::begin(kMacAddress), std::end(kMacAddress), std::begin(mac_address)); + EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_)) + .WillRepeatedly(testing::Return(true)); + EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_)) + .WillRepeatedly(testing::Return(true)); + + // Register for iface state toggle events. + bool callback_invoked = false; + iface_util::IfaceEventHandlers event_handlers = {}; + event_handlers.on_state_toggle_off_on = + [&callback_invoked](const std::string& /* iface_name */) { callback_invoked = true; }; + iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers); + // Invoke setMacAddress and ensure that the cb is invoked. + ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address)); + ASSERT_TRUE(callback_invoked); + + // Unregister for iface state toggle events. + callback_invoked = false; + iface_util_->unregisterIfaceEventHandlers(kIfaceName); + // Invoke setMacAddress and ensure that the cb is not invoked. + ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address)); + ASSERT_FALSE(callback_invoked); +} +} // namespace iface_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp new file mode 100644 index 0000000000..c7c566bec1 --- /dev/null +++ b/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp @@ -0,0 +1,132 @@ +/* + * 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 +#include +#include +#include + +#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38 +#include "wifi_nan_iface.h" + +#include "mock_interface_tool.h" +#include "mock_wifi_feature_flags.h" +#include "mock_wifi_iface_util.h" +#include "mock_wifi_legacy_hal.h" + +using testing::NiceMock; +using testing::Return; +using testing::Test; + +namespace { +constexpr char kIfaceName[] = "mockWlan0"; +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { + +using android::hardware::wifi::V1_2::NanDataPathConfirmInd; + +bool CaptureIfaceEventHandlers(const std::string& /* iface_name*/, + iface_util::IfaceEventHandlers in_iface_event_handlers, + iface_util::IfaceEventHandlers* out_iface_event_handlers) { + *out_iface_event_handlers = in_iface_event_handlers; + return true; +} + +class MockNanIfaceEventCallback : public V1_5::IWifiNanIfaceEventCallback { + public: + MockNanIfaceEventCallback() = default; + + MOCK_METHOD3(notifyCapabilitiesResponse, + Return(uint16_t, const WifiNanStatus&, + const android::hardware::wifi::V1_0::NanCapabilities&)); + MOCK_METHOD2(notifyEnableResponse, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyConfigResponse, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyDisableResponse, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD3(notifyStartPublishResponse, Return(uint16_t, const WifiNanStatus&, uint8_t)); + MOCK_METHOD2(notifyStopPublishResponse, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD3(notifyStartSubscribeResponse, + Return(uint16_t, const WifiNanStatus&, uint8_t)); + MOCK_METHOD2(notifyStopSubscribeResponse, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyTransmitFollowupResponse, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyCreateDataInterfaceResponse, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyDeleteDataInterfaceResponse, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD3(notifyInitiateDataPathResponse, + Return(uint16_t, const WifiNanStatus&, uint32_t)); + MOCK_METHOD2(notifyRespondToDataPathIndicationResponse, + Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD2(notifyTerminateDataPathResponse, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD1(eventClusterEvent, Return(const NanClusterEventInd&)); + MOCK_METHOD1(eventDisabled, Return(const WifiNanStatus&)); + MOCK_METHOD2(eventPublishTerminated, Return(uint8_t, const WifiNanStatus&)); + MOCK_METHOD2(eventSubscribeTerminated, Return(uint8_t, const WifiNanStatus&)); + MOCK_METHOD1(eventMatch, Return(const NanMatchInd&)); + MOCK_METHOD2(eventMatchExpired, Return(uint8_t, uint32_t)); + MOCK_METHOD1(eventFollowupReceived, Return(const NanFollowupReceivedInd&)); + MOCK_METHOD2(eventTransmitFollowup, Return(uint16_t, const WifiNanStatus&)); + MOCK_METHOD1(eventDataPathRequest, Return(const NanDataPathRequestInd&)); + MOCK_METHOD1(eventDataPathConfirm, + Return(const android::hardware::wifi::V1_0::NanDataPathConfirmInd&)); + MOCK_METHOD1(eventDataPathTerminated, Return(uint32_t)); + MOCK_METHOD1(eventDataPathConfirm_1_2, Return(const NanDataPathConfirmInd&)); + MOCK_METHOD1(eventDataPathScheduleUpdate, Return(const NanDataPathScheduleUpdateInd&)); + MOCK_METHOD3(notifyCapabilitiesResponse_1_5, + Return(uint16_t, const WifiNanStatus&, const V1_5::NanCapabilities&)); +}; + +class WifiNanIfaceTest : public Test { + protected: + legacy_hal::wifi_hal_fn fake_func_table_; + std::shared_ptr> iface_tool_{ + new NiceMock}; + std::shared_ptr> legacy_hal_{ + new NiceMock(iface_tool_, fake_func_table_, true)}; + std::shared_ptr> iface_util_{ + new NiceMock(iface_tool_, legacy_hal_)}; +}; + +TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) { + iface_util::IfaceEventHandlers captured_iface_event_handlers = {}; + EXPECT_CALL(*legacy_hal_, nanRegisterCallbackHandlers(testing::_, testing::_)) + .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS)); + EXPECT_CALL(*iface_util_, registerIfaceEventHandlers(testing::_, testing::_)) + .WillOnce(testing::Invoke(bind(CaptureIfaceEventHandlers, std::placeholders::_1, + std::placeholders::_2, &captured_iface_event_handlers))); + sp nan_iface = new WifiNanIface(kIfaceName, false, legacy_hal_, iface_util_); + + // Register a mock nan event callback. + sp> mock_event_callback{ + new NiceMock}; + nan_iface->registerEventCallback(mock_event_callback, [](const WifiStatus& status) { + ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); + }); + // Ensure that the eventDisabled() function in mock callback will be + // invoked. + WifiNanStatus expected_nan_status = {NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""}; + EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status)).Times(1); + + // Trigger the iface state toggle callback. + captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName); +} +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi.cpp b/wifi/1.6/default/wifi.cpp new file mode 100644 index 0000000000..c302ce2434 --- /dev/null +++ b/wifi/1.6/default/wifi.cpp @@ -0,0 +1,294 @@ +/* + * 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. + */ + +#include + +#include "hidl_return_util.h" +#include "wifi.h" +#include "wifi_status_util.h" + +namespace { +// Starting Chip ID, will be assigned to primary chip +static constexpr android::hardware::wifi::V1_0::ChipId kPrimaryChipId = 0; +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using hidl_return_util::validateAndCall; +using hidl_return_util::validateAndCallWithLock; + +Wifi::Wifi(const std::shared_ptr iface_tool, + const std::shared_ptr legacy_hal_factory, + const std::shared_ptr mode_controller, + const std::shared_ptr feature_flags) + : iface_tool_(iface_tool), + legacy_hal_factory_(legacy_hal_factory), + mode_controller_(mode_controller), + feature_flags_(feature_flags), + run_state_(RunState::STOPPED) {} + +bool Wifi::isValid() { + // This object is always valid. + return true; +} + +Return Wifi::registerEventCallback(const sp& event_callback, + registerEventCallback_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, + &Wifi::registerEventCallbackInternal, hidl_status_cb, event_callback); +} + +Return Wifi::registerEventCallback_1_5(const sp& event_callback, + registerEventCallback_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, + &Wifi::registerEventCallbackInternal_1_5, hidl_status_cb, + event_callback); +} + +Return Wifi::isStarted() { + return run_state_ != RunState::STOPPED; +} + +Return Wifi::start(start_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal, + hidl_status_cb); +} + +Return Wifi::stop(stop_cb hidl_status_cb) { + return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal, + hidl_status_cb); +} + +Return Wifi::getChipIds(getChipIds_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipIdsInternal, + hidl_status_cb); +} + +Return Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipInternal, + hidl_status_cb, chip_id); +} + +Return Wifi::debug(const hidl_handle& handle, const hidl_vec&) { + LOG(INFO) << "-----------Debug is called----------------"; + if (chips_.size() == 0) { + return Void(); + } + + for (sp chip : chips_) { + if (!chip.get()) continue; + + chip->debug(handle, {}); + } + return Void(); +} + +WifiStatus Wifi::registerEventCallbackInternal( + const sp& event_callback __unused) { + // Deprecated support for this callback. + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus Wifi::registerEventCallbackInternal_1_5( + const sp& event_callback) { + if (!event_cb_handler_.addCallback(event_callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus Wifi::startInternal() { + if (run_state_ == RunState::STARTED) { + return createWifiStatus(WifiStatusCode::SUCCESS); + } else if (run_state_ == RunState::STOPPING) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping"); + } + WifiStatus wifi_status = initializeModeControllerAndLegacyHal(); + if (wifi_status.code == WifiStatusCode::SUCCESS) { + // Register the callback for subsystem restart + const auto& on_subsystem_restart_callback = [this](const std::string& error) { + WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + LOG(INFO) << "Attempting to invoke onSubsystemRestart " + "callback"; + if (!callback->onSubsystemRestart(wifi_status).isOk()) { + LOG(ERROR) << "Failed to invoke onSubsystemRestart callback"; + } else { + LOG(INFO) << "Succeeded to invoke onSubsystemRestart " + "callback"; + } + } + }; + + // Create the chip instance once the HAL is started. + android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId; + for (auto& hal : legacy_hals_) { + chips_.push_back( + new WifiChip(chipId, chipId == kPrimaryChipId, hal, mode_controller_, + std::make_shared(iface_tool_, hal), + feature_flags_, on_subsystem_restart_callback)); + chipId++; + } + run_state_ = RunState::STARTED; + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onStart().isOk()) { + LOG(ERROR) << "Failed to invoke onStart callback"; + }; + } + LOG(INFO) << "Wifi HAL started"; + } else { + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onFailure(wifi_status).isOk()) { + LOG(ERROR) << "Failed to invoke onFailure callback"; + } + } + LOG(ERROR) << "Wifi HAL start failed"; + // Clear the event callback objects since the HAL start failed. + event_cb_handler_.invalidate(); + } + return wifi_status; +} + +WifiStatus Wifi::stopInternal( + /* NONNULL */ std::unique_lock* lock) { + if (run_state_ == RunState::STOPPED) { + return createWifiStatus(WifiStatusCode::SUCCESS); + } else if (run_state_ == RunState::STOPPING) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping"); + } + // Clear the chip object and its child objects since the HAL is now + // stopped. + for (auto& chip : chips_) { + if (chip.get()) { + chip->invalidate(); + chip.clear(); + } + } + chips_.clear(); + WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock); + if (wifi_status.code == WifiStatusCode::SUCCESS) { + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onStop().isOk()) { + LOG(ERROR) << "Failed to invoke onStop callback"; + }; + } + LOG(INFO) << "Wifi HAL stopped"; + } else { + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onFailure(wifi_status).isOk()) { + LOG(ERROR) << "Failed to invoke onFailure callback"; + } + } + LOG(ERROR) << "Wifi HAL stop failed"; + } + // Clear the event callback objects since the HAL is now stopped. + event_cb_handler_.invalidate(); + return wifi_status; +} + +std::pair> Wifi::getChipIdsInternal() { + std::vector chip_ids; + + for (auto& chip : chips_) { + ChipId chip_id = getChipIdFromWifiChip(chip); + if (chip_id != UINT32_MAX) chip_ids.emplace_back(chip_id); + } + return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)}; +} + +std::pair> Wifi::getChipInternal(ChipId chip_id) { + for (auto& chip : chips_) { + ChipId cand_id = getChipIdFromWifiChip(chip); + if ((cand_id != UINT32_MAX) && (cand_id == chip_id)) + return {createWifiStatus(WifiStatusCode::SUCCESS), chip}; + } + + return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; +} + +WifiStatus Wifi::initializeModeControllerAndLegacyHal() { + if (!mode_controller_->initialize()) { + LOG(ERROR) << "Failed to initialize firmware mode controller"; + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + + legacy_hals_ = legacy_hal_factory_->getHals(); + if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + int index = 0; // for failure log + for (auto& hal : legacy_hals_) { + legacy_hal::wifi_error legacy_status = hal->initialize(); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + // Currently WifiLegacyHal::initialize does not allocate extra mem, + // only initializes the function table. If this changes, need to + // implement WifiLegacyHal::deinitialize and deinitalize the + // HALs already initialized + LOG(ERROR) << "Failed to initialize legacy HAL index: " << index + << " error: " << legacyErrorToString(legacy_status); + return createWifiStatusFromLegacyError(legacy_status); + } + index++; + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController( + /* NONNULL */ std::unique_lock* lock) { + legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS; + int index = 0; + + run_state_ = RunState::STOPPING; + for (auto& hal : legacy_hals_) { + legacy_hal::wifi_error tmp = hal->stop(lock, [&]() {}); + if (tmp != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to stop legacy HAL index: " << index + << " error: " << legacyErrorToString(legacy_status); + legacy_status = tmp; + } + index++; + } + run_state_ = RunState::STOPPED; + + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "One or more legacy HALs failed to stop"; + return createWifiStatusFromLegacyError(legacy_status); + } + if (!mode_controller_->deinitialize()) { + LOG(ERROR) << "Failed to deinitialize firmware mode controller"; + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +ChipId Wifi::getChipIdFromWifiChip(sp& chip) { + ChipId chip_id = UINT32_MAX; + if (chip.get()) { + chip->getId([&](WifiStatus status, uint32_t id) { + if (status.code == WifiStatusCode::SUCCESS) { + chip_id = id; + } + }); + } + + return chip_id; +} +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi.h b/wifi/1.6/default/wifi.h new file mode 100644 index 0000000000..435358e797 --- /dev/null +++ b/wifi/1.6/default/wifi.h @@ -0,0 +1,105 @@ +/* + * 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. + */ + +#ifndef WIFI_H_ +#define WIFI_H_ + +// HACK: NAN is a macro defined in math.h, which can be included in various +// headers. This wifi HAL uses an enum called NAN, which does not compile when +// the macro is defined. Undefine NAN to work around it. +#undef NAN +#include + +#include +#include +#include + +#include "hidl_callback_util.h" +#include "wifi_chip.h" +#include "wifi_feature_flags.h" +#include "wifi_legacy_hal.h" +#include "wifi_legacy_hal_factory.h" +#include "wifi_mode_controller.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { + +/** + * Root HIDL interface object used to control the Wifi HAL. + */ +class Wifi : public V1_6::IWifi { + public: + Wifi(const std::shared_ptr iface_tool, + const std::shared_ptr legacy_hal_factory, + const std::shared_ptr mode_controller, + const std::shared_ptr feature_flags); + + bool isValid(); + + // HIDL methods exposed. + Return registerEventCallback(const sp& event_callback, + registerEventCallback_cb hidl_status_cb) override; + Return registerEventCallback_1_5(const sp& event_callback, + registerEventCallback_1_5_cb hidl_status_cb) override; + Return isStarted() override; + Return start(start_cb hidl_status_cb) override; + Return stop(stop_cb hidl_status_cb) override; + Return getChipIds(getChipIds_cb hidl_status_cb) override; + Return getChip(ChipId chip_id, getChip_cb hidl_status_cb) override; + Return debug(const hidl_handle& handle, const hidl_vec& options) override; + + private: + enum class RunState { STOPPED, STARTED, STOPPING }; + + // Corresponding worker functions for the HIDL methods. + WifiStatus registerEventCallbackInternal( + const sp& event_callback __unused); + WifiStatus registerEventCallbackInternal_1_5( + const sp& event_callback); + WifiStatus startInternal(); + WifiStatus stopInternal(std::unique_lock* lock); + std::pair> getChipIdsInternal(); + std::pair> getChipInternal(ChipId chip_id); + + WifiStatus initializeModeControllerAndLegacyHal(); + WifiStatus stopLegacyHalAndDeinitializeModeController( + std::unique_lock* lock); + ChipId getChipIdFromWifiChip(sp& chip); + + // Instance is created in this root level |IWifi| HIDL interface object + // and shared with all the child HIDL interface objects. + std::shared_ptr iface_tool_; + std::shared_ptr legacy_hal_factory_; + std::shared_ptr mode_controller_; + std::vector> legacy_hals_; + std::shared_ptr feature_flags_; + RunState run_state_; + std::vector> chips_; + hidl_callback_util::HidlCallbackHandler event_cb_handler_; + + DISALLOW_COPY_AND_ASSIGN(Wifi); +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_H_ diff --git a/wifi/1.6/default/wifi_ap_iface.cpp b/wifi/1.6/default/wifi_ap_iface.cpp new file mode 100644 index 0000000000..b2957db13f --- /dev/null +++ b/wifi/1.6/default/wifi_ap_iface.cpp @@ -0,0 +1,204 @@ +/* + * 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. + */ + +#include + +#include "hidl_return_util.h" +#include "hidl_struct_util.h" +#include "wifi_ap_iface.h" +#include "wifi_status_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using hidl_return_util::validateAndCall; + +WifiApIface::WifiApIface(const std::string& ifname, const std::vector& instances, + const std::weak_ptr legacy_hal, + const std::weak_ptr iface_util) + : ifname_(ifname), + instances_(instances), + legacy_hal_(legacy_hal), + iface_util_(iface_util), + is_valid_(true) {} + +void WifiApIface::invalidate() { + legacy_hal_.reset(); + is_valid_ = false; +} + +bool WifiApIface::isValid() { + return is_valid_; +} + +std::string WifiApIface::getName() { + return ifname_; +} + +void WifiApIface::removeInstance(std::string instance) { + instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end()); +} + +Return WifiApIface::getName(getName_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::getNameInternal, hidl_status_cb); +} + +Return WifiApIface::getType(getType_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::getTypeInternal, hidl_status_cb); +} + +Return WifiApIface::setCountryCode(const hidl_array& code, + setCountryCode_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::setCountryCodeInternal, hidl_status_cb, code); +} + +Return WifiApIface::getValidFrequenciesForBand(V1_0::WifiBand band, + getValidFrequenciesForBand_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::getValidFrequenciesForBandInternal, hidl_status_cb, band); +} + +Return WifiApIface::setMacAddress(const hidl_array& mac, + setMacAddress_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::setMacAddressInternal, hidl_status_cb, mac); +} + +Return WifiApIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::getFactoryMacAddressInternal, hidl_status_cb, + instances_.size() > 0 ? instances_[0] : ifname_); +} + +Return WifiApIface::resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::resetToFactoryMacAddressInternal, hidl_status_cb); +} + +Return WifiApIface::getBridgedInstances(getBridgedInstances_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::getBridgedInstancesInternal, hidl_status_cb); +} + +std::pair WifiApIface::getNameInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; +} + +std::pair WifiApIface::getTypeInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::AP}; +} + +WifiStatus WifiApIface::setCountryCodeInternal(const std::array& code) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode( + instances_.size() > 0 ? instances_[0] : ifname_, code); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair> +WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) { + static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch"); + legacy_hal::wifi_error legacy_status; + std::vector valid_frequencies; + std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand( + instances_.size() > 0 ? instances_[0] : ifname_, + hidl_struct_util::convertHidlWifiBandToLegacy(band)); + return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies}; +} + +WifiStatus WifiApIface::setMacAddressInternal(const std::array& mac) { + // Support random MAC up to 2 interfaces + if (instances_.size() == 2) { + int rbyte = 1; + for (auto const& intf : instances_) { + std::array rmac = mac; + // reverse the bits to avoid collision + rmac[rbyte] = 0xff - rmac[rbyte]; + if (!iface_util_.lock()->setMacAddress(intf, rmac)) { + LOG(INFO) << "Failed to set random mac address on " << intf; + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + rbyte++; + } + } + // It also needs to set mac address for bridged interface, otherwise the mac + // address of bridged interface will be changed after one of instance + // down. + if (!iface_util_.lock()->setMacAddress(ifname_, mac)) { + LOG(ERROR) << "Fail to config MAC for interface " << ifname_; + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +std::pair> WifiApIface::getFactoryMacAddressInternal( + const std::string& ifaceName) { + std::array mac = iface_util_.lock()->getFactoryMacAddress(ifaceName); + if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; +} + +WifiStatus WifiApIface::resetToFactoryMacAddressInternal() { + std::pair> getMacResult; + if (instances_.size() == 2) { + for (auto const& intf : instances_) { + getMacResult = getFactoryMacAddressInternal(intf); + LOG(DEBUG) << "Reset MAC to factory MAC on " << intf; + if (getMacResult.first.code != WifiStatusCode::SUCCESS || + !iface_util_.lock()->setMacAddress(intf, getMacResult.second)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + } + // It needs to set mac address for bridged interface, otherwise the mac + // address of the bridged interface will be changed after one of the + // instance down. Thus we are generating a random MAC address for the + // bridged interface even if we got the request to reset the Factory + // MAC. Since the bridged interface is an internal interface for the + // operation of bpf and others networking operation. + if (!iface_util_.lock()->setMacAddress(ifname_, + iface_util_.lock()->createRandomMacAddress())) { + LOG(ERROR) << "Fail to config MAC for bridged interface " << ifname_; + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + } else { + getMacResult = getFactoryMacAddressInternal(ifname_); + LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_; + if (getMacResult.first.code != WifiStatusCode::SUCCESS || + !iface_util_.lock()->setMacAddress(ifname_, getMacResult.second)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +std::pair> WifiApIface::getBridgedInstancesInternal() { + std::vector instances; + for (const auto& instance_name : instances_) { + instances.push_back(instance_name); + } + return {createWifiStatus(WifiStatusCode::SUCCESS), instances}; +} +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_ap_iface.h b/wifi/1.6/default/wifi_ap_iface.h new file mode 100644 index 0000000000..d1c06424df --- /dev/null +++ b/wifi/1.6/default/wifi_ap_iface.h @@ -0,0 +1,89 @@ +/* + * 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. + */ + +#ifndef WIFI_AP_IFACE_H_ +#define WIFI_AP_IFACE_H_ + +#include +#include + +#include "wifi_iface_util.h" +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; + +/** + * HIDL interface object used to control a AP Iface instance. + */ +class WifiApIface : public V1_5::IWifiApIface { + public: + WifiApIface(const std::string& ifname, const std::vector& instances, + const std::weak_ptr legacy_hal, + const std::weak_ptr iface_util); + // Refer to |WifiChip::invalidate()|. + void invalidate(); + bool isValid(); + std::string getName(); + void removeInstance(std::string instance); + + // HIDL methods exposed. + Return getName(getName_cb hidl_status_cb) override; + Return getType(getType_cb hidl_status_cb) override; + Return setCountryCode(const hidl_array& code, + setCountryCode_cb hidl_status_cb) override; + Return getValidFrequenciesForBand(V1_0::WifiBand band, + getValidFrequenciesForBand_cb hidl_status_cb) override; + Return setMacAddress(const hidl_array& mac, + setMacAddress_cb hidl_status_cb) override; + Return getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override; + Return resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) override; + + Return getBridgedInstances(getBridgedInstances_cb hidl_status_cb) override; + + private: + // Corresponding worker functions for the HIDL methods. + std::pair getNameInternal(); + std::pair getTypeInternal(); + WifiStatus setCountryCodeInternal(const std::array& code); + std::pair> getValidFrequenciesForBandInternal( + V1_0::WifiBand band); + WifiStatus setMacAddressInternal(const std::array& mac); + std::pair> getFactoryMacAddressInternal( + const std::string& ifaceName); + WifiStatus resetToFactoryMacAddressInternal(); + std::pair> getBridgedInstancesInternal(); + + std::string ifname_; + std::vector instances_; + std::weak_ptr legacy_hal_; + std::weak_ptr iface_util_; + bool is_valid_; + + DISALLOW_COPY_AND_ASSIGN(WifiApIface); +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_AP_IFACE_H_ diff --git a/wifi/1.6/default/wifi_chip.cpp b/wifi/1.6/default/wifi_chip.cpp new file mode 100644 index 0000000000..c1ce766a4f --- /dev/null +++ b/wifi/1.6/default/wifi_chip.cpp @@ -0,0 +1,1903 @@ +/* + * 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. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "hidl_return_util.h" +#include "hidl_struct_util.h" +#include "wifi_chip.h" +#include "wifi_status_util.h" + +#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-" + +namespace { +using android::sp; +using android::base::unique_fd; +using android::hardware::hidl_string; +using android::hardware::hidl_vec; +using android::hardware::wifi::V1_0::ChipModeId; +using android::hardware::wifi::V1_0::IfaceType; +using android::hardware::wifi::V1_0::IWifiChip; + +constexpr char kCpioMagic[] = "070701"; +constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3; +constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10; +constexpr uint32_t kMaxRingBufferFileNum = 20; +constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/"; +constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface"; +constexpr char kNoActiveWlanIfaceNamePropertyValue[] = ""; +constexpr unsigned kMaxWlanIfaces = 5; +constexpr char kApBridgeIfacePrefix[] = "ap_br_"; + +template +void invalidateAndClear(std::vector>& ifaces, sp iface) { + iface->invalidate(); + ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end()); +} + +template +void invalidateAndClearAll(std::vector>& ifaces) { + for (const auto& iface : ifaces) { + iface->invalidate(); + } + ifaces.clear(); +} + +template +std::vector getNames(std::vector>& ifaces) { + std::vector names; + for (const auto& iface : ifaces) { + names.emplace_back(iface->getName()); + } + return names; +} + +template +sp findUsingName(std::vector>& ifaces, const std::string& name) { + std::vector names; + for (const auto& iface : ifaces) { + if (name == iface->getName()) { + return iface; + } + } + return nullptr; +} + +std::string getWlanIfaceName(unsigned idx) { + if (idx >= kMaxWlanIfaces) { + CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces; + return {}; + } + + std::array buffer; + if (idx == 0 || idx == 1) { + const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface"; + auto res = property_get(altPropName, buffer.data(), nullptr); + if (res > 0) 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(); + + return "wlan" + std::to_string(idx); +} + +// Returns the dedicated iface name if defined. +// Returns two ifaces in bridged mode. +std::vector getPredefinedApIfaceNames(bool is_bridged) { + std::vector ifnames; + std::array buffer; + buffer.fill(0); + if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) { + return ifnames; + } + ifnames.push_back(buffer.data()); + if (is_bridged) { + buffer.fill(0); + if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) { + return ifnames; + } + ifnames.push_back(buffer.data()); + } + return ifnames; +} + +std::string getPredefinedP2pIfaceName() { + std::array primaryIfaceName; + char p2pParentIfname[100]; + std::string p2pDevIfName = ""; + std::array buffer; + property_get("wifi.direct.interface", buffer.data(), "p2p0"); + if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) { + /* Get the p2p parent interface name from p2p device interface name set + * in property */ + strncpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX), + strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)); + if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) { + return buffer.data(); + } + /* Check if the parent interface derived from p2p device interface name + * is active */ + if (strncmp(p2pParentIfname, primaryIfaceName.data(), + strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) { + /* + * Update the predefined p2p device interface parent interface name + * with current active wlan interface + */ + p2pDevIfName += P2P_MGMT_DEVICE_PREFIX; + p2pDevIfName += primaryIfaceName.data(); + LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str(); + return p2pDevIfName; + } + } + return buffer.data(); +} + +// Returns the dedicated iface name if one is defined. +std::string getPredefinedNanIfaceName() { + std::array buffer; + if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) { + return {}; + } + return buffer.data(); +} + +void setActiveWlanIfaceNameProperty(const std::string& ifname) { + auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data()); + if (res != 0) { + PLOG(ERROR) << "Failed to set active wlan iface name property"; + } +} + +// delete files that meet either conditions: +// 1. older than a predefined time in the wifi tombstone dir. +// 2. Files in excess to a predefined amount, starting from the oldest ones +bool removeOldFilesInternal() { + time_t now = time(0); + const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds; + std::unique_ptr dir_dump(opendir(kTombstoneFolderPath), closedir); + if (!dir_dump) { + PLOG(ERROR) << "Failed to open directory"; + return false; + } + struct dirent* dp; + bool success = true; + std::list> valid_files; + while ((dp = readdir(dir_dump.get()))) { + if (dp->d_type != DT_REG) { + continue; + } + std::string cur_file_name(dp->d_name); + struct stat cur_file_stat; + std::string cur_file_path = kTombstoneFolderPath + cur_file_name; + if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) { + PLOG(ERROR) << "Failed to get file stat for " << cur_file_path; + success = false; + continue; + } + const time_t cur_file_time = cur_file_stat.st_mtime; + valid_files.push_back(std::pair(cur_file_time, cur_file_path)); + } + valid_files.sort(); // sort the list of files by last modified time from + // small to big. + uint32_t cur_file_count = valid_files.size(); + for (auto cur_file : valid_files) { + if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) { + if (unlink(cur_file.second.c_str()) != 0) { + PLOG(ERROR) << "Error deleting file"; + success = false; + } + cur_file_count--; + } else { + break; + } + } + return success; +} + +// Helper function for |cpioArchiveFilesInDir| +bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) { + std::array read_buf; + ssize_t llen = + sprintf(read_buf.data(), "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X", + kCpioMagic, static_cast(st.st_ino), st.st_mode, st.st_uid, st.st_gid, + static_cast(st.st_nlink), static_cast(st.st_mtime), + static_cast(st.st_size), major(st.st_dev), minor(st.st_dev), + major(st.st_rdev), minor(st.st_rdev), static_cast(file_name_len), 0); + if (write(out_fd, read_buf.data(), llen) == -1) { + PLOG(ERROR) << "Error writing cpio header to file " << file_name; + return false; + } + if (write(out_fd, file_name, file_name_len) == -1) { + PLOG(ERROR) << "Error writing filename to file " << file_name; + return false; + } + + // NUL Pad header up to 4 multiple bytes. + llen = (llen + file_name_len) % 4; + if (llen != 0) { + const uint32_t zero = 0; + if (write(out_fd, &zero, 4 - llen) == -1) { + PLOG(ERROR) << "Error padding 0s to file " << file_name; + return false; + } + } + return true; +} + +// Helper function for |cpioArchiveFilesInDir| +size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) { + // writing content of file + std::array read_buf; + ssize_t llen = st.st_size; + size_t n_error = 0; + while (llen > 0) { + ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size()); + if (bytes_read == -1) { + PLOG(ERROR) << "Error reading file"; + return ++n_error; + } + llen -= bytes_read; + if (write(out_fd, read_buf.data(), bytes_read) == -1) { + PLOG(ERROR) << "Error writing data to file"; + return ++n_error; + } + if (bytes_read == 0) { // this should never happen, but just in case + // to unstuck from while loop + PLOG(ERROR) << "Unexpected read result"; + n_error++; + break; + } + } + llen = st.st_size % 4; + if (llen != 0) { + const uint32_t zero = 0; + if (write(out_fd, &zero, 4 - llen) == -1) { + PLOG(ERROR) << "Error padding 0s to file"; + return ++n_error; + } + } + return n_error; +} + +// Helper function for |cpioArchiveFilesInDir| +bool cpioWriteFileTrailer(int out_fd) { + std::array read_buf; + read_buf.fill(0); + if (write(out_fd, read_buf.data(), + sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0) + 4) == -1) { + PLOG(ERROR) << "Error writing trailing bytes"; + return false; + } + return true; +} + +// Archives all files in |input_dir| and writes result into |out_fd| +// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive" +// portion +size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) { + struct dirent* dp; + size_t n_error = 0; + std::unique_ptr dir_dump(opendir(input_dir), closedir); + if (!dir_dump) { + PLOG(ERROR) << "Failed to open directory"; + return ++n_error; + } + while ((dp = readdir(dir_dump.get()))) { + if (dp->d_type != DT_REG) { + continue; + } + std::string cur_file_name(dp->d_name); + struct stat st; + const std::string cur_file_path = kTombstoneFolderPath + cur_file_name; + if (stat(cur_file_path.c_str(), &st) == -1) { + PLOG(ERROR) << "Failed to get file stat for " << cur_file_path; + n_error++; + continue; + } + const int fd_read = open(cur_file_path.c_str(), O_RDONLY); + if (fd_read == -1) { + PLOG(ERROR) << "Failed to open file " << cur_file_path; + n_error++; + continue; + } + std::string file_name_with_last_modified_time = + cur_file_name + "-" + std::to_string(st.st_mtime); + // string.size() does not include the null terminator. The cpio FreeBSD + // file header expects the null character to be included in the length. + const size_t file_name_len = file_name_with_last_modified_time.size() + 1; + unique_fd file_auto_closer(fd_read); + if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(), + file_name_len)) { + return ++n_error; + } + size_t write_error = cpioWriteFileContent(fd_read, out_fd, st); + if (write_error) { + return n_error + write_error; + } + } + if (!cpioWriteFileTrailer(out_fd)) { + return ++n_error; + } + return n_error; +} + +// Helper function to create a non-const char*. +std::vector makeCharVec(const std::string& str) { + std::vector vec(str.size() + 1); + vec.assign(str.begin(), str.end()); + vec.push_back('\0'); + return vec; +} + +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using hidl_return_util::validateAndCall; +using hidl_return_util::validateAndCallWithLock; + +WifiChip::WifiChip(ChipId chip_id, bool is_primary, + const std::weak_ptr legacy_hal, + const std::weak_ptr mode_controller, + const std::shared_ptr iface_util, + const std::weak_ptr feature_flags, + const std::function& handler) + : chip_id_(chip_id), + legacy_hal_(legacy_hal), + mode_controller_(mode_controller), + iface_util_(iface_util), + is_valid_(true), + current_mode_id_(feature_flags::chip_mode_ids::kInvalid), + modes_(feature_flags.lock()->getChipModes(is_primary)), + debug_ring_buffer_cb_registered_(false), + subsystemCallbackHandler_(handler) { + setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue); +} + +void WifiChip::invalidate() { + if (!writeRingbufferFilesInternal()) { + LOG(ERROR) << "Error writing files to flash"; + } + invalidateAndRemoveAllIfaces(); + setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue); + legacy_hal_.reset(); + event_cb_handler_.invalidate(); + is_valid_ = false; +} + +bool WifiChip::isValid() { + return is_valid_; +} + +std::set> WifiChip::getEventCallbacks() { + return event_cb_handler_.getCallbacks(); +} + +Return WifiChip::getId(getId_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal, + hidl_status_cb); +} + +// Deprecated support for this callback +Return WifiChip::registerEventCallback(const sp& event_callback, + registerEventCallback_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::registerEventCallbackInternal, hidl_status_cb, + event_callback); +} + +Return WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getCapabilitiesInternal, hidl_status_cb); +} + +Return WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getAvailableModesInternal, hidl_status_cb); +} + +Return WifiChip::configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) { + return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::configureChipInternal, hidl_status_cb, mode_id); +} + +Return WifiChip::getMode(getMode_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getModeInternal, hidl_status_cb); +} + +Return WifiChip::requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::requestChipDebugInfoInternal, hidl_status_cb); +} + +Return WifiChip::requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::requestDriverDebugDumpInternal, hidl_status_cb); +} + +Return WifiChip::requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::requestFirmwareDebugDumpInternal, hidl_status_cb); +} + +Return WifiChip::createApIface(createApIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::createApIfaceInternal, hidl_status_cb); +} + +Return WifiChip::createBridgedApIface(createBridgedApIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::createBridgedApIfaceInternal, hidl_status_cb); +} + +Return WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getApIfaceNamesInternal, hidl_status_cb); +} + +Return WifiChip::getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getApIfaceInternal, hidl_status_cb, ifname); +} + +Return WifiChip::removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::removeApIfaceInternal, hidl_status_cb, ifname); +} + +Return WifiChip::removeIfaceInstanceFromBridgedApIface( + const hidl_string& ifname, const hidl_string& ifInstanceName, + removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, hidl_status_cb, + ifname, ifInstanceName); +} + +Return WifiChip::createNanIface(createNanIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::createNanIfaceInternal, hidl_status_cb); +} + +Return WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getNanIfaceNamesInternal, hidl_status_cb); +} + +Return WifiChip::getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getNanIfaceInternal, hidl_status_cb, ifname); +} + +Return WifiChip::removeNanIface(const hidl_string& ifname, removeNanIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::removeNanIfaceInternal, hidl_status_cb, ifname); +} + +Return WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::createP2pIfaceInternal, hidl_status_cb); +} + +Return WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb); +} + +Return WifiChip::getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getP2pIfaceInternal, hidl_status_cb, ifname); +} + +Return WifiChip::removeP2pIface(const hidl_string& ifname, removeP2pIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::removeP2pIfaceInternal, hidl_status_cb, ifname); +} + +Return WifiChip::createStaIface(createStaIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::createStaIfaceInternal, hidl_status_cb); +} + +Return WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getStaIfaceNamesInternal, hidl_status_cb); +} + +Return WifiChip::getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getStaIfaceInternal, hidl_status_cb, ifname); +} + +Return WifiChip::removeStaIface(const hidl_string& ifname, removeStaIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::removeStaIfaceInternal, hidl_status_cb, ifname); +} + +Return WifiChip::createRttController(const sp& bound_iface, + createRttController_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::createRttControllerInternal, hidl_status_cb, bound_iface); +} + +Return WifiChip::getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getDebugRingBuffersStatusInternal, hidl_status_cb); +} + +Return WifiChip::startLoggingToDebugRingBuffer( + const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, + uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes, + startLoggingToDebugRingBuffer_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::startLoggingToDebugRingBufferInternal, hidl_status_cb, + ring_name, verbose_level, max_interval_in_sec, min_data_size_in_bytes); +} + +Return WifiChip::forceDumpToDebugRingBuffer(const hidl_string& ring_name, + forceDumpToDebugRingBuffer_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::forceDumpToDebugRingBufferInternal, hidl_status_cb, + ring_name); +} + +Return WifiChip::flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::flushRingBufferToFileInternal, hidl_status_cb); +} + +Return WifiChip::stopLoggingToDebugRingBuffer( + stopLoggingToDebugRingBuffer_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::stopLoggingToDebugRingBufferInternal, hidl_status_cb); +} + +Return WifiChip::getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getDebugHostWakeReasonStatsInternal, hidl_status_cb); +} + +Return WifiChip::enableDebugErrorAlerts(bool enable, + enableDebugErrorAlerts_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::enableDebugErrorAlertsInternal, hidl_status_cb, enable); +} + +Return WifiChip::selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario, + selectTxPowerScenario_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::selectTxPowerScenarioInternal, hidl_status_cb, scenario); +} + +Return WifiChip::resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::resetTxPowerScenarioInternal, hidl_status_cb); +} + +Return WifiChip::setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::setLatencyModeInternal, hidl_status_cb, mode); +} + +Return WifiChip::registerEventCallback_1_2( + const sp& event_callback, + registerEventCallback_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::registerEventCallbackInternal_1_2, hidl_status_cb, + event_callback); +} + +Return WifiChip::selectTxPowerScenario_1_2(TxPowerScenario scenario, + selectTxPowerScenario_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::selectTxPowerScenarioInternal_1_2, hidl_status_cb, scenario); +} + +Return WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getCapabilitiesInternal_1_3, hidl_status_cb); +} + +Return WifiChip::getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getCapabilitiesInternal_1_5, hidl_status_cb); +} + +Return WifiChip::debug(const hidl_handle& handle, const hidl_vec&) { + if (handle != nullptr && handle->numFds >= 1) { + { + std::unique_lock lk(lock_t); + for (const auto& item : ringbuffer_map_) { + forceDumpToDebugRingBufferInternal(item.first); + } + // unique_lock unlocked here + } + usleep(100 * 1000); // sleep for 100 milliseconds to wait for + // ringbuffer updates. + int fd = handle->data[0]; + if (!writeRingbufferFilesInternal()) { + LOG(ERROR) << "Error writing files to flash"; + } + uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath); + if (n_error != 0) { + LOG(ERROR) << n_error << " errors occured in cpio function"; + } + fsync(fd); + } else { + LOG(ERROR) << "File handle error"; + } + return Void(); +} + +Return WifiChip::createRttController_1_4(const sp& bound_iface, + createRttController_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::createRttControllerInternal_1_4, hidl_status_cb, bound_iface); +} + +Return WifiChip::registerEventCallback_1_4( + const sp& event_callback, + registerEventCallback_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::registerEventCallbackInternal_1_4, hidl_status_cb, + event_callback); +} + +Return WifiChip::setMultiStaPrimaryConnection( + const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::setMultiStaPrimaryConnectionInternal, hidl_status_cb, ifname); +} + +Return WifiChip::setMultiStaUseCase(MultiStaUseCase use_case, + setMultiStaUseCase_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::setMultiStaUseCaseInternal, hidl_status_cb, use_case); +} + +Return WifiChip::setCoexUnsafeChannels(const hidl_vec& unsafeChannels, + hidl_bitfield restrictions, + setCoexUnsafeChannels_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::setCoexUnsafeChannelsInternal, hidl_status_cb, unsafeChannels, + restrictions); +} + +Return WifiChip::setCountryCode(const hidl_array& code, + setCountryCode_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiChip::setCountryCodeInternal, hidl_status_cb, code); +} + +Return WifiChip::getUsableChannels( + WifiBand band, hidl_bitfield ifaceModeMask, + hidl_bitfield filterMask, + getUsableChannels_cb _hidl_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getUsableChannelsInternal, _hidl_cb, band, ifaceModeMask, + filterMask); +} + +Return WifiChip::triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::triggerSubsystemRestartInternal, hidl_status_cb); +} + +void WifiChip::invalidateAndRemoveAllIfaces() { + invalidateAndClearBridgedApAll(); + invalidateAndClearAll(ap_ifaces_); + invalidateAndClearAll(nan_ifaces_); + invalidateAndClearAll(p2p_ifaces_); + invalidateAndClearAll(sta_ifaces_); + // Since all the ifaces are invalid now, all RTT controller objects + // using those ifaces also need to be invalidated. + for (const auto& rtt : rtt_controllers_) { + rtt->invalidate(); + } + rtt_controllers_.clear(); +} + +void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) { + for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) { + auto nan_iface = *it; + if (nan_iface->getName() == removed_iface_name) { + nan_iface->invalidate(); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onIfaceRemoved(IfaceType::NAN, removed_iface_name).isOk()) { + LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; + } + } + it = nan_ifaces_.erase(it); + } else { + ++it; + } + } + + for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) { + auto rtt = *it; + if (rtt->getIfaceName() == removed_iface_name) { + rtt->invalidate(); + it = rtt_controllers_.erase(it); + } else { + ++it; + } + } +} + +std::pair WifiChip::getIdInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_}; +} + +WifiStatus WifiChip::registerEventCallbackInternal( + const sp& /* event_callback */) { + // Deprecated support for this callback. + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +std::pair WifiChip::getCapabilitiesInternal() { + // Deprecated support for this callback. + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0}; +} + +std::pair> +WifiChip::getAvailableModesInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), modes_}; +} + +WifiStatus WifiChip::configureChipInternal( + /* NONNULL */ std::unique_lock* lock, ChipModeId mode_id) { + if (!isValidModeId(mode_id)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + if (mode_id == current_mode_id_) { + LOG(DEBUG) << "Already in the specified mode " << mode_id; + return createWifiStatus(WifiStatusCode::SUCCESS); + } + WifiStatus status = handleChipConfiguration(lock, mode_id); + if (status.code != WifiStatusCode::SUCCESS) { + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onChipReconfigureFailure(status).isOk()) { + LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback"; + } + } + return status; + } + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onChipReconfigured(mode_id).isOk()) { + LOG(ERROR) << "Failed to invoke onChipReconfigured callback"; + } + } + current_mode_id_ = mode_id; + LOG(INFO) << "Configured chip in mode " << mode_id; + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); + + legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_); + + return status; +} + +std::pair WifiChip::getModeInternal() { + if (!isValidModeId(current_mode_id_)) { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), current_mode_id_}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_}; +} + +std::pair WifiChip::requestChipDebugInfoInternal() { + V1_4::IWifiChip::ChipDebugInfo result; + legacy_hal::wifi_error legacy_status; + std::string driver_desc; + const auto ifname = getFirstActiveWlanIfaceName(); + std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status); + WifiStatus status = + createWifiStatusFromLegacyError(legacy_status, "failed to get driver version"); + return {status, result}; + } + result.driverDescription = driver_desc.c_str(); + + std::string firmware_desc; + std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status); + WifiStatus status = + createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version"); + return {status, result}; + } + result.firmwareDescription = firmware_desc.c_str(); + + return {createWifiStatus(WifiStatusCode::SUCCESS), result}; +} + +std::pair> WifiChip::requestDriverDebugDumpInternal() { + legacy_hal::wifi_error legacy_status; + std::vector driver_dump; + std::tie(legacy_status, driver_dump) = + legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName()); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status); + return {createWifiStatusFromLegacyError(legacy_status), std::vector()}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump}; +} + +std::pair> WifiChip::requestFirmwareDebugDumpInternal() { + legacy_hal::wifi_error legacy_status; + std::vector firmware_dump; + std::tie(legacy_status, firmware_dump) = + legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName()); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status); + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump}; +} + +WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) { + legacy_hal::wifi_error legacy_status; + legacy_status = legacy_hal_.lock()->createVirtualInterface( + apVirtIf, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP)); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to add interface: " << apVirtIf << " " + << legacyErrorToString(legacy_status); + return createWifiStatusFromLegacyError(legacy_status); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +sp WifiChip::newWifiApIface(std::string& ifname) { + std::vector ap_instances; + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == ifname) { + ap_instances = it.second; + } + } + sp iface = new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_); + ap_ifaces_.push_back(iface); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) { + LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; + } + } + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); + return iface; +} + +std::pair> WifiChip::createApIfaceInternal() { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + std::string ifname = allocateApIfaceName(); + WifiStatus status = createVirtualApInterface(ifname); + if (status.code != WifiStatusCode::SUCCESS) { + return {status, {}}; + } + sp iface = newWifiApIface(ifname); + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +std::pair> WifiChip::createBridgedApIfaceInternal() { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + std::vector ap_instances = allocateBridgedApInstanceNames(); + if (ap_instances.size() < 2) { + LOG(ERROR) << "Fail to allocate two instances"; + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0]; + for (int i = 0; i < 2; i++) { + WifiStatus status = createVirtualApInterface(ap_instances[i]); + if (status.code != WifiStatusCode::SUCCESS) { + if (i != 0) { // The failure happened when creating second virtual + // iface. + legacy_hal_.lock()->deleteVirtualInterface( + ap_instances.front()); // Remove the first virtual iface. + } + return {status, {}}; + } + } + br_ifaces_ap_instances_[br_ifname] = ap_instances; + if (!iface_util_->createBridge(br_ifname)) { + LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str(); + invalidateAndClearBridgedAp(br_ifname); + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + for (auto const& instance : ap_instances) { + // Bind ap instance interface to AP bridge + if (!iface_util_->addIfaceToBridge(br_ifname, instance)) { + LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str(); + invalidateAndClearBridgedAp(br_ifname); + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + } + sp iface = newWifiApIface(br_ifname); + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +std::pair> WifiChip::getApIfaceNamesInternal() { + if (ap_ifaces_.empty()) { + return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)}; +} + +std::pair> WifiChip::getApIfaceInternal( + const std::string& ifname) { + const auto iface = findUsingName(ap_ifaces_, ifname); + if (!iface.get()) { + return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { + const auto iface = findUsingName(ap_ifaces_, ifname); + if (!iface.get()) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + // Invalidate & remove any dependent objects first. + // Note: This is probably not required because we never create + // nan/rtt objects over AP iface. But, there is no harm to do it + // here and not make that assumption all over the place. + invalidateAndRemoveDependencies(ifname); + // Clear the bridge interface and the iface instance. + invalidateAndClearBridgedAp(ifname); + invalidateAndClear(ap_ifaces_, iface); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) { + LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; + } + } + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( + const std::string& ifname, const std::string& ifInstanceName) { + const auto iface = findUsingName(ap_ifaces_, ifname); + if (!iface.get() || ifInstanceName.empty()) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + // Requires to remove one of the instance in bridge mode + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == ifname) { + std::vector ap_instances = it.second; + for (auto const& iface : ap_instances) { + if (iface == ifInstanceName) { + if (!iface_util_->removeIfaceFromBridge(it.first, iface)) { + LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from " + << ifname; + return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->deleteVirtualInterface(iface); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to del interface: " << iface << " " + << legacyErrorToString(legacy_status); + return createWifiStatusFromLegacyError(legacy_status); + } + ap_instances.erase( + std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName), + ap_instances.end()); + br_ifaces_ap_instances_[ifname] = ap_instances; + break; + } + } + break; + } + } + iface->removeInstance(ifInstanceName); + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); + + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +std::pair> WifiChip::createNanIfaceInternal() { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + bool is_dedicated_iface = true; + std::string ifname = getPredefinedNanIfaceName(); + if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) { + // Use the first shared STA iface (wlan0) if a dedicated aware iface is + // not defined. + ifname = getFirstActiveWlanIfaceName(); + is_dedicated_iface = false; + } + sp iface = new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_); + nan_ifaces_.push_back(iface); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) { + LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; + } + } + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +std::pair> WifiChip::getNanIfaceNamesInternal() { + if (nan_ifaces_.empty()) { + return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)}; +} + +std::pair> WifiChip::getNanIfaceInternal( + const std::string& ifname) { + const auto iface = findUsingName(nan_ifaces_, ifname); + if (!iface.get()) { + return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) { + const auto iface = findUsingName(nan_ifaces_, ifname); + if (!iface.get()) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + invalidateAndClear(nan_ifaces_, iface); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) { + LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; + } + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +std::pair> WifiChip::createP2pIfaceInternal() { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + std::string ifname = getPredefinedP2pIfaceName(); + sp iface = new WifiP2pIface(ifname, legacy_hal_); + p2p_ifaces_.push_back(iface); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) { + LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; + } + } + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +std::pair> WifiChip::getP2pIfaceNamesInternal() { + if (p2p_ifaces_.empty()) { + return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)}; +} + +std::pair> WifiChip::getP2pIfaceInternal(const std::string& ifname) { + const auto iface = findUsingName(p2p_ifaces_, ifname); + if (!iface.get()) { + return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) { + const auto iface = findUsingName(p2p_ifaces_, ifname); + if (!iface.get()) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + invalidateAndClear(p2p_ifaces_, iface); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) { + LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; + } + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +std::pair> WifiChip::createStaIfaceInternal() { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + std::string ifname = allocateStaIfaceName(); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface( + ifname, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA)); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to add interface: " << ifname << " " + << legacyErrorToString(legacy_status); + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + sp iface = new WifiStaIface(ifname, legacy_hal_, iface_util_); + sta_ifaces_.push_back(iface); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) { + LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; + } + } + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +std::pair> WifiChip::getStaIfaceNamesInternal() { + if (sta_ifaces_.empty()) { + return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)}; +} + +std::pair> WifiChip::getStaIfaceInternal( + const std::string& ifname) { + const auto iface = findUsingName(sta_ifaces_, ifname); + if (!iface.get()) { + return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) { + const auto iface = findUsingName(sta_ifaces_, ifname); + if (!iface.get()) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + // Invalidate & remove any dependent objects first. + invalidateAndRemoveDependencies(ifname); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to remove interface: " << ifname << " " + << legacyErrorToString(legacy_status); + } + invalidateAndClear(sta_ifaces_, iface); + for (const auto& callback : event_cb_handler_.getCallbacks()) { + if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) { + LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; + } + } + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +std::pair> WifiChip::createRttControllerInternal( + const sp& /*bound_iface*/) { + LOG(ERROR) << "createRttController is not supported on this HAL"; + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +std::pair> +WifiChip::getDebugRingBuffersStatusInternal() { + legacy_hal::wifi_error legacy_status; + std::vector legacy_ring_buffer_status_vec; + std::tie(legacy_status, legacy_ring_buffer_status_vec) = + legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName()); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + std::vector hidl_ring_buffer_status_vec; + if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl( + legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_ring_buffer_status_vec}; +} + +WifiStatus WifiChip::startLoggingToDebugRingBufferInternal( + const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, + uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) { + WifiStatus status = registerDebugRingBufferCallback(); + if (status.code != WifiStatusCode::SUCCESS) { + return status; + } + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging( + getFirstActiveWlanIfaceName(), ring_name, + static_cast::type>(verbose_level), + max_interval_in_sec, min_data_size_in_bytes); + ringbuffer_map_.insert( + std::pair(ring_name, Ringbuffer(kMaxBufferSizeBytes))); + // if verbose logging enabled, turn up HAL daemon logging as well. + if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) { + android::base::SetMinimumLogSeverity(android::base::DEBUG); + } else { + android::base::SetMinimumLogSeverity(android::base::VERBOSE); + } + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(const hidl_string& ring_name) { + WifiStatus status = registerDebugRingBufferCallback(); + if (status.code != WifiStatusCode::SUCCESS) { + return status; + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name); + + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::flushRingBufferToFileInternal() { + if (!writeRingbufferFilesInternal()) { + LOG(ERROR) << "Error writing files to flash"; + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() { + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName()); + if (legacy_status == legacy_hal::WIFI_SUCCESS) { + debug_ring_buffer_cb_registered_ = false; + } + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair +WifiChip::getDebugHostWakeReasonStatsInternal() { + legacy_hal::wifi_error legacy_status; + legacy_hal::WakeReasonStats legacy_stats; + std::tie(legacy_status, legacy_stats) = + legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName()); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + WifiDebugHostWakeReasonStats hidl_stats; + if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, &hidl_stats)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats}; +} + +WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) { + legacy_hal::wifi_error legacy_status; + if (enable) { + android::wp weak_ptr_this(this); + const auto& on_alert_callback = [weak_ptr_this](int32_t error_code, + std::vector debug_data) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) { + LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback"; + } + } + }; + legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler( + getFirstActiveWlanIfaceName(), on_alert_callback); + } else { + legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler( + getFirstActiveWlanIfaceName()); + } + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario) { + auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( + getFirstActiveWlanIfaceName(), + hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario)); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::resetTxPowerScenarioInternal() { + auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName()); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) { + auto legacy_status = legacy_hal_.lock()->setLatencyMode( + getFirstActiveWlanIfaceName(), hidl_struct_util::convertHidlLatencyModeToLegacy(mode)); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::registerEventCallbackInternal_1_2( + const sp& /* event_callback */) { + // Deprecated support for this callback. + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario) { + auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( + getFirstActiveWlanIfaceName(), + hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario)); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair WifiChip::getCapabilitiesInternal_1_3() { + // Deprecated support for this callback. + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0}; +} + +std::pair WifiChip::getCapabilitiesInternal_1_5() { + legacy_hal::wifi_error legacy_status; + uint64_t legacy_feature_set; + uint32_t legacy_logger_feature_set; + const auto ifname = getFirstActiveWlanIfaceName(); + std::tie(legacy_status, legacy_feature_set) = + 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(ifname); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + // some devices don't support querying logger feature set + legacy_logger_feature_set = 0; + } + uint32_t hidl_caps; + if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities( + legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; +} + +std::pair> WifiChip::createRttControllerInternal_1_4( + const sp& bound_iface) { + if (sta_ifaces_.size() == 0 && !canCurrentModeSupportIfaceOfType(IfaceType::STA)) { + LOG(ERROR) << "createRttControllerInternal_1_4: Chip cannot support STAs " + "(and RTT by extension)"; + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + sp rtt = + new WifiRttController(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_); + rtt_controllers_.emplace_back(rtt); + return {createWifiStatus(WifiStatusCode::SUCCESS), rtt}; +} + +WifiStatus WifiChip::registerEventCallbackInternal_1_4( + const sp& event_callback) { + if (!event_cb_handler_.addCallback(event_callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) { + auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) { + auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase( + hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case)); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::setCoexUnsafeChannelsInternal(std::vector unsafe_channels, + uint32_t restrictions) { + std::vector legacy_unsafe_channels; + if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels, + &legacy_unsafe_channels)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + uint32_t legacy_restrictions = 0; + if (restrictions & CoexRestriction::WIFI_DIRECT) { + legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT; + } + if (restrictions & CoexRestriction::SOFTAP) { + legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP; + } + if (restrictions & CoexRestriction::WIFI_AWARE) { + legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE; + } + auto legacy_status = + legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::setCountryCodeInternal(const std::array& code) { + auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair> WifiChip::getUsableChannelsInternal( + WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask) { + legacy_hal::wifi_error legacy_status; + std::vector legacy_usable_channels; + std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels( + hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band), + hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask), + hidl_struct_util::convertHidlUsableChannelFilterToLegacy(filterMask)); + + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + std::vector hidl_usable_channels; + if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(legacy_usable_channels, + &hidl_usable_channels)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels}; +} + +WifiStatus WifiChip::triggerSubsystemRestartInternal() { + auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart(); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::handleChipConfiguration( + /* NONNULL */ std::unique_lock* lock, ChipModeId mode_id) { + // If the chip is already configured in a different mode, stop + // the legacy HAL and then start it after firmware mode change. + if (isValidModeId(current_mode_id_)) { + LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id; + invalidateAndRemoveAllIfaces(); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {}); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status); + return createWifiStatusFromLegacyError(legacy_status); + } + } + // Firmware mode change not needed for V2 devices. + bool success = true; + if (mode_id == feature_flags::chip_mode_ids::kV1Sta) { + success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA); + } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) { + success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP); + } + if (!success) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start(); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status); + return createWifiStatusFromLegacyError(legacy_status); + } + // Every time the HAL is restarted, we need to register the + // radio mode change callback. + WifiStatus status = registerRadioModeChangeCallback(); + if (status.code != WifiStatusCode::SUCCESS) { + // This probably is not a critical failure? + LOG(ERROR) << "Failed to register radio mode change callback"; + } + // Extract and save the version information into property. + std::pair version_info; + version_info = WifiChip::requestChipDebugInfoInternal(); + if (WifiStatusCode::SUCCESS == version_info.first.code) { + property_set("vendor.wlan.firmware.version", + version_info.second.firmwareDescription.c_str()); + property_set("vendor.wlan.driver.version", version_info.second.driverDescription.c_str()); + } + + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiChip::registerDebugRingBufferCallback() { + if (debug_ring_buffer_cb_registered_) { + return createWifiStatus(WifiStatusCode::SUCCESS); + } + + android::wp weak_ptr_this(this); + const auto& on_ring_buffer_data_callback = + [weak_ptr_this](const std::string& name, const std::vector& data, + const legacy_hal::wifi_ring_buffer_status& status) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiDebugRingBufferStatus hidl_status; + if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(status, + &hidl_status)) { + LOG(ERROR) << "Error converting ring buffer status"; + return; + } + { + std::unique_lock lk(shared_ptr_this->lock_t); + const auto& target = shared_ptr_this->ringbuffer_map_.find(name); + if (target != shared_ptr_this->ringbuffer_map_.end()) { + Ringbuffer& cur_buffer = target->second; + cur_buffer.append(data); + } else { + LOG(ERROR) << "Ringname " << name << " not found"; + return; + } + // unique_lock unlocked here + } + }; + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler( + getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback); + + if (legacy_status == legacy_hal::WIFI_SUCCESS) { + debug_ring_buffer_cb_registered_ = true; + } + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiChip::registerRadioModeChangeCallback() { + android::wp weak_ptr_this(this); + const auto& on_radio_mode_change_callback = + [weak_ptr_this](const std::vector& mac_infos) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + std::vector hidl_radio_mode_infos; + if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(mac_infos, + &hidl_radio_mode_infos)) { + LOG(ERROR) << "Error converting wifi mac info"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos).isOk()) { + LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4" + << " callback on: " << toString(callback); + } + } + }; + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->registerRadioModeChangeCallbackHandler( + getFirstActiveWlanIfaceName(), on_radio_mode_change_callback); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::vector WifiChip::getCurrentModeIfaceCombinations() { + if (!isValidModeId(current_mode_id_)) { + LOG(ERROR) << "Chip not configured in a mode yet"; + return {}; + } + for (const auto& mode : modes_) { + if (mode.id == current_mode_id_) { + return mode.availableCombinations; + } + } + CHECK(0) << "Expected to find iface combinations for current mode!"; + return {}; +} + +// Returns a map indexed by IfaceType with the number of ifaces currently +// created of the corresponding type. +std::map WifiChip::getCurrentIfaceCombination() { + std::map iface_counts; + iface_counts[IfaceType::AP] = ap_ifaces_.size(); + iface_counts[IfaceType::NAN] = nan_ifaces_.size(); + iface_counts[IfaceType::P2P] = p2p_ifaces_.size(); + iface_counts[IfaceType::STA] = sta_ifaces_.size(); + return iface_counts; +} + +// This expands the provided iface combinations to a more parseable +// form. Returns a vector of available combinations possible with the number +// of ifaces of each type in the combination. +// This method is a port of HalDeviceManager.expandIfaceCombos() from framework. +std::vector> WifiChip::expandIfaceCombinations( + const V1_4::IWifiChip::ChipIfaceCombination& combination) { + uint32_t num_expanded_combos = 1; + for (const auto& limit : combination.limits) { + for (uint32_t i = 0; i < limit.maxIfaces; i++) { + num_expanded_combos *= limit.types.size(); + } + } + + // Allocate the vector of expanded combos and reset all iface counts to 0 + // in each combo. + std::vector> expanded_combos; + expanded_combos.resize(num_expanded_combos); + for (auto& expanded_combo : expanded_combos) { + for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { + expanded_combo[type] = 0; + } + } + uint32_t span = num_expanded_combos; + for (const auto& limit : combination.limits) { + for (uint32_t i = 0; i < limit.maxIfaces; i++) { + span /= limit.types.size(); + for (uint32_t k = 0; k < num_expanded_combos; ++k) { + const auto iface_type = limit.types[(k / span) % limit.types.size()]; + expanded_combos[k][iface_type]++; + } + } + } + return expanded_combos; +} + +bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( + const std::map& expanded_combo, IfaceType requested_type) { + const auto current_combo = getCurrentIfaceCombination(); + + // Check if we have space for 1 more iface of |type| in this combo + for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { + size_t num_ifaces_needed = current_combo.at(type); + if (type == requested_type) { + num_ifaces_needed++; + } + size_t num_ifaces_allowed = expanded_combo.at(type); + if (num_ifaces_needed > num_ifaces_allowed) { + return false; + } + } + return true; +} + +// This method does the following: +// a) Enumerate all possible iface combos by expanding the current +// ChipIfaceCombination. +// b) Check if the requested iface type can be added to the current mode +// with the iface combination that is already active. +bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType requested_type) { + if (!isValidModeId(current_mode_id_)) { + LOG(ERROR) << "Chip not configured in a mode yet"; + return false; + } + const auto combinations = getCurrentModeIfaceCombinations(); + for (const auto& combination : combinations) { + const auto expanded_combos = expandIfaceCombinations(combination); + for (const auto& expanded_combo : expanded_combos) { + if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(expanded_combo, + requested_type)) { + return true; + } + } + } + return false; +} + +// Note: This does not consider ifaces already active. It only checks if the +// provided expanded iface combination can support the requested combo. +bool WifiChip::canExpandedIfaceComboSupportIfaceCombo( + const std::map& expanded_combo, + const std::map& req_combo) { + // Check if we have space for 1 more iface of |type| in this combo + for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { + if (req_combo.count(type) == 0) { + // Iface of "type" not in the req_combo. + continue; + } + size_t num_ifaces_needed = req_combo.at(type); + size_t num_ifaces_allowed = expanded_combo.at(type); + if (num_ifaces_needed > num_ifaces_allowed) { + return false; + } + } + return true; +} +// This method does the following: +// a) Enumerate all possible iface combos by expanding the current +// ChipIfaceCombination. +// b) Check if the requested iface combo can be added to the current mode. +// Note: This does not consider ifaces already active. It only checks if the +// current mode can support the requested combo. +bool WifiChip::canCurrentModeSupportIfaceCombo(const std::map& req_combo) { + if (!isValidModeId(current_mode_id_)) { + LOG(ERROR) << "Chip not configured in a mode yet"; + return false; + } + const auto combinations = getCurrentModeIfaceCombinations(); + for (const auto& combination : combinations) { + const auto expanded_combos = expandIfaceCombinations(combination); + for (const auto& expanded_combo : expanded_combos) { + if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo, req_combo)) { + return true; + } + } + } + return false; +} + +// This method does the following: +// a) Enumerate all possible iface combos by expanding the current +// ChipIfaceCombination. +// b) Check if the requested iface type can be added to the current mode. +bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) { + // Check if we can support at least 1 iface of type. + std::map req_iface_combo; + req_iface_combo[requested_type] = 1; + return canCurrentModeSupportIfaceCombo(req_iface_combo); +} + +bool WifiChip::isValidModeId(ChipModeId mode_id) { + for (const auto& mode : modes_) { + if (mode.id == mode_id) { + return true; + } + } + return false; +} + +bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() { + // Check if we can support at least 1 STA & 1 AP concurrently. + std::map req_iface_combo; + req_iface_combo[IfaceType::AP] = 1; + req_iface_combo[IfaceType::STA] = 1; + return canCurrentModeSupportIfaceCombo(req_iface_combo); +} + +bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() { + // Check if we can support at least 2 STA concurrently. + std::map req_iface_combo; + req_iface_combo[IfaceType::STA] = 2; + return canCurrentModeSupportIfaceCombo(req_iface_combo); +} + +std::string WifiChip::getFirstActiveWlanIfaceName() { + if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName(); + if (ap_ifaces_.size() > 0) { + // If the first active wlan iface is bridged iface. + // Return first instance name. + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == ap_ifaces_[0]->getName()) { + return it.second[0]; + } + } + return ap_ifaces_[0]->getName(); + } + // This could happen if the chip call is made before any STA/AP + // iface is created. Default to wlan0 for such cases. + LOG(WARNING) << "No active wlan interfaces in use! Using default"; + return getWlanIfaceNameWithType(IfaceType::STA, 0); +} + +// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx| +// not already in use. +// Note: This doesn't check the actual presence of these interfaces. +std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) { + for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) { + const auto ifname = getWlanIfaceNameWithType(type, idx); + if (findUsingNameFromBridgedApInstances(ifname)) continue; + 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(false) << "All wlan interfaces in use already!"; + return {}; +} + +uint32_t WifiChip::startIdxOfApIface() { + if (isDualStaConcurrencyAllowedInCurrentMode()) { + // When the HAL support dual STAs, AP should start with idx 2. + return 2; + } else if (isStaApConcurrencyAllowedInCurrentMode()) { + // When the HAL support STA + AP but it doesn't support dual STAs. + // AP should start with idx 1. + return 1; + } + // No concurrency support. + return 0; +} + +// AP iface names start with idx 1 for modes supporting +// concurrent STA and not dual AP, else start with idx 0. +std::string WifiChip::allocateApIfaceName() { + // Check if we have a dedicated iface for AP. + std::vector ifnames = getPredefinedApIfaceNames(false); + if (!ifnames.empty()) { + return ifnames[0]; + } + return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface()); +} + +std::vector WifiChip::allocateBridgedApInstanceNames() { + // Check if we have a dedicated iface for AP. + std::vector instances = getPredefinedApIfaceNames(true); + if (instances.size() == 2) { + return instances; + } else { + int num_ifaces_need_to_allocate = 2 - instances.size(); + for (int i = 0; i < num_ifaces_need_to_allocate; i++) { + std::string instance_name = + allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i); + if (!instance_name.empty()) { + instances.push_back(instance_name); + } + } + } + return instances; +} + +// STA iface names start with idx 0. +// Primary STA iface will always be 0. +std::string WifiChip::allocateStaIfaceName() { + return allocateApOrStaIfaceName(IfaceType::STA, 0); +} + +bool WifiChip::writeRingbufferFilesInternal() { + if (!removeOldFilesInternal()) { + LOG(ERROR) << "Error occurred while deleting old tombstone files"; + return false; + } + // write ringbuffers to file + { + std::unique_lock lk(lock_t); + for (auto& item : ringbuffer_map_) { + Ringbuffer& cur_buffer = item.second; + if (cur_buffer.getData().empty()) { + continue; + } + const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX"; + const int dump_fd = mkstemp(makeCharVec(file_path_raw).data()); + if (dump_fd == -1) { + PLOG(ERROR) << "create file failed"; + return false; + } + unique_fd file_auto_closer(dump_fd); + for (const auto& cur_block : cur_buffer.getData()) { + if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) == + -1) { + PLOG(ERROR) << "Error writing to file"; + } + } + cur_buffer.clear(); + } + // unique_lock unlocked here + } + return true; +} + +std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) { + std::string ifname; + + // let the legacy hal override the interface name + legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname); + if (err == legacy_hal::WIFI_SUCCESS) return ifname; + + return getWlanIfaceName(idx); +} + +void WifiChip::invalidateAndClearBridgedApAll() { + for (auto const& it : br_ifaces_ap_instances_) { + for (auto const& iface : it.second) { + iface_util_->removeIfaceFromBridge(it.first, iface); + legacy_hal_.lock()->deleteVirtualInterface(iface); + } + iface_util_->deleteBridge(it.first); + } + br_ifaces_ap_instances_.clear(); +} + +void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) { + if (br_name.empty()) return; + // delete managed interfaces + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == br_name) { + for (auto const& iface : it.second) { + iface_util_->removeIfaceFromBridge(br_name, iface); + legacy_hal_.lock()->deleteVirtualInterface(iface); + } + iface_util_->deleteBridge(br_name); + br_ifaces_ap_instances_.erase(br_name); + break; + } + } + return; +} + +bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) { + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == name) { + return true; + } + for (auto const& iface : it.second) { + if (iface == name) { + return true; + } + } + } + return false; +} + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_chip.h b/wifi/1.6/default/wifi_chip.h new file mode 100644 index 0000000000..8a068985d1 --- /dev/null +++ b/wifi/1.6/default/wifi_chip.h @@ -0,0 +1,294 @@ +/* + * 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. + */ + +#ifndef WIFI_CHIP_H_ +#define WIFI_CHIP_H_ + +#include +#include +#include + +#include +#include +#include + +#include "hidl_callback_util.h" +#include "ringbuffer.h" +#include "wifi_ap_iface.h" +#include "wifi_feature_flags.h" +#include "wifi_legacy_hal.h" +#include "wifi_mode_controller.h" +#include "wifi_nan_iface.h" +#include "wifi_p2p_iface.h" +#include "wifi_rtt_controller.h" +#include "wifi_sta_iface.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; +using V1_5::WifiBand; +using V1_5::WifiUsableChannel; + +/** + * HIDL interface object used to control a Wifi HAL chip instance. + * Since there is only a single chip instance used today, there is no + * identifying handle information stored here. + */ +class WifiChip : public V1_5::IWifiChip { + public: + WifiChip(ChipId chip_id, bool is_primary, + const std::weak_ptr legacy_hal, + const std::weak_ptr mode_controller, + const std::shared_ptr iface_util, + const std::weak_ptr feature_flags, + const std::function& subsystemCallbackHandler); + // HIDL does not provide a built-in mechanism to let the server invalidate + // a HIDL interface object after creation. If any client process holds onto + // a reference to the object in their context, any method calls on that + // reference will continue to be directed to the server. + // + // However Wifi HAL needs to control the lifetime of these objects. So, add + // a public |invalidate| method to |WifiChip| and it's child objects. This + // will be used to mark an object invalid when either: + // a) Wifi HAL is stopped, or + // b) Wifi Chip is reconfigured. + // + // All HIDL method implementations should check if the object is still + // marked valid before processing them. + void invalidate(); + bool isValid(); + std::set> getEventCallbacks(); + + // HIDL methods exposed. + Return getId(getId_cb hidl_status_cb) override; + // Deprecated support for this callback + Return registerEventCallback(const sp& event_callback, + registerEventCallback_cb hidl_status_cb) override; + Return getCapabilities(getCapabilities_cb hidl_status_cb) override; + Return getAvailableModes(getAvailableModes_cb hidl_status_cb) override; + Return configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) override; + Return getMode(getMode_cb hidl_status_cb) override; + Return requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) override; + Return requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) override; + Return requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) override; + Return createApIface(createApIface_cb hidl_status_cb) override; + Return createBridgedApIface(createBridgedApIface_cb hidl_status_cb) override; + Return getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override; + Return getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) override; + Return removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) override; + Return removeIfaceInstanceFromBridgedApIface( + const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName, + removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override; + Return createNanIface(createNanIface_cb hidl_status_cb) override; + Return getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override; + Return getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) override; + Return removeNanIface(const hidl_string& ifname, + removeNanIface_cb hidl_status_cb) override; + Return createP2pIface(createP2pIface_cb hidl_status_cb) override; + Return getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) override; + Return getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) override; + Return removeP2pIface(const hidl_string& ifname, + removeP2pIface_cb hidl_status_cb) override; + Return createStaIface(createStaIface_cb hidl_status_cb) override; + Return getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) override; + Return getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) override; + Return removeStaIface(const hidl_string& ifname, + removeStaIface_cb hidl_status_cb) override; + Return createRttController(const sp& bound_iface, + createRttController_cb hidl_status_cb) override; + Return getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) override; + Return startLoggingToDebugRingBuffer( + const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, + uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes, + startLoggingToDebugRingBuffer_cb hidl_status_cb) override; + Return forceDumpToDebugRingBuffer(const hidl_string& ring_name, + forceDumpToDebugRingBuffer_cb hidl_status_cb) override; + Return flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) override; + Return stopLoggingToDebugRingBuffer( + stopLoggingToDebugRingBuffer_cb hidl_status_cb) override; + Return getDebugHostWakeReasonStats( + getDebugHostWakeReasonStats_cb hidl_status_cb) override; + Return enableDebugErrorAlerts(bool enable, + enableDebugErrorAlerts_cb hidl_status_cb) override; + Return selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario, + selectTxPowerScenario_cb hidl_status_cb) override; + Return resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) override; + Return setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) override; + Return registerEventCallback_1_2(const sp& event_callback, + registerEventCallback_1_2_cb hidl_status_cb) override; + Return selectTxPowerScenario_1_2(TxPowerScenario scenario, + selectTxPowerScenario_cb hidl_status_cb) override; + Return getCapabilities_1_3(getCapabilities_cb hidl_status_cb) override; + Return getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) override; + Return debug(const hidl_handle& handle, const hidl_vec& options) override; + Return createRttController_1_4(const sp& bound_iface, + createRttController_1_4_cb hidl_status_cb) override; + Return registerEventCallback_1_4(const sp& event_callback, + registerEventCallback_1_4_cb hidl_status_cb) override; + Return setMultiStaPrimaryConnection( + const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) override; + Return setMultiStaUseCase(MultiStaUseCase use_case, + setMultiStaUseCase_cb hidl_status_cb) override; + Return setCoexUnsafeChannels(const hidl_vec& unsafe_channels, + hidl_bitfield restrictions, + setCoexUnsafeChannels_cb hidl_status_cb) override; + Return setCountryCode(const hidl_array& code, + setCountryCode_cb _hidl_cb) override; + Return getUsableChannels(WifiBand band, hidl_bitfield ifaceModeMask, + hidl_bitfield filterMask, + getUsableChannels_cb _hidl_cb) override; + Return triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) override; + + private: + void invalidateAndRemoveAllIfaces(); + // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are + // invalidated & removed. + void invalidateAndRemoveDependencies(const std::string& removed_iface_name); + + // Corresponding worker functions for the HIDL methods. + std::pair getIdInternal(); + // Deprecated support for this callback + WifiStatus registerEventCallbackInternal( + const sp& event_callback); + std::pair getCapabilitiesInternal(); + std::pair> getAvailableModesInternal(); + WifiStatus configureChipInternal(std::unique_lock* lock, + ChipModeId mode_id); + std::pair getModeInternal(); + std::pair requestChipDebugInfoInternal(); + std::pair> requestDriverDebugDumpInternal(); + std::pair> requestFirmwareDebugDumpInternal(); + sp newWifiApIface(std::string& ifname); + WifiStatus createVirtualApInterface(const std::string& apVirtIf); + std::pair> createApIfaceInternal(); + std::pair> createBridgedApIfaceInternal(); + std::pair> getApIfaceNamesInternal(); + std::pair> getApIfaceInternal(const std::string& ifname); + WifiStatus removeApIfaceInternal(const std::string& ifname); + WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal(const std::string& brIfaceName, + const std::string& ifInstanceName); + std::pair> createNanIfaceInternal(); + std::pair> getNanIfaceNamesInternal(); + std::pair> getNanIfaceInternal(const std::string& ifname); + WifiStatus removeNanIfaceInternal(const std::string& ifname); + std::pair> createP2pIfaceInternal(); + std::pair> getP2pIfaceNamesInternal(); + std::pair> getP2pIfaceInternal(const std::string& ifname); + WifiStatus removeP2pIfaceInternal(const std::string& ifname); + std::pair> createStaIfaceInternal(); + std::pair> getStaIfaceNamesInternal(); + std::pair> getStaIfaceInternal(const std::string& ifname); + WifiStatus removeStaIfaceInternal(const std::string& ifname); + std::pair> createRttControllerInternal( + const sp& bound_iface); + std::pair> + getDebugRingBuffersStatusInternal(); + WifiStatus startLoggingToDebugRingBufferInternal(const hidl_string& ring_name, + WifiDebugRingBufferVerboseLevel verbose_level, + uint32_t max_interval_in_sec, + uint32_t min_data_size_in_bytes); + WifiStatus forceDumpToDebugRingBufferInternal(const hidl_string& ring_name); + WifiStatus flushRingBufferToFileInternal(); + WifiStatus stopLoggingToDebugRingBufferInternal(); + std::pair getDebugHostWakeReasonStatsInternal(); + WifiStatus enableDebugErrorAlertsInternal(bool enable); + WifiStatus selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario); + WifiStatus resetTxPowerScenarioInternal(); + WifiStatus setLatencyModeInternal(LatencyMode mode); + WifiStatus registerEventCallbackInternal_1_2( + const sp& event_callback); + WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario); + std::pair getCapabilitiesInternal_1_3(); + std::pair getCapabilitiesInternal_1_5(); + std::pair> createRttControllerInternal_1_4( + const sp& bound_iface); + WifiStatus registerEventCallbackInternal_1_4( + const sp& event_callback); + WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname); + WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case); + WifiStatus setCoexUnsafeChannelsInternal(std::vector unsafe_channels, + uint32_t restrictions); + WifiStatus setCountryCodeInternal(const std::array& code); + std::pair> getUsableChannelsInternal( + WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask); + WifiStatus handleChipConfiguration(std::unique_lock* lock, + ChipModeId mode_id); + WifiStatus registerDebugRingBufferCallback(); + WifiStatus registerRadioModeChangeCallback(); + + std::vector getCurrentModeIfaceCombinations(); + std::map getCurrentIfaceCombination(); + std::vector> expandIfaceCombinations( + const V1_4::IWifiChip::ChipIfaceCombination& combination); + bool canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( + const std::map& expanded_combo, IfaceType requested_type); + bool canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType requested_type); + bool canExpandedIfaceComboSupportIfaceCombo(const std::map& expanded_combo, + const std::map& req_combo); + bool canCurrentModeSupportIfaceCombo(const std::map& req_combo); + bool canCurrentModeSupportIfaceOfType(IfaceType requested_type); + bool isValidModeId(ChipModeId mode_id); + bool isStaApConcurrencyAllowedInCurrentMode(); + bool isDualStaConcurrencyAllowedInCurrentMode(); + uint32_t startIdxOfApIface(); + std::string getFirstActiveWlanIfaceName(); + std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx); + std::string allocateApIfaceName(); + std::vector allocateBridgedApInstanceNames(); + std::string allocateStaIfaceName(); + bool writeRingbufferFilesInternal(); + std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx); + void invalidateAndClearBridgedApAll(); + void invalidateAndClearBridgedAp(const std::string& br_name); + bool findUsingNameFromBridgedApInstances(const std::string& name); + WifiStatus triggerSubsystemRestartInternal(); + + ChipId chip_id_; + std::weak_ptr legacy_hal_; + std::weak_ptr mode_controller_; + std::shared_ptr iface_util_; + std::vector> ap_ifaces_; + std::vector> nan_ifaces_; + std::vector> p2p_ifaces_; + std::vector> sta_ifaces_; + std::vector> rtt_controllers_; + std::map ringbuffer_map_; + bool is_valid_; + // Members pertaining to chip configuration. + uint32_t current_mode_id_; + std::mutex lock_t; + std::vector modes_; + // The legacy ring buffer callback API has only a global callback + // registration mechanism. Use this to check if we have already + // registered a callback. + bool debug_ring_buffer_cb_registered_; + hidl_callback_util::HidlCallbackHandler event_cb_handler_; + + const std::function subsystemCallbackHandler_; + std::map> br_ifaces_ap_instances_; + DISALLOW_COPY_AND_ASSIGN(WifiChip); +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_CHIP_H_ diff --git a/wifi/1.6/default/wifi_feature_flags.cpp b/wifi/1.6/default/wifi_feature_flags.cpp new file mode 100644 index 0000000000..71319e1e90 --- /dev/null +++ b/wifi/1.6/default/wifi_feature_flags.cpp @@ -0,0 +1,239 @@ +/* + * 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. + */ + +#include + +#include +#include + +#include "wifi_feature_flags.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace feature_flags { + +using V1_0::ChipModeId; +using V1_0::IfaceType; +using V1_0::IWifiChip; + +/* The chip may either have a single mode supporting any number of combinations, + * or a fixed dual-mode (so it involves firmware loading to switch between + * modes) setting. If there is a need to support more modes, it needs to be + * implemented manually in WiFi HAL (see changeFirmwareMode in + * WifiChip::handleChipConfiguration). + * + * Supported combinations are defined in device's makefile, for example: + * WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}}, + * WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}} + * What means: + * Interface combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface + * operations. + * Interface combination 2: 1 STA and 2 AP concurrent iface operations. + * + * For backward compatibility, the following makefile flags can be used to + * generate combinations list: + * - WIFI_HIDL_FEATURE_DUAL_INTERFACE + * - WIFI_HIDL_FEATURE_DISABLE_AP + * - WIFI_HIDL_FEATURE_AWARE + * However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided. + * With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with + * two interface combinations: + * Interface Combination 1: Will support 1 STA and 1 P2P or NAN (optional) + * concurrent iface operations. + * Interface Combination 2: Will support 1 STA and 1 AP concurrent + * iface operations. + * + * The only dual-mode configuration supported is for alternating STA and AP + * mode, that may involve firmware reloading. In such case, there are 2 separate + * modes of operation with 1 interface combination each: + * Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional) + * concurrent iface operations. + * Mode 2 (AP mode): Will support 1 AP iface operation. + * + * If Aware is enabled, the iface combination will be modified to support either + * P2P or NAN in place of just P2P. + */ +// clang-format off +#ifdef WIFI_HAL_INTERFACE_COMBINATIONS +constexpr ChipModeId kMainModeId = chip_mode_ids::kV3; +#elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE) +// former V2 (fixed dual interface) setup expressed as V3 +constexpr ChipModeId kMainModeId = chip_mode_ids::kV3; +# ifdef WIFI_HIDL_FEATURE_DISABLE_AP +# ifdef WIFI_HIDL_FEATURE_AWARE +// 1 STA + 1 of (P2P or NAN) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}} +# else +// 1 STA + 1 P2P +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}} +# endif +# else +# ifdef WIFI_HIDL_FEATURE_AWARE +// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ + {{{STA}, 1}, {{P2P, NAN}, 1}} +# else +// (1 STA + 1 AP) or (1 STA + 1 P2P) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\ + {{{STA}, 1}, {{P2P}, 1}} +# endif +# endif +#else +// V1 (fixed single interface, dual-mode chip) +constexpr ChipModeId kMainModeId = chip_mode_ids::kV1Sta; +# ifdef WIFI_HIDL_FEATURE_AWARE +// 1 STA + 1 of (P2P or NAN) +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}} +# else +// 1 STA + 1 P2P +# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}} +# endif + +# ifndef WIFI_HIDL_FEATURE_DISABLE_AP +# define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}} +# endif +#endif +// clang-format on + +/** + * Helper class to convert a collection of combination limits to a combination. + * + * The main point here is to simplify the syntax required by + * WIFI_HAL_INTERFACE_COMBINATIONS. + */ +struct ChipIfaceCombination : public hidl_vec { + ChipIfaceCombination(const std::initializer_list list) + : hidl_vec(list) {} + + operator IWifiChip::ChipIfaceCombination() const { return {*this}; } + + static hidl_vec make_vec( + const std::initializer_list list) { + return hidl_vec( // + std::begin(list), std::end(list)); + } +}; + +#define STA IfaceType::STA +#define AP IfaceType::AP +#define P2P IfaceType::P2P +#define NAN IfaceType::NAN +static const std::vector kChipModesPrimary{ + {kMainModeId, ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})}, +#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP + {chip_mode_ids::kV1Ap, + ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})}, +#endif +}; + +static const std::vector kChipModesSecondary{ +#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP + {chip_mode_ids::kV3, + ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})}, +#endif +}; + +constexpr char kDebugPresetInterfaceCombinationIdxProperty[] = + "persist.vendor.debug.wifi.hal.preset_interface_combination_idx"; +// List of pre-defined interface combinations that can be enabled at runtime via +// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the +// corresponding index value. +static const std::vector>> kDebugChipModes{ + // Legacy combination - No STA/AP concurrencies. + // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN)) + {"No STA/AP Concurrency", + {{kMainModeId, + ChipIfaceCombination::make_vec({{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}}, + + // STA + AP concurrency + // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) + {"STA + AP Concurrency", + {{kMainModeId, ChipIfaceCombination::make_vec( + {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}}, + + // STA + STA concurrency + // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN)) + {"Dual STA Concurrency", + {{kMainModeId, ChipIfaceCombination::make_vec( + {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}, + + // AP + AP + STA concurrency + // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN)) + {"Dual AP Concurrency", + {{kMainModeId, ChipIfaceCombination::make_vec( + {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}}, + + // STA + STA concurrency and AP + AP + STA concurrency + // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN)) + {"Dual STA & Dual AP Concurrency", + {{kMainModeId, ChipIfaceCombination::make_vec( + {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}, + + // STA + STA concurrency + // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA)) + {"Dual STA or STA plus single other interface", + {{kMainModeId, + ChipIfaceCombination::make_vec({{{{STA}, 1}, {{P2P, NAN, AP}, 1}}, {{{STA}, 2}}})}}}}; + +#undef STA +#undef AP +#undef P2P +#undef NAN + +#ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION +#pragma message \ + "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \ + "'config_wifi_ap_randomization_supported' in " \ + "frameworks/base/core/res/res/values/config.xml in the device overlay " \ + "instead" +#endif // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION + +WifiFeatureFlags::WifiFeatureFlags() {} + +std::vector WifiFeatureFlags::getChipModesForPrimary() { + std::array buffer; + auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr); + // Debug propety not set, use the device preset interface combination. + if (res <= 0) return kChipModesPrimary; + + // Debug propety set, use one of the debug preset interface combination. + unsigned long idx = std::stoul(buffer.data()); + if (idx >= kDebugChipModes.size()) { + LOG(ERROR) << "Invalid index set in property: " + << kDebugPresetInterfaceCombinationIdxProperty; + return kChipModesPrimary; + } + std::string name; + std::vector chip_modes; + std::tie(name, chip_modes) = kDebugChipModes[idx]; + LOG(INFO) << "Using debug chip mode: <" << name + << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty; + return chip_modes; +} + +std::vector WifiFeatureFlags::getChipModes(bool is_primary) { + return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary; +} + +} // namespace feature_flags +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_feature_flags.h b/wifi/1.6/default/wifi_feature_flags.h new file mode 100644 index 0000000000..d5844d99b3 --- /dev/null +++ b/wifi/1.6/default/wifi_feature_flags.h @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#ifndef WIFI_FEATURE_FLAGS_H_ +#define WIFI_FEATURE_FLAGS_H_ + +#include + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace feature_flags { + +namespace chip_mode_ids { +// These mode ID's should be unique (even across combo versions). Refer to +// handleChipConfiguration() for it's usage. +constexpr V1_0::ChipModeId kInvalid = UINT32_MAX; +// Mode ID's for V1 +constexpr V1_0::ChipModeId kV1Sta = 0; +constexpr V1_0::ChipModeId kV1Ap = 1; +// Mode ID for V3 +constexpr V1_0::ChipModeId kV3 = 3; +} // namespace chip_mode_ids + +class WifiFeatureFlags { + public: + WifiFeatureFlags(); + virtual ~WifiFeatureFlags() = default; + + virtual std::vector getChipModes(bool is_primary); + + private: + std::vector getChipModesForPrimary(); +}; + +} // namespace feature_flags +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_FEATURE_FLAGS_H_ diff --git a/wifi/1.6/default/wifi_iface_util.cpp b/wifi/1.6/default/wifi_iface_util.cpp new file mode 100644 index 0000000000..d55e4f8251 --- /dev/null +++ b/wifi/1.6/default/wifi_iface_util.cpp @@ -0,0 +1,176 @@ +/* + * 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 +#include +#include +#include +#include + +#include +#include +#include + +#undef NAN +#include "wifi_iface_util.h" + +namespace { +// Constants to set the local bit & clear the multicast bit. +constexpr uint8_t kMacAddressMulticastMask = 0x01; +constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02; +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace iface_util { + +WifiIfaceUtil::WifiIfaceUtil(const std::weak_ptr iface_tool, + const std::weak_ptr legacy_hal) + : iface_tool_(iface_tool), + legacy_hal_(legacy_hal), + random_mac_address_(nullptr), + event_handlers_map_() {} + +std::array WifiIfaceUtil::getFactoryMacAddress(const std::string& iface_name) { + return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str()); +} + +bool WifiIfaceUtil::setMacAddress(const std::string& iface_name, + const std::array& mac) { +#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE + legacy_hal::wifi_error legacy_status; + uint64_t legacy_feature_set; + std::tie(legacy_status, legacy_feature_set) = + legacy_hal_.lock()->getSupportedFeatureSet(iface_name); + + if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) && + !iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) { + LOG(ERROR) << "SetUpState(false) failed."; + return false; + } +#endif + bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac); +#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE + if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) && + !iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) { + LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready."; + // Wait for driver ready and try to set iface UP again + if (legacy_hal_.lock()->waitForDriverReady() != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "SetUpState(true) wait for driver ready failed."; + return false; + } + if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) { + LOG(ERROR) << "SetUpState(true) failed after retry."; + return false; + } + } +#endif + IfaceEventHandlers event_handlers = {}; + const auto it = event_handlers_map_.find(iface_name); + if (it != event_handlers_map_.end()) { + event_handlers = it->second; + } + if (event_handlers.on_state_toggle_off_on != nullptr) { + event_handlers.on_state_toggle_off_on(iface_name); + } + if (!success) { + LOG(ERROR) << "SetMacAddress failed on " << iface_name; + } else { + LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name; + } + return success; +} + +std::array WifiIfaceUtil::getOrCreateRandomMacAddress() { + if (random_mac_address_) { + return *random_mac_address_.get(); + } + random_mac_address_ = std::make_unique>(createRandomMacAddress()); + return *random_mac_address_.get(); +} + +void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name, + IfaceEventHandlers handlers) { + event_handlers_map_[iface_name] = handlers; +} + +void WifiIfaceUtil::unregisterIfaceEventHandlers(const std::string& iface_name) { + event_handlers_map_.erase(iface_name); +} + +std::array WifiIfaceUtil::createRandomMacAddress() { + std::array address = {}; + std::random_device rd; + std::default_random_engine engine(rd()); + std::uniform_int_distribution dist(std::numeric_limits::min(), + std::numeric_limits::max()); + for (size_t i = 0; i < address.size(); i++) { + address[i] = dist(engine); + } + // Set the local bit and clear the multicast bit. + address[0] |= kMacAddressLocallyAssignedMask; + address[0] &= ~kMacAddressMulticastMask; + return address; +} + +bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) { + if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) { + LOG(ERROR) << "SetUpState to " << request_up << " failed"; + return false; + } + return true; +} + +unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) { + return if_nametoindex(iface_name.c_str()); +} + +bool WifiIfaceUtil::createBridge(const std::string& br_name) { + if (!iface_tool_.lock()->createBridge(br_name)) { + return false; + } + + if (!iface_tool_.lock()->SetUpState(br_name.c_str(), true)) { + LOG(ERROR) << "bridge SetUpState(true) failed."; + } + return true; +} + +bool WifiIfaceUtil::deleteBridge(const std::string& br_name) { + if (!iface_tool_.lock()->SetUpState(br_name.c_str(), false)) { + LOG(INFO) << "SetUpState(false) failed for bridge=" << br_name.c_str(); + } + + return iface_tool_.lock()->deleteBridge(br_name); +} + +bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, const std::string& if_name) { + return iface_tool_.lock()->addIfaceToBridge(br_name, if_name); +} + +bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, const std::string& if_name) { + return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name); +} + +} // namespace iface_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_iface_util.h b/wifi/1.6/default/wifi_iface_util.h new file mode 100644 index 0000000000..c5db5deed1 --- /dev/null +++ b/wifi/1.6/default/wifi_iface_util.h @@ -0,0 +1,87 @@ +/* + * 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 WIFI_IFACE_UTIL_H_ +#define WIFI_IFACE_UTIL_H_ + +#include + +#include + +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace iface_util { + +// Iface event handlers. +struct IfaceEventHandlers { + // Callback to be invoked when the iface is set down & up for MAC address + // change. + std::function on_state_toggle_off_on; +}; + +/** + * Util class for common iface operations. + */ +class WifiIfaceUtil { + public: + WifiIfaceUtil(const std::weak_ptr iface_tool, + const std::weak_ptr legacy_hal); + virtual ~WifiIfaceUtil() = default; + + virtual std::array getFactoryMacAddress(const std::string& iface_name); + virtual bool setMacAddress(const std::string& iface_name, const std::array& mac); + // Get or create a random MAC address. The MAC address returned from + // this method will remain the same throughout the lifetime of the HAL + // daemon. (So, changes on every reboot) + virtual std::array getOrCreateRandomMacAddress(); + + // Register for any iface event callbacks for the provided interface. + virtual void registerIfaceEventHandlers(const std::string& iface_name, + IfaceEventHandlers handlers); + virtual void unregisterIfaceEventHandlers(const std::string& iface_name); + virtual bool setUpState(const std::string& iface_name, bool request_up); + virtual unsigned ifNameToIndex(const std::string& iface_name); + + virtual bool createBridge(const std::string& br_name); + + virtual bool deleteBridge(const std::string& br_name); + + virtual bool addIfaceToBridge(const std::string& br_name, const std::string& if_name); + + virtual bool removeIfaceFromBridge(const std::string& br_name, const std::string& if_name); + // Get a random MAC address. + virtual std::array createRandomMacAddress(); + + private: + std::weak_ptr iface_tool_; + std::weak_ptr legacy_hal_; + std::unique_ptr> random_mac_address_; + std::map event_handlers_map_; +}; + +} // namespace iface_util +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_IFACE_UTIL_H_ diff --git a/wifi/1.6/default/wifi_legacy_hal.cpp b/wifi/1.6/default/wifi_legacy_hal.cpp new file mode 100644 index 0000000000..e6e8141603 --- /dev/null +++ b/wifi/1.6/default/wifi_legacy_hal.cpp @@ -0,0 +1,1578 @@ +/* + * 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. + */ + +#include +#include + +#include +#include +#include + +#include "hidl_sync_util.h" +#include "wifi_legacy_hal.h" +#include "wifi_legacy_hal_stubs.h" + +namespace { +// Constants ported over from the legacy HAL calling code +// (com_android_server_wifi_WifiNative.cpp). This will all be thrown +// away when this shim layer is replaced by the real vendor +// implementation. +static constexpr uint32_t kMaxVersionStringLength = 256; +static constexpr uint32_t kMaxCachedGscanResults = 64; +static constexpr uint32_t kMaxGscanFrequenciesForBand = 64; +static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128; +static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32; +static constexpr uint32_t kMaxRingBuffers = 10; +static constexpr uint32_t kMaxWifiUsableChannels = 256; +// need a long timeout (1000ms) for chips that unload their driver. +static constexpr uint32_t kMaxStopCompleteWaitMs = 1000; +static constexpr char kDriverPropName[] = "wlan.driver.status"; + +// Helper function to create a non-const char* for legacy Hal API's. +std::vector makeCharVec(const std::string& str) { + std::vector vec(str.size() + 1); + vec.assign(str.begin(), str.end()); + vec.push_back('\0'); + return vec; +} +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace legacy_hal { + +// Legacy HAL functions accept "C" style function pointers, so use global +// functions to pass to the legacy HAL function and store the corresponding +// std::function methods to be invoked. +// +// Callback to be invoked once |stop| is complete +std::function on_stop_complete_internal_callback; +void onAsyncStopComplete(wifi_handle handle) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_stop_complete_internal_callback) { + on_stop_complete_internal_callback(handle); + // Invalidate this callback since we don't want this firing again. + on_stop_complete_internal_callback = nullptr; + } +} + +// Callback to be invoked for driver dump. +std::function on_driver_memory_dump_internal_callback; +void onSyncDriverMemoryDump(char* buffer, int buffer_size) { + if (on_driver_memory_dump_internal_callback) { + on_driver_memory_dump_internal_callback(buffer, buffer_size); + } +} + +// Callback to be invoked for firmware dump. +std::function on_firmware_memory_dump_internal_callback; +void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) { + if (on_firmware_memory_dump_internal_callback) { + on_firmware_memory_dump_internal_callback(buffer, buffer_size); + } +} + +// Callback to be invoked for Gscan events. +std::function on_gscan_event_internal_callback; +void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_gscan_event_internal_callback) { + on_gscan_event_internal_callback(id, event); + } +} + +// Callback to be invoked for Gscan full results. +std::function + on_gscan_full_result_internal_callback; +void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result, + uint32_t buckets_scanned) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_gscan_full_result_internal_callback) { + on_gscan_full_result_internal_callback(id, result, buckets_scanned); + } +} + +// Callback to be invoked for link layer stats results. +std::function + on_link_layer_stats_result_internal_callback; +void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios, + wifi_radio_stat* radio_stat) { + if (on_link_layer_stats_result_internal_callback) { + on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, radio_stat); + } +} + +// Callback to be invoked for rssi threshold breach. +std::function + on_rssi_threshold_breached_internal_callback; +void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, int8_t rssi) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_rssi_threshold_breached_internal_callback) { + on_rssi_threshold_breached_internal_callback(id, bssid, rssi); + } +} + +// Callback to be invoked for ring buffer data indication. +std::function + on_ring_buffer_data_internal_callback; +void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size, + wifi_ring_buffer_status* status) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_ring_buffer_data_internal_callback) { + on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, status); + } +} + +// Callback to be invoked for error alert indication. +std::function on_error_alert_internal_callback; +void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, int err_code) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_error_alert_internal_callback) { + on_error_alert_internal_callback(id, buffer, buffer_size, err_code); + } +} + +// Callback to be invoked for radio mode change indication. +std::function + on_radio_mode_change_internal_callback; +void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, wifi_mac_info* mac_infos) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_radio_mode_change_internal_callback) { + on_radio_mode_change_internal_callback(id, num_macs, mac_infos); + } +} + +// Callback to be invoked to report subsystem restart +std::function on_subsystem_restart_internal_callback; +void onAsyncSubsystemRestart(const char* error) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_subsystem_restart_internal_callback) { + on_subsystem_restart_internal_callback(error); + } +} + +// Callback to be invoked for rtt results results. +std::function + on_rtt_results_internal_callback; +void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_rtt_results_internal_callback) { + on_rtt_results_internal_callback(id, num_results, rtt_results); + on_rtt_results_internal_callback = nullptr; + } +} + +// Callbacks for the various NAN operations. +// NOTE: These have very little conversions to perform before invoking the user +// callbacks. +// So, handle all of them here directly to avoid adding an unnecessary layer. +std::function on_nan_notify_response_user_callback; +void onAysncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_notify_response_user_callback && msg) { + on_nan_notify_response_user_callback(id, *msg); + } +} + +std::function on_nan_event_publish_replied_user_callback; +void onAysncNanEventPublishReplied(NanPublishRepliedInd* /* event */) { + LOG(ERROR) << "onAysncNanEventPublishReplied triggered"; +} + +std::function on_nan_event_publish_terminated_user_callback; +void onAysncNanEventPublishTerminated(NanPublishTerminatedInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_publish_terminated_user_callback && event) { + on_nan_event_publish_terminated_user_callback(*event); + } +} + +std::function on_nan_event_match_user_callback; +void onAysncNanEventMatch(NanMatchInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_match_user_callback && event) { + on_nan_event_match_user_callback(*event); + } +} + +std::function on_nan_event_match_expired_user_callback; +void onAysncNanEventMatchExpired(NanMatchExpiredInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_match_expired_user_callback && event) { + on_nan_event_match_expired_user_callback(*event); + } +} + +std::function + on_nan_event_subscribe_terminated_user_callback; +void onAysncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_subscribe_terminated_user_callback && event) { + on_nan_event_subscribe_terminated_user_callback(*event); + } +} + +std::function on_nan_event_followup_user_callback; +void onAysncNanEventFollowup(NanFollowupInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_followup_user_callback && event) { + on_nan_event_followup_user_callback(*event); + } +} + +std::function on_nan_event_disc_eng_event_user_callback; +void onAysncNanEventDiscEngEvent(NanDiscEngEventInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_disc_eng_event_user_callback && event) { + on_nan_event_disc_eng_event_user_callback(*event); + } +} + +std::function on_nan_event_disabled_user_callback; +void onAysncNanEventDisabled(NanDisabledInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_disabled_user_callback && event) { + on_nan_event_disabled_user_callback(*event); + } +} + +std::function on_nan_event_tca_user_callback; +void onAysncNanEventTca(NanTCAInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_tca_user_callback && event) { + on_nan_event_tca_user_callback(*event); + } +} + +std::function on_nan_event_beacon_sdf_payload_user_callback; +void onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_beacon_sdf_payload_user_callback && event) { + on_nan_event_beacon_sdf_payload_user_callback(*event); + } +} + +std::function on_nan_event_data_path_request_user_callback; +void onAysncNanEventDataPathRequest(NanDataPathRequestInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_data_path_request_user_callback && event) { + on_nan_event_data_path_request_user_callback(*event); + } +} +std::function on_nan_event_data_path_confirm_user_callback; +void onAysncNanEventDataPathConfirm(NanDataPathConfirmInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_data_path_confirm_user_callback && event) { + on_nan_event_data_path_confirm_user_callback(*event); + } +} + +std::function on_nan_event_data_path_end_user_callback; +void onAysncNanEventDataPathEnd(NanDataPathEndInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_data_path_end_user_callback && event) { + on_nan_event_data_path_end_user_callback(*event); + } +} + +std::function on_nan_event_transmit_follow_up_user_callback; +void onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_transmit_follow_up_user_callback && event) { + on_nan_event_transmit_follow_up_user_callback(*event); + } +} + +std::function on_nan_event_range_request_user_callback; +void onAysncNanEventRangeRequest(NanRangeRequestInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_range_request_user_callback && event) { + on_nan_event_range_request_user_callback(*event); + } +} + +std::function on_nan_event_range_report_user_callback; +void onAysncNanEventRangeReport(NanRangeReportInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_range_report_user_callback && event) { + on_nan_event_range_report_user_callback(*event); + } +} + +std::function on_nan_event_schedule_update_user_callback; +void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_nan_event_schedule_update_user_callback && event) { + on_nan_event_schedule_update_user_callback(*event); + } +} + +// Callbacks for the various TWT operations. +std::function on_twt_event_setup_response_callback; +void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_twt_event_setup_response_callback && event) { + on_twt_event_setup_response_callback(*event); + } +} + +std::function on_twt_event_teardown_completion_callback; +void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_twt_event_teardown_completion_callback && event) { + on_twt_event_teardown_completion_callback(*event); + } +} + +std::function on_twt_event_info_frame_received_callback; +void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_twt_event_info_frame_received_callback && event) { + on_twt_event_info_frame_received_callback(*event); + } +} + +std::function on_twt_event_device_notify_callback; +void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_twt_event_device_notify_callback && event) { + on_twt_event_device_notify_callback(*event); + } +} + +// End of the free-standing "C" style callbacks. + +WifiLegacyHal::WifiLegacyHal(const std::weak_ptr iface_tool, + const wifi_hal_fn& fn, bool is_primary) + : global_func_table_(fn), + global_handle_(nullptr), + awaiting_event_loop_termination_(false), + is_started_(false), + iface_tool_(iface_tool), + is_primary_(is_primary) {} + +wifi_error WifiLegacyHal::initialize() { + LOG(DEBUG) << "Initialize legacy HAL"; + // this now does nothing, since HAL function table is provided + // to the constructor + return WIFI_SUCCESS; +} + +wifi_error WifiLegacyHal::start() { + // Ensure that we're starting in a good state. + CHECK(global_func_table_.wifi_initialize && !global_handle_ && iface_name_to_handle_.empty() && + !awaiting_event_loop_termination_); + if (is_started_) { + LOG(DEBUG) << "Legacy HAL already started"; + return WIFI_SUCCESS; + } + LOG(DEBUG) << "Waiting for the driver ready"; + wifi_error status = global_func_table_.wifi_wait_for_driver_ready(); + if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) { + LOG(ERROR) << "Failed or timed out awaiting driver ready"; + return status; + } + + if (is_primary_) { + property_set(kDriverPropName, "ok"); + + if (!iface_tool_.lock()->SetWifiUpState(true)) { + LOG(ERROR) << "Failed to set WiFi interface up"; + return WIFI_ERROR_UNKNOWN; + } + } + + LOG(DEBUG) << "Starting legacy HAL"; + status = global_func_table_.wifi_initialize(&global_handle_); + if (status != WIFI_SUCCESS || !global_handle_) { + LOG(ERROR) << "Failed to retrieve global handle"; + return status; + } + std::thread(&WifiLegacyHal::runEventLoop, this).detach(); + status = retrieveIfaceHandles(); + if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) { + LOG(ERROR) << "Failed to retrieve wlan interface handle"; + return status; + } + LOG(DEBUG) << "Legacy HAL start complete"; + is_started_ = true; + return WIFI_SUCCESS; +} + +wifi_error WifiLegacyHal::stop( + /* NONNULL */ std::unique_lock* lock, + const std::function& on_stop_complete_user_callback) { + if (!is_started_) { + LOG(DEBUG) << "Legacy HAL already stopped"; + on_stop_complete_user_callback(); + return WIFI_SUCCESS; + } + LOG(DEBUG) << "Stopping legacy HAL"; + on_stop_complete_internal_callback = [on_stop_complete_user_callback, + this](wifi_handle handle) { + CHECK_EQ(global_handle_, handle) << "Handle mismatch"; + LOG(INFO) << "Legacy HAL stop complete callback received"; + // Invalidate all the internal pointers now that the HAL is + // stopped. + invalidate(); + if (is_primary_) iface_tool_.lock()->SetWifiUpState(false); + on_stop_complete_user_callback(); + is_started_ = false; + }; + awaiting_event_loop_termination_ = true; + global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete); + const auto status = + stop_wait_cv_.wait_for(*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs), + [this] { return !awaiting_event_loop_termination_; }); + if (!status) { + LOG(ERROR) << "Legacy HAL stop failed or timed out"; + return WIFI_ERROR_UNKNOWN; + } + LOG(DEBUG) << "Legacy HAL stop complete"; + return WIFI_SUCCESS; +} + +bool WifiLegacyHal::isStarted() { + return is_started_; +} + +wifi_error WifiLegacyHal::waitForDriverReady() { + return global_func_table_.wifi_wait_for_driver_ready(); +} + +std::pair WifiLegacyHal::getDriverVersion(const std::string& iface_name) { + std::array buffer; + buffer.fill(0); + wifi_error status = global_func_table_.wifi_get_driver_version(getIfaceHandle(iface_name), + buffer.data(), buffer.size()); + return {status, buffer.data()}; +} + +std::pair WifiLegacyHal::getFirmwareVersion( + const std::string& iface_name) { + std::array buffer; + buffer.fill(0); + wifi_error status = global_func_table_.wifi_get_firmware_version(getIfaceHandle(iface_name), + buffer.data(), buffer.size()); + return {status, buffer.data()}; +} + +std::pair> WifiLegacyHal::requestDriverMemoryDump( + const std::string& iface_name) { + std::vector driver_dump; + on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, int buffer_size) { + driver_dump.insert(driver_dump.end(), reinterpret_cast(buffer), + reinterpret_cast(buffer) + buffer_size); + }; + wifi_error status = global_func_table_.wifi_get_driver_memory_dump(getIfaceHandle(iface_name), + {onSyncDriverMemoryDump}); + on_driver_memory_dump_internal_callback = nullptr; + return {status, std::move(driver_dump)}; +} + +std::pair> WifiLegacyHal::requestFirmwareMemoryDump( + const std::string& iface_name) { + std::vector firmware_dump; + on_firmware_memory_dump_internal_callback = [&firmware_dump](char* buffer, int buffer_size) { + firmware_dump.insert(firmware_dump.end(), reinterpret_cast(buffer), + reinterpret_cast(buffer) + buffer_size); + }; + wifi_error status = global_func_table_.wifi_get_firmware_memory_dump( + getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump}); + on_firmware_memory_dump_internal_callback = nullptr; + return {status, std::move(firmware_dump)}; +} + +std::pair WifiLegacyHal::getSupportedFeatureSet( + const std::string& iface_name) { + feature_set set = 0, chip_set = 0; + wifi_error status = WIFI_SUCCESS; + + static_assert(sizeof(set) == sizeof(uint64_t), + "Some feature_flags can not be represented in output"); + wifi_interface_handle iface_handle = getIfaceHandle(iface_name); + + global_func_table_.wifi_get_chip_feature_set( + global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */ + + if (iface_handle) { + status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set); + } + return {status, static_cast(set | chip_set)}; +} + +std::pair WifiLegacyHal::getPacketFilterCapabilities( + const std::string& iface_name) { + PacketFilterCapabilities caps; + wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities( + getIfaceHandle(iface_name), &caps.version, &caps.max_len); + return {status, caps}; +} + +wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name, + const std::vector& program) { + return global_func_table_.wifi_set_packet_filter(getIfaceHandle(iface_name), program.data(), + program.size()); +} + +std::pair> WifiLegacyHal::readApfPacketFilterData( + const std::string& iface_name) { + PacketFilterCapabilities caps; + wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities( + getIfaceHandle(iface_name), &caps.version, &caps.max_len); + if (status != WIFI_SUCCESS) { + return {status, {}}; + } + + // Size the buffer to read the entire program & work memory. + std::vector buffer(caps.max_len); + + status = global_func_table_.wifi_read_packet_filter( + getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), buffer.size()); + return {status, move(buffer)}; +} + +std::pair WifiLegacyHal::getGscanCapabilities( + const std::string& iface_name) { + wifi_gscan_capabilities caps; + wifi_error status = + global_func_table_.wifi_get_gscan_capabilities(getIfaceHandle(iface_name), &caps); + return {status, caps}; +} + +wifi_error WifiLegacyHal::startGscan( + const std::string& iface_name, wifi_request_id id, const wifi_scan_cmd_params& params, + const std::function& on_failure_user_callback, + const on_gscan_results_callback& on_results_user_callback, + const on_gscan_full_result_callback& on_full_result_user_callback) { + // If there is already an ongoing background scan, reject new scan requests. + if (on_gscan_event_internal_callback || on_gscan_full_result_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + + // This callback will be used to either trigger |on_results_user_callback| + // or |on_failure_user_callback|. + on_gscan_event_internal_callback = [iface_name, on_failure_user_callback, + on_results_user_callback, + this](wifi_request_id id, wifi_scan_event event) { + switch (event) { + case WIFI_SCAN_RESULTS_AVAILABLE: + case WIFI_SCAN_THRESHOLD_NUM_SCANS: + case WIFI_SCAN_THRESHOLD_PERCENT: { + wifi_error status; + std::vector cached_scan_results; + std::tie(status, cached_scan_results) = getGscanCachedResults(iface_name); + if (status == WIFI_SUCCESS) { + on_results_user_callback(id, cached_scan_results); + return; + } + FALLTHROUGH_INTENDED; + } + // Fall through if failed. Failure to retrieve cached scan + // results should trigger a background scan failure. + case WIFI_SCAN_FAILED: + on_failure_user_callback(id); + on_gscan_event_internal_callback = nullptr; + on_gscan_full_result_internal_callback = nullptr; + return; + } + LOG(FATAL) << "Unexpected gscan event received: " << event; + }; + + on_gscan_full_result_internal_callback = [on_full_result_user_callback]( + wifi_request_id id, wifi_scan_result* result, + uint32_t buckets_scanned) { + if (result) { + on_full_result_user_callback(id, result, buckets_scanned); + } + }; + + wifi_scan_result_handler handler = {onAsyncGscanFullResult, onAsyncGscanEvent}; + wifi_error status = + global_func_table_.wifi_start_gscan(id, getIfaceHandle(iface_name), params, handler); + if (status != WIFI_SUCCESS) { + on_gscan_event_internal_callback = nullptr; + on_gscan_full_result_internal_callback = nullptr; + } + return status; +} + +wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, wifi_request_id id) { + // If there is no an ongoing background scan, reject stop requests. + // TODO(b/32337212): This needs to be handled by the HIDL object because we + // need to return the NOT_STARTED error code. + if (!on_gscan_event_internal_callback && !on_gscan_full_result_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + wifi_error status = global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name)); + // If the request Id is wrong, don't stop the ongoing background scan. Any + // other error should be treated as the end of background scan. + if (status != WIFI_ERROR_INVALID_REQUEST_ID) { + on_gscan_event_internal_callback = nullptr; + on_gscan_full_result_internal_callback = nullptr; + } + return status; +} + +std::pair> WifiLegacyHal::getValidFrequenciesForBand( + const std::string& iface_name, wifi_band band) { + static_assert(sizeof(uint32_t) >= sizeof(wifi_channel), + "Wifi Channel cannot be represented in output"); + std::vector freqs; + freqs.resize(kMaxGscanFrequenciesForBand); + int32_t num_freqs = 0; + wifi_error status = global_func_table_.wifi_get_valid_channels( + getIfaceHandle(iface_name), band, freqs.size(), + reinterpret_cast(freqs.data()), &num_freqs); + CHECK(num_freqs >= 0 && static_cast(num_freqs) <= kMaxGscanFrequenciesForBand); + freqs.resize(num_freqs); + return {status, std::move(freqs)}; +} + +wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, bool dfs_on) { + return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), dfs_on ? 0 : 1); +} + +wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, bool debug) { + wifi_link_layer_params params; + params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold; + params.aggressive_statistics_gathering = debug; + return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), params); +} + +wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) { + // TODO: Do we care about these responses? + uint32_t clear_mask_rsp; + uint8_t stop_rsp; + return global_func_table_.wifi_clear_link_stats(getIfaceHandle(iface_name), 0xFFFFFFFF, + &clear_mask_rsp, 1, &stop_rsp); +} + +std::pair WifiLegacyHal::getLinkLayerStats( + const std::string& iface_name) { + LinkLayerStats link_stats{}; + LinkLayerStats* link_stats_ptr = &link_stats; + + on_link_layer_stats_result_internal_callback = [&link_stats_ptr]( + wifi_request_id /* id */, + wifi_iface_stat* iface_stats_ptr, + int num_radios, + wifi_radio_stat* radio_stats_ptr) { + wifi_radio_stat* l_radio_stats_ptr; + wifi_peer_info* l_peer_info_stats_ptr; + + if (iface_stats_ptr != nullptr) { + link_stats_ptr->iface = *iface_stats_ptr; + l_peer_info_stats_ptr = iface_stats_ptr->peer_info; + for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) { + WifiPeerInfo peer; + peer.peer_info = *l_peer_info_stats_ptr; + if (l_peer_info_stats_ptr->num_rate > 0) { + /* Copy the rate stats */ + peer.rate_stats.assign( + l_peer_info_stats_ptr->rate_stats, + l_peer_info_stats_ptr->rate_stats + l_peer_info_stats_ptr->num_rate); + } + peer.peer_info.num_rate = 0; + link_stats_ptr->peers.push_back(peer); + l_peer_info_stats_ptr = + (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + sizeof(wifi_peer_info) + + (sizeof(wifi_rate_stat) * + l_peer_info_stats_ptr->num_rate)); + } + link_stats_ptr->iface.num_peers = 0; + } else { + LOG(ERROR) << "Invalid iface stats in link layer stats"; + } + if (num_radios <= 0 || radio_stats_ptr == nullptr) { + LOG(ERROR) << "Invalid radio stats in link layer stats"; + return; + } + l_radio_stats_ptr = radio_stats_ptr; + for (int i = 0; i < num_radios; i++) { + LinkLayerRadioStats radio; + + radio.stats = *l_radio_stats_ptr; + // Copy over the tx level array to the separate vector. + if (l_radio_stats_ptr->num_tx_levels > 0 && + l_radio_stats_ptr->tx_time_per_levels != nullptr) { + radio.tx_time_per_levels.assign( + l_radio_stats_ptr->tx_time_per_levels, + l_radio_stats_ptr->tx_time_per_levels + l_radio_stats_ptr->num_tx_levels); + } + radio.stats.num_tx_levels = 0; + radio.stats.tx_time_per_levels = nullptr; + /* Copy over the channel stat to separate vector */ + if (l_radio_stats_ptr->num_channels > 0) { + /* Copy the channel stats */ + radio.channel_stats.assign( + l_radio_stats_ptr->channels, + l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels); + } + link_stats_ptr->radios.push_back(radio); + l_radio_stats_ptr = + (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) + + (sizeof(wifi_channel_stat) * + l_radio_stats_ptr->num_channels)); + } + }; + + wifi_error status = global_func_table_.wifi_get_link_stats(0, getIfaceHandle(iface_name), + {onSyncLinkLayerStatsResult}); + on_link_layer_stats_result_internal_callback = nullptr; + return {status, link_stats}; +} + +wifi_error WifiLegacyHal::startRssiMonitoring( + const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi, + const on_rssi_threshold_breached_callback& on_threshold_breached_user_callback) { + if (on_rssi_threshold_breached_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + on_rssi_threshold_breached_internal_callback = [on_threshold_breached_user_callback]( + wifi_request_id id, uint8_t* bssid_ptr, + int8_t rssi) { + if (!bssid_ptr) { + return; + } + std::array bssid_arr; + // |bssid_ptr| pointer is assumed to have 6 bytes for the mac + // address. + std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr)); + on_threshold_breached_user_callback(id, bssid_arr, rssi); + }; + wifi_error status = global_func_table_.wifi_start_rssi_monitoring( + id, getIfaceHandle(iface_name), max_rssi, min_rssi, {onAsyncRssiThresholdBreached}); + if (status != WIFI_SUCCESS) { + on_rssi_threshold_breached_internal_callback = nullptr; + } + return status; +} + +wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, wifi_request_id id) { + if (!on_rssi_threshold_breached_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + wifi_error status = + global_func_table_.wifi_stop_rssi_monitoring(id, getIfaceHandle(iface_name)); + // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any + // other error should be treated as the end of background scan. + if (status != WIFI_ERROR_INVALID_REQUEST_ID) { + on_rssi_threshold_breached_internal_callback = nullptr; + } + return status; +} + +std::pair WifiLegacyHal::getRoamingCapabilities( + const std::string& iface_name) { + wifi_roaming_capabilities caps; + wifi_error status = + global_func_table_.wifi_get_roaming_capabilities(getIfaceHandle(iface_name), &caps); + return {status, caps}; +} + +wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name, + const wifi_roaming_config& config) { + wifi_roaming_config config_internal = config; + return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), &config_internal); +} + +wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name, + fw_roaming_state_t state) { + return global_func_table_.wifi_enable_firmware_roaming(getIfaceHandle(iface_name), state); +} + +wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, bool enable) { + return global_func_table_.wifi_configure_nd_offload(getIfaceHandle(iface_name), enable); +} + +wifi_error WifiLegacyHal::startSendingOffloadedPacket(const std::string& iface_name, + uint32_t cmd_id, uint16_t ether_type, + const std::vector& ip_packet_data, + const std::array& src_address, + const std::array& dst_address, + uint32_t period_in_ms) { + std::vector ip_packet_data_internal(ip_packet_data); + std::vector src_address_internal(src_address.data(), + src_address.data() + src_address.size()); + std::vector dst_address_internal(dst_address.data(), + dst_address.data() + dst_address.size()); + return global_func_table_.wifi_start_sending_offloaded_packet( + cmd_id, getIfaceHandle(iface_name), ether_type, ip_packet_data_internal.data(), + ip_packet_data_internal.size(), src_address_internal.data(), + dst_address_internal.data(), period_in_ms); +} + +wifi_error WifiLegacyHal::stopSendingOffloadedPacket(const std::string& iface_name, + uint32_t cmd_id) { + return global_func_table_.wifi_stop_sending_offloaded_packet(cmd_id, + getIfaceHandle(iface_name)); +} + +wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name, + wifi_power_scenario scenario) { + return global_func_table_.wifi_select_tx_power_scenario(getIfaceHandle(iface_name), scenario); +} + +wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) { + return global_func_table_.wifi_reset_tx_power_scenario(getIfaceHandle(iface_name)); +} + +wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, wifi_latency_mode mode) { + return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), mode); +} + +wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode, + uint32_t completion_window) { + return global_func_table_.wifi_set_thermal_mitigation_mode(global_handle_, mode, + completion_window); +} + +wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(uint32_t start, uint32_t end, + uint32_t access_category) { + return global_func_table_.wifi_map_dscp_access_category(global_handle_, start, end, + access_category); +} + +wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() { + return global_func_table_.wifi_reset_dscp_mapping(global_handle_); +} + +std::pair WifiLegacyHal::getLoggerSupportedFeatureSet( + const std::string& iface_name) { + uint32_t supported_feature_flags = 0; + wifi_error status = WIFI_SUCCESS; + + wifi_interface_handle iface_handle = getIfaceHandle(iface_name); + + if (iface_handle) { + status = global_func_table_.wifi_get_logger_supported_feature_set(iface_handle, + &supported_feature_flags); + } + return {status, supported_feature_flags}; +} + +wifi_error WifiLegacyHal::startPktFateMonitoring(const std::string& iface_name) { + return global_func_table_.wifi_start_pkt_fate_monitoring(getIfaceHandle(iface_name)); +} + +std::pair> WifiLegacyHal::getTxPktFates( + const std::string& iface_name) { + std::vector tx_pkt_fates; + tx_pkt_fates.resize(MAX_FATE_LOG_LEN); + size_t num_fates = 0; + wifi_error status = global_func_table_.wifi_get_tx_pkt_fates( + getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), &num_fates); + CHECK(num_fates <= MAX_FATE_LOG_LEN); + tx_pkt_fates.resize(num_fates); + return {status, std::move(tx_pkt_fates)}; +} + +std::pair> WifiLegacyHal::getRxPktFates( + const std::string& iface_name) { + std::vector rx_pkt_fates; + rx_pkt_fates.resize(MAX_FATE_LOG_LEN); + size_t num_fates = 0; + wifi_error status = global_func_table_.wifi_get_rx_pkt_fates( + getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), &num_fates); + CHECK(num_fates <= MAX_FATE_LOG_LEN); + rx_pkt_fates.resize(num_fates); + return {status, std::move(rx_pkt_fates)}; +} + +std::pair WifiLegacyHal::getWakeReasonStats( + const std::string& iface_name) { + WakeReasonStats stats; + stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize); + stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize); + + // This legacy struct needs separate memory to store the variable sized wake + // reason types. + stats.wake_reason_cnt.cmd_event_wake_cnt = + reinterpret_cast(stats.cmd_event_wake_cnt.data()); + stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size(); + stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0; + stats.wake_reason_cnt.driver_fw_local_wake_cnt = + reinterpret_cast(stats.driver_fw_local_wake_cnt.data()); + stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = stats.driver_fw_local_wake_cnt.size(); + stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0; + + wifi_error status = global_func_table_.wifi_get_wake_reason_stats(getIfaceHandle(iface_name), + &stats.wake_reason_cnt); + + CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 && + static_cast(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <= + kMaxWakeReasonStatsArraySize); + stats.cmd_event_wake_cnt.resize(stats.wake_reason_cnt.cmd_event_wake_cnt_used); + stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr; + + CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 && + static_cast(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <= + kMaxWakeReasonStatsArraySize); + stats.driver_fw_local_wake_cnt.resize(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used); + stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr; + + return {status, stats}; +} + +wifi_error WifiLegacyHal::registerRingBufferCallbackHandler( + const std::string& iface_name, const on_ring_buffer_data_callback& on_user_data_callback) { + if (on_ring_buffer_data_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + on_ring_buffer_data_internal_callback = [on_user_data_callback]( + char* ring_name, char* buffer, int buffer_size, + wifi_ring_buffer_status* status) { + if (status && buffer) { + std::vector buffer_vector(reinterpret_cast(buffer), + reinterpret_cast(buffer) + buffer_size); + on_user_data_callback(ring_name, buffer_vector, *status); + } + }; + wifi_error status = global_func_table_.wifi_set_log_handler(0, getIfaceHandle(iface_name), + {onAsyncRingBufferData}); + if (status != WIFI_SUCCESS) { + on_ring_buffer_data_internal_callback = nullptr; + } + return status; +} + +wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(const std::string& iface_name) { + if (!on_ring_buffer_data_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + on_ring_buffer_data_internal_callback = nullptr; + return global_func_table_.wifi_reset_log_handler(0, getIfaceHandle(iface_name)); +} + +std::pair> WifiLegacyHal::getRingBuffersStatus( + const std::string& iface_name) { + std::vector ring_buffers_status; + ring_buffers_status.resize(kMaxRingBuffers); + uint32_t num_rings = kMaxRingBuffers; + wifi_error status = global_func_table_.wifi_get_ring_buffers_status( + getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data()); + CHECK(num_rings <= kMaxRingBuffers); + ring_buffers_status.resize(num_rings); + return {status, std::move(ring_buffers_status)}; +} + +wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name, + const std::string& ring_name, + uint32_t verbose_level, uint32_t max_interval_sec, + uint32_t min_data_size) { + return global_func_table_.wifi_start_logging(getIfaceHandle(iface_name), verbose_level, 0, + max_interval_sec, min_data_size, + makeCharVec(ring_name).data()); +} + +wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name, + const std::string& ring_name) { + return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name), + makeCharVec(ring_name).data()); +} + +wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler( + const std::string& iface_name, const on_error_alert_callback& on_user_alert_callback) { + if (on_error_alert_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + on_error_alert_internal_callback = [on_user_alert_callback](wifi_request_id id, char* buffer, + int buffer_size, int err_code) { + if (buffer) { + CHECK(id == 0); + on_user_alert_callback( + err_code, + std::vector(reinterpret_cast(buffer), + reinterpret_cast(buffer) + buffer_size)); + } + }; + wifi_error status = global_func_table_.wifi_set_alert_handler(0, getIfaceHandle(iface_name), + {onAsyncErrorAlert}); + if (status != WIFI_SUCCESS) { + on_error_alert_internal_callback = nullptr; + } + return status; +} + +wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(const std::string& iface_name) { + if (!on_error_alert_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + on_error_alert_internal_callback = nullptr; + return global_func_table_.wifi_reset_alert_handler(0, getIfaceHandle(iface_name)); +} + +wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler( + const std::string& iface_name, + const on_radio_mode_change_callback& on_user_change_callback) { + if (on_radio_mode_change_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + on_radio_mode_change_internal_callback = [on_user_change_callback]( + wifi_request_id /* id */, uint32_t num_macs, + wifi_mac_info* mac_infos_arr) { + if (num_macs > 0 && mac_infos_arr) { + std::vector mac_infos_vec; + for (uint32_t i = 0; i < num_macs; i++) { + WifiMacInfo mac_info; + mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id; + mac_info.mac_band = mac_infos_arr[i].mac_band; + for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) { + WifiIfaceInfo iface_info; + iface_info.name = mac_infos_arr[i].iface_info[j].iface_name; + iface_info.channel = mac_infos_arr[i].iface_info[j].channel; + mac_info.iface_infos.push_back(iface_info); + } + mac_infos_vec.push_back(mac_info); + } + on_user_change_callback(mac_infos_vec); + } + }; + wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler( + 0, getIfaceHandle(iface_name), {onAsyncRadioModeChange}); + if (status != WIFI_SUCCESS) { + on_radio_mode_change_internal_callback = nullptr; + } + return status; +} + +wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler( + const on_subsystem_restart_callback& on_restart_callback) { + if (on_subsystem_restart_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + on_subsystem_restart_internal_callback = [on_restart_callback](const char* error) { + on_restart_callback(error); + }; + wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler( + global_handle_, {onAsyncSubsystemRestart}); + if (status != WIFI_SUCCESS) { + on_subsystem_restart_internal_callback = nullptr; + } + return status; +} + +wifi_error WifiLegacyHal::startRttRangeRequest( + const std::string& iface_name, wifi_request_id id, + const std::vector& rtt_configs, + const on_rtt_results_callback& on_results_user_callback) { + if (on_rtt_results_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + + on_rtt_results_internal_callback = [on_results_user_callback](wifi_request_id id, + unsigned num_results, + wifi_rtt_result* rtt_results[]) { + if (num_results > 0 && !rtt_results) { + LOG(ERROR) << "Unexpected nullptr in RTT results"; + return; + } + std::vector rtt_results_vec; + std::copy_if(rtt_results, rtt_results + num_results, back_inserter(rtt_results_vec), + [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; }); + on_results_user_callback(id, rtt_results_vec); + }; + + std::vector rtt_configs_internal(rtt_configs); + wifi_error status = global_func_table_.wifi_rtt_range_request( + id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(), + {onAsyncRttResults}); + if (status != WIFI_SUCCESS) { + on_rtt_results_internal_callback = nullptr; + } + return status; +} + +wifi_error WifiLegacyHal::cancelRttRangeRequest( + const std::string& iface_name, wifi_request_id id, + const std::vector>& mac_addrs) { + if (!on_rtt_results_internal_callback) { + return WIFI_ERROR_NOT_AVAILABLE; + } + static_assert(sizeof(mac_addr) == sizeof(std::array), "MAC address size mismatch"); + // TODO: How do we handle partial cancels (i.e only a subset of enabled mac + // addressed are cancelled). + std::vector> mac_addrs_internal(mac_addrs); + wifi_error status = global_func_table_.wifi_rtt_range_cancel( + id, getIfaceHandle(iface_name), mac_addrs.size(), + reinterpret_cast(mac_addrs_internal.data())); + // If the request Id is wrong, don't stop the ongoing range request. Any + // other error should be treated as the end of rtt ranging. + if (status != WIFI_ERROR_INVALID_REQUEST_ID) { + on_rtt_results_internal_callback = nullptr; + } + return status; +} + +std::pair WifiLegacyHal::getRttCapabilities( + const std::string& iface_name) { + wifi_rtt_capabilities rtt_caps; + wifi_error status = + global_func_table_.wifi_get_rtt_capabilities(getIfaceHandle(iface_name), &rtt_caps); + return {status, rtt_caps}; +} + +std::pair WifiLegacyHal::getRttResponderInfo( + const std::string& iface_name) { + wifi_rtt_responder rtt_responder; + wifi_error status = global_func_table_.wifi_rtt_get_responder_info(getIfaceHandle(iface_name), + &rtt_responder); + return {status, rtt_responder}; +} + +wifi_error WifiLegacyHal::enableRttResponder(const std::string& iface_name, wifi_request_id id, + const wifi_channel_info& channel_hint, + uint32_t max_duration_secs, + const wifi_rtt_responder& info) { + wifi_rtt_responder info_internal(info); + return global_func_table_.wifi_enable_responder(id, getIfaceHandle(iface_name), channel_hint, + max_duration_secs, &info_internal); +} + +wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, wifi_request_id id) { + return global_func_table_.wifi_disable_responder(id, getIfaceHandle(iface_name)); +} + +wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, wifi_request_id id, + const wifi_lci_information& info) { + wifi_lci_information info_internal(info); + return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), &info_internal); +} + +wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, wifi_request_id id, + const wifi_lcr_information& info) { + wifi_lcr_information info_internal(info); + return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), &info_internal); +} + +wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(const std::string& iface_name, + const NanCallbackHandlers& user_callbacks) { + on_nan_notify_response_user_callback = user_callbacks.on_notify_response; + on_nan_event_publish_terminated_user_callback = user_callbacks.on_event_publish_terminated; + on_nan_event_match_user_callback = user_callbacks.on_event_match; + on_nan_event_match_expired_user_callback = user_callbacks.on_event_match_expired; + on_nan_event_subscribe_terminated_user_callback = user_callbacks.on_event_subscribe_terminated; + on_nan_event_followup_user_callback = user_callbacks.on_event_followup; + on_nan_event_disc_eng_event_user_callback = user_callbacks.on_event_disc_eng_event; + on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled; + on_nan_event_tca_user_callback = user_callbacks.on_event_tca; + on_nan_event_beacon_sdf_payload_user_callback = user_callbacks.on_event_beacon_sdf_payload; + on_nan_event_data_path_request_user_callback = user_callbacks.on_event_data_path_request; + on_nan_event_data_path_confirm_user_callback = user_callbacks.on_event_data_path_confirm; + on_nan_event_data_path_end_user_callback = user_callbacks.on_event_data_path_end; + on_nan_event_transmit_follow_up_user_callback = user_callbacks.on_event_transmit_follow_up; + on_nan_event_range_request_user_callback = user_callbacks.on_event_range_request; + on_nan_event_range_report_user_callback = user_callbacks.on_event_range_report; + on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update; + + return global_func_table_.wifi_nan_register_handler( + getIfaceHandle(iface_name), + {onAysncNanNotifyResponse, onAysncNanEventPublishReplied, + onAysncNanEventPublishTerminated, onAysncNanEventMatch, onAysncNanEventMatchExpired, + onAysncNanEventSubscribeTerminated, onAysncNanEventFollowup, + onAysncNanEventDiscEngEvent, onAysncNanEventDisabled, onAysncNanEventTca, + onAysncNanEventBeaconSdfPayload, onAysncNanEventDataPathRequest, + onAysncNanEventDataPathConfirm, onAysncNanEventDataPathEnd, + onAysncNanEventTransmitFollowUp, onAysncNanEventRangeRequest, + onAysncNanEventRangeReport, onAsyncNanEventScheduleUpdate}); +} + +wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id, + const NanEnableRequest& msg) { + NanEnableRequest msg_internal(msg); + return global_func_table_.wifi_nan_enable_request(id, getIfaceHandle(iface_name), + &msg_internal); +} + +wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, transaction_id id) { + return global_func_table_.wifi_nan_disable_request(id, getIfaceHandle(iface_name)); +} + +wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, transaction_id id, + const NanPublishRequest& msg) { + NanPublishRequest msg_internal(msg); + return global_func_table_.wifi_nan_publish_request(id, getIfaceHandle(iface_name), + &msg_internal); +} + +wifi_error WifiLegacyHal::nanPublishCancelRequest(const std::string& iface_name, transaction_id id, + const NanPublishCancelRequest& msg) { + NanPublishCancelRequest msg_internal(msg); + return global_func_table_.wifi_nan_publish_cancel_request(id, getIfaceHandle(iface_name), + &msg_internal); +} + +wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, transaction_id id, + const NanSubscribeRequest& msg) { + NanSubscribeRequest msg_internal(msg); + return global_func_table_.wifi_nan_subscribe_request(id, getIfaceHandle(iface_name), + &msg_internal); +} + +wifi_error WifiLegacyHal::nanSubscribeCancelRequest(const std::string& iface_name, + transaction_id id, + const NanSubscribeCancelRequest& msg) { + NanSubscribeCancelRequest msg_internal(msg); + return global_func_table_.wifi_nan_subscribe_cancel_request(id, getIfaceHandle(iface_name), + &msg_internal); +} + +wifi_error WifiLegacyHal::nanTransmitFollowupRequest(const std::string& iface_name, + transaction_id id, + const NanTransmitFollowupRequest& msg) { + NanTransmitFollowupRequest msg_internal(msg); + return global_func_table_.wifi_nan_transmit_followup_request(id, getIfaceHandle(iface_name), + &msg_internal); +} + +wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, transaction_id id, + const NanStatsRequest& msg) { + NanStatsRequest msg_internal(msg); + return global_func_table_.wifi_nan_stats_request(id, getIfaceHandle(iface_name), &msg_internal); +} + +wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, transaction_id id, + const NanConfigRequest& msg) { + NanConfigRequest msg_internal(msg); + return global_func_table_.wifi_nan_config_request(id, getIfaceHandle(iface_name), + &msg_internal); +} + +wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, transaction_id id, + const NanTCARequest& msg) { + NanTCARequest msg_internal(msg); + return global_func_table_.wifi_nan_tca_request(id, getIfaceHandle(iface_name), &msg_internal); +} + +wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(const std::string& iface_name, + transaction_id id, + const NanBeaconSdfPayloadRequest& msg) { + NanBeaconSdfPayloadRequest msg_internal(msg); + return global_func_table_.wifi_nan_beacon_sdf_payload_request(id, getIfaceHandle(iface_name), + &msg_internal); +} + +std::pair WifiLegacyHal::nanGetVersion() { + NanVersion version; + wifi_error status = global_func_table_.wifi_nan_get_version(global_handle_, &version); + return {status, version}; +} + +wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, transaction_id id) { + return global_func_table_.wifi_nan_get_capabilities(id, getIfaceHandle(iface_name)); +} + +wifi_error WifiLegacyHal::nanDataInterfaceCreate(const std::string& iface_name, transaction_id id, + const std::string& data_iface_name) { + return global_func_table_.wifi_nan_data_interface_create(id, getIfaceHandle(iface_name), + makeCharVec(data_iface_name).data()); +} + +wifi_error WifiLegacyHal::nanDataInterfaceDelete(const std::string& iface_name, transaction_id id, + const std::string& data_iface_name) { + return global_func_table_.wifi_nan_data_interface_delete(id, getIfaceHandle(iface_name), + makeCharVec(data_iface_name).data()); +} + +wifi_error WifiLegacyHal::nanDataRequestInitiator(const std::string& iface_name, transaction_id id, + const NanDataPathInitiatorRequest& msg) { + NanDataPathInitiatorRequest msg_internal(msg); + return global_func_table_.wifi_nan_data_request_initiator(id, getIfaceHandle(iface_name), + &msg_internal); +} + +wifi_error WifiLegacyHal::nanDataIndicationResponse(const std::string& iface_name, + transaction_id id, + const NanDataPathIndicationResponse& msg) { + NanDataPathIndicationResponse msg_internal(msg); + return global_func_table_.wifi_nan_data_indication_response(id, getIfaceHandle(iface_name), + &msg_internal); +} + +typedef struct { + u8 num_ndp_instances; + NanDataPathId ndp_instance_id; +} NanDataPathEndSingleNdpIdRequest; + +wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, transaction_id id, + uint32_t ndpInstanceId) { + NanDataPathEndSingleNdpIdRequest msg; + msg.num_ndp_instances = 1; + msg.ndp_instance_id = ndpInstanceId; + wifi_error status = global_func_table_.wifi_nan_data_end(id, getIfaceHandle(iface_name), + (NanDataPathEndRequest*)&msg); + return status; +} + +wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name, + std::array code) { + std::string code_str(code.data(), code.data() + code.size()); + return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), code_str.c_str()); +} + +wifi_error WifiLegacyHal::retrieveIfaceHandles() { + wifi_interface_handle* iface_handles = nullptr; + int num_iface_handles = 0; + wifi_error status = + global_func_table_.wifi_get_ifaces(global_handle_, &num_iface_handles, &iface_handles); + if (status != WIFI_SUCCESS) { + LOG(ERROR) << "Failed to enumerate interface handles"; + return status; + } + iface_name_to_handle_.clear(); + for (int i = 0; i < num_iface_handles; ++i) { + std::array iface_name_arr = {}; + status = global_func_table_.wifi_get_iface_name(iface_handles[i], iface_name_arr.data(), + iface_name_arr.size()); + if (status != WIFI_SUCCESS) { + LOG(WARNING) << "Failed to get interface handle name"; + continue; + } + // Assuming the interface name is null terminated since the legacy HAL + // API does not return a size. + std::string iface_name(iface_name_arr.data()); + LOG(INFO) << "Adding interface handle for " << iface_name; + iface_name_to_handle_[iface_name] = iface_handles[i]; + } + return WIFI_SUCCESS; +} + +wifi_interface_handle WifiLegacyHal::getIfaceHandle(const std::string& iface_name) { + const auto iface_handle_iter = iface_name_to_handle_.find(iface_name); + if (iface_handle_iter == iface_name_to_handle_.end()) { + LOG(ERROR) << "Unknown iface name: " << iface_name; + return nullptr; + } + return iface_handle_iter->second; +} + +void WifiLegacyHal::runEventLoop() { + LOG(DEBUG) << "Starting legacy HAL event loop"; + global_func_table_.wifi_event_loop(global_handle_); + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (!awaiting_event_loop_termination_) { + LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping"; + } + LOG(DEBUG) << "Legacy HAL event loop terminated"; + awaiting_event_loop_termination_ = false; + stop_wait_cv_.notify_one(); +} + +std::pair> WifiLegacyHal::getGscanCachedResults( + const std::string& iface_name) { + std::vector cached_scan_results; + cached_scan_results.resize(kMaxCachedGscanResults); + int32_t num_results = 0; + wifi_error status = global_func_table_.wifi_get_cached_gscan_results( + getIfaceHandle(iface_name), true /* always flush */, cached_scan_results.size(), + cached_scan_results.data(), &num_results); + CHECK(num_results >= 0 && static_cast(num_results) <= kMaxCachedGscanResults); + cached_scan_results.resize(num_results); + // Check for invalid IE lengths in these cached scan results and correct it. + for (auto& cached_scan_result : cached_scan_results) { + int num_scan_results = cached_scan_result.num_results; + for (int i = 0; i < num_scan_results; i++) { + auto& scan_result = cached_scan_result.results[i]; + if (scan_result.ie_length > 0) { + LOG(DEBUG) << "Cached scan result has non-zero IE length " << scan_result.ie_length; + scan_result.ie_length = 0; + } + } + } + return {status, std::move(cached_scan_results)}; +} + +wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname, + wifi_interface_type iftype) { + // Create the interface if it doesn't exist. If interface already exist, + // Vendor Hal should return WIFI_SUCCESS. + wifi_error status = global_func_table_.wifi_virtual_interface_create(global_handle_, + ifname.c_str(), iftype); + return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status); +} + +wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) { + // Delete the interface if it was created dynamically. + wifi_error status = + global_func_table_.wifi_virtual_interface_delete(global_handle_, ifname.c_str()); + return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status); +} + +wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname, + wifi_error status) { + if (status == WIFI_SUCCESS) { + // refresh list of handlers now. + status = retrieveIfaceHandles(); + } else if (status == WIFI_ERROR_NOT_SUPPORTED) { + // Vendor hal does not implement this API. Such vendor implementations + // are expected to create / delete interface by other means. + + // check if interface exists. + if (if_nametoindex(ifname.c_str())) { + status = retrieveIfaceHandles(); + } + } + return status; +} + +wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, std::string& ifname) { + std::array buffer; + + wifi_error res = global_func_table_.wifi_get_supported_iface_name( + global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size()); + if (res == WIFI_SUCCESS) ifname = buffer.data(); + + return res; +} + +wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(const std::string& ifname) { + return global_func_table_.wifi_multi_sta_set_primary_connection(global_handle_, + getIfaceHandle(ifname)); +} + +wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) { + return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, use_case); +} + +wifi_error WifiLegacyHal::setCoexUnsafeChannels( + std::vector unsafe_channels, uint32_t restrictions) { + return global_func_table_.wifi_set_coex_unsafe_channels(global_handle_, unsafe_channels.size(), + unsafe_channels.data(), restrictions); +} + +wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, wifi_voip_mode mode) { + return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode); +} + +wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name, + const TwtCallbackHandlers& user_callbacks) { + on_twt_event_setup_response_callback = user_callbacks.on_setup_response; + on_twt_event_teardown_completion_callback = user_callbacks.on_teardown_completion; + on_twt_event_info_frame_received_callback = user_callbacks.on_info_frame_received; + on_twt_event_device_notify_callback = user_callbacks.on_device_notify; + + return global_func_table_.wifi_twt_register_handler( + getIfaceHandle(iface_name), + {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion, + onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify}); +} + +std::pair WifiLegacyHal::twtGetCapability( + const std::string& iface_name) { + TwtCapabilitySet capSet; + wifi_error status = + global_func_table_.wifi_twt_get_capability(getIfaceHandle(iface_name), &capSet); + return {status, capSet}; +} + +wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name, + const TwtSetupRequest& msg) { + TwtSetupRequest msgInternal(msg); + return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), &msgInternal); +} + +wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name, + const TwtTeardownRequest& msg) { + TwtTeardownRequest msgInternal(msg); + return global_func_table_.wifi_twt_teardown_request(getIfaceHandle(iface_name), &msgInternal); +} + +wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name, + const TwtInfoFrameRequest& msg) { + TwtInfoFrameRequest msgInternal(msg); + return global_func_table_.wifi_twt_info_frame_request(getIfaceHandle(iface_name), &msgInternal); +} + +std::pair WifiLegacyHal::twtGetStats(const std::string& iface_name, + uint8_t configId) { + TwtStats stats; + wifi_error status = + global_func_table_.wifi_twt_get_stats(getIfaceHandle(iface_name), configId, &stats); + return {status, stats}; +} + +wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, uint8_t configId) { + return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), configId); +} + +wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) { + return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), multiplier); +} + +std::pair> WifiLegacyHal::getUsableChannels( + uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask) { + std::vector channels; + channels.resize(kMaxWifiUsableChannels); + uint32_t size = 0; + wifi_error status = global_func_table_.wifi_get_usable_channels( + global_handle_, band_mask, iface_mode_mask, filter_mask, channels.size(), &size, + reinterpret_cast(channels.data())); + CHECK(size >= 0 && size <= kMaxWifiUsableChannels); + channels.resize(size); + return {status, std::move(channels)}; +} + +wifi_error WifiLegacyHal::triggerSubsystemRestart() { + return global_func_table_.wifi_trigger_subsystem_restart(global_handle_); +} + +void WifiLegacyHal::invalidate() { + global_handle_ = nullptr; + iface_name_to_handle_.clear(); + on_driver_memory_dump_internal_callback = nullptr; + on_firmware_memory_dump_internal_callback = nullptr; + on_gscan_event_internal_callback = nullptr; + on_gscan_full_result_internal_callback = nullptr; + on_link_layer_stats_result_internal_callback = nullptr; + on_rssi_threshold_breached_internal_callback = nullptr; + on_ring_buffer_data_internal_callback = nullptr; + on_error_alert_internal_callback = nullptr; + on_radio_mode_change_internal_callback = nullptr; + on_subsystem_restart_internal_callback = nullptr; + on_rtt_results_internal_callback = nullptr; + on_nan_notify_response_user_callback = nullptr; + on_nan_event_publish_terminated_user_callback = nullptr; + on_nan_event_match_user_callback = nullptr; + on_nan_event_match_expired_user_callback = nullptr; + on_nan_event_subscribe_terminated_user_callback = nullptr; + on_nan_event_followup_user_callback = nullptr; + on_nan_event_disc_eng_event_user_callback = nullptr; + on_nan_event_disabled_user_callback = nullptr; + on_nan_event_tca_user_callback = nullptr; + on_nan_event_beacon_sdf_payload_user_callback = nullptr; + on_nan_event_data_path_request_user_callback = nullptr; + on_nan_event_data_path_confirm_user_callback = nullptr; + on_nan_event_data_path_end_user_callback = nullptr; + on_nan_event_transmit_follow_up_user_callback = nullptr; + on_nan_event_range_request_user_callback = nullptr; + on_nan_event_range_report_user_callback = nullptr; + on_nan_event_schedule_update_user_callback = nullptr; + on_twt_event_setup_response_callback = nullptr; + on_twt_event_teardown_completion_callback = nullptr; + on_twt_event_info_frame_received_callback = nullptr; + on_twt_event_device_notify_callback = nullptr; +} + +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_legacy_hal.h b/wifi/1.6/default/wifi_legacy_hal.h new file mode 100644 index 0000000000..d87242cdd5 --- /dev/null +++ b/wifi/1.6/default/wifi_legacy_hal.h @@ -0,0 +1,700 @@ +/* + * 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. + */ + +#ifndef WIFI_LEGACY_HAL_H_ +#define WIFI_LEGACY_HAL_H_ + +#include +#include +#include +#include +#include + +#include +#include + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +// This is in a separate namespace to prevent typename conflicts between +// the legacy HAL types and the HIDL interface types. +namespace legacy_hal { +// Import all the types defined inside the legacy HAL header files into this +// namespace. +using ::frame_info; +using ::frame_type; +using ::FRAME_TYPE_80211_MGMT; +using ::FRAME_TYPE_ETHERNET_II; +using ::FRAME_TYPE_UNKNOWN; +using ::fw_roaming_state_t; +using ::mac_addr; +using ::NAN_CHANNEL_24G_BAND; +using ::NAN_CHANNEL_5G_BAND_HIGH; +using ::NAN_CHANNEL_5G_BAND_LOW; +using ::NAN_DISABLE_RANGE_REPORT; +using ::NAN_DO_NOT_USE_SRF; +using ::NAN_DP_CHANNEL_NOT_REQUESTED; +using ::NAN_DP_CONFIG_NO_SECURITY; +using ::NAN_DP_CONFIG_SECURITY; +using ::NAN_DP_END; +using ::NAN_DP_FORCE_CHANNEL_SETUP; +using ::NAN_DP_INITIATOR_RESPONSE; +using ::NAN_DP_INTERFACE_CREATE; +using ::NAN_DP_INTERFACE_DELETE; +using ::NAN_DP_REQUEST_ACCEPT; +using ::NAN_DP_REQUEST_CHANNEL_SETUP; +using ::NAN_DP_REQUEST_REJECT; +using ::NAN_DP_RESPONDER_RESPONSE; +using ::NAN_GET_CAPABILITIES; +using ::NAN_MATCH_ALG_MATCH_CONTINUOUS; +using ::NAN_MATCH_ALG_MATCH_NEVER; +using ::NAN_MATCH_ALG_MATCH_ONCE; +using ::NAN_PUBLISH_TYPE_SOLICITED; +using ::NAN_PUBLISH_TYPE_UNSOLICITED; +using ::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED; +using ::NAN_RANGING_AUTO_RESPONSE_DISABLE; +using ::NAN_RANGING_AUTO_RESPONSE_ENABLE; +using ::NAN_RANGING_DISABLE; +using ::NAN_RANGING_ENABLE; +using ::NAN_RESPONSE_BEACON_SDF_PAYLOAD; +using ::NAN_RESPONSE_CONFIG; +using ::NAN_RESPONSE_DISABLED; +using ::NAN_RESPONSE_ENABLED; +using ::NAN_RESPONSE_ERROR; +using ::NAN_RESPONSE_PUBLISH; +using ::NAN_RESPONSE_PUBLISH_CANCEL; +using ::NAN_RESPONSE_STATS; +using ::NAN_RESPONSE_SUBSCRIBE; +using ::NAN_RESPONSE_SUBSCRIBE_CANCEL; +using ::NAN_RESPONSE_TCA; +using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP; +using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE; +using ::NAN_SECURITY_KEY_INPUT_PMK; +using ::NAN_SERVICE_ACCEPT_POLICY_ALL; +using ::NAN_SERVICE_ACCEPT_POLICY_NONE; +using ::NAN_SRF_ATTR_BLOOM_FILTER; +using ::NAN_SRF_ATTR_PARTIAL_MAC_ADDR; +using ::NAN_SRF_INCLUDE_DO_NOT_RESPOND; +using ::NAN_SRF_INCLUDE_RESPOND; +using ::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND; +using ::NAN_SSI_REQUIRED_IN_MATCH_IND; +using ::NAN_STATUS_ALREADY_ENABLED; +using ::NAN_STATUS_FOLLOWUP_QUEUE_FULL; +using ::NAN_STATUS_INTERNAL_FAILURE; +using ::NAN_STATUS_INVALID_NDP_ID; +using ::NAN_STATUS_INVALID_PARAM; +using ::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID; +using ::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID; +using ::NAN_STATUS_NAN_NOT_ALLOWED; +using ::NAN_STATUS_NO_OTA_ACK; +using ::NAN_STATUS_NO_RESOURCE_AVAILABLE; +using ::NAN_STATUS_PROTOCOL_FAILURE; +using ::NAN_STATUS_SUCCESS; +using ::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED; +using ::NAN_SUBSCRIBE_TYPE_ACTIVE; +using ::NAN_SUBSCRIBE_TYPE_PASSIVE; +using ::NAN_TRANSMIT_IN_DW; +using ::NAN_TRANSMIT_IN_FAW; +using ::NAN_TX_PRIORITY_HIGH; +using ::NAN_TX_PRIORITY_NORMAL; +using ::NAN_TX_TYPE_BROADCAST; +using ::NAN_TX_TYPE_UNICAST; +using ::NAN_USE_SRF; +using ::NanBeaconSdfPayloadInd; +using ::NanCapabilities; +using ::NanChannelInfo; +using ::NanConfigRequest; +using ::NanDataPathChannelCfg; +using ::NanDataPathConfirmInd; +using ::NanDataPathEndInd; +using ::NanDataPathIndicationResponse; +using ::NanDataPathInitiatorRequest; +using ::NanDataPathRequestInd; +using ::NanDataPathScheduleUpdateInd; +using ::NanDisabledInd; +using ::NanDiscEngEventInd; +using ::NanEnableRequest; +using ::NanFollowupInd; +using ::NanMatchAlg; +using ::NanMatchExpiredInd; +using ::NanMatchInd; +using ::NanPublishCancelRequest; +using ::NanPublishRequest; +using ::NanPublishTerminatedInd; +using ::NanPublishType; +using ::NanRangeReportInd; +using ::NanRangeRequestInd; +using ::NanResponseMsg; +using ::NanSRFType; +using ::NanStatusType; +using ::NanSubscribeCancelRequest; +using ::NanSubscribeRequest; +using ::NanSubscribeTerminatedInd; +using ::NanSubscribeType; +using ::NanTransmitFollowupInd; +using ::NanTransmitFollowupRequest; +using ::NanTxType; +using ::ROAMING_DISABLE; +using ::ROAMING_ENABLE; +using ::RTT_PEER_AP; +using ::RTT_PEER_NAN; +using ::RTT_PEER_P2P_CLIENT; +using ::RTT_PEER_P2P_GO; +using ::RTT_PEER_STA; +using ::rtt_peer_type; +using ::RTT_STATUS_ABORTED; +using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL; +using ::RTT_STATUS_FAIL_BUSY_TRY_LATER; +using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE; +using ::RTT_STATUS_FAIL_INVALID_TS; +using ::RTT_STATUS_FAIL_NO_CAPABILITY; +using ::RTT_STATUS_FAIL_NO_RSP; +using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET; +using ::RTT_STATUS_FAIL_PROTOCOL; +using ::RTT_STATUS_FAIL_REJECTED; +using ::RTT_STATUS_FAIL_SCHEDULE; +using ::RTT_STATUS_FAIL_TM_TIMEOUT; +using ::RTT_STATUS_FAILURE; +using ::RTT_STATUS_INVALID_REQ; +using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED; +using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE; +using ::RTT_STATUS_NO_WIFI; +using ::RTT_STATUS_SUCCESS; +using ::RTT_TYPE_1_SIDED; +using ::RTT_TYPE_2_SIDED; +using ::RX_PKT_FATE_DRV_DROP_FILTER; +using ::RX_PKT_FATE_DRV_DROP_INVALID; +using ::RX_PKT_FATE_DRV_DROP_NOBUFS; +using ::RX_PKT_FATE_DRV_DROP_OTHER; +using ::RX_PKT_FATE_DRV_QUEUED; +using ::RX_PKT_FATE_FW_DROP_FILTER; +using ::RX_PKT_FATE_FW_DROP_INVALID; +using ::RX_PKT_FATE_FW_DROP_NOBUFS; +using ::RX_PKT_FATE_FW_DROP_OTHER; +using ::RX_PKT_FATE_FW_QUEUED; +using ::RX_PKT_FATE_SUCCESS; +using ::ssid_t; +using ::transaction_id; +using ::TX_PKT_FATE_ACKED; +using ::TX_PKT_FATE_DRV_DROP_INVALID; +using ::TX_PKT_FATE_DRV_DROP_NOBUFS; +using ::TX_PKT_FATE_DRV_DROP_OTHER; +using ::TX_PKT_FATE_DRV_QUEUED; +using ::TX_PKT_FATE_FW_DROP_INVALID; +using ::TX_PKT_FATE_FW_DROP_NOBUFS; +using ::TX_PKT_FATE_FW_DROP_OTHER; +using ::TX_PKT_FATE_FW_QUEUED; +using ::TX_PKT_FATE_SENT; +using ::WIFI_AC_BE; +using ::WIFI_AC_BK; +using ::WIFI_AC_VI; +using ::WIFI_AC_VO; +using ::wifi_band; +using ::WIFI_BAND_A; +using ::WIFI_BAND_A_DFS; +using ::WIFI_BAND_A_WITH_DFS; +using ::WIFI_BAND_ABG; +using ::WIFI_BAND_ABG_WITH_DFS; +using ::WIFI_BAND_BG; +using ::WIFI_BAND_UNSPECIFIED; +using ::wifi_cached_scan_results; +using ::WIFI_CHAN_WIDTH_10; +using ::WIFI_CHAN_WIDTH_160; +using ::WIFI_CHAN_WIDTH_20; +using ::WIFI_CHAN_WIDTH_40; +using ::WIFI_CHAN_WIDTH_5; +using ::WIFI_CHAN_WIDTH_80; +using ::WIFI_CHAN_WIDTH_80P80; +using ::WIFI_CHAN_WIDTH_INVALID; +using ::wifi_channel_info; +using ::wifi_channel_stat; +using ::wifi_channel_width; +using ::wifi_coex_restriction; +using ::wifi_coex_unsafe_channel; +using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED; +using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY; +using ::wifi_error; +using ::WIFI_ERROR_BUSY; +using ::WIFI_ERROR_INVALID_ARGS; +using ::WIFI_ERROR_INVALID_REQUEST_ID; +using ::WIFI_ERROR_NONE; +using ::WIFI_ERROR_NOT_AVAILABLE; +using ::WIFI_ERROR_NOT_SUPPORTED; +using ::WIFI_ERROR_OUT_OF_MEMORY; +using ::WIFI_ERROR_TIMED_OUT; +using ::WIFI_ERROR_TOO_MANY_REQUESTS; +using ::WIFI_ERROR_UNINITIALIZED; +using ::WIFI_ERROR_UNKNOWN; +using ::wifi_gscan_capabilities; +using ::wifi_hal_fn; +using ::wifi_information_element; +using ::WIFI_INTERFACE_IBSS; +using ::WIFI_INTERFACE_MESH; +using ::wifi_interface_mode; +using ::WIFI_INTERFACE_NAN; +using ::WIFI_INTERFACE_P2P_CLIENT; +using ::WIFI_INTERFACE_P2P_GO; +using ::WIFI_INTERFACE_SOFTAP; +using ::WIFI_INTERFACE_STA; +using ::WIFI_INTERFACE_TDLS; +using ::wifi_interface_type; +using ::WIFI_INTERFACE_TYPE_AP; +using ::WIFI_INTERFACE_TYPE_NAN; +using ::WIFI_INTERFACE_TYPE_P2P; +using ::WIFI_INTERFACE_TYPE_STA; +using ::WIFI_INTERFACE_UNKNOWN; +using ::wifi_latency_mode; +using ::WIFI_LATENCY_MODE_LOW; +using ::WIFI_LATENCY_MODE_NORMAL; +using ::wifi_lci_information; +using ::wifi_lcr_information; +using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED; +using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; +using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED; +using ::WIFI_LOGGER_PACKET_FATE_SUPPORTED; +using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED; +using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED; +using ::WIFI_MOTION_EXPECTED; +using ::WIFI_MOTION_NOT_EXPECTED; +using ::wifi_motion_pattern; +using ::WIFI_MOTION_UNKNOWN; +using ::wifi_multi_sta_use_case; +using ::wifi_power_scenario; +using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF; +using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON; +using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF; +using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON; +using ::WIFI_POWER_SCENARIO_VOICE_CALL; +using ::wifi_rate; +using ::wifi_request_id; +using ::wifi_ring_buffer_status; +using ::wifi_roaming_capabilities; +using ::wifi_roaming_config; +using ::wifi_rtt_bw; +using ::WIFI_RTT_BW_10; +using ::WIFI_RTT_BW_160; +using ::WIFI_RTT_BW_20; +using ::WIFI_RTT_BW_40; +using ::WIFI_RTT_BW_5; +using ::WIFI_RTT_BW_80; +using ::wifi_rtt_capabilities; +using ::wifi_rtt_config; +using ::wifi_rtt_preamble; +using ::WIFI_RTT_PREAMBLE_HE; +using ::WIFI_RTT_PREAMBLE_HT; +using ::WIFI_RTT_PREAMBLE_LEGACY; +using ::WIFI_RTT_PREAMBLE_VHT; +using ::wifi_rtt_responder; +using ::wifi_rtt_result; +using ::wifi_rtt_status; +using ::wifi_rtt_type; +using ::wifi_rx_packet_fate; +using ::wifi_rx_report; +using ::wifi_scan_bucket_spec; +using ::wifi_scan_cmd_params; +using ::WIFI_SCAN_FLAG_INTERRUPTED; +using ::wifi_scan_result; +using ::WIFI_SUCCESS; +using ::wifi_tx_packet_fate; +using ::wifi_tx_report; +using ::wifi_usable_channel; +using ::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE; +using ::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY; +using ::WLAN_MAC_2_4_BAND; +using ::WLAN_MAC_5_0_BAND; +using ::WLAN_MAC_60_0_BAND; +using ::WLAN_MAC_6_0_BAND; + +// APF capabilities supported by the iface. +struct PacketFilterCapabilities { + uint32_t version; + uint32_t max_len; +}; + +// WARNING: We don't care about the variable sized members of either +// |wifi_iface_stat|, |wifi_radio_stat| structures. So, using the pragma +// to escape the compiler warnings regarding this. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wgnu-variable-sized-type-not-at-end" +// The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in +// |wifi_radio_stat| structure in the legacy HAL API. Separate that out +// into a separate return element to avoid passing pointers around. +struct LinkLayerRadioStats { + wifi_radio_stat stats; + std::vector tx_time_per_levels; + std::vector channel_stats; +}; + +struct WifiPeerInfo { + wifi_peer_info peer_info; + std::vector rate_stats; +}; + +struct LinkLayerStats { + wifi_iface_stat iface; + std::vector radios; + std::vector peers; +}; +#pragma GCC diagnostic pop + +// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and +// |WLAN_DRIVER_WAKE_REASON_CNT.driver_fw_local_wake_cnt| stats is provided +// as a pointer in |WLAN_DRIVER_WAKE_REASON_CNT| structure in the legacy HAL +// API. Separate that out into a separate return elements to avoid passing +// pointers around. +struct WakeReasonStats { + WLAN_DRIVER_WAKE_REASON_CNT wake_reason_cnt; + std::vector cmd_event_wake_cnt; + std::vector driver_fw_local_wake_cnt; +}; + +// NAN response and event callbacks struct. +struct NanCallbackHandlers { + // NotifyResponse invoked to notify the status of the Request. + std::function on_notify_response; + // Various event callbacks. + std::function on_event_publish_terminated; + std::function on_event_match; + std::function on_event_match_expired; + std::function on_event_subscribe_terminated; + std::function on_event_followup; + std::function on_event_disc_eng_event; + std::function on_event_disabled; + std::function on_event_tca; + std::function on_event_beacon_sdf_payload; + std::function on_event_data_path_request; + std::function on_event_data_path_confirm; + std::function on_event_data_path_end; + std::function on_event_transmit_follow_up; + std::function on_event_range_request; + std::function on_event_range_report; + std::function on_event_schedule_update; +}; + +// Full scan results contain IE info and are hence passed by reference, to +// preserve the variable length array member |ie_data|. Callee must not retain +// the pointer. +using on_gscan_full_result_callback = + std::function; +// These scan results don't contain any IE info, so no need to pass by +// reference. +using on_gscan_results_callback = + std::function&)>; + +// Invoked when the rssi value breaches the thresholds set. +using on_rssi_threshold_breached_callback = + std::function, int8_t)>; + +// Callback for RTT range request results. +// Rtt results contain IE info and are hence passed by reference, to +// preserve the |LCI| and |LCR| pointers. Callee must not retain +// the pointer. +using on_rtt_results_callback = + std::function&)>; + +// Callback for ring buffer data. +using on_ring_buffer_data_callback = std::function&, const wifi_ring_buffer_status&)>; + +// Callback for alerts. +using on_error_alert_callback = std::function&)>; + +// Callback for subsystem restart +using on_subsystem_restart_callback = std::function; + +// Struct for the mac info from the legacy HAL. This is a cleaner version +// of the |wifi_mac_info| & |wifi_iface_info|. +typedef struct { + std::string name; + wifi_channel channel; +} WifiIfaceInfo; + +typedef struct { + uint32_t wlan_mac_id; + /* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */ + uint32_t mac_band; + /* Represents the connected Wi-Fi interfaces associated with each MAC */ + std::vector iface_infos; +} WifiMacInfo; + +// Callback for radio mode change +using on_radio_mode_change_callback = std::function&)>; + +// TWT response and event callbacks struct. +struct TwtCallbackHandlers { + // Callback for TWT setup response + std::function on_setup_response; + // Callback for TWT teardown completion + std::function on_teardown_completion; + // Callback for TWT info frame received event + std::function on_info_frame_received; + // Callback for TWT notification from the device + std::function on_device_notify; +}; + +/** + * Class that encapsulates all legacy HAL interactions. + * This class manages the lifetime of the event loop thread used by legacy HAL. + * + * Note: There will only be a single instance of this class created in the Wifi + * object and will be valid for the lifetime of the process. + */ +class WifiLegacyHal { + public: + WifiLegacyHal(const std::weak_ptr iface_tool, const wifi_hal_fn& fn, + bool is_primary); + virtual ~WifiLegacyHal() = default; + + // Initialize the legacy HAL function table. + virtual wifi_error initialize(); + // Start the legacy HAL and the event looper thread. + virtual wifi_error start(); + // Deinitialize the legacy HAL and wait for the event loop thread to exit + // using a predefined timeout. + virtual wifi_error stop(std::unique_lock* lock, + const std::function& on_complete_callback); + virtual wifi_error waitForDriverReady(); + // Checks if legacy HAL has successfully started + bool isStarted(); + // Wrappers for all the functions in the legacy HAL function table. + virtual std::pair getDriverVersion(const std::string& iface_name); + virtual std::pair getFirmwareVersion(const std::string& iface_name); + std::pair> requestDriverMemoryDump( + const std::string& iface_name); + std::pair> requestFirmwareMemoryDump( + const std::string& iface_name); + std::pair getSupportedFeatureSet(const std::string& iface_name); + // APF functions. + std::pair getPacketFilterCapabilities( + const std::string& iface_name); + wifi_error setPacketFilter(const std::string& iface_name, const std::vector& program); + std::pair> readApfPacketFilterData( + const std::string& iface_name); + // Gscan functions. + std::pair getGscanCapabilities( + const std::string& iface_name); + // These API's provides a simplified interface over the legacy Gscan API's: + // a) All scan events from the legacy HAL API other than the + // |WIFI_SCAN_FAILED| are treated as notification of results. + // This method then retrieves the cached scan results from the legacy + // HAL API and triggers the externally provided + // |on_results_user_callback| on success. + // b) |WIFI_SCAN_FAILED| scan event or failure to retrieve cached scan + // results + // triggers the externally provided |on_failure_user_callback|. + // c) Full scan result event triggers the externally provided + // |on_full_result_user_callback|. + wifi_error startGscan(const std::string& iface_name, wifi_request_id id, + const wifi_scan_cmd_params& params, + const std::function& on_failure_callback, + const on_gscan_results_callback& on_results_callback, + const on_gscan_full_result_callback& on_full_result_callback); + wifi_error stopGscan(const std::string& iface_name, wifi_request_id id); + std::pair> getValidFrequenciesForBand( + const std::string& iface_name, wifi_band band); + virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on); + // Link layer stats functions. + wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug); + wifi_error disableLinkLayerStats(const std::string& iface_name); + std::pair getLinkLayerStats(const std::string& iface_name); + // RSSI monitor functions. + wifi_error startRssiMonitoring( + const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi, + const on_rssi_threshold_breached_callback& on_threshold_breached_callback); + wifi_error stopRssiMonitoring(const std::string& iface_name, wifi_request_id id); + std::pair getRoamingCapabilities( + const std::string& iface_name); + wifi_error configureRoaming(const std::string& iface_name, const wifi_roaming_config& config); + wifi_error enableFirmwareRoaming(const std::string& iface_name, fw_roaming_state_t state); + wifi_error configureNdOffload(const std::string& iface_name, bool enable); + wifi_error startSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id, + uint16_t ether_type, + const std::vector& ip_packet_data, + const std::array& src_address, + const std::array& dst_address, + uint32_t period_in_ms); + wifi_error stopSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id); + virtual wifi_error selectTxPowerScenario(const std::string& iface_name, + wifi_power_scenario scenario); + virtual wifi_error resetTxPowerScenario(const std::string& iface_name); + wifi_error setLatencyMode(const std::string& iface_name, wifi_latency_mode mode); + wifi_error setThermalMitigationMode(wifi_thermal_mode mode, uint32_t completion_window); + wifi_error setDscpToAccessCategoryMapping(uint32_t start, uint32_t end, + uint32_t access_category); + wifi_error resetDscpToAccessCategoryMapping(); + // Logger/debug functions. + std::pair getLoggerSupportedFeatureSet(const std::string& iface_name); + wifi_error startPktFateMonitoring(const std::string& iface_name); + std::pair> getTxPktFates(const std::string& iface_name); + std::pair> getRxPktFates(const std::string& iface_name); + std::pair getWakeReasonStats(const std::string& iface_name); + wifi_error registerRingBufferCallbackHandler( + const std::string& iface_name, const on_ring_buffer_data_callback& on_data_callback); + wifi_error deregisterRingBufferCallbackHandler(const std::string& iface_name); + wifi_error registerSubsystemRestartCallbackHandler( + const on_subsystem_restart_callback& on_restart_callback); + std::pair> getRingBuffersStatus( + const std::string& iface_name); + wifi_error startRingBufferLogging(const std::string& iface_name, const std::string& ring_name, + uint32_t verbose_level, uint32_t max_interval_sec, + uint32_t min_data_size); + wifi_error getRingBufferData(const std::string& iface_name, const std::string& ring_name); + wifi_error registerErrorAlertCallbackHandler(const std::string& iface_name, + const on_error_alert_callback& on_alert_callback); + wifi_error deregisterErrorAlertCallbackHandler(const std::string& iface_name); + // Radio mode functions. + virtual wifi_error registerRadioModeChangeCallbackHandler( + const std::string& iface_name, + const on_radio_mode_change_callback& on_user_change_callback); + // RTT functions. + wifi_error startRttRangeRequest(const std::string& iface_name, wifi_request_id id, + const std::vector& rtt_configs, + const on_rtt_results_callback& on_results_callback); + wifi_error cancelRttRangeRequest(const std::string& iface_name, wifi_request_id id, + const std::vector>& mac_addrs); + std::pair getRttCapabilities(const std::string& iface_name); + std::pair getRttResponderInfo(const std::string& iface_name); + wifi_error enableRttResponder(const std::string& iface_name, wifi_request_id id, + const wifi_channel_info& channel_hint, uint32_t max_duration_secs, + const wifi_rtt_responder& info); + wifi_error disableRttResponder(const std::string& iface_name, wifi_request_id id); + wifi_error setRttLci(const std::string& iface_name, wifi_request_id id, + const wifi_lci_information& info); + wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id, + const wifi_lcr_information& info); + // NAN functions. + virtual wifi_error nanRegisterCallbackHandlers(const std::string& iface_name, + const NanCallbackHandlers& callbacks); + wifi_error nanEnableRequest(const std::string& iface_name, transaction_id id, + const NanEnableRequest& msg); + virtual wifi_error nanDisableRequest(const std::string& iface_name, transaction_id id); + wifi_error nanPublishRequest(const std::string& iface_name, transaction_id id, + const NanPublishRequest& msg); + wifi_error nanPublishCancelRequest(const std::string& iface_name, transaction_id id, + const NanPublishCancelRequest& msg); + wifi_error nanSubscribeRequest(const std::string& iface_name, transaction_id id, + const NanSubscribeRequest& msg); + wifi_error nanSubscribeCancelRequest(const std::string& iface_name, transaction_id id, + const NanSubscribeCancelRequest& msg); + wifi_error nanTransmitFollowupRequest(const std::string& iface_name, transaction_id id, + const NanTransmitFollowupRequest& msg); + wifi_error nanStatsRequest(const std::string& iface_name, transaction_id id, + const NanStatsRequest& msg); + wifi_error nanConfigRequest(const std::string& iface_name, transaction_id id, + const NanConfigRequest& msg); + wifi_error nanTcaRequest(const std::string& iface_name, transaction_id id, + const NanTCARequest& msg); + wifi_error nanBeaconSdfPayloadRequest(const std::string& iface_name, transaction_id id, + const NanBeaconSdfPayloadRequest& msg); + std::pair nanGetVersion(); + wifi_error nanGetCapabilities(const std::string& iface_name, transaction_id id); + wifi_error nanDataInterfaceCreate(const std::string& iface_name, transaction_id id, + const std::string& data_iface_name); + virtual wifi_error nanDataInterfaceDelete(const std::string& iface_name, transaction_id id, + const std::string& data_iface_name); + wifi_error nanDataRequestInitiator(const std::string& iface_name, transaction_id id, + const NanDataPathInitiatorRequest& msg); + wifi_error nanDataIndicationResponse(const std::string& iface_name, transaction_id id, + const NanDataPathIndicationResponse& msg); + wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, uint32_t ndpInstanceId); + // AP functions. + wifi_error setCountryCode(const std::string& iface_name, std::array code); + + // interface functions. + virtual wifi_error createVirtualInterface(const std::string& ifname, + wifi_interface_type iftype); + virtual wifi_error deleteVirtualInterface(const std::string& ifname); + wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname); + + // STA + STA functions + virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname); + virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case); + + // Coex functions. + virtual wifi_error setCoexUnsafeChannels(std::vector unsafe_channels, + uint32_t restrictions); + + wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode); + + wifi_error twtRegisterHandler(const std::string& iface_name, + const TwtCallbackHandlers& handler); + + std::pair twtGetCapability(const std::string& iface_name); + + wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg); + + wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg); + + wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg); + + std::pair twtGetStats(const std::string& iface_name, uint8_t configId); + + wifi_error twtClearStats(const std::string& iface_name, uint8_t configId); + + wifi_error setDtimConfig(const std::string& iface_name, uint32_t multiplier); + + // Retrieve the list of usable channels in the requested bands + // for the requested modes + std::pair> getUsableChannels( + uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask); + + wifi_error triggerSubsystemRestart(); + + private: + // Retrieve interface handles for all the available interfaces. + wifi_error retrieveIfaceHandles(); + wifi_interface_handle getIfaceHandle(const std::string& iface_name); + // Run the legacy HAL event loop thread. + void runEventLoop(); + // Retrieve the cached gscan results to pass the results back to the + // external callbacks. + std::pair> getGscanCachedResults( + const std::string& iface_name); + void invalidate(); + // Handles wifi (error) status of Virtual interface create/delete + wifi_error handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname, + wifi_error status); + + // Global function table of legacy HAL. + wifi_hal_fn global_func_table_; + // Opaque handle to be used for all global operations. + wifi_handle global_handle_; + // Map of interface name to handle that is to be used for all interface + // specific operations. + std::map iface_name_to_handle_; + // Flag to indicate if we have initiated the cleanup of legacy HAL. + std::atomic awaiting_event_loop_termination_; + std::condition_variable_any stop_wait_cv_; + // Flag to indicate if the legacy HAL has been started. + bool is_started_; + std::weak_ptr iface_tool_; + // flag to indicate if this HAL is for the primary chip. This is used + // in order to avoid some hard-coded behavior used with older HALs, + // such as bring wlan0 interface up/down on start/stop HAL. + // it may be removed once vendor HALs are updated. + bool is_primary_; +}; + +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_LEGACY_HAL_H_ diff --git a/wifi/1.6/default/wifi_legacy_hal_factory.cpp b/wifi/1.6/default/wifi_legacy_hal_factory.cpp new file mode 100644 index 0000000000..147bf4d7cc --- /dev/null +++ b/wifi/1.6/default/wifi_legacy_hal_factory.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "wifi_legacy_hal_factory.h" +#include "wifi_legacy_hal_stubs.h" + +namespace { +static constexpr char kVendorHalsDescPath[] = "/vendor/etc/wifi/vendor_hals"; +static constexpr char kVendorHalsDescExt[] = ".xml"; +static constexpr uint32_t kVendorHalsDescVersion = 1; + +bool isDirectory(struct dirent* entryPtr) { + bool isDir = false; + if (entryPtr->d_type != DT_UNKNOWN && entryPtr->d_type != DT_LNK) { + isDir = (entryPtr->d_type == DT_DIR); + } else { + struct stat entryStat; + stat(entryPtr->d_name, &entryStat); + isDir = S_ISDIR(entryStat.st_mode); + } + return isDir; +} + +bool isFileExtension(const char* name, const char* ext) { + if (name == NULL) return false; + if (ext == NULL) return false; + + size_t extLen = strlen(ext); + size_t nameLen = strlen(name); + + if (extLen > nameLen) return false; + + if (strncmp(name + nameLen - extLen, ext, extLen) != 0) return false; + + return true; +} +}; // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace legacy_hal { + +WifiLegacyHalFactory::WifiLegacyHalFactory( + const std::weak_ptr iface_tool) + : iface_tool_(iface_tool) {} + +std::vector> WifiLegacyHalFactory::getHals() { + if (legacy_hals_.empty()) { + if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList(); + for (auto& desc : descs_) { + std::shared_ptr hal = + std::make_shared(iface_tool_, desc.fn, desc.primary); + legacy_hals_.push_back(hal); + } + } + + return legacy_hals_; +} + +bool WifiLegacyHalFactory::initVendorHalDescriptorFromLinked() { + wifi_hal_lib_desc desc; + + if (!initLinkedHalFunctionTable(&desc.fn)) return false; + + desc.primary = true; + desc.handle = NULL; + descs_.push_back(desc); + return true; +} + +bool WifiLegacyHalFactory::initLinkedHalFunctionTable(wifi_hal_fn* hal_fn) { + init_wifi_vendor_hal_func_table_t initfn; + + initfn = (init_wifi_vendor_hal_func_table_t)dlsym(RTLD_DEFAULT, + "init_wifi_vendor_hal_func_table"); + if (!initfn) { + LOG(INFO) << "no vendor HAL library linked, will try dynamic load"; + return false; + } + + if (!initHalFuncTableWithStubs(hal_fn)) { + LOG(ERROR) << "Can not initialize the basic function pointer table"; + return false; + } + + if (initfn(hal_fn) != WIFI_SUCCESS) { + LOG(ERROR) << "Can not initialize the vendor function pointer table"; + return false; + } + + return true; +} + +/* + * Overall structure of the HAL descriptor XML schema + * + * + * + * /vendor/lib64/libwifi-hal-qcom.so + * 1 + * + */ +void WifiLegacyHalFactory::initVendorHalsDescriptorList() { + xmlDocPtr xml; + xmlNodePtr node, cnode; + char* version; + std::string path; + xmlChar* value; + wifi_hal_lib_desc desc; + + LOG(INFO) << "processing vendor HALs descriptions in " << kVendorHalsDescPath; + DIR* dirPtr = ::opendir(kVendorHalsDescPath); + if (dirPtr == NULL) { + LOG(ERROR) << "failed to open " << kVendorHalsDescPath; + return; + } + for (struct dirent* entryPtr = ::readdir(dirPtr); entryPtr != NULL; + entryPtr = ::readdir(dirPtr)) { + if (isDirectory(entryPtr)) continue; + + if (!isFileExtension(entryPtr->d_name, kVendorHalsDescExt)) + continue; // only process .xml files + + LOG(INFO) << "processing config file: " << entryPtr->d_name; + + std::string fullPath(kVendorHalsDescPath); + fullPath.append("/"); + fullPath.append(entryPtr->d_name); + xml = xmlReadFile(fullPath.c_str(), "UTF-8", XML_PARSE_RECOVER); + if (!xml) { + LOG(ERROR) << "failed to parse: " << entryPtr->d_name << " skipping..."; + continue; + } + node = xmlDocGetRootElement(xml); + if (!node) { + LOG(ERROR) << "empty config file: " << entryPtr->d_name << " skipping..."; + goto skip; + } + if (xmlStrcmp(node->name, BAD_CAST "WifiVendorHal")) { + LOG(ERROR) << "bad config, root element not WifiVendorHal: " << entryPtr->d_name + << " skipping..."; + goto skip; + } + version = (char*)xmlGetProp(node, BAD_CAST "version"); + if (!version || strtoul(version, NULL, 0) != kVendorHalsDescVersion) { + LOG(ERROR) << "conf file: " << entryPtr->d_name + << "must have version: " << kVendorHalsDescVersion << ", skipping..."; + goto skip; + } + cnode = node->children; + path.clear(); + desc.primary = false; + while (cnode) { + if (!xmlStrcmp(cnode->name, BAD_CAST "path")) { + value = xmlNodeListGetString(xml, cnode->children, 1); + if (value) path = (char*)value; + xmlFree(value); + } else if (!xmlStrcmp(cnode->name, BAD_CAST "primary")) { + value = xmlNodeListGetString(xml, cnode->children, 1); + desc.primary = !xmlStrcmp(value, BAD_CAST "1"); + xmlFree(value); + } + cnode = cnode->next; + } + if (path.empty()) { + LOG(ERROR) << "hal library path not provided in: " << entryPtr->d_name + << ", skipping..."; + goto skip; + } + if (loadVendorHalLib(path, desc)) { + if (desc.primary) + descs_.insert(descs_.begin(), desc); + else + descs_.push_back(desc); + } + skip: + xmlFreeDoc(xml); + } + ::closedir(dirPtr); +} + +bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc) { + void* h = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL); + init_wifi_vendor_hal_func_table_t initfn; + wifi_error res; + + if (!h) { + LOG(ERROR) << "failed to open vendor hal library: " << path; + return false; + } + initfn = (init_wifi_vendor_hal_func_table_t)dlsym(h, "init_wifi_vendor_hal_func_table"); + if (!initfn) { + LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path; + goto out_err; + } + + if (!initHalFuncTableWithStubs(&desc.fn)) { + LOG(ERROR) << "Can not initialize the basic function pointer table"; + goto out_err; + } + res = initfn(&desc.fn); + if (res != WIFI_SUCCESS) { + LOG(ERROR) << "failed to initialize the vendor func table in: " << path + << " error: " << res; + goto out_err; + } + + res = desc.fn.wifi_early_initialize(); + // vendor HALs which do not implement early_initialize will return + // WIFI_ERROR_NOT_SUPPORTED, treat this as success. + if (res != WIFI_SUCCESS && res != WIFI_ERROR_NOT_SUPPORTED) { + LOG(ERROR) << "early initialization failed in: " << path << " error: " << res; + goto out_err; + } + + desc.handle = h; + return true; +out_err: + dlclose(h); + return false; +} + +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_legacy_hal_factory.h b/wifi/1.6/default/wifi_legacy_hal_factory.h new file mode 100644 index 0000000000..9f4423efb7 --- /dev/null +++ b/wifi/1.6/default/wifi_legacy_hal_factory.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WIFI_LEGACY_HAL_FACTORY_H_ +#define WIFI_LEGACY_HAL_FACTORY_H_ + +#include + +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +// This is in a separate namespace to prevent typename conflicts between +// the legacy HAL types and the HIDL interface types. +namespace legacy_hal { +/** + * Class that creates WifiLegacyHal objects for vendor HALs in the system. + */ +class WifiLegacyHalFactory { + public: + WifiLegacyHalFactory(const std::weak_ptr iface_tool); + virtual ~WifiLegacyHalFactory() = default; + + std::vector> getHals(); + + private: + typedef struct { + wifi_hal_fn fn; + bool primary; + void* handle; + } wifi_hal_lib_desc; + + bool initVendorHalDescriptorFromLinked(); + void initVendorHalsDescriptorList(); + bool initLinkedHalFunctionTable(wifi_hal_fn* hal_fn); + bool loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc); + + std::weak_ptr iface_tool_; + std::vector descs_; + std::vector> legacy_hals_; +}; + +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_LEGACY_HAL_FACTORY_H_ diff --git a/wifi/1.6/default/wifi_legacy_hal_stubs.cpp b/wifi/1.6/default/wifi_legacy_hal_stubs.cpp new file mode 100644 index 0000000000..e03e1ae1a1 --- /dev/null +++ b/wifi/1.6/default/wifi_legacy_hal_stubs.cpp @@ -0,0 +1,171 @@ +/* + * 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. + */ + +#include "wifi_legacy_hal_stubs.h" + +// TODO: Remove these stubs from HalTool in libwifi-system. +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace legacy_hal { +template +struct stubFunction; + +template +struct stubFunction { + static constexpr R invoke(Args...) { return WIFI_ERROR_NOT_SUPPORTED; } +}; +template +struct stubFunction { + static constexpr void invoke(Args...) {} +}; + +template +void populateStubFor(T* val) { + *val = &stubFunction::invoke; +} + +bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { + if (hal_fn == nullptr) { + return false; + } + populateStubFor(&hal_fn->wifi_initialize); + populateStubFor(&hal_fn->wifi_wait_for_driver_ready); + populateStubFor(&hal_fn->wifi_cleanup); + populateStubFor(&hal_fn->wifi_event_loop); + populateStubFor(&hal_fn->wifi_get_error_info); + populateStubFor(&hal_fn->wifi_get_supported_feature_set); + populateStubFor(&hal_fn->wifi_get_concurrency_matrix); + populateStubFor(&hal_fn->wifi_set_scanning_mac_oui); + populateStubFor(&hal_fn->wifi_get_supported_channels); + populateStubFor(&hal_fn->wifi_is_epr_supported); + populateStubFor(&hal_fn->wifi_get_ifaces); + populateStubFor(&hal_fn->wifi_get_iface_name); + populateStubFor(&hal_fn->wifi_set_iface_event_handler); + populateStubFor(&hal_fn->wifi_reset_iface_event_handler); + populateStubFor(&hal_fn->wifi_start_gscan); + populateStubFor(&hal_fn->wifi_stop_gscan); + populateStubFor(&hal_fn->wifi_get_cached_gscan_results); + populateStubFor(&hal_fn->wifi_set_bssid_hotlist); + populateStubFor(&hal_fn->wifi_reset_bssid_hotlist); + populateStubFor(&hal_fn->wifi_set_significant_change_handler); + populateStubFor(&hal_fn->wifi_reset_significant_change_handler); + populateStubFor(&hal_fn->wifi_get_gscan_capabilities); + populateStubFor(&hal_fn->wifi_set_link_stats); + populateStubFor(&hal_fn->wifi_get_link_stats); + populateStubFor(&hal_fn->wifi_clear_link_stats); + populateStubFor(&hal_fn->wifi_get_valid_channels); + populateStubFor(&hal_fn->wifi_rtt_range_request); + populateStubFor(&hal_fn->wifi_rtt_range_cancel); + populateStubFor(&hal_fn->wifi_get_rtt_capabilities); + populateStubFor(&hal_fn->wifi_rtt_get_responder_info); + populateStubFor(&hal_fn->wifi_enable_responder); + populateStubFor(&hal_fn->wifi_disable_responder); + populateStubFor(&hal_fn->wifi_set_nodfs_flag); + populateStubFor(&hal_fn->wifi_start_logging); + populateStubFor(&hal_fn->wifi_set_epno_list); + populateStubFor(&hal_fn->wifi_reset_epno_list); + populateStubFor(&hal_fn->wifi_set_country_code); + populateStubFor(&hal_fn->wifi_get_firmware_memory_dump); + populateStubFor(&hal_fn->wifi_set_log_handler); + populateStubFor(&hal_fn->wifi_reset_log_handler); + populateStubFor(&hal_fn->wifi_set_alert_handler); + populateStubFor(&hal_fn->wifi_reset_alert_handler); + populateStubFor(&hal_fn->wifi_get_firmware_version); + populateStubFor(&hal_fn->wifi_get_ring_buffers_status); + populateStubFor(&hal_fn->wifi_get_logger_supported_feature_set); + populateStubFor(&hal_fn->wifi_get_ring_data); + populateStubFor(&hal_fn->wifi_enable_tdls); + populateStubFor(&hal_fn->wifi_disable_tdls); + populateStubFor(&hal_fn->wifi_get_tdls_status); + populateStubFor(&hal_fn->wifi_get_tdls_capabilities); + populateStubFor(&hal_fn->wifi_get_driver_version); + populateStubFor(&hal_fn->wifi_set_passpoint_list); + populateStubFor(&hal_fn->wifi_reset_passpoint_list); + populateStubFor(&hal_fn->wifi_set_lci); + populateStubFor(&hal_fn->wifi_set_lcr); + populateStubFor(&hal_fn->wifi_start_sending_offloaded_packet); + populateStubFor(&hal_fn->wifi_stop_sending_offloaded_packet); + populateStubFor(&hal_fn->wifi_start_rssi_monitoring); + populateStubFor(&hal_fn->wifi_stop_rssi_monitoring); + populateStubFor(&hal_fn->wifi_get_wake_reason_stats); + populateStubFor(&hal_fn->wifi_configure_nd_offload); + populateStubFor(&hal_fn->wifi_get_driver_memory_dump); + populateStubFor(&hal_fn->wifi_start_pkt_fate_monitoring); + populateStubFor(&hal_fn->wifi_get_tx_pkt_fates); + populateStubFor(&hal_fn->wifi_get_rx_pkt_fates); + populateStubFor(&hal_fn->wifi_nan_enable_request); + populateStubFor(&hal_fn->wifi_nan_disable_request); + populateStubFor(&hal_fn->wifi_nan_publish_request); + populateStubFor(&hal_fn->wifi_nan_publish_cancel_request); + populateStubFor(&hal_fn->wifi_nan_subscribe_request); + populateStubFor(&hal_fn->wifi_nan_subscribe_cancel_request); + populateStubFor(&hal_fn->wifi_nan_transmit_followup_request); + populateStubFor(&hal_fn->wifi_nan_stats_request); + populateStubFor(&hal_fn->wifi_nan_config_request); + populateStubFor(&hal_fn->wifi_nan_tca_request); + populateStubFor(&hal_fn->wifi_nan_beacon_sdf_payload_request); + populateStubFor(&hal_fn->wifi_nan_register_handler); + populateStubFor(&hal_fn->wifi_nan_get_version); + populateStubFor(&hal_fn->wifi_nan_get_capabilities); + populateStubFor(&hal_fn->wifi_nan_data_interface_create); + populateStubFor(&hal_fn->wifi_nan_data_interface_delete); + populateStubFor(&hal_fn->wifi_nan_data_request_initiator); + populateStubFor(&hal_fn->wifi_nan_data_indication_response); + populateStubFor(&hal_fn->wifi_nan_data_end); + populateStubFor(&hal_fn->wifi_get_packet_filter_capabilities); + populateStubFor(&hal_fn->wifi_set_packet_filter); + populateStubFor(&hal_fn->wifi_read_packet_filter); + populateStubFor(&hal_fn->wifi_get_roaming_capabilities); + populateStubFor(&hal_fn->wifi_enable_firmware_roaming); + populateStubFor(&hal_fn->wifi_configure_roaming); + populateStubFor(&hal_fn->wifi_select_tx_power_scenario); + populateStubFor(&hal_fn->wifi_reset_tx_power_scenario); + populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler); + populateStubFor(&hal_fn->wifi_set_latency_mode); + populateStubFor(&hal_fn->wifi_set_thermal_mitigation_mode); + populateStubFor(&hal_fn->wifi_virtual_interface_create); + populateStubFor(&hal_fn->wifi_virtual_interface_delete); + populateStubFor(&hal_fn->wifi_map_dscp_access_category); + populateStubFor(&hal_fn->wifi_reset_dscp_mapping); + populateStubFor(&hal_fn->wifi_set_subsystem_restart_handler); + populateStubFor(&hal_fn->wifi_get_supported_iface_name); + populateStubFor(&hal_fn->wifi_early_initialize); + populateStubFor(&hal_fn->wifi_get_chip_feature_set); + populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection); + populateStubFor(&hal_fn->wifi_multi_sta_set_use_case); + populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels); + populateStubFor(&hal_fn->wifi_set_voip_mode); + populateStubFor(&hal_fn->wifi_twt_register_handler); + populateStubFor(&hal_fn->wifi_twt_get_capability); + populateStubFor(&hal_fn->wifi_twt_setup_request); + populateStubFor(&hal_fn->wifi_twt_teardown_request); + populateStubFor(&hal_fn->wifi_twt_info_frame_request); + populateStubFor(&hal_fn->wifi_twt_get_stats); + populateStubFor(&hal_fn->wifi_twt_clear_stats); + populateStubFor(&hal_fn->wifi_set_dtim_config); + populateStubFor(&hal_fn->wifi_get_usable_channels); + populateStubFor(&hal_fn->wifi_trigger_subsystem_restart); + return true; +} +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_legacy_hal_stubs.h b/wifi/1.6/default/wifi_legacy_hal_stubs.h new file mode 100644 index 0000000000..c9a03bf4c9 --- /dev/null +++ b/wifi/1.6/default/wifi_legacy_hal_stubs.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#ifndef WIFI_LEGACY_HAL_STUBS_H_ +#define WIFI_LEGACY_HAL_STUBS_H_ + +#include + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace legacy_hal { + +bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn); +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_LEGACY_HAL_STUBS_H_ diff --git a/wifi/1.6/default/wifi_mode_controller.cpp b/wifi/1.6/default/wifi_mode_controller.cpp new file mode 100644 index 0000000000..4b8ac7dd1c --- /dev/null +++ b/wifi/1.6/default/wifi_mode_controller.cpp @@ -0,0 +1,89 @@ +/* + * 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. + */ + +#include +#include +#include + +#include "wifi_mode_controller.h" + +using android::hardware::wifi::V1_0::IfaceType; +using android::wifi_hal::DriverTool; + +namespace { +int convertIfaceTypeToFirmwareMode(IfaceType type) { + int mode; + switch (type) { + case IfaceType::AP: + mode = DriverTool::kFirmwareModeAp; + break; + case IfaceType::P2P: + mode = DriverTool::kFirmwareModeP2p; + break; + case IfaceType::NAN: + // NAN is exposed in STA mode currently. + mode = DriverTool::kFirmwareModeSta; + break; + case IfaceType::STA: + mode = DriverTool::kFirmwareModeSta; + break; + } + return mode; +} +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace mode_controller { + +WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {} + +bool WifiModeController::isFirmwareModeChangeNeeded(IfaceType type) { + return driver_tool_->IsFirmwareModeChangeNeeded(convertIfaceTypeToFirmwareMode(type)); +} + +bool WifiModeController::initialize() { + if (!driver_tool_->LoadDriver()) { + LOG(ERROR) << "Failed to load WiFi driver"; + return false; + } + return true; +} + +bool WifiModeController::changeFirmwareMode(IfaceType type) { + if (!driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))) { + LOG(ERROR) << "Failed to change firmware mode"; + return false; + } + return true; +} + +bool WifiModeController::deinitialize() { + if (!driver_tool_->UnloadDriver()) { + LOG(ERROR) << "Failed to unload WiFi driver"; + return false; + } + return true; +} +} // namespace mode_controller +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_mode_controller.h b/wifi/1.6/default/wifi_mode_controller.h new file mode 100644 index 0000000000..fee2b66d4e --- /dev/null +++ b/wifi/1.6/default/wifi_mode_controller.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +#ifndef WIFI_MODE_CONTROLLER_H_ +#define WIFI_MODE_CONTROLLER_H_ + +#include + +#include + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +namespace mode_controller { +using namespace android::hardware::wifi::V1_0; + +/** + * Class that encapsulates all firmware mode configuration. + * This class will perform the necessary firmware reloads to put the chip in the + * required state (essentially a wrapper over DriverTool). + */ +class WifiModeController { + public: + WifiModeController(); + virtual ~WifiModeController() = default; + + // Checks if a firmware mode change is necessary to support the specified + // iface type operations. + virtual bool isFirmwareModeChangeNeeded(IfaceType type); + virtual bool initialize(); + // Change the firmware mode to support the specified iface type operations. + virtual bool changeFirmwareMode(IfaceType type); + // Unload the driver. This should be invoked whenever |IWifi.stop()| is + // invoked. + virtual bool deinitialize(); + + private: + std::unique_ptr driver_tool_; +}; + +} // namespace mode_controller +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_MODE_CONTROLLER_H_ diff --git a/wifi/1.6/default/wifi_nan_iface.cpp b/wifi/1.6/default/wifi_nan_iface.cpp new file mode 100644 index 0000000000..236cb64e32 --- /dev/null +++ b/wifi/1.6/default/wifi_nan_iface.cpp @@ -0,0 +1,905 @@ +/* + * 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. + */ + +#include + +#include "hidl_return_util.h" +#include "hidl_struct_util.h" +#include "wifi_nan_iface.h" +#include "wifi_status_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using hidl_return_util::validateAndCall; + +WifiNanIface::WifiNanIface(const std::string& ifname, bool is_dedicated_iface, + const std::weak_ptr legacy_hal, + const std::weak_ptr iface_util) + : ifname_(ifname), + is_dedicated_iface_(is_dedicated_iface), + legacy_hal_(legacy_hal), + iface_util_(iface_util), + is_valid_(true) { + if (is_dedicated_iface_) { + // If using a dedicated iface, set the iface up first. + if (!iface_util_.lock()->setUpState(ifname_, true)) { + // Fatal failure, invalidate the iface object. + invalidate(); + return; + } + } + // Register all the callbacks here. these should be valid for the lifetime + // of the object. Whenever the mode changes legacy HAL will remove + // all of these callbacks. + legacy_hal::NanCallbackHandlers callback_handlers; + android::wp weak_ptr_this(this); + + // Callback for response. + callback_handlers.on_notify_response = [weak_ptr_this](legacy_hal::transaction_id id, + const legacy_hal::NanResponseMsg& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus wifiNanStatus; + if (!hidl_struct_util::convertLegacyNanResponseHeaderToHidl(msg, &wifiNanStatus)) { + LOG(ERROR) << "Failed to convert nan response header"; + return; + } + + switch (msg.response_type) { + case legacy_hal::NAN_RESPONSE_ENABLED: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyEnableResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_DISABLED: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyDisableResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_PUBLISH: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyStartPublishResponse(id, wifiNanStatus, + msg.body.publish_response.publish_id) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyStopPublishResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyTransmitFollowupResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_SUBSCRIBE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyStartSubscribeResponse( + id, wifiNanStatus, + msg.body.subscribe_response.subscribe_id) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyStopSubscribeResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_CONFIG: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyConfigResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_GET_CAPABILITIES: { + V1_5::NanCapabilities hidl_struct; + if (!hidl_struct_util::convertLegacyNanCapabilitiesResponseToHidl( + msg.body.nan_capabilities, &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks_1_5()) { + if (!callback->notifyCapabilitiesResponse_1_5(id, wifiNanStatus, hidl_struct) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_INTERFACE_CREATE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyCreateDataInterfaceResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_INTERFACE_DELETE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyDeleteDataInterfaceResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_INITIATOR_RESPONSE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyInitiateDataPathResponse( + id, wifiNanStatus, + msg.body.data_request_response.ndp_instance_id) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_RESPONDER_RESPONSE: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyRespondToDataPathIndicationResponse(id, wifiNanStatus) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_DP_END: { + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->notifyTerminateDataPathResponse(id, wifiNanStatus).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + break; + } + case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD: + /* fall through */ + case legacy_hal::NAN_RESPONSE_TCA: + /* fall through */ + case legacy_hal::NAN_RESPONSE_STATS: + /* fall through */ + case legacy_hal::NAN_RESPONSE_ERROR: + /* fall through */ + default: + LOG(ERROR) << "Unknown or unhandled response type: " << msg.response_type; + return; + } + }; + + callback_handlers.on_event_disc_eng_event = + [weak_ptr_this](const legacy_hal::NanDiscEngEventInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + NanClusterEventInd hidl_struct; + // event types defined identically - hence can be cast + hidl_struct.eventType = (NanClusterEventType)msg.event_type; + hidl_struct.addr = msg.data.mac_addr.addr; + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventClusterEvent(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_disabled = [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus status; + hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason), + &status); + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventDisabled(status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_publish_terminated = + [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus status; + hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, + sizeof(msg.nan_reason), &status); + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventPublishTerminated(msg.publish_id, status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_subscribe_terminated = + [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus status; + hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, + sizeof(msg.nan_reason), &status); + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventSubscribeTerminated(msg.subscribe_id, status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_match = [weak_ptr_this](const legacy_hal::NanMatchInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + NanMatchInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanMatchIndToHidl(msg, &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventMatch(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_match_expired = [weak_ptr_this]( + const legacy_hal::NanMatchExpiredInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventMatchExpired(msg.publish_subscribe_id, msg.requestor_instance_id) + .isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_followup = [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + NanFollowupReceivedInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanFollowupIndToHidl(msg, &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventFollowupReceived(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_transmit_follow_up = + [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + WifiNanStatus status; + hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, + sizeof(msg.nan_reason), &status); + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventTransmitFollowup(msg.id, status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_data_path_request = + [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + NanDataPathRequestInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanDataPathRequestIndToHidl(msg, + &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventDataPathRequest(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_data_path_confirm = + [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + V1_2::NanDataPathConfirmInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanDataPathConfirmIndToHidl(msg, + &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks_1_2()) { + if (!callback->eventDataPathConfirm_1_2(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + callback_handlers.on_event_data_path_end = + [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + for (int i = 0; i < msg.num_ndp_instances; ++i) { + if (!callback->eventDataPathTerminated(msg.ndp_instance_id[i]).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + } + }; + + callback_handlers.on_event_beacon_sdf_payload = + [weak_ptr_this](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) { + LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called"; + }; + + callback_handlers.on_event_range_request = + [weak_ptr_this](const legacy_hal::NanRangeRequestInd& /* msg */) { + LOG(ERROR) << "on_event_range_request - should not be called"; + }; + + callback_handlers.on_event_range_report = + [weak_ptr_this](const legacy_hal::NanRangeReportInd& /* msg */) { + LOG(ERROR) << "on_event_range_report - should not be called"; + }; + + callback_handlers.on_event_schedule_update = + [weak_ptr_this](const legacy_hal::NanDataPathScheduleUpdateInd& msg) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + V1_2::NanDataPathScheduleUpdateInd hidl_struct; + if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl( + msg, &hidl_struct)) { + LOG(ERROR) << "Failed to convert nan capabilities response"; + return; + } + + for (const auto& callback : shared_ptr_this->getEventCallbacks_1_2()) { + if (!callback->eventDataPathScheduleUpdate(hidl_struct).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, callback_handlers); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to register nan callbacks. Invalidating object"; + invalidate(); + } + + // Register for iface state toggle events. + iface_util::IfaceEventHandlers event_handlers = {}; + event_handlers.on_state_toggle_off_on = [weak_ptr_this](const std::string& /* iface_name */) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + // Tell framework that NAN has been disabled. + WifiNanStatus status = {NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""}; + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->eventDisabled(status).isOk()) { + LOG(ERROR) << "Failed to invoke the callback"; + } + } + }; + iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers); +} + +void WifiNanIface::invalidate() { + if (!isValid()) { + return; + } + // send commands to HAL to actually disable and destroy interfaces + legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF); + legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0"); + legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1"); + iface_util_.lock()->unregisterIfaceEventHandlers(ifname_); + legacy_hal_.reset(); + event_cb_handler_.invalidate(); + event_cb_handler_1_2_.invalidate(); + event_cb_handler_1_5_.invalidate(); + is_valid_ = false; + if (is_dedicated_iface_) { + // If using a dedicated iface, set the iface down. + iface_util_.lock()->setUpState(ifname_, false); + } +} + +bool WifiNanIface::isValid() { + return is_valid_; +} + +std::string WifiNanIface::getName() { + return ifname_; +} + +std::set> WifiNanIface::getEventCallbacks() { + return event_cb_handler_.getCallbacks(); +} + +std::set> WifiNanIface::getEventCallbacks_1_2() { + return event_cb_handler_1_2_.getCallbacks(); +} + +std::set> WifiNanIface::getEventCallbacks_1_5() { + return event_cb_handler_1_5_.getCallbacks(); +} + +Return WifiNanIface::getName(getName_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::getNameInternal, hidl_status_cb); +} + +Return WifiNanIface::getType(getType_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::getTypeInternal, hidl_status_cb); +} + +Return WifiNanIface::registerEventCallback( + const sp& callback, + registerEventCallback_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::registerEventCallbackInternal, hidl_status_cb, callback); +} + +Return WifiNanIface::getCapabilitiesRequest(uint16_t cmd_id, + getCapabilitiesRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::getCapabilitiesRequestInternal, hidl_status_cb, cmd_id); +} + +Return WifiNanIface::enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg, + enableRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::enableRequestInternal, hidl_status_cb, cmd_id, msg); +} + +Return WifiNanIface::configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg, + configRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::configRequestInternal, hidl_status_cb, cmd_id, msg); +} + +Return WifiNanIface::disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::disableRequestInternal, hidl_status_cb, cmd_id); +} + +Return WifiNanIface::startPublishRequest(uint16_t cmd_id, const NanPublishRequest& msg, + startPublishRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::startPublishRequestInternal, hidl_status_cb, cmd_id, msg); +} + +Return WifiNanIface::stopPublishRequest(uint16_t cmd_id, uint8_t sessionId, + stopPublishRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::stopPublishRequestInternal, hidl_status_cb, cmd_id, + sessionId); +} + +Return WifiNanIface::startSubscribeRequest(uint16_t cmd_id, const NanSubscribeRequest& msg, + startSubscribeRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::startSubscribeRequestInternal, hidl_status_cb, cmd_id, + msg); +} + +Return WifiNanIface::stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId, + stopSubscribeRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::stopSubscribeRequestInternal, hidl_status_cb, cmd_id, + sessionId); +} + +Return WifiNanIface::transmitFollowupRequest(uint16_t cmd_id, + const NanTransmitFollowupRequest& msg, + transmitFollowupRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::transmitFollowupRequestInternal, hidl_status_cb, cmd_id, + msg); +} + +Return WifiNanIface::createDataInterfaceRequest( + uint16_t cmd_id, const hidl_string& iface_name, + createDataInterfaceRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::createDataInterfaceRequestInternal, hidl_status_cb, + cmd_id, iface_name); +} + +Return WifiNanIface::deleteDataInterfaceRequest( + uint16_t cmd_id, const hidl_string& iface_name, + deleteDataInterfaceRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::deleteDataInterfaceRequestInternal, hidl_status_cb, + cmd_id, iface_name); +} + +Return WifiNanIface::initiateDataPathRequest(uint16_t cmd_id, + const NanInitiateDataPathRequest& msg, + initiateDataPathRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::initiateDataPathRequestInternal, hidl_status_cb, cmd_id, + msg); +} + +Return WifiNanIface::respondToDataPathIndicationRequest( + uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg, + respondToDataPathIndicationRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::respondToDataPathIndicationRequestInternal, + hidl_status_cb, cmd_id, msg); +} + +Return WifiNanIface::terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId, + terminateDataPathRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::terminateDataPathRequestInternal, hidl_status_cb, cmd_id, + ndpInstanceId); +} + +Return WifiNanIface::registerEventCallback_1_2( + const sp& callback, + registerEventCallback_1_2_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::registerEventCallback_1_2Internal, hidl_status_cb, + callback); +} + +Return WifiNanIface::enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + enableRequest_1_2_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::enableRequest_1_2Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return WifiNanIface::configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + configRequest_1_2_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::configRequest_1_2Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return WifiNanIface::enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + enableRequest_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::enableRequest_1_4Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return WifiNanIface::configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + configRequest_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::configRequest_1_4Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return WifiNanIface::registerEventCallback_1_5( + const sp& callback, + registerEventCallback_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::registerEventCallback_1_5Internal, hidl_status_cb, + callback); +} + +Return WifiNanIface::enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2, + enableRequest_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::enableRequest_1_5Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return WifiNanIface::configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2, + configRequest_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::configRequest_1_5Internal, hidl_status_cb, cmd_id, msg1, + msg2); +} + +Return WifiNanIface::getCapabilitiesRequest_1_5( + uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiNanIface::getCapabilitiesRequest_1_5Internal, hidl_status_cb, + cmd_id); +} + +std::pair WifiNanIface::getNameInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; +} + +std::pair WifiNanIface::getTypeInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::NAN}; +} + +WifiStatus WifiNanIface::registerEventCallbackInternal( + const sp& callback) { + if (!event_cb_handler_.addCallback(callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::enableRequestInternal(uint16_t /* cmd_id */, + const V1_0::NanEnableRequest& /* msg */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::configRequestInternal(uint16_t /* cmd_id */, + const V1_0::NanConfigRequest& /* msg */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::disableRequestInternal(uint16_t cmd_id) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::startPublishRequestInternal(uint16_t cmd_id, + const NanPublishRequest& msg) { + legacy_hal::NanPublishRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanPublishRequestToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId) { + legacy_hal::NanPublishCancelRequest legacy_msg; + legacy_msg.publish_id = sessionId; + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::startSubscribeRequestInternal(uint16_t cmd_id, + const NanSubscribeRequest& msg) { + legacy_hal::NanSubscribeRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanSubscribeRequestToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId) { + legacy_hal::NanSubscribeCancelRequest legacy_msg; + legacy_msg.subscribe_id = sessionId; + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::transmitFollowupRequestInternal(uint16_t cmd_id, + const NanTransmitFollowupRequest& msg) { + legacy_hal::NanTransmitFollowupRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanTransmitFollowupRequestToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::createDataInterfaceRequestInternal(uint16_t cmd_id, + const std::string& iface_name) { + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name); + return createWifiStatusFromLegacyError(legacy_status); +} +WifiStatus WifiNanIface::deleteDataInterfaceRequestInternal(uint16_t cmd_id, + const std::string& iface_name) { + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name); + return createWifiStatusFromLegacyError(legacy_status); +} +WifiStatus WifiNanIface::initiateDataPathRequestInternal(uint16_t cmd_id, + const NanInitiateDataPathRequest& msg) { + legacy_hal::NanDataPathInitiatorRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequestToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} +WifiStatus WifiNanIface::respondToDataPathIndicationRequestInternal( + uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg) { + legacy_hal::NanDataPathIndicationResponse legacy_msg; + if (!hidl_struct_util::convertHidlNanDataPathIndicationResponseToLegacy(msg, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} +WifiStatus WifiNanIface::terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId) { + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::registerEventCallback_1_2Internal( + const sp& callback) { + sp callback_1_0 = callback; + if (!event_cb_handler_.addCallback(callback_1_0)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + if (!event_cb_handler_1_2_.addCallback(callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiNanIface::enableRequest_1_2Internal( + uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::configRequest_1_2Internal( + uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::enableRequest_1_4Internal( + uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::configRequest_1_4Internal( + uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */, + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiNanIface::registerEventCallback_1_5Internal( + const sp& callback) { + sp callback_1_0 = callback; + if (!event_cb_handler_.addCallback(callback_1_0)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + sp callback_1_2 = callback; + if (!event_cb_handler_1_2_.addCallback(callback_1_2)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + if (!event_cb_handler_1_5_.addCallback(callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::enableRequest_1_5Internal(uint16_t cmd_id, + const V1_4::NanEnableRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2) { + legacy_hal::NanEnableRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanEnableRequest_1_5ToLegacy(msg1, msg2, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiNanIface::configRequest_1_5Internal(uint16_t cmd_id, + const V1_4::NanConfigRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2) { + legacy_hal::NanConfigRequest legacy_msg; + if (!hidl_struct_util::convertHidlNanConfigRequest_1_5ToLegacy(msg1, msg2, &legacy_msg)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg); + return createWifiStatusFromLegacyError(legacy_status); +} + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_nan_iface.h b/wifi/1.6/default/wifi_nan_iface.h new file mode 100644 index 0000000000..c445afc541 --- /dev/null +++ b/wifi/1.6/default/wifi_nan_iface.h @@ -0,0 +1,174 @@ +/* + * 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. + */ + +#ifndef WIFI_NAN_IFACE_H_ +#define WIFI_NAN_IFACE_H_ + +#include +#include +#include + +#include "hidl_callback_util.h" +#include "wifi_iface_util.h" +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; +using namespace android::hardware::wifi::V1_2; + +/** + * HIDL interface object used to control a NAN Iface instance. + */ +class WifiNanIface : public V1_5::IWifiNanIface { + public: + WifiNanIface(const std::string& ifname, bool is_dedicated_iface, + const std::weak_ptr legacy_hal, + const std::weak_ptr iface_util); + // Refer to |WifiChip::invalidate()|. + void invalidate(); + bool isValid(); + std::string getName(); + + // HIDL methods exposed. + Return getName(getName_cb hidl_status_cb) override; + Return getType(getType_cb hidl_status_cb) override; + Return registerEventCallback(const sp& callback, + registerEventCallback_cb hidl_status_cb) override; + Return getCapabilitiesRequest(uint16_t cmd_id, + getCapabilitiesRequest_cb hidl_status_cb) override; + Return enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg, + enableRequest_cb hidl_status_cb) override; + Return configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg, + configRequest_cb hidl_status_cb) override; + Return disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) override; + Return startPublishRequest(uint16_t cmd_id, const NanPublishRequest& msg, + startPublishRequest_cb hidl_status_cb) override; + Return stopPublishRequest(uint16_t cmd_id, uint8_t sessionId, + stopPublishRequest_cb hidl_status_cb) override; + Return startSubscribeRequest(uint16_t cmd_id, const NanSubscribeRequest& msg, + startSubscribeRequest_cb hidl_status_cb) override; + Return stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId, + stopSubscribeRequest_cb hidl_status_cb) override; + Return transmitFollowupRequest(uint16_t cmd_id, const NanTransmitFollowupRequest& msg, + transmitFollowupRequest_cb hidl_status_cb) override; + Return createDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name, + createDataInterfaceRequest_cb hidl_status_cb) override; + Return deleteDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name, + deleteDataInterfaceRequest_cb hidl_status_cb) override; + Return initiateDataPathRequest(uint16_t cmd_id, const NanInitiateDataPathRequest& msg, + initiateDataPathRequest_cb hidl_status_cb) override; + Return respondToDataPathIndicationRequest( + uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg, + respondToDataPathIndicationRequest_cb hidl_status_cb) override; + Return terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId, + terminateDataPathRequest_cb hidl_status_cb) override; + + Return registerEventCallback_1_2(const sp& callback, + registerEventCallback_1_2_cb hidl_status_cb) override; + Return enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + enableRequest_1_2_cb hidl_status_cb) override; + Return configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + configRequest_1_2_cb hidl_status_cb) override; + Return enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + enableRequest_1_4_cb hidl_status_cb) override; + Return configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2, + configRequest_1_4_cb hidl_status_cb) override; + Return registerEventCallback_1_5(const sp& callback, + registerEventCallback_1_5_cb hidl_status_cb) override; + Return enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2, + enableRequest_1_4_cb hidl_status_cb) override; + Return configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2, + configRequest_1_4_cb hidl_status_cb) override; + Return getCapabilitiesRequest_1_5(uint16_t cmd_id, + getCapabilitiesRequest_cb hidl_status_cb) override; + + private: + // Corresponding worker functions for the HIDL methods. + std::pair getNameInternal(); + std::pair getTypeInternal(); + WifiStatus registerEventCallbackInternal(const sp& callback); + WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id); + WifiStatus enableRequestInternal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg); + WifiStatus configRequestInternal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg); + WifiStatus disableRequestInternal(uint16_t cmd_id); + WifiStatus startPublishRequestInternal(uint16_t cmd_id, const NanPublishRequest& msg); + WifiStatus stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId); + WifiStatus startSubscribeRequestInternal(uint16_t cmd_id, const NanSubscribeRequest& msg); + WifiStatus stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId); + WifiStatus transmitFollowupRequestInternal(uint16_t cmd_id, + const NanTransmitFollowupRequest& msg); + WifiStatus createDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name); + WifiStatus deleteDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name); + WifiStatus initiateDataPathRequestInternal(uint16_t cmd_id, + const NanInitiateDataPathRequest& msg); + WifiStatus respondToDataPathIndicationRequestInternal( + uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg); + WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId); + + WifiStatus registerEventCallback_1_2Internal( + const sp& callback); + WifiStatus enableRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus configRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg, + const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus enableRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus configRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg, + const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus registerEventCallback_1_5Internal( + const sp& callback); + WifiStatus enableRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const V1_5::NanConfigRequestSupplemental& msg2); + WifiStatus configRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg, + const V1_5::NanConfigRequestSupplemental& msg2); + WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id); + + // all 1_0 and descendant callbacks + std::set> getEventCallbacks(); + // all 1_2 and descendant callbacks + std::set> getEventCallbacks_1_2(); + // all 1_5 and descendant callbacks + std::set> getEventCallbacks_1_5(); + + std::string ifname_; + bool is_dedicated_iface_; + std::weak_ptr legacy_hal_; + std::weak_ptr iface_util_; + bool is_valid_; + hidl_callback_util::HidlCallbackHandler event_cb_handler_; + hidl_callback_util::HidlCallbackHandler event_cb_handler_1_2_; + hidl_callback_util::HidlCallbackHandler event_cb_handler_1_5_; + + DISALLOW_COPY_AND_ASSIGN(WifiNanIface); +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_NAN_IFACE_H_ diff --git a/wifi/1.6/default/wifi_p2p_iface.cpp b/wifi/1.6/default/wifi_p2p_iface.cpp new file mode 100644 index 0000000000..d4b1fcabf1 --- /dev/null +++ b/wifi/1.6/default/wifi_p2p_iface.cpp @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#include + +#include "hidl_return_util.h" +#include "wifi_p2p_iface.h" +#include "wifi_status_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using hidl_return_util::validateAndCall; + +WifiP2pIface::WifiP2pIface(const std::string& ifname, + const std::weak_ptr legacy_hal) + : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {} + +void WifiP2pIface::invalidate() { + legacy_hal_.reset(); + is_valid_ = false; +} + +bool WifiP2pIface::isValid() { + return is_valid_; +} + +std::string WifiP2pIface::getName() { + return ifname_; +} + +Return WifiP2pIface::getName(getName_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiP2pIface::getNameInternal, hidl_status_cb); +} + +Return WifiP2pIface::getType(getType_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiP2pIface::getTypeInternal, hidl_status_cb); +} + +std::pair WifiP2pIface::getNameInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; +} + +std::pair WifiP2pIface::getTypeInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::P2P}; +} + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_p2p_iface.h b/wifi/1.6/default/wifi_p2p_iface.h new file mode 100644 index 0000000000..00894437cf --- /dev/null +++ b/wifi/1.6/default/wifi_p2p_iface.h @@ -0,0 +1,66 @@ +/* + * 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. + */ + +#ifndef WIFI_P2P_IFACE_H_ +#define WIFI_P2P_IFACE_H_ + +#include +#include + +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; + +/** + * HIDL interface object used to control a P2P Iface instance. + */ +class WifiP2pIface : public V1_0::IWifiP2pIface { + public: + WifiP2pIface(const std::string& ifname, + const std::weak_ptr legacy_hal); + // Refer to |WifiChip::invalidate()|. + void invalidate(); + bool isValid(); + std::string getName(); + + // HIDL methods exposed. + Return getName(getName_cb hidl_status_cb) override; + Return getType(getType_cb hidl_status_cb) override; + + private: + // Corresponding worker functions for the HIDL methods. + std::pair getNameInternal(); + std::pair getTypeInternal(); + + std::string ifname_; + std::weak_ptr legacy_hal_; + bool is_valid_; + + DISALLOW_COPY_AND_ASSIGN(WifiP2pIface); +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_P2P_IFACE_H_ diff --git a/wifi/1.6/default/wifi_rtt_controller.cpp b/wifi/1.6/default/wifi_rtt_controller.cpp new file mode 100644 index 0000000000..f5e1d5aafc --- /dev/null +++ b/wifi/1.6/default/wifi_rtt_controller.cpp @@ -0,0 +1,311 @@ +/* + * 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. + */ + +#include + +#include "hidl_return_util.h" +#include "hidl_struct_util.h" +#include "wifi_rtt_controller.h" +#include "wifi_status_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using hidl_return_util::validateAndCall; + +WifiRttController::WifiRttController(const std::string& iface_name, + const sp& bound_iface, + const std::weak_ptr legacy_hal) + : ifname_(iface_name), bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {} + +void WifiRttController::invalidate() { + legacy_hal_.reset(); + event_callbacks_.clear(); + is_valid_ = false; +} + +bool WifiRttController::isValid() { + return is_valid_; +} + +std::vector> WifiRttController::getEventCallbacks() { + return event_callbacks_; +} + +std::string WifiRttController::getIfaceName() { + return ifname_; +} + +Return WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getBoundIfaceInternal, hidl_status_cb); +} + +Return WifiRttController::registerEventCallback( + const sp& callback, + registerEventCallback_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::registerEventCallbackInternal, hidl_status_cb, + callback); +} + +Return WifiRttController::rangeRequest(uint32_t cmd_id, + const hidl_vec& rtt_configs, + rangeRequest_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::rangeRequestInternal, hidl_status_cb, cmd_id, + rtt_configs); +} + +Return WifiRttController::rangeCancel(uint32_t cmd_id, + const hidl_vec>& addrs, + rangeCancel_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::rangeCancelInternal, hidl_status_cb, cmd_id, addrs); +} + +Return WifiRttController::getCapabilities(getCapabilities_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getCapabilitiesInternal, hidl_status_cb); +} + +Return WifiRttController::setLci(uint32_t cmd_id, const RttLciInformation& lci, + setLci_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::setLciInternal, hidl_status_cb, cmd_id, lci); +} + +Return WifiRttController::setLcr(uint32_t cmd_id, const RttLcrInformation& lcr, + setLcr_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::setLcrInternal, hidl_status_cb, cmd_id, lcr); +} + +Return WifiRttController::getResponderInfo(getResponderInfo_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getResponderInfoInternal, hidl_status_cb); +} + +Return WifiRttController::enableResponder(uint32_t cmd_id, + const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, + const V1_0::RttResponder& info, + enableResponder_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::enableResponderInternal, hidl_status_cb, cmd_id, + channel_hint, max_duration_seconds, info); +} + +Return WifiRttController::disableResponder(uint32_t cmd_id, + disableResponder_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::disableResponderInternal, hidl_status_cb, cmd_id); +} + +Return WifiRttController::registerEventCallback_1_4( + const sp& callback, + registerEventCallback_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::registerEventCallbackInternal_1_4, hidl_status_cb, + callback); +} + +Return WifiRttController::rangeRequest_1_4(uint32_t cmd_id, + const hidl_vec& rtt_configs, + rangeRequest_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::rangeRequestInternal_1_4, hidl_status_cb, cmd_id, + rtt_configs); +} + +Return WifiRttController::getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getCapabilitiesInternal_1_4, hidl_status_cb); +} + +Return WifiRttController::getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::getResponderInfoInternal_1_4, hidl_status_cb); +} + +Return WifiRttController::enableResponder_1_4(uint32_t cmd_id, + const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, + const V1_4::RttResponder& info, + enableResponder_1_4_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, + &WifiRttController::enableResponderInternal_1_4, hidl_status_cb, cmd_id, + channel_hint, max_duration_seconds, info); +} + +std::pair> WifiRttController::getBoundIfaceInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_}; +} + +WifiStatus WifiRttController::registerEventCallbackInternal( + const sp& /* callback */) { + // Deprecated support for this api + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiRttController::rangeRequestInternal( + uint32_t /* cmd_id */, const std::vector& /* rtt_configs */) { + // Deprecated support for this api + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiRttController::rangeCancelInternal( + uint32_t cmd_id, const std::vector>& addrs) { + std::vector> legacy_addrs; + for (const auto& addr : addrs) { + legacy_addrs.push_back(addr); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, legacy_addrs); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair WifiRttController::getCapabilitiesInternal() { + // Deprecated support for this api + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id, const RttLciInformation& lci) { + legacy_hal::wifi_lci_information legacy_lci; + if (!hidl_struct_util::convertHidlRttLciInformationToLegacy(lci, &legacy_lci)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiRttController::setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr) { + legacy_hal::wifi_lcr_information legacy_lcr; + if (!hidl_struct_util::convertHidlRttLcrInformationToLegacy(lcr, &legacy_lcr)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair WifiRttController::getResponderInfoInternal() { + // Deprecated support for this api + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +WifiStatus WifiRttController::enableResponderInternal(uint32_t /* cmd_id */, + const WifiChannelInfo& /* channel_hint */, + uint32_t /* max_duration_seconds */, + const V1_0::RttResponder& /* info */) { + // Deprecated support for this api + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)}; +} + +WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiRttController::registerEventCallbackInternal_1_4( + const sp& callback) { + // TODO(b/31632518): remove the callback when the client is destroyed + event_callbacks_.emplace_back(callback); + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +WifiStatus WifiRttController::rangeRequestInternal_1_4( + uint32_t cmd_id, const std::vector& rtt_configs) { + std::vector legacy_configs; + if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + android::wp weak_ptr_this(this); + const auto& on_results_callback = + [weak_ptr_this](legacy_hal::wifi_request_id id, + const std::vector& results) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + std::vector hidl_results; + if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl(results, + &hidl_results)) { + LOG(ERROR) << "Failed to convert rtt results to HIDL structs"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + callback->onResults_1_4(id, hidl_results); + } + }; + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest( + ifname_, cmd_id, legacy_configs, on_results_callback); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair WifiRttController::getCapabilitiesInternal_1_4() { + legacy_hal::wifi_error legacy_status; + legacy_hal::wifi_rtt_capabilities legacy_caps; + std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + V1_4::RttCapabilities hidl_caps; + if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps, &hidl_caps)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; +} + +std::pair WifiRttController::getResponderInfoInternal_1_4() { + legacy_hal::wifi_error legacy_status; + legacy_hal::wifi_rtt_responder legacy_responder; + std::tie(legacy_status, legacy_responder) = legacy_hal_.lock()->getRttResponderInfo(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + V1_4::RttResponder hidl_responder; + if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder, &hidl_responder)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder}; +} + +WifiStatus WifiRttController::enableResponderInternal_1_4(uint32_t cmd_id, + const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, + const V1_4::RttResponder& info) { + legacy_hal::wifi_channel_info legacy_channel_info; + if (!hidl_struct_util::convertHidlWifiChannelInfoToLegacy(channel_hint, &legacy_channel_info)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_rtt_responder legacy_responder; + if (!hidl_struct_util::convertHidlRttResponderToLegacy(info, &legacy_responder)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder( + ifname_, cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder); + return createWifiStatusFromLegacyError(legacy_status); +} +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_rtt_controller.h b/wifi/1.6/default/wifi_rtt_controller.h new file mode 100644 index 0000000000..b4a2116f2b --- /dev/null +++ b/wifi/1.6/default/wifi_rtt_controller.h @@ -0,0 +1,117 @@ +/* + * 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. + */ + +#ifndef WIFI_RTT_CONTROLLER_H_ +#define WIFI_RTT_CONTROLLER_H_ + +#include +#include +#include +#include + +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { + +/** + * HIDL interface object used to control all RTT operations. + */ +class WifiRttController : public V1_4::IWifiRttController { + public: + WifiRttController(const std::string& iface_name, const sp& bound_iface, + const std::weak_ptr legacy_hal); + // Refer to |WifiChip::invalidate()|. + void invalidate(); + bool isValid(); + std::vector> getEventCallbacks(); + std::string getIfaceName(); + + // HIDL methods exposed. + Return getBoundIface(getBoundIface_cb hidl_status_cb) override; + Return registerEventCallback(const sp& callback, + registerEventCallback_cb hidl_status_cb) override; + Return rangeRequest(uint32_t cmd_id, const hidl_vec& rtt_configs, + rangeRequest_cb hidl_status_cb) override; + Return rangeCancel(uint32_t cmd_id, const hidl_vec>& addrs, + rangeCancel_cb hidl_status_cb) override; + Return getCapabilities(getCapabilities_cb hidl_status_cb) override; + Return setLci(uint32_t cmd_id, const RttLciInformation& lci, + setLci_cb hidl_status_cb) override; + Return setLcr(uint32_t cmd_id, const RttLcrInformation& lcr, + setLcr_cb hidl_status_cb) override; + Return getResponderInfo(getResponderInfo_cb hidl_status_cb) override; + Return enableResponder(uint32_t cmd_id, const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, const V1_0::RttResponder& info, + enableResponder_cb hidl_status_cb) override; + Return disableResponder(uint32_t cmd_id, disableResponder_cb hidl_status_cb) override; + Return registerEventCallback_1_4( + const sp& callback, + registerEventCallback_1_4_cb hidl_status_cb) override; + Return rangeRequest_1_4(uint32_t cmd_id, const hidl_vec& rtt_configs, + rangeRequest_1_4_cb hidl_status_cb) override; + Return getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) override; + Return getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) override; + Return enableResponder_1_4(uint32_t cmd_id, const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, const V1_4::RttResponder& info, + enableResponder_1_4_cb hidl_status_cb) override; + + private: + // Corresponding worker functions for the HIDL methods. + std::pair> getBoundIfaceInternal(); + WifiStatus registerEventCallbackInternal( + const sp& callback); + WifiStatus rangeRequestInternal(uint32_t cmd_id, + const std::vector& rtt_configs); + WifiStatus rangeCancelInternal(uint32_t cmd_id, + const std::vector>& addrs); + std::pair getCapabilitiesInternal(); + WifiStatus setLciInternal(uint32_t cmd_id, const RttLciInformation& lci); + WifiStatus setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr); + std::pair getResponderInfoInternal(); + WifiStatus enableResponderInternal(uint32_t cmd_id, const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, + const V1_0::RttResponder& info); + WifiStatus disableResponderInternal(uint32_t cmd_id); + WifiStatus registerEventCallbackInternal_1_4( + const sp& callback); + WifiStatus rangeRequestInternal_1_4(uint32_t cmd_id, + const std::vector& rtt_configs); + std::pair getCapabilitiesInternal_1_4(); + std::pair getResponderInfoInternal_1_4(); + WifiStatus enableResponderInternal_1_4(uint32_t cmd_id, const WifiChannelInfo& channel_hint, + uint32_t max_duration_seconds, + const V1_4::RttResponder& info); + + std::string ifname_; + sp bound_iface_; + std::weak_ptr legacy_hal_; + std::vector> event_callbacks_; + bool is_valid_; + + DISALLOW_COPY_AND_ASSIGN(WifiRttController); +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_RTT_CONTROLLER_H_ diff --git a/wifi/1.6/default/wifi_sta_iface.cpp b/wifi/1.6/default/wifi_sta_iface.cpp new file mode 100644 index 0000000000..f852d36689 --- /dev/null +++ b/wifi/1.6/default/wifi_sta_iface.cpp @@ -0,0 +1,583 @@ +/* + * 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. + */ + +#include + +#include "hidl_return_util.h" +#include "hidl_struct_util.h" +#include "wifi_sta_iface.h" +#include "wifi_status_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using hidl_return_util::validateAndCall; + +WifiStaIface::WifiStaIface(const std::string& ifname, + const std::weak_ptr legacy_hal, + const std::weak_ptr iface_util) + : ifname_(ifname), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) { + // Turn on DFS channel usage for STA iface. + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to set DFS flag; DFS channels may be unavailable."; + } +} + +void WifiStaIface::invalidate() { + legacy_hal_.reset(); + event_cb_handler_.invalidate(); + is_valid_ = false; +} + +bool WifiStaIface::isValid() { + return is_valid_; +} + +std::string WifiStaIface::getName() { + return ifname_; +} + +std::set> WifiStaIface::getEventCallbacks() { + return event_cb_handler_.getCallbacks(); +} + +Return WifiStaIface::getName(getName_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getNameInternal, hidl_status_cb); +} + +Return WifiStaIface::getType(getType_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getTypeInternal, hidl_status_cb); +} + +Return WifiStaIface::registerEventCallback(const sp& callback, + registerEventCallback_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::registerEventCallbackInternal, hidl_status_cb, callback); +} + +Return WifiStaIface::getCapabilities(getCapabilities_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getCapabilitiesInternal, hidl_status_cb); +} + +Return WifiStaIface::getApfPacketFilterCapabilities( + getApfPacketFilterCapabilities_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getApfPacketFilterCapabilitiesInternal, hidl_status_cb); +} + +Return WifiStaIface::installApfPacketFilter(uint32_t cmd_id, const hidl_vec& program, + installApfPacketFilter_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::installApfPacketFilterInternal, hidl_status_cb, cmd_id, + program); +} + +Return WifiStaIface::readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::readApfPacketFilterDataInternal, hidl_status_cb); +} + +Return WifiStaIface::getBackgroundScanCapabilities( + getBackgroundScanCapabilities_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getBackgroundScanCapabilitiesInternal, hidl_status_cb); +} + +Return WifiStaIface::getValidFrequenciesForBand( + V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getValidFrequenciesForBandInternal, hidl_status_cb, band); +} + +Return WifiStaIface::startBackgroundScan(uint32_t cmd_id, + const StaBackgroundScanParameters& params, + startBackgroundScan_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::startBackgroundScanInternal, hidl_status_cb, cmd_id, + params); +} + +Return WifiStaIface::stopBackgroundScan(uint32_t cmd_id, + stopBackgroundScan_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::stopBackgroundScanInternal, hidl_status_cb, cmd_id); +} + +Return WifiStaIface::enableLinkLayerStatsCollection( + bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::enableLinkLayerStatsCollectionInternal, hidl_status_cb, + debug); +} + +Return WifiStaIface::disableLinkLayerStatsCollection( + disableLinkLayerStatsCollection_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::disableLinkLayerStatsCollectionInternal, hidl_status_cb); +} + +Return WifiStaIface::getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getLinkLayerStatsInternal, hidl_status_cb); +} + +Return WifiStaIface::getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getLinkLayerStatsInternal_1_3, hidl_status_cb); +} + +Return WifiStaIface::getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getLinkLayerStatsInternal_1_5, hidl_status_cb); +} + +Return WifiStaIface::startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, + startRssiMonitoring_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::startRssiMonitoringInternal, hidl_status_cb, cmd_id, + max_rssi, min_rssi); +} + +Return WifiStaIface::stopRssiMonitoring(uint32_t cmd_id, + stopRssiMonitoring_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::stopRssiMonitoringInternal, hidl_status_cb, cmd_id); +} + +Return WifiStaIface::getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getRoamingCapabilitiesInternal, hidl_status_cb); +} + +Return WifiStaIface::configureRoaming(const StaRoamingConfig& config, + configureRoaming_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::configureRoamingInternal, hidl_status_cb, config); +} + +Return WifiStaIface::setRoamingState(StaRoamingState state, + setRoamingState_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::setRoamingStateInternal, hidl_status_cb, state); +} + +Return WifiStaIface::enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::enableNdOffloadInternal, hidl_status_cb, enable); +} + +Return WifiStaIface::startSendingKeepAlivePackets( + uint32_t cmd_id, const hidl_vec& ip_packet_data, uint16_t ether_type, + const hidl_array& src_address, const hidl_array& dst_address, + uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::startSendingKeepAlivePacketsInternal, hidl_status_cb, + cmd_id, ip_packet_data, ether_type, src_address, dst_address, + period_in_ms); +} + +Return WifiStaIface::stopSendingKeepAlivePackets( + uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::stopSendingKeepAlivePacketsInternal, hidl_status_cb, + cmd_id); +} + +Return WifiStaIface::setScanningMacOui(const hidl_array& oui, + setScanningMacOui_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::setScanningMacOuiInternal, hidl_status_cb, oui); +} + +Return WifiStaIface::startDebugPacketFateMonitoring( + startDebugPacketFateMonitoring_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::startDebugPacketFateMonitoringInternal, hidl_status_cb); +} + +Return WifiStaIface::getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getDebugTxPacketFatesInternal, hidl_status_cb); +} + +Return WifiStaIface::getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getDebugRxPacketFatesInternal, hidl_status_cb); +} + +Return WifiStaIface::setMacAddress(const hidl_array& mac, + setMacAddress_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::setMacAddressInternal, hidl_status_cb, mac); +} + +Return WifiStaIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getFactoryMacAddressInternal, hidl_status_cb); +} + +Return WifiStaIface::setScanMode(bool enable, setScanMode_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::setScanModeInternal, hidl_status_cb, enable); +} + +std::pair WifiStaIface::getNameInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; +} + +std::pair WifiStaIface::getTypeInternal() { + return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::STA}; +} + +WifiStatus WifiStaIface::registerEventCallbackInternal( + const sp& callback) { + if (!event_cb_handler_.addCallback(callback)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +std::pair WifiStaIface::getCapabilitiesInternal() { + legacy_hal::wifi_error legacy_status; + uint64_t legacy_feature_set; + std::tie(legacy_status, legacy_feature_set) = + legacy_hal_.lock()->getSupportedFeatureSet(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), 0}; + } + uint32_t legacy_logger_feature_set; + std::tie(legacy_status, legacy_logger_feature_set) = + 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; + } + uint32_t hidl_caps; + if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities( + legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; +} + +std::pair +WifiStaIface::getApfPacketFilterCapabilitiesInternal() { + legacy_hal::wifi_error legacy_status; + legacy_hal::PacketFilterCapabilities legacy_caps; + std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getPacketFilterCapabilities(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + StaApfPacketFilterCapabilities hidl_caps; + if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps, &hidl_caps)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; +} + +WifiStatus WifiStaIface::installApfPacketFilterInternal(uint32_t /* cmd_id */, + const std::vector& program) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setPacketFilter(ifname_, program); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair> WifiStaIface::readApfPacketFilterDataInternal() { + const std::pair> legacy_status_and_data = + legacy_hal_.lock()->readApfPacketFilterData(ifname_); + return {createWifiStatusFromLegacyError(legacy_status_and_data.first), + std::move(legacy_status_and_data.second)}; +} + +std::pair +WifiStaIface::getBackgroundScanCapabilitiesInternal() { + legacy_hal::wifi_error legacy_status; + legacy_hal::wifi_gscan_capabilities legacy_caps; + std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getGscanCapabilities(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + StaBackgroundScanCapabilities hidl_caps; + if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps, &hidl_caps)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; +} + +std::pair> +WifiStaIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) { + static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch"); + legacy_hal::wifi_error legacy_status; + std::vector valid_frequencies; + std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand( + ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band)); + return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies}; +} + +WifiStatus WifiStaIface::startBackgroundScanInternal(uint32_t cmd_id, + const StaBackgroundScanParameters& params) { + legacy_hal::wifi_scan_cmd_params legacy_params; + if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params, &legacy_params)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + android::wp weak_ptr_this(this); + const auto& on_failure_callback = [weak_ptr_this](legacy_hal::wifi_request_id id) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onBackgroundScanFailure(id).isOk()) { + LOG(ERROR) << "Failed to invoke onBackgroundScanFailure callback"; + } + } + }; + const auto& on_results_callback = + [weak_ptr_this](legacy_hal::wifi_request_id id, + const std::vector& results) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + std::vector hidl_scan_datas; + if (!hidl_struct_util::convertLegacyVectorOfCachedGscanResultsToHidl( + results, &hidl_scan_datas)) { + LOG(ERROR) << "Failed to convert scan results to HIDL structs"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onBackgroundScanResults(id, hidl_scan_datas).isOk()) { + LOG(ERROR) << "Failed to invoke onBackgroundScanResults callback"; + } + } + }; + const auto& on_full_result_callback = [weak_ptr_this]( + legacy_hal::wifi_request_id id, + const legacy_hal::wifi_scan_result* result, + uint32_t buckets_scanned) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + StaScanResult hidl_scan_result; + if (!hidl_struct_util::convertLegacyGscanResultToHidl(*result, true, &hidl_scan_result)) { + LOG(ERROR) << "Failed to convert full scan results to HIDL structs"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onBackgroundFullScanResult(id, buckets_scanned, hidl_scan_result) + .isOk()) { + LOG(ERROR) << "Failed to invoke onBackgroundFullScanResult callback"; + } + } + }; + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->startGscan(ifname_, cmd_id, legacy_params, on_failure_callback, + on_results_callback, on_full_result_callback); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiStaIface::stopBackgroundScanInternal(uint32_t cmd_id) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopGscan(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableLinkLayerStats(ifname_); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair WifiStaIface::getLinkLayerStatsInternal() { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +std::pair WifiStaIface::getLinkLayerStatsInternal_1_3() { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +std::pair WifiStaIface::getLinkLayerStatsInternal_1_5() { + legacy_hal::wifi_error legacy_status; + legacy_hal::LinkLayerStats legacy_stats; + std::tie(legacy_status, legacy_stats) = legacy_hal_.lock()->getLinkLayerStats(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + V1_5::StaLinkLayerStats hidl_stats; + if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &hidl_stats)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats}; +} + +WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, + int32_t min_rssi) { + android::wp weak_ptr_this(this); + const auto& on_threshold_breached_callback = [weak_ptr_this](legacy_hal::wifi_request_id id, + std::array bssid, + int8_t rssi) { + const auto shared_ptr_this = weak_ptr_this.promote(); + if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { + LOG(ERROR) << "Callback invoked on an invalid object"; + return; + } + for (const auto& callback : shared_ptr_this->getEventCallbacks()) { + if (!callback->onRssiThresholdBreached(id, bssid, rssi).isOk()) { + LOG(ERROR) << "Failed to invoke onRssiThresholdBreached callback"; + } + } + }; + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRssiMonitoring( + ifname_, cmd_id, max_rssi, min_rssi, on_threshold_breached_callback); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiStaIface::stopRssiMonitoringInternal(uint32_t cmd_id) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair WifiStaIface::getRoamingCapabilitiesInternal() { + legacy_hal::wifi_error legacy_status; + legacy_hal::wifi_roaming_capabilities legacy_caps; + std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRoamingCapabilities(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + StaRoamingCapabilities hidl_caps; + if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps, &hidl_caps)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; +} + +WifiStatus WifiStaIface::configureRoamingInternal(const StaRoamingConfig& config) { + legacy_hal::wifi_roaming_config legacy_config; + if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config, &legacy_config)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->configureRoaming(ifname_, legacy_config); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableFirmwareRoaming( + ifname_, hidl_struct_util::convertHidlRoamingStateToLegacy(state)); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->configureNdOffload(ifname_, enable); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal( + uint32_t cmd_id, const std::vector& ip_packet_data, uint16_t ether_type, + const std::array& src_address, const std::array& dst_address, + uint32_t period_in_ms) { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startSendingOffloadedPacket( + ifname_, cmd_id, ether_type, ip_packet_data, src_address, dst_address, period_in_ms); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(uint32_t cmd_id) { + legacy_hal::wifi_error legacy_status = + legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id); + return createWifiStatusFromLegacyError(legacy_status); +} + +WifiStatus WifiStaIface::setScanningMacOuiInternal(const std::array& /* oui */) { + // deprecated. + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() { + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startPktFateMonitoring(ifname_); + return createWifiStatusFromLegacyError(legacy_status); +} + +std::pair> +WifiStaIface::getDebugTxPacketFatesInternal() { + legacy_hal::wifi_error legacy_status; + std::vector legacy_fates; + std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getTxPktFates(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + std::vector hidl_fates; + if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl(legacy_fates, + &hidl_fates)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates}; +} + +std::pair> +WifiStaIface::getDebugRxPacketFatesInternal() { + legacy_hal::wifi_error legacy_status; + std::vector legacy_fates; + std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getRxPktFates(ifname_); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + std::vector hidl_fates; + if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl(legacy_fates, + &hidl_fates)) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates}; +} + +WifiStatus WifiStaIface::setMacAddressInternal(const std::array& mac) { + bool status = iface_util_.lock()->setMacAddress(ifname_, mac); + if (!status) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +std::pair> WifiStaIface::getFactoryMacAddressInternal() { + std::array mac = iface_util_.lock()->getFactoryMacAddress(ifname_); + if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) { + return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac}; + } + return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; +} + +WifiStatus WifiStaIface::setScanModeInternal(bool enable) { + // OEM's need to implement this on their devices if needed. + LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported"; + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_sta_iface.h b/wifi/1.6/default/wifi_sta_iface.h new file mode 100644 index 0000000000..37358a5fb0 --- /dev/null +++ b/wifi/1.6/default/wifi_sta_iface.h @@ -0,0 +1,155 @@ +/* + * 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. + */ + +#ifndef WIFI_STA_IFACE_H_ +#define WIFI_STA_IFACE_H_ + +#include +#include +#include + +#include "hidl_callback_util.h" +#include "wifi_iface_util.h" +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; + +/** + * HIDL interface object used to control a STA Iface instance. + */ +class WifiStaIface : public V1_5::IWifiStaIface { + public: + WifiStaIface(const std::string& ifname, + const std::weak_ptr legacy_hal, + const std::weak_ptr iface_util); + // Refer to |WifiChip::invalidate()|. + void invalidate(); + bool isValid(); + std::set> getEventCallbacks(); + std::string getName(); + + // HIDL methods exposed. + Return getName(getName_cb hidl_status_cb) override; + Return getType(getType_cb hidl_status_cb) override; + Return registerEventCallback(const sp& callback, + registerEventCallback_cb hidl_status_cb) override; + Return getCapabilities(getCapabilities_cb hidl_status_cb) override; + Return getApfPacketFilterCapabilities( + getApfPacketFilterCapabilities_cb hidl_status_cb) override; + Return installApfPacketFilter(uint32_t cmd_id, const hidl_vec& program, + installApfPacketFilter_cb hidl_status_cb) override; + Return readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) override; + Return getBackgroundScanCapabilities( + getBackgroundScanCapabilities_cb hidl_status_cb) override; + Return getValidFrequenciesForBand(V1_0::WifiBand band, + getValidFrequenciesForBand_cb hidl_status_cb) override; + Return startBackgroundScan(uint32_t cmd_id, const StaBackgroundScanParameters& params, + startBackgroundScan_cb hidl_status_cb) override; + Return stopBackgroundScan(uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) override; + Return enableLinkLayerStatsCollection( + bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) override; + Return disableLinkLayerStatsCollection( + disableLinkLayerStatsCollection_cb hidl_status_cb) override; + Return getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) override; + Return getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) override; + Return getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) override; + Return startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, + startRssiMonitoring_cb hidl_status_cb) override; + Return stopRssiMonitoring(uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override; + Return getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) override; + Return configureRoaming(const StaRoamingConfig& config, + configureRoaming_cb hidl_status_cb) override; + Return setRoamingState(StaRoamingState state, setRoamingState_cb hidl_status_cb) override; + Return enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) override; + Return startSendingKeepAlivePackets( + uint32_t cmd_id, const hidl_vec& ip_packet_data, uint16_t ether_type, + const hidl_array& src_address, const hidl_array& dst_address, + uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) override; + Return stopSendingKeepAlivePackets( + uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) override; + Return setScanningMacOui(const hidl_array& oui, + setScanningMacOui_cb hidl_status_cb) override; + Return startDebugPacketFateMonitoring( + startDebugPacketFateMonitoring_cb hidl_status_cb) override; + Return getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) override; + Return getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) override; + Return setMacAddress(const hidl_array& mac, + setMacAddress_cb hidl_status_cb) override; + Return getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override; + Return setScanMode(bool enable, setScanMode_cb hidl_status_cb) override; + + private: + // Corresponding worker functions for the HIDL methods. + std::pair getNameInternal(); + std::pair getTypeInternal(); + WifiStatus registerEventCallbackInternal(const sp& callback); + std::pair getCapabilitiesInternal(); + std::pair getApfPacketFilterCapabilitiesInternal(); + WifiStatus installApfPacketFilterInternal(uint32_t cmd_id, const std::vector& program); + std::pair> readApfPacketFilterDataInternal(); + std::pair getBackgroundScanCapabilitiesInternal(); + std::pair> getValidFrequenciesForBandInternal( + V1_0::WifiBand band); + WifiStatus startBackgroundScanInternal(uint32_t cmd_id, + const StaBackgroundScanParameters& params); + WifiStatus stopBackgroundScanInternal(uint32_t cmd_id); + WifiStatus enableLinkLayerStatsCollectionInternal(bool debug); + WifiStatus disableLinkLayerStatsCollectionInternal(); + std::pair getLinkLayerStatsInternal(); + std::pair getLinkLayerStatsInternal_1_3(); + std::pair getLinkLayerStatsInternal_1_5(); + WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi); + WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id); + std::pair getRoamingCapabilitiesInternal(); + WifiStatus configureRoamingInternal(const StaRoamingConfig& config); + WifiStatus setRoamingStateInternal(StaRoamingState state); + WifiStatus enableNdOffloadInternal(bool enable); + WifiStatus startSendingKeepAlivePacketsInternal(uint32_t cmd_id, + const std::vector& ip_packet_data, + uint16_t ether_type, + const std::array& src_address, + const std::array& dst_address, + uint32_t period_in_ms); + WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id); + WifiStatus setScanningMacOuiInternal(const std::array& oui); + WifiStatus startDebugPacketFateMonitoringInternal(); + std::pair> getDebugTxPacketFatesInternal(); + std::pair> getDebugRxPacketFatesInternal(); + WifiStatus setMacAddressInternal(const std::array& mac); + std::pair> getFactoryMacAddressInternal(); + WifiStatus setScanModeInternal(bool enable); + + std::string ifname_; + std::weak_ptr legacy_hal_; + std::weak_ptr iface_util_; + bool is_valid_; + hidl_callback_util::HidlCallbackHandler event_cb_handler_; + + DISALLOW_COPY_AND_ASSIGN(WifiStaIface); +}; + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_STA_IFACE_H_ diff --git a/wifi/1.6/default/wifi_status_util.cpp b/wifi/1.6/default/wifi_status_util.cpp new file mode 100644 index 0000000000..3b18e537cd --- /dev/null +++ b/wifi/1.6/default/wifi_status_util.cpp @@ -0,0 +1,106 @@ +/* + * 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. + */ + +#include "wifi_status_util.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { + +std::string legacyErrorToString(legacy_hal::wifi_error error) { + switch (error) { + case legacy_hal::WIFI_SUCCESS: + return "SUCCESS"; + case legacy_hal::WIFI_ERROR_UNINITIALIZED: + return "UNINITIALIZED"; + case legacy_hal::WIFI_ERROR_NOT_AVAILABLE: + return "NOT_AVAILABLE"; + case legacy_hal::WIFI_ERROR_NOT_SUPPORTED: + return "NOT_SUPPORTED"; + case legacy_hal::WIFI_ERROR_INVALID_ARGS: + return "INVALID_ARGS"; + case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID: + return "INVALID_REQUEST_ID"; + case legacy_hal::WIFI_ERROR_TIMED_OUT: + return "TIMED_OUT"; + case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS: + return "TOO_MANY_REQUESTS"; + case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY: + return "OUT_OF_MEMORY"; + case legacy_hal::WIFI_ERROR_BUSY: + return "BUSY"; + case legacy_hal::WIFI_ERROR_UNKNOWN: + return "UNKNOWN"; + default: + return "UNKNOWN ERROR"; + } +} + +WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description) { + return {code, description}; +} + +WifiStatus createWifiStatus(WifiStatusCode code) { + return createWifiStatus(code, ""); +} + +WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, const std::string& desc) { + switch (error) { + case legacy_hal::WIFI_ERROR_UNINITIALIZED: + case legacy_hal::WIFI_ERROR_NOT_AVAILABLE: + return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, desc); + + case legacy_hal::WIFI_ERROR_NOT_SUPPORTED: + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED, desc); + + case legacy_hal::WIFI_ERROR_INVALID_ARGS: + case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID: + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS, desc); + + case legacy_hal::WIFI_ERROR_TIMED_OUT: + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", timed out"); + + case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS: + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", too many requests"); + + case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY: + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", out of memory"); + + case legacy_hal::WIFI_ERROR_BUSY: + return createWifiStatus(WifiStatusCode::ERROR_BUSY); + + case legacy_hal::WIFI_ERROR_NONE: + return createWifiStatus(WifiStatusCode::SUCCESS, desc); + + case legacy_hal::WIFI_ERROR_UNKNOWN: + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown"); + + default: + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown error"); + } +} + +WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) { + return createWifiStatusFromLegacyError(error, ""); +} + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.6/default/wifi_status_util.h b/wifi/1.6/default/wifi_status_util.h new file mode 100644 index 0000000000..ea1c29486b --- /dev/null +++ b/wifi/1.6/default/wifi_status_util.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef WIFI_STATUS_UTIL_H_ +#define WIFI_STATUS_UTIL_H_ + +#include + +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_6 { +namespace implementation { +using namespace android::hardware::wifi::V1_0; + +std::string legacyErrorToString(legacy_hal::wifi_error error); +WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description); +WifiStatus createWifiStatus(WifiStatusCode code); +WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, + const std::string& description); +WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error); + +} // namespace implementation +} // namespace V1_6 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_STATUS_UTIL_H_ -- cgit v1.2.3 From 962d5dfa99ca005be636294a519e752ffc5e1245 Mon Sep 17 00:00:00 2001 From: Gabriel Biren Date: Wed, 12 Jan 2022 23:15:17 +0000 Subject: Allow VTS tests to pass on devices without Hostapd AIDL. Bug: 214298597 Test: Run VTS tests on an AOSP build (since AOSP is still using the HIDL interface). Change-Id: I4bd005b5c96570694477a4b45fa5cc790c45be8f --- wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp index 41c54b3725..8f881968d7 100644 --- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp +++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp @@ -431,6 +431,7 @@ TEST_P(HostapdAidl, AddAccessPointWithDualBandConfig) { EXPECT_TRUE(status.isOk()); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdAidl); INSTANTIATE_TEST_SUITE_P( Hostapd, HostapdAidl, testing::ValuesIn(android::getAidlHalInstanceNames(IHostapd::descriptor)), -- cgit v1.2.3 From 7bd42e1b14baccde7eb584541181eaec0612a64a Mon Sep 17 00:00:00 2001 From: Joe Bolinger Date: Wed, 12 Jan 2022 16:27:03 -0800 Subject: Update common and face AIDL for session logging. Bug: 204585936 Bug: 204584403 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: Icba064c5c48f808327323ab64b7b63f68737a2f8 --- biometrics/face/aidl/Android.bp | 2 +- .../android/hardware/biometrics/face/ISession.aidl | 3 +++ .../android/hardware/biometrics/face/ISession.aidl | 20 ++++++++++++++++++++ biometrics/face/aidl/default/Android.bp | 4 ++-- biometrics/face/aidl/default/Session.cpp | 21 +++++++++++++++++++++ biometrics/face/aidl/default/Session.h | 14 ++++++++++++++ biometrics/face/aidl/default/face-default.xml | 1 + biometrics/face/aidl/vts/Android.bp | 4 ++-- .../compatibility_matrix.current.xml | 1 + 9 files changed, 65 insertions(+), 5 deletions(-) diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp index 3f53fc8cdf..fff2c1d3d4 100644 --- a/biometrics/face/aidl/Android.bp +++ b/biometrics/face/aidl/Android.bp @@ -16,7 +16,7 @@ aidl_interface { imports: [ "android.hardware.biometrics.common", "android.hardware.common-V2", - "android.hardware.keymaster", + "android.hardware.keymaster-V3", ], stability: "vintf", backend: { diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl index 78178642cd..4b51bb17cc 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl @@ -48,4 +48,7 @@ interface ISession { void invalidateAuthenticatorId(); void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat); void close(); + android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context); + android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface, in android.hardware.biometrics.common.OperationContext context); + android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context); } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 5f06b408e8..bbe3632b6b 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -17,6 +17,7 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.face.EnrollmentStageConfig; import android.hardware.biometrics.face.EnrollmentType; import android.hardware.biometrics.face.Feature; @@ -441,4 +442,23 @@ interface ISession { * - ISessionCallback#onSessionClosed */ void close(); + + /** + * These are alternative methods for some operations to allow the HAL to make optional + * optimizations during execution. + * + * HALs may ignore the additional context and treat all *WithContext methods the same as + * the original methods. + */ + + /* See ISession#authenticateWithContext(long) */ + ICancellationSignal authenticateWithContext(in long operationId, in OperationContext context); + + /* See ISession#enroll(HardwareAuthToken, EnrollmentType, Feature[], NativeHandle) */ + ICancellationSignal enrollWithContext(in HardwareAuthToken hat, in EnrollmentType type, + in Feature[] features, in @nullable NativeHandle previewSurface, + in OperationContext context); + + /* See ISession#detectInteraction() */ + ICancellationSignal detectInteractionWithContext(in OperationContext context); } diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp index 509231859d..7f66ecaf83 100644 --- a/biometrics/face/aidl/default/Android.bp +++ b/biometrics/face/aidl/default/Android.bp @@ -16,8 +16,8 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.biometrics.face-V1-ndk", - "android.hardware.biometrics.common-V1-ndk", + "android.hardware.biometrics.face-V2-ndk", + "android.hardware.biometrics.common-V2-ndk", ], srcs: [ "main.cpp", diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index 01cb620b35..9e753e5c33 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -151,4 +151,25 @@ ndk::ScopedAStatus Session::close() { return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::authenticateWithContext( + int64_t operationId, const common::OperationContext& /*context*/, + std::shared_ptr* out) { + return authenticate(operationId, out); +} + +ndk::ScopedAStatus Session::enrollWithContext(const keymaster::HardwareAuthToken& hat, + EnrollmentType enrollmentType, + const std::vector& features, + const std::optional& previewSurface, + const common::OperationContext& /*context*/, + std::shared_ptr* out) { + return enroll(hat, enrollmentType, features, previewSurface, out); +} + +ndk::ScopedAStatus Session::detectInteractionWithContext( + const common::OperationContext& /*context*/, + std::shared_ptr* out) { + return detectInteraction(out); +} + } // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index 4152909a49..0ce9e2060e 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -68,6 +68,20 @@ class Session : public BnSession { ndk::ScopedAStatus close() override; + ndk::ScopedAStatus authenticateWithContext( + int64_t operationId, const common::OperationContext& context, + std::shared_ptr* out) override; + + ndk::ScopedAStatus enrollWithContext( + const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType, + const std::vector& features, const std::optional& previewSurface, + const common::OperationContext& context, + std::shared_ptr* out) override; + + ndk::ScopedAStatus detectInteractionWithContext( + const common::OperationContext& context, + std::shared_ptr* out) override; + private: std::shared_ptr cb_; std::mt19937 mRandom; diff --git a/biometrics/face/aidl/default/face-default.xml b/biometrics/face/aidl/default/face-default.xml index 6915ad0a4d..e6ef842734 100644 --- a/biometrics/face/aidl/default/face-default.xml +++ b/biometrics/face/aidl/default/face-default.xml @@ -1,6 +1,7 @@ android.hardware.biometrics.face + 2 IFace/default diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp index 09ec4d06e3..4171ac3364 100644 --- a/biometrics/face/aidl/vts/Android.bp +++ b/biometrics/face/aidl/vts/Android.bp @@ -15,8 +15,8 @@ cc_test { ], srcs: ["VtsHalBiometricsFaceTargetTest.cpp"], static_libs: [ - "android.hardware.biometrics.common-V1-ndk", - "android.hardware.biometrics.face-V1-ndk", + "android.hardware.biometrics.common-V2-ndk", + "android.hardware.biometrics.face-V2-ndk", "android.hardware.common-V2-ndk", "android.hardware.keymaster-V3-ndk", ], diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index cf856889df..2762bf1de5 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -110,6 +110,7 @@ android.hardware.biometrics.face + 2 IFace default -- cgit v1.2.3 From 42b2d0a65f4ba512004cf86c1e8ebd8898cd423d Mon Sep 17 00:00:00 2001 From: Yuchen He Date: Wed, 12 Jan 2022 04:39:37 +0000 Subject: Support the location injection in AIDL HAL Bug: 213225295 Test: atest VtsHalGnssTargetTest Change-Id: Iff9fca55722af9bad6cc50f0170e4e1a069d05d6 --- gnss/aidl/default/Gnss.cpp | 19 +++++++++++-- gnss/aidl/default/Gnss.h | 1 + gnss/common/utils/default/GnssReplayUtils.cpp | 2 +- gnss/common/utils/default/NmeaFixInfo.cpp | 37 +++++++++++++++++++++++++ gnss/common/utils/default/include/NmeaFixInfo.h | 3 ++ 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index e296351d95..657877898f 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -20,6 +20,7 @@ #include #include #include "AGnss.h" +#include "DeviceFileReader.h" #include "GnssBatching.h" #include "GnssConfiguration.h" #include "GnssDebug.h" @@ -28,10 +29,13 @@ #include "GnssNavigationMessageInterface.h" #include "GnssPsds.h" #include "GnssVisibilityControl.h" +#include "NmeaFixInfo.h" #include "Utils.h" namespace aidl::android::hardware::gnss { +using ::android::hardware::gnss::common::NmeaFixInfo; using ::android::hardware::gnss::common::Utils; + using ndk::ScopedAStatus; using GnssSvInfo = IGnssCallback::GnssSvInfo; @@ -62,6 +66,12 @@ ScopedAStatus Gnss::setCallback(const std::shared_ptr& callback) return ScopedAStatus::ok(); } +std::unique_ptr Gnss::getLocationFromHW() { + std::string inputStr = + ::android::hardware::gnss::common::DeviceFileReader::Instance().getLocationData(); + return ::android::hardware::gnss::common::NmeaFixInfo::getAidlLocationFromInputStr(inputStr); +} + ScopedAStatus Gnss::start() { ALOGD("start()"); if (mIsActive) { @@ -82,9 +92,14 @@ ScopedAStatus Gnss::start() { auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList()); this->reportSvStatus(svStatus); + auto currentLocation = getLocationFromHW(); mGnssPowerIndication->notePowerConsumption(); - const auto location = Utils::getMockLocation(); - this->reportLocation(location); + if (currentLocation != nullptr) { + this->reportLocation(*currentLocation); + } else { + const auto location = Utils::getMockLocation(); + this->reportLocation(location); + } std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); } }); diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index 384c8629a2..f21d756c24 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -79,6 +79,7 @@ class Gnss : public BnGnss { std::vector filterBlocklistedSatellites( std::vector gnssSvInfoList); void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const; + std::unique_ptr getLocationFromHW(); static std::shared_ptr sGnssCallback; diff --git a/gnss/common/utils/default/GnssReplayUtils.cpp b/gnss/common/utils/default/GnssReplayUtils.cpp index e3f4ff82a0..535647716b 100644 --- a/gnss/common/utils/default/GnssReplayUtils.cpp +++ b/gnss/common/utils/default/GnssReplayUtils.cpp @@ -41,7 +41,7 @@ bool ReplayUtils::isGnssRawMeasurement(const std::string& inputStr) { bool ReplayUtils::isNMEA(const std::string& inputStr) { return !inputStr.empty() && (inputStr.find("$GPRMC,", 0) != std::string::npos || - inputStr.find("$GPRMA,", 0) != std::string::npos); + inputStr.find("$GPGGA,", 0) != std::string::npos); } } // namespace common diff --git a/gnss/common/utils/default/NmeaFixInfo.cpp b/gnss/common/utils/default/NmeaFixInfo.cpp index c7ee13488b..22aef90204 100644 --- a/gnss/common/utils/default/NmeaFixInfo.cpp +++ b/gnss/common/utils/default/NmeaFixInfo.cpp @@ -34,6 +34,9 @@ namespace hardware { namespace gnss { namespace common { +using aidl::android::hardware::gnss::ElapsedRealtime; +using aidl::android::hardware::gnss::GnssLocation; + NmeaFixInfo::NmeaFixInfo() : hasGMCRecord(false), hasGGARecord(false) {} float NmeaFixInfo::getAltitudeMeters() const { @@ -236,6 +239,40 @@ std::unique_ptr NmeaFixInfo::getLocationFromInputStr( return nmeaFixInfo.toGnssLocation(); } +/** + * Convert V2_0::GnssLocation to aidl::GnssLocation. + */ +std::unique_ptr NmeaFixInfo::getAidlLocationFromInputStr( + const std::string& inputStr) { + std::unique_ptr locationV2 = getLocationFromInputStr(inputStr); + if (locationV2 == nullptr) { + return nullptr; + } + + ElapsedRealtime elapsedRealtime = { + .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS, + .timestampNs = ::android::elapsedRealtimeNano(), + // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks. + // In an actual implementation provide an estimate of the synchronization uncertainty + // or don't set the field. + .timeUncertaintyNs = 1020400}; + + GnssLocation location = { + .gnssLocationFlags = locationV2->v1_0.gnssLocationFlags, + .latitudeDegrees = locationV2->v1_0.latitudeDegrees, + .longitudeDegrees = locationV2->v1_0.longitudeDegrees, + .altitudeMeters = locationV2->v1_0.altitudeMeters, + .speedMetersPerSec = locationV2->v1_0.speedMetersPerSec, + .bearingDegrees = locationV2->v1_0.bearingDegrees, + .horizontalAccuracyMeters = locationV2->v1_0.horizontalAccuracyMeters, + .verticalAccuracyMeters = locationV2->v1_0.verticalAccuracyMeters, + .speedAccuracyMetersPerSecond = locationV2->v1_0.speedAccuracyMetersPerSecond, + .bearingAccuracyDegrees = locationV2->v1_0.bearingAccuracyDegrees, + .timestampMillis = locationV2->v1_0.timestamp, + .elapsedRealtime = elapsedRealtime}; + return std::make_unique(location); +} + /** * Parses the input string in NMEA format and convert to GnssLocation. */ diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h index 5c27045316..407336121d 100644 --- a/gnss/common/utils/default/include/NmeaFixInfo.h +++ b/gnss/common/utils/default/include/NmeaFixInfo.h @@ -22,6 +22,7 @@ #include #include #include +#include "aidl/android/hardware/gnss/IGnss.h" namespace android { namespace hardware { namespace gnss { @@ -45,6 +46,8 @@ class NmeaFixInfo { public: static std::unique_ptr getLocationFromInputStr(const std::string& inputStr); + static std::unique_ptr getAidlLocationFromInputStr( + const std::string& inputStr); private: static void splitStr(const std::string& line, const char& delimiter, -- cgit v1.2.3 From c6b8907a322adc6e0861346ae2749a4e05703659 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Tue, 14 Dec 2021 14:32:51 +0000 Subject: Alter spec text for RSA-PSS to match reality The Key{Mint,Master} spec previously said that RSA-PSS mode should use SHA-1 for the MGF1 digest, separately from whatever Tag::DIGEST gets specified as the main digest. However, both the reference implementation and the VTS/CTS tests use BoringSSL's defaults, which is to re-use the main digest as the MGF1 digest if none is separately specified. Given that this behaviour is embedded in many implementations over several years (and given that there isn't a security implication), change the spec to match this behaviour. Also update the VTS test code to make this clear/obvious. Test: VtsAidlKeyMintTargetTest, VtsHalKeymasterV4_0TargetTest Bug: 210424594 Merged-In: I4303f28d094ef4d4b9dc931d6728b1fa040de20d Change-Id: I4303f28d094ef4d4b9dc931d6728b1fa040de20d --- current.txt | 1 + keymaster/4.0/IKeymasterDevice.hal | 3 ++- keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp | 1 + .../aidl/android/hardware/security/keymint/IKeyMintOperation.aidl | 3 ++- security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp | 1 + 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/current.txt b/current.txt index 21ee123576..7718b98519 100644 --- a/current.txt +++ b/current.txt @@ -903,6 +903,7 @@ c8a57364f6ad20842be14f4db284df5304f7521ca8eac6bcc1fa6c5b466fb8a6 android.hardwar # ABI preserving changes to HALs during Android T 62ace52d9c3ff1f60f94118557a2aaf0b953513e59dcd34d5f94ae28d4c7e780 android.hardware.fastboot@1.0::IFastboot +d0fb32f3ddeb9af7115ab32905225ea69b930d2472be8e9610f0cf136c15aefb android.hardware.keymaster@4.0::IKeymasterDevice # b/210424594 ca62a2a95d173ed323309e5e00f653ad3cceec82a6e5e4976a249cb5aafe2515 android.hardware.neuralnetworks@1.2::types fa76bced6b1b71c40fc706c508a9011284c57f57831cd0cf5f45653ed4ea463e android.hardware.neuralnetworks@1.3::types diff --git a/keymaster/4.0/IKeymasterDevice.hal b/keymaster/4.0/IKeymasterDevice.hal index dfde060e3f..1c6ae478f4 100644 --- a/keymaster/4.0/IKeymasterDevice.hal +++ b/keymaster/4.0/IKeymasterDevice.hal @@ -1254,7 +1254,8 @@ interface IKeymasterDevice { * o PaddingMode::RSA_PSS. For PSS-padded signature operations, the PSS salt length must match * the size of the PSS digest selected. The digest specified with Tag::DIGEST in inputParams * on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask - * generation function and SHA1 must be used as the MGF1 digest algorithm. + * generation function and the digest specified with Tag:DIGEST in inputParams must also be + * used as the MGF1 digest algorithm. * * o PaddingMode::RSA_OAEP. The digest specified with Tag::DIGEST in inputParams on begin is * used as the OAEP digest algorithm, MGF1 must be used as the mask generation function and diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp index 2449268943..2ff33b0940 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -1712,6 +1712,7 @@ TEST_P(VerificationOperationsTest, RsaAllPaddingsAndDigests) { case PaddingMode::RSA_PSS: EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0); EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0); + EXPECT_GT(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md), 0); break; case PaddingMode::RSA_PKCS1_1_5_SIGN: // PKCS1 is the default; don't need to set anything. diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl index ce83044d0e..ca8955552e 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl @@ -227,7 +227,8 @@ interface IKeyMintOperation { * o PaddingMode::RSA_PSS. For PSS-padded signature operations, the PSS salt length must match * the size of the PSS digest selected. The digest specified with Tag::DIGEST in params * on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask - * generation function and SHA1 must be used as the MGF1 digest algorithm. + * generation function and the digest specified with Tag:DIGEST in params on begin() must also + * be used as the MGF1 digest algorithm. * * -- ECDSA keys -- * diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 02462fce3a..374f2da7a8 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -812,6 +812,7 @@ void KeyMintAidlTestBase::LocalVerifyMessage(const string& message, const string if (padding == PaddingMode::RSA_PSS) { EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0); EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0); + EXPECT_GT(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md), 0); } ASSERT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, -- cgit v1.2.3 From ab1851e9f2c40942fff243504788795aeaf89961 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Tue, 14 Dec 2021 14:32:51 +0000 Subject: Alter spec text for RSA-PSS to match reality The Key{Mint,Master} spec previously said that RSA-PSS mode should use SHA-1 for the MGF1 digest, separately from whatever Tag::DIGEST gets specified as the main digest. However, both the reference implementation and the VTS/CTS tests use BoringSSL's defaults, which is to re-use the main digest as the MGF1 digest if none is separately specified. Given that this behaviour is embedded in many implementations over several years (and given that there isn't a security implication), change the spec to match this behaviour. Also update the VTS test code to make this clear/obvious. Test: VtsAidlKeyMintTargetTest, VtsHalKeymasterV4_0TargetTest Bug: 210424594 Change-Id: I4303f28d094ef4d4b9dc931d6728b1fa040de20d Ignore-AOSP-First: target internal master first due to merge conflict --- current.txt | 1 + keymaster/4.0/IKeymasterDevice.hal | 3 ++- keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp | 1 + .../aidl/android/hardware/security/keymint/IKeyMintOperation.aidl | 3 ++- security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp | 1 + 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/current.txt b/current.txt index 1dbf5ab1be..1fedaa0d6e 100644 --- a/current.txt +++ b/current.txt @@ -907,6 +907,7 @@ c8a57364f6ad20842be14f4db284df5304f7521ca8eac6bcc1fa6c5b466fb8a6 android.hardwar # ABI preserving changes to HALs during Android T 62ace52d9c3ff1f60f94118557a2aaf0b953513e59dcd34d5f94ae28d4c7e780 android.hardware.fastboot@1.0::IFastboot f767a132ef28275294db15353f14f3876a4048770751931a77d038d4228f2cb7 android.hardware.graphics.composer@2.4::IComposerClient +d0fb32f3ddeb9af7115ab32905225ea69b930d2472be8e9610f0cf136c15aefb android.hardware.keymaster@4.0::IKeymasterDevice # b/210424594 ca62a2a95d173ed323309e5e00f653ad3cceec82a6e5e4976a249cb5aafe2515 android.hardware.neuralnetworks@1.2::types fa76bced6b1b71c40fc706c508a9011284c57f57831cd0cf5f45653ed4ea463e android.hardware.neuralnetworks@1.3::types diff --git a/keymaster/4.0/IKeymasterDevice.hal b/keymaster/4.0/IKeymasterDevice.hal index dfde060e3f..1c6ae478f4 100644 --- a/keymaster/4.0/IKeymasterDevice.hal +++ b/keymaster/4.0/IKeymasterDevice.hal @@ -1254,7 +1254,8 @@ interface IKeymasterDevice { * o PaddingMode::RSA_PSS. For PSS-padded signature operations, the PSS salt length must match * the size of the PSS digest selected. The digest specified with Tag::DIGEST in inputParams * on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask - * generation function and SHA1 must be used as the MGF1 digest algorithm. + * generation function and the digest specified with Tag:DIGEST in inputParams must also be + * used as the MGF1 digest algorithm. * * o PaddingMode::RSA_OAEP. The digest specified with Tag::DIGEST in inputParams on begin is * used as the OAEP digest algorithm, MGF1 must be used as the mask generation function and diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp index 767614754b..6412f3a06b 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -1712,6 +1712,7 @@ TEST_P(VerificationOperationsTest, RsaAllPaddingsAndDigests) { case PaddingMode::RSA_PSS: EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0); EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0); + EXPECT_GT(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md), 0); break; case PaddingMode::RSA_PKCS1_1_5_SIGN: // PKCS1 is the default; don't need to set anything. diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl index ce83044d0e..ca8955552e 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl @@ -227,7 +227,8 @@ interface IKeyMintOperation { * o PaddingMode::RSA_PSS. For PSS-padded signature operations, the PSS salt length must match * the size of the PSS digest selected. The digest specified with Tag::DIGEST in params * on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask - * generation function and SHA1 must be used as the MGF1 digest algorithm. + * generation function and the digest specified with Tag:DIGEST in params on begin() must also + * be used as the MGF1 digest algorithm. * * -- ECDSA keys -- * diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 02462fce3a..374f2da7a8 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -812,6 +812,7 @@ void KeyMintAidlTestBase::LocalVerifyMessage(const string& message, const string if (padding == PaddingMode::RSA_PSS) { EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0); EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0); + EXPECT_GT(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md), 0); } ASSERT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, -- cgit v1.2.3 From 4dd1b26caf2aaeee25429bc369b75c1187a4fd43 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Wed, 12 Jan 2022 20:20:23 -0800 Subject: BtAudio: Replace bitmask capabilities with vector Bug: 203490261 Test: m android.hardware.bluetooth.audio-update-api Change-Id: I258e9912ab740990cab61772f0d6893a64d372d9 --- .../android/hardware/bluetooth/audio/AacCapabilities.aidl | 4 ++-- .../android/hardware/bluetooth/audio/AacObjectType.aidl | 8 ++++---- .../android/hardware/bluetooth/audio/AptxCapabilities.aidl | 2 +- .../current/android/hardware/bluetooth/audio/ChannelMode.aidl | 6 +++--- .../android/hardware/bluetooth/audio/LdacCapabilities.aidl | 4 ++-- .../android/hardware/bluetooth/audio/LdacChannelMode.aidl | 8 ++++---- .../android/hardware/bluetooth/audio/LdacQualityIndex.aidl | 8 ++++---- .../android/hardware/bluetooth/audio/PcmCapabilities.aidl | 2 +- .../android/hardware/bluetooth/audio/SbcAllocMethod.aidl | 4 ++-- .../android/hardware/bluetooth/audio/SbcCapabilities.aidl | 4 ++-- .../android/hardware/bluetooth/audio/SbcChannelMode.aidl | 10 +++++----- .../aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl | 6 ++---- .../aidl/android/hardware/bluetooth/audio/AacObjectType.aidl | 8 ++++---- .../android/hardware/bluetooth/audio/AptxCapabilities.aidl | 3 +-- .../aidl/android/hardware/bluetooth/audio/ChannelMode.aidl | 6 +++--- .../android/hardware/bluetooth/audio/LdacCapabilities.aidl | 6 ++---- .../aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl | 8 ++++---- .../android/hardware/bluetooth/audio/LdacQualityIndex.aidl | 8 ++++---- .../aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl | 2 +- .../aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl | 4 ++-- .../aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl | 6 ++---- .../aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl | 10 +++++----- 22 files changed, 60 insertions(+), 67 deletions(-) diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl index ad44c26f59..899b8ca6db 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl @@ -34,9 +34,9 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable AacCapabilities { - android.hardware.bluetooth.audio.AacObjectType objectType; + android.hardware.bluetooth.audio.AacObjectType[] objectType; int[] sampleRateHz; - android.hardware.bluetooth.audio.ChannelMode channelMode; + android.hardware.bluetooth.audio.ChannelMode[] channelMode; boolean variableBitRateSupported; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl index c129c66b40..2148244d06 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl @@ -34,8 +34,8 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum AacObjectType { - MPEG2_LC = 1, - MPEG4_LC = 2, - MPEG4_LTP = 4, - MPEG4_SCALABLE = 8, + MPEG2_LC = 0, + MPEG4_LC = 1, + MPEG4_LTP = 2, + MPEG4_SCALABLE = 3, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl index 4767b696ec..08a38e26e1 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl @@ -35,6 +35,6 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable AptxCapabilities { int[] sampleRateHz; - android.hardware.bluetooth.audio.ChannelMode channelMode; + android.hardware.bluetooth.audio.ChannelMode[] channelMode; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl index 3ca93c3e03..c3bc7410e4 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl @@ -34,7 +34,7 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum ChannelMode { - UNKNOWN = 1, - MONO = 2, - STEREO = 4, + UNKNOWN = 0, + MONO = 1, + STEREO = 2, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl index 19e041a15c..aa4e4c8793 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl @@ -35,7 +35,7 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable LdacCapabilities { int[] sampleRateHz; - android.hardware.bluetooth.audio.LdacChannelMode channelMode; - android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex; + android.hardware.bluetooth.audio.LdacChannelMode[] channelMode; + android.hardware.bluetooth.audio.LdacQualityIndex[] qualityIndex; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl index a9d6c5e14e..88d6faff53 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl @@ -34,8 +34,8 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum LdacChannelMode { - UNKNOWN = 1, - STEREO = 2, - DUAL = 4, - MONO = 8, + UNKNOWN = 0, + STEREO = 1, + DUAL = 2, + MONO = 3, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl index 693392fe51..35e435867e 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl @@ -34,8 +34,8 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum LdacQualityIndex { - HIGH = 1, - MID = 2, - LOW = 4, - ABR = 8, + HIGH = 0, + MID = 1, + LOW = 2, + ABR = 3, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl index 6cfe5cd78c..0c2f87d599 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl @@ -35,7 +35,7 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable PcmCapabilities { int[] sampleRateHz; - android.hardware.bluetooth.audio.ChannelMode channelMode; + android.hardware.bluetooth.audio.ChannelMode[] channelMode; byte[] bitsPerSample; int[] dataIntervalUs; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl index 5170f164a3..091f6d7246 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl @@ -34,6 +34,6 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum SbcAllocMethod { - ALLOC_MD_S = 1, - ALLOC_MD_L = 2, + ALLOC_MD_S = 0, + ALLOC_MD_L = 1, } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl index ec3aa0f262..c8d7e7e74e 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl @@ -35,10 +35,10 @@ package android.hardware.bluetooth.audio; @VintfStability parcelable SbcCapabilities { int[] sampleRateHz; - android.hardware.bluetooth.audio.SbcChannelMode channelMode; + android.hardware.bluetooth.audio.SbcChannelMode[] channelMode; byte[] blockLength; byte[] numSubbands; - android.hardware.bluetooth.audio.SbcAllocMethod allocMethod; + android.hardware.bluetooth.audio.SbcAllocMethod[] allocMethod; byte[] bitsPerSample; int minBitpool; int maxBitpool; diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl index 88fca4aac4..6441a99877 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl @@ -34,9 +34,9 @@ package android.hardware.bluetooth.audio; @Backing(type="byte") @VintfStability enum SbcChannelMode { - UNKNOWN = 1, - JOINT_STEREO = 2, - STEREO = 4, - DUAL = 8, - MONO = 16, + UNKNOWN = 0, + JOINT_STEREO = 1, + STEREO = 2, + DUAL = 3, + MONO = 4, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl index 43038836aa..c4153e9ffd 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl @@ -24,11 +24,9 @@ import android.hardware.bluetooth.audio.ChannelMode; */ @VintfStability parcelable AacCapabilities { - /* bitfield */ - AacObjectType objectType; + AacObjectType[] objectType; int[] sampleRateHz; - /* bitfield */ - ChannelMode channelMode; + ChannelMode[] channelMode; boolean variableBitRateSupported; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl index 480e422e1c..4e9958c855 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl @@ -22,17 +22,17 @@ enum AacObjectType { /** * MPEG-2 Low Complexity. Support is Mandatory. */ - MPEG2_LC = 1, + MPEG2_LC, /** * MPEG-4 Low Complexity. Support is Optional. */ - MPEG4_LC = 1 << 1, + MPEG4_LC, /** * MPEG-4 Long Term Prediction. Support is Optional. */ - MPEG4_LTP = 1 << 2, + MPEG4_LTP, /** * MPEG-4 Scalable. Support is Optional. */ - MPEG4_SCALABLE = 1 << 3, + MPEG4_SCALABLE, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl index 6a37fc6a41..f5605d31fe 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl @@ -24,7 +24,6 @@ import android.hardware.bluetooth.audio.ChannelMode; @VintfStability parcelable AptxCapabilities { int[] sampleRateHz; - /* bitfield */ - ChannelMode channelMode; + ChannelMode[] channelMode; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl index 2df879d837..66138724ae 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl @@ -19,7 +19,7 @@ package android.hardware.bluetooth.audio; @VintfStability @Backing(type="byte") enum ChannelMode { - UNKNOWN = 1, - MONO = 1 << 1, - STEREO = 1 << 2, + UNKNOWN, + MONO, + STEREO, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl index 44cca7e071..1dbec0896b 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl @@ -26,9 +26,7 @@ import android.hardware.bluetooth.audio.LdacQualityIndex; @VintfStability parcelable LdacCapabilities { int[] sampleRateHz; - /* bitfiled */ - LdacChannelMode channelMode; - /* bitfiled */ - LdacQualityIndex qualityIndex; + LdacChannelMode[] channelMode; + LdacQualityIndex[] qualityIndex; byte[] bitsPerSample; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl index 3acca32fc2..3cc910f49c 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl @@ -22,8 +22,8 @@ package android.hardware.bluetooth.audio; @VintfStability @Backing(type="byte") enum LdacChannelMode { - UNKNOWN = 1, - STEREO = 1 << 1, - DUAL = 1 << 2, - MONO = 1 << 3, + UNKNOWN, + STEREO, + DUAL, + MONO, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl index cb125839ef..9993b8b6d2 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl @@ -22,17 +22,17 @@ enum LdacQualityIndex { /** * 990kbps */ - HIGH = 1, + HIGH, /** * 660kbps */ - MID = 1 << 1, + MID, /** * 330kbps */ - LOW = 1 << 2, + LOW, /** * Adaptive Bit Rate mode */ - ABR = 1 << 3, + ABR, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl index f5d699edf1..776b777f50 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl @@ -24,7 +24,7 @@ import android.hardware.bluetooth.audio.ChannelMode; @VintfStability parcelable PcmCapabilities { int[] sampleRateHz; - ChannelMode channelMode; + ChannelMode[] channelMode; byte[] bitsPerSample; /** * Data interval for data transfer diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl index 7047e346dc..1159f30374 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl @@ -22,9 +22,9 @@ enum SbcAllocMethod { /** * SNR */ - ALLOC_MD_S = 1, + ALLOC_MD_S, /** * Loudness */ - ALLOC_MD_L = 1 << 1, + ALLOC_MD_L, } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl index cf62ed4e5e..743a1f73e2 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl @@ -25,12 +25,10 @@ import android.hardware.bluetooth.audio.SbcChannelMode; @VintfStability parcelable SbcCapabilities { int[] sampleRateHz; - /* bitfield */ - SbcChannelMode channelMode; + SbcChannelMode[] channelMode; byte[] blockLength; byte[] numSubbands; - /* bitfield */ - SbcAllocMethod allocMethod; + SbcAllocMethod[] allocMethod; byte[] bitsPerSample; /* * range from 2 to 250. diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl index 7eb38cd9f7..68e32670e8 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl @@ -19,9 +19,9 @@ package android.hardware.bluetooth.audio; @VintfStability @Backing(type="byte") enum SbcChannelMode { - UNKNOWN = 1, - JOINT_STEREO = 1 << 1, - STEREO = 1 << 2, - DUAL = 1 << 3, - MONO = 1 << 4, + UNKNOWN, + JOINT_STEREO, + STEREO, + DUAL, + MONO, } -- cgit v1.2.3 From 4c6e9ebf1ee7fbfda9a0997c7dc509db1bdbc29c Mon Sep 17 00:00:00 2001 From: Kriti Dang Date: Wed, 17 Nov 2021 14:56:29 +0100 Subject: Composer hal changes for boot time display mode Bug: 203520442 Test: m Test: atest VtsHalGraphicsComposer3_TargetTest Change-Id: I530d7f52acaaee8c728dbd9a95ecca017804304a --- .../graphics/composer3/IComposerClient.aidl | 3 ++ .../graphics/composer3/IComposerClient.aidl | 52 ++++++++++++++++++++ .../VtsHalGraphicsComposer3_TargetTest.cpp | 55 ++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl index e9d9745dff..a8239cd052 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl @@ -61,6 +61,9 @@ interface IComposerClient { void registerCallback(in android.hardware.graphics.composer3.IComposerCallback callback); void setActiveConfig(long display, int config); android.hardware.graphics.composer3.VsyncPeriodChangeTimeline setActiveConfigWithConstraints(long display, int config, in android.hardware.graphics.composer3.VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints); + void setBootDisplayConfig(long display, int config); + void clearBootDisplayConfig(long display); + int getPreferredBootDisplayConfig(long display); void setAutoLowLatencyMode(long display, boolean on); void setClientTargetSlotCount(long display, int clientTargetSlotCount); void setColorMode(long display, android.hardware.graphics.composer3.ColorMode mode, android.hardware.graphics.composer3.RenderIntent intent); diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl index 3ab6329bff..9a29e7e23e 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl @@ -548,6 +548,58 @@ interface IComposerClient { VsyncPeriodChangeTimeline setActiveConfigWithConstraints( long display, int config, in VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints); + /** + * Sets the display config in which the device boots. + * + * If the device is unable to boot in this config for any reason (example HDMI display changed), + * the implementation should try to find a config which matches the resolution and refresh-rate + * of this config. If no such config exists, the implementation's preferred display config + * should be used. + * + * @param display is the display for which the boot config is set. + * @param config is the new boot config for the display. + * + * @exception EX_BAD_DISPLAY when an invalid display handle was passed in. + * @exception EX_BAD_CONFIG when an invalid config id was passed in. + * + * @see getDisplayConfigs + * @see clearBootDisplayConfig + * @see getPreferredBootDisplayConfig + */ + void setBootDisplayConfig(long display, int config); + + /** + * Clears the boot display config. + * + * The device should boot in the implementation's preferred display config. + * + * @param display is the display for which the cached boot config is cleared. + * + * @exception EX_BAD_DISPLAY when an invalid display handle was passed in. + * + * @see getDisplayConfigs + * @see setBootDisplayConfig + * @see getPreferredBootDisplayConfig + */ + void clearBootDisplayConfig(long display); + + /** + * Returns the implementation's preferred display config. + * + * This is the display config used by the implementation at boot time, if the boot display + * config has not been requested yet, or if it has been previously cleared. + * + * @param display is the display to which the preferred config is queried. + * @return the implementation's preferred display config. + * + * @exception EX_BAD_DISPLAY when an invalid display handle was passed in. + * + * @see getDisplayConfigs + * @see setBootDisplayConfig + * @see clearBootDisplayConfig + */ + int getPreferredBootDisplayConfig(long display); + /** * Requests the display to enable/disable its low latency mode. * diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index c61693e458..a59a090b27 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -716,6 +716,61 @@ TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadConfig) { } } +TEST_P(GraphicsComposerAidlTest, setBootDisplayConfig_BadDisplay) { + int32_t config = 0; + auto const error = mComposerClient->setBootDisplayConfig(mInvalidDisplayId, config); + + EXPECT_FALSE(error.isOk()); + EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); +} + +TEST_P(GraphicsComposerAidlTest, setBootDisplayConfig_BadConfig) { + for (VtsDisplay& display : mDisplays) { + int32_t invalidConfigId = GetInvalidConfigId(); + const auto error = mComposerClient->setBootDisplayConfig(display.get(), invalidConfigId); + EXPECT_FALSE(error.isOk()); + EXPECT_EQ(IComposerClient::EX_BAD_CONFIG, error.getServiceSpecificError()); + } +} + +TEST_P(GraphicsComposerAidlTest, setBootDisplayConfig) { + std::vector configs; + EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk()); + for (auto config : configs) { + EXPECT_TRUE(mComposerClient->setBootDisplayConfig(mPrimaryDisplay, config).isOk()); + } +} + +TEST_P(GraphicsComposerAidlTest, clearBootDisplayConfig_BadDisplay) { + auto const error = mComposerClient->clearBootDisplayConfig(mInvalidDisplayId); + + EXPECT_FALSE(error.isOk()); + EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); +} + +TEST_P(GraphicsComposerAidlTest, clearBootDisplayConfig) { + EXPECT_TRUE(mComposerClient->clearBootDisplayConfig(mPrimaryDisplay).isOk()); +} + +TEST_P(GraphicsComposerAidlTest, getPreferredBootDisplayConfig_BadDisplay) { + int32_t config; + auto const error = mComposerClient->getPreferredBootDisplayConfig(mInvalidDisplayId, &config); + + EXPECT_FALSE(error.isOk()); + EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); +} + +TEST_P(GraphicsComposerAidlTest, getPreferredBootDisplayConfig) { + int32_t preferredDisplayConfig = 0; + auto const error = mComposerClient->getPreferredBootDisplayConfig(mPrimaryDisplay, + &preferredDisplayConfig); + EXPECT_TRUE(error.isOk()); + + std::vector configs; + EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk()); + EXPECT_NE(configs.end(), std::find(configs.begin(), configs.end(), preferredDisplayConfig)); +} + TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyModeBadDisplay) { EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true) -- cgit v1.2.3 From c338f29b6d8cb271776a640143be19aca1dbc26f Mon Sep 17 00:00:00 2001 From: Sneh Bansal Date: Wed, 12 Jan 2022 20:23:57 +0530 Subject: VTS: Check for "ro.board.first_api_level" in GetBarringInfo() Some GRF targets launched with S release do not support getBarringInfo() API. Check "ro.board.first_api_level" also to return from the test-case when the response is REQUEST_NOT_SUPPORTED. Bug: 212384410 Change-Id: I890f54f80ff3aca3dcb2c51f20db087d453c2927 --- radio/1.5/vts/functional/radio_hidl_hal_api.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp index d108951c0e..152858f6a8 100644 --- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp @@ -1271,8 +1271,12 @@ TEST_P(RadioHidlTest_v1_5, getBarringInfo) { EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial); int32_t firstApiLevel = android::base::GetIntProperty("ro.product.first_api_level", 0); + int32_t boardApiLevel = android::base::GetIntProperty("ro.board.first_api_level", 0); // Allow devices shipping with Radio::1_5 and Android 11 to not support barring info. - if (firstApiLevel > 0 && firstApiLevel <= 30) { + // b/212384410 Some GRF targets lauched with S release but with vendor R release + // do not support getBarringInfo API. Allow these devices to not support barring info. + if ((firstApiLevel > 0 && firstApiLevel <= 30) || + (boardApiLevel > 0 && boardApiLevel <= 30)) { ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); // Early exit for devices that don't support barring info. -- cgit v1.2.3 From 0331815adb4c952bcdd01d938b106495349186da Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Thu, 13 Jan 2022 12:24:19 -0500 Subject: Add VTS for setLayerBlockingRegion Fixes: 213361853 Test this Change-Id: Iaca3be9f83420964cd3945d39665a95da50fee08 --- .../VtsHalGraphicsComposer3_TargetTest.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index 829b0ff66f..a3ee49f474 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -1698,6 +1698,26 @@ TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SURFACE_DAMAGE) { ASSERT_TRUE(mReader.takeErrors().empty()); } +TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLOCKING_REGION) { + int64_t layer; + EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk()); + + Rect empty{0, 0, 0, 0}; + Rect unit{0, 0, 1, 1}; + + mWriter.setLayerBlockingRegion(mPrimaryDisplay, layer, std::vector(1, empty)); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); + + mWriter.setLayerBlockingRegion(mPrimaryDisplay, layer, std::vector(1, unit)); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); + + mWriter.setLayerBlockingRegion(mPrimaryDisplay, layer, std::vector()); + execute(); + ASSERT_TRUE(mReader.takeErrors().empty()); +} + TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLEND_MODE) { int64_t layer; EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk()); -- cgit v1.2.3 From d561cc3391c3683fc3801d074877ec9ade0b6169 Mon Sep 17 00:00:00 2001 From: Sooraj Sasindran Date: Tue, 11 Jan 2022 09:42:21 -0800 Subject: add slicingConfigChanged api add slicing config changed api to be sent by modem whenever there is a slice config change Test: build, vts tracked using bug 214043323 Bug: 194332512 Change-Id: I86e8ab8ac5aa782b099434f1a04ce314631b7f4e --- .../android/hardware/radio/data/IRadioDataIndication.aidl | 1 + .../android/hardware/radio/data/IRadioDataIndication.aidl | 14 ++++++++++++++ .../compat/libradiocompat/data/RadioIndication-data.cpp | 7 +++++++ .../include/libradiocompat/RadioIndication.h | 2 ++ radio/aidl/vts/radio_data_indication.cpp | 5 +++++ radio/aidl/vts/radio_data_utils.h | 2 ++ 6 files changed, 31 insertions(+) diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl index b0cc1eb189..0ffa1f7ddf 100644 --- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl @@ -38,4 +38,5 @@ interface IRadioDataIndication { oneway void keepaliveStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.KeepaliveStatus status); oneway void pcoData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.PcoDataInfo pco); oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.DataProfileInfo dataProfileInfo); + oneway void slicingConfigChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SlicingConfig slicingConfig); } diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl index 1772c8859f..938c695fd4 100644 --- a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl +++ b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl @@ -21,6 +21,7 @@ import android.hardware.radio.data.DataProfileInfo; import android.hardware.radio.data.KeepaliveStatus; import android.hardware.radio.data.PcoDataInfo; import android.hardware.radio.data.SetupDataCallResult; +import android.hardware.radio.data.SlicingConfig; /** * Interface declaring unsolicited radio indications for data APIs. @@ -72,4 +73,17 @@ oneway interface IRadioDataIndication { * @param dataProfileInfo Data profile info. */ void unthrottleApn(in RadioIndicationType type, in DataProfileInfo dataProfileInfo); + + /** + * Indicates the current slicing configuration including URSP rules and NSSAIs + * (configured, allowed and rejected). URSP stands for UE route selection policy and is defined + * in 3GPP TS 24.526 Section 4.2. An NSSAI is a collection of network slices. Each network slice + * is identified by an S-NSSAI and is represented by the struct SliceInfo. NSSAI and S-NSSAI + * are defined in 3GPP TS 24.501. + * + * @param type Type of radio indication + * @param slicingConfig Current slicing configuration + * + */ + void slicingConfigChanged(in RadioIndicationType type, in SlicingConfig slicingConfig); } diff --git a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp index 1d367d2025..602bb39390 100644 --- a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp +++ b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp @@ -85,4 +85,11 @@ Return RadioIndication::unthrottleApn(V1_0::RadioIndicationType type, return {}; } +Return RadioIndication::slicingConfigChanged(V1_0::RadioIndicationType type, + const V1_6::SlicingConfig& slicingConfig) { + LOG_CALL << type; + dataCb()->slicingConfigChanged(toAidl(type), toAidl(slicingConfig)); + return {}; +} + } // namespace android::hardware::radio::compat diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h index c668af5dce..6cfd59c6a3 100644 --- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h +++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h @@ -186,6 +186,8 @@ class RadioIndication : public V1_6::IRadioIndication { V1_0::RadioIndicationType type, const hidl_vec& dcList) override; Return unthrottleApn(V1_0::RadioIndicationType type, const hidl_string& apn) override; + Return slicingConfigChanged(V1_0::RadioIndicationType type, + const V1_6::SlicingConfig& slicingConfig); Return currentLinkCapacityEstimate_1_6(V1_0::RadioIndicationType type, const V1_6::LinkCapacityEstimate& lce) override; Return currentSignalStrength_1_6(V1_0::RadioIndicationType type, diff --git a/radio/aidl/vts/radio_data_indication.cpp b/radio/aidl/vts/radio_data_indication.cpp index 4d3c539d91..61e079e532 100644 --- a/radio/aidl/vts/radio_data_indication.cpp +++ b/radio/aidl/vts/radio_data_indication.cpp @@ -37,3 +37,8 @@ ndk::ScopedAStatus RadioDataIndication::unthrottleApn(RadioIndicationType /*type const DataProfileInfo& /*dataProfileInfo*/) { return ndk::ScopedAStatus::ok(); } + +ndk::ScopedAStatus RadioDataIndication::slicingConfigChanged( + RadioIndicationType /*type*/, const SlicingConfig& /*slicingConfig*/) { + return ndk::ScopedAStatus::ok(); +} diff --git a/radio/aidl/vts/radio_data_utils.h b/radio/aidl/vts/radio_data_utils.h index 50c7878a2c..fb91ef61d5 100644 --- a/radio/aidl/vts/radio_data_utils.h +++ b/radio/aidl/vts/radio_data_utils.h @@ -95,6 +95,8 @@ class RadioDataIndication : public BnRadioDataIndication { virtual ndk::ScopedAStatus unthrottleApn(RadioIndicationType type, const DataProfileInfo& dataProfile) override; + virtual ndk::ScopedAStatus slicingConfigChanged(RadioIndicationType type, + const SlicingConfig& slicingConfig) override; }; // The main test class for Radio AIDL Data. -- cgit v1.2.3 From 8df6fa133bee3e428208cd2d1ecfd55d14da3598 Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Thu, 13 Jan 2022 11:51:58 -0800 Subject: [LSC] Add LOCAL_LICENSE_KINDS to hardware/interfaces Added SPDX-license-identifier-Apache-2.0 to: bluetooth/audio/aidl/Android.bp Bug: 68860345 Bug: 151177513 Bug: 151953481 Test: m all Change-Id: Ie941d147d28d4e6e7b9eb93154e029f743e8b086 --- bluetooth/audio/aidl/Android.bp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp index 60da877af2..12eed55072 100644 --- a/bluetooth/audio/aidl/Android.bp +++ b/bluetooth/audio/aidl/Android.bp @@ -12,6 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + aidl_interface { name: "android.hardware.bluetooth.audio", vendor_available: true, -- cgit v1.2.3 From 19a6a6a76ca5abedfaf4d4fd871b70bd8ef3eba7 Mon Sep 17 00:00:00 2001 From: Yuchen He Date: Thu, 13 Jan 2022 18:39:50 +0000 Subject: Add parser to support CSV location data Bug: 213225295 Test: launch_cvd -cpus 16 -memory_mb 16192 --start_gnss_proxy --gnss_file_path=/google/data/rw/users/yu/yuchenhe/input.txt (Running blue dot in Google Maps) Change-Id: I572315888c2f57ce701e695acb03aa6b28787f31 --- gnss/common/utils/default/Android.bp | 1 + gnss/common/utils/default/FixLocationParser.cpp | 75 ++++++++++++++++++++++ .../utils/default/include/FixLocationParser.h | 48 ++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 gnss/common/utils/default/FixLocationParser.cpp create mode 100644 gnss/common/utils/default/include/FixLocationParser.h diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index 05bec882de..b896f04ddf 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -39,6 +39,7 @@ cc_library_static { "v2_1/GnssMeasurement.cpp", "v2_1/GnssMeasurementCorrections.cpp", "DeviceFileReader.cpp", + "FixLocationParser.cpp", "GnssRawMeasurementParser.cpp", "GnssReplayUtils.cpp", "MockLocation.cpp", diff --git a/gnss/common/utils/default/FixLocationParser.cpp b/gnss/common/utils/default/FixLocationParser.cpp new file mode 100644 index 0000000000..f391d96616 --- /dev/null +++ b/gnss/common/utils/default/FixLocationParser.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 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 "FixLocationParser.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace common { + +using aidl::android::hardware::gnss::ElapsedRealtime; +using aidl::android::hardware::gnss::GnssLocation; + +std::unique_ptr FixLocationParser::getLocationFromInputStr( + const std::string& locationStr) { + /* + * Fix,Provider,LatitudeDegrees,LongitudeDegrees,AltitudeMeters,SpeedMps, + * AccuracyMeters,BearingDegrees,UnixTimeMillis,SpeedAccuracyMps,BearingAccuracyDegrees, + * elapsedRealtimeNanos + */ + if (locationStr.empty()) { + return nullptr; + } + std::vector locationStrRecords; + ParseUtils::splitStr(locationStr, LINE_SEPARATOR, locationStrRecords); + if (locationStrRecords.empty()) { + return nullptr; + } + + std::vector locationValues; + ParseUtils::splitStr(locationStrRecords[0], COMMA_SEPARATOR, locationValues); + if (locationValues.size() < 12) { + return nullptr; + } + ElapsedRealtime elapsedRealtime = { + .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS, + .timestampNs = ::android::elapsedRealtimeNano(), + // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks. + // In an actual implementation provide an estimate of the synchronization uncertainty + // or don't set the field. + .timeUncertaintyNs = 1020400}; + + GnssLocation location = { + .gnssLocationFlags = 0xFF, + .latitudeDegrees = ParseUtils::tryParseDouble(locationValues[2], 0), + .longitudeDegrees = ParseUtils::tryParseDouble(locationValues[3], 0), + .altitudeMeters = ParseUtils::tryParseDouble(locationValues[4], 0), + .speedMetersPerSec = ParseUtils::tryParseDouble(locationValues[5], 0), + .bearingDegrees = ParseUtils::tryParseDouble(locationValues[7], 0), + .horizontalAccuracyMeters = ParseUtils::tryParseDouble(locationValues[6], 0), + .verticalAccuracyMeters = ParseUtils::tryParseDouble(locationValues[6], 0), + .speedAccuracyMetersPerSecond = ParseUtils::tryParseDouble(locationValues[9], 0), + .bearingAccuracyDegrees = ParseUtils::tryParseDouble(locationValues[10], 0), + .timestampMillis = ParseUtils::tryParseLongLong(locationValues[8], 0), + .elapsedRealtime = elapsedRealtime}; + return std::make_unique(location); +} + +} // namespace common +} // namespace gnss +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/gnss/common/utils/default/include/FixLocationParser.h b/gnss/common/utils/default/include/FixLocationParser.h new file mode 100644 index 0000000000..a73891452a --- /dev/null +++ b/gnss/common/utils/default/include/FixLocationParser.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 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_common_default_FixLocationParser_H_ +#define android_hardware_gnss_common_default_FixLocationParser_H_ + +#include + +#include +#include +#include + +#include +#include +#include +#include "Constants.h" +#include "ParseUtils.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace common { + +struct FixLocationParser { + public: + static std::unique_ptr getLocationFromInputStr( + const std::string& inputStr); +}; + +} // namespace common +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // android_hardware_gnss_common_default_FixLocationParser_H_ \ No newline at end of file -- cgit v1.2.3 From 154fbf15198acb7ddb37126a914f0f5bf2e24510 Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Thu, 13 Jan 2022 16:50:17 -0800 Subject: [LSC] Add LOCAL_LICENSE_KINDS to hardware/interfaces Added SPDX-license-identifier-Apache-2.0 to: sensors/aidl/Android.bp Bug: 68860345 Bug: 151177513 Bug: 151953481 Test: m all Change-Id: I6597543c2398a639c850f72bfe7013e9df2a2358 --- sensors/aidl/Android.bp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp index 7324abf50d..92b7ad03d8 100644 --- a/sensors/aidl/Android.bp +++ b/sensors/aidl/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + aidl_interface { name: "android.hardware.sensors", vendor_available: true, -- cgit v1.2.3 From 59329712a917a4c4e81fffc0891063d0c5d96fff Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Thu, 13 Jan 2022 07:59:37 -0800 Subject: Update VTS to use ExternalTexture impl We want to expose GraphicBuffer properties via ExternalTexture class and within, SurfaceFlinger access the buffer via this proxy interface. This allows us to inject and mock GraphicBuffers as needed. Specifically this will be used to recreate layer state from transaction traces. Test: compiles Bug: 200284593 Change-Id: If2b6c43bb5b302fbc49dfa49d6ac1f79f92f30f7 --- graphics/composer/2.2/utils/vts/ReadbackVts.cpp | 5 +++-- graphics/composer/2.2/utils/vts/RenderEngineVts.cpp | 5 +++-- .../composer3/vts/functional/composer-vts/ReadbackVts.cpp | 14 ++++++++------ .../vts/functional/composer-vts/RenderEngineVts.cpp | 5 +++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp index 30596fc4c9..a1794afeed 100644 --- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp +++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp @@ -17,6 +17,7 @@ #include #include #include "renderengine/ExternalTexture.h" +#include "renderengine/impl/ExternalTexture.h" namespace android { namespace hardware { @@ -281,11 +282,11 @@ void TestBufferLayer::write(const std::shared_ptr& writer) { LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.buffer.buffer = std::make_shared( + layerSettings.source.buffer.buffer = std::make_shared( new GraphicBuffer(mBufferHandle->get(), GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, static_cast(mFormat), 1, mUsage, mStride), mRenderEngine.getInternalRenderEngine(), - renderengine::ExternalTexture::Usage::READABLE); + renderengine::impl::ExternalTexture::Usage::READABLE); layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED; diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp index 2d4cc7d80e..4a33fb5b42 100644 --- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp +++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp @@ -15,6 +15,7 @@ */ #include +#include "renderengine/impl/ExternalTexture.h" namespace android { namespace hardware { @@ -68,8 +69,8 @@ void TestRenderEngine::drawLayers() { [](renderengine::LayerSettings& settings) -> renderengine::LayerSettings { return settings; }); - auto texture = std::make_shared( - mGraphicBuffer, *mRenderEngine, renderengine::ExternalTexture::Usage::WRITEABLE); + auto texture = std::make_shared( + mGraphicBuffer, *mRenderEngine, renderengine::impl::ExternalTexture::Usage::WRITEABLE); auto [status, readyFence] = mRenderEngine ->drawLayers(mDisplaySettings, compositionLayers, texture, true, std::move(bufferFence)) diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp index 5eb912bb3f..c5e4268e6b 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp @@ -22,6 +22,7 @@ #include #include "include/RenderEngineVts.h" #include "renderengine/ExternalTexture.h" +#include "renderengine/impl/ExternalTexture.h" // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion @@ -306,12 +307,13 @@ void TestBufferLayer::write(ComposerClientWriter& writer) { LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.buffer.buffer = std::make_shared<::android::renderengine::ExternalTexture>( - ::android::sp<::android::GraphicBuffer>::make( - mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, - static_cast(mPixelFormat), 1, mUsage, mStride), - mRenderEngine.getInternalRenderEngine(), - ::android::renderengine::ExternalTexture::Usage::READABLE); + layerSettings.source.buffer.buffer = + std::make_shared<::android::renderengine::impl::ExternalTexture>( + ::android::sp<::android::GraphicBuffer>::make( + mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth, + mHeight, static_cast(mPixelFormat), 1, mUsage, mStride), + mRenderEngine.getInternalRenderEngine(), + ::android::renderengine::impl::ExternalTexture::Usage::READABLE); layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED; diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp index 50ce462459..6ff064f93c 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp @@ -15,6 +15,7 @@ */ #include "include/RenderEngineVts.h" +#include "renderengine/impl/ExternalTexture.h" namespace aidl::android::hardware::graphics::composer3::vts { @@ -62,9 +63,9 @@ void TestRenderEngine::drawLayers() { std::back_insert_iterator(compositionLayers), [](::android::renderengine::LayerSettings& settings) -> ::android::renderengine::LayerSettings { return settings; }); - auto texture = std::make_shared<::android::renderengine::ExternalTexture>( + auto texture = std::make_shared<::android::renderengine::impl::ExternalTexture>( mGraphicBuffer, *mRenderEngine, - ::android::renderengine::ExternalTexture::Usage::WRITEABLE); + ::android::renderengine::impl::ExternalTexture::Usage::WRITEABLE); auto [status, readyFence] = mRenderEngine ->drawLayers(mDisplaySettings, compositionLayers, texture, true, std::move(bufferFence)) -- cgit v1.2.3 From 9918ede8cec4bcaec76d32dc963177897ce46fae Mon Sep 17 00:00:00 2001 From: Ling Ma Date: Thu, 13 Jan 2022 19:55:45 +0000 Subject: Add ApnType.ENTERPRISE Test: build succeed Bug: 214240937 Change-Id: I718ff225c7fc9b9667f6360ae623e5d8bbf1f03c --- .../current/android/hardware/radio/data/ApnTypes.aidl | 3 +++ radio/aidl/android/hardware/radio/data/ApnTypes.aidl | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl index 6982d404bd..980b042cdf 100644 --- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl @@ -47,4 +47,7 @@ enum ApnTypes { EMERGENCY = 512, MCX = 1024, XCAP = 2048, + VSIM = 4096, + BIP = 8192, + ENTERPRISE = 16384, } diff --git a/radio/aidl/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl index e780d8ee6b..ae103fc7e5 100644 --- a/radio/aidl/android/hardware/radio/data/ApnTypes.aidl +++ b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl @@ -73,4 +73,16 @@ enum ApnTypes { * APN type for XCAP */ XCAP = 1 << 11, + /** + * APN type for VSIM. + */ + VSIM = 1 << 12, + /** + * APN type for BIP. + */ + BIP = 1 << 13, + /** + * APN type for ENTERPRISE + */ + ENTERPRISE = 1 << 14 } -- cgit v1.2.3 From aae30614d6efec7e7c7aea61845b06e9b583087d Mon Sep 17 00:00:00 2001 From: Greg Kaiser Date: Fri, 14 Jan 2022 07:54:49 -0800 Subject: VtsAidlHalSensorsTargetTest: Fix assignment To make this assignment have an impact outside the function, we need to assign to the dereference of the pointer. Test: TreeHugger Bug: 195593357 Change-Id: I3541735574d6ebe2f2620c2bc5fbf5dd7d97cd91 --- sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp index 608a4b0c4c..1bc7263048 100644 --- a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp +++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp @@ -978,7 +978,7 @@ void SensorsAidlTest::verifyRegisterDirectChannel( ASSERT_EQ(status.getExceptionCode(), error); ASSERT_EQ(channelHandle, -1); } - directChannelHandle = &channelHandle; + *directChannelHandle = channelHandle; } void SensorsAidlTest::verifyUnregisterDirectChannel(int32_t* channelHandle, -- cgit v1.2.3 From 7b957abe495da313ba7ec0611f92721aeae5529c Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Fri, 14 Jan 2022 17:10:09 +0000 Subject: Add alecmouri to composer OWNERS Change-Id: I01a0958e1371ba0e6a92d7f5f0d19ce0acdb7604 --- graphics/composer/2.1/default/OWNERS | 1 + graphics/composer/2.1/utils/OWNERS | 1 + graphics/composer/2.1/vts/OWNERS | 1 + graphics/composer/2.1/vts/functional/OWNERS | 2 ++ graphics/composer/2.2/default/OWNERS | 2 ++ graphics/composer/2.2/utils/OWNERS | 1 + graphics/composer/2.2/vts/functional/OWNERS | 1 + graphics/composer/2.3/default/OWNERS | 1 + graphics/composer/2.3/utils/OWNERS | 1 + graphics/composer/2.3/vts/functional/OWNERS | 1 + graphics/composer/2.4/default/OWNERS | 1 + graphics/composer/2.4/utils/OWNERS | 1 + graphics/composer/2.4/vts/functional/OWNERS | 1 + 13 files changed, 15 insertions(+) diff --git a/graphics/composer/2.1/default/OWNERS b/graphics/composer/2.1/default/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.1/default/OWNERS +++ b/graphics/composer/2.1/default/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.1/utils/OWNERS b/graphics/composer/2.1/utils/OWNERS index 7af69b4203..83c4f5f613 100644 --- a/graphics/composer/2.1/utils/OWNERS +++ b/graphics/composer/2.1/utils/OWNERS @@ -1,2 +1,3 @@ adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.1/vts/OWNERS b/graphics/composer/2.1/vts/OWNERS index ea06752da7..a643bbdf0e 100644 --- a/graphics/composer/2.1/vts/OWNERS +++ b/graphics/composer/2.1/vts/OWNERS @@ -1,5 +1,6 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com # VTS team diff --git a/graphics/composer/2.1/vts/functional/OWNERS b/graphics/composer/2.1/vts/functional/OWNERS index a2ed8c8500..3d970d16fc 100644 --- a/graphics/composer/2.1/vts/functional/OWNERS +++ b/graphics/composer/2.1/vts/functional/OWNERS @@ -1,2 +1,4 @@ # Bug component: 25423 +adyabr@google.com +alecmouri@google.com sumir@google.com diff --git a/graphics/composer/2.2/default/OWNERS b/graphics/composer/2.2/default/OWNERS index 709c4d1c35..e8f584dd15 100644 --- a/graphics/composer/2.2/default/OWNERS +++ b/graphics/composer/2.2/default/OWNERS @@ -1,3 +1,5 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com + diff --git a/graphics/composer/2.2/utils/OWNERS b/graphics/composer/2.2/utils/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.2/utils/OWNERS +++ b/graphics/composer/2.2/utils/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.2/vts/functional/OWNERS b/graphics/composer/2.2/vts/functional/OWNERS index 31b0dc752b..a4eb0caf84 100644 --- a/graphics/composer/2.2/vts/functional/OWNERS +++ b/graphics/composer/2.2/vts/functional/OWNERS @@ -1,5 +1,6 @@ # Bug component: 25423 # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com sumir@google.com diff --git a/graphics/composer/2.3/default/OWNERS b/graphics/composer/2.3/default/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.3/default/OWNERS +++ b/graphics/composer/2.3/default/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.3/utils/OWNERS b/graphics/composer/2.3/utils/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.3/utils/OWNERS +++ b/graphics/composer/2.3/utils/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.3/vts/functional/OWNERS b/graphics/composer/2.3/vts/functional/OWNERS index 31b0dc752b..a4eb0caf84 100644 --- a/graphics/composer/2.3/vts/functional/OWNERS +++ b/graphics/composer/2.3/vts/functional/OWNERS @@ -1,5 +1,6 @@ # Bug component: 25423 # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com sumir@google.com diff --git a/graphics/composer/2.4/default/OWNERS b/graphics/composer/2.4/default/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.4/default/OWNERS +++ b/graphics/composer/2.4/default/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.4/utils/OWNERS b/graphics/composer/2.4/utils/OWNERS index 709c4d1c35..331c80d22a 100644 --- a/graphics/composer/2.4/utils/OWNERS +++ b/graphics/composer/2.4/utils/OWNERS @@ -1,3 +1,4 @@ # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com diff --git a/graphics/composer/2.4/vts/functional/OWNERS b/graphics/composer/2.4/vts/functional/OWNERS index 31b0dc752b..a4eb0caf84 100644 --- a/graphics/composer/2.4/vts/functional/OWNERS +++ b/graphics/composer/2.4/vts/functional/OWNERS @@ -1,5 +1,6 @@ # Bug component: 25423 # Graphics team adyabr@google.com +alecmouri@google.com lpy@google.com sumir@google.com -- cgit v1.2.3 From 734c841dafbf2018efd67ef214b28048998a28ce Mon Sep 17 00:00:00 2001 From: Brian J Murray Date: Thu, 13 Jan 2022 14:55:30 -0800 Subject: Block cipher fixups Various block cipher testing fixups. Some of these changes reflect edge cases I encountered when running local GSC builds. Change: * Extend ciphertext lengths. * Add SCOPED_TRACE() within for loops. * Use '\t' instead of 'a' for PKCS7 padding. Test: CTS/VTS Signed-off-by: Brian J Murray Change-Id: I4555519787e0133367ad3f40609d43a7bc71c36e --- .../keymint/aidl/vts/functional/KeyMintTest.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 5b80b6fac0..d109058b8f 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -4608,8 +4608,10 @@ TEST_P(EncryptionOperationsTest, AesEcbPkcs7Padding) { auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7); // Try various message lengths; all should work. - for (size_t i = 0; i < 32; ++i) { - string message(i, 'a'); + for (size_t i = 0; i <= 48; i++) { + SCOPED_TRACE(testing::Message() << "i = " << i); + // Edge case: '\t' (0x09) is also a valid PKCS7 padding character. + string message(i, '\t'); string ciphertext = EncryptMessage(message, params); EXPECT_EQ(i + 16 - (i % 16), ciphertext.size()); string plaintext = DecryptMessage(ciphertext, params); @@ -4633,7 +4635,7 @@ TEST_P(EncryptionOperationsTest, AesEcbWrongPadding) { auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7); // Try various message lengths; all should fail - for (size_t i = 0; i < 32; ++i) { + for (size_t i = 0; i <= 48; i++) { string message(i, 'a'); EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, params)); } @@ -5775,8 +5777,8 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcRoundTripSuccess) { ASSERT_GT(key_blob_.size(), 0U); - // Two-block message. - string message = "1234567890123456"; + // Four-block message. + string message = "12345678901234561234567890123456"; vector iv1; string ciphertext1 = EncryptMessage(message, BlockMode::CBC, PaddingMode::NONE, &iv1); EXPECT_EQ(message.size(), ciphertext1.size()); @@ -5936,8 +5938,10 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcPkcs7Padding) { .Padding(PaddingMode::PKCS7))); // Try various message lengths; all should work. - for (size_t i = 0; i < 32; ++i) { - string message(i, 'a'); + for (size_t i = 0; i <= 32; i++) { + SCOPED_TRACE(testing::Message() << "i = " << i); + // Edge case: '\t' (0x09) is also a valid PKCS7 padding character, albeit not for 3DES. + string message(i, '\t'); vector iv; string ciphertext = EncryptMessage(message, BlockMode::CBC, PaddingMode::PKCS7, &iv); EXPECT_EQ(i + 8 - (i % 8), ciphertext.size()); @@ -5959,7 +5963,7 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcNoPaddingKeyWithPkcs7Padding) { .Padding(PaddingMode::NONE))); // Try various message lengths; all should fail. - for (size_t i = 0; i < 32; ++i) { + for (size_t i = 0; i <= 32; i++) { auto begin_params = AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::PKCS7); EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, begin_params)); @@ -5990,6 +5994,7 @@ TEST_P(EncryptionOperationsTest, TripleDesCbcPkcs7PaddingCorrupted) { .Authorization(TAG_NONCE, iv); for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) { + SCOPED_TRACE(testing::Message() << "i = " << i); ++ciphertext[ciphertext.size() / 2]; EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)); string plaintext; -- cgit v1.2.3 From bd838b8b5e673451e5ac85131d6cb119960d2fce Mon Sep 17 00:00:00 2001 From: Tyler Trephan Date: Thu, 13 Jan 2022 22:52:53 +0000 Subject: Moved implementation of ConvertUtils to cpp file. Test: make android.hardware.sensors@aidl-multihal Bug: 206867060 Change-Id: I73e8d061bdfe39f956acda1cf9b138da2dcc1f22 --- sensors/aidl/default/multihal/Android.bp | 1 + sensors/aidl/default/multihal/ConvertUtils.cpp | 321 ++++++++++++++++ .../aidl/default/multihal/include/ConvertUtils.h | 406 +-------------------- 3 files changed, 339 insertions(+), 389 deletions(-) create mode 100644 sensors/aidl/default/multihal/ConvertUtils.cpp diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp index a7f6af2df2..eee10625bb 100644 --- a/sensors/aidl/default/multihal/Android.bp +++ b/sensors/aidl/default/multihal/Android.bp @@ -43,6 +43,7 @@ cc_library_static { export_include_dirs: ["include"], srcs: [ "HalProxyAidl.cpp", + "ConvertUtils.cpp", ], visibility: [ ":__subpackages__", diff --git a/sensors/aidl/default/multihal/ConvertUtils.cpp b/sensors/aidl/default/multihal/ConvertUtils.cpp new file mode 100644 index 0000000000..4d6697be3e --- /dev/null +++ b/sensors/aidl/default/multihal/ConvertUtils.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2021 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 "ConvertUtils.h" +#include +#include + +using AidlSensorInfo = ::aidl::android::hardware::sensors::SensorInfo; +using AidlSensorType = ::aidl::android::hardware::sensors::SensorType; +using AidlEvent = ::aidl::android::hardware::sensors::Event; +using AidlSensorStatus = ::aidl::android::hardware::sensors::SensorStatus; +using ::aidl::android::hardware::sensors::AdditionalInfo; +using ::aidl::android::hardware::sensors::DynamicSensorInfo; +using ::android::hardware::sensors::V1_0::MetaDataEventType; +using V1_0SensorStatus = ::android::hardware::sensors::V1_0::SensorStatus; +using ::android::hardware::sensors::V1_0::AdditionalInfoType; +using V2_1SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo; +using V2_1Event = ::android::hardware::sensors::V2_1::Event; +using V2_1SensorType = ::android::hardware::sensors::V2_1::SensorType; + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +AidlSensorInfo convertSensorInfo(const V2_1SensorInfo& sensorInfo) { + AidlSensorInfo aidlSensorInfo; + aidlSensorInfo.sensorHandle = sensorInfo.sensorHandle; + aidlSensorInfo.name = sensorInfo.name; + aidlSensorInfo.vendor = sensorInfo.vendor; + aidlSensorInfo.version = sensorInfo.version; + aidlSensorInfo.type = (AidlSensorType)sensorInfo.type; + aidlSensorInfo.typeAsString = sensorInfo.typeAsString; + aidlSensorInfo.maxRange = sensorInfo.maxRange; + aidlSensorInfo.resolution = sensorInfo.resolution; + aidlSensorInfo.power = sensorInfo.power; + aidlSensorInfo.minDelayUs = sensorInfo.minDelay; + aidlSensorInfo.fifoReservedEventCount = sensorInfo.fifoReservedEventCount; + aidlSensorInfo.fifoMaxEventCount = sensorInfo.fifoMaxEventCount; + aidlSensorInfo.requiredPermission = sensorInfo.requiredPermission; + aidlSensorInfo.maxDelayUs = sensorInfo.maxDelay; + aidlSensorInfo.flags = sensorInfo.flags; + return aidlSensorInfo; +} + +void convertToHidlEvent(const AidlEvent& aidlEvent, V2_1Event* hidlEvent) { + hidlEvent->timestamp = aidlEvent.timestamp; + hidlEvent->sensorHandle = aidlEvent.sensorHandle; + hidlEvent->sensorType = (V2_1SensorType)aidlEvent.sensorType; + + switch (aidlEvent.sensorType) { + case AidlSensorType::META_DATA: + hidlEvent->u.meta.what = + (MetaDataEventType)aidlEvent.payload.get().what; + break; + case AidlSensorType::ACCELEROMETER: + case AidlSensorType::MAGNETIC_FIELD: + case AidlSensorType::ORIENTATION: + case AidlSensorType::GYROSCOPE: + case AidlSensorType::GRAVITY: + case AidlSensorType::LINEAR_ACCELERATION: + hidlEvent->u.vec3.x = aidlEvent.payload.get().x; + hidlEvent->u.vec3.y = aidlEvent.payload.get().y; + hidlEvent->u.vec3.z = aidlEvent.payload.get().z; + break; + case AidlSensorType::GAME_ROTATION_VECTOR: + hidlEvent->u.vec4.x = aidlEvent.payload.get().x; + hidlEvent->u.vec4.y = aidlEvent.payload.get().y; + hidlEvent->u.vec4.z = aidlEvent.payload.get().z; + hidlEvent->u.vec4.w = aidlEvent.payload.get().w; + break; + case AidlSensorType::ROTATION_VECTOR: + case AidlSensorType::GEOMAGNETIC_ROTATION_VECTOR: + std::copy(aidlEvent.payload.get().values.data(), + aidlEvent.payload.get().values.data() + 5, + hidlEvent->u.data.data()); + break; + case AidlSensorType::ACCELEROMETER_UNCALIBRATED: + case AidlSensorType::MAGNETIC_FIELD_UNCALIBRATED: + case AidlSensorType::GYROSCOPE_UNCALIBRATED: + hidlEvent->u.uncal.x = aidlEvent.payload.get().x; + hidlEvent->u.uncal.y = aidlEvent.payload.get().y; + hidlEvent->u.uncal.z = aidlEvent.payload.get().z; + hidlEvent->u.uncal.x_bias = aidlEvent.payload.get().xBias; + hidlEvent->u.uncal.y_bias = aidlEvent.payload.get().yBias; + hidlEvent->u.uncal.z_bias = aidlEvent.payload.get().zBias; + break; + case AidlSensorType::DEVICE_ORIENTATION: + case AidlSensorType::LIGHT: + case AidlSensorType::PRESSURE: + case AidlSensorType::PROXIMITY: + case AidlSensorType::RELATIVE_HUMIDITY: + case AidlSensorType::AMBIENT_TEMPERATURE: + case AidlSensorType::SIGNIFICANT_MOTION: + case AidlSensorType::STEP_DETECTOR: + case AidlSensorType::TILT_DETECTOR: + case AidlSensorType::WAKE_GESTURE: + case AidlSensorType::GLANCE_GESTURE: + case AidlSensorType::PICK_UP_GESTURE: + case AidlSensorType::WRIST_TILT_GESTURE: + case AidlSensorType::STATIONARY_DETECT: + case AidlSensorType::MOTION_DETECT: + case AidlSensorType::HEART_BEAT: + case AidlSensorType::LOW_LATENCY_OFFBODY_DETECT: + case AidlSensorType::HINGE_ANGLE: + hidlEvent->u.scalar = aidlEvent.payload.get(); + break; + case AidlSensorType::STEP_COUNTER: + hidlEvent->u.stepCount = aidlEvent.payload.get(); + break; + case AidlSensorType::HEART_RATE: + hidlEvent->u.heartRate.bpm = + aidlEvent.payload.get().bpm; + hidlEvent->u.heartRate.status = + (V1_0SensorStatus)aidlEvent.payload.get() + .status; + break; + case AidlSensorType::POSE_6DOF: + std::copy(std::begin(aidlEvent.payload.get().values), + std::end(aidlEvent.payload.get().values), + hidlEvent->u.pose6DOF.data()); + break; + case AidlSensorType::DYNAMIC_SENSOR_META: + hidlEvent->u.dynamic.connected = + aidlEvent.payload.get().connected; + hidlEvent->u.dynamic.sensorHandle = + aidlEvent.payload.get().sensorHandle; + std::copy( + std::begin( + aidlEvent.payload.get().uuid.values), + std::end(aidlEvent.payload.get().uuid.values), + hidlEvent->u.dynamic.uuid.data()); + break; + case AidlSensorType::ADDITIONAL_INFO: { + const AdditionalInfo& additionalInfo = + aidlEvent.payload.get(); + hidlEvent->u.additional.type = (AdditionalInfoType)additionalInfo.type; + hidlEvent->u.additional.serial = additionalInfo.serial; + + switch (additionalInfo.payload.getTag()) { + case AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32: { + const auto& aidlData = + additionalInfo.payload + .get() + .values; + std::copy(std::begin(aidlData), std::end(aidlData), + hidlEvent->u.additional.u.data_int32.data()); + break; + } + case AdditionalInfo::AdditionalInfoPayload::Tag::dataFloat: { + const auto& aidlData = + additionalInfo.payload + .get() + .values; + std::copy(std::begin(aidlData), std::end(aidlData), + hidlEvent->u.additional.u.data_float.data()); + break; + } + default: + ALOGE("Invalid sensor additioanl info tag: %d", + additionalInfo.payload.getTag()); + break; + } + break; + } + default: + CHECK_GE((int32_t)aidlEvent.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE); + std::copy(std::begin(aidlEvent.payload.get().values), + std::end(aidlEvent.payload.get().values), + hidlEvent->u.data.data()); + break; + } +} + +void convertToAidlEvent(const V2_1Event& hidlEvent, AidlEvent* aidlEvent) { + aidlEvent->timestamp = hidlEvent.timestamp; + aidlEvent->sensorHandle = hidlEvent.sensorHandle; + aidlEvent->sensorType = (AidlSensorType)hidlEvent.sensorType; + switch (hidlEvent.sensorType) { + case V2_1SensorType::META_DATA: { + AidlEvent::EventPayload::MetaData meta; + meta.what = (Event::EventPayload::MetaData::MetaDataEventType)hidlEvent.u.meta.what; + aidlEvent->payload.set(meta); + break; + } + case V2_1SensorType::ACCELEROMETER: + case V2_1SensorType::MAGNETIC_FIELD: + case V2_1SensorType::ORIENTATION: + case V2_1SensorType::GYROSCOPE: + case V2_1SensorType::GRAVITY: + case V2_1SensorType::LINEAR_ACCELERATION: { + AidlEvent::EventPayload::Vec3 vec3; + vec3.x = hidlEvent.u.vec3.x; + vec3.y = hidlEvent.u.vec3.y; + vec3.z = hidlEvent.u.vec3.z; + aidlEvent->payload.set(vec3); + break; + } + case V2_1SensorType::GAME_ROTATION_VECTOR: { + AidlEvent::EventPayload::Vec4 vec4; + vec4.x = hidlEvent.u.vec4.x; + vec4.y = hidlEvent.u.vec4.y; + vec4.z = hidlEvent.u.vec4.z; + vec4.w = hidlEvent.u.vec4.w; + aidlEvent->payload.set(vec4); + break; + } + case V2_1SensorType::ROTATION_VECTOR: + case V2_1SensorType::GEOMAGNETIC_ROTATION_VECTOR: { + AidlEvent::EventPayload::Data data; + std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + 5, + std::begin(data.values)); + aidlEvent->payload.set(data); + break; + } + case V2_1SensorType::MAGNETIC_FIELD_UNCALIBRATED: + case V2_1SensorType::GYROSCOPE_UNCALIBRATED: + case V2_1SensorType::ACCELEROMETER_UNCALIBRATED: { + AidlEvent::EventPayload::Uncal uncal; + uncal.x = hidlEvent.u.uncal.x; + uncal.y = hidlEvent.u.uncal.y; + uncal.z = hidlEvent.u.uncal.z; + uncal.xBias = hidlEvent.u.uncal.x_bias; + uncal.yBias = hidlEvent.u.uncal.y_bias; + uncal.zBias = hidlEvent.u.uncal.z_bias; + aidlEvent->payload.set(uncal); + break; + } + case V2_1SensorType::DEVICE_ORIENTATION: + case V2_1SensorType::LIGHT: + case V2_1SensorType::PRESSURE: + case V2_1SensorType::PROXIMITY: + case V2_1SensorType::RELATIVE_HUMIDITY: + case V2_1SensorType::AMBIENT_TEMPERATURE: + case V2_1SensorType::SIGNIFICANT_MOTION: + case V2_1SensorType::STEP_DETECTOR: + case V2_1SensorType::TILT_DETECTOR: + case V2_1SensorType::WAKE_GESTURE: + case V2_1SensorType::GLANCE_GESTURE: + case V2_1SensorType::PICK_UP_GESTURE: + case V2_1SensorType::WRIST_TILT_GESTURE: + case V2_1SensorType::STATIONARY_DETECT: + case V2_1SensorType::MOTION_DETECT: + case V2_1SensorType::HEART_BEAT: + case V2_1SensorType::LOW_LATENCY_OFFBODY_DETECT: + case V2_1SensorType::HINGE_ANGLE: + aidlEvent->payload.set(hidlEvent.u.scalar); + break; + case V2_1SensorType::STEP_COUNTER: + aidlEvent->payload.set(hidlEvent.u.stepCount); + break; + case V2_1SensorType::HEART_RATE: { + AidlEvent::EventPayload::HeartRate heartRate; + heartRate.bpm = hidlEvent.u.heartRate.bpm; + heartRate.status = (SensorStatus)hidlEvent.u.heartRate.status; + aidlEvent->payload.set(heartRate); + break; + } + case V2_1SensorType::POSE_6DOF: { + AidlEvent::EventPayload::Pose6Dof pose6Dof; + std::copy(hidlEvent.u.pose6DOF.data(), + hidlEvent.u.pose6DOF.data() + hidlEvent.u.pose6DOF.size(), + std::begin(pose6Dof.values)); + aidlEvent->payload.set(pose6Dof); + break; + } + case V2_1SensorType::DYNAMIC_SENSOR_META: { + DynamicSensorInfo dynamicSensorInfo; + dynamicSensorInfo.connected = hidlEvent.u.dynamic.connected; + dynamicSensorInfo.sensorHandle = hidlEvent.u.dynamic.sensorHandle; + std::copy(hidlEvent.u.dynamic.uuid.data(), + hidlEvent.u.dynamic.uuid.data() + hidlEvent.u.dynamic.uuid.size(), + std::begin(dynamicSensorInfo.uuid.values)); + aidlEvent->payload.set(dynamicSensorInfo); + break; + } + case V2_1SensorType::ADDITIONAL_INFO: { + AdditionalInfo additionalInfo; + additionalInfo.type = (AdditionalInfo::AdditionalInfoType)hidlEvent.u.additional.type; + additionalInfo.serial = hidlEvent.u.additional.serial; + + AdditionalInfo::AdditionalInfoPayload::Int32Values int32Values; + std::copy(hidlEvent.u.additional.u.data_int32.data(), + hidlEvent.u.additional.u.data_int32.data() + + hidlEvent.u.additional.u.data_int32.size(), + std::begin(int32Values.values)); + additionalInfo.payload.set( + int32Values); + aidlEvent->payload.set(additionalInfo); + break; + } + default: { + CHECK_GE((int32_t)hidlEvent.sensorType, (int32_t)V2_1SensorType::DEVICE_PRIVATE_BASE); + AidlEvent::EventPayload::Data data; + std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + hidlEvent.u.data.size(), + std::begin(data.values)); + aidlEvent->payload.set(data); + break; + } + } +} + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/ConvertUtils.h b/sensors/aidl/default/multihal/include/ConvertUtils.h index 09ec0dc144..91dfabde3a 100644 --- a/sensors/aidl/default/multihal/include/ConvertUtils.h +++ b/sensors/aidl/default/multihal/include/ConvertUtils.h @@ -16,7 +16,8 @@ #pragma once -#include +#include +#include namespace aidl { namespace android { @@ -24,396 +25,23 @@ namespace hardware { namespace sensors { namespace implementation { -static ::aidl::android::hardware::sensors::SensorInfo convertSensorInfo( - const ::android::hardware::sensors::V2_1::SensorInfo& sensorInfo) { - ::aidl::android::hardware::sensors::SensorInfo aidlSensorInfo; - aidlSensorInfo.sensorHandle = sensorInfo.sensorHandle; - aidlSensorInfo.name = sensorInfo.name; - aidlSensorInfo.vendor = sensorInfo.vendor; - aidlSensorInfo.version = sensorInfo.version; - aidlSensorInfo.type = (::aidl::android::hardware::sensors::SensorType)sensorInfo.type; - aidlSensorInfo.typeAsString = sensorInfo.typeAsString; - aidlSensorInfo.maxRange = sensorInfo.maxRange; - aidlSensorInfo.resolution = sensorInfo.resolution; - aidlSensorInfo.power = sensorInfo.power; - aidlSensorInfo.minDelayUs = sensorInfo.minDelay; - aidlSensorInfo.fifoReservedEventCount = sensorInfo.fifoReservedEventCount; - aidlSensorInfo.fifoMaxEventCount = sensorInfo.fifoMaxEventCount; - aidlSensorInfo.requiredPermission = sensorInfo.requiredPermission; - aidlSensorInfo.maxDelayUs = sensorInfo.maxDelay; - aidlSensorInfo.flags = sensorInfo.flags; - return aidlSensorInfo; -} - -static void convertToHidlEvent(const ::aidl::android::hardware::sensors::Event& aidlEvent, - ::android::hardware::sensors::V2_1::Event* hidlEvent) { - hidlEvent->timestamp = aidlEvent.timestamp; - hidlEvent->sensorHandle = aidlEvent.sensorHandle; - hidlEvent->sensorType = (::android::hardware::sensors::V2_1::SensorType)aidlEvent.sensorType; - - switch (aidlEvent.sensorType) { - case ::aidl::android::hardware::sensors::SensorType::META_DATA: - hidlEvent->u.meta.what = - (::android::hardware::sensors::V1_0::MetaDataEventType)aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::meta>() - .what; - break; - case ::aidl::android::hardware::sensors::SensorType::ACCELEROMETER: - case ::aidl::android::hardware::sensors::SensorType::MAGNETIC_FIELD: - case ::aidl::android::hardware::sensors::SensorType::ORIENTATION: - case ::aidl::android::hardware::sensors::SensorType::GYROSCOPE: - case ::aidl::android::hardware::sensors::SensorType::GRAVITY: - case ::aidl::android::hardware::sensors::SensorType::LINEAR_ACCELERATION: - hidlEvent->u.vec3.x = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::vec3>() - .x; - hidlEvent->u.vec3.y = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::vec3>() - .y; - hidlEvent->u.vec3.z = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::vec3>() - .z; - break; - case ::aidl::android::hardware::sensors::SensorType::GAME_ROTATION_VECTOR: - hidlEvent->u.vec4.x = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::vec4>() - .x; - hidlEvent->u.vec4.y = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::vec4>() - .y; - hidlEvent->u.vec4.z = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::vec4>() - .z; - hidlEvent->u.vec4.w = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::vec4>() - .w; - break; - case ::aidl::android::hardware::sensors::SensorType::ROTATION_VECTOR: - case ::aidl::android::hardware::sensors::SensorType::GEOMAGNETIC_ROTATION_VECTOR: - std::copy(aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::data>() - .values.data(), - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload:: - data>() - .values.data() + - 5, - hidlEvent->u.data.data()); - break; - case ::aidl::android::hardware::sensors::SensorType::ACCELEROMETER_UNCALIBRATED: - case ::aidl::android::hardware::sensors::SensorType::MAGNETIC_FIELD_UNCALIBRATED: - case ::aidl::android::hardware::sensors::SensorType::GYROSCOPE_UNCALIBRATED: - hidlEvent->u.uncal.x = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() - .x; - hidlEvent->u.uncal.y = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() - .y; - hidlEvent->u.uncal.z = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() - .z; - hidlEvent->u.uncal.x_bias = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() - .xBias; - hidlEvent->u.uncal.y_bias = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() - .yBias; - hidlEvent->u.uncal.z_bias = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::uncal>() - .zBias; - break; - case ::aidl::android::hardware::sensors::SensorType::DEVICE_ORIENTATION: - case ::aidl::android::hardware::sensors::SensorType::LIGHT: - case ::aidl::android::hardware::sensors::SensorType::PRESSURE: - case ::aidl::android::hardware::sensors::SensorType::PROXIMITY: - case ::aidl::android::hardware::sensors::SensorType::RELATIVE_HUMIDITY: - case ::aidl::android::hardware::sensors::SensorType::AMBIENT_TEMPERATURE: - case ::aidl::android::hardware::sensors::SensorType::SIGNIFICANT_MOTION: - case ::aidl::android::hardware::sensors::SensorType::STEP_DETECTOR: - case ::aidl::android::hardware::sensors::SensorType::TILT_DETECTOR: - case ::aidl::android::hardware::sensors::SensorType::WAKE_GESTURE: - case ::aidl::android::hardware::sensors::SensorType::GLANCE_GESTURE: - case ::aidl::android::hardware::sensors::SensorType::PICK_UP_GESTURE: - case ::aidl::android::hardware::sensors::SensorType::WRIST_TILT_GESTURE: - case ::aidl::android::hardware::sensors::SensorType::STATIONARY_DETECT: - case ::aidl::android::hardware::sensors::SensorType::MOTION_DETECT: - case ::aidl::android::hardware::sensors::SensorType::HEART_BEAT: - case ::aidl::android::hardware::sensors::SensorType::LOW_LATENCY_OFFBODY_DETECT: - case ::aidl::android::hardware::sensors::SensorType::HINGE_ANGLE: - hidlEvent->u.scalar = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::scalar>(); - break; - case ::aidl::android::hardware::sensors::SensorType::STEP_COUNTER: - hidlEvent->u.stepCount = aidlEvent.payload.get< - ::aidl::android::hardware::sensors::Event::EventPayload::stepCount>(); - break; - case ::aidl::android::hardware::sensors::SensorType::HEART_RATE: - hidlEvent->u.heartRate.bpm = aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event:: - EventPayload::heartRate>() - .bpm; - hidlEvent->u.heartRate.status = - (::android::hardware::sensors::V1_0::SensorStatus)aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload:: - heartRate>() - .status; - break; - case ::aidl::android::hardware::sensors::SensorType::POSE_6DOF: - std::copy(std::begin(aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event:: - EventPayload::pose6DOF>() - .values), - std::end(aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event:: - EventPayload::data>() - .values), - hidlEvent->u.pose6DOF.data()); - break; - case ::aidl::android::hardware::sensors::SensorType::DYNAMIC_SENSOR_META: - hidlEvent->u.dynamic.connected = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::dynamic>() - .connected; - hidlEvent->u.dynamic.sensorHandle = - aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event::EventPayload::dynamic>() - .sensorHandle; - std::copy(std::begin(aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event:: - EventPayload::dynamic>() - .uuid.values), - std::end(aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event:: - EventPayload::dynamic>() - .uuid.values), - hidlEvent->u.dynamic.uuid.data()); - break; - case ::aidl::android::hardware::sensors::SensorType::ADDITIONAL_INFO: { - const AdditionalInfo& additionalInfo = aidlEvent.payload.get< - ::aidl::android::hardware::sensors::Event::EventPayload::additional>(); - hidlEvent->u.additional.type = - (::android::hardware::sensors::V1_0::AdditionalInfoType)additionalInfo.type; - hidlEvent->u.additional.serial = additionalInfo.serial; - - switch (additionalInfo.payload.getTag()) { - case ::aidl::android::hardware::sensors::AdditionalInfo::AdditionalInfoPayload:: - Tag::dataInt32: - std::copy( - std::begin(additionalInfo.payload - .get<::aidl::android::hardware::sensors:: - AdditionalInfo::AdditionalInfoPayload:: - dataInt32>() - .values), - std::end(additionalInfo.payload - .get<::aidl::android::hardware::sensors:: - AdditionalInfo::AdditionalInfoPayload:: - dataInt32>() - .values), - hidlEvent->u.additional.u.data_int32.data()); - break; - case ::aidl::android::hardware::sensors::AdditionalInfo::AdditionalInfoPayload:: - Tag::dataFloat: - std::copy( - std::begin(additionalInfo.payload - .get<::aidl::android::hardware::sensors:: - AdditionalInfo::AdditionalInfoPayload:: - dataFloat>() - .values), - std::end(additionalInfo.payload - .get<::aidl::android::hardware::sensors:: - AdditionalInfo::AdditionalInfoPayload:: - dataFloat>() - .values), - hidlEvent->u.additional.u.data_float.data()); - break; - default: - ALOGE("Invalid sensor additioanl info tag: %d", - additionalInfo.payload.getTag()); - break; - } - break; - } - default: - CHECK_GE((int32_t)aidlEvent.sensorType, - (int32_t)::aidl::android::hardware::sensors::SensorType::DEVICE_PRIVATE_BASE); - std::copy(std::begin(aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event:: - EventPayload::data>() - .values), - std::end(aidlEvent.payload - .get<::aidl::android::hardware::sensors::Event:: - EventPayload::data>() - .values), - hidlEvent->u.data.data()); - break; - } -} +/** + * Generates an AIDL SensorInfo instance from the passed HIDL V2.1 SensorInfo instance. + */ +::aidl::android::hardware::sensors::SensorInfo convertSensorInfo( + const ::android::hardware::sensors::V2_1::SensorInfo& sensorInfo); -static void convertToAidlEvent(const ::android::hardware::sensors::V2_1::Event& hidlEvent, - ::aidl::android::hardware::sensors::Event* aidlEvent) { - aidlEvent->timestamp = hidlEvent.timestamp; - aidlEvent->sensorHandle = hidlEvent.sensorHandle; - aidlEvent->sensorType = (::aidl::android::hardware::sensors::SensorType)hidlEvent.sensorType; - switch (hidlEvent.sensorType) { - case ::android::hardware::sensors::V2_1::SensorType::META_DATA: { - ::aidl::android::hardware::sensors::Event::EventPayload::MetaData meta; - meta.what = (::aidl::android::hardware::sensors::Event::EventPayload::MetaData:: - MetaDataEventType)hidlEvent.u.meta.what; - aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::meta>( - meta); - break; - } - case ::android::hardware::sensors::V2_1::SensorType::ACCELEROMETER: - case ::android::hardware::sensors::V2_1::SensorType::MAGNETIC_FIELD: - case ::android::hardware::sensors::V2_1::SensorType::ORIENTATION: - case ::android::hardware::sensors::V2_1::SensorType::GYROSCOPE: - case ::android::hardware::sensors::V2_1::SensorType::GRAVITY: - case ::android::hardware::sensors::V2_1::SensorType::LINEAR_ACCELERATION: { - ::aidl::android::hardware::sensors::Event::EventPayload::Vec3 vec3; - vec3.x = hidlEvent.u.vec3.x; - vec3.y = hidlEvent.u.vec3.y; - vec3.z = hidlEvent.u.vec3.z; - aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::vec3>( - vec3); - break; - } - case ::android::hardware::sensors::V2_1::SensorType::GAME_ROTATION_VECTOR: { - ::aidl::android::hardware::sensors::Event::EventPayload::Vec4 vec4; - vec4.x = hidlEvent.u.vec4.x; - vec4.y = hidlEvent.u.vec4.y; - vec4.z = hidlEvent.u.vec4.z; - vec4.w = hidlEvent.u.vec4.w; - aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::vec4>( - vec4); - break; - } - case ::android::hardware::sensors::V2_1::SensorType::ROTATION_VECTOR: - case ::android::hardware::sensors::V2_1::SensorType::GEOMAGNETIC_ROTATION_VECTOR: { - ::aidl::android::hardware::sensors::Event::EventPayload::Data data; - std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + 5, - std::begin(data.values)); - aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::data>( - data); - break; - } - case ::android::hardware::sensors::V2_1::SensorType::MAGNETIC_FIELD_UNCALIBRATED: - case ::android::hardware::sensors::V2_1::SensorType::GYROSCOPE_UNCALIBRATED: - case ::android::hardware::sensors::V2_1::SensorType::ACCELEROMETER_UNCALIBRATED: { - ::aidl::android::hardware::sensors::Event::EventPayload::Uncal uncal; - uncal.x = hidlEvent.u.uncal.x; - uncal.y = hidlEvent.u.uncal.y; - uncal.z = hidlEvent.u.uncal.z; - uncal.xBias = hidlEvent.u.uncal.x_bias; - uncal.yBias = hidlEvent.u.uncal.y_bias; - uncal.zBias = hidlEvent.u.uncal.z_bias; - aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::uncal>( - uncal); - break; - } - case ::android::hardware::sensors::V2_1::SensorType::DEVICE_ORIENTATION: - case ::android::hardware::sensors::V2_1::SensorType::LIGHT: - case ::android::hardware::sensors::V2_1::SensorType::PRESSURE: - case ::android::hardware::sensors::V2_1::SensorType::PROXIMITY: - case ::android::hardware::sensors::V2_1::SensorType::RELATIVE_HUMIDITY: - case ::android::hardware::sensors::V2_1::SensorType::AMBIENT_TEMPERATURE: - case ::android::hardware::sensors::V2_1::SensorType::SIGNIFICANT_MOTION: - case ::android::hardware::sensors::V2_1::SensorType::STEP_DETECTOR: - case ::android::hardware::sensors::V2_1::SensorType::TILT_DETECTOR: - case ::android::hardware::sensors::V2_1::SensorType::WAKE_GESTURE: - case ::android::hardware::sensors::V2_1::SensorType::GLANCE_GESTURE: - case ::android::hardware::sensors::V2_1::SensorType::PICK_UP_GESTURE: - case ::android::hardware::sensors::V2_1::SensorType::WRIST_TILT_GESTURE: - case ::android::hardware::sensors::V2_1::SensorType::STATIONARY_DETECT: - case ::android::hardware::sensors::V2_1::SensorType::MOTION_DETECT: - case ::android::hardware::sensors::V2_1::SensorType::HEART_BEAT: - case ::android::hardware::sensors::V2_1::SensorType::LOW_LATENCY_OFFBODY_DETECT: - case ::android::hardware::sensors::V2_1::SensorType::HINGE_ANGLE: - aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::scalar>( - hidlEvent.u.scalar); - break; - case ::android::hardware::sensors::V2_1::SensorType::STEP_COUNTER: - aidlEvent->payload - .set<::aidl::android::hardware::sensors::Event::EventPayload::stepCount>( - hidlEvent.u.stepCount); - break; - case ::android::hardware::sensors::V2_1::SensorType::HEART_RATE: { - ::aidl::android::hardware::sensors::Event::EventPayload::HeartRate heartRate; - heartRate.bpm = hidlEvent.u.heartRate.bpm; - heartRate.status = - (::aidl::android::hardware::sensors::SensorStatus)hidlEvent.u.heartRate.status; - aidlEvent->payload - .set<::aidl::android::hardware::sensors::Event::EventPayload::heartRate>( - heartRate); - break; - } - case ::android::hardware::sensors::V2_1::SensorType::POSE_6DOF: { - ::aidl::android::hardware::sensors::Event::EventPayload::Pose6Dof pose6Dof; - std::copy(hidlEvent.u.pose6DOF.data(), - hidlEvent.u.pose6DOF.data() + hidlEvent.u.pose6DOF.size(), - std::begin(pose6Dof.values)); - aidlEvent->payload - .set<::aidl::android::hardware::sensors::Event::EventPayload::pose6DOF>( - pose6Dof); - break; - } - case ::android::hardware::sensors::V2_1::SensorType::DYNAMIC_SENSOR_META: { - ::aidl::android::hardware::sensors::DynamicSensorInfo dynamicSensorInfo; - dynamicSensorInfo.connected = hidlEvent.u.dynamic.connected; - dynamicSensorInfo.sensorHandle = hidlEvent.u.dynamic.sensorHandle; - std::copy(hidlEvent.u.dynamic.uuid.data(), - hidlEvent.u.dynamic.uuid.data() + hidlEvent.u.dynamic.uuid.size(), - std::begin(dynamicSensorInfo.uuid.values)); - aidlEvent->payload - .set<::aidl::android::hardware::sensors::Event::EventPayload::dynamic>( - dynamicSensorInfo); - break; - } - case ::android::hardware::sensors::V2_1::SensorType::ADDITIONAL_INFO: { - ::aidl::android::hardware::sensors::AdditionalInfo additionalInfo; - additionalInfo.type = - (::aidl::android::hardware::sensors::AdditionalInfo::AdditionalInfoType) - hidlEvent.u.additional.type; - additionalInfo.serial = hidlEvent.u.additional.serial; +/** + * Populates a HIDL V2.1 Event instance based on an AIDL Event instance. + */ +void convertToHidlEvent(const ::aidl::android::hardware::sensors::Event& aidlEvent, + ::android::hardware::sensors::V2_1::Event* hidlEvent); - ::aidl::android::hardware::sensors::AdditionalInfo::AdditionalInfoPayload::Int32Values - int32Values; - std::copy(hidlEvent.u.additional.u.data_int32.data(), - hidlEvent.u.additional.u.data_int32.data() + - hidlEvent.u.additional.u.data_int32.size(), - std::begin(int32Values.values)); - additionalInfo.payload.set<::aidl::android::hardware::sensors::AdditionalInfo:: - AdditionalInfoPayload::dataInt32>(int32Values); - aidlEvent->payload - .set<::aidl::android::hardware::sensors::Event::EventPayload::additional>( - additionalInfo); - break; - } - default: { - CHECK_GE((int32_t)hidlEvent.sensorType, - (int32_t)::android::hardware::sensors::V2_1::SensorType::DEVICE_PRIVATE_BASE); - ::aidl::android::hardware::sensors::Event::EventPayload::Data data; - std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + hidlEvent.u.data.size(), - std::begin(data.values)); - aidlEvent->payload.set<::aidl::android::hardware::sensors::Event::EventPayload::data>( - data); - break; - } - } -} +/** + * Populates an AIDL Event instance based on a HIDL V2.1 Event instance. + */ +void convertToAidlEvent(const ::android::hardware::sensors::V2_1::Event& hidlEvent, + ::aidl::android::hardware::sensors::Event* aidlEvent); } // namespace implementation } // namespace sensors -- cgit v1.2.3 From 760c1081f509b2577317881806049764cb04900c Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Fri, 14 Jan 2022 13:45:05 -0800 Subject: Allow atrace hal tracefs access Add atrace hal to the readtracefs group Bug: 214591300 Test: adb shell perfetto (Use config with atrace_categories) Change-Id: Id9e06f88539b59480d5cf57a4ba67cef4676c1d5 --- atrace/1.0/default/android.hardware.atrace@1.0-service.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc index 7110b45c9f..31459b4916 100644 --- a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc +++ b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc @@ -14,4 +14,4 @@ service vendor.atrace-hal-1-0 /vendor/bin/hw/android.hardware.atrace@1.0-service interface android.hardware.atrace@1.0::IAtraceDevice default class early_hal user system - group system + group system readtracefs -- cgit v1.2.3 From 54cfc5a102845d560e151e9f091a90faebaaff97 Mon Sep 17 00:00:00 2001 From: Yu Shan Date: Tue, 26 Oct 2021 15:22:28 -0700 Subject: Add PendingRequestPool to handle pending requests. PendingRequestPool would store all pending requests that we have not yet got responses from hardware. If a request has been pending for too long, the timout callback would be called and the request would be removed. Test: atest DefaultVehicleHalTest Bug: 203713317 Change-Id: I4d7ae2c72b960347be70ac4cc8ce3d66eb8128f9 --- .../hardware/test/FakeVehicleHardwareTest.cpp | 6 +- automotive/vehicle/aidl/impl/vhal/Android.bp | 1 + .../aidl/impl/vhal/include/DefaultVehicleHal.h | 5 + .../aidl/impl/vhal/include/PendingRequestPool.h | 100 ++++++++ .../aidl/impl/vhal/src/PendingRequestPool.cpp | 220 +++++++++++++++++ .../aidl/impl/vhal/test/PendingRequestPoolTest.cpp | 274 +++++++++++++++++++++ 6 files changed, 603 insertions(+), 3 deletions(-) create mode 100644 automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h create mode 100644 automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.cpp create mode 100644 automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp index f8df6e62d1..970d044d43 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp @@ -154,7 +154,7 @@ class FakeVehicleHardwareTest : public ::testing::Test { return toInt(result.error()); } - void onSetValues(const std::vector results) { + void onSetValues(std::vector results) { for (auto& result : results) { mSetValueResults.push_back(result); } @@ -162,7 +162,7 @@ class FakeVehicleHardwareTest : public ::testing::Test { const std::vector& getSetValueResults() { return mSetValueResults; } - void onGetValues(const std::vector results) { + void onGetValues(std::vector results) { for (auto& result : results) { mGetValueResults.push_back(result); } @@ -170,7 +170,7 @@ class FakeVehicleHardwareTest : public ::testing::Test { const std::vector& getGetValueResults() { return mGetValueResults; } - void onPropertyChangeEvent(const std::vector& values) { + void onPropertyChangeEvent(std::vector values) { for (auto& value : values) { mChangedProperties.push_back(value); } diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp index 454fea5050..a54ab4bbe9 100644 --- a/automotive/vehicle/aidl/impl/vhal/Android.bp +++ b/automotive/vehicle/aidl/impl/vhal/Android.bp @@ -56,6 +56,7 @@ cc_library { srcs: [ "src/ConnectedClient.cpp", "src/DefaultVehicleHal.cpp", + "src/PendingRequestPool.cpp", ], static_libs: [ "VehicleHalUtils", diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h index 4ee3ee93d8..f6f7d80002 100644 --- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h +++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h @@ -88,12 +88,17 @@ class DefaultVehicleHal final : public ::aidl::android::hardware::automotive::ve GetSetValuesClient<::aidl::android::hardware::automotive::vehicle::SetValueResult, ::aidl::android::hardware::automotive::vehicle::SetValueResults>; + // The default timeout of get or set value requests is 30s. + // TODO(b/214605968): define TIMEOUT_IN_NANO in IVehicle and allow getValues/setValues/subscribe + // to specify custom timeouts. + static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000; const std::unique_ptr mVehicleHardware; // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to // lock guard them. std::unordered_map mConfigsByPropId; + // Only modified in constructor, so thread-safe. std::unique_ptr<::ndk::ScopedFileDescriptor> mConfigFile; std::mutex mLock; diff --git a/automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h b/automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h new file mode 100644 index 0000000000..6dcfaff5fa --- /dev/null +++ b/automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2021 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_automotive_vehicle_aidl_impl_vhal_include_PendingRequestPool_H_ +#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_PendingRequestPool_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { + +// A thread-safe pending request pool that tracks whether each request has timed-out. +class PendingRequestPool final { + public: + using TimeoutCallbackFunc = std::function&)>; + + explicit PendingRequestPool(int64_t timeoutInSec); + + ~PendingRequestPool(); + + // Adds a list of requests to the request pool. + // The clientId is the key for all the requests. It could be a number or an address to a data + // structure that represents a client. The caller must maintain this data structure. + // All the request IDs must be unique for one client, if any of the requestIds is duplicate with + // any pending request IDs for the client, this function returns error and no requests would be + // added. Otherwise, they would be added to the request pool. + // The callback would be called if requests are not finished within {@code mTimeoutInNano} + // seconds. + android::base::Result addRequests(const void* clientId, + const std::unordered_set& requestIds, + std::shared_ptr callback); + + // Checks whether the request is currently pending. + bool isRequestPending(const void* clientId, int64_t requestId) const; + + // Tries to mark the requests as finished and remove them from the pool if the request is + // currently pending. Returns the list of request that is pending and has been finished + // successfully. This function would try to finish any valid requestIds even though some of the + // requestIds are not valid. + std::unordered_set tryFinishRequests(const void* clientId, + const std::unordered_set& requestIds); + + // Returns how many pending requests in the pool, for testing purpose. + size_t countPendingRequests(const void* clientId) const; + + private: + // The maximum number of pending requests allowed per client. If exceeds this number, adding + // more requests would fail. This is to prevent spamming from client. + static constexpr size_t MAX_PENDING_REQUEST_PER_CLIENT = 10000; + + struct PendingRequest { + std::unordered_set requestIds; + int64_t timeoutTimestamp; + std::shared_ptr callback; + }; + + int64_t mTimeoutInNano; + mutable std::mutex mLock; + std::unordered_map> mPendingRequestsByClient + GUARDED_BY(mLock); + std::thread mThread; + std::atomic mThreadStop = false; + std::condition_variable mCv; + std::mutex mCvLock; + + bool isRequestPendingLocked(const void* clientId, int64_t requestId) const REQUIRES(mLock); + + // Checks whether the requests in the pool has timed-out, run periodically in a separate thread. + void checkTimeout(); +}; + +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android + +#endif // android_hardware_automotive_vehicle_aidl_impl_vhal_include_PendingRequestPool_H_ diff --git a/automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.cpp b/automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.cpp new file mode 100644 index 0000000000..c2d6f89c2d --- /dev/null +++ b/automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2021 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 "PendingRequestPool.h" + +#include +#include + +#include +#include + +#include + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { + +namespace { + +using ::aidl::android::hardware::automotive::vehicle::StatusCode; +using ::android::base::Error; +using ::android::base::Result; + +// At least check every 1s. +constexpr int64_t CHECK_TIME_IN_NANO = 1000000000; + +} // namespace + +PendingRequestPool::PendingRequestPool(int64_t timeoutInNano) + : mTimeoutInNano(timeoutInNano), mThread([this] { + // [this] must be alive within this thread because destructor would wait for this thread + // to exit. + int64_t sleepTime = std::min(mTimeoutInNano, static_cast(CHECK_TIME_IN_NANO)); + std::unique_lock lk(mCvLock); + while (!mCv.wait_for(lk, std::chrono::nanoseconds(sleepTime), + [this] { return mThreadStop.load(); })) { + checkTimeout(); + } + }) {} + +PendingRequestPool::~PendingRequestPool() { + mThreadStop = true; + mCv.notify_all(); + if (mThread.joinable()) { + mThread.join(); + } + + // If this pool is being destructed, send out all pending requests as timeout. + { + std::scoped_lock lockGuard(mLock); + + for (auto& [_, pendingRequests] : mPendingRequestsByClient) { + for (const auto& request : pendingRequests) { + (*request.callback)(request.requestIds); + } + } + mPendingRequestsByClient.clear(); + } +} + +Result PendingRequestPool::addRequests(const void* clientId, + const std::unordered_set& requestIds, + std::shared_ptr callback) { + std::scoped_lock lockGuard(mLock); + std::list* pendingRequests; + size_t pendingRequestCount = 0; + if (mPendingRequestsByClient.find(clientId) != mPendingRequestsByClient.end()) { + pendingRequests = &mPendingRequestsByClient[clientId]; + for (const auto& pendingRequest : *pendingRequests) { + const auto& pendingRequestIds = pendingRequest.requestIds; + for (int64_t requestId : requestIds) { + if (pendingRequestIds.find(requestId) != pendingRequestIds.end()) { + return Error(toInt(StatusCode::INVALID_ARG)) + << "duplicate request ID: " << requestId; + } + } + pendingRequestCount += pendingRequestIds.size(); + } + } else { + // Create a new empty list for this client. + pendingRequests = &mPendingRequestsByClient[clientId]; + } + + if (requestIds.size() > MAX_PENDING_REQUEST_PER_CLIENT - pendingRequestCount) { + return Error(toInt(StatusCode::TRY_AGAIN)) << "too many pending requests"; + } + + int64_t currentTime = elapsedRealtimeNano(); + int64_t timeoutTimestamp = currentTime + mTimeoutInNano; + + pendingRequests->push_back({ + .requestIds = std::unordered_set(requestIds.begin(), requestIds.end()), + .timeoutTimestamp = timeoutTimestamp, + .callback = callback, + }); + + return {}; +} + +bool PendingRequestPool::isRequestPending(const void* clientId, int64_t requestId) const { + std::scoped_lock lockGuard(mLock); + + return isRequestPendingLocked(clientId, requestId); +} + +size_t PendingRequestPool::countPendingRequests(const void* clientId) const { + std::scoped_lock lockGuard(mLock); + + auto it = mPendingRequestsByClient.find(clientId); + if (it == mPendingRequestsByClient.end()) { + return 0; + } + + size_t count = 0; + for (const auto& pendingRequest : it->second) { + count += pendingRequest.requestIds.size(); + } + + return count; +} + +bool PendingRequestPool::isRequestPendingLocked(const void* clientId, int64_t requestId) const { + auto it = mPendingRequestsByClient.find(clientId); + if (it == mPendingRequestsByClient.end()) { + return false; + } + for (const auto& pendingRequest : it->second) { + const auto& requestIds = pendingRequest.requestIds; + if (requestIds.find(requestId) != requestIds.end()) { + return true; + } + } + return false; +} + +void PendingRequestPool::checkTimeout() { + std::vector timeoutRequests; + { + std::scoped_lock lockGuard(mLock); + + int64_t currentTime = elapsedRealtimeNano(); + + std::vector clientsWithEmptyRequests; + + for (auto& [clientId, pendingRequests] : mPendingRequestsByClient) { + auto it = pendingRequests.begin(); + while (it != pendingRequests.end()) { + if (it->timeoutTimestamp >= currentTime) { + break; + } + timeoutRequests.push_back(std::move(*it)); + it = pendingRequests.erase(it); + } + + if (pendingRequests.empty()) { + clientsWithEmptyRequests.push_back(clientId); + } + } + + for (const void* clientId : clientsWithEmptyRequests) { + mPendingRequestsByClient.erase(clientId); + } + } + + // Call the callback outside the lock. + for (const auto& request : timeoutRequests) { + (*request.callback)(request.requestIds); + } +} + +std::unordered_set PendingRequestPool::tryFinishRequests( + const void* clientId, const std::unordered_set& requestIds) { + std::scoped_lock lockGuard(mLock); + + std::unordered_set foundIds; + + if (mPendingRequestsByClient.find(clientId) == mPendingRequestsByClient.end()) { + return foundIds; + } + + auto& pendingRequests = mPendingRequestsByClient[clientId]; + auto it = pendingRequests.begin(); + while (it != pendingRequests.end()) { + auto& pendingRequestIds = it->requestIds; + for (int64_t requestId : requestIds) { + auto idIt = pendingRequestIds.find(requestId); + if (idIt == pendingRequestIds.end()) { + continue; + } + pendingRequestIds.erase(idIt); + foundIds.insert(requestId); + } + if (pendingRequestIds.empty()) { + it = pendingRequests.erase(it); + continue; + } + it++; + } + + return foundIds; +} + +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp new file mode 100644 index 0000000000..03d795beaa --- /dev/null +++ b/automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2021 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 "PendingRequestPool.h" + +#include +#include + +#include +#include + +#include +#include + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { + +using ::aidl::android::hardware::automotive::vehicle::StatusCode; + +using ::testing::ElementsAre; +using ::testing::UnorderedElementsAre; +using ::testing::WhenSorted; + +class PendingRequestPoolTest : public ::testing::Test { + public: + void SetUp() override { mPool = std::make_unique(TEST_TIMEOUT); } + + void TearDown() override { + if (mPool != nullptr) { + ASSERT_EQ(mPool->countPendingRequests(getTestClientId()), static_cast(0)) + << "at least one pending request still exists in the pool when finish"; + } + } + + PendingRequestPool* getPool() { return mPool.get(); } + + void destroyPool() { mPool.reset(); } + + int64_t getTimeout() { return TEST_TIMEOUT; } + + void* getTestClientId() { return reinterpret_cast(0); } + + private: + // Test timeout is 0.1s. + static const int64_t TEST_TIMEOUT = 100000000; + + std::unique_ptr mPool; +}; + +TEST_F(PendingRequestPoolTest, testFinishAllRequests) { + std::mutex lock; + std::vector timeoutRequestIds; + + std::unordered_set requestIds; + for (int64_t i = 0; i < 10; i++) { + requestIds.insert(i); + } + + auto callback = std::make_shared( + [&lock, &timeoutRequestIds](const std::unordered_set& requests) { + std::scoped_lock lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), requestIds, callback)); + + for (int64_t i = 0; i < 10; i++) { + ASSERT_TRUE(getPool()->isRequestPending(getTestClientId(), i)); + } + + for (int64_t i = 0; i < 10; i++) { + ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {i}), UnorderedElementsAre(i)); + } + + for (int64_t i = 0; i < 10; i++) { + ASSERT_FALSE(getPool()->isRequestPending(getTestClientId(), i)); + } +} + +TEST_F(PendingRequestPoolTest, testFinishHalfOfRequest) { + int64_t timeout = getTimeout(); + std::mutex lock; + std::vector timeoutRequestIds; + + std::unordered_set requestIds; + for (int64_t i = 0; i < 10; i++) { + requestIds.insert(i); + } + + auto callback = std::make_shared( + [&lock, &timeoutRequestIds](const std::unordered_set& requests) { + std::scoped_lock lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), requestIds, callback)); + + for (int64_t i = 0; i < 10; i++) { + ASSERT_TRUE(getPool()->isRequestPending(getTestClientId(), i)); + } + + // Finish half of the requests. + requestIds.clear(); + for (int64_t i = 0; i < 5; i++) { + requestIds.insert(i); + } + + ASSERT_EQ(getPool()->tryFinishRequests(getTestClientId(), requestIds), requestIds); + + for (int64_t i = 0; i < 5; i++) { + ASSERT_FALSE(getPool()->isRequestPending(getTestClientId(), i)); + } + for (int64_t i = 5; i < 10; i++) { + ASSERT_TRUE(getPool()->isRequestPending(getTestClientId(), i)); + } + + // Wait until the unfinished requests timeout. The check interval is timeout, so at max we + // would wait an additional interval, which is 2 * timeout until the callback is called. + std::this_thread::sleep_for(2 * std::chrono::nanoseconds(timeout)); + + ASSERT_THAT(timeoutRequestIds, WhenSorted(ElementsAre(5, 6, 7, 8, 9))); +} + +TEST_F(PendingRequestPoolTest, testFinishRequestTwice) { + std::mutex lock; + std::vector timeoutRequestIds; + + auto callback = std::make_shared( + [&lock, &timeoutRequestIds](const std::unordered_set& requests) { + std::scoped_lock lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback)); + + ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {0}), UnorderedElementsAre(0)) + << "failed to finish an added request"; + ASSERT_TRUE(getPool()->tryFinishRequests(getTestClientId(), {0}).empty()) + << "finish a request second time must return empty result"; +} + +TEST_F(PendingRequestPoolTest, testFinishRequestNonExistingId) { + std::mutex lock; + std::vector timeoutRequestIds; + + auto callback = std::make_shared( + [&lock, &timeoutRequestIds](const std::unordered_set& requests) { + std::scoped_lock lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0, 1, 2}, callback)); + + ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {0, 1, 2, 3}), + UnorderedElementsAre(0, 1, 2)) + << "finished request IDs must not contain non-existing request ID"; + // Even though one of the request to finish does not exist, the rest of the requests should be + // finished. + ASSERT_EQ(getPool()->countPendingRequests(getTestClientId()), static_cast(0)) + << "requests not being finished correctly"; +} + +TEST_F(PendingRequestPoolTest, testFinishAfterTimeout) { + std::mutex lock; + std::vector timeoutRequestIds; + + auto callback = std::make_shared( + [&lock, &timeoutRequestIds](const std::unordered_set& requests) { + std::scoped_lock lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback)); + + std::this_thread::sleep_for(2 * std::chrono::nanoseconds(getTimeout())); + + ASSERT_TRUE(getPool()->tryFinishRequests(getTestClientId(), {0}).empty()) + << "finish a request after timeout must do nothing"; +} + +TEST_F(PendingRequestPoolTest, testDestroyWithPendingRequests) { + std::mutex lock; + std::vector timeoutRequestIds; + + auto callback = std::make_shared( + [&lock, &timeoutRequestIds](const std::unordered_set& requests) { + std::scoped_lock lockGuard(lock); + for (int64_t request : requests) { + timeoutRequestIds.push_back(request); + } + }); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback)); + + destroyPool(); + + // Before the pool is destroyed, the pending requests should be notified as timeout. + ASSERT_THAT(timeoutRequestIds, UnorderedElementsAre(0)) + << "timeout not triggered when the pool is destroyed"; +} + +TEST_F(PendingRequestPoolTest, testDuplicateRequestId) { + auto callback = std::make_shared( + [](std::unordered_set) {}); + + ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback)); + ASSERT_FALSE(getPool()->addRequests(getTestClientId(), {1, 2, 0}, callback).ok()) + << "adding duplicate request IDs must fail"; + + ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {0}), UnorderedElementsAre(0)); +} + +TEST_F(PendingRequestPoolTest, testSameRequestIdForDifferentClient) { + auto callback = std::make_shared( + [](std::unordered_set) {}); + + ASSERT_RESULT_OK(getPool()->addRequests(reinterpret_cast(0), {0}, callback)); + ASSERT_RESULT_OK(getPool()->addRequests(reinterpret_cast(1), {1, 2, 0}, callback)); + + ASSERT_THAT(getPool()->tryFinishRequests(reinterpret_cast(0), {0}), + UnorderedElementsAre(0)); + ASSERT_THAT(getPool()->tryFinishRequests(reinterpret_cast(1), {1, 2, 0}), + UnorderedElementsAre(0, 1, 2)); +} + +TEST_F(PendingRequestPoolTest, testPendingRequestCountLimit) { + auto callback = std::make_shared( + [](std::unordered_set) {}); + + std::unordered_set requests; + + // MAX_PENDING_REQUEST_PER_CLIENT = 10000 + for (size_t i = 0; i < 10000; i++) { + requests.insert(static_cast(i)); + } + ASSERT_RESULT_OK(getPool()->addRequests(reinterpret_cast(0), requests, callback)); + + auto result = getPool()->addRequests(reinterpret_cast(0), {static_cast(10000)}, + callback); + ASSERT_FALSE(result.ok()) << "adding more pending requests than limit must fail"; + ASSERT_EQ(result.error().code(), toInt(StatusCode::TRY_AGAIN)); + + getPool()->tryFinishRequests(reinterpret_cast(0), requests); +} + +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android -- cgit v1.2.3 From 0d9b1a9d287d3751c305742af81850b7ceea0c6b Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Tue, 5 Oct 2021 10:17:01 -0700 Subject: Define AIDL reusable execution interface. This CL defines the AIDL interface for reusable execution. This CL also fixes a stale statement in IBurst about deadlineNs: boot_clock should be used rather than steady_clock. Bug: 202405342 Bug: 202431255 Test: NNT_static Test: VtsHalNeuralnetworksTargetTest Change-Id: I07d26909081018ffd92264d76109a66d4a0de3bd --- .../compatibility_matrix.current.xml | 2 +- .../hardware/neuralnetworks/IExecution.aidl | 39 ++++++ .../hardware/neuralnetworks/IPreparedModel.aidl | 1 + .../android/hardware/neuralnetworks/IBurst.aidl | 8 +- .../hardware/neuralnetworks/IExecution.aidl | 153 +++++++++++++++++++++ .../hardware/neuralnetworks/IPreparedModel.aidl | 44 +++++- 6 files changed, 237 insertions(+), 10 deletions(-) create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl create mode 100644 neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index cf856889df..d0c55f2a24 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -455,7 +455,7 @@ android.hardware.neuralnetworks - 1-3 + 1-4 IDevice .* diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl new file mode 100644 index 0000000000..ab5275e582 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IExecution { + android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in long deadlineNs); + android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in ParcelFileDescriptor[] waitFor, in long deadlineNs, in long durationNs); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl index fccb5dc98e..f89956719e 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -37,6 +37,7 @@ interface IPreparedModel { android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs); android.hardware.neuralnetworks.IBurst configureExecutionBurst(); + android.hardware.neuralnetworks.IExecution createReusableExecution(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long loopTimeoutDurationNs); const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000; const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000; } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl index decdc481f1..b089c499c6 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl @@ -78,10 +78,10 @@ interface IBurst { * runs from the time the driver sees the call to the executeSynchronously * function to the time the driver returns from the function. * @param deadlineNs The time by which the execution is expected to complete. The time is - * measured in nanoseconds since epoch of the steady clock (as from - * std::chrono::steady_clock). If the execution cannot be finished by the - * deadline, the execution may be aborted. Passing -1 means the deadline is - * omitted. Other negative values are invalid. + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the execution cannot be finished + * by the deadline, the execution may be aborted. Passing -1 means the + * deadline is omitted. Other negative values are invalid. * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent * executing a {@link OperationType::WHILE} operation. If a loop * condition model does not output false within this duration, the diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl new file mode 100644 index 0000000000..3cb9c1a592 --- /dev/null +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2021 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.neuralnetworks; + +import android.hardware.neuralnetworks.ExecutionResult; +import android.hardware.neuralnetworks.FencedExecutionResult; + +/** + * IExecution represents a reusable execution object with request and most other execution + * properties fixed. It is used to launch executions. + * + * At most one execution may occur on a reusable execution object at any given time, either by + * means of executeSynchronously or executeFenced. + * + * An IExecution object is used to control a set of executions on the same prepared model with + * the same request and properties. IExecution objects enable some optimizations: + * (1) An IExecution object can preserve resources between executions. For example, a driver can + * map a memory object when the IExecution object is created and cache the mapping for reuse in + * subsequent executions. Any cached resource can be released when the IExecution object is + * destroyed. + * (2) Because an IExecution object may be used for at most one execution at a time, any transient + * execution resources such as intermediate tensors can be allocated once when the IExecution + * object is created and freed when the IExecution object is destroyed. + * (3) An IExecution object is created for a fixed request. This enables the implementation to apply + * request-specific optimizations. For example, an implementation can avoid request validation + * and conversions when the IExecution object is reused. An implementation may also choose to + * specialize the dynamic tensor shapes in the IExecution object according to the request. + */ +@VintfStability +interface IExecution { + /** + * Performs a synchronous execution on the reusable execution object. + * + * The execution is performed synchronously with respect to the caller. executeSynchronously + * must verify the inputs to the function are correct, and the usages of memory pools allocated + * by IDevice::allocate are valid. If there is an error, executeSynchronously must immediately + * return a service specific exception with the appropriate ErrorStatus value. If the inputs to + * the function are valid and there is no error, executeSynchronously must perform the + * execution, and must not return until the execution is complete. + * + * The caller must not change the content of any data object referenced by the 'request' + * provided in {@link IPreparedModel::createReusableExecution} (described by the + * {@link DataLocation} of a {@link RequestArgument}) until executeSynchronously returns. + * executeSynchronously must not change the content of any of the data objects corresponding to + * 'request' inputs. + * + * If the execution object was configured from a prepared model wherein all tensor operands have + * fully specified dimensions, and the inputs to the function are valid, and at execution time + * every operation's input operands have legal values, then the execution should complete + * successfully: there must be no failure unless the device itself is in a bad state. + * + * If the execution object was created with measureTiming being true and the execution is + * successful, the driver may report the timing information in the returning + * {@link ExecutionResult}. The duration runs from the time the driver sees the call to the time + * the driver returns from the function. + * + * executeSynchronously may be called with an optional deadline. If the execution is not able to + * be completed before the provided deadline, the execution may be aborted, and either + * {@link ErrorStatus::MISSED_DEADLINE_TRANSIENT} or {@link + * ErrorStatus::MISSED_DEADLINE_PERSISTENT} may be returned. The error due to an abort must be + * sent the same way as other errors, described above. + * + * @param deadlineNs The time by which the execution is expected to complete. The time is + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the execution cannot be finished + * by the deadline, the execution may be aborted. Passing -1 means the + * deadline is omitted. Other negative values are invalid. + * @return ExecutionResult parcelable, containing the status of the execution, output shapes + * and timing information. + * @throws ServiceSpecificException with one of the following ErrorStatus values: + * - DEVICE_UNAVAILABLE if driver is offline or busy + * - GENERAL_FAILURE if there is an unspecified error + * - INVALID_ARGUMENT if one of the input arguments is invalid + * - MISSED_DEADLINE_* if the execution is aborted because it cannot be completed by the + * deadline + * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver + */ + ExecutionResult executeSynchronously(in long deadlineNs); + + /** + * Launch a fenced asynchronous execution on the reusable execution object. + * + * The execution is performed asynchronously with respect to the caller. executeFenced must + * verify the inputs to the function are correct, and the usages of memory pools allocated by + * IDevice::allocate are valid. If there is an error, executeFenced must immediately return a + * service specific exception with the corresponding ErrorStatus. If the inputs to the function + * are valid and there is no error, executeFenced must dispatch an asynchronous task to perform + * the execution in the background, and immediately return a {@link FencedExecutionResult} + * containing two fields: a callback (which can be used by the client to query the duration and + * runtime error status) and a sync fence (which will be signaled once the execution is + * completed). If the task has finished before the call returns, syncFence file descriptor may + * be set to -1. The execution must wait for all the sync fences (if any) in waitFor to be + * signaled before starting the actual execution. + * + * When the asynchronous task has finished its execution, it must immediately signal the + * syncFence returned from the executeFenced call. After the syncFence is signaled, the task + * must not modify the content of any data object referenced by the 'request' provided in + * IPreparedModel::createReusableExecution (described by the {@link DataLocation} of a + * {@link RequestArgument}). + * + * executeFenced may be called with an optional deadline and an optional duration. If the + * execution is not able to be completed before the provided deadline or within the timeout + * duration (measured from when all sync fences in waitFor are signaled), whichever comes + * earlier, the execution may be aborted, and either + * {@link ErrorStatus::MISSED_DEADLINE_TRANSIENT} or {@link + * ErrorStatus::MISSED_DEADLINE_PERSISTENT} may be returned. The error due to an abort must be + * sent the same way as other errors, described above. + * + * If any of the sync fences in waitFor changes to error status after the executeFenced call + * succeeds, or the execution is aborted because it cannot finish before the deadline has been + * reached or the duration has elapsed, the driver must immediately set the returned syncFence + * to error status. + * + * @param waitFor A vector of sync fence file descriptors. Execution must not start until all + * sync fences have been signaled. + * @param deadlineNs The time by which the execution is expected to complete. The time is + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the execution cannot be finished + * by the deadline, the execution may be aborted. Passing -1 means the + * deadline is omitted. Other negative values are invalid. + * @param durationNs The length of time in nanoseconds within which the execution is expected + * to complete after all sync fences in waitFor are signaled. If the + * execution cannot be finished within the duration, the execution may be + * aborted. Passing -1 means the duration is omitted. Other negative values + * are invalid. + * @return The FencedExecutionResult parcelable, containing IFencedExecutionCallback and the + * sync fence. + * @throws ServiceSpecificException with one of the following ErrorStatus values: + * - DEVICE_UNAVAILABLE if driver is offline or busy + * - GENERAL_FAILURE if there is an unspecified error + * - INVALID_ARGUMENT if one of the input arguments is invalid, including fences in error + * states. + * - MISSED_DEADLINE_* if the execution is aborted because it cannot be completed by the + * deadline + * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver + */ + FencedExecutionResult executeFenced( + in ParcelFileDescriptor[] waitFor, in long deadlineNs, in long durationNs); +} diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl index 956b626dd9..79053e527f 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -21,6 +21,7 @@ import android.hardware.neuralnetworks.ErrorStatus; import android.hardware.neuralnetworks.ExecutionResult; import android.hardware.neuralnetworks.FencedExecutionResult; import android.hardware.neuralnetworks.IBurst; +import android.hardware.neuralnetworks.IExecution; import android.hardware.neuralnetworks.Request; /** @@ -105,11 +106,12 @@ interface IPreparedModel { * IDevice::allocate are valid. If there is an error, executeFenced must immediately return a * service specific exception with the corresponding ErrorStatus. If the inputs to the function * are valid and there is no error, executeFenced must dispatch an asynchronous task to perform - * the execution in the background, assign a sync fence that will be signaled once the execution - * is completed and immediately return a callback that can be used by the client to query the - * duration and runtime error status. If the task has finished before the call returns, - * syncFence file descriptor may be set to -1. The execution must wait for all the sync fences - * (if any) in waitFor to be signaled before starting the actual execution. + * the execution in the background, and immediately return a {@link FencedExecutionResult} + * containing two fields: a callback (which can be used by the client to query the duration and + * runtime error status) and a sync fence (which will be signaled once the execution is + * completed). If the task has finished before the call returns, syncFence file descriptor may + * be set to -1. The execution must wait for all the sync fences (if any) in waitFor to be + * signaled before starting the actual execution. * * When the asynchronous task has finished its execution, it must immediately signal the * syncFence returned from the executeFenced call. After the syncFence is signaled, the task @@ -186,4 +188,36 @@ interface IPreparedModel { * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver */ IBurst configureExecutionBurst(); + + /** + * Create a reusable execution object to launch multiple executions with the same request and + * properties. + * + * createReusableExecution must verify the inputs to the function are correct, and the usages of + * memory pools allocated by IDevice::allocate are valid. If there is an error, + * createReusableExecution must immediately return a service specific exception with the + * appropriate ErrorStatus value. If the inputs to the function are valid and there is no error, + * createReusableExecution must construct a reusable execution. + * + * @param request The input and output information on which the prepared model is to be + * executed. + * @param measure Specifies whether or not to measure duration of the execution. + * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent + * executing a {@link OperationType::WHILE} operation. If a loop + * condition model does not output false within this duration, the + * computation performed on the returned reusable execution object + * must be aborted. If -1 is provided, the maximum amount + * of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other + * negative values are invalid. When provided, the duration must + * not exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}. + * @return execution An IExecution object representing a reusable execution that has been + * specialized for a fixed request. + * @throws ServiceSpecificException with one of the following ErrorStatus values: + * - DEVICE_UNAVAILABLE if driver is offline or busy + * - GENERAL_FAILURE if there is an unspecified error + * - INVALID_ARGUMENT if one of the input arguments is invalid + * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver + */ + IExecution createReusableExecution( + in Request request, in boolean measureTiming, in long loopTimeoutDurationNs); } -- cgit v1.2.3 From 7f5c7d293c2dad462dc9c0f1f1a160fb2c2c9a9b Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Tue, 5 Oct 2021 14:10:41 -0700 Subject: Reusable execution at HAL level -- HAL. This CL modifies the canonical/AIDL adapter to use IExecution object if available. Bug: 202405342 Bug: 202431255 Test: NNT_static Test: CtsNNAPITestCases Test: VtsHalNeuralnetworksTargetTest Change-Id: I6aac3c57f97ac87a5ba3f78cfd843fcc403decff --- neuralnetworks/aidl/utils/Android.bp | 37 ++- .../aidl/utils/include/nnapi/hal/aidl/Callbacks.h | 3 + .../aidl/utils/include/nnapi/hal/aidl/Execution.h | 41 +++- .../utils/include/nnapi/hal/aidl/HalInterfaces.h | 5 + .../utils/include/nnapi/hal/aidl/PreparedModel.h | 6 +- .../aidl/utils/include/nnapi/hal/aidl/Utils.h | 2 + neuralnetworks/aidl/utils/src/Callbacks.cpp | 7 +- neuralnetworks/aidl/utils/src/Device.cpp | 4 +- neuralnetworks/aidl/utils/src/Execution.cpp | 45 ++-- neuralnetworks/aidl/utils/src/PreparedModel.cpp | 158 ++++++++----- neuralnetworks/aidl/utils/test/DeviceTest.cpp | 27 +-- neuralnetworks/aidl/utils/test/ExecutionTest.cpp | 254 +++++++++++++++++++++ neuralnetworks/aidl/utils/test/MockExecution.h | 47 ++++ neuralnetworks/aidl/utils/test/MockPreparedModel.h | 5 + .../aidl/utils/test/PreparedModelTest.cpp | 194 ++++++++++++---- neuralnetworks/aidl/utils/test/TestUtils.cpp | 44 ++++ neuralnetworks/aidl/utils/test/TestUtils.h | 43 ++++ .../aidl/vts/functional/MemoryDomainTests.cpp | 5 + .../aidl/include/nnapi/hal/aidl/Execution.h | 56 +++++ .../aidl/include/nnapi/hal/aidl/PreparedModel.h | 4 + .../utils/adapter/aidl/src/PreparedModel.cpp | 99 ++++++++ 21 files changed, 925 insertions(+), 161 deletions(-) create mode 100644 neuralnetworks/aidl/utils/test/ExecutionTest.cpp create mode 100644 neuralnetworks/aidl/utils/test/MockExecution.h create mode 100644 neuralnetworks/aidl/utils/test/TestUtils.cpp create mode 100644 neuralnetworks/aidl/utils/test/TestUtils.h create mode 100644 neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp index e3561042be..3faa613514 100644 --- a/neuralnetworks/aidl/utils/Android.bp +++ b/neuralnetworks/aidl/utils/Android.bp @@ -26,7 +26,14 @@ package { cc_defaults { name: "neuralnetworks_utils_hal_aidl_defaults", defaults: ["neuralnetworks_utils_defaults"], - srcs: ["src/*"], + srcs: [ + // AIDL utils that a driver may depend on. + "src/BufferTracker.cpp", + "src/Conversions.cpp", + "src/HalUtils.cpp", + "src/Utils.cpp", + "src/ValidateHal.cpp", + ], local_include_dirs: ["include/nnapi/hal/aidl/"], export_include_dirs: ["include"], cflags: ["-Wthread-safety"], @@ -47,6 +54,7 @@ cc_defaults { }, } +// Deprecated. Remove once all modules depending on this are migrated away. cc_library_static { name: "neuralnetworks_utils_hal_aidl_v1", defaults: ["neuralnetworks_utils_hal_aidl_defaults"], @@ -55,20 +63,26 @@ cc_library_static { ], } -cc_library_static { - name: "neuralnetworks_utils_hal_aidl_v2", - defaults: ["neuralnetworks_utils_hal_aidl_defaults"], - shared_libs: [ - "android.hardware.neuralnetworks-V2-ndk", - ], -} - cc_library_static { name: "neuralnetworks_utils_hal_aidl", defaults: ["neuralnetworks_utils_hal_aidl_defaults"], + srcs: [ + // Additional AIDL utils for the runtime. + "src/Assertions.cpp", + "src/Buffer.cpp", + "src/Burst.cpp", + "src/Callbacks.cpp", + "src/Device.cpp", + "src/Execution.cpp", + "src/InvalidDevice.cpp", + "src/PreparedModel.cpp", + "src/ProtectCallback.cpp", + "src/Service.cpp", + ], shared_libs: [ - "android.hardware.neuralnetworks-V3-ndk", + "android.hardware.neuralnetworks-V4-ndk", ], + cflags: ["-DNN_AIDL_V4_OR_ABOVE"], } // A cc_defaults that includes the latest non-experimental AIDL utilities and other AIDL libraries @@ -79,9 +93,10 @@ cc_defaults { static_libs: [ "android.hardware.common-V2-ndk", "android.hardware.graphics.common-V3-ndk", - "android.hardware.neuralnetworks-V3-ndk", + "android.hardware.neuralnetworks-V4-ndk", "neuralnetworks_utils_hal_aidl", ], + cflags: ["-DNN_AIDL_V4_OR_ABOVE"], } cc_test { diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h index 168264babf..960be2bb54 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h @@ -36,6 +36,8 @@ class PreparedModelCallback final : public BnPreparedModelCallback, public IProt public: using Data = nn::GeneralResult; + PreparedModelCallback(nn::Version featureLevel) : kFeatureLevel(featureLevel) {} + ndk::ScopedAStatus notify(ErrorStatus status, const std::shared_ptr& preparedModel) override; @@ -44,6 +46,7 @@ class PreparedModelCallback final : public BnPreparedModelCallback, public IProt Data get(); private: + const nn::Version kFeatureLevel; hal::utils::TransferValue mData; }; diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h index a77ea984b2..14802b98cc 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h @@ -17,6 +17,8 @@ #ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H +#include + #include #include #include @@ -33,17 +35,22 @@ namespace aidl::android::hardware::neuralnetworks::utils { -class Execution final : public nn::IExecution, public std::enable_shared_from_this { +// A reusable execution implementation with a cached Request, internally it is still passing the +// request to the driver in every computation. +class ExecutionWithCachedRequest final + : public nn::IExecution, + public std::enable_shared_from_this { struct PrivateConstructorTag {}; public: - static nn::GeneralResult> create( + static nn::GeneralResult> create( std::shared_ptr preparedModel, Request request, hal::utils::RequestRelocation relocation, bool measure, int64_t loopTimeoutDuration); - Execution(PrivateConstructorTag tag, std::shared_ptr preparedModel, - Request request, hal::utils::RequestRelocation relocation, bool measure, - int64_t loopTimeoutDuration); + ExecutionWithCachedRequest(PrivateConstructorTag tag, + std::shared_ptr preparedModel, Request request, + hal::utils::RequestRelocation relocation, bool measure, + int64_t loopTimeoutDuration); nn::ExecutionResult, nn::Timing>> compute( const nn::OptionalTimePoint& deadline) const override; @@ -60,6 +67,30 @@ class Execution final : public nn::IExecution, public std::enable_shared_from_th const int64_t kLoopTimeoutDuration; }; +// A reusable execution implementation that is backed by an actual AIDL IExecution object. +class Execution final : public nn::IExecution, public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + std::shared_ptr execution, + hal::utils::RequestRelocation relocation); + + Execution(PrivateConstructorTag tag, std::shared_ptr execution, + hal::utils::RequestRelocation relocation); + + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + const std::shared_ptr kExecution; + const hal::utils::RequestRelocation kRelocation; +}; + } // namespace aidl::android::hardware::neuralnetworks::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h index 3fb443c388..205d428cf4 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h @@ -61,6 +61,11 @@ #include #include +#ifdef NN_AIDL_V4_OR_ABOVE +#include +#include +#endif // NN_AIDL_V4_OR_ABOVE + namespace android::nn { namespace aidl_hal = ::aidl::android::hardware::neuralnetworks; diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h index 4035764ea4..24cd681658 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h @@ -41,10 +41,11 @@ class PreparedModel final : public nn::IPreparedModel, public: static nn::GeneralResult> create( - std::shared_ptr preparedModel); + std::shared_ptr preparedModel, nn::Version featureLevel); PreparedModel(PrivateConstructorTag tag, - std::shared_ptr preparedModel); + std::shared_ptr preparedModel, + nn::Version featureLevel); nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, @@ -78,6 +79,7 @@ class PreparedModel final : public nn::IPreparedModel, private: const std::shared_ptr kPreparedModel; + const nn::Version kFeatureLevel; }; } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h index a27487e17c..beca38b1ee 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h @@ -38,6 +38,8 @@ constexpr std::optional aidlVersionToCanonicalVersion(int aidlVersi return nn::kVersionFeatureLevel6; case 3: return nn::kVersionFeatureLevel7; + case 4: + return nn::kVersionFeatureLevel8; default: return std::nullopt; } diff --git a/neuralnetworks/aidl/utils/src/Callbacks.cpp b/neuralnetworks/aidl/utils/src/Callbacks.cpp index 8084970690..554f3faa73 100644 --- a/neuralnetworks/aidl/utils/src/Callbacks.cpp +++ b/neuralnetworks/aidl/utils/src/Callbacks.cpp @@ -38,16 +38,17 @@ namespace { // nn::kVersionFeatureLevel5. On failure, this function returns with the appropriate // nn::GeneralError. nn::GeneralResult prepareModelCallback( - ErrorStatus status, const std::shared_ptr& preparedModel) { + ErrorStatus status, const std::shared_ptr& preparedModel, + nn::Version featureLevel) { HANDLE_STATUS_AIDL(status) << "model preparation failed with " << toString(status); - return NN_TRY(PreparedModel::create(preparedModel)); + return NN_TRY(PreparedModel::create(preparedModel, featureLevel)); } } // namespace ndk::ScopedAStatus PreparedModelCallback::notify( ErrorStatus status, const std::shared_ptr& preparedModel) { - mData.put(prepareModelCallback(status, preparedModel)); + mData.put(prepareModelCallback(status, preparedModel, kFeatureLevel)); return ndk::ScopedAStatus::ok(); } diff --git a/neuralnetworks/aidl/utils/src/Device.cpp b/neuralnetworks/aidl/utils/src/Device.cpp index 5b7ec4ebd7..bad10ed347 100644 --- a/neuralnetworks/aidl/utils/src/Device.cpp +++ b/neuralnetworks/aidl/utils/src/Device.cpp @@ -229,7 +229,7 @@ nn::GeneralResult Device::prepareModel( const auto aidlDataCache = NN_TRY(convert(dataCache)); const auto aidlToken = NN_TRY(convert(token)); - const auto cb = ndk::SharedRefBase::make(); + const auto cb = ndk::SharedRefBase::make(kFeatureLevel); const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModel(aidlModel, aidlPreference, aidlPriority, aidlDeadline, @@ -247,7 +247,7 @@ nn::GeneralResult Device::prepareModelFromCache( const auto aidlDataCache = NN_TRY(convert(dataCache)); const auto aidlToken = NN_TRY(convert(token)); - const auto cb = ndk::SharedRefBase::make(); + const auto cb = ndk::SharedRefBase::make(kFeatureLevel); const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModelFromCache(aidlDeadline, aidlModelCache, aidlDataCache, diff --git a/neuralnetworks/aidl/utils/src/Execution.cpp b/neuralnetworks/aidl/utils/src/Execution.cpp index 94edd90c89..c4add636e5 100644 --- a/neuralnetworks/aidl/utils/src/Execution.cpp +++ b/neuralnetworks/aidl/utils/src/Execution.cpp @@ -35,36 +35,39 @@ namespace aidl::android::hardware::neuralnetworks::utils { -nn::GeneralResult> Execution::create( - std::shared_ptr preparedModel, Request request, - hal::utils::RequestRelocation relocation, bool measure, int64_t loopTimeoutDuration) { +nn::GeneralResult> +ExecutionWithCachedRequest::create(std::shared_ptr preparedModel, + Request request, hal::utils::RequestRelocation relocation, + bool measure, int64_t loopTimeoutDuration) { if (preparedModel == nullptr) { - return NN_ERROR() << "aidl::utils::Execution::create must have non-null preparedModel"; + return NN_ERROR() << "aidl::utils::ExecutionWithCachedRequest::create must have non-null " + "preparedModel"; } - return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), - std::move(request), std::move(relocation), measure, - loopTimeoutDuration); + return std::make_shared( + PrivateConstructorTag{}, std::move(preparedModel), std::move(request), + std::move(relocation), measure, loopTimeoutDuration); } -Execution::Execution(PrivateConstructorTag /*tag*/, - std::shared_ptr preparedModel, Request request, - hal::utils::RequestRelocation relocation, bool measure, - int64_t loopTimeoutDuration) +ExecutionWithCachedRequest::ExecutionWithCachedRequest( + PrivateConstructorTag /*tag*/, std::shared_ptr preparedModel, + Request request, hal::utils::RequestRelocation relocation, bool measure, + int64_t loopTimeoutDuration) : kPreparedModel(std::move(preparedModel)), kRequest(std::move(request)), kRelocation(std::move(relocation)), kMeasure(measure), kLoopTimeoutDuration(loopTimeoutDuration) {} -nn::ExecutionResult, nn::Timing>> Execution::compute( - const nn::OptionalTimePoint& deadline) const { +nn::ExecutionResult, nn::Timing>> +ExecutionWithCachedRequest::compute(const nn::OptionalTimePoint& deadline) const { const auto aidlDeadline = NN_TRY(convert(deadline)); return kPreparedModel->executeInternal(kRequest, kMeasure, aidlDeadline, kLoopTimeoutDuration, kRelocation); } -nn::GeneralResult> Execution::computeFenced( +nn::GeneralResult> +ExecutionWithCachedRequest::computeFenced( const std::vector& waitFor, const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& timeoutDurationAfterFence) const { const auto aidlWaitFor = NN_TRY(convert(waitFor)); @@ -75,4 +78,18 @@ nn::GeneralResult> Execu aidlTimeoutDurationAfterFence, kRelocation); } +nn::GeneralResult> Execution::create( + std::shared_ptr execution, hal::utils::RequestRelocation relocation) { + if (execution == nullptr) { + return NN_ERROR() << "aidl::utils::Execution::create must have non-null execution"; + } + + return std::make_shared(PrivateConstructorTag{}, std::move(execution), + std::move(relocation)); +} + +Execution::Execution(PrivateConstructorTag /*tag*/, std::shared_ptr execution, + hal::utils::RequestRelocation relocation) + : kExecution(std::move(execution)), kRelocation(std::move(relocation)) {} + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/src/PreparedModel.cpp b/neuralnetworks/aidl/utils/src/PreparedModel.cpp index f25c2c8825..6d1de569d0 100644 --- a/neuralnetworks/aidl/utils/src/PreparedModel.cpp +++ b/neuralnetworks/aidl/utils/src/PreparedModel.cpp @@ -54,21 +54,77 @@ nn::GeneralResult> convertFencedExecutionResul return std::make_pair(NN_TRY(nn::convert(timingLaunched)), NN_TRY(nn::convert(timingFenced))); } +nn::ExecutionResult, nn::Timing>> handleExecutionResult( + const ExecutionResult& result, const hal::utils::RequestRelocation& relocation) { + if (!result.outputSufficientSize) { + auto canonicalOutputShapes = + nn::convert(result.outputShapes).value_or(std::vector{}); + return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes)) + << "execution failed with " << nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; + } + auto [outputShapes, timing] = + NN_TRY(convertExecutionResults(result.outputShapes, result.timing)); + + if (relocation.output) { + relocation.output->flush(); + } + return std::make_pair(std::move(outputShapes), timing); +} + +nn::GeneralResult> +handleFencedExecutionResult(const FencedExecutionResult& result, + const hal::utils::RequestRelocation& relocation) { + auto resultSyncFence = nn::SyncFence::createAsSignaled(); + if (result.syncFence.get() != -1) { + resultSyncFence = nn::SyncFence::create(NN_TRY(nn::convert(result.syncFence))).value(); + } + + auto callback = result.callback; + if (callback == nullptr) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "callback is null"; + } + + // If computeFenced required the request memory to be moved into shared memory, block here until + // the fenced execution has completed and flush the memory back. + if (relocation.output) { + const auto state = resultSyncFence.syncWait({}); + if (state != nn::SyncFence::FenceState::SIGNALED) { + return NN_ERROR() << "syncWait failed with " << state; + } + relocation.output->flush(); + } + + // Create callback which can be used to retrieve the execution error status and timings. + nn::ExecuteFencedInfoCallback resultCallback = + [callback]() -> nn::GeneralResult> { + ErrorStatus errorStatus; + Timing timingLaunched; + Timing timingFenced; + const auto ret = callback->getExecutionInfo(&timingLaunched, &timingFenced, &errorStatus); + HANDLE_ASTATUS(ret) << "fenced execution callback getExecutionInfo failed"; + return convertFencedExecutionResults(errorStatus, timingLaunched, timingFenced); + }; + + return std::make_pair(std::move(resultSyncFence), std::move(resultCallback)); +} + } // namespace nn::GeneralResult> PreparedModel::create( - std::shared_ptr preparedModel) { + std::shared_ptr preparedModel, nn::Version featureLevel) { if (preparedModel == nullptr) { return NN_ERROR() << "aidl_hal::utils::PreparedModel::create must have non-null preparedModel"; } - return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel)); + return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), + featureLevel); } PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, - std::shared_ptr preparedModel) - : kPreparedModel(std::move(preparedModel)) {} + std::shared_ptr preparedModel, + nn::Version featureLevel) + : kPreparedModel(std::move(preparedModel)), kFeatureLevel(featureLevel) {} nn::ExecutionResult, nn::Timing>> PreparedModel::execute( const nn::Request& request, nn::MeasureTiming measure, @@ -101,19 +157,7 @@ PreparedModel::executeInternal(const Request& request, bool measure, int64_t dea const auto ret = kPreparedModel->executeSynchronously(request, measure, deadline, loopTimeoutDuration, &executionResult); HANDLE_ASTATUS(ret) << "executeSynchronously failed"; - if (!executionResult.outputSufficientSize) { - auto canonicalOutputShapes = - nn::convert(executionResult.outputShapes).value_or(std::vector{}); - return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes)) - << "execution failed with " << nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; - } - auto [outputShapes, timing] = - NN_TRY(convertExecutionResults(executionResult.outputShapes, executionResult.timing)); - - if (relocation.output) { - relocation.output->flush(); - } - return std::make_pair(std::move(outputShapes), timing); + return handleExecutionResult(executionResult, relocation); } nn::GeneralResult> @@ -154,39 +198,7 @@ PreparedModel::executeFencedInternal(const Request& request, kPreparedModel->executeFenced(request, waitFor, measure, deadline, loopTimeoutDuration, timeoutDurationAfterFence, &result); HANDLE_ASTATUS(ret) << "executeFenced failed"; - - auto resultSyncFence = nn::SyncFence::createAsSignaled(); - if (result.syncFence.get() != -1) { - resultSyncFence = nn::SyncFence::create(NN_TRY(nn::convert(result.syncFence))).value(); - } - - auto callback = result.callback; - if (callback == nullptr) { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "callback is null"; - } - - // If executeFenced required the request memory to be moved into shared memory, block here until - // the fenced execution has completed and flush the memory back. - if (relocation.output) { - const auto state = resultSyncFence.syncWait({}); - if (state != nn::SyncFence::FenceState::SIGNALED) { - return NN_ERROR() << "syncWait failed with " << state; - } - relocation.output->flush(); - } - - // Create callback which can be used to retrieve the execution error status and timings. - nn::ExecuteFencedInfoCallback resultCallback = - [callback]() -> nn::GeneralResult> { - ErrorStatus errorStatus; - Timing timingLaunched; - Timing timingFenced; - const auto ret = callback->getExecutionInfo(&timingLaunched, &timingFenced, &errorStatus); - HANDLE_ASTATUS(ret) << "fenced execution callback getExecutionInfo failed"; - return convertFencedExecutionResults(errorStatus, timingLaunched, timingFenced); - }; - - return std::make_pair(std::move(resultSyncFence), std::move(resultCallback)); + return handleFencedExecutionResult(result, relocation); } nn::GeneralResult PreparedModel::createReusableExecution( @@ -202,8 +214,18 @@ nn::GeneralResult PreparedModel::createReusableExecution( auto aidlRequest = NN_TRY(convert(requestInShared)); auto aidlMeasure = NN_TRY(convert(measure)); auto aidlLoopTimeoutDuration = NN_TRY(convert(loopTimeoutDuration)); - return Execution::create(shared_from_this(), std::move(aidlRequest), std::move(relocation), - aidlMeasure, aidlLoopTimeoutDuration); + + if (kFeatureLevel.level >= nn::Version::Level::FEATURE_LEVEL_8) { + std::shared_ptr execution; + const auto ret = kPreparedModel->createReusableExecution( + aidlRequest, aidlMeasure, aidlLoopTimeoutDuration, &execution); + HANDLE_ASTATUS(ret) << "createReusableExecution failed"; + return Execution::create(std::move(execution), std::move(relocation)); + } + + return ExecutionWithCachedRequest::create(shared_from_this(), std::move(aidlRequest), + std::move(relocation), aidlMeasure, + aidlLoopTimeoutDuration); } nn::GeneralResult PreparedModel::configureExecutionBurst() const { @@ -218,4 +240,36 @@ std::any PreparedModel::getUnderlyingResource() const { return resource; } +nn::ExecutionResult, nn::Timing>> Execution::compute( + const nn::OptionalTimePoint& deadline) const { + const auto aidlDeadline = NN_TRY(convert(deadline)); + + if (kRelocation.input) { + kRelocation.input->flush(); + } + + ExecutionResult executionResult; + auto ret = kExecution->executeSynchronously(aidlDeadline, &executionResult); + HANDLE_ASTATUS(ret) << "executeSynchronously failed"; + return handleExecutionResult(executionResult, kRelocation); +} + +nn::GeneralResult> Execution::computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const { + const auto aidlWaitFor = NN_TRY(convert(waitFor)); + const auto aidlDeadline = NN_TRY(convert(deadline)); + const auto aidlTimeoutDurationAfterFence = NN_TRY(convert(timeoutDurationAfterFence)); + + if (kRelocation.input) { + kRelocation.input->flush(); + } + + FencedExecutionResult result; + const auto ret = kExecution->executeFenced(aidlWaitFor, aidlDeadline, + aidlTimeoutDurationAfterFence, &result); + HANDLE_ASTATUS(ret) << "executeFenced failed"; + return handleFencedExecutionResult(result, kRelocation); +} + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp index 0366e7dff0..fb13af8d9f 100644 --- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp +++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp @@ -17,6 +17,7 @@ #include "MockBuffer.h" #include "MockDevice.h" #include "MockPreparedModel.h" +#include "TestUtils.h" #include #include @@ -146,26 +147,7 @@ constexpr auto makeDeadObjectFailure = [] { return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT); }; -class DeviceTest : public ::testing::TestWithParam { - protected: - const nn::Version kVersion = GetParam(); -}; - -std::string printDeviceTest(const testing::TestParamInfo& info) { - const nn::Version version = info.param; - CHECK(!version.runtimeOnlyFeatures); - switch (version.level) { - case nn::Version::Level::FEATURE_LEVEL_5: - return "v1"; - case nn::Version::Level::FEATURE_LEVEL_6: - return "v2"; - case nn::Version::Level::FEATURE_LEVEL_7: - return "v3"; - default: - LOG(FATAL) << "Invalid AIDL version: " << version; - return "invalid"; - } -} +class DeviceTest : public VersionedAidlUtilsTestBase {}; } // namespace @@ -894,9 +876,6 @@ TEST_P(DeviceTest, allocateDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } -INSTANTIATE_TEST_SUITE_P(TestDevice, DeviceTest, - ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6, - nn::kVersionFeatureLevel7), - printDeviceTest); +INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(DeviceTest, kAllAidlVersions); } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/ExecutionTest.cpp b/neuralnetworks/aidl/utils/test/ExecutionTest.cpp new file mode 100644 index 0000000000..8519290145 --- /dev/null +++ b/neuralnetworks/aidl/utils/test/ExecutionTest.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2021 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 "MockExecution.h" +#include "MockFencedExecutionCallback.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace aidl::android::hardware::neuralnetworks::utils { +namespace { + +using ::testing::_; +using ::testing::DoAll; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; +using ::testing::SetArgPointee; + +const std::shared_ptr kInvalidExecution; +constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1}; + +constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); }; + +constexpr auto makeGeneralFailure = [] { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast(ErrorStatus::GENERAL_FAILURE)); +}; +constexpr auto makeGeneralTransportFailure = [] { + return ndk::ScopedAStatus::fromStatus(STATUS_NO_MEMORY); +}; +constexpr auto makeDeadObjectFailure = [] { + return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT); +}; + +auto makeFencedExecutionResult(const std::shared_ptr& callback) { + return [callback](const std::vector& /*waitFor*/, + int64_t /*deadline*/, int64_t /*duration*/, + FencedExecutionResult* fencedExecutionResult) { + *fencedExecutionResult = FencedExecutionResult{.callback = callback, + .syncFence = ndk::ScopedFileDescriptor(-1)}; + return ndk::ScopedAStatus::ok(); + }; +} + +} // namespace + +TEST(ExecutionTest, invalidExecution) { + // run test + const auto result = Execution::create(kInvalidExecution, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeSync) { + // setup call + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + const auto mockExecutionResult = ExecutionResult{ + .outputSufficientSize = true, + .outputShapes = {}, + .timing = kNoTiming, + }; + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce( + DoAll(SetArgPointee<1>(mockExecutionResult), InvokeWithoutArgs(makeStatusOk))); + + // run test + const auto result = execution->compute({}); + + // verify result + EXPECT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ExecutionTest, executeSyncError) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce(Invoke(makeGeneralFailure)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeSyncTransportFailure) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeSyncDeadObject) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ExecutionTest, executeFenced) { + // setup call + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming), + SetArgPointee<2>(ErrorStatus::NONE), Invoke(makeStatusOk))); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeFencedExecutionResult(mockCallback))); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& [syncFence, callback] = result.value(); + EXPECT_EQ(syncFence.syncWait({}), nn::SyncFence::FenceState::SIGNALED); + ASSERT_NE(callback, nullptr); + + // get results from callback + const auto callbackResult = callback(); + ASSERT_TRUE(callbackResult.has_value()) << "Failed with " << callbackResult.error().code << ": " + << callbackResult.error().message; +} + +TEST(ExecutionTest, executeFencedCallbackError) { + // setup call + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) + .Times(1) + .WillOnce(Invoke(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming), + SetArgPointee<2>(ErrorStatus::GENERAL_FAILURE), + Invoke(makeStatusOk)))); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeFencedExecutionResult(mockCallback))); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& [syncFence, callback] = result.value(); + EXPECT_NE(syncFence.syncWait({}), nn::SyncFence::FenceState::ACTIVE); + ASSERT_NE(callback, nullptr); + + // verify callback failure + const auto callbackResult = callback(); + ASSERT_FALSE(callbackResult.has_value()); + EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeFencedError) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeFencedTransportFailure) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeFencedDeadObject) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +} // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/MockExecution.h b/neuralnetworks/aidl/utils/test/MockExecution.h new file mode 100644 index 0000000000..216f569abc --- /dev/null +++ b/neuralnetworks/aidl/utils/test/MockExecution.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H + +#include +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::utils { + +class MockExecution final : public BnExecution { + public: + static std::shared_ptr create(); + + MOCK_METHOD(ndk::ScopedAStatus, executeSynchronously, + (int64_t deadline, ExecutionResult* executionResult), (override)); + MOCK_METHOD(ndk::ScopedAStatus, executeFenced, + (const std::vector& waitFor, int64_t deadline, + int64_t duration, FencedExecutionResult* fencedExecutionResult), + (override)); +}; + +inline std::shared_ptr MockExecution::create() { + return ndk::SharedRefBase::make(); +} + +} // namespace aidl::android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H diff --git a/neuralnetworks/aidl/utils/test/MockPreparedModel.h b/neuralnetworks/aidl/utils/test/MockPreparedModel.h index a4ae2b778a..0ed9af9929 100644 --- a/neuralnetworks/aidl/utils/test/MockPreparedModel.h +++ b/neuralnetworks/aidl/utils/test/MockPreparedModel.h @@ -17,6 +17,7 @@ #ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_PREPARED_MODEL_H #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_PREPARED_MODEL_H +#include #include #include #include @@ -41,6 +42,10 @@ class MockPreparedModel final : public BnPreparedModel { (override)); MOCK_METHOD(ndk::ScopedAStatus, configureExecutionBurst, (std::shared_ptr * burst), (override)); + MOCK_METHOD(ndk::ScopedAStatus, createReusableExecution, + (const Request& request, bool measureTiming, int64_t loopTimeoutDuration, + std::shared_ptr* execution), + (override)); }; inline std::shared_ptr MockPreparedModel::create() { diff --git a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp index 8bb5c90d1e..8cfb7c123a 100644 --- a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp +++ b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp @@ -15,8 +15,10 @@ */ #include "MockBurst.h" +#include "MockExecution.h" #include "MockFencedExecutionCallback.h" #include "MockPreparedModel.h" +#include "TestUtils.h" #include #include @@ -66,21 +68,23 @@ auto makeFencedExecutionResult(const std::shared_ptr= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup call const uint32_t kNumberOfComputations = 2; const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockExecutionResult = ExecutionResult{ .outputSufficientSize = true, .outputShapes = {}, @@ -283,10 +289,12 @@ TEST(PreparedModelTest, reusableExecuteSync) { } } -TEST(PreparedModelTest, reusableExecuteSyncError) { +TEST_P(PreparedModelTest, reusableExecuteSyncError) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(Invoke(makeGeneralFailure)); @@ -303,10 +311,12 @@ TEST(PreparedModelTest, reusableExecuteSyncError) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) { +TEST_P(PreparedModelTest, reusableExecuteSyncTransportFailure) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); @@ -323,10 +333,12 @@ TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteSyncDeadObject) { +TEST_P(PreparedModelTest, reusableExecuteSyncDeadObject) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); @@ -343,11 +355,13 @@ TEST(PreparedModelTest, reusableExecuteSyncDeadObject) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, reusableExecuteFenced) { +TEST_P(PreparedModelTest, reusableExecuteFenced) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup call const uint32_t kNumberOfComputations = 2; const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockCallback = MockFencedExecutionCallback::create(); EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) .Times(kNumberOfComputations) @@ -379,10 +393,12 @@ TEST(PreparedModelTest, reusableExecuteFenced) { } } -TEST(PreparedModelTest, reusableExecuteFencedCallbackError) { +TEST_P(PreparedModelTest, reusableExecuteFencedCallbackError) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup call const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockCallback = MockFencedExecutionCallback::create(); EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) .Times(1) @@ -413,10 +429,12 @@ TEST(PreparedModelTest, reusableExecuteFencedCallbackError) { EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteFencedError) { +TEST_P(PreparedModelTest, reusableExecuteFencedError) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); @@ -433,10 +451,12 @@ TEST(PreparedModelTest, reusableExecuteFencedError) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) { +TEST_P(PreparedModelTest, reusableExecuteFencedTransportFailure) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); @@ -453,10 +473,12 @@ TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteFencedDeadObject) { +TEST_P(PreparedModelTest, reusableExecuteFencedDeadObject) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); @@ -473,14 +495,14 @@ TEST(PreparedModelTest, reusableExecuteFencedDeadObject) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, configureExecutionBurst) { +TEST_P(PreparedModelTest, configureExecutionBurst) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); const auto mockBurst = ndk::SharedRefBase::make(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(DoAll(SetArgPointee<0>(mockBurst), Invoke(makeStatusOk))); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -491,13 +513,13 @@ TEST(PreparedModelTest, configureExecutionBurst) { EXPECT_NE(result.value(), nullptr); } -TEST(PreparedModelTest, configureExecutionBurstError) { +TEST_P(PreparedModelTest, configureExecutionBurstError) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -507,13 +529,13 @@ TEST(PreparedModelTest, configureExecutionBurstError) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, configureExecutionBurstTransportFailure) { +TEST_P(PreparedModelTest, configureExecutionBurstTransportFailure) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -523,13 +545,13 @@ TEST(PreparedModelTest, configureExecutionBurstTransportFailure) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, configureExecutionBurstDeadObject) { +TEST_P(PreparedModelTest, configureExecutionBurstDeadObject) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -539,10 +561,84 @@ TEST(PreparedModelTest, configureExecutionBurstDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, getUnderlyingResource) { +TEST_P(PreparedModelTest, createReusableExecution) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto mockExecution = ndk::SharedRefBase::make(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<3>(mockExecution), Invoke(makeStatusOk))); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST_P(PreparedModelTest, createReusableExecutionError) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST_P(PreparedModelTest, createReusableExecutionTransportFailure) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST_P(PreparedModelTest, createReusableExecutionDeadObject) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST_P(PreparedModelTest, getUnderlyingResource) { + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto resource = preparedModel->getUnderlyingResource(); @@ -554,4 +650,6 @@ TEST(PreparedModelTest, getUnderlyingResource) { EXPECT_EQ(maybeMock->get(), mockPreparedModel.get()); } +INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(PreparedModelTest, kAllAidlVersions); + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/TestUtils.cpp b/neuralnetworks/aidl/utils/test/TestUtils.cpp new file mode 100644 index 0000000000..9abec883a6 --- /dev/null +++ b/neuralnetworks/aidl/utils/test/TestUtils.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 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 "TestUtils.h" + +#include +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::utils { + +std::string printTestVersion(const testing::TestParamInfo& info) { + switch (info.param.level) { + case nn::Version::Level::FEATURE_LEVEL_5: + return "v1"; + case nn::Version::Level::FEATURE_LEVEL_6: + return "v2"; + case nn::Version::Level::FEATURE_LEVEL_7: + return "v3"; + case nn::Version::Level::FEATURE_LEVEL_8: + return "v4"; + default: + LOG(FATAL) << "Invalid AIDL version: " << info.param; + return "invalid"; + } +} + +} // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/TestUtils.h b/neuralnetworks/aidl/utils/test/TestUtils.h new file mode 100644 index 0000000000..23f734a47a --- /dev/null +++ b/neuralnetworks/aidl/utils/test/TestUtils.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H + +#include +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::utils { + +class VersionedAidlUtilsTestBase : public ::testing::TestWithParam { + protected: + const nn::Version kVersion = GetParam(); +}; + +std::string printTestVersion(const testing::TestParamInfo& info); + +inline const auto kAllAidlVersions = + ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6, + nn::kVersionFeatureLevel7, nn::kVersionFeatureLevel8); + +#define INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(TestSuite, versions) \ + INSTANTIATE_TEST_SUITE_P(Versioned, TestSuite, versions, printTestVersion) + +} // namespace aidl::android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp index cd5475c0d3..b3e9c633e3 100644 --- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp +++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp @@ -208,6 +208,11 @@ class InvalidPreparedModel : public BnPreparedModel { return ndk::ScopedAStatus::fromServiceSpecificError( static_cast(ErrorStatus::GENERAL_FAILURE)); } + ndk::ScopedAStatus createReusableExecution(const aidl_hal::Request&, bool, int64_t, + std::shared_ptr*) override { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast(ErrorStatus::GENERAL_FAILURE)); + } }; template diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h new file mode 100644 index 0000000000..6a9ac57fbe --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H + +#include "nnapi/hal/aidl/Adapter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IExecution to BnExecution. +class Execution : public BnExecution { + public: + explicit Execution(::android::nn::SharedExecution execution); + + ndk::ScopedAStatus executeSynchronously(int64_t deadlineNs, + ExecutionResult* executionResult) override; + ndk::ScopedAStatus executeFenced(const std::vector& waitFor, + int64_t deadlineNs, int64_t durationNs, + FencedExecutionResult* fencedExecutionResult) override; + + protected: + const ::android::nn::SharedExecution kExecution; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h index 93e0427426..f92b0bc783 100644 --- a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,9 @@ class PreparedModel : public BnPreparedModel { int64_t loopTimeoutDurationNs, int64_t durationNs, FencedExecutionResult* executionResult) override; ndk::ScopedAStatus configureExecutionBurst(std::shared_ptr* burst) override; + ndk::ScopedAStatus createReusableExecution(const Request& request, bool measureTiming, + int64_t loopTimeoutDurationNs, + std::shared_ptr* execution) override; ::android::nn::SharedPreparedModel getUnderlyingPreparedModel() const; diff --git a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp index 71ed1a857b..5cab62c625 100644 --- a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp +++ b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp @@ -17,6 +17,7 @@ #include "PreparedModel.h" #include "Burst.h" +#include "Execution.h" #include #include @@ -26,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -167,6 +169,56 @@ nn::GeneralResult executeFenced( .syncFence = std::move(fileDescriptor)}; } +nn::GeneralResult createReusableExecution( + const nn::IPreparedModel& preparedModel, const Request& request, bool measureTiming, + int64_t loopTimeoutDurationNs) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO; + const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs)); + return preparedModel.createReusableExecution(nnRequest, nnMeasureTiming, nnLoopTimeoutDuration); +} + +nn::ExecutionResult executeSynchronously(const nn::IExecution& execution, + int64_t deadlineNs) { + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + + const auto result = execution.compute(nnDeadline); + + if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + const auto& [message, code, outputShapes] = result.error(); + LOG(ERROR) << "executeSynchronously failed with " << code << ": " << message; + return ExecutionResult{.outputSufficientSize = false, + .outputShapes = utils::convert(outputShapes).value(), + .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}}; + } + + const auto& [outputShapes, timing] = NN_TRY(result); + return ExecutionResult{.outputSufficientSize = true, + .outputShapes = utils::convert(outputShapes).value(), + .timing = utils::convert(timing).value()}; +} + +nn::GeneralResult executeFenced( + const nn::IExecution& execution, const std::vector& waitFor, + int64_t deadlineNs, int64_t durationNs) { + const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor)); + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + const auto nnDuration = NN_TRY(makeOptionalDuration(durationNs)); + + auto [syncFence, executeFencedInfoCallback] = + NN_TRY(execution.computeFenced(nnWaitFor, nnDeadline, nnDuration)); + + ndk::ScopedFileDescriptor fileDescriptor; + if (syncFence.hasFd()) { + auto uniqueFd = NN_TRY(nn::dupFd(syncFence.getFd())); + fileDescriptor = ndk::ScopedFileDescriptor(uniqueFd.release()); + } + + return FencedExecutionResult{.callback = ndk::SharedRefBase::make( + std::move(executeFencedInfoCallback)), + .syncFence = std::move(fileDescriptor)}; +} + } // namespace PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel) @@ -222,4 +274,51 @@ nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const { return kPreparedModel; } +ndk::ScopedAStatus PreparedModel::createReusableExecution(const Request& request, + bool measureTiming, + int64_t loopTimeoutDurationNs, + std::shared_ptr* execution) { + auto result = adapter::createReusableExecution(*kPreparedModel, request, measureTiming, + loopTimeoutDurationNs); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *execution = ndk::SharedRefBase::make(std::move(result).value()); + return ndk::ScopedAStatus::ok(); +} + +Execution::Execution(nn::SharedExecution execution) : kExecution(std::move(execution)) { + CHECK(kExecution != nullptr); +} + +ndk::ScopedAStatus Execution::executeSynchronously(int64_t deadlineNs, + ExecutionResult* executionResult) { + auto result = adapter::executeSynchronously(*kExecution, deadlineNs); + if (!result.has_value()) { + const auto& [message, code, _] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Execution::executeFenced(const std::vector& waitFor, + int64_t deadlineNs, int64_t durationNs, + FencedExecutionResult* executionResult) { + auto result = adapter::executeFenced(*kExecution, waitFor, deadlineNs, durationNs); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::neuralnetworks::adapter -- cgit v1.2.3 From 38dd4789016954fc5797d141f9d9ff4825024c2e Mon Sep 17 00:00:00 2001 From: David Gross Date: Wed, 17 Nov 2021 15:39:18 -0800 Subject: Add NNAPI specification and infrastructure for FL7. Adds operations MIRROR_PAD and REVERSE. Extends RSQRT to support QUANT8_ASYMM and QUANT8_ASYMM_SIGNED. DOES NOT include tests or CPU reference implementation. (This is a slightly non-trivial cherry pick that had to be hand-edited to compensate for the fact that certain nn::Version changes are absent from the target branch.) Bug: 202280917 Test: NeuralNetworksTest_static Test: VtsHalNeuralnetworksTargetTest Merged-In: I0b2133346b996849faac00c46885e3633c78f024 Change-Id: I0b2133346b996849faac00c46885e3633c78f024 (cherry picked from commit 04ed8595b5587e9f6e71ac45edd17cf92da56c32) --- .../compatibility_matrix.current.xml | 2 +- .../hardware/neuralnetworks/OperationType.aidl | 2 + .../hardware/neuralnetworks/OperationType.aidl | 69 ++++++++++++++++++++++ neuralnetworks/aidl/utils/Android.bp | 2 +- .../aidl/utils/include/nnapi/hal/aidl/Utils.h | 2 +- 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index eb6ead3851..baf31e234e 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -396,7 +396,7 @@ android.hardware.neuralnetworks - 1-2 + 1-3 IDevice .* diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl index 2eff11b146..34506c8860 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl @@ -138,4 +138,6 @@ enum OperationType { RANK = 101, BATCH_MATMUL = 102, PACK = 103, + MIRROR_PAD = 104, + REVERSE = 105, } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl index 3499fc1af8..0b745a966b 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl @@ -4229,6 +4229,8 @@ enum OperationType { * Supported tensor {@link OperandType}: * * {@link OperandType::TENSOR_FLOAT16} * * {@link OperandType::TENSOR_FLOAT32} + * * {@link OperandType::TENSOR_QUANT8_ASYMM} (since NNAPI feature level 7) + * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since NNAPI feature level 7) * * Supported tensor rank: from 1. * @@ -4237,6 +4239,9 @@ enum OperationType { * * Outputs: * * 0: The output tensor of same shape as input0. + * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and + * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor, + * the scale and zeroPoint can be different from inputs' scale and zeroPoint. */ RSQRT = 83, /** @@ -5214,4 +5219,68 @@ enum OperationType { * * 0: The packed tensor. */ PACK = 103, + + /** + * Pads a tensor with mirrored values. + * + * Supported tensor {@link OperandType}: + * * {@link OperandType::TENSOR_FLOAT16} + * * {@link OperandType::TENSOR_FLOAT32} + * * {@link OperandType::TENSOR_QUANT8_ASYMM} + * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} + * * {@link OperandType::TENSOR_INT32} + * + * Supported tensor rank: from 1. + * + * Inputs: + * * 0: An n-D tensor, specifying the tensor to be padded. + * * 1: A 2-D tensor of {@link OperandType::TENSOR_INT32}, the paddings + * for each spatial dimension of the input tensor. The shape of the + * tensor must be {rank(input0), 2}. + * padding[i, 0] specifies the number of elements to be padded in the + * front of dimension i. + * padding[i, 1] specifies the number of elements to be padded after the + * end of dimension i. + * * 2: An {@link OperandType::INT32} scalar, specifying the mode. + * Options are 0:REFLECT and 1:SYMMETRIC. + * + * Outputs: + * * 0: A tensor of the same {@link OperandType} as input0. The + * output tensor has the same rank as input0, and each + * dimension of the output tensor has the same size as the + * corresponding dimension of the input tensor plus the size + * of the padding: + * output0.dimension[i] = + * padding[i, 0] + input0.dimension[i] + padding[i, 1] + * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and + * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor, + * the scale and zeroPoint must be the same as input0. + */ + MIRROR_PAD = 104, + + /** + * Reverses a specified dimension of a tensor. + * + * Supported tensor {@link OperandType}: + * * {@link OperandType::TENSOR_FLOAT16} + * * {@link OperandType::TENSOR_FLOAT32} + * * {@link OperandType::TENSOR_QUANT8_ASYMM} + * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} + * * {@link OperandType::TENSOR_INT32} + * + * Supported tensor rank: up to 8. + * + * Inputs: + * * 0: Input tensor of rank n. + * * 1: Axis tensor of type {@link OperandType::TENSOR_INT32} and shape [1], + * specifying which dimension of the input tensor is to be reversed. The dimension + * must be in the range [0, n). + * + * Outputs: + * * 0: The reversed tensor. + * For {@link OperandType::TENSOR_QUANT8_ASYMM} and + * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensors, + * the scales and zeroPoint must be the same as input0. + */ + REVERSE = 105, } diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp index 872e4e8581..5a6a080653 100644 --- a/neuralnetworks/aidl/utils/Android.bp +++ b/neuralnetworks/aidl/utils/Android.bp @@ -38,7 +38,7 @@ cc_library_static { "neuralnetworks_utils_hal_common", ], shared_libs: [ - "android.hardware.neuralnetworks-V2-ndk", + "android.hardware.neuralnetworks-V3-ndk", "libbinder_ndk", "libhidlbase", "libnativewindow", diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h index 72cf73e136..03530955ca 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h @@ -29,7 +29,7 @@ namespace aidl::android::hardware::neuralnetworks::utils { constexpr auto kDefaultPriority = Priority::MEDIUM; -constexpr auto kVersion = nn::Version::FEATURE_LEVEL_6; +constexpr auto kVersion = nn::Version::FEATURE_LEVEL_7; template nn::Result validate(const Type& halObject) { -- cgit v1.2.3 From 8cfb70f93ef39ff5b3ad11dacc2e1f961a5602ca Mon Sep 17 00:00:00 2001 From: David Gross Date: Wed, 12 Jan 2022 14:18:36 -0800 Subject: Freeze neuralnetworks AIDL version as v3 for FL7 $ m android.hardware.neuralnetworks-update-api $ m android.hardware.neuralnetworks-freeze-api (This cherry pick required hand editing to change makefile references from android.hardware.neuralnetworks-V2-ndk to android.hardware.neuralnetworks-V3-ndk.) Bug: 202280925 Test: adb shell NeuralNetworksTest_static Test: atest VtsHalNeuralnetworksTargetTest Merged-In: I2b2755d7376bb847b15b395e280bf352b5b9ef55 Change-Id: I2b2755d7376bb847b15b395e280bf352b5b9ef55 (cherry picked from commit 68e4300c72a8646f085b94e309abc5b6edd300e8) --- neuralnetworks/1.3/vts/functional/Android.bp | 2 +- neuralnetworks/aidl/Android.bp | 1 + .../android.hardware.neuralnetworks/3/.hash | 1 + .../hardware/neuralnetworks/BufferDesc.aidl | 38 ++++++ .../hardware/neuralnetworks/BufferRole.aidl | 40 ++++++ .../hardware/neuralnetworks/Capabilities.aidl | 42 ++++++ .../hardware/neuralnetworks/DataLocation.aidl | 41 ++++++ .../hardware/neuralnetworks/DeviceBuffer.aidl | 39 ++++++ .../hardware/neuralnetworks/DeviceType.aidl | 41 ++++++ .../hardware/neuralnetworks/ErrorStatus.aidl | 46 +++++++ .../neuralnetworks/ExecutionPreference.aidl | 40 ++++++ .../hardware/neuralnetworks/ExecutionResult.aidl | 40 ++++++ .../android/hardware/neuralnetworks/Extension.aidl | 39 ++++++ .../neuralnetworks/ExtensionNameAndPrefix.aidl | 39 ++++++ .../ExtensionOperandTypeInformation.aidl | 40 ++++++ .../neuralnetworks/FencedExecutionResult.aidl | 39 ++++++ .../neuralnetworks/FusedActivationFunc.aidl | 41 ++++++ .../3/android/hardware/neuralnetworks/IBuffer.aidl | 39 ++++++ .../3/android/hardware/neuralnetworks/IBurst.aidl | 39 ++++++ .../3/android/hardware/neuralnetworks/IDevice.aidl | 52 ++++++++ .../neuralnetworks/IFencedExecutionCallback.aidl | 38 ++++++ .../hardware/neuralnetworks/IPreparedModel.aidl | 42 ++++++ .../neuralnetworks/IPreparedModelCallback.aidl | 38 ++++++ .../neuralnetworks/IPreparedModelParcel.aidl | 38 ++++++ .../3/android/hardware/neuralnetworks/Memory.aidl | 40 ++++++ .../3/android/hardware/neuralnetworks/Model.aidl | 43 +++++++ .../neuralnetworks/NumberOfCacheFiles.aidl | 39 ++++++ .../3/android/hardware/neuralnetworks/Operand.aidl | 44 +++++++ .../neuralnetworks/OperandExtraParams.aidl | 39 ++++++ .../hardware/neuralnetworks/OperandLifeTime.aidl | 44 +++++++ .../neuralnetworks/OperandPerformance.aidl | 39 ++++++ .../hardware/neuralnetworks/OperandType.aidl | 53 ++++++++ .../android/hardware/neuralnetworks/Operation.aidl | 40 ++++++ .../hardware/neuralnetworks/OperationType.aidl | 143 +++++++++++++++++++++ .../hardware/neuralnetworks/OutputShape.aidl | 39 ++++++ .../hardware/neuralnetworks/PerformanceInfo.aidl | 39 ++++++ .../android/hardware/neuralnetworks/Priority.aidl | 40 ++++++ .../3/android/hardware/neuralnetworks/Request.aidl | 40 ++++++ .../hardware/neuralnetworks/RequestArgument.aidl | 40 ++++++ .../hardware/neuralnetworks/RequestMemoryPool.aidl | 39 ++++++ .../android/hardware/neuralnetworks/Subgraph.aidl | 41 ++++++ .../neuralnetworks/SymmPerChannelQuantParams.aidl | 39 ++++++ .../3/android/hardware/neuralnetworks/Timing.aidl | 39 ++++++ neuralnetworks/aidl/utils/Android.bp | 2 +- neuralnetworks/aidl/vts/functional/Android.bp | 2 +- neuralnetworks/utils/common/Android.bp | 2 +- neuralnetworks/utils/service/Android.bp | 2 +- 47 files changed, 1738 insertions(+), 5 deletions(-) create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp index ab0a0184be..5cf71cffd6 100644 --- a/neuralnetworks/1.3/vts/functional/Android.bp +++ b/neuralnetworks/1.3/vts/functional/Android.bp @@ -66,7 +66,7 @@ cc_test { "VtsHalNeuralNetworksV1_0_utils", "VtsHalNeuralNetworksV1_2_utils", "VtsHalNeuralNetworksV1_3_utils", - "android.hardware.neuralnetworks-V2-ndk", + "android.hardware.neuralnetworks-V3-ndk", "android.hardware.neuralnetworks@1.0", "android.hardware.neuralnetworks@1.1", "android.hardware.neuralnetworks@1.2", diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp index f5193df281..f38d6cafaf 100644 --- a/neuralnetworks/aidl/Android.bp +++ b/neuralnetworks/aidl/Android.bp @@ -37,5 +37,6 @@ aidl_interface { versions: [ "1", "2", + "3", ], } diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash new file mode 100644 index 0000000000..3b9f018381 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash @@ -0,0 +1 @@ +8c2c4ca2327e6f779dad6119c03d832ea4e1def1 diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl new file mode 100644 index 0000000000..05cec76c88 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable BufferDesc { + int[] dimensions; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl new file mode 100644 index 0000000000..10a6b75ac7 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable BufferRole { + int modelIndex; + int ioIndex; + float probability; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl new file mode 100644 index 0000000000..30877c0294 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Capabilities { + android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceScalar; + android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceTensor; + android.hardware.neuralnetworks.OperandPerformance[] operandPerformance; + android.hardware.neuralnetworks.PerformanceInfo ifPerformance; + android.hardware.neuralnetworks.PerformanceInfo whilePerformance; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl new file mode 100644 index 0000000000..db49a38979 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable DataLocation { + int poolIndex; + long offset; + long length; + long padding; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl new file mode 100644 index 0000000000..7cdd6db742 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable DeviceBuffer { + android.hardware.neuralnetworks.IBuffer buffer; + int token; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl new file mode 100644 index 0000000000..82fe8ae3e7 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum DeviceType { + OTHER = 1, + CPU = 2, + GPU = 3, + ACCELERATOR = 4, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl new file mode 100644 index 0000000000..57d5d6e4cd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum ErrorStatus { + NONE = 0, + DEVICE_UNAVAILABLE = 1, + GENERAL_FAILURE = 2, + OUTPUT_INSUFFICIENT_SIZE = 3, + INVALID_ARGUMENT = 4, + MISSED_DEADLINE_TRANSIENT = 5, + MISSED_DEADLINE_PERSISTENT = 6, + RESOURCE_EXHAUSTED_TRANSIENT = 7, + RESOURCE_EXHAUSTED_PERSISTENT = 8, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl new file mode 100644 index 0000000000..4352d8f334 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum ExecutionPreference { + LOW_POWER = 0, + FAST_SINGLE_ANSWER = 1, + SUSTAINED_SPEED = 2, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl new file mode 100644 index 0000000000..44e9922f52 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable ExecutionResult { + boolean outputSufficientSize; + android.hardware.neuralnetworks.OutputShape[] outputShapes; + android.hardware.neuralnetworks.Timing timing; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl new file mode 100644 index 0000000000..c47028d99f --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Extension { + String name; + android.hardware.neuralnetworks.ExtensionOperandTypeInformation[] operandTypes; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl new file mode 100644 index 0000000000..6c287fd460 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable ExtensionNameAndPrefix { + String name; + char prefix; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl new file mode 100644 index 0000000000..a3680aa9dd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable ExtensionOperandTypeInformation { + char type; + boolean isTensor; + int byteSize; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl new file mode 100644 index 0000000000..7952b34632 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable FencedExecutionResult { + android.hardware.neuralnetworks.IFencedExecutionCallback callback; + @nullable ParcelFileDescriptor syncFence; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl new file mode 100644 index 0000000000..7e61bbbdb1 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum FusedActivationFunc { + NONE = 0, + RELU = 1, + RELU1 = 2, + RELU6 = 3, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl new file mode 100644 index 0000000000..f10e7e24ca --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IBuffer { + void copyFrom(in android.hardware.neuralnetworks.Memory src, in int[] dimensions); + void copyTo(in android.hardware.neuralnetworks.Memory dst); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl new file mode 100644 index 0000000000..eb3d0b004a --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IBurst { + android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in long[] memoryIdentifierTokens, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); + void releaseMemoryResource(in long memoryIdentifierToken); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl new file mode 100644 index 0000000000..c9c67f2fcd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IDevice { + android.hardware.neuralnetworks.DeviceBuffer allocate(in android.hardware.neuralnetworks.BufferDesc desc, in android.hardware.neuralnetworks.IPreparedModelParcel[] preparedModels, in android.hardware.neuralnetworks.BufferRole[] inputRoles, in android.hardware.neuralnetworks.BufferRole[] outputRoles); + android.hardware.neuralnetworks.Capabilities getCapabilities(); + android.hardware.neuralnetworks.NumberOfCacheFiles getNumberOfCacheFilesNeeded(); + android.hardware.neuralnetworks.Extension[] getSupportedExtensions(); + boolean[] getSupportedOperations(in android.hardware.neuralnetworks.Model model); + android.hardware.neuralnetworks.DeviceType getType(); + String getVersionString(); + void prepareModel(in android.hardware.neuralnetworks.Model model, in android.hardware.neuralnetworks.ExecutionPreference preference, in android.hardware.neuralnetworks.Priority priority, in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback); + void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback); + const int BYTE_SIZE_OF_CACHE_TOKEN = 32; + const int MAX_NUMBER_OF_CACHE_FILES = 32; + const int EXTENSION_TYPE_HIGH_BITS_PREFIX = 15; + const int EXTENSION_TYPE_LOW_BITS_TYPE = 16; + const int OPERAND_TYPE_BASE_MAX = 65535; + const int OPERATION_TYPE_BASE_MAX = 65535; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl new file mode 100644 index 0000000000..0bfb80ac78 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IFencedExecutionCallback { + android.hardware.neuralnetworks.ErrorStatus getExecutionInfo(out android.hardware.neuralnetworks.Timing timingLaunched, out android.hardware.neuralnetworks.Timing timingFenced); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl new file mode 100644 index 0000000000..fccb5dc98e --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IPreparedModel { + android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); + android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs); + android.hardware.neuralnetworks.IBurst configureExecutionBurst(); + const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000; + const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl new file mode 100644 index 0000000000..e0c763bc2a --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IPreparedModelCallback { + void notify(in android.hardware.neuralnetworks.ErrorStatus status, in android.hardware.neuralnetworks.IPreparedModel preparedModel); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl new file mode 100644 index 0000000000..dbedf12772 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable IPreparedModelParcel { + android.hardware.neuralnetworks.IPreparedModel preparedModel; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl new file mode 100644 index 0000000000..37fa102cf4 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +union Memory { + android.hardware.common.Ashmem ashmem; + android.hardware.common.MappableFile mappableFile; + android.hardware.graphics.common.HardwareBuffer hardwareBuffer; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl new file mode 100644 index 0000000000..30d8dda55d --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Model { + android.hardware.neuralnetworks.Subgraph main; + android.hardware.neuralnetworks.Subgraph[] referenced; + byte[] operandValues; + android.hardware.neuralnetworks.Memory[] pools; + boolean relaxComputationFloat32toFloat16; + android.hardware.neuralnetworks.ExtensionNameAndPrefix[] extensionNameToPrefix; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl new file mode 100644 index 0000000000..9314760a43 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable NumberOfCacheFiles { + int numModelCache; + int numDataCache; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl new file mode 100644 index 0000000000..1d9bdd8446 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Operand { + android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32; + int[] dimensions; + float scale; + int zeroPoint; + android.hardware.neuralnetworks.OperandLifeTime lifetime = android.hardware.neuralnetworks.OperandLifeTime.TEMPORARY_VARIABLE; + android.hardware.neuralnetworks.DataLocation location; + @nullable android.hardware.neuralnetworks.OperandExtraParams extraParams; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl new file mode 100644 index 0000000000..14792cff08 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +union OperandExtraParams { + android.hardware.neuralnetworks.SymmPerChannelQuantParams channelQuant; + byte[] extension; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl new file mode 100644 index 0000000000..40adfb1dd8 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum OperandLifeTime { + TEMPORARY_VARIABLE = 0, + SUBGRAPH_INPUT = 1, + SUBGRAPH_OUTPUT = 2, + CONSTANT_COPY = 3, + CONSTANT_POOL = 4, + NO_VALUE = 5, + SUBGRAPH = 6, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl new file mode 100644 index 0000000000..ebb361b762 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable OperandPerformance { + android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32; + android.hardware.neuralnetworks.PerformanceInfo info; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl new file mode 100644 index 0000000000..9f2c759d38 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum OperandType { + FLOAT32 = 0, + INT32 = 1, + UINT32 = 2, + TENSOR_FLOAT32 = 3, + TENSOR_INT32 = 4, + TENSOR_QUANT8_ASYMM = 5, + BOOL = 6, + TENSOR_QUANT16_SYMM = 7, + TENSOR_FLOAT16 = 8, + TENSOR_BOOL8 = 9, + FLOAT16 = 10, + TENSOR_QUANT8_SYMM_PER_CHANNEL = 11, + TENSOR_QUANT16_ASYMM = 12, + TENSOR_QUANT8_SYMM = 13, + TENSOR_QUANT8_ASYMM_SIGNED = 14, + SUBGRAPH = 15, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl new file mode 100644 index 0000000000..a4a3fbee60 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Operation { + android.hardware.neuralnetworks.OperationType type = android.hardware.neuralnetworks.OperationType.ADD; + int[] inputs; + int[] outputs; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl new file mode 100644 index 0000000000..34506c8860 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum OperationType { + ADD = 0, + AVERAGE_POOL_2D = 1, + CONCATENATION = 2, + CONV_2D = 3, + DEPTHWISE_CONV_2D = 4, + DEPTH_TO_SPACE = 5, + DEQUANTIZE = 6, + EMBEDDING_LOOKUP = 7, + FLOOR = 8, + FULLY_CONNECTED = 9, + HASHTABLE_LOOKUP = 10, + L2_NORMALIZATION = 11, + L2_POOL_2D = 12, + LOCAL_RESPONSE_NORMALIZATION = 13, + LOGISTIC = 14, + LSH_PROJECTION = 15, + LSTM = 16, + MAX_POOL_2D = 17, + MUL = 18, + RELU = 19, + RELU1 = 20, + RELU6 = 21, + RESHAPE = 22, + RESIZE_BILINEAR = 23, + RNN = 24, + SOFTMAX = 25, + SPACE_TO_DEPTH = 26, + SVDF = 27, + TANH = 28, + BATCH_TO_SPACE_ND = 29, + DIV = 30, + MEAN = 31, + PAD = 32, + SPACE_TO_BATCH_ND = 33, + SQUEEZE = 34, + STRIDED_SLICE = 35, + SUB = 36, + TRANSPOSE = 37, + ABS = 38, + ARGMAX = 39, + ARGMIN = 40, + AXIS_ALIGNED_BBOX_TRANSFORM = 41, + BIDIRECTIONAL_SEQUENCE_LSTM = 42, + BIDIRECTIONAL_SEQUENCE_RNN = 43, + BOX_WITH_NMS_LIMIT = 44, + CAST = 45, + CHANNEL_SHUFFLE = 46, + DETECTION_POSTPROCESSING = 47, + EQUAL = 48, + EXP = 49, + EXPAND_DIMS = 50, + GATHER = 51, + GENERATE_PROPOSALS = 52, + GREATER = 53, + GREATER_EQUAL = 54, + GROUPED_CONV_2D = 55, + HEATMAP_MAX_KEYPOINT = 56, + INSTANCE_NORMALIZATION = 57, + LESS = 58, + LESS_EQUAL = 59, + LOG = 60, + LOGICAL_AND = 61, + LOGICAL_NOT = 62, + LOGICAL_OR = 63, + LOG_SOFTMAX = 64, + MAXIMUM = 65, + MINIMUM = 66, + NEG = 67, + NOT_EQUAL = 68, + PAD_V2 = 69, + POW = 70, + PRELU = 71, + QUANTIZE = 72, + QUANTIZED_16BIT_LSTM = 73, + RANDOM_MULTINOMIAL = 74, + REDUCE_ALL = 75, + REDUCE_ANY = 76, + REDUCE_MAX = 77, + REDUCE_MIN = 78, + REDUCE_PROD = 79, + REDUCE_SUM = 80, + ROI_ALIGN = 81, + ROI_POOLING = 82, + RSQRT = 83, + SELECT = 84, + SIN = 85, + SLICE = 86, + SPLIT = 87, + SQRT = 88, + TILE = 89, + TOPK_V2 = 90, + TRANSPOSE_CONV_2D = 91, + UNIDIRECTIONAL_SEQUENCE_LSTM = 92, + UNIDIRECTIONAL_SEQUENCE_RNN = 93, + RESIZE_NEAREST_NEIGHBOR = 94, + QUANTIZED_LSTM = 95, + IF = 96, + WHILE = 97, + ELU = 98, + HARD_SWISH = 99, + FILL = 100, + RANK = 101, + BATCH_MATMUL = 102, + PACK = 103, + MIRROR_PAD = 104, + REVERSE = 105, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl new file mode 100644 index 0000000000..f7335054cf --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable OutputShape { + int[] dimensions; + boolean isSufficient; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl new file mode 100644 index 0000000000..04910f5410 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable PerformanceInfo { + float execTime; + float powerUsage; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl new file mode 100644 index 0000000000..8f357097ab --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@Backing(type="int") @VintfStability +enum Priority { + LOW = 0, + MEDIUM = 1, + HIGH = 2, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl new file mode 100644 index 0000000000..39ec7a9acd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Request { + android.hardware.neuralnetworks.RequestArgument[] inputs; + android.hardware.neuralnetworks.RequestArgument[] outputs; + android.hardware.neuralnetworks.RequestMemoryPool[] pools; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl new file mode 100644 index 0000000000..e3541c0ece --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable RequestArgument { + boolean hasNoValue; + android.hardware.neuralnetworks.DataLocation location; + int[] dimensions; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl new file mode 100644 index 0000000000..312f5813bc --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +union RequestMemoryPool { + android.hardware.neuralnetworks.Memory pool; + int token; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl new file mode 100644 index 0000000000..b7d44515f4 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Subgraph { + android.hardware.neuralnetworks.Operand[] operands; + android.hardware.neuralnetworks.Operation[] operations; + int[] inputIndexes; + int[] outputIndexes; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl new file mode 100644 index 0000000000..02d68f9ed1 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable SymmPerChannelQuantParams { + float[] scales; + int channelDim; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl new file mode 100644 index 0000000000..bcc83cfbee --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +parcelable Timing { + long timeOnDeviceNs; + long timeInDriverNs; +} diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp index 5a6a080653..068727214f 100644 --- a/neuralnetworks/aidl/utils/Android.bp +++ b/neuralnetworks/aidl/utils/Android.bp @@ -54,7 +54,7 @@ cc_test { static_libs: [ "android.hardware.common-V2-ndk", "android.hardware.graphics.common-V2-ndk", - "android.hardware.neuralnetworks-V2-ndk", + "android.hardware.neuralnetworks-V3-ndk", "libaidlcommonsupport", "libgmock", "libneuralnetworks_common", diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp index 3558d12aa1..27758a7487 100644 --- a/neuralnetworks/aidl/vts/functional/Android.bp +++ b/neuralnetworks/aidl/vts/functional/Android.bp @@ -51,7 +51,7 @@ cc_test { static_libs: [ "android.hardware.common-V2-ndk", "android.hardware.graphics.common-V2-ndk", - "android.hardware.neuralnetworks-V2-ndk", + "android.hardware.neuralnetworks-V3-ndk", "android.hidl.allocator@1.0", "android.hidl.memory@1.0", "libaidlcommonsupport", diff --git a/neuralnetworks/utils/common/Android.bp b/neuralnetworks/utils/common/Android.bp index e50fa37a0a..86608ee104 100644 --- a/neuralnetworks/utils/common/Android.bp +++ b/neuralnetworks/utils/common/Android.bp @@ -35,7 +35,7 @@ cc_library_static { "neuralnetworks_types", ], shared_libs: [ - "android.hardware.neuralnetworks-V2-ndk", + "android.hardware.neuralnetworks-V3-ndk", "libhidlbase", "libnativewindow", "libbinder_ndk", diff --git a/neuralnetworks/utils/service/Android.bp b/neuralnetworks/utils/service/Android.bp index fbb8679508..80f1ff8bec 100644 --- a/neuralnetworks/utils/service/Android.bp +++ b/neuralnetworks/utils/service/Android.bp @@ -39,7 +39,7 @@ cc_library_static { "neuralnetworks_utils_hal_common", ], shared_libs: [ - "android.hardware.neuralnetworks-V2-ndk", + "android.hardware.neuralnetworks-V3-ndk", "android.hardware.neuralnetworks@1.0", "android.hardware.neuralnetworks@1.1", "android.hardware.neuralnetworks@1.2", -- cgit v1.2.3 From 3210fd82425b90fcd933d0b79541a85a7c8ea15b Mon Sep 17 00:00:00 2001 From: David Gross Date: Thu, 2 Dec 2021 15:39:33 -0800 Subject: FL7: Add some AIDL_V3 test infrastructure Test: atest VtsHalNeuralnetworksTargetTest -- --test-arg com.android.tradefed.testtype.GTest:native-test-flag:"--gtest_filter=*abs*:*floor*:*log*:*rsqrt*:*sin*:*sqrt*" Bug: 202280925 Merged-In: I848add0ddb94e1500a5d4d6af5d51ddf5ebba045 Change-Id: I848add0ddb94e1500a5d4d6af5d51ddf5ebba045 (cherry picked from commit 8e9fbfc592d937ea39b587660f9790a0daae31ea) --- neuralnetworks/aidl/vts/functional/Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp index 27758a7487..4fdf57d843 100644 --- a/neuralnetworks/aidl/vts/functional/Android.bp +++ b/neuralnetworks/aidl/vts/functional/Android.bp @@ -63,6 +63,7 @@ cc_test { "neuralnetworks_utils_hal_aidl", ], whole_static_libs: [ + "neuralnetworks_generated_AIDL_V3_example", "neuralnetworks_generated_AIDL_V2_example", "neuralnetworks_generated_V1_0_example", "neuralnetworks_generated_V1_1_example", -- cgit v1.2.3 From ec291441a54ebbfbe764e31c89e0670bbcc5be27 Mon Sep 17 00:00:00 2001 From: David Gross Date: Tue, 7 Dec 2021 15:51:42 -0800 Subject: FL7: Refine REVERSE specification Test: N/A Bug: 202280925 Merged-In: Iae1f177254023c750c701e6594a61f3958de538c Change-Id: Iae1f177254023c750c701e6594a61f3958de538c (cherry picked from commit 91a30c1ceab9d27dd491fd961c70217b20c27578) --- neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl index 0b745a966b..88c61c34b7 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl @@ -5277,7 +5277,7 @@ enum OperationType { * must be in the range [0, n). * * Outputs: - * * 0: The reversed tensor. + * * 0: The reversed tensor of the same shape as the input tensor. * For {@link OperandType::TENSOR_QUANT8_ASYMM} and * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensors, * the scales and zeroPoint must be the same as input0. -- cgit v1.2.3 From 75c5fdcb8c6ffd43ffe357ade3ae905989ba8221 Mon Sep 17 00:00:00 2001 From: David Gross Date: Fri, 7 Jan 2022 14:56:03 -0800 Subject: FL7: Refine MIRROR_PAD specification Test: N/A Bug: 202280925 Merged-In: If19d45d806f6ba33f9aa6c7af9bc411957cdc706 Change-Id: If19d45d806f6ba33f9aa6c7af9bc411957cdc706 (cherry picked from commit 4718025a6c3b4c0fe62eb39879b93aec90340446) --- .../android/hardware/neuralnetworks/OperationType.aidl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl index 88c61c34b7..04c15b9eb1 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl @@ -5223,6 +5223,18 @@ enum OperationType { /** * Pads a tensor with mirrored values. * + * This operator specifies one of two padding modes: REFLECT or SYMMETRIC. + * In the case of REFLECT mode, the mirroring excludes the border element + * on the padding side. + * In the case of SYMMETRIC mode, the mirroring includes the border element + * on the padding side. + * + * For example, if the input is the 1-D tensor `[1, 2, 3]` and the padding + * is `[0, 2]` (i.e., pad no elements before the first (and only) dimension, + * and two elements after the first (and only) dimension), then: + * - REFLECT mode produces the output `[1, 2, 3, 2, 1]` + * - SYMMETRIC mode produces the output `[1, 2, 3, 3, 2]` + * * Supported tensor {@link OperandType}: * * {@link OperandType::TENSOR_FLOAT16} * * {@link OperandType::TENSOR_FLOAT32} @@ -5241,6 +5253,11 @@ enum OperationType { * front of dimension i. * padding[i, 1] specifies the number of elements to be padded after the * end of dimension i. + * Each padding value must be nonnegative. + * In the case of REFLECT mode, each padding value must be less than the + * corresponding dimension. + * In the case of SYMMETRIC mode, each padding value must be less than or + * equal to the corresponding dimension. * * 2: An {@link OperandType::INT32} scalar, specifying the mode. * Options are 0:REFLECT and 1:SYMMETRIC. * -- cgit v1.2.3 From 4847855f2b73861ec406b8acde6edc7ef3678aba Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Fri, 14 Jan 2022 13:45:05 -0800 Subject: Allow atrace hal tracefs access Add atrace hal to the readtracefs group Bug: 214591300 Test: adb shell perfetto (Use config with atrace_categories) Change-Id: Id9e06f88539b59480d5cf57a4ba67cef4676c1d5 Merged-In: Id9e06f88539b59480d5cf57a4ba67cef4676c1d5 --- atrace/1.0/default/android.hardware.atrace@1.0-service.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc index 7110b45c9f..31459b4916 100644 --- a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc +++ b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc @@ -14,4 +14,4 @@ service vendor.atrace-hal-1-0 /vendor/bin/hw/android.hardware.atrace@1.0-service interface android.hardware.atrace@1.0::IAtraceDevice default class early_hal user system - group system + group system readtracefs -- cgit v1.2.3 From cf9779659cc4d0c5ec0f75235471d23bc3742516 Mon Sep 17 00:00:00 2001 From: Tanmay Patil Date: Fri, 14 Jan 2022 13:57:05 -0800 Subject: Remove SurroundView HAL from compatibility_matrix.current This will depreciate the SV HAL from Android T onwards. Refer go/aaos-sv-hal-depreciate for details on reason Bug: 213898970 Test: Verfied with presubmit Change-Id: I5decd4fcf4a3ac4abc3b2229894f015ee506c03e --- compatibility_matrices/compatibility_matrix.current.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index f03008a4e4..7a70667f54 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -77,14 +77,6 @@ default - - android.hardware.automotive.sv - 1.0 - - ISurroundViewService - default - - android.hardware.automotive.vehicle -- cgit v1.2.3 From 28e06feed8c63b6d89454f7d36436dc476bfd9da Mon Sep 17 00:00:00 2001 From: Yu Shan Date: Tue, 11 Jan 2022 21:06:48 -0800 Subject: Use the new LargeParcelable API. Bug: 210063973 Test: atest DefaultVehicleHalTest Change-Id: Id1805638918acdf5bc79d2591d26829289ba56e8 --- .../aidl/impl/vhal/include/ParcelableUtils.h | 32 ++++++-------- .../aidl/impl/vhal/src/DefaultVehicleHal.cpp | 49 +++++++++------------- .../aidl/impl/vhal/test/DefaultVehicleHalTest.cpp | 37 +++++++--------- 3 files changed, 46 insertions(+), 72 deletions(-) diff --git a/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h index dcb15b9c63..4b7c2f3221 100644 --- a/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h +++ b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h @@ -31,19 +31,18 @@ namespace vehicle { template ::ndk::ScopedAStatus vectorToStableLargeParcelable(std::vector&& values, T2* output) { + output->payloads = std::move(values); auto result = ::android::automotive::car_binder_lib::LargeParcelableBase:: - parcelableVectorToStableLargeParcelable(values); + parcelableToStableLargeParcelable(*output); if (!result.ok()) { return toScopedAStatus( result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR); } auto& fd = result.value(); - if (fd == nullptr) { - // If we no longer needs values, move it inside the payloads to avoid copying. - output->payloads = std::move(values); - } else { + if (fd != nullptr) { // Move the returned ScopedFileDescriptor pointer to ScopedFileDescriptor value in // 'sharedMemoryFd' field. + output->payloads.clear(); output->sharedMemoryFd = std::move(*fd); } return ::ndk::ScopedAStatus::ok(); @@ -57,12 +56,13 @@ template return vectorToStableLargeParcelable(std::move(valuesCopy), output); } -template -::android::base::expected, ::ndk::ScopedAStatus> stableLargeParcelableToVector( - const T2& largeParcelable) { - ::android::base::Result>> result = - ::android::automotive::car_binder_lib::LargeParcelableBase:: - stableLargeParcelableToParcelableVector(largeParcelable.sharedMemoryFd); +template +::android::base::expected< + ::android::automotive::car_binder_lib::LargeParcelableBase::BorrowedOwnedObject, + ::ndk::ScopedAStatus> +fromStableLargeParcelable(const T& largeParcelable) { + auto result = ::android::automotive::car_binder_lib::LargeParcelableBase:: + stableLargeParcelableToParcelable(largeParcelable); if (!result.ok()) { return ::android::base::unexpected(toScopedAStatus( @@ -70,15 +70,7 @@ template "failed to parse large parcelable")); } - if (!result.value().has_value()) { - return ::android::base::unexpected( - ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( - toInt(::aidl::android::hardware::automotive::vehicle::StatusCode:: - INVALID_ARG), - "empty request")); - } - - return std::move(result.value().value()); + return std::move(result.value()); } } // namespace vehicle diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp index e98f02112e..7f09a59fbb 100644 --- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp +++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp @@ -57,7 +57,9 @@ DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr hardware) for (auto& config : configs) { mConfigsByPropId[config.prop] = config; } - auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(configs); + VehiclePropConfigs vehiclePropConfigs; + vehiclePropConfigs.payloads = std::move(configs); + auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs); if (!result.ok()) { ALOGE("failed to convert configs to shared memory file, error: %s, code: %d", getErrorMsg(result).c_str(), getIntErrorCode(result)); @@ -71,6 +73,7 @@ DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr hardware) ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) { if (mConfigFile != nullptr) { + output->payloads.clear(); output->sharedMemoryFd.set(dup(mConfigFile->get())); return ScopedAStatus::ok(); } @@ -131,20 +134,14 @@ ScopedAStatus DefaultVehicleHal::getValues(const CallbackType& callback, const GetValueRequests& requests) { // TODO(b/203713317): check for duplicate properties and duplicate request IDs. - const std::vector* getValueRequests; - // Define deserializedResults here because we need it to have the same lifetime as - // getValueRequests. - expected, ScopedAStatus> deserializedResults; - if (!requests.payloads.empty()) { - getValueRequests = &requests.payloads; - } else { - deserializedResults = stableLargeParcelableToVector(requests); - if (!deserializedResults.ok()) { - ALOGE("failed to parse getValues requests"); - return std::move(deserializedResults.error()); - } - getValueRequests = &deserializedResults.value(); + expected, ScopedAStatus> + deserializedResults = fromStableLargeParcelable(requests); + if (!deserializedResults.ok()) { + ALOGE("getValues: failed to parse getValues requests"); + return std::move(deserializedResults.error()); } + const std::vector& getValueRequests = + deserializedResults.value().getObject()->payloads; std::shared_ptr client; { @@ -153,7 +150,7 @@ ScopedAStatus DefaultVehicleHal::getValues(const CallbackType& callback, } if (StatusCode status = - mVehicleHardware->getValues(client->getResultCallback(), *getValueRequests); + mVehicleHardware->getValues(client->getResultCallback(), getValueRequests); status != StatusCode::OK) { return ScopedAStatus::fromServiceSpecificErrorWithMessage( toInt(status), "failed to get value from VehicleHardware"); @@ -166,27 +163,21 @@ ScopedAStatus DefaultVehicleHal::setValues(const CallbackType& callback, const SetValueRequests& requests) { // TODO(b/203713317): check for duplicate properties and duplicate request IDs. - const std::vector* setValueRequests; - // Define deserializedResults here because we need it to have the same lifetime as - // setValueRequests. - expected, ScopedAStatus> deserializedResults; - if (!requests.payloads.empty()) { - setValueRequests = &requests.payloads; - } else { - deserializedResults = stableLargeParcelableToVector(requests); - if (!deserializedResults.ok()) { - ALOGE("failed to parse setValues requests"); - return std::move(deserializedResults.error()); - } - setValueRequests = &deserializedResults.value(); + expected, ScopedAStatus> + deserializedResults = fromStableLargeParcelable(requests); + if (!deserializedResults.ok()) { + ALOGE("setValues: failed to parse setValues requests"); + return std::move(deserializedResults.error()); } + const std::vector& setValueRequests = + deserializedResults.value().getObject()->payloads; // A list of failed result we already know before sending to hardware. std::vector failedResults; // The list of requests that we would send to hardware. std::vector hardwareRequests; - for (auto& request : *setValueRequests) { + for (auto& request : setValueRequests) { int64_t requestId = request.requestId; if (auto result = checkProperty(request.value); !result.ok()) { ALOGW("property not valid: %s", result.error().message().c_str()); diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp index 8934a7b012..ffc08a71b8 100644 --- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp +++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp @@ -389,15 +389,14 @@ class DefaultVehicleHalTest : public ::testing::Test { }); } - auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable( - expectedHardwareRequests); + requests.payloads = expectedHardwareRequests; + auto result = LargeParcelableBase::parcelableToStableLargeParcelable(requests); if (!result.ok()) { return result.error(); } - if (result.value() == nullptr) { - requests.payloads = expectedHardwareRequests; - } else { + if (result.value() != nullptr) { requests.sharedMemoryFd = std::move(*result.value()); + requests.payloads.clear(); } return {}; } @@ -423,14 +422,13 @@ class DefaultVehicleHalTest : public ::testing::Test { }); } - auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable( - expectedHardwareRequests); + requests.payloads = expectedHardwareRequests; + auto result = LargeParcelableBase::parcelableToStableLargeParcelable(requests); if (!result.ok()) { return result.error(); } - if (result.value() == nullptr) { - requests.payloads = expectedHardwareRequests; - } else { + if (result.value() != nullptr) { + requests.payloads.clear(); requests.sharedMemoryFd = std::move(*result.value()); } return {}; @@ -490,13 +488,10 @@ TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsLarge) { ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage(); ASSERT_TRUE(output.payloads.empty()); - Result>> result = - LargeParcelableBase::stableLargeParcelableToParcelableVector( - output.sharedMemoryFd); + auto result = LargeParcelableBase::stableLargeParcelableToParcelable(output); ASSERT_TRUE(result.ok()) << "failed to parse result shared memory file: " << result.error().message(); - ASSERT_TRUE(result.value().has_value()) << "empty parsed value"; - ASSERT_EQ(result.value().value(), testConfigs); + ASSERT_EQ(result.value().getObject()->payloads, testConfigs); } TEST_F(DefaultVehicleHalTest, testGetValuesSmall) { @@ -544,11 +539,9 @@ TEST_F(DefaultVehicleHalTest, testGetValuesLarge) { ASSERT_TRUE(getValueResults.payloads.empty()) << "payload should be empty, shared memory file should be used"; - auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector( - getValueResults.sharedMemoryFd); + auto result = LargeParcelableBase::stableLargeParcelableToParcelable(getValueResults); ASSERT_TRUE(result.ok()) << "failed to parse shared memory file"; - ASSERT_TRUE(result.value().has_value()) << "no parsed value"; - ASSERT_EQ(result.value().value(), expectedResults) << "results mismatch"; + ASSERT_EQ(result.value().getObject()->payloads, expectedResults) << "results mismatch"; EXPECT_EQ(countClients(), static_cast(1)); } @@ -621,11 +614,9 @@ TEST_F(DefaultVehicleHalTest, testSetValuesLarge) { ASSERT_TRUE(setValueResults.payloads.empty()) << "payload should be empty, shared memory file should be used"; - auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector( - setValueResults.sharedMemoryFd); + auto result = LargeParcelableBase::stableLargeParcelableToParcelable(setValueResults); ASSERT_TRUE(result.ok()) << "failed to parse shared memory file"; - ASSERT_TRUE(result.value().has_value()) << "no parsed value"; - ASSERT_EQ(result.value().value(), expectedResults) << "results mismatch"; + ASSERT_EQ(result.value().getObject()->payloads, expectedResults) << "results mismatch"; EXPECT_EQ(countClients(), static_cast(1)); } -- cgit v1.2.3 From 600e91322b2cba39171c9085fba679dd9d2a0de8 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Fri, 7 Jan 2022 16:27:22 -0800 Subject: Add aidl version of android.hardware.input.common This is a type HAL that will be used for input-related types. Currently the main thing that's stored there is MotionEvent. Bug: 210158587 Test: m Change-Id: Id6658a179147591564521a36d0de296a1f2212b0 --- compatibility_matrices/exclude/fcm_exclude.cpp | 1 + input/common/aidl/Android.bp | 22 ++ .../android/hardware/input/common/Action.aidl | 50 +++ .../android/hardware/input/common/Axis.aidl | 82 +++++ .../android/hardware/input/common/Button.aidl | 45 +++ .../hardware/input/common/Classification.aidl | 40 +++ .../android/hardware/input/common/EdgeFlag.aidl | 42 +++ .../android/hardware/input/common/Flag.aidl | 40 +++ .../android/hardware/input/common/Meta.aidl | 55 +++ .../android/hardware/input/common/MotionEvent.aidl | 56 +++ .../hardware/input/common/PointerCoords.aidl | 39 +++ .../hardware/input/common/PointerProperties.aidl | 39 +++ .../android/hardware/input/common/PolicyFlag.aidl | 47 +++ .../android/hardware/input/common/Source.aidl | 53 +++ .../android/hardware/input/common/SourceClass.aidl | 43 +++ .../android/hardware/input/common/ToolType.aidl | 42 +++ .../android/hardware/input/common/VideoFrame.aidl | 41 +++ .../aidl/android/hardware/input/common/Action.aidl | 89 +++++ .../aidl/android/hardware/input/common/Axis.aidl | 387 +++++++++++++++++++++ .../aidl/android/hardware/input/common/Button.aidl | 33 ++ .../hardware/input/common/Classification.aidl | 34 ++ .../android/hardware/input/common/EdgeFlag.aidl | 45 +++ .../aidl/android/hardware/input/common/Flag.aidl | 45 +++ .../aidl/android/hardware/input/common/Meta.aidl | 94 +++++ .../android/hardware/input/common/MotionEvent.aidl | 114 ++++++ .../hardware/input/common/PointerCoords.aidl | 41 +++ .../hardware/input/common/PointerProperties.aidl | 41 +++ .../android/hardware/input/common/PolicyFlag.aidl | 70 ++++ .../aidl/android/hardware/input/common/Source.aidl | 43 +++ .../android/hardware/input/common/SourceClass.aidl | 28 ++ .../android/hardware/input/common/ToolType.aidl | 30 ++ .../android/hardware/input/common/VideoFrame.aidl | 79 +++++ 32 files changed, 1910 insertions(+) create mode 100644 input/common/aidl/Android.bp create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl create mode 100644 input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl create mode 100644 input/common/aidl/android/hardware/input/common/Action.aidl create mode 100644 input/common/aidl/android/hardware/input/common/Axis.aidl create mode 100644 input/common/aidl/android/hardware/input/common/Button.aidl create mode 100644 input/common/aidl/android/hardware/input/common/Classification.aidl create mode 100644 input/common/aidl/android/hardware/input/common/EdgeFlag.aidl create mode 100644 input/common/aidl/android/hardware/input/common/Flag.aidl create mode 100644 input/common/aidl/android/hardware/input/common/Meta.aidl create mode 100644 input/common/aidl/android/hardware/input/common/MotionEvent.aidl create mode 100644 input/common/aidl/android/hardware/input/common/PointerCoords.aidl create mode 100644 input/common/aidl/android/hardware/input/common/PointerProperties.aidl create mode 100644 input/common/aidl/android/hardware/input/common/PolicyFlag.aidl create mode 100644 input/common/aidl/android/hardware/input/common/Source.aidl create mode 100644 input/common/aidl/android/hardware/input/common/SourceClass.aidl create mode 100644 input/common/aidl/android/hardware/input/common/ToolType.aidl create mode 100644 input/common/aidl/android/hardware/input/common/VideoFrame.aidl diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp index 2aa4bb2a22..414c502fd7 100644 --- a/compatibility_matrices/exclude/fcm_exclude.cpp +++ b/compatibility_matrices/exclude/fcm_exclude.cpp @@ -56,6 +56,7 @@ bool ShouldCheckMissingHalsInFcm(const std::string& package) { "android.hardware.common", "android.hardware.common.fmq", "android.hardware.graphics.common", + "android.hardware.input.common", "android.hardware.keymaster", "android.hardware.radio", "android.hardware.uwb.fira_android", diff --git a/input/common/aidl/Android.bp b/input/common/aidl/Android.bp new file mode 100644 index 0000000000..6cf64a6fdd --- /dev/null +++ b/input/common/aidl/Android.bp @@ -0,0 +1,22 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +aidl_interface { + name: "android.hardware.input.common", + srcs: ["android/hardware/input/common/*.aidl"], + stability: "vintf", + backend: { + cpp: { + enabled: false, + }, + java: { + enabled: false, + }, + }, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl new file mode 100644 index 0000000000..a2e0381188 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="int") @VintfStability +enum Action { + DOWN = 0, + UP = 1, + MOVE = 2, + CANCEL = 3, + OUTSIDE = 4, + POINTER_DOWN = 5, + POINTER_UP = 6, + HOVER_MOVE = 7, + SCROLL = 8, + HOVER_ENTER = 9, + HOVER_EXIT = 10, + BUTTON_PRESS = 11, + BUTTON_RELEASE = 12, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl new file mode 100644 index 0000000000..2114c7deb1 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="int") @VintfStability +enum Axis { + X = 0, + Y = 1, + PRESSURE = 2, + SIZE = 3, + TOUCH_MAJOR = 4, + TOUCH_MINOR = 5, + TOOL_MAJOR = 6, + TOOL_MINOR = 7, + ORIENTATION = 8, + VSCROLL = 9, + HSCROLL = 10, + Z = 11, + RX = 12, + RY = 13, + RZ = 14, + HAT_X = 15, + HAT_Y = 16, + LTRIGGER = 17, + RTRIGGER = 18, + THROTTLE = 19, + RUDDER = 20, + WHEEL = 21, + GAS = 22, + BRAKE = 23, + DISTANCE = 24, + TILT = 25, + SCROLL = 26, + RELATIVE_X = 27, + RELATIVE_Y = 28, + GENERIC_1 = 32, + GENERIC_2 = 33, + GENERIC_3 = 34, + GENERIC_4 = 35, + GENERIC_5 = 36, + GENERIC_6 = 37, + GENERIC_7 = 38, + GENERIC_8 = 39, + GENERIC_9 = 40, + GENERIC_10 = 41, + GENERIC_11 = 42, + GENERIC_12 = 43, + GENERIC_13 = 44, + GENERIC_14 = 45, + GENERIC_15 = 46, + GENERIC_16 = 47, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl new file mode 100644 index 0000000000..10ad65a19a --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="int") @VintfStability +enum Button { + NONE = 0, + PRIMARY = 1, + SECONDARY = 2, + TERTIARY = 4, + BACK = 8, + FORWARD = 16, + STYLUS_PRIMARY = 32, + STYLUS_SECONDARY = 64, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl new file mode 100644 index 0000000000..ddd524685f --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="byte") @VintfStability +enum Classification { + NONE = 0, + AMBIGUOUS_GESTURE = 1, + DEEP_PRESS = 2, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl new file mode 100644 index 0000000000..1040049b81 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="int") @VintfStability +enum EdgeFlag { + NONE = 0, + TOP = 1, + BOTTOM = 2, + LEFT = 4, + RIGHT = 8, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl new file mode 100644 index 0000000000..d3fcd9ff16 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="int") @VintfStability +enum Flag { + WINDOW_IS_OBSCURED = 1, + IS_GENERATED_GESTURE = 8, + TAINTED = -2147483648, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl new file mode 100644 index 0000000000..2c229f9f36 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="int") @VintfStability +enum Meta { + NONE = 0, + ALT_ON = 2, + ALT_LEFT_ON = 16, + ALT_RIGHT_ON = 32, + SHIFT_ON = 1, + SHIFT_LEFT_ON = 64, + SHIFT_RIGHT_ON = 128, + SYM_ON = 4, + FUNCTION_ON = 8, + CTRL_ON = 4096, + CTRL_LEFT_ON = 8192, + CTRL_RIGHT_ON = 16384, + META_ON = 65536, + META_LEFT_ON = 131072, + META_RIGHT_ON = 262144, + CAPS_LOCK_ON = 1048576, + NUM_LOCK_ON = 2097152, + SCROLL_LOCK_ON = 4194304, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl new file mode 100644 index 0000000000..84af4bf4ca --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@VintfStability +parcelable MotionEvent { + int deviceId; + android.hardware.input.common.Source source; + int displayId; + long downTime; + long eventTime; + android.hardware.input.common.Action action; + byte actionIndex; + android.hardware.input.common.Button actionButton; + android.hardware.input.common.Flag flags; + android.hardware.input.common.PolicyFlag policyFlags; + android.hardware.input.common.EdgeFlag edgeFlags; + android.hardware.input.common.Meta metaState; + android.hardware.input.common.Button buttonState; + float xPrecision; + float yPrecision; + android.hardware.input.common.PointerProperties[] pointerProperties; + android.hardware.input.common.PointerCoords[] pointerCoords; + int deviceTimestamp; + android.hardware.input.common.VideoFrame[] frames; +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl new file mode 100644 index 0000000000..353a106868 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@VintfStability +parcelable PointerCoords { + long bits; + float[] values; +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl new file mode 100644 index 0000000000..a49581b438 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@VintfStability +parcelable PointerProperties { + int id; + android.hardware.input.common.ToolType toolType; +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl new file mode 100644 index 0000000000..247e868fcb --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="int") @VintfStability +enum PolicyFlag { + WAKE = 1, + VIRTUAL = 2, + FUNCTION = 4, + GESTURE = 8, + INJECTED = 16777216, + TRUSTED = 33554432, + FILTERED = 67108864, + DISABLE_KEY_REPEAT = 134217728, + INTERACTIVE = 536870912, + PASS_TO_USER = 1073741824, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl new file mode 100644 index 0000000000..24d02cdbdc --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="int") @VintfStability +enum Source { + UNKNOWN = 0, + KEYBOARD = 257, + DPAD = 513, + GAMEPAD = 1025, + TOUCHSCREEN = 4098, + MOUSE = 8194, + STYLUS = 16386, + BLUETOOTH_STYLUS = 49154, + TRACKBALL = 65540, + MOUSE_RELATIVE = 131076, + TOUCHPAD = 1048584, + TOUCH_NAVIGATION = 2097152, + ROTARY_ENCODER = 4194304, + JOYSTICK = 16777232, + SENSOR = 67108864, + ANY = -256, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl new file mode 100644 index 0000000000..96eede24b0 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="byte") @VintfStability +enum SourceClass { + NONE = 0, + BUTTON = 1, + POINTER = 2, + NAVIGATION = 4, + POSITION = 8, + JOYSTICK = 16, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl new file mode 100644 index 0000000000..ac1b69d74e --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@Backing(type="byte") @VintfStability +enum ToolType { + UNKNOWN = 0, + FINGER = 1, + STYLUS = 2, + MOUSE = 3, + ERASER = 4, +} diff --git a/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl new file mode 100644 index 0000000000..14985c51d5 --- /dev/null +++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.input.common; +@VintfStability +parcelable VideoFrame { + char[] data; + int height; + int width; + long timestamp; +} diff --git a/input/common/aidl/android/hardware/input/common/Action.aidl b/input/common/aidl/android/hardware/input/common/Action.aidl new file mode 100644 index 0000000000..ebe5e676dc --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Action.aidl @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Motion event actions + */ +@VintfStability +@Backing(type="int") +enum Action { + /** + * 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, +} diff --git a/input/common/aidl/android/hardware/input/common/Axis.aidl b/input/common/aidl/android/hardware/input/common/Axis.aidl new file mode 100644 index 0000000000..11509494fa --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Axis.aidl @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Constants that identify each individual axis of a motion event. + * Each value represents a bit position. The user is expected to manually shift + * to the desired position (e.g., 1 << Axis.X) when reading or writing these + * from a bitfield manually. + */ +@VintfStability +@Backing(type="int") +enum Axis { + /** + * 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). + * On game pads with two analog joysticks, this axis is often reinterpreted + * to report the absolute X position of the second joystick instead. + */ + 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, +} diff --git a/input/common/aidl/android/hardware/input/common/Button.aidl b/input/common/aidl/android/hardware/input/common/Button.aidl new file mode 100644 index 0000000000..4bbd5f5a17 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Button.aidl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Buttons that are associated with motion events. + */ +@VintfStability +@Backing(type="int") +enum Button { + 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, +} diff --git a/input/common/aidl/android/hardware/input/common/Classification.aidl b/input/common/aidl/android/hardware/input/common/Classification.aidl new file mode 100644 index 0000000000..f573174e90 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Classification.aidl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Classification of the current gesture, if available. + */ +@VintfStability +@Backing(type="byte") +enum Classification { + 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/input/common/aidl/android/hardware/input/common/EdgeFlag.aidl b/input/common/aidl/android/hardware/input/common/EdgeFlag.aidl new file mode 100644 index 0000000000..8d2263586e --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/EdgeFlag.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Edge flags + */ +@VintfStability +@Backing(type="int") +enum EdgeFlag { + /** + * 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, +} diff --git a/input/common/aidl/android/hardware/input/common/Flag.aidl b/input/common/aidl/android/hardware/input/common/Flag.aidl new file mode 100644 index 0000000000..600bdd3993 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Flag.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Motion event flags + */ +@VintfStability +@Backing(type="int") +enum Flag { + /** + * 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, + /** + * Motion event is inconsistent with previously sent motion events. + */ + TAINTED = 1 << 31, +} diff --git a/input/common/aidl/android/hardware/input/common/Meta.aidl b/input/common/aidl/android/hardware/input/common/Meta.aidl new file mode 100644 index 0000000000..9ccf11b69d --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Meta.aidl @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Meta key / modifier state + */ +@VintfStability +@Backing(type="int") +enum Meta { + NONE = 0, + /** + * One of the ALT meta keys is pressed. + */ + ALT_ON = 1 << 1, + /** + * The left ALT meta key is pressed. + */ + ALT_LEFT_ON = 1 << 4, + /** + * The right ALT meta key is pressed. + */ + ALT_RIGHT_ON = 1 << 5, + /** + * One of the SHIFT meta keys is pressed. + */ + SHIFT_ON = 1 << 0, + /** + * The left SHIFT meta key is pressed. + */ + SHIFT_LEFT_ON = 1 << 6, + /** + * The right SHIFT meta key is pressed. + */ + SHIFT_RIGHT_ON = 1 << 7, + /** + * The SYM meta key is pressed. + */ + SYM_ON = 1 << 2, + /** + * The FUNCTION meta key is pressed. + */ + FUNCTION_ON = 1 << 3, + /** + * One of the CTRL meta keys is pressed. + */ + CTRL_ON = 1 << 12, + /** + * The left CTRL meta key is pressed. + */ + CTRL_LEFT_ON = 1 << 13, + /** + * The right CTRL meta key is pressed. + */ + CTRL_RIGHT_ON = 1 << 14, + /** + * One of the META meta keys is pressed. + */ + META_ON = 1 << 16, + /** + * The left META meta key is pressed. + */ + META_LEFT_ON = 1 << 17, + /** + * The right META meta key is pressed. + */ + META_RIGHT_ON = 1 << 18, + /** + * The CAPS LOCK meta key is on. + */ + CAPS_LOCK_ON = 1 << 20, + /** + * The NUM LOCK meta key is on. + */ + NUM_LOCK_ON = 1 << 21, + /** + * The SCROLL LOCK meta key is on. + */ + SCROLL_LOCK_ON = 1 << 22, +} diff --git a/input/common/aidl/android/hardware/input/common/MotionEvent.aidl b/input/common/aidl/android/hardware/input/common/MotionEvent.aidl new file mode 100644 index 0000000000..dfea7033f2 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/MotionEvent.aidl @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2022 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.common; + +import android.hardware.input.common.Action; +import android.hardware.input.common.Button; +import android.hardware.input.common.EdgeFlag; +import android.hardware.input.common.Flag; +import android.hardware.input.common.Meta; +import android.hardware.input.common.PointerCoords; +import android.hardware.input.common.PointerProperties; +import android.hardware.input.common.PolicyFlag; +import android.hardware.input.common.Source; +import android.hardware.input.common.VideoFrame; + +/** + * Analogous to Android's native MotionEvent / NotifyMotionArgs. + * Stores the basic information about pointer movements. + */ +@VintfStability +parcelable MotionEvent { + /** + * The id of the device which produced this event. + */ + int deviceId; + /** + * The source type of this event. + */ + Source source; + /** + * The display id associated with this event. + */ + int displayId; + /** + * Time when the initial touch down occurred, in nanoseconds. + */ + long downTime; + /** + * Time when this event occurred, in nanoseconds. + */ + long 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. + */ + byte actionIndex; + /** + * The button that has been modified during a press or release action. + */ + Button actionButton; + /** + * The motion event flags. + */ + Flag flags; + /** + * The motion event policy flags. + */ + PolicyFlag policyFlags; + /** + * The edges, if any, that were touched by this motion event. + */ + EdgeFlag edgeFlags; + /** + * The state of any meta / modifier keys that were in effect when the event was generated. + */ + Meta metaState; + /** + * The state of buttons that are pressed. + */ + 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. + */ + PointerProperties[] pointerProperties; + /** + * The coordinates of each pointer. + */ + PointerCoords[] pointerCoords; + /** + * Device time at which the event occurred, in microseconds. + * Will wrap after a little over an hour. + */ + int deviceTimestamp; + /** + * The video frames, if any, associated with the current or previous motion events. + */ + VideoFrame[] frames; +} diff --git a/input/common/aidl/android/hardware/input/common/PointerCoords.aidl b/input/common/aidl/android/hardware/input/common/PointerCoords.aidl new file mode 100644 index 0000000000..56d9a74a4f --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/PointerCoords.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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.common; + +import android.hardware.input.common.Axis; + +/** + * Pointer coordinate data. Analogous to Android's PointerCoords. + */ +@VintfStability +parcelable PointerCoords { + /** + * Bitfield of axes that are present in this structure. + * Each bit position matches an axis defined in Axis.aidl. + */ + long 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. + */ + float[] values; +} diff --git a/input/common/aidl/android/hardware/input/common/PointerProperties.aidl b/input/common/aidl/android/hardware/input/common/PointerProperties.aidl new file mode 100644 index 0000000000..38d815e022 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/PointerProperties.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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.common; + +import android.hardware.input.common.ToolType; + +/** + * Properties of a particular pointer. Analogous to Android's PointerProperties. + */ +@VintfStability +parcelable 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. + */ + int id; + /** + * Type of tool used to make contact, such as a finger or stylus, if known. + */ + ToolType toolType; +} diff --git a/input/common/aidl/android/hardware/input/common/PolicyFlag.aidl b/input/common/aidl/android/hardware/input/common/PolicyFlag.aidl new file mode 100644 index 0000000000..c5edd0d433 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/PolicyFlag.aidl @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Policy flags. + * The values 1 << 4 through 1 << 23 are not currently used. + * When a new value is added, make sure it matches a value defined in Input.h + * and other relevant files in frameworks/base and frameworks/native. + */ +@VintfStability +@Backing(type="int") +enum PolicyFlag { + /** + * 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, + /** + * 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, + /** + * 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, +} diff --git a/input/common/aidl/android/hardware/input/common/Source.aidl b/input/common/aidl/android/hardware/input/common/Source.aidl new file mode 100644 index 0000000000..7eb6d66d64 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/Source.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2022 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.common; + +import android.hardware.input.common.SourceClass; + +/** + * Input sources + */ +@VintfStability +@Backing(type="int") +enum Source { + 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, + SENSOR = (1 << 26) | SourceClass.NONE, + ANY = 0xFFFFFF00, +} diff --git a/input/common/aidl/android/hardware/input/common/SourceClass.aidl b/input/common/aidl/android/hardware/input/common/SourceClass.aidl new file mode 100644 index 0000000000..43157981e3 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/SourceClass.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 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.common; + +@VintfStability +@Backing(type="byte") +enum SourceClass { + NONE = 0 << 0, + BUTTON = 1 << 0, + POINTER = 1 << 1, + NAVIGATION = 1 << 2, + POSITION = 1 << 3, + JOYSTICK = 1 << 4, +} diff --git a/input/common/aidl/android/hardware/input/common/ToolType.aidl b/input/common/aidl/android/hardware/input/common/ToolType.aidl new file mode 100644 index 0000000000..cfa057dc15 --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/ToolType.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Tool type of a pointer + */ +@VintfStability +@Backing(type="byte") +enum ToolType { + UNKNOWN = 0, + FINGER = 1, + STYLUS = 2, + MOUSE = 3, + ERASER = 4, +} diff --git a/input/common/aidl/android/hardware/input/common/VideoFrame.aidl b/input/common/aidl/android/hardware/input/common/VideoFrame.aidl new file mode 100644 index 0000000000..409cee50fc --- /dev/null +++ b/input/common/aidl/android/hardware/input/common/VideoFrame.aidl @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2022 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.common; + +/** + * Touch heatmap. + * + * The array is a 2-D row-major matrix with dimensions (height, width). + * The heatmap data is rotated 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 a 10 x 6 matrix: + * + * <-- width --> + * 0 1 2 3 4 5 ^ + * 6 7 8 9 10 11 | + * 12 13 14 15 16 17 | + * 18 ... 23 | + * 24 ... 29 | height + * 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 height=10 and width=6. + * + * If the screen orientation changes to landscape (a 90 degree orientation + * change), the frame's dimensions will become 6 x 10 + * and the data will look as follows: + * 54 48 42 36 30 24 18 12 6 0 ^ + * ... 13 7 1 | + * ... 14 8 2 | height + * ... 15 9 3 | + * ... 16 10 4 | + * 59 53 47 41 35 29 23 17 11 5 v + * <-- width --> + * + * Here the element "0" is at the physical top left of the unrotated screen. + * + * Since the coordinates of a MotionEvent are also adjusted based on the + * orientation, the rotation of the video frame data ensures that + * the axes for MotionEvent and VideoFrame data are consistent. + */ +@VintfStability +parcelable VideoFrame { + /** + * Video frame data. + * Size of the data is height * width. + */ + char[] data; + int height; + int width; + /** + * Time at which the frame was collected, in nanoseconds. + * Measured with the same clock that is used to populate MotionEvent times. + */ + long timestamp; +} -- cgit v1.2.3 From 37d77dded63f6f4d28a853e459e42939eb308328 Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Thu, 30 Dec 2021 13:14:29 +0800 Subject: Add IGnssAntennaInfo AIDL HAL Bug: 205185369 Test: atest VtsHalGnssTargetTest Change-Id: If269c61b408c2710a4fa224de4d684c99ac5732b --- .../current/android/hardware/gnss/IGnss.aidl | 1 + .../android/hardware/gnss/IGnssAntennaInfo.aidl | 39 ++++++ .../hardware/gnss/IGnssAntennaInfoCallback.aidl | 60 +++++++++ gnss/aidl/android/hardware/gnss/IGnss.aidl | 8 ++ .../android/hardware/gnss/IGnssAntennaInfo.aidl | 41 ++++++ .../hardware/gnss/IGnssAntennaInfoCallback.aidl | 140 +++++++++++++++++++ gnss/aidl/android/hardware/gnss/IGnssCallback.aidl | 2 +- gnss/aidl/default/Android.bp | 1 + gnss/aidl/default/Gnss.cpp | 12 +- gnss/aidl/default/Gnss.h | 3 + gnss/aidl/default/GnssAntennaInfo.cpp | 149 +++++++++++++++++++++ gnss/aidl/default/GnssAntennaInfo.h | 51 +++++++ gnss/aidl/vts/Android.bp | 1 + gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp | 26 ++++ gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h | 36 +++++ gnss/aidl/vts/gnss_hal_test_cases.cpp | 85 ++++++++++++ 16 files changed, 653 insertions(+), 2 deletions(-) create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfoCallback.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl create mode 100644 gnss/aidl/default/GnssAntennaInfo.cpp create mode 100644 gnss/aidl/default/GnssAntennaInfo.h create mode 100644 gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp create mode 100644 gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl index 1b4c5817ce..281c531977 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl @@ -53,6 +53,7 @@ interface IGnss { void injectBestLocation(in android.hardware.gnss.GnssLocation location); void deleteAidingData(in android.hardware.gnss.IGnss.GnssAidingData aidingDataFlags); void setPositionMode(in android.hardware.gnss.IGnss.GnssPositionMode mode, in android.hardware.gnss.IGnss.GnssPositionRecurrence recurrence, in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs, in boolean lowPowerMode); + android.hardware.gnss.IGnssAntennaInfo getExtensionGnssAntennaInfo(); const int ERROR_INVALID_ARGUMENT = 1; const int ERROR_ALREADY_INIT = 2; const int ERROR_GENERIC = 3; diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.aidl new file mode 100644 index 0000000000..2734ac1d69 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +interface IGnssAntennaInfo { + void setCallback(in android.hardware.gnss.IGnssAntennaInfoCallback callback); + void close(); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfoCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfoCallback.aidl new file mode 100644 index 0000000000..ada97077e7 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfoCallback.aidl @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +interface IGnssAntennaInfoCallback { + void gnssAntennaInfoCb(in android.hardware.gnss.IGnssAntennaInfoCallback.GnssAntennaInfo[] gnssAntennaInfos); + @VintfStability + parcelable Row { + double[] row; + } + @VintfStability + parcelable Coord { + double x; + double xUncertainty; + double y; + double yUncertainty; + double z; + double zUncertainty; + } + @VintfStability + parcelable GnssAntennaInfo { + long carrierFrequencyHz; + android.hardware.gnss.IGnssAntennaInfoCallback.Coord phaseCenterOffsetCoordinateMillimeters; + android.hardware.gnss.IGnssAntennaInfoCallback.Row[] phaseCenterVariationCorrectionMillimeters; + android.hardware.gnss.IGnssAntennaInfoCallback.Row[] phaseCenterVariationCorrectionUncertaintyMillimeters; + android.hardware.gnss.IGnssAntennaInfoCallback.Row[] signalGainCorrectionDbi; + android.hardware.gnss.IGnssAntennaInfoCallback.Row[] signalGainCorrectionUncertaintyDbi; + } +} diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index 4ddc6a6193..e1d46703fa 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -18,6 +18,7 @@ package android.hardware.gnss; import android.hardware.gnss.GnssLocation; import android.hardware.gnss.IAGnss; +import android.hardware.gnss.IGnssAntennaInfo; import android.hardware.gnss.IGnssBatching; import android.hardware.gnss.IGnssCallback; import android.hardware.gnss.IGnssConfiguration; @@ -277,4 +278,11 @@ interface IGnss { void setPositionMode(in GnssPositionMode mode, in GnssPositionRecurrence recurrence, in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs, in boolean lowPowerMode); + + /* + * This method returns the IGnssAntennaInfo. + * + * @return Handle to the IGnssAntennaInfo. + */ + IGnssAntennaInfo getExtensionGnssAntennaInfo(); } diff --git a/gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.aidl b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.aidl new file mode 100644 index 0000000000..de83b67bd6 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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; + +import android.hardware.gnss.IGnssAntennaInfoCallback; + +/** + * Extended interface for GNSS antenna information support. + */ +@VintfStability +interface IGnssAntennaInfo { + /** + * Registers the callback routines with the HAL. + * + * @param callback Handle to the GnssAntennaInfo callback interface. + */ + void setCallback(in IGnssAntennaInfoCallback callback); + + /** + * Stops updates from the HAL, and unregisters the callback routines. + * After a call to close(), the previously registered callbacks must be + * considered invalid by the HAL. + * If close() is invoked without a previous setCallback, this function must perform + * no work. + */ + void close(); +} diff --git a/gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl new file mode 100644 index 0000000000..ef0a7fc6fd --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2021 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; + +/** + * The callback interface to report GNSS antenna information from the HAL. + */ +@VintfStability +interface IGnssAntennaInfoCallback { + /** + * A row of doubles. This is used to represent a row in a 2D array, which are used to + * characterize the phase center variation corrections and signal gain corrections. + */ + @VintfStability + parcelable Row { + double[] row; + } + + /** + * A point in 3D space, with associated uncertainty. + */ + @VintfStability + parcelable Coord { + double x; + + double xUncertainty; + + double y; + + double yUncertainty; + + double z; + + double zUncertainty; + } + + @VintfStability + parcelable GnssAntennaInfo { + /** + * The carrier frequency in Hz. + */ + long carrierFrequencyHz; + + /** + * Phase center offset (PCO) with associated 1-sigma uncertainty. PCO is defined with + * respect to the origin of the Android sensor coordinate system, e.g., center of primary + * screen for mobiles - see sensor or form factor documents for details. + */ + Coord phaseCenterOffsetCoordinateMillimeters; + + /** + * 2D vectors representing the phase center variation (PCV) corrections, in + * millimeters, at regularly spaced azimuthal angle (theta) and zenith angle + * (phi). The PCV correction is added to the phase measurement to obtain the + * corrected value. + * + * The azimuthal angle, theta, is defined with respect to the X axis of the + * Android sensor coordinate system, increasing toward the Y axis. The zenith + * angle, phi, is defined with respect to the Z axis of the Android Sensor + * coordinate system, increasing toward the X-Y plane. + * + * Each row vector (outer vectors) represents a fixed theta. The first row + * corresponds to a theta angle of 0 degrees. The last row corresponds to a + * theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular + * spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows). + * + * The columns (inner vectors) represent fixed zenith angles, beginning at 0 + * degrees and ending at 180 degrees. They are separated by deltaPhi, the regular + * spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1). + * + * This field is optional, i.e., an empty vector. + */ + Row[] phaseCenterVariationCorrectionMillimeters; + + /** + * 2D vectors of 1-sigma uncertainty in millimeters associated with the PCV + * correction values. + * + * This field is optional, i.e., an empty vector. + */ + Row[] phaseCenterVariationCorrectionUncertaintyMillimeters; + + /** + * 2D vectors representing the signal gain corrections at regularly spaced + * azimuthal angle (theta) and zenith angle (phi). The values are calculated or + * measured at the antenna feed point without considering the radio and receiver + * noise figure and path loss contribution, in dBi, i.e., decibel over isotropic + * antenna with the same total power. The signal gain correction is added the + * signal gain measurement to obtain the corrected value. + * + * The azimuthal angle, theta, is defined with respect to the X axis of the + * Android sensor coordinate system, increasing toward the Y axis. The zenith + * angle, phi, is defined with respect to the Z axis of the Android Sensor + * coordinate system, increasing toward the X-Y plane. + * + * Each row vector (outer vectors) represents a fixed theta. The first row + * corresponds to a theta angle of 0 degrees. The last row corresponds to a + * theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular + * spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows). + * + * The columns (inner vectors) represent fixed zenith angles, beginning at 0 + * degrees and ending at 180 degrees. They are separated by deltaPhi, the regular + * spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1). + * + * This field is optional, i.e., an empty vector. + */ + Row[] signalGainCorrectionDbi; + + /** + * 2D vectors of 1-sigma uncertainty in dBi associated with the signal + * gain correction values. + * + * This field is optional, i.e., an empty vector. + */ + Row[] signalGainCorrectionUncertaintyDbi; + } + + /** + * Called when on connection, and on known-change to these values, such as upon a known + * GNSS RF antenna tuning change, or a foldable device state change. + * + * This is optional. It can never be called if the GNSS antenna information is not + * available. + */ + void gnssAntennaInfoCb(in GnssAntennaInfo[] gnssAntennaInfos); +} diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl index 157c912054..a74d097ad6 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl @@ -67,7 +67,7 @@ interface IGnssCallback { /** Capability bit mask indicating that GNSS supports measurement corrections */ const int CAPABILITY_MEASUREMENT_CORRECTIONS = 1 << 10; - /** Capability bit mask indicating that GNSS supports measurement corrections */ + /** Capability bit mask indicating that GNSS supports antenna info */ const int CAPABILITY_ANTENNA_INFO = 1 << 11; /** Capability bit mask indicating that GNSS supports correlation vector */ diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 29c26d16ec..6168ad5f33 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -58,6 +58,7 @@ cc_binary { srcs: [ "AGnss.cpp", "Gnss.cpp", + "GnssAntennaInfo.cpp", "GnssBatching.cpp", "GnssDebug.cpp", "GnssGeofence.cpp", diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index 657877898f..2c6df995f1 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -21,6 +21,7 @@ #include #include "AGnss.h" #include "DeviceFileReader.h" +#include "GnssAntennaInfo.h" #include "GnssBatching.h" #include "GnssConfiguration.h" #include "GnssDebug.h" @@ -56,7 +57,8 @@ ScopedAStatus Gnss::setCallback(const std::shared_ptr& callback) int capabilities = (int)(IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST | IGnssCallback::CAPABILITY_SATELLITE_PVT | - IGnssCallback::CAPABILITY_CORRELATION_VECTOR); + IGnssCallback::CAPABILITY_CORRELATION_VECTOR | + IGnssCallback::CAPABILITY_ANTENNA_INFO); auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities); if (!status.isOk()) { @@ -279,4 +281,12 @@ ndk::ScopedAStatus Gnss::getExtensionGnssVisibilityControl( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Gnss::getExtensionGnssAntennaInfo( + std::shared_ptr* iGnssAntennaInfo) { + ALOGD("Gnss::getExtensionGnssAntennaInfo"); + + *iGnssAntennaInfo = SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index f21d756c24..b92f4fb9ba 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -69,6 +70,8 @@ class Gnss : public BnGnss { ndk::ScopedAStatus getExtensionGnssVisibilityControl( std::shared_ptr* iGnssVisibilityControl) override; + ndk::ScopedAStatus getExtensionGnssAntennaInfo( + std::shared_ptr* iGnssAntennaInfo) override; std::shared_ptr mGnssConfiguration; std::shared_ptr mGnssPowerIndication; diff --git a/gnss/aidl/default/GnssAntennaInfo.cpp b/gnss/aidl/default/GnssAntennaInfo.cpp new file mode 100644 index 0000000000..72def716de --- /dev/null +++ b/gnss/aidl/default/GnssAntennaInfo.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2021 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 "GnssAntennaInfoAidl" + +#include "GnssAntennaInfo.h" +#include +#include +#include "Utils.h" + +namespace aidl::android::hardware::gnss { + +using namespace ::android::hardware::gnss; +using Row = IGnssAntennaInfoCallback::Row; +using Coord = IGnssAntennaInfoCallback::Coord; + +std::shared_ptr GnssAntennaInfo::sCallback = nullptr; + +GnssAntennaInfo::GnssAntennaInfo() : mMinIntervalMs(1000) {} + +GnssAntennaInfo::~GnssAntennaInfo() { + stop(); +} + +// Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow. +ndk::ScopedAStatus GnssAntennaInfo::setCallback( + const std::shared_ptr& callback) { + ALOGD("setCallback"); + std::unique_lock lock(mMutex); + sCallback = callback; + + if (mIsActive) { + ALOGW("GnssAntennaInfo callback already set. Resetting the callback..."); + stop(); + } + start(); + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus GnssAntennaInfo::close() { + ALOGD("close"); + stop(); + std::unique_lock lock(mMutex); + sCallback = nullptr; + return ndk::ScopedAStatus::ok(); +} + +void GnssAntennaInfo::start() { + ALOGD("start"); + mIsActive = true; + mThread = std::thread([this]() { + while (mIsActive == true) { + if (sCallback != nullptr) { + IGnssAntennaInfoCallback::GnssAntennaInfo mockAntennaInfo_1 = { + .carrierFrequencyHz = 1575420000, + .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 1, + .xUncertainty = 0.1, + .y = 2, + .yUncertainty = 0.1, + .z = 3, + .zUncertainty = 0.1}, + .phaseCenterVariationCorrectionMillimeters = + { + Row{std::vector{1, -1, 5, -2, 3, -1}}, + Row{std::vector{-2, 3, 2, 0, 1, 2}}, + Row{std::vector{1, 3, 2, -1, -3, 5}}, + }, + .phaseCenterVariationCorrectionUncertaintyMillimeters = + { + Row{std::vector{0.1, 0.2, 0.4, 0.1, 0.2, 0.3}}, + Row{std::vector{0.3, 0.2, 0.3, 0.6, 0.1, 0.1}}, + Row{std::vector{0.1, 0.1, 0.4, 0.2, 0.5, 0.3}}, + }, + .signalGainCorrectionDbi = + { + Row{std::vector{2, -3, 1, -3, 0, -4}}, + Row{std::vector{1, 0, -4, 1, 3, -2}}, + Row{std::vector{3, -2, 0, -2, 3, 0}}, + }, + .signalGainCorrectionUncertaintyDbi = + { + Row{std::vector{0.3, 0.1, 0.2, 0.6, 0.1, 0.3}}, + Row{std::vector{0.1, 0.1, 0.5, 0.2, 0.3, 0.1}}, + Row{std::vector{0.2, 0.4, 0.2, 0.1, 0.1, 0.2}}, + }, + }; + + IGnssAntennaInfoCallback::GnssAntennaInfo mockAntennaInfo_2 = { + .carrierFrequencyHz = 1176450000, + .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 5, + .xUncertainty = 0.1, + .y = 6, + .yUncertainty = 0.1, + .z = 7, + .zUncertainty = 0.1}, + }; + + std::vector mockAntennaInfos = { + mockAntennaInfo_1, + mockAntennaInfo_2, + }; + this->reportAntennaInfo(mockAntennaInfos); + } + + /** For mock implementation this is good. On real device, we should only report + antennaInfo at start and when there is a configuration change. **/ + std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); + } + }); +} + +void GnssAntennaInfo::stop() { + ALOGD("stop"); + mIsActive = false; + if (mThread.joinable()) { + mThread.join(); + } +} + +void GnssAntennaInfo::reportAntennaInfo( + const std::vector& antennaInfo) const { + std::unique_lock lock(mMutex); + + if (sCallback == nullptr) { + ALOGE("%s: No non-null callback", __func__); + return; + } + + auto ret = sCallback->gnssAntennaInfoCb(antennaInfo); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } +} + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssAntennaInfo.h b/gnss/aidl/default/GnssAntennaInfo.h new file mode 100644 index 0000000000..2cf7b1366b --- /dev/null +++ b/gnss/aidl/default/GnssAntennaInfo.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +namespace aidl::android::hardware::gnss { + +struct GnssAntennaInfo : public BnGnssAntennaInfo { + public: + GnssAntennaInfo(); + ~GnssAntennaInfo(); + ndk::ScopedAStatus setCallback( + const std::shared_ptr& callback) override; + ndk::ScopedAStatus close() override; + + private: + void start(); + void stop(); + void reportAntennaInfo( + const std::vector& antennaInfo) const; + + // Guarded by mMutex + static std::shared_ptr sCallback; + + std::atomic mIsActive; + std::atomic mMinIntervalMs; + std::thread mThread; + + // Synchronization lock for sCallback + mutable std::mutex mMutex; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index d532fad357..6045b0e38d 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -31,6 +31,7 @@ cc_test { "gnss_hal_test.cpp", "gnss_hal_test_cases.cpp", "AGnssCallbackAidl.cpp", + "GnssAntennaInfoCallbackAidl.cpp", "GnssBatchingCallback.cpp", "GnssCallbackAidl.cpp", "GnssGeofenceCallback.cpp", diff --git a/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp new file mode 100644 index 0000000000..11001cde89 --- /dev/null +++ b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2021 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 "GnssAntennaInfoCallbackAidl.h" +#include +#include + +android::binder::Status GnssAntennaInfoCallbackAidl::gnssAntennaInfoCb( + const std::vector& gnssAntennaInfos) { + ALOGD("GnssAntennaInfo received. Size = %d", (int)gnssAntennaInfos.size()); + antenna_info_cbq_.store(gnssAntennaInfos); + return android::binder::Status::ok(); +} diff --git a/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h new file mode 100644 index 0000000000..77e105797a --- /dev/null +++ b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include "GnssCallbackEventQueue.h" + +/** Implementation for IGnssAntennaInfoCallback. */ +class GnssAntennaInfoCallbackAidl : public android::hardware::gnss::BnGnssAntennaInfoCallback { + public: + GnssAntennaInfoCallbackAidl() : antenna_info_cbq_("info"){}; + ~GnssAntennaInfoCallbackAidl(){}; + + android::binder::Status gnssAntennaInfoCb( + const std::vector& gnssAntennaInfos) + override; + + android::hardware::gnss::common::GnssCallbackEventQueue< + std::vector> + antenna_info_cbq_; +}; diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index eec50b0a13..0d85ffe9c3 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include "AGnssCallbackAidl.h" +#include "GnssAntennaInfoCallbackAidl.h" #include "GnssBatchingCallback.h" #include "GnssGeofenceCallback.h" #include "GnssMeasurementCallbackAidl.h" @@ -44,6 +46,8 @@ using android::hardware::gnss::GnssMeasurement; using android::hardware::gnss::GnssPowerStats; using android::hardware::gnss::IAGnss; using android::hardware::gnss::IGnss; +using android::hardware::gnss::IGnssAntennaInfo; +using android::hardware::gnss::IGnssAntennaInfoCallback; using android::hardware::gnss::IGnssBatching; using android::hardware::gnss::IGnssBatchingCallback; using android::hardware::gnss::IGnssCallback; @@ -1009,3 +1013,84 @@ TEST_P(GnssHalTest, TestGnssAgcInGnssMeasurement) { status = iGnssMeasurement->close(); ASSERT_TRUE(status.isOk()); } + +/* + * TestGnssAntennaInfo: + * Sets a GnssAntennaInfoCallback, waits for report, and verifies + * 1. phaseCenterOffsetCoordinateMillimeters is valid + * 2. phaseCenterOffsetCoordinateUncertaintyMillimeters is valid. + * PhaseCenterVariationCorrections and SignalGainCorrections are optional. + */ +TEST_P(GnssHalTest, TestGnssAntennaInfo) { + const int kAntennaInfoTimeoutSeconds = 2; + + if (aidl_gnss_hal_->getInterfaceVersion() == 1) { + return; + } + + sp iGnssAntennaInfo; + auto status = aidl_gnss_hal_->getExtensionGnssAntennaInfo(&iGnssAntennaInfo); + ASSERT_TRUE(status.isOk()); + + if (!(aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_ANTENNA_INFO) || + iGnssAntennaInfo == nullptr) { + ALOGD("GnssAntennaInfo AIDL is not supported."); + return; + } + + auto callback = sp::make(); + status = iGnssAntennaInfo->setCallback(callback); + ASSERT_TRUE(status.isOk()); + + std::vector antennaInfos; + ASSERT_TRUE(callback->antenna_info_cbq_.retrieve(antennaInfos, kAntennaInfoTimeoutSeconds)); + EXPECT_EQ(callback->antenna_info_cbq_.calledCount(), 1); + ASSERT_TRUE(antennaInfos.size() > 0); + + for (auto antennaInfo : antennaInfos) { + // Remaining fields are optional + if (!antennaInfo.phaseCenterVariationCorrectionMillimeters.empty()) { + int numRows = antennaInfo.phaseCenterVariationCorrectionMillimeters.size(); + int numColumns = antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size(); + // Must have at least 1 row and 2 columns + ASSERT_TRUE(numRows >= 1 && numColumns >= 2); + + // Corrections and uncertainties must have same dimensions + ASSERT_TRUE(antennaInfo.phaseCenterVariationCorrectionMillimeters.size() == + antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.size()); + ASSERT_TRUE( + antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size() == + antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters[0].row.size()); + + // Must be rectangular + for (auto row : antennaInfo.phaseCenterVariationCorrectionMillimeters) { + ASSERT_TRUE(row.row.size() == numColumns); + } + for (auto row : antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters) { + ASSERT_TRUE(row.row.size() == numColumns); + } + } + if (!antennaInfo.signalGainCorrectionDbi.empty()) { + int numRows = antennaInfo.signalGainCorrectionDbi.size(); + int numColumns = antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size(); + // Must have at least 1 row and 2 columns + ASSERT_TRUE(numRows >= 1 && numColumns >= 2); + + // Corrections and uncertainties must have same dimensions + ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi.size() == + antennaInfo.signalGainCorrectionUncertaintyDbi.size()); + ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi[0].row.size() == + antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size()); + + // Must be rectangular + for (auto row : antennaInfo.signalGainCorrectionDbi) { + ASSERT_TRUE(row.row.size() == numColumns); + } + for (auto row : antennaInfo.signalGainCorrectionUncertaintyDbi) { + ASSERT_TRUE(row.row.size() == numColumns); + } + } + } + + iGnssAntennaInfo->close(); +} -- cgit v1.2.3 From 20bac52a5b9b18789ba4ccad986cdf3effd0bd86 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Wed, 29 Dec 2021 23:52:39 -0800 Subject: Add Bluetooth Audio AIDL utils Test: manual Bug: 203490261 Change-Id: Ia299a61e89273ea1c9d132425598975418f57a03 --- bluetooth/audio/utils/Android.bp | 25 + .../utils/aidl_session/BluetoothAudioCodecs.cpp | 489 +++++++++++++ .../utils/aidl_session/BluetoothAudioCodecs.h | 88 +++ .../utils/aidl_session/BluetoothAudioSession.cpp | 581 +++++++++++++++ .../utils/aidl_session/BluetoothAudioSession.h | 227 ++++++ .../aidl_session/BluetoothAudioSessionControl.h | 182 +++++ .../aidl_session/BluetoothAudioSessionReport.h | 87 +++ .../utils/aidl_session/HidlToAidlMiddleware.cpp | 775 +++++++++++++++++++++ .../utils/aidl_session/HidlToAidlMiddleware_2_0.h | 73 ++ .../utils/aidl_session/HidlToAidlMiddleware_2_1.h | 42 ++ .../utils/aidl_session/HidlToAidlMiddleware_2_2.h | 65 ++ .../audio/utils/session/BluetoothAudioSession.cpp | 30 + .../utils/session/BluetoothAudioSession_2_1.cpp | 8 + .../utils/session/BluetoothAudioSession_2_1.h | 1 + .../utils/session/BluetoothAudioSession_2_2.cpp | 25 + .../utils/session/BluetoothAudioSession_2_2.h | 1 + 16 files changed, 2699 insertions(+) create mode 100644 bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp create mode 100644 bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h create mode 100644 bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp create mode 100644 bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h create mode 100644 bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h create mode 100644 bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h create mode 100644 bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp create mode 100644 bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h create mode 100644 bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h create mode 100644 bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp index 4f712bffab..974357e278 100644 --- a/bluetooth/audio/utils/Android.bp +++ b/bluetooth/audio/utils/Android.bp @@ -32,5 +32,30 @@ cc_library_shared { "libhidlbase", "liblog", "libutils", + "libbluetooth_audio_session_aidl", + ], +} + +cc_library_shared { + name: "libbluetooth_audio_session_aidl", + vendor: true, + srcs: [ + "aidl_session/BluetoothAudioCodecs.cpp", + "aidl_session/BluetoothAudioSession.cpp", + "aidl_session/HidlToAidlMiddleware.cpp", + ], + export_include_dirs: ["aidl_session/"], + header_libs: ["libhardware_headers"], + shared_libs: [ + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "android.hardware.bluetooth.audio@2.2", + "libbase", + "libcutils", + "libbinder_ndk", + "libfmq", + "liblog", + "android.hardware.bluetooth.audio-V1-ndk", + "libhidlbase", ], } diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp new file mode 100644 index 0000000000..92cd0f5b14 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp @@ -0,0 +1,489 @@ +/* + * Copyright (C) 2022 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 "BTAudioCodecsAidl" + +#include "BluetoothAudioCodecs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +static const PcmCapabilities kDefaultSoftwarePcmCapabilities = { + .sampleRateHz = {16000, 24000, 44100, 48000, 88200, 96000}, + .channelMode = {ChannelMode::MONO, ChannelMode::STEREO}, + .bitsPerSample = {16, 24, 32}, + .dataIntervalUs = {}, +}; + +static const SbcCapabilities kDefaultOffloadSbcCapability = { + .sampleRateHz = {44100}, + .channelMode = {SbcChannelMode::MONO, SbcChannelMode::JOINT_STEREO}, + .blockLength = {4, 8, 12, 16}, + .numSubbands = {8}, + .allocMethod = {SbcAllocMethod::ALLOC_MD_L}, + .bitsPerSample = {16}, + .minBitpool = 2, + .maxBitpool = 53}; + +static const AacCapabilities kDefaultOffloadAacCapability = { + .objectType = {AacObjectType::MPEG2_LC}, + .sampleRateHz = {44100}, + .channelMode = {ChannelMode::STEREO}, + .variableBitRateSupported = true, + .bitsPerSample = {16}}; + +static const LdacCapabilities kDefaultOffloadLdacCapability = { + .sampleRateHz = {44100, 48000, 88200, 96000}, + .channelMode = {LdacChannelMode::DUAL, LdacChannelMode::STEREO}, + .qualityIndex = {LdacQualityIndex::HIGH}, + .bitsPerSample = {16, 24, 32}}; + +static const AptxCapabilities kDefaultOffloadAptxCapability = { + .sampleRateHz = {44100, 48000}, + .channelMode = {ChannelMode::STEREO}, + .bitsPerSample = {16}, +}; + +static const AptxCapabilities kDefaultOffloadAptxHdCapability = { + .sampleRateHz = {44100, 48000}, + .channelMode = {ChannelMode::STEREO}, + .bitsPerSample = {24}, +}; + +static const Lc3Capabilities kDefaultOffloadLc3Capability = { + .samplingFrequencyHz = {44100, 48000}, + .frameDurationUs = {7500, 10000}, + .channelMode = {ChannelMode::MONO, ChannelMode::STEREO}, +}; + +const std::vector kDefaultOffloadA2dpCodecCapabilities = { + {.codecType = CodecType::SBC, .capabilities = {}}, + {.codecType = CodecType::AAC, .capabilities = {}}, + {.codecType = CodecType::LDAC, .capabilities = {}}, + {.codecType = CodecType::APTX, .capabilities = {}}, + {.codecType = CodecType::APTX_HD, .capabilities = {}}, + {.codecType = CodecType::LC3, .capabilities = {}}}; + +std::vector kDefaultOffloadLeAudioCapabilities; + +static const UnicastCapability kInvalidUnicastCapability = { + .codecType = CodecType::UNKNOWN}; + +static const BroadcastCapability kInvalidBroadcastCapability = { + .codecType = CodecType::UNKNOWN}; + +// Default Supported Codecs +// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30 +static const Lc3Capabilities kLc3Capability_16_1 = { + .samplingFrequencyHz = {16000}, + .frameDurationUs = {7500}, + .octetsPerFrame = {30}}; + +// Default Supported Codecs +// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40 +static const Lc3Capabilities kLc3Capability_16_2 = { + .samplingFrequencyHz = {16000}, + .frameDurationUs = {10000}, + .octetsPerFrame = {40}}; + +// Default Supported Codecs +// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120 +static const Lc3Capabilities kLc3Capability_48_4 = { + .samplingFrequencyHz = {48000}, + .frameDurationUs = {10000}, + .octetsPerFrame = {120}}; + +static const std::vector supportedLc3CapabilityList = { + kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1}; + +static AudioLocation stereoAudio = static_cast( + static_cast(AudioLocation::FRONT_LEFT) | + static_cast(AudioLocation::FRONT_RIGHT)); +static AudioLocation monoAudio = AudioLocation::UNKNOWN; + +// Stores the supported setting of audio location, connected device, and the +// channel count for each device +std::vector> + supportedDeviceSetting = {std::make_tuple(stereoAudio, 2, 1), + std::make_tuple(monoAudio, 1, 2), + std::make_tuple(monoAudio, 1, 1)}; + +template +bool BluetoothAudioCodecs::ContainedInVector( + const std::vector& vector, const typename identity::type& target) { + return std::find(vector.begin(), vector.end(), target) != vector.end(); +} + +bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const SbcConfiguration sbc_data = + codec_specific.get(); + + if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz, + sbc_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadSbcCapability.blockLength, + sbc_data.blockLength) && + ContainedInVector(kDefaultOffloadSbcCapability.numSubbands, + sbc_data.numSubbands) && + ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample, + sbc_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadSbcCapability.channelMode, + sbc_data.channelMode) && + ContainedInVector(kDefaultOffloadSbcCapability.allocMethod, + sbc_data.allocMethod) && + sbc_data.minBitpool <= sbc_data.maxBitpool && + kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool && + kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const AacConfiguration aac_data = + codec_specific.get(); + + if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz, + aac_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample, + aac_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadAacCapability.channelMode, + aac_data.channelMode) && + ContainedInVector(kDefaultOffloadAacCapability.objectType, + aac_data.objectType) && + (!aac_data.variableBitRateEnabled || + kDefaultOffloadAacCapability.variableBitRateSupported)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != + CodecConfiguration::CodecSpecific::ldacConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const LdacConfiguration ldac_data = + codec_specific.get(); + + if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz, + ldac_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample, + ldac_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadLdacCapability.channelMode, + ldac_data.channelMode) && + ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex, + ldac_data.qualityIndex)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != + CodecConfiguration::CodecSpecific::aptxConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const AptxConfiguration aptx_data = + codec_specific.get(); + + if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz, + aptx_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample, + aptx_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadAptxCapability.channelMode, + aptx_data.channelMode)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != + CodecConfiguration::CodecSpecific::aptxConfig) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const AptxConfiguration aptx_data = + codec_specific.get(); + + if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz, + aptx_data.sampleRateHz) && + ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample, + aptx_data.bitsPerSample) && + ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode, + aptx_data.channelMode)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadLc3ConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific) { + if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::lc3Config) { + LOG(WARNING) << __func__ + << ": Invalid CodecSpecific=" << codec_specific.toString(); + return false; + } + const Lc3Configuration lc3_data = + codec_specific.get(); + + if (ContainedInVector(kDefaultOffloadLc3Capability.samplingFrequencyHz, + lc3_data.samplingFrequencyHz) && + ContainedInVector(kDefaultOffloadLc3Capability.frameDurationUs, + lc3_data.frameDurationUs) && + ContainedInVector(kDefaultOffloadLc3Capability.channelMode, + lc3_data.channelMode)) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << codec_specific.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid( + const SessionType& session_type, const LeAudioConfiguration&) { + if (session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && + session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { + return false; + } + return true; +} + +std::vector +BluetoothAudioCodecs::GetSoftwarePcmCapabilities() { + return {kDefaultSoftwarePcmCapabilities}; +} + +std::vector +BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities( + const SessionType& session_type) { + if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return {}; + } + std::vector offload_a2dp_codec_capabilities = + kDefaultOffloadA2dpCodecCapabilities; + for (auto& codec_capability : offload_a2dp_codec_capabilities) { + switch (codec_capability.codecType) { + case CodecType::SBC: + codec_capability.capabilities + .set( + kDefaultOffloadSbcCapability); + break; + case CodecType::AAC: + codec_capability.capabilities + .set( + kDefaultOffloadAacCapability); + break; + case CodecType::LDAC: + codec_capability.capabilities + .set( + kDefaultOffloadLdacCapability); + break; + case CodecType::APTX: + codec_capability.capabilities + .set( + kDefaultOffloadAptxCapability); + break; + case CodecType::APTX_HD: + codec_capability.capabilities + .set( + kDefaultOffloadAptxHdCapability); + break; + case CodecType::LC3: + codec_capability.capabilities + .set( + kDefaultOffloadLc3Capability); + break; + case CodecType::UNKNOWN: + codec_capability = {}; + break; + } + } + return offload_a2dp_codec_capabilities; +} + +bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid( + const PcmConfiguration& pcm_config) { + if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz, + pcm_config.sampleRateHz) && + ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample, + pcm_config.bitsPerSample) && + ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode, + pcm_config.channelMode) + // data interval is not checked for now + // && pcm_config.dataIntervalUs != 0 + ) { + return true; + } + LOG(WARNING) << __func__ + << ": Unsupported CodecSpecific=" << pcm_config.toString(); + return false; +} + +bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid( + const SessionType& session_type, const CodecConfiguration& codec_config) { + if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + LOG(ERROR) << __func__ + << ": Invalid SessionType=" << toString(session_type); + return false; + } + const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config; + switch (codec_config.codecType) { + case CodecType::SBC: + if (IsOffloadSbcConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::AAC: + if (IsOffloadAacConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::LDAC: + if (IsOffloadLdacConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::APTX: + if (IsOffloadAptxConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::APTX_HD: + if (IsOffloadAptxHdConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::LC3: + if (IsOffloadLc3ConfigurationValid(codec_specific)) { + return true; + } + break; + case CodecType::UNKNOWN: + break; + } + return false; +} + +UnicastCapability composeUnicastLc3Capability( + AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount, + const Lc3Capabilities& capability) { + return { + .codecType = CodecType::LC3, + .supportedChannel = audioLocation, + .deviceCount = deviceCnt, + .channelCountPerDevice = channelCount, + .leAudioCodecCapabilities = + UnicastCapability::LeAudioCodecCapabilities(capability), + }; +} + +std::vector +BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities( + const SessionType& session_type) { + if (session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && + session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { + return std::vector(0); + } + + if (kDefaultOffloadLeAudioCapabilities.empty()) { + for (auto [audioLocation, deviceCnt, channelCount] : + supportedDeviceSetting) { + for (auto capability : supportedLc3CapabilityList) { + UnicastCapability lc3Capability = composeUnicastLc3Capability( + audioLocation, deviceCnt, channelCount, capability); + UnicastCapability lc3MonoDecodeCapability = + composeUnicastLc3Capability(monoAudio, 1, 1, capability); + + // Adds the capability for encode only + kDefaultOffloadLeAudioCapabilities.push_back( + {.unicastEncodeCapability = lc3Capability, + .unicastDecodeCapability = kInvalidUnicastCapability, + .broadcastCapability = kInvalidBroadcastCapability}); + + // Adds the capability for decode only + kDefaultOffloadLeAudioCapabilities.push_back( + {.unicastEncodeCapability = kInvalidUnicastCapability, + .unicastDecodeCapability = lc3Capability, + .broadcastCapability = kInvalidBroadcastCapability}); + + // Adds the capability for the case that encode and decode exist at the + // same time + kDefaultOffloadLeAudioCapabilities.push_back( + {.unicastEncodeCapability = lc3Capability, + .unicastDecodeCapability = lc3MonoDecodeCapability, + .broadcastCapability = kInvalidBroadcastCapability}); + } + } + } + + return kDefaultOffloadLeAudioCapabilities; +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h new file mode 100644 index 0000000000..c542ce5be7 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioCodecs { + public: + static std::vector GetSoftwarePcmCapabilities(); + static std::vector GetA2dpOffloadCodecCapabilities( + const SessionType& session_type); + + static bool IsSoftwarePcmConfigurationValid( + const PcmConfiguration& pcm_config); + static bool IsOffloadCodecConfigurationValid( + const SessionType& session_type, const CodecConfiguration& codec_config); + + static bool IsOffloadLeAudioConfigurationValid( + const SessionType& session_type, const Lc3Configuration& codec_config); + + static bool IsOffloadLeAudioConfigurationValid( + const SessionType& session_type, + const LeAudioConfiguration& codec_config); + + static std::vector + GetLeAudioOffloadCodecCapabilities(const SessionType& session_type); + + private: + template + struct identity { + typedef T type; + }; + template + static bool ContainedInVector(const std::vector& vector, + const typename identity::type& target); + template + static bool ContainedInBitmask(const T& bitmask, const T& target); + static bool IsSingleBit(uint32_t bitmasks, uint32_t bitfield); + static bool IsOffloadSbcConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadAacConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadLdacConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadAptxConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadAptxHdConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadLc3ConfigurationValid( + const CodecConfiguration::CodecSpecific& codec_specific); + static bool IsOffloadLeAudioConfigurationValid( + const SessionType& session_type, const LeAudioCodecConfiguration&); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp new file mode 100644 index 0000000000..95e473e5b9 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp @@ -0,0 +1,581 @@ +/* + * Copyright (C) 2022 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 +#define LOG_TAG "BTAudioSessionAidl" + +#include +#include +#include + +#include "BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +static constexpr int kFmqSendTimeoutMs = 1000; // 1000 ms timeout for sending +static constexpr int kFmqReceiveTimeoutMs = + 1000; // 1000 ms timeout for receiving +static constexpr int kWritePollMs = 1; // polled non-blocking interval +static constexpr int kReadPollMs = 1; // polled non-blocking interval + +const CodecConfiguration BluetoothAudioSession::kInvalidCodecConfiguration = {}; +const LeAudioConfiguration kInvalidLeAudioConfiguration = {}; +AudioConfiguration BluetoothAudioSession::invalidSoftwareAudioConfiguration = + {}; +AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {}; +AudioConfiguration BluetoothAudioSession::invalidLeOffloadAudioConfig = {}; + +BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type) + : session_type_(session_type), stack_iface_(nullptr), data_mq_(nullptr) { + invalidSoftwareAudioConfiguration.set( + kInvalidPcmConfiguration); + invalidOffloadAudioConfiguration.set( + kInvalidCodecConfiguration); + invalidLeOffloadAudioConfig.set( + kInvalidLeAudioConfiguration); +} + +/*** + * + * Callback methods + * + ***/ + +void BluetoothAudioSession::OnSessionStarted( + const std::shared_ptr stack_iface, + const DataMQDesc* mq_desc, const AudioConfiguration& audio_config) { + std::lock_guard guard(mutex_); + if (stack_iface == nullptr) { + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) + << ", IBluetoothAudioPort Invalid"; + } else if (!UpdateAudioConfig(audio_config)) { + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) + << ", AudioConfiguration=" << audio_config.toString() + << " Invalid"; + } else if (!UpdateDataPath(mq_desc)) { + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) + << " MqDescriptor Invalid"; + if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + audio_config_ = std::make_unique( + invalidOffloadAudioConfiguration); + } else { + audio_config_ = std::make_unique( + invalidSoftwareAudioConfiguration); + } + } else { + stack_iface_ = stack_iface; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << ", AudioConfiguration=" << audio_config.toString(); + ReportSessionStatus(); + } +} + +void BluetoothAudioSession::OnSessionEnded() { + std::lock_guard guard(mutex_); + bool toggled = IsSessionReady(); + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); + if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + audio_config_ = + std::make_unique(invalidOffloadAudioConfiguration); + } else { + audio_config_ = + std::make_unique(invalidSoftwareAudioConfiguration); + } + stack_iface_ = nullptr; + UpdateDataPath(nullptr); + if (toggled) { + ReportSessionStatus(); + } +} + +/*** + * + * Util methods + * + ***/ + +const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() { + std::lock_guard guard(mutex_); + if (!IsSessionReady()) { + if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return invalidOffloadAudioConfiguration; + } else { + return invalidSoftwareAudioConfiguration; + } + switch (session_type_) { + case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: + return invalidOffloadAudioConfiguration; + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH: + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH: + return invalidLeOffloadAudioConfig; + default: + return invalidSoftwareAudioConfiguration; + } + } + return *audio_config_; +} + +void BluetoothAudioSession::ReportAudioConfigChanged( + const AudioConfiguration& audio_config) { + if (session_type_ != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && + session_type_ != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { + return; + } + std::lock_guard guard(mutex_); + audio_config_ = std::make_unique(audio_config); + if (observers_.empty()) { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO port state observer"; + return; + } + for (auto& observer : observers_) { + uint16_t cookie = observer.first; + std::shared_ptr cb = observer.second; + LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_) + << ", bluetooth_audio=0x" + << ::android::base::StringPrintf("%04x", cookie); + if (cb->audio_configuration_changed_cb_ != nullptr) { + cb->audio_configuration_changed_cb_(cookie); + } + } +} + +bool BluetoothAudioSession::IsSessionReady() { + std::lock_guard guard(mutex_); + + bool is_mq_valid = + (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type_ == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type_ == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH || + (data_mq_ != nullptr && data_mq_->isValid())); + return stack_iface_ != nullptr && is_mq_valid; +} + +/*** + * + * Status callback methods + * + ***/ + +uint16_t BluetoothAudioSession::RegisterStatusCback( + const PortStatusCallbacks& callbacks) { + std::lock_guard guard(mutex_); + uint16_t cookie = ObserversCookieGetInitValue(session_type_); + uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_); + + while (cookie < cookie_upper_bound) { + if (observers_.find(cookie) == observers_.end()) { + break; + } + ++cookie; + } + if (cookie >= cookie_upper_bound) { + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) + << " has " << observers_.size() + << " observers already (No Resource)"; + return kObserversCookieUndefined; + } + std::shared_ptr cb = + std::make_shared(); + *cb = callbacks; + observers_[cookie] = cb; + return cookie; +} + +void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) { + std::lock_guard guard(mutex_); + if (observers_.erase(cookie) != 1) { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << " no such provider=0x" + << ::android::base::StringPrintf("%04x", cookie); + } +} + +/*** + * + * Stream methods + * + ***/ + +bool BluetoothAudioSession::StartStream() { + std::lock_guard guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return false; + } + auto hal_retval = stack_iface_->startStream(); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + return false; + } + return true; +} + +bool BluetoothAudioSession::SuspendStream() { + std::lock_guard guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return false; + } + auto hal_retval = stack_iface_->suspendStream(); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + return false; + } + return true; +} + +void BluetoothAudioSession::StopStream() { + std::lock_guard guard(mutex_); + if (!IsSessionReady()) { + return; + } + auto hal_retval = stack_iface_->stopStream(); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + } +} + +/*** + * + * Private methods + * + ***/ + +bool BluetoothAudioSession::UpdateDataPath(const DataMQDesc* mq_desc) { + if (mq_desc == nullptr) { + // usecase of reset by nullptr + data_mq_ = nullptr; + return true; + } + std::unique_ptr temp_mq; + temp_mq.reset(new DataMQ(*mq_desc)); + if (!temp_mq || !temp_mq->isValid()) { + data_mq_ = nullptr; + return false; + } + data_mq_ = std::move(temp_mq); + return true; +} + +bool BluetoothAudioSession::UpdateAudioConfig( + const AudioConfiguration& audio_config) { + bool is_software_session = + (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || + session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH || + session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH || + session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH); + bool is_offload_a2dp_session = + (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH); + bool is_offload_le_audio_session = + (session_type_ == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type_ == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH); + auto audio_config_tag = audio_config.getTag(); + bool is_software_audio_config = + (is_software_session && + audio_config_tag == AudioConfiguration::pcmConfig); + bool is_a2dp_offload_audio_config = + (is_offload_a2dp_session && + audio_config_tag == AudioConfiguration::a2dpConfig); + bool is_le_audio_offload_audio_config = + (is_offload_le_audio_session && + audio_config_tag == AudioConfiguration::leAudioConfig); + if (!is_software_audio_config && !is_a2dp_offload_audio_config && + !is_le_audio_offload_audio_config) { + return false; + } + audio_config_ = std::make_unique(audio_config); + return true; +} + +void BluetoothAudioSession::ReportSessionStatus() { + // This is locked already by OnSessionStarted / OnSessionEnded + if (observers_.empty()) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO port state observer"; + return; + } + for (auto& observer : observers_) { + uint16_t cookie = observer.first; + std::shared_ptr callback = observer.second; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " notify to bluetooth_audio=0x" + << ::android::base::StringPrintf("%04x", cookie); + callback->session_changed_cb_(cookie); + } +} + +/*** + * + * PCM methods + * + ***/ + +size_t BluetoothAudioSession::OutWritePcmData(const void* buffer, + size_t bytes) { + if (buffer == nullptr || bytes <= 0) { + return 0; + } + size_t total_written = 0; + int timeout_ms = kFmqSendTimeoutMs; + do { + std::unique_lock lock(mutex_); + if (!IsSessionReady()) { + break; + } + size_t num_bytes_to_write = data_mq_->availableToWrite(); + if (num_bytes_to_write) { + if (num_bytes_to_write > (bytes - total_written)) { + num_bytes_to_write = bytes - total_written; + } + + if (!data_mq_->write( + static_cast(buffer) + total_written, + num_bytes_to_write)) { + LOG(ERROR) << "FMQ datapath writing " << total_written << "/" << bytes + << " failed"; + return total_written; + } + total_written += num_bytes_to_write; + } else if (timeout_ms >= kWritePollMs) { + lock.unlock(); + usleep(kWritePollMs * 1000); + timeout_ms -= kWritePollMs; + } else { + LOG(DEBUG) << "Data " << total_written << "/" << bytes << " overflow " + << (kFmqSendTimeoutMs - timeout_ms) << " ms"; + return total_written; + } + } while (total_written < bytes); + return total_written; +} + +size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) { + if (buffer == nullptr || bytes <= 0) { + return 0; + } + size_t total_read = 0; + int timeout_ms = kFmqReceiveTimeoutMs; + do { + std::unique_lock lock(mutex_); + if (!IsSessionReady()) { + break; + } + size_t num_bytes_to_read = data_mq_->availableToRead(); + if (num_bytes_to_read) { + if (num_bytes_to_read > (bytes - total_read)) { + num_bytes_to_read = bytes - total_read; + } + if (!data_mq_->read(static_cast(buffer) + total_read, + num_bytes_to_read)) { + LOG(ERROR) << "FMQ datapath reading " << total_read << "/" << bytes + << " failed"; + return total_read; + } + total_read += num_bytes_to_read; + } else if (timeout_ms >= kReadPollMs) { + lock.unlock(); + usleep(kReadPollMs * 1000); + timeout_ms -= kReadPollMs; + continue; + } else { + LOG(DEBUG) << "Data " << total_read << "/" << bytes << " overflow " + << (kFmqReceiveTimeoutMs - timeout_ms) << " ms"; + return total_read; + } + } while (total_read < bytes); + return total_read; +} + +/*** + * + * Other methods + * + ***/ + +void BluetoothAudioSession::ReportControlStatus(bool start_resp, + BluetoothAudioStatus status) { + std::lock_guard guard(mutex_); + if (observers_.empty()) { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO port state observer"; + return; + } + for (auto& observer : observers_) { + uint16_t cookie = observer.first; + std::shared_ptr callback = observer.second; + LOG(INFO) << __func__ << " - status=" << toString(status) + << " for SessionType=" << toString(session_type_) + << ", bluetooth_audio=0x" + << ::android::base::StringPrintf("%04x", cookie) + << (start_resp ? " started" : " suspended"); + callback->control_result_cb_(cookie, start_resp, status); + } +} + +bool BluetoothAudioSession::GetPresentationPosition( + PresentationPosition& presentation_position) { + std::lock_guard guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return false; + } + bool retval = false; + + if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + return false; + } + return retval; +} + +void BluetoothAudioSession::UpdateSourceMetadata( + const struct source_metadata& source_metadata) { + std::lock_guard guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return; + } + + ssize_t track_count = source_metadata.track_count; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << "," + << track_count << " track(s)"; + if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || + session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return; + } + + SourceMetadata hal_source_metadata; + hal_source_metadata.tracks.resize(track_count); + for (int i = 0; i < track_count; i++) { + hal_source_metadata.tracks[i].usage = + static_cast( + source_metadata.tracks[i].usage); + hal_source_metadata.tracks[i].contentType = + static_cast( + source_metadata.tracks[i].content_type); + hal_source_metadata.tracks[i].gain = source_metadata.tracks[i].gain; + LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_) + << ", usage=" << toString(hal_source_metadata.tracks[i].usage) + << ", content=" + << toString(hal_source_metadata.tracks[i].contentType) + << ", gain=" << hal_source_metadata.tracks[i].gain; + } + + auto hal_retval = stack_iface_->updateSourceMetadata(hal_source_metadata); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + } +} + +void BluetoothAudioSession::UpdateSinkMetadata( + const struct sink_metadata& sink_metadata) { + std::lock_guard guard(mutex_); + if (!IsSessionReady()) { + LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return; + } + + ssize_t track_count = sink_metadata.track_count; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << "," + << track_count << " track(s)"; + if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || + session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return; + } + + SinkMetadata hal_sink_metadata; + hal_sink_metadata.tracks.resize(track_count); + for (int i = 0; i < track_count; i++) { + hal_sink_metadata.tracks[i].source = + static_cast( + sink_metadata.tracks[i].source); + hal_sink_metadata.tracks[i].gain = sink_metadata.tracks[i].gain; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << ", source=" << sink_metadata.tracks[i].source + << ", dest_device=" << sink_metadata.tracks[i].dest_device + << ", gain=" << sink_metadata.tracks[i].gain + << ", dest_device_address=" + << sink_metadata.tracks[i].dest_device_address; + } + + auto hal_retval = stack_iface_->updateSinkMetadata(hal_sink_metadata); + if (!hal_retval.isOk()) { + LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" + << toString(session_type_) << " failed"; + } +} + +bool BluetoothAudioSession::IsAidlAvailable() { + if (is_aidl_checked) return is_aidl_available; + is_aidl_available = + (AServiceManager_checkService( + kDefaultAudioProviderFactoryInterface.c_str()) != nullptr); + is_aidl_checked = true; + return is_aidl_available; +} + +/*** + * + * BluetoothAudioSessionInstance + * + ***/ +std::mutex BluetoothAudioSessionInstance::mutex_; +std::unordered_map> + BluetoothAudioSessionInstance::sessions_map_; + +std::shared_ptr +BluetoothAudioSessionInstance::GetSessionInstance( + const SessionType& session_type) { + std::lock_guard guard(mutex_); + + if (!sessions_map_.empty()) { + auto entry = sessions_map_.find(session_type); + if (entry != sessions_map_.end()) { + return entry->second; + } + } + std::shared_ptr session_ptr = + std::make_shared(session_type); + sessions_map_[session_type] = session_ptr; + return session_ptr; +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h new file mode 100644 index 0000000000..85fd571f28 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using ::aidl::android::hardware::common::fmq::MQDescriptor; +using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; +using ::android::AidlMessageQueue; + +using ::aidl::android::hardware::audio::common::SinkMetadata; +using ::aidl::android::hardware::audio::common::SourceMetadata; + +using MQDataType = int8_t; +using MQDataMode = SynchronizedReadWrite; +using DataMQ = AidlMessageQueue; +using DataMQDesc = + ::aidl::android::hardware::common::fmq::MQDescriptor; + +static constexpr uint16_t kObserversCookieSize = 0x0010; // 0x0000 ~ 0x000f +static constexpr uint16_t kObserversCookieUndefined = + (static_cast(SessionType::UNKNOWN) << 8 & 0xff00); +inline SessionType ObserversCookieGetSessionType(uint16_t cookie) { + return static_cast(cookie >> 8 & 0x00ff); +} +inline uint16_t ObserversCookieGetInitValue(SessionType session_type) { + return (static_cast(session_type) << 8 & 0xff00); +} +inline uint16_t ObserversCookieGetUpperBound(SessionType session_type) { + return (static_cast(session_type) << 8 & 0xff00) + + kObserversCookieSize; +} + +/*** + * This presents the callbacks of started / suspended and session changed, + * and the bluetooth_audio module uses to receive the status notification + ***/ +struct PortStatusCallbacks { + /*** + * control_result_cb_ - when the Bluetooth stack reports results of + * streamStarted or streamSuspended, the BluetoothAudioProvider will invoke + * this callback to report to the bluetooth_audio module. + * @param: cookie - indicates which bluetooth_audio output should handle + * @param: start_resp - this report is for startStream or not + * @param: status - the result of startStream + ***/ + std::function + control_result_cb_; + /*** + * session_changed_cb_ - when the Bluetooth stack start / end session, the + * BluetoothAudioProvider will invoke this callback to notify to the + * bluetooth_audio module. + * @param: cookie - indicates which bluetooth_audio output should handle + ***/ + std::function session_changed_cb_; + /*** + * audio_configuration_changed_cb_ - when the Bluetooth stack change the audio + * configuration, the BluetoothAudioProvider will invoke this callback to + * notify to the bluetooth_audio module. + * @param: cookie - indicates which bluetooth_audio output should handle + ***/ + std::function audio_configuration_changed_cb_; +}; + +class BluetoothAudioSession { + public: + BluetoothAudioSession(const SessionType& session_type); + + /*** + * The function helps to check if this session is ready or not + * @return: true if the Bluetooth stack has started the specified session + ***/ + bool IsSessionReady(); + + /*** + * The report function is used to report that the Bluetooth stack has started + * this session without any failure, and will invoke session_changed_cb_ to + * notify those registered bluetooth_audio outputs + ***/ + void OnSessionStarted(const std::shared_ptr stack_iface, + const DataMQDesc* mq_desc, + const AudioConfiguration& audio_config); + + /*** + * The report function is used to report that the Bluetooth stack has ended + * the session, and will invoke session_changed_cb_ to notify registered + * bluetooth_audio outputs + ***/ + void OnSessionEnded(); + + /*** + * The report function is used to report that the Bluetooth stack has notified + * the result of startStream or suspendStream, and will invoke + * control_result_cb_ to notify registered bluetooth_audio outputs + ***/ + void ReportControlStatus(bool start_resp, BluetoothAudioStatus status); + + /*** + * The control function helps the bluetooth_audio module to register + * PortStatusCallbacks + * @return: cookie - the assigned number to this bluetooth_audio output + ***/ + uint16_t RegisterStatusCback(const PortStatusCallbacks& cbacks); + + /*** + * The control function helps the bluetooth_audio module to unregister + * PortStatusCallbacks + * @param: cookie - indicates which bluetooth_audio output is + ***/ + void UnregisterStatusCback(uint16_t cookie); + + /*** + * The control function is for the bluetooth_audio module to get the current + * AudioConfiguration + ***/ + const AudioConfiguration& GetAudioConfig(); + + /*** + * The report function is used to report that the Bluetooth stack has notified + * the audio configuration changed, and will invoke + * audio_configuration_changed_cb_ to notify registered bluetooth_audio + * outputs + ***/ + void ReportAudioConfigChanged(const AudioConfiguration& audio_config); + + /*** + * Those control functions are for the bluetooth_audio module to start, + * suspend, stop stream, to check position, and to update metadata. + ***/ + bool StartStream(); + bool SuspendStream(); + void StopStream(); + bool GetPresentationPosition(PresentationPosition& presentation_position); + void UpdateSourceMetadata(const struct source_metadata& source_metadata); + void UpdateSinkMetadata(const struct sink_metadata& sink_metadata); + + // The control function writes stream to FMQ + size_t OutWritePcmData(const void* buffer, size_t bytes); + // The control function read stream from FMQ + size_t InReadPcmData(void* buffer, size_t bytes); + + // Return if IBluetoothAudioProviderFactory implementation existed + static bool IsAidlAvailable(); + + static constexpr PcmConfiguration kInvalidPcmConfiguration = {}; + // can't be constexpr because of non-literal type + static const CodecConfiguration kInvalidCodecConfiguration; + + static AudioConfiguration invalidSoftwareAudioConfiguration; + static AudioConfiguration invalidOffloadAudioConfiguration; + static AudioConfiguration invalidLeOffloadAudioConfig; + + private: + // using recursive_mutex to allow hwbinder to re-enter again. + std::recursive_mutex mutex_; + SessionType session_type_; + + // audio control path to use for both software and offloading + std::shared_ptr stack_iface_; + // audio data path (FMQ) for software encoding + std::unique_ptr data_mq_; + // audio data configuration for both software and offloading + std::unique_ptr audio_config_; + + // saving those registered bluetooth_audio's callbacks + std::unordered_map> + observers_; + + bool UpdateDataPath(const DataMQDesc* mq_desc); + bool UpdateAudioConfig(const AudioConfiguration& audio_config); + // invoking the registered session_changed_cb_ + void ReportSessionStatus(); + + static inline std::atomic is_aidl_checked = false; + static inline std::atomic is_aidl_available = false; + static inline const std::string kDefaultAudioProviderFactoryInterface = + std::string() + IBluetoothAudioProviderFactory::descriptor + "/default"; +}; + +class BluetoothAudioSessionInstance { + public: + // The API is to fetch the specified session of A2DP / Hearing Aid + static std::shared_ptr GetSessionInstance( + const SessionType& session_type); + + private: + static std::mutex mutex_; + static std::unordered_map> + sessions_map_; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h new file mode 100644 index 0000000000..a3ed42894c --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h @@ -0,0 +1,182 @@ +/* + * Copyright 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. + */ + +#pragma once + +#include "BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioSessionControl { + public: + /*** + * The control API helps to check if session is ready or not + * @return: true if the Bluetooth stack has started th specified session + ***/ + static bool IsSessionReady(const SessionType& session_type) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->IsSessionReady(); + } + + return false; + } + + /*** + * The control API helps the bluetooth_audio module to register + * PortStatusCallbacks + * @return: cookie - the assigned number to this bluetooth_audio output + ***/ + static uint16_t RegisterControlResultCback( + const SessionType& session_type, const PortStatusCallbacks& cbacks) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->RegisterStatusCback(cbacks); + } + return kObserversCookieUndefined; + } + + /*** + * The control API helps the bluetooth_audio module to unregister + * PortStatusCallbacks + * @param: cookie - indicates which bluetooth_audio output is + ***/ + static void UnregisterControlResultCback(const SessionType& session_type, + uint16_t cookie) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->UnregisterStatusCback(cookie); + } + } + + /*** + * The control API for the bluetooth_audio module to get current + * AudioConfiguration + ***/ + static const AudioConfiguration GetAudioConfig( + const SessionType& session_type) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->GetAudioConfig(); + } else if (session_type == + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return BluetoothAudioSession::invalidOffloadAudioConfiguration; + } else { + return BluetoothAudioSession::invalidSoftwareAudioConfiguration; + } + } + + /*** + * Those control APIs for the bluetooth_audio module to start / suspend / + stop + * stream, to check position, and to update metadata. + ***/ + static bool StartStream(const SessionType& session_type) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->StartStream(); + } + return false; + } + + static bool SuspendStream(const SessionType& session_type) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->SuspendStream(); + } + return false; + } + + static void StopStream(const SessionType& session_type) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->StopStream(); + } + } + + static bool GetPresentationPosition( + const SessionType& session_type, + PresentationPosition& presentation_position) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->GetPresentationPosition(presentation_position); + } + return false; + } + + static void UpdateSourceMetadata( + const SessionType& session_type, + const struct source_metadata& source_metadata) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->UpdateSourceMetadata(source_metadata); + } + } + + static void UpdateSinkMetadata(const SessionType& session_type, + const struct sink_metadata& sink_metadata) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->UpdateSinkMetadata(sink_metadata); + } + } + + /*** + * The control API writes stream to FMQ + ***/ + static size_t OutWritePcmData(const SessionType& session_type, + const void* buffer, size_t bytes) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->OutWritePcmData(buffer, bytes); + } + return 0; + } + + /*** + * The control API reads stream from FMQ + ***/ + static size_t InReadPcmData(const SessionType& session_type, void* buffer, + size_t bytes) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + return session_ptr->InReadPcmData(buffer, bytes); + } + return 0; + } +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h new file mode 100644 index 0000000000..18569c3827 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioSessionReport { + public: + /*** + * The API reports the Bluetooth stack has started the session, and will + * inform registered bluetooth_audio outputs + ***/ + static void OnSessionStarted( + const SessionType& session_type, + const std::shared_ptr host_iface, + const DataMQDesc* data_mq, const AudioConfiguration& audio_config) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->OnSessionStarted(host_iface, data_mq, audio_config); + } + } + + /*** + * The API reports the Bluetooth stack has ended the session, and will + * inform registered bluetooth_audio outputs + ***/ + static void OnSessionEnded(const SessionType& session_type) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->OnSessionEnded(); + } + } + + /*** + * The API reports the Bluetooth stack has replied the result of startStream + * or suspendStream, and will inform registered bluetooth_audio outputs + ***/ + static void ReportControlStatus(const SessionType& session_type, + const bool& start_resp, + BluetoothAudioStatus status) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->ReportControlStatus(start_resp, status); + } + } + /*** + * The API reports the Bluetooth stack has replied the changed of the audio + * configuration, and will inform registered bluetooth_audio outputs + ***/ + static void ReportAudioConfigChanged(const SessionType& session_type, + const AudioConfiguration& audio_config) { + std::shared_ptr session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if (session_ptr != nullptr) { + session_ptr->ReportAudioConfigChanged(audio_config); + } + } +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp new file mode 100644 index 0000000000..91e0238783 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp @@ -0,0 +1,775 @@ +/* + * Copyright (C) 2022 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 "BtAudioNakahara" + +#include +#include +#include +#include + +#include +#include + +#include "../aidl_session/BluetoothAudioSession.h" +#include "../aidl_session/BluetoothAudioSessionControl.h" +#include "HidlToAidlMiddleware_2_0.h" +#include "HidlToAidlMiddleware_2_1.h" +#include "HidlToAidlMiddleware_2_2.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using HidlStatus = ::android::hardware::bluetooth::audio::V2_0::Status; +using PcmConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::PcmParameters; +using SampleRate_2_0 = ::android::hardware::bluetooth::audio::V2_0::SampleRate; +using ChannelMode_2_0 = + ::android::hardware::bluetooth::audio::V2_0::ChannelMode; +using BitsPerSample_2_0 = + ::android::hardware::bluetooth::audio::V2_0::BitsPerSample; +using CodecConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration; +using CodecType_2_0 = ::android::hardware::bluetooth::audio::V2_0::CodecType; +using SbcConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcParameters; +using AacConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AacParameters; +using LdacConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::LdacParameters; +using AptxConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AptxParameters; +using SbcAllocMethod_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod; +using SbcBlockLength_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength; +using SbcChannelMode_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode; +using SbcNumSubbands_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands; +using AacObjectType_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AacObjectType; +using AacVarBitRate_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate; +using LdacChannelMode_2_0 = + ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode; +using LdacQualityIndex_2_0 = + ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex; + +using PcmConfig_2_1 = + ::android::hardware::bluetooth::audio::V2_1::PcmParameters; +using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate; +using Lc3CodecConfig_2_1 = + ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration; +using Lc3Config_2_1 = + ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters; +using Lc3FrameDuration_2_1 = + ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration; + +using LeAudioConfig_2_2 = + ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration; +using LeAudioMode_2_2 = + ::android::hardware::bluetooth::audio::V2_2::LeAudioMode; + +std::mutex legacy_callback_lock; +std::unordered_map< + SessionType, + std::unordered_map>> + legacy_callback_table; + +const static std::unordered_map + session_type_2_0_to_aidl_map{ + {SessionType_2_0::A2DP_SOFTWARE_ENCODING_DATAPATH, + SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH}, + {SessionType_2_0::A2DP_HARDWARE_OFFLOAD_DATAPATH, + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH}, + {SessionType_2_0::HEARING_AID_SOFTWARE_ENCODING_DATAPATH, + SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH}, + }; + +const static std::unordered_map + session_type_2_1_to_aidl_map{ + {SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH, + SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH}, + {SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH, + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH}, + {SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH, + SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH}, + {SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH, + SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH}, + {SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH, + SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH}, + {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH, + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH}, + {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH, + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH}, + }; + +const static std::unordered_map + sample_rate_to_hidl_2_0_map{ + {44100, SampleRate_2_0::RATE_44100}, + {48000, SampleRate_2_0::RATE_48000}, + {88200, SampleRate_2_0::RATE_88200}, + {96000, SampleRate_2_0::RATE_96000}, + {176400, SampleRate_2_0::RATE_176400}, + {192000, SampleRate_2_0::RATE_192000}, + {16000, SampleRate_2_0::RATE_16000}, + {24000, SampleRate_2_0::RATE_24000}, + }; + +const static std::unordered_map + sample_rate_to_hidl_2_1_map{ + {44100, SampleRate_2_1::RATE_44100}, + {48000, SampleRate_2_1::RATE_48000}, + {88200, SampleRate_2_1::RATE_88200}, + {96000, SampleRate_2_1::RATE_96000}, + {176400, SampleRate_2_1::RATE_176400}, + {192000, SampleRate_2_1::RATE_192000}, + {16000, SampleRate_2_1::RATE_16000}, + {24000, SampleRate_2_1::RATE_24000}, + {8000, SampleRate_2_1::RATE_8000}, + {32000, SampleRate_2_1::RATE_32000}, + }; + +const static std::unordered_map + codec_type_to_hidl_2_0_map{ + {CodecType::UNKNOWN, CodecType_2_0::UNKNOWN}, + {CodecType::SBC, CodecType_2_0::SBC}, + {CodecType::AAC, CodecType_2_0::AAC}, + {CodecType::APTX, CodecType_2_0::APTX}, + {CodecType::APTX_HD, CodecType_2_0::APTX_HD}, + {CodecType::LDAC, CodecType_2_0::LDAC}, + {CodecType::LC3, CodecType_2_0::UNKNOWN}, + }; + +const static std::unordered_map + sbc_channel_mode_to_hidl_2_0_map{ + {SbcChannelMode::UNKNOWN, SbcChannelMode_2_0::UNKNOWN}, + {SbcChannelMode::JOINT_STEREO, SbcChannelMode_2_0::JOINT_STEREO}, + {SbcChannelMode::STEREO, SbcChannelMode_2_0::STEREO}, + {SbcChannelMode::DUAL, SbcChannelMode_2_0::DUAL}, + {SbcChannelMode::MONO, SbcChannelMode_2_0::MONO}, + }; + +const static std::unordered_map + sbc_block_length_to_hidl_map{ + {4, SbcBlockLength_2_0::BLOCKS_4}, + {8, SbcBlockLength_2_0::BLOCKS_8}, + {12, SbcBlockLength_2_0::BLOCKS_12}, + {16, SbcBlockLength_2_0::BLOCKS_16}, + }; + +const static std::unordered_map + sbc_subbands_to_hidl_map{ + {4, SbcNumSubbands_2_0::SUBBAND_4}, + {8, SbcNumSubbands_2_0::SUBBAND_8}, + }; + +const static std::unordered_map + sbc_alloc_method_to_hidl_map{ + {SbcAllocMethod::ALLOC_MD_S, SbcAllocMethod_2_0::ALLOC_MD_S}, + {SbcAllocMethod::ALLOC_MD_L, SbcAllocMethod_2_0::ALLOC_MD_L}, + }; + +const static std::unordered_map + aac_object_type_to_hidl_map{ + {AacObjectType::MPEG2_LC, AacObjectType_2_0::MPEG2_LC}, + {AacObjectType::MPEG4_LC, AacObjectType_2_0::MPEG4_LC}, + {AacObjectType::MPEG4_LTP, AacObjectType_2_0::MPEG4_LTP}, + {AacObjectType::MPEG4_SCALABLE, AacObjectType_2_0::MPEG4_SCALABLE}, + }; + +const static std::unordered_map + ldac_channel_mode_to_hidl_map{ + {LdacChannelMode::UNKNOWN, LdacChannelMode_2_0::UNKNOWN}, + {LdacChannelMode::STEREO, LdacChannelMode_2_0::STEREO}, + {LdacChannelMode::DUAL, LdacChannelMode_2_0::DUAL}, + {LdacChannelMode::MONO, LdacChannelMode_2_0::MONO}, + }; + +const static std::unordered_map + ldac_qindex_to_hidl_map{ + {LdacQualityIndex::HIGH, LdacQualityIndex_2_0::QUALITY_HIGH}, + {LdacQualityIndex::MID, LdacQualityIndex_2_0::QUALITY_MID}, + {LdacQualityIndex::LOW, LdacQualityIndex_2_0::QUALITY_LOW}, + {LdacQualityIndex::ABR, LdacQualityIndex_2_0::QUALITY_ABR}, + }; + +const static std::unordered_map + leaudio_mode_to_hidl_map{ + {LeAudioMode::UNKNOWN, LeAudioMode_2_2::UNKNOWN}, + {LeAudioMode::UNICAST, LeAudioMode_2_2::UNICAST}, + {LeAudioMode::BROADCAST, LeAudioMode_2_2::BROADCAST}, + }; + +inline SessionType from_session_type_2_0( + const SessionType_2_0& session_type_hidl) { + auto it = session_type_2_0_to_aidl_map.find(session_type_hidl); + if (it != session_type_2_0_to_aidl_map.end()) return it->second; + return SessionType::UNKNOWN; +} + +inline SessionType from_session_type_2_1( + const SessionType_2_1& session_type_hidl) { + auto it = session_type_2_1_to_aidl_map.find(session_type_hidl); + if (it != session_type_2_1_to_aidl_map.end()) return it->second; + return SessionType::UNKNOWN; +} + +inline HidlStatus to_hidl_status(const BluetoothAudioStatus& status) { + switch (status) { + case BluetoothAudioStatus::SUCCESS: + return HidlStatus::SUCCESS; + case BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION: + return HidlStatus::UNSUPPORTED_CODEC_CONFIGURATION; + default: + return HidlStatus::FAILURE; + } +} + +inline SampleRate_2_0 to_hidl_sample_rate_2_0(const int32_t sample_rate_hz) { + auto it = sample_rate_to_hidl_2_0_map.find(sample_rate_hz); + if (it != sample_rate_to_hidl_2_0_map.end()) return it->second; + return SampleRate_2_0::RATE_UNKNOWN; +} + +inline SampleRate_2_1 to_hidl_sample_rate_2_1(const int32_t sample_rate_hz) { + auto it = sample_rate_to_hidl_2_1_map.find(sample_rate_hz); + if (it != sample_rate_to_hidl_2_1_map.end()) return it->second; + return SampleRate_2_1::RATE_UNKNOWN; +} + +inline BitsPerSample_2_0 to_hidl_bits_per_sample(const int8_t bit_per_sample) { + switch (bit_per_sample) { + case 16: + return BitsPerSample_2_0::BITS_16; + case 24: + return BitsPerSample_2_0::BITS_24; + case 32: + return BitsPerSample_2_0::BITS_32; + default: + return BitsPerSample_2_0::BITS_UNKNOWN; + } +} + +inline ChannelMode_2_0 to_hidl_channel_mode(const ChannelMode channel_mode) { + switch (channel_mode) { + case ChannelMode::MONO: + return ChannelMode_2_0::MONO; + case ChannelMode::STEREO: + return ChannelMode_2_0::STEREO; + default: + return ChannelMode_2_0::UNKNOWN; + } +} + +inline PcmConfig_2_0 to_hidl_pcm_config_2_0( + const PcmConfiguration& pcm_config) { + PcmConfig_2_0 hidl_pcm_config; + hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_0(pcm_config.sampleRateHz); + hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode); + hidl_pcm_config.bitsPerSample = + to_hidl_bits_per_sample(pcm_config.bitsPerSample); + return hidl_pcm_config; +} + +inline CodecType_2_0 to_hidl_codec_type_2_0(const CodecType codec_type) { + auto it = codec_type_to_hidl_2_0_map.find(codec_type); + if (it != codec_type_to_hidl_2_0_map.end()) return it->second; + return CodecType_2_0::UNKNOWN; +} + +inline SbcConfig_2_0 to_hidl_sbc_config(const SbcConfiguration sbc_config) { + SbcConfig_2_0 hidl_sbc_config; + hidl_sbc_config.minBitpool = sbc_config.minBitpool; + hidl_sbc_config.maxBitpool = sbc_config.maxBitpool; + hidl_sbc_config.sampleRate = to_hidl_sample_rate_2_0(sbc_config.sampleRateHz); + hidl_sbc_config.bitsPerSample = + to_hidl_bits_per_sample(sbc_config.bitsPerSample); + if (sbc_channel_mode_to_hidl_2_0_map.find(sbc_config.channelMode) != + sbc_channel_mode_to_hidl_2_0_map.end()) { + hidl_sbc_config.channelMode = + sbc_channel_mode_to_hidl_2_0_map.at(sbc_config.channelMode); + } + if (sbc_block_length_to_hidl_map.find(sbc_config.blockLength) != + sbc_block_length_to_hidl_map.end()) { + hidl_sbc_config.blockLength = + sbc_block_length_to_hidl_map.at(sbc_config.blockLength); + } + if (sbc_subbands_to_hidl_map.find(sbc_config.numSubbands) != + sbc_subbands_to_hidl_map.end()) { + hidl_sbc_config.numSubbands = + sbc_subbands_to_hidl_map.at(sbc_config.numSubbands); + } + if (sbc_alloc_method_to_hidl_map.find(sbc_config.allocMethod) != + sbc_alloc_method_to_hidl_map.end()) { + hidl_sbc_config.allocMethod = + sbc_alloc_method_to_hidl_map.at(sbc_config.allocMethod); + } + return hidl_sbc_config; +} + +inline AacConfig_2_0 to_hidl_aac_config(const AacConfiguration aac_config) { + AacConfig_2_0 hidl_aac_config; + hidl_aac_config.sampleRate = to_hidl_sample_rate_2_0(aac_config.sampleRateHz); + hidl_aac_config.bitsPerSample = + to_hidl_bits_per_sample(aac_config.bitsPerSample); + hidl_aac_config.channelMode = to_hidl_channel_mode(aac_config.channelMode); + if (aac_object_type_to_hidl_map.find(aac_config.objectType) != + aac_object_type_to_hidl_map.end()) { + hidl_aac_config.objectType = + aac_object_type_to_hidl_map.at(aac_config.objectType); + } + hidl_aac_config.variableBitRateEnabled = aac_config.variableBitRateEnabled + ? AacVarBitRate_2_0::ENABLED + : AacVarBitRate_2_0::DISABLED; + return hidl_aac_config; +} + +inline LdacConfig_2_0 to_hidl_ldac_config(const LdacConfiguration ldac_config) { + LdacConfig_2_0 hidl_ldac_config; + hidl_ldac_config.sampleRate = + to_hidl_sample_rate_2_0(ldac_config.sampleRateHz); + hidl_ldac_config.bitsPerSample = + to_hidl_bits_per_sample(ldac_config.bitsPerSample); + if (ldac_channel_mode_to_hidl_map.find(ldac_config.channelMode) != + ldac_channel_mode_to_hidl_map.end()) { + hidl_ldac_config.channelMode = + ldac_channel_mode_to_hidl_map.at(ldac_config.channelMode); + } + if (ldac_qindex_to_hidl_map.find(ldac_config.qualityIndex) != + ldac_qindex_to_hidl_map.end()) { + hidl_ldac_config.qualityIndex = + ldac_qindex_to_hidl_map.at(ldac_config.qualityIndex); + } + return hidl_ldac_config; +} + +inline AptxConfig_2_0 to_hidl_aptx_config(const AptxConfiguration aptx_config) { + AptxConfig_2_0 hidl_aptx_config; + hidl_aptx_config.sampleRate = + to_hidl_sample_rate_2_0(aptx_config.sampleRateHz); + hidl_aptx_config.bitsPerSample = + to_hidl_bits_per_sample(aptx_config.bitsPerSample); + hidl_aptx_config.channelMode = to_hidl_channel_mode(aptx_config.channelMode); + return hidl_aptx_config; +} + +inline CodecConfig_2_0 to_hidl_codec_config_2_0( + const CodecConfiguration& codec_config) { + CodecConfig_2_0 hidl_codec_config; + hidl_codec_config.codecType = to_hidl_codec_type_2_0(codec_config.codecType); + hidl_codec_config.encodedAudioBitrate = + static_cast(codec_config.encodedAudioBitrate); + hidl_codec_config.peerMtu = static_cast(codec_config.peerMtu); + hidl_codec_config.isScmstEnabled = codec_config.isScmstEnabled; + switch (codec_config.config.getTag()) { + case CodecConfiguration::CodecSpecific::sbcConfig: + hidl_codec_config.config.sbcConfig(to_hidl_sbc_config( + codec_config.config + .get())); + break; + case CodecConfiguration::CodecSpecific::aacConfig: + hidl_codec_config.config.aacConfig(to_hidl_aac_config( + codec_config.config + .get())); + break; + case CodecConfiguration::CodecSpecific::ldacConfig: + hidl_codec_config.config.ldacConfig(to_hidl_ldac_config( + codec_config.config + .get())); + break; + case CodecConfiguration::CodecSpecific::aptxConfig: + hidl_codec_config.config.aptxConfig(to_hidl_aptx_config( + codec_config.config + .get())); + break; + default: + break; + } + return hidl_codec_config; +} + +inline AudioConfig_2_0 to_hidl_audio_config_2_0( + const AudioConfiguration& audio_config) { + AudioConfig_2_0 hidl_audio_config; + if (audio_config.getTag() == AudioConfiguration::pcmConfig) { + hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_0( + audio_config.get())); + } else if (audio_config.getTag() == AudioConfiguration::a2dpConfig) { + hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( + audio_config.get())); + } + return hidl_audio_config; +} + +inline PcmConfig_2_1 to_hidl_pcm_config_2_1( + const PcmConfiguration& pcm_config) { + PcmConfig_2_1 hidl_pcm_config; + hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_1(pcm_config.sampleRateHz); + hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode); + hidl_pcm_config.bitsPerSample = + to_hidl_bits_per_sample(pcm_config.bitsPerSample); + hidl_pcm_config.dataIntervalUs = + static_cast(pcm_config.dataIntervalUs); + return hidl_pcm_config; +} + +inline Lc3Config_2_1 to_hidl_lc3_config_2_1( + const Lc3Configuration& lc3_config) { + Lc3Config_2_1 hidl_lc3_config; + hidl_lc3_config.pcmBitDepth = to_hidl_bits_per_sample(lc3_config.pcmBitDepth); + hidl_lc3_config.samplingFrequency = + to_hidl_sample_rate_2_1(lc3_config.samplingFrequencyHz); + if (lc3_config.samplingFrequencyHz == 10000) + hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_10000US; + else if (lc3_config.samplingFrequencyHz == 7500) + hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_7500US; + hidl_lc3_config.octetsPerFrame = + static_cast(lc3_config.octetsPerFrame); + hidl_lc3_config.blocksPerSdu = static_cast(lc3_config.blocksPerSdu); + return hidl_lc3_config; +} + +inline Lc3CodecConfig_2_1 to_hidl_leaudio_config_2_1( + const LeAudioConfiguration& leaudio_config) { + auto& unicast_config = + leaudio_config.modeConfig + .get(); + + auto& le_codec_config = unicast_config.leAudioCodecConfig + .get(); + + Lc3CodecConfig_2_1 hidl_lc3_codec_config; + hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config); + + hidl_lc3_codec_config.audioChannelAllocation = + unicast_config.streamMap.size(); + + return hidl_lc3_codec_config; +} + +inline LeAudioConfig_2_2 to_hidl_leaudio_config_2_2( + const LeAudioConfiguration& leaudio_config) { + LeAudioConfig_2_2 hidl_leaudio_config; + if (leaudio_mode_to_hidl_map.find(leaudio_config.mode) != + leaudio_mode_to_hidl_map.end()) { + hidl_leaudio_config.mode = leaudio_mode_to_hidl_map.at(leaudio_config.mode); + } + + if (leaudio_config.modeConfig.getTag() == + LeAudioConfiguration::LeAudioModeConfig::unicastConfig) { + auto& unicast_config = + leaudio_config.modeConfig + .get(); + ::android::hardware::bluetooth::audio::V2_2::UnicastConfig + hidl_unicast_config; + hidl_unicast_config.peerDelay = + static_cast(unicast_config.peerDelay); + + auto& lc3_config = unicast_config.leAudioCodecConfig + .get(); + hidl_unicast_config.lc3Config = to_hidl_lc3_config_2_1(lc3_config); + + hidl_unicast_config.streamMap.resize(unicast_config.streamMap.size()); + for (int i = 0; i < unicast_config.streamMap.size(); i++) { + hidl_unicast_config.streamMap[i].audioChannelAllocation = + static_cast( + unicast_config.streamMap[i].audioChannelAllocation); + hidl_unicast_config.streamMap[i].streamHandle = + static_cast(unicast_config.streamMap[i].streamHandle); + } + } else if (leaudio_config.modeConfig.getTag() == + LeAudioConfiguration::LeAudioModeConfig::broadcastConfig) { + auto bcast_config = + leaudio_config.modeConfig + .get(); + ::android::hardware::bluetooth::audio::V2_2::BroadcastConfig + hidl_bcast_config; + hidl_bcast_config.streamMap.resize(bcast_config.streamMap.size()); + for (int i = 0; i < bcast_config.streamMap.size(); i++) { + hidl_bcast_config.streamMap[i].audioChannelAllocation = + static_cast( + bcast_config.streamMap[i].audioChannelAllocation); + hidl_bcast_config.streamMap[i].streamHandle = + static_cast(bcast_config.streamMap[i].streamHandle); + hidl_bcast_config.streamMap[i].lc3Config = to_hidl_lc3_config_2_1( + bcast_config.streamMap[i] + .leAudioCodecConfig.get()); + } + } + return hidl_leaudio_config; +} + +inline AudioConfig_2_1 to_hidl_audio_config_2_1( + const AudioConfiguration& audio_config) { + AudioConfig_2_1 hidl_audio_config; + switch (audio_config.getTag()) { + case AudioConfiguration::pcmConfig: + hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1( + audio_config.get())); + break; + case AudioConfiguration::a2dpConfig: + hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( + audio_config.get())); + break; + case AudioConfiguration::leAudioConfig: + hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1( + audio_config.get())); + break; + } + return hidl_audio_config; +} + +inline AudioConfig_2_2 to_hidl_audio_config_2_2( + const AudioConfiguration& audio_config) { + AudioConfig_2_2 hidl_audio_config; + switch (audio_config.getTag()) { + case AudioConfiguration::pcmConfig: + hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1( + audio_config.get())); + break; + case AudioConfiguration::a2dpConfig: + hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( + audio_config.get())); + break; + case AudioConfiguration::leAudioConfig: + hidl_audio_config.leAudioConfig(to_hidl_leaudio_config_2_2( + audio_config.get())); + break; + } + return hidl_audio_config; +} + +/*** + * + * 2.0 + * + ***/ + +bool HidlToAidlMiddleware_2_0::IsSessionReady( + const SessionType_2_0& session_type) { + return BluetoothAudioSessionControl::IsSessionReady( + from_session_type_2_0(session_type)); +} + +uint16_t HidlToAidlMiddleware_2_0::RegisterControlResultCback( + const SessionType_2_0& session_type, + const PortStatusCallbacks_2_0& cbacks) { + PortStatusCallbacks_2_2 callback_2_2{ + .control_result_cb_ = cbacks.control_result_cb_, + .session_changed_cb_ = cbacks.session_changed_cb_, + }; + return HidlToAidlMiddleware_2_2::RegisterControlResultCback( + static_cast(session_type), callback_2_2); +} + +void HidlToAidlMiddleware_2_0::UnregisterControlResultCback( + const SessionType_2_0& session_type, uint16_t cookie) { + HidlToAidlMiddleware_2_2::UnregisterControlResultCback( + static_cast(session_type), cookie); +} + +const AudioConfig_2_0 HidlToAidlMiddleware_2_0::GetAudioConfig( + const SessionType_2_0& session_type) { + return to_hidl_audio_config_2_0(BluetoothAudioSessionControl::GetAudioConfig( + from_session_type_2_0(session_type))); +} + +bool HidlToAidlMiddleware_2_0::StartStream( + const SessionType_2_0& session_type) { + return BluetoothAudioSessionControl::StartStream( + from_session_type_2_0(session_type)); +} + +void HidlToAidlMiddleware_2_0::StopStream(const SessionType_2_0& session_type) { + return BluetoothAudioSessionControl::StopStream( + from_session_type_2_0(session_type)); +} + +bool HidlToAidlMiddleware_2_0::SuspendStream( + const SessionType_2_0& session_type) { + return BluetoothAudioSessionControl::SuspendStream( + from_session_type_2_0(session_type)); +} + +bool HidlToAidlMiddleware_2_0::GetPresentationPosition( + const SessionType_2_0& session_type, uint64_t* remote_delay_report_ns, + uint64_t* total_bytes_readed, timespec* data_position) { + PresentationPosition presentation_position; + auto ret_val = BluetoothAudioSessionControl::GetPresentationPosition( + from_session_type_2_0(session_type), presentation_position); + if (remote_delay_report_ns) + *remote_delay_report_ns = presentation_position.remoteDeviceAudioDelayNanos; + if (total_bytes_readed) + *total_bytes_readed = presentation_position.transmittedOctets; + if (data_position) + *data_position = { + .tv_sec = static_cast<__kernel_old_time_t>( + presentation_position.transmittedOctetsTimestamp.tvSec), + .tv_nsec = static_cast( + presentation_position.transmittedOctetsTimestamp.tvNSec)}; + return ret_val; +} + +void HidlToAidlMiddleware_2_0::UpdateTracksMetadata( + const SessionType_2_0& session_type, + const struct source_metadata* source_metadata) { + return BluetoothAudioSessionControl::UpdateSourceMetadata( + from_session_type_2_0(session_type), *source_metadata); +} + +size_t HidlToAidlMiddleware_2_0::OutWritePcmData( + const SessionType_2_0& session_type, const void* buffer, size_t bytes) { + return BluetoothAudioSessionControl::OutWritePcmData( + from_session_type_2_0(session_type), buffer, bytes); +} + +bool HidlToAidlMiddleware_2_0::IsAidlAvailable() { + return BluetoothAudioSession::IsAidlAvailable(); +} + +/*** + * + * 2.1 + * + ***/ + +const AudioConfig_2_1 HidlToAidlMiddleware_2_1::GetAudioConfig( + const SessionType_2_1& session_type) { + return to_hidl_audio_config_2_1(BluetoothAudioSessionControl::GetAudioConfig( + from_session_type_2_1(session_type))); +} + +/*** + * + * 2.2 + * + ***/ + +bool HidlToAidlMiddleware_2_2::IsSessionReady( + const SessionType_2_1& session_type) { + return BluetoothAudioSessionControl::IsSessionReady( + from_session_type_2_1(session_type)); +} + +uint16_t HidlToAidlMiddleware_2_2::RegisterControlResultCback( + const SessionType_2_1& session_type, + const PortStatusCallbacks_2_2& cbacks) { + LOG(INFO) << __func__ << ": " << toString(session_type); + auto aidl_session_type = from_session_type_2_1(session_type); + // Pass the exact reference to the lambda + auto& session_legacy_callback_table = + legacy_callback_table[aidl_session_type]; + PortStatusCallbacks aidl_callbacks{}; + if (cbacks.control_result_cb_) { + aidl_callbacks.control_result_cb_ = + [&session_legacy_callback_table](uint16_t cookie, bool start_resp, + const BluetoothAudioStatus& status) { + if (session_legacy_callback_table.find(cookie) == + session_legacy_callback_table.end()) { + LOG(ERROR) << __func__ << ": Unknown callback invoked!"; + return; + } + auto& cback = session_legacy_callback_table[cookie]; + cback->control_result_cb_(cookie, start_resp, to_hidl_status(status)); + }; + } + if (cbacks.session_changed_cb_) { + aidl_callbacks.session_changed_cb_ = + [&session_legacy_callback_table](uint16_t cookie) { + if (session_legacy_callback_table.find(cookie) == + session_legacy_callback_table.end()) { + LOG(ERROR) << __func__ << ": Unknown callback invoked!"; + return; + } + auto& cback = session_legacy_callback_table[cookie]; + cback->session_changed_cb_(cookie); + }; + }; + if (cbacks.audio_configuration_changed_cb_) { + aidl_callbacks.audio_configuration_changed_cb_ = + [&session_legacy_callback_table](uint16_t cookie) { + if (session_legacy_callback_table.find(cookie) == + session_legacy_callback_table.end()) { + LOG(ERROR) << __func__ << ": Unknown callback invoked!"; + return; + } + auto& cback = session_legacy_callback_table[cookie]; + cback->audio_configuration_changed_cb_(cookie); + }; + }; + auto cookie = BluetoothAudioSessionControl::RegisterControlResultCback( + aidl_session_type, aidl_callbacks); + { + std::lock_guard guard(legacy_callback_lock); + session_legacy_callback_table[cookie] = + std::make_shared(cbacks); + } + return cookie; +} + +void HidlToAidlMiddleware_2_2::UnregisterControlResultCback( + const SessionType_2_1& session_type, uint16_t cookie) { + LOG(INFO) << __func__ << ": " << toString(session_type); + auto aidl_session_type = from_session_type_2_1(session_type); + BluetoothAudioSessionControl::UnregisterControlResultCback(aidl_session_type, + cookie); + auto& session_callback_table = legacy_callback_table[aidl_session_type]; + if (session_callback_table.find(cookie) != session_callback_table.end()) { + std::lock_guard guard(legacy_callback_lock); + session_callback_table.erase(cookie); + } +} + +const AudioConfig_2_2 HidlToAidlMiddleware_2_2::GetAudioConfig( + const SessionType_2_1& session_type) { + return to_hidl_audio_config_2_2(BluetoothAudioSessionControl::GetAudioConfig( + from_session_type_2_1(session_type))); +} + +bool HidlToAidlMiddleware_2_2::StartStream( + const SessionType_2_1& session_type) { + return BluetoothAudioSessionControl::StartStream( + from_session_type_2_1(session_type)); +} + +bool HidlToAidlMiddleware_2_2::SuspendStream( + const SessionType_2_1& session_type) { + return BluetoothAudioSessionControl::SuspendStream( + from_session_type_2_1(session_type)); +} + +void HidlToAidlMiddleware_2_2::StopStream(const SessionType_2_1& session_type) { + return BluetoothAudioSessionControl::StopStream( + from_session_type_2_1(session_type)); +} + +void HidlToAidlMiddleware_2_2::UpdateSinkMetadata( + const SessionType_2_1& session_type, + const struct sink_metadata* sink_metadata) { + return BluetoothAudioSessionControl::UpdateSinkMetadata( + from_session_type_2_1(session_type), *sink_metadata); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h new file mode 100644 index 0000000000..d10ee3759a --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2022 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 + +#include "../session/BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using SessionType_2_0 = + ::android::hardware::bluetooth::audio::V2_0::SessionType; +using PortStatusCallbacks_2_0 = + ::android::bluetooth::audio::PortStatusCallbacks; +using AudioConfig_2_0 = + ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration; + +class HidlToAidlMiddleware_2_0 { + public: + static bool IsAidlAvailable(); + + static bool IsSessionReady(const SessionType_2_0& session_type); + + static uint16_t RegisterControlResultCback( + const SessionType_2_0& session_type, + const PortStatusCallbacks_2_0& cbacks); + + static void UnregisterControlResultCback(const SessionType_2_0& session_type, + uint16_t cookie); + + static const AudioConfig_2_0 GetAudioConfig( + const SessionType_2_0& session_type); + + static bool StartStream(const SessionType_2_0& session_type); + + static void StopStream(const SessionType_2_0& session_type); + + static bool SuspendStream(const SessionType_2_0& session_type); + + static bool GetPresentationPosition(const SessionType_2_0& session_type, + uint64_t* remote_delay_report_ns, + uint64_t* total_bytes_readed, + timespec* data_position); + + static void UpdateTracksMetadata( + const SessionType_2_0& session_type, + const struct source_metadata* source_metadata); + + static size_t OutWritePcmData(const SessionType_2_0& session_type, + const void* buffer, size_t bytes); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h new file mode 100644 index 0000000000..82dce96d3e --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 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 + +#include "../session/BluetoothAudioSession.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using SessionType_2_1 = + ::android::hardware::bluetooth::audio::V2_1::SessionType; +using AudioConfig_2_1 = + ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration; + +class HidlToAidlMiddleware_2_1 { + public: + static const AudioConfig_2_1 GetAudioConfig( + const SessionType_2_1& session_type); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h new file mode 100644 index 0000000000..149e4042d1 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2022 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 + +#include "../session/BluetoothAudioSession.h" +#include "../session/BluetoothAudioSession_2_2.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using SessionType_2_1 = + ::android::hardware::bluetooth::audio::V2_1::SessionType; +using PortStatusCallbacks_2_0 = + ::android::bluetooth::audio::PortStatusCallbacks; +using PortStatusCallbacks_2_2 = + ::android::bluetooth::audio::PortStatusCallbacks_2_2; +using AudioConfig_2_2 = + ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration; + +class HidlToAidlMiddleware_2_2 { + public: + static bool IsSessionReady(const SessionType_2_1& session_type); + + static uint16_t RegisterControlResultCback( + const SessionType_2_1& session_type, + const PortStatusCallbacks_2_2& cbacks); + + static void UnregisterControlResultCback(const SessionType_2_1& session_type, + uint16_t cookie); + + static const AudioConfig_2_2 GetAudioConfig( + const SessionType_2_1& session_type); + + static bool StartStream(const SessionType_2_1& session_type); + + static bool SuspendStream(const SessionType_2_1& session_type); + + static void StopStream(const SessionType_2_1& session_type); + + static void UpdateSinkMetadata(const SessionType_2_1& session_type, + const struct sink_metadata* sink_metadata); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp index 2f3ddaf213..6d5608b0a4 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp @@ -21,10 +21,13 @@ #include #include +#include "../aidl_session/HidlToAidlMiddleware_2_0.h" + namespace android { namespace bluetooth { namespace audio { +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0; using ::android::hardware::audio::common::V5_0::AudioContentType; using ::android::hardware::audio::common::V5_0::AudioUsage; using ::android::hardware::audio::common::V5_0::PlaybackTrackMetadata; @@ -149,6 +152,8 @@ void BluetoothAudioSession::ReportControlStatus( // The function helps to check if this session is ready or not // @return: true if the Bluetooth stack has started the specified session bool BluetoothAudioSession::IsSessionReady() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::IsSessionReady(session_type_); std::lock_guard guard(mutex_); bool dataMQ_valid = (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH || @@ -200,6 +205,9 @@ bool BluetoothAudioSession::UpdateAudioConfig( // @return: cookie - the assigned number to this bluetooth_audio output uint16_t BluetoothAudioSession::RegisterStatusCback( const PortStatusCallbacks& cbacks) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::RegisterControlResultCback(session_type_, + cbacks); std::lock_guard guard(mutex_); uint16_t cookie = ObserversCookieGetInitValue(session_type_); uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_); @@ -227,6 +235,9 @@ uint16_t BluetoothAudioSession::RegisterStatusCback( // PortStatusCallbacks // @param: cookie - indicates which bluetooth_audio output is void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::UnregisterControlResultCback(session_type_, + cookie); std::lock_guard guard(mutex_); if (observers_.erase(cookie) != 1) { LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) @@ -238,6 +249,9 @@ void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) { // The control function is for the bluetooth_audio module to get the current // AudioConfiguration const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return (audio_config_ = + HidlToAidlMiddleware_2_0::GetAudioConfig(session_type_)); std::lock_guard guard(mutex_); if (IsSessionReady()) { return audio_config_; @@ -251,6 +265,8 @@ const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() { // Those control functions are for the bluetooth_audio module to start, suspend, // stop stream, to check position, and to update metadata. bool BluetoothAudioSession::StartStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::StartStream(session_type_); std::lock_guard guard(mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) @@ -267,6 +283,8 @@ bool BluetoothAudioSession::StartStream() { } bool BluetoothAudioSession::SuspendStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::SuspendStream(session_type_); std::lock_guard guard(mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) @@ -283,6 +301,8 @@ bool BluetoothAudioSession::SuspendStream() { } void BluetoothAudioSession::StopStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::StopStream(session_type_); std::lock_guard guard(mutex_); if (!IsSessionReady()) { return; @@ -297,6 +317,10 @@ void BluetoothAudioSession::StopStream() { bool BluetoothAudioSession::GetPresentationPosition( uint64_t* remote_delay_report_ns, uint64_t* total_bytes_readed, timespec* data_position) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::GetPresentationPosition( + session_type_, remote_delay_report_ns, total_bytes_readed, + data_position); std::lock_guard guard(mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) @@ -330,6 +354,9 @@ bool BluetoothAudioSession::GetPresentationPosition( void BluetoothAudioSession::UpdateTracksMetadata( const struct source_metadata* source_metadata) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::UpdateTracksMetadata(session_type_, + source_metadata); std::lock_guard guard(mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) @@ -374,6 +401,9 @@ void BluetoothAudioSession::UpdateTracksMetadata( // The control function writes stream to FMQ size_t BluetoothAudioSession::OutWritePcmData(const void* buffer, size_t bytes) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_0::OutWritePcmData(session_type_, buffer, + bytes); if (buffer == nullptr || !bytes) return 0; size_t totalWritten = 0; int ms_timeout = kFmqSendTimeoutMs; diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp index bf1f9b5b2a..276a291470 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp @@ -21,9 +21,14 @@ #include #include +#include "../aidl_session/HidlToAidlMiddleware_2_0.h" +#include "../aidl_session/HidlToAidlMiddleware_2_1.h" + namespace android { namespace bluetooth { namespace audio { +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0; +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_1; using SessionType_2_1 = ::android::hardware::bluetooth::audio::V2_1::SessionType; using SessionType_2_0 = @@ -72,6 +77,7 @@ BluetoothAudioSession_2_1::BluetoothAudioSession_2_1( } else { session_type_2_1_ = (session_type); } + raw_session_type_ = session_type; } std::shared_ptr @@ -83,6 +89,8 @@ BluetoothAudioSession_2_1::GetAudioSession() { // AudioConfiguration const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration BluetoothAudioSession_2_1::GetAudioConfig() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_1::GetAudioConfig(raw_session_type_); std::lock_guard guard(audio_session->mutex_); if (audio_session->IsSessionReady()) { // If session is unknown it means it should be 2.0 type diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h index 5a351531a3..e6340649d8 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h @@ -31,6 +31,7 @@ class BluetoothAudioSession_2_1 { std::shared_ptr audio_session; ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_; + ::android::hardware::bluetooth::audio::V2_1::SessionType raw_session_type_; // audio data configuration for both software and offloading ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp index 60ac4ece6f..4613ddc05a 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp @@ -22,10 +22,15 @@ #include #include +#include "../aidl_session/HidlToAidlMiddleware_2_0.h" +#include "../aidl_session/HidlToAidlMiddleware_2_2.h" + namespace android { namespace bluetooth { namespace audio { +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0; +using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_2; using ::android::hardware::audio::common::V5_0::AudioSource; using ::android::hardware::audio::common::V5_0::RecordTrackMetadata; using ::android::hardware::audio::common::V5_0::SinkMetadata; @@ -93,6 +98,7 @@ BluetoothAudioSession_2_2::BluetoothAudioSession_2_2( } else { session_type_2_1_ = (session_type); } + raw_session_type_ = session_type; invalidSoftwareAudioConfiguration.pcmConfig(kInvalidPcmParameters); invalidOffloadAudioConfiguration.codecConfig( audio_session->kInvalidCodecConfiguration); @@ -100,6 +106,8 @@ BluetoothAudioSession_2_2::BluetoothAudioSession_2_2( } bool BluetoothAudioSession_2_2::IsSessionReady() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::IsSessionReady(raw_session_type_); if (session_type_2_1_ != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && session_type_2_1_ != @@ -122,6 +130,9 @@ BluetoothAudioSession_2_2::GetAudioSession_2_1() { void BluetoothAudioSession_2_2::UpdateSinkMetadata( const struct sink_metadata* sink_metadata) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::UpdateSinkMetadata(raw_session_type_, + sink_metadata); std::lock_guard guard(audio_session->mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_) @@ -172,6 +183,8 @@ void BluetoothAudioSession_2_2::UpdateSinkMetadata( // AudioConfiguration const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration BluetoothAudioSession_2_2::GetAudioConfig() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::GetAudioConfig(raw_session_type_); std::lock_guard guard(audio_session->mutex_); if (IsSessionReady()) { auto audio_config_discriminator = audio_config_2_2_.getDiscriminator(); @@ -226,6 +239,8 @@ BluetoothAudioSession_2_2::GetAudioConfig() { // Those control functions are for the bluetooth_audio module to start, suspend, // stop stream, to check position, and to update metadata. bool BluetoothAudioSession_2_2::StartStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::StartStream(raw_session_type_); std::lock_guard guard(audio_session->mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_) @@ -242,6 +257,8 @@ bool BluetoothAudioSession_2_2::StartStream() { } bool BluetoothAudioSession_2_2::SuspendStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::SuspendStream(raw_session_type_); std::lock_guard guard(audio_session->mutex_); if (!IsSessionReady()) { LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_) @@ -258,6 +275,8 @@ bool BluetoothAudioSession_2_2::SuspendStream() { } void BluetoothAudioSession_2_2::StopStream() { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::StopStream(raw_session_type_); std::lock_guard guard(audio_session->mutex_); if (!IsSessionReady()) { return; @@ -395,6 +414,9 @@ void BluetoothAudioSession_2_2::OnSessionEnded() { // @return: cookie - the assigned number to this bluetooth_audio output uint16_t BluetoothAudioSession_2_2::RegisterStatusCback( const PortStatusCallbacks_2_2& cbacks) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::RegisterControlResultCback( + raw_session_type_, cbacks); if (session_type_2_1_ != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && session_type_2_1_ != @@ -432,6 +454,9 @@ uint16_t BluetoothAudioSession_2_2::RegisterStatusCback( // PortStatusCallbacks_2_2 // @param: cookie - indicates which bluetooth_audio output is void BluetoothAudioSession_2_2::UnregisterStatusCback(uint16_t cookie) { + if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) + return HidlToAidlMiddleware_2_2::UnregisterControlResultCback( + raw_session_type_, cookie); std::lock_guard guard(audio_session->mutex_); if (session_type_2_1_ != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h index 3673fd8ccf..b6f96ab25c 100644 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h +++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h @@ -68,6 +68,7 @@ class BluetoothAudioSession_2_2 { std::shared_ptr audio_session_2_1; ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_; + ::android::hardware::bluetooth::audio::V2_1::SessionType raw_session_type_; // audio data configuration for both software and offloading ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration -- cgit v1.2.3 From 6ab53e76a3d1f7969c95668aa254987aeb818154 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Wed, 29 Dec 2021 23:53:33 -0800 Subject: Add Bluetooth Audio default AIDL implementation Test: manual Bug: 203490261 Change-Id: I39224ecdd18b9eb0626d6188442a33ef65820673 --- bluetooth/audio/aidl/Android.bp | 4 + .../aidl/default/A2dpOffloadAudioProvider.cpp | 71 +++++++++++ .../audio/aidl/default/A2dpOffloadAudioProvider.h | 45 +++++++ .../aidl/default/A2dpSoftwareAudioProvider.cpp | 100 +++++++++++++++ .../audio/aidl/default/A2dpSoftwareAudioProvider.h | 48 +++++++ bluetooth/audio/aidl/default/Android.bp | 34 +++++ .../audio/aidl/default/BluetoothAudioProvider.cpp | 138 +++++++++++++++++++++ .../audio/aidl/default/BluetoothAudioProvider.h | 67 ++++++++++ .../aidl/default/BluetoothAudioProviderFactory.cpp | 124 ++++++++++++++++++ .../aidl/default/BluetoothAudioProviderFactory.h | 51 ++++++++ .../audio/aidl/default/HearingAidAudioProvider.cpp | 95 ++++++++++++++ .../audio/aidl/default/HearingAidAudioProvider.h | 48 +++++++ .../aidl/default/LeAudioOffloadAudioProvider.cpp | 83 +++++++++++++ .../aidl/default/LeAudioOffloadAudioProvider.h | 55 ++++++++ .../aidl/default/LeAudioSoftwareAudioProvider.cpp | 125 +++++++++++++++++++ .../aidl/default/LeAudioSoftwareAudioProvider.h | 58 +++++++++ bluetooth/audio/aidl/default/bluetooth_audio.xml | 6 + 17 files changed, 1152 insertions(+) create mode 100644 bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp create mode 100644 bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h create mode 100644 bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp create mode 100644 bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h create mode 100644 bluetooth/audio/aidl/default/Android.bp create mode 100644 bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp create mode 100644 bluetooth/audio/aidl/default/BluetoothAudioProvider.h create mode 100644 bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp create mode 100644 bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h create mode 100644 bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp create mode 100644 bluetooth/audio/aidl/default/HearingAidAudioProvider.h create mode 100644 bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp create mode 100644 bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h create mode 100644 bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp create mode 100644 bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h create mode 100644 bluetooth/audio/aidl/default/bluetooth_audio.xml diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp index 12eed55072..5107240957 100644 --- a/bluetooth/audio/aidl/Android.bp +++ b/bluetooth/audio/aidl/Android.bp @@ -43,6 +43,10 @@ aidl_interface { vndk: { enabled: true, }, + apex_available: [ + "//apex_available:platform", + "com.android.bluetooth", + ], }, }, } diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp new file mode 100644 index 0000000000..fc8a911145 --- /dev/null +++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2022 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 "BTAudioProviderA2dpHW" + +#include "A2dpOffloadAudioProvider.h" + +#include +#include +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +A2dpOffloadAudioProvider::A2dpOffloadAudioProvider() { + session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH; +} + +bool A2dpOffloadAudioProvider::isValid(const SessionType& session_type) { + return (session_type == session_type_); +} + +ndk::ScopedAStatus A2dpOffloadAudioProvider::startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::a2dpConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid( + session_type_, audio_config.get())) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus A2dpOffloadAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + *_aidl_return = DataMQDesc(); + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + nullptr, *audio_config_); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h new file mode 100644 index 0000000000..5934f5b32d --- /dev/null +++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class A2dpOffloadAudioProvider : public BluetoothAudioProvider { + public: + A2dpOffloadAudioProvider(); + + bool isValid(const SessionType& session_type) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp new file mode 100644 index 0000000000..7e4907409e --- /dev/null +++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2022 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 "BTAudioProviderA2dpSW" + +#include "A2dpSoftwareAudioProvider.h" + +#include +#include +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +// Here the buffer size is based on SBC +static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo +// SBC is 128, and here we choose the LCM of 16, 24, and 32 +static constexpr uint32_t kPcmFrameCount = 96; +static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount; +// The max counts by 1 tick (20ms) for SBC is about 7. Since using 96 for the +// PCM counts, here we just choose a greater number +static constexpr uint32_t kRtpFrameCount = 10; +static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount; +static constexpr uint32_t kBufferCount = 2; // double buffer +static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount; + +A2dpSoftwareAudioProvider::A2dpSoftwareAudioProvider() + : BluetoothAudioProvider(), data_mq_(nullptr) { + LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize + << " byte(s)"; + std::unique_ptr data_mq( + new DataMQ(kDataMqSize, /* EventFlag */ true)); + if (data_mq && data_mq->isValid()) { + data_mq_ = std::move(data_mq); + session_type_ = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH; + } else { + ALOGE_IF(!data_mq, "failed to allocate data MQ"); + ALOGE_IF(data_mq && !data_mq->isValid(), "data MQ is invalid"); + } +} + +bool A2dpSoftwareAudioProvider::isValid(const SessionType& sessionType) { + return (sessionType == session_type_ && data_mq_ && data_mq_->isValid()); +} + +ndk::ScopedAStatus A2dpSoftwareAudioProvider::startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::pcmConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + const PcmConfiguration& pcm_config = + audio_config.get(); + if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) { + LOG(WARNING) << __func__ << " - Unsupported PCM Configuration=" + << pcm_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus A2dpSoftwareAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + if (data_mq_ == nullptr || !data_mq_->isValid()) { + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + *_aidl_return = data_mq_->dupeDesc(); + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + _aidl_return, *audio_config_); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h new file mode 100644 index 0000000000..3bc0a135dd --- /dev/null +++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class A2dpSoftwareAudioProvider : public BluetoothAudioProvider { + public: + A2dpSoftwareAudioProvider(); + + bool isValid(const SessionType& sessionType) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + // audio data queue for software encoding + std::unique_ptr data_mq_; + + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp new file mode 100644 index 0000000000..846702fa0e --- /dev/null +++ b/bluetooth/audio/aidl/default/Android.bp @@ -0,0 +1,34 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_library_shared { + name: "android.hardware.bluetooth.audio-V1-impl", + vendor: true, + vintf_fragments: ["bluetooth_audio.xml"], + srcs: [ + "BluetoothAudioProvider.cpp", + "BluetoothAudioProviderFactory.cpp", + "A2dpOffloadAudioProvider.cpp", + "A2dpSoftwareAudioProvider.cpp", + "HearingAidAudioProvider.cpp", + "LeAudioOffloadAudioProvider.cpp", + "LeAudioSoftwareAudioProvider.cpp", + ], + export_include_dirs: ["."], + header_libs: ["libhardware_headers"], + shared_libs: [ + "libbase", + "libbinder_ndk", + "libcutils", + "libfmq", + "liblog", + "android.hardware.bluetooth.audio-V1-ndk", + "libbluetooth_audio_session_aidl", + ], +} diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp new file mode 100644 index 0000000000..c2ffa2efa2 --- /dev/null +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2022 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 "BTAudioProviderStub" + +#include "BluetoothAudioProvider.h" + +#include +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +BluetoothAudioProvider::BluetoothAudioProvider() { + death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient( + AIBinder_DeathRecipient_new(binderDiedCallbackAidl)); +} + +ndk::ScopedAStatus BluetoothAudioProvider::startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (host_if == nullptr) { + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + audio_config_ = std::make_unique(audio_config); + stack_iface_ = host_if; + + AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(), + this); + + onSessionReady(_aidl_return); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProvider::endSession() { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); + + if (stack_iface_ != nullptr) { + BluetoothAudioSessionReport::OnSessionEnded(session_type_); + + AIBinder_unlinkToDeath(stack_iface_->asBinder().get(), + death_recipient_.get(), this); + } else { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + } + + stack_iface_ = nullptr; + audio_config_ = nullptr; + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProvider::streamStarted( + BluetoothAudioStatus status) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << ", status=" << toString(status); + + if (stack_iface_ != nullptr) { + BluetoothAudioSessionReport::ReportControlStatus(session_type_, true, + status); + } else { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << ", status=" << toString(status) << " has NO session"; + } + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProvider::streamSuspended( + BluetoothAudioStatus status) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << ", status=" << toString(status); + + if (stack_iface_ != nullptr) { + BluetoothAudioSessionReport::ReportControlStatus(session_type_, false, + status); + } else { + LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) + << ", status=" << toString(status) << " has NO session"; + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProvider::updateAudioConfiguration( + const AudioConfiguration& audio_config) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); + + if (stack_iface_ == nullptr || audio_config_ == nullptr) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " has NO session"; + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + if (audio_config.getTag() != audio_config_->getTag()) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) + << " audio config type is not match"; + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + audio_config_ = std::make_unique(audio_config); + BluetoothAudioSessionReport::ReportAudioConfigChanged(session_type_, + *audio_config_); + return ndk::ScopedAStatus::ok(); +} + +void BluetoothAudioProvider::binderDiedCallbackAidl(void* ptr) { + LOG(ERROR) << __func__ << " - BluetoothAudio Service died"; + auto provider = static_cast(ptr); + if (provider == nullptr) { + LOG(ERROR) << __func__ << ": Null AudioProvider HAL died"; + return; + } + provider->endSession(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h new file mode 100644 index 0000000000..f7acbdf7e3 --- /dev/null +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include + +using ::aidl::android::hardware::common::fmq::MQDescriptor; +using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; +using ::android::AidlMessageQueue; + +using MqDataType = int8_t; +using MqDataMode = SynchronizedReadWrite; +using DataMQ = AidlMessageQueue; +using DataMQDesc = MQDescriptor; + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioProvider : public BnBluetoothAudioProvider { + public: + BluetoothAudioProvider(); + + ndk::ScopedAStatus startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + ndk::ScopedAStatus endSession(); + ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status); + ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status); + ndk::ScopedAStatus updateAudioConfiguration( + const AudioConfiguration& audio_config); + + virtual bool isValid(const SessionType& sessionType) = 0; + + protected: + virtual ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) = 0; + static void binderDiedCallbackAidl(void* cookie_ptr); + + ::ndk::ScopedAIBinder_DeathRecipient death_recipient_; + + std::shared_ptr stack_iface_; + std::unique_ptr audio_config_ = nullptr; + SessionType session_type_; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp new file mode 100644 index 0000000000..8e6cee7b2f --- /dev/null +++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2022 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 "BTAudioProvidersFactory" + +#include "BluetoothAudioProviderFactory.h" + +#include +#include + +#include "A2dpOffloadAudioProvider.h" +#include "A2dpSoftwareAudioProvider.h" +#include "BluetoothAudioProvider.h" +#include "HearingAidAudioProvider.h" +#include "LeAudioOffloadAudioProvider.h" +#include "LeAudioSoftwareAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {} + +ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider( + const SessionType session_type, + std::shared_ptr* _aidl_return) { + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type); + std::shared_ptr provider = nullptr; + + switch (session_type) { + case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make(); + break; + case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make(); + break; + case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make(); + break; + case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make(); + break; + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH: + provider = ndk::SharedRefBase::make(); + break; + case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH: + provider = ndk::SharedRefBase::make(); + break; + case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH: + provider = ndk::SharedRefBase::make(); + break; + default: + provider = nullptr; + break; + } + + if (provider == nullptr || !provider->isValid(session_type)) { + provider = nullptr; + LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + *_aidl_return = provider; + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderCapabilities( + const SessionType session_type, + std::vector* _aidl_return) { + if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + auto codec_capabilities = + BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(session_type); + _aidl_return->resize(codec_capabilities.size()); + for (int i = 0; i < codec_capabilities.size(); i++) { + _aidl_return->at(i).set( + codec_capabilities[i]); + } + } else if (session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { + std::vector db_codec_capabilities = + BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(session_type); + if (db_codec_capabilities.size()) { + _aidl_return->resize(db_codec_capabilities.size()); + for (int i = 0; i < db_codec_capabilities.size(); ++i) { + _aidl_return->at(i).set( + db_codec_capabilities[i]); + } + } + } else if (session_type != SessionType::UNKNOWN) { + auto pcm_capabilities = BluetoothAudioCodecs::GetSoftwarePcmCapabilities(); + _aidl_return->resize(pcm_capabilities.size()); + for (int i = 0; i < pcm_capabilities.size(); i++) { + _aidl_return->at(i).set( + pcm_capabilities[i]); + } + } + + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type) + << " supports " << _aidl_return->size() << " codecs"; + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h new file mode 100644 index 0000000000..96d888c166 --- /dev/null +++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "A2dpOffloadAudioProvider.h" +#include "A2dpSoftwareAudioProvider.h" +#include "BluetoothAudioProvider.h" +#include "HearingAidAudioProvider.h" +#include "LeAudioOffloadAudioProvider.h" +#include "LeAudioSoftwareAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothAudioProviderFactory : public BnBluetoothAudioProviderFactory { + public: + BluetoothAudioProviderFactory(); + + ndk::ScopedAStatus openProvider( + const SessionType session_type, + std::shared_ptr* _aidl_return) override; + + ndk::ScopedAStatus getProviderCapabilities( + const SessionType session_type, + std::vector* _aidl_return) override; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp new file mode 100644 index 0000000000..a993059b65 --- /dev/null +++ b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2022 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 "BTAudioProviderHearingAid" + +#include "HearingAidAudioProvider.h" + +#include +#include +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo +static constexpr uint32_t kPcmFrameCount = 128; +static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount; +static constexpr uint32_t kRtpFrameCount = 7; // max counts by 1 tick (20ms) +static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount; +static constexpr uint32_t kBufferCount = 1; // single buffer +static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount; + +HearingAidAudioProvider::HearingAidAudioProvider() + : BluetoothAudioProvider(), data_mq_(nullptr) { + LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize + << " byte(s)"; + std::unique_ptr data_mq( + new DataMQ(kDataMqSize, /* EventFlag */ true)); + if (data_mq && data_mq->isValid()) { + data_mq_ = std::move(data_mq); + session_type_ = SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH; + } else { + ALOGE_IF(!data_mq, "failed to allocate data MQ"); + ALOGE_IF(data_mq && !data_mq->isValid(), "data MQ is invalid"); + } +} +bool HearingAidAudioProvider::isValid(const SessionType& sessionType) { + return (sessionType == session_type_ && data_mq_ && data_mq_->isValid()); +} + +ndk::ScopedAStatus HearingAidAudioProvider::startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::pcmConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + const auto& pcm_config = audio_config.get(); + if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) { + LOG(WARNING) << __func__ << " - Unsupported PCM Configuration=" + << pcm_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus HearingAidAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + if (data_mq_ == nullptr || !data_mq_->isValid()) { + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + auto desc = data_mq_->dupeDesc(); + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + &desc, *audio_config_); + *_aidl_return = data_mq_->dupeDesc(); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/aidl/default/HearingAidAudioProvider.h b/bluetooth/audio/aidl/default/HearingAidAudioProvider.h new file mode 100644 index 0000000000..a7e19e982d --- /dev/null +++ b/bluetooth/audio/aidl/default/HearingAidAudioProvider.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class HearingAidAudioProvider : public BluetoothAudioProvider { + public: + HearingAidAudioProvider(); + + bool isValid(const SessionType& sessionType) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + // audio data queue for software encoding + std::unique_ptr data_mq_; + + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp new file mode 100644 index 0000000000..4078783c99 --- /dev/null +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022 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 "BTAudioProviderLeAudioSW" + +#include "LeAudioOffloadAudioProvider.h" + +#include +#include +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider() + : LeAudioOffloadAudioProvider() { + session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH; +} + +LeAudioOffloadInputAudioProvider::LeAudioOffloadInputAudioProvider() + : LeAudioOffloadAudioProvider() { + session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH; +} + +LeAudioOffloadAudioProvider::LeAudioOffloadAudioProvider() + : BluetoothAudioProvider() {} + +bool LeAudioOffloadAudioProvider::isValid(const SessionType& sessionType) { + return (sessionType == session_type_); +} + +ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::leAudioConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + const auto& le_audio_config = + audio_config.get(); + if (!BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid( + session_type_, le_audio_config)) { + LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration=" + << le_audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + nullptr, *audio_config_); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h new file mode 100644 index 0000000000..a27a2e71ce --- /dev/null +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { + public: + LeAudioOffloadAudioProvider(); + + bool isValid(const SessionType& sessionType) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider { + public: + LeAudioOffloadOutputAudioProvider(); +}; + +class LeAudioOffloadInputAudioProvider : public LeAudioOffloadAudioProvider { + public: + LeAudioOffloadInputAudioProvider(); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp new file mode 100644 index 0000000000..f9962fd9d9 --- /dev/null +++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2022 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 "BTAudioProviderLeAudioHW" + +#include "LeAudioSoftwareAudioProvider.h" + +#include +#include +#include + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +static constexpr uint32_t kBufferOutCount = 2; // two frame buffer +static constexpr uint32_t kBufferInCount = 2; // two frame buffer + +inline uint32_t channel_mode_to_channel_count(ChannelMode channel_mode) { + switch (channel_mode) { + case ChannelMode::MONO: + return 1; + case ChannelMode::STEREO: + return 2; + default: + return 0; + } + return 0; +} + +LeAudioSoftwareOutputAudioProvider::LeAudioSoftwareOutputAudioProvider() + : LeAudioSoftwareAudioProvider() { + session_type_ = SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH; +} + +LeAudioSoftwareInputAudioProvider::LeAudioSoftwareInputAudioProvider() + : LeAudioSoftwareAudioProvider() { + session_type_ = SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH; +} + +LeAudioSoftwareAudioProvider::LeAudioSoftwareAudioProvider() + : BluetoothAudioProvider(), data_mq_(nullptr) {} + +bool LeAudioSoftwareAudioProvider::isValid(const SessionType& sessionType) { + return (sessionType == session_type_); +} + +ndk::ScopedAStatus LeAudioSoftwareAudioProvider::startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) { + if (audio_config.getTag() != AudioConfiguration::pcmConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + const auto& pcm_config = audio_config.get(); + if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) { + LOG(WARNING) << __func__ << " - Unsupported PCM Configuration=" + << pcm_config.toString(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + uint32_t buffer_modifier = 0; + if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH) + buffer_modifier = kBufferOutCount; + else if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH) + buffer_modifier = kBufferInCount; + + uint32_t data_mq_size = + (ceil(pcm_config.sampleRateHz) / 1000) * + channel_mode_to_channel_count(pcm_config.channelMode) * + (pcm_config.bitsPerSample / 8) * (pcm_config.dataIntervalUs / 1000) * + buffer_modifier; + + LOG(INFO) << __func__ << " - size of audio buffer " << data_mq_size + << " byte(s)"; + + std::unique_ptr temp_data_mq( + new DataMQ(data_mq_size, /* EventFlag */ true)); + if (temp_data_mq == nullptr || !temp_data_mq->isValid()) { + ALOGE_IF(!temp_data_mq, "failed to allocate data MQ"); + ALOGE_IF(temp_data_mq && !temp_data_mq->isValid(), "data MQ is invalid"); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + data_mq_ = std::move(temp_data_mq); + + return BluetoothAudioProvider::startSession(host_if, audio_config, + _aidl_return); +} + +ndk::ScopedAStatus LeAudioSoftwareAudioProvider::onSessionReady( + DataMQDesc* _aidl_return) { + if (data_mq_ == nullptr || !data_mq_->isValid()) { + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + *_aidl_return = data_mq_->dupeDesc(); + BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_, + _aidl_return, *audio_config_); + return ndk::ScopedAStatus::ok(); +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h new file mode 100644 index 0000000000..fa581820c6 --- /dev/null +++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BluetoothAudioProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class LeAudioSoftwareAudioProvider : public BluetoothAudioProvider { + public: + LeAudioSoftwareAudioProvider(); + + bool isValid(const SessionType& sessionType) override; + + ndk::ScopedAStatus startSession( + const std::shared_ptr& host_if, + const AudioConfiguration& audio_config, DataMQDesc* _aidl_return); + + private: + // audio data queue for software encoding + std::unique_ptr data_mq_; + + ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; +}; + +class LeAudioSoftwareOutputAudioProvider : public LeAudioSoftwareAudioProvider { + public: + LeAudioSoftwareOutputAudioProvider(); +}; + +class LeAudioSoftwareInputAudioProvider : public LeAudioSoftwareAudioProvider { + public: + LeAudioSoftwareInputAudioProvider(); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/aidl/default/bluetooth_audio.xml b/bluetooth/audio/aidl/default/bluetooth_audio.xml new file mode 100644 index 0000000000..1859a1a366 --- /dev/null +++ b/bluetooth/audio/aidl/default/bluetooth_audio.xml @@ -0,0 +1,6 @@ + + + android.hardware.bluetooth.audio + IBluetoothAudioProviderFactory/default + + \ No newline at end of file -- cgit v1.2.3 From cd938514bad68ee561fe94a302ceba0bb1a9995d Mon Sep 17 00:00:00 2001 From: Alan Stokes Date: Mon, 17 Jan 2022 10:37:54 +0000 Subject: Allow CompOS to use DICE Bug: 214233409 Test: Builds Change-Id: I1640b64fbb4b63097106dba56269fe1cac6d1679 --- security/dice/aidl/Android.bp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/security/dice/aidl/Android.bp b/security/dice/aidl/Android.bp index af9dd33c3b..01bc91e5eb 100644 --- a/security/dice/aidl/Android.bp +++ b/security/dice/aidl/Android.bp @@ -41,6 +41,10 @@ aidl_interface { }, rust: { enabled: true, + apex_available: [ + "//apex_available:platform", + "com.android.compos", + ], }, }, // versions: ["1"], -- cgit v1.2.3 From 4c7b8f8fd93576daba32591c812206044b272480 Mon Sep 17 00:00:00 2001 From: Edwin Tung Date: Fri, 14 Jan 2022 17:32:04 +0800 Subject: Combining GnssVisibilityControl to gnss aidl_interface Bug: 208728105 Test: atest VtsHalGnssTargetTest Change-Id: I7295a59a93778a186727e2a22c9669770f021d1a --- gnss/aidl/Android.bp | 23 ++----- .../visibility_control/IGnssVisibilityControl.aidl | 39 ------------ .../IGnssVisibilityControlCallback.aidl | 74 ---------------------- .../visibility_control/IGnssVisibilityControl.aidl | 39 ++++++++++++ .../IGnssVisibilityControlCallback.aidl | 74 ++++++++++++++++++++++ .../visibility_control/IGnssVisibilityControl.aidl | 2 +- gnss/aidl/default/Android.bp | 1 - gnss/aidl/vts/Android.bp | 1 - gnss/aidl/vts/gnss_hal_test_cases.cpp | 3 +- 9 files changed, 120 insertions(+), 136 deletions(-) delete mode 100644 gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl delete mode 100644 gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp index 12dd0ac16e..d90cf0b634 100644 --- a/gnss/aidl/Android.bp +++ b/gnss/aidl/Android.bp @@ -23,28 +23,13 @@ package { default_applicable_licenses: ["hardware_interfaces_license"], } -aidl_interface { - name: "android.hardware.gnss.visibility_control", - vendor_available: true, - srcs: ["android/hardware/gnss/visibility_control/*.aidl"], - stability: "vintf", - backend: { - java: { - platform_apis: true, - }, - ndk: { - vndk: { - enabled: true, - }, - }, - }, -} - aidl_interface { name: "android.hardware.gnss", vendor_available: true, - srcs: ["android/hardware/gnss/*.aidl"], - imports: ["android.hardware.gnss.visibility_control"], + srcs: [ + "android/hardware/gnss/*.aidl", + "android/hardware/gnss/visibility_control/*.aidl", + ], stability: "vintf", backend: { java: { diff --git a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl b/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl deleted file mode 100644 index 7ef08d2f52..0000000000 --- a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2021 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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.gnss.visibility_control; -@VintfStability -interface IGnssVisibilityControl { - void enableNfwLocationAccess(in String[] proxyApps); - void setCallback(in android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback callback); -} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl deleted file mode 100644 index 37e1886576..0000000000 --- a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2021 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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m -update-api`. -// -// You must not make a backward incompatible change to any AIDL file built -// with the aidl_interface module type with versions property set. The module -// type is used to build AIDL files in a way that they can be used across -// independently updatable components of the system. If a device is shipped -// with such a backward incompatible change, it has a high risk of breaking -// later when a module using the interface is updated, e.g., Mainline modules. - -package android.hardware.gnss.visibility_control; -@VintfStability -interface IGnssVisibilityControlCallback { - void nfwNotifyCb(in android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwNotification notification); - boolean isInEmergencySession(); - @Backing(type="int") @VintfStability - enum NfwProtocolStack { - CTRL_PLANE = 0, - SUPL = 1, - IMS = 10, - SIM = 11, - OTHER_PROTOCOL_STACK = 100, - } - @Backing(type="int") @VintfStability - enum NfwRequestor { - CARRIER = 0, - OEM = 10, - MODEM_CHIPSET_VENDOR = 11, - GNSS_CHIPSET_VENDOR = 12, - OTHER_CHIPSET_VENDOR = 13, - AUTOMOBILE_CLIENT = 20, - OTHER_REQUESTOR = 100, - } - @Backing(type="int") @VintfStability - enum NfwResponseType { - REJECTED = 0, - ACCEPTED_NO_LOCATION_PROVIDED = 1, - ACCEPTED_LOCATION_PROVIDED = 2, - } - @VintfStability - parcelable NfwNotification { - String proxyAppPackageName; - android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwProtocolStack protocolStack; - String otherProtocolStackName; - android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwRequestor requestor; - String requestorId; - android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwResponseType responseType; - boolean inEmergencyMode; - boolean isCachedLocation; - } -} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl new file mode 100644 index 0000000000..f6740992c4 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss.visibility_control; +@VintfStability +interface IGnssVisibilityControl { + void enableNfwLocationAccess(in @utf8InCpp String[] proxyApps); + void setCallback(in android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback callback); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl new file mode 100644 index 0000000000..37e1886576 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss.visibility_control; +@VintfStability +interface IGnssVisibilityControlCallback { + void nfwNotifyCb(in android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwNotification notification); + boolean isInEmergencySession(); + @Backing(type="int") @VintfStability + enum NfwProtocolStack { + CTRL_PLANE = 0, + SUPL = 1, + IMS = 10, + SIM = 11, + OTHER_PROTOCOL_STACK = 100, + } + @Backing(type="int") @VintfStability + enum NfwRequestor { + CARRIER = 0, + OEM = 10, + MODEM_CHIPSET_VENDOR = 11, + GNSS_CHIPSET_VENDOR = 12, + OTHER_CHIPSET_VENDOR = 13, + AUTOMOBILE_CLIENT = 20, + OTHER_REQUESTOR = 100, + } + @Backing(type="int") @VintfStability + enum NfwResponseType { + REJECTED = 0, + ACCEPTED_NO_LOCATION_PROVIDED = 1, + ACCEPTED_LOCATION_PROVIDED = 2, + } + @VintfStability + parcelable NfwNotification { + String proxyAppPackageName; + android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwProtocolStack protocolStack; + String otherProtocolStackName; + android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwRequestor requestor; + String requestorId; + android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwResponseType responseType; + boolean inEmergencyMode; + boolean isCachedLocation; + } +} diff --git a/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl index 93c3f2c94f..c9c15491fb 100644 --- a/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl +++ b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl @@ -71,7 +71,7 @@ interface IGnssVisibilityControl { * The package name of the proxy Android application follows the standard Java language * package naming format. For example, com.example.myapp. */ - void enableNfwLocationAccess(in String[] proxyApps); + void enableNfwLocationAccess(in @utf8InCpp String[] proxyApps); /** * Registers the callback for HAL implementation to use. diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 29c26d16ec..6d03279ea1 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -52,7 +52,6 @@ cc_binary { "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.measurement_corrections@1.0", "android.hardware.gnss.visibility_control@1.0", - "android.hardware.gnss.visibility_control-V1-ndk", "android.hardware.gnss-V2-ndk", ], srcs: [ diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index d532fad357..36497aa240 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -50,7 +50,6 @@ cc_test { static_libs: [ "android.hardware.gnss-V2-cpp", "android.hardware.gnss@common-vts-lib", - "android.hardware.gnss.visibility_control-V1-cpp", ], test_suites: [ "general-tests", diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index eec50b0a13..99d196debb 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -923,7 +923,8 @@ TEST_P(GnssHalTest, TestGnssVisibilityControlExtension) { status = iGnssVisibilityControl->setCallback(gnssVisibilityControlCallback); ASSERT_TRUE(status.isOk()); - std::vector proxyApps{String16("com.example.ims"), String16("com.example.mdt")}; + std::vector proxyApps{std::string("com.example.ims"), + std::string("com.example.mdt")}; status = iGnssVisibilityControl->enableNfwLocationAccess(proxyApps); ASSERT_TRUE(status.isOk()); } -- cgit v1.2.3 From 859200800c70a5780931abc8db40b7ade99eef12 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Tue, 11 Jan 2022 14:25:55 -0800 Subject: Add VTS tests for reusable execution. - Modified generated tests and validation tests to exercise reusable execution. - Add a scoped trace to print the test config when an error occurs Bug: 202405342 Bug: 202431255 Test: VtsHalNeuralnetworksTargetTest Change-Id: I3e2346903e430080ec4d926bf08daf6825ea4dce --- .../aidl/vts/functional/GeneratedTestHarness.cpp | 451 ++++++++++++--------- neuralnetworks/aidl/vts/functional/Utils.cpp | 11 + neuralnetworks/aidl/vts/functional/Utils.h | 2 + .../aidl/vts/functional/ValidateRequest.cpp | 53 +++ .../aidl/vts/functional/VtsHalNeuralnetworks.h | 2 + 5 files changed, 329 insertions(+), 190 deletions(-) diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp index f67fd34383..2460fbad86 100644 --- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp @@ -58,25 +58,52 @@ struct TestConfig { bool measureTiming; OutputType outputType; MemoryType memoryType; + bool reusable; // `reportSkipping` indicates if a test should print an info message in case // it is skipped. The field is set to true by default and is set to false in // quantization coupling tests to suppress skipping a test bool reportSkipping; - TestConfig(Executor executor, bool measureTiming, OutputType outputType, MemoryType memoryType) + TestConfig(Executor executor, bool measureTiming, OutputType outputType, MemoryType memoryType, + bool reusable) : executor(executor), measureTiming(measureTiming), outputType(outputType), memoryType(memoryType), + reusable(reusable), reportSkipping(true) {} TestConfig(Executor executor, bool measureTiming, OutputType outputType, MemoryType memoryType, - bool reportSkipping) + bool reusable, bool reportSkipping) : executor(executor), measureTiming(measureTiming), outputType(outputType), memoryType(memoryType), + reusable(reusable), reportSkipping(reportSkipping) {} }; +std::string toString(OutputType type) { + switch (type) { + case OutputType::FULLY_SPECIFIED: + return "FULLY_SPECIFIED"; + case OutputType::UNSPECIFIED: + return "UNSPECIFIED"; + case OutputType::INSUFFICIENT: + return "INSUFFICIENT"; + case OutputType::MISSED_DEADLINE: + return "MISSED_DEADLINE"; + } +} + +std::string toString(const TestConfig& config) { + std::stringstream ss; + ss << "TestConfig{.executor=" << toString(config.executor) + << ", .measureTiming=" << (config.measureTiming ? "true" : "false") + << ", .outputType=" << toString(config.outputType) + << ", .memoryType=" << toString(config.memoryType) + << ", .reusable=" << (config.reusable ? "true" : "false") << "}"; + return ss.str(); +} + enum class IOType { INPUT, OUTPUT }; class DeviceMemoryAllocator { @@ -558,209 +585,241 @@ void EvaluatePreparedModel(const std::shared_ptr& device, loopTimeoutDurationNs = 1 * kMillisecond; } - ErrorStatus executionStatus; - std::vector outputShapes; - Timing timing = kNoTiming; - switch (testConfig.executor) { - case Executor::SYNC: { - SCOPED_TRACE("synchronous"); - - ExecutionResult executionResult; - // execute - const auto ret = preparedModel->executeSynchronously(request, testConfig.measureTiming, - kNoDeadline, loopTimeoutDurationNs, - &executionResult); - ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) - << ret.getDescription(); - if (ret.isOk()) { - executionStatus = executionResult.outputSufficientSize - ? ErrorStatus::NONE - : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; - outputShapes = std::move(executionResult.outputShapes); - timing = executionResult.timing; - } else { - executionStatus = static_cast(ret.getServiceSpecificError()); - } - break; - } - case Executor::BURST: { - SCOPED_TRACE("burst"); - - // create burst - std::shared_ptr burst; - auto ret = preparedModel->configureExecutionBurst(&burst); - ASSERT_TRUE(ret.isOk()) << ret.getDescription(); - ASSERT_NE(nullptr, burst.get()); - - // associate a unique slot with each memory pool - int64_t currentSlot = 0; - std::vector slots; - slots.reserve(request.pools.size()); - for (const auto& pool : request.pools) { - if (pool.getTag() == RequestMemoryPool::Tag::pool) { - slots.push_back(currentSlot++); + std::shared_ptr execution; + if (testConfig.reusable) { + const auto ret = preparedModel->createReusableExecution(request, testConfig.measureTiming, + loopTimeoutDurationNs, &execution); + ASSERT_TRUE(ret.isOk()) << static_cast(ret.getServiceSpecificError()); + ASSERT_NE(nullptr, execution.get()); + } + + const auto executeAndCheckResults = [&preparedModel, &execution, &testConfig, &testModel, + &context, &request, loopTimeoutDurationNs, skipped]() { + ErrorStatus executionStatus; + std::vector outputShapes; + Timing timing = kNoTiming; + switch (testConfig.executor) { + case Executor::SYNC: { + SCOPED_TRACE("synchronous"); + + ExecutionResult executionResult; + // execute + ::ndk::ScopedAStatus ret; + if (testConfig.reusable) { + ret = execution->executeSynchronously(kNoDeadline, &executionResult); } else { - EXPECT_EQ(pool.getTag(), RequestMemoryPool::Tag::token); - slots.push_back(-1); + ret = preparedModel->executeSynchronously(request, testConfig.measureTiming, + kNoDeadline, loopTimeoutDurationNs, + &executionResult); } + ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) + << ret.getDescription(); + if (ret.isOk()) { + executionStatus = executionResult.outputSufficientSize + ? ErrorStatus::NONE + : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; + outputShapes = std::move(executionResult.outputShapes); + timing = executionResult.timing; + } else { + executionStatus = static_cast(ret.getServiceSpecificError()); + } + break; } + case Executor::BURST: { + SCOPED_TRACE("burst"); - ExecutionResult executionResult; - // execute - ret = burst->executeSynchronously(request, slots, testConfig.measureTiming, kNoDeadline, - loopTimeoutDurationNs, &executionResult); - ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) - << ret.getDescription(); - if (ret.isOk()) { - executionStatus = executionResult.outputSufficientSize - ? ErrorStatus::NONE - : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; - outputShapes = std::move(executionResult.outputShapes); - timing = executionResult.timing; - } else { - executionStatus = static_cast(ret.getServiceSpecificError()); - } - - // Mark each slot as unused after the execution. This is unnecessary because the burst - // is freed after this scope ends, but this is here to test the functionality. - for (int64_t slot : slots) { - ret = burst->releaseMemoryResource(slot); + // create burst + std::shared_ptr burst; + auto ret = preparedModel->configureExecutionBurst(&burst); ASSERT_TRUE(ret.isOk()) << ret.getDescription(); - } + ASSERT_NE(nullptr, burst.get()); + + // associate a unique slot with each memory pool + int64_t currentSlot = 0; + std::vector slots; + slots.reserve(request.pools.size()); + for (const auto& pool : request.pools) { + if (pool.getTag() == RequestMemoryPool::Tag::pool) { + slots.push_back(currentSlot++); + } else { + EXPECT_EQ(pool.getTag(), RequestMemoryPool::Tag::token); + slots.push_back(-1); + } + } - break; - } - case Executor::FENCED: { - SCOPED_TRACE("fenced"); - ErrorStatus result = ErrorStatus::NONE; - FencedExecutionResult executionResult; - auto ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming, - kNoDeadline, loopTimeoutDurationNs, kNoDuration, - &executionResult); - ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) - << ret.getDescription(); - if (!ret.isOk()) { - result = static_cast(ret.getServiceSpecificError()); - executionStatus = result; - } else if (executionResult.syncFence.get() != -1) { - std::vector waitFor; - auto dupFd = dup(executionResult.syncFence.get()); - ASSERT_NE(dupFd, -1); - waitFor.emplace_back(dupFd); - // If a sync fence is returned, try start another run waiting for the sync fence. - ret = preparedModel->executeFenced(request, waitFor, testConfig.measureTiming, - kNoDeadline, loopTimeoutDurationNs, kNoDuration, - &executionResult); - ASSERT_TRUE(ret.isOk()); - waitForSyncFence(executionResult.syncFence.get()); + ExecutionResult executionResult; + // execute + ret = burst->executeSynchronously(request, slots, testConfig.measureTiming, + kNoDeadline, loopTimeoutDurationNs, + &executionResult); + ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) + << ret.getDescription(); + if (ret.isOk()) { + executionStatus = executionResult.outputSufficientSize + ? ErrorStatus::NONE + : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; + outputShapes = std::move(executionResult.outputShapes); + timing = executionResult.timing; + } else { + executionStatus = static_cast(ret.getServiceSpecificError()); + } + + // Mark each slot as unused after the execution. This is unnecessary because the + // burst is freed after this scope ends, but this is here to test the functionality. + for (int64_t slot : slots) { + ret = burst->releaseMemoryResource(slot); + ASSERT_TRUE(ret.isOk()) << ret.getDescription(); + } + + break; } - if (result == ErrorStatus::NONE) { - ASSERT_NE(executionResult.callback, nullptr); - Timing timingFenced; - auto ret = executionResult.callback->getExecutionInfo(&timing, &timingFenced, - &executionStatus); - ASSERT_TRUE(ret.isOk()); + case Executor::FENCED: { + SCOPED_TRACE("fenced"); + ErrorStatus result = ErrorStatus::NONE; + FencedExecutionResult executionResult; + ::ndk::ScopedAStatus ret; + if (testConfig.reusable) { + ret = execution->executeFenced({}, kNoDeadline, kNoDuration, &executionResult); + } else { + ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming, + kNoDeadline, loopTimeoutDurationNs, + kNoDuration, &executionResult); + } + ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) + << ret.getDescription(); + if (!ret.isOk()) { + result = static_cast(ret.getServiceSpecificError()); + executionStatus = result; + } else if (executionResult.syncFence.get() != -1) { + std::vector waitFor; + auto dupFd = dup(executionResult.syncFence.get()); + ASSERT_NE(dupFd, -1); + waitFor.emplace_back(dupFd); + // If a sync fence is returned, try start another run waiting for the sync + // fence. + ret = preparedModel->executeFenced(request, waitFor, testConfig.measureTiming, + kNoDeadline, loopTimeoutDurationNs, + kNoDuration, &executionResult); + ASSERT_TRUE(ret.isOk()); + waitForSyncFence(executionResult.syncFence.get()); + } + if (result == ErrorStatus::NONE) { + ASSERT_NE(executionResult.callback, nullptr); + Timing timingFenced; + auto ret = executionResult.callback->getExecutionInfo(&timing, &timingFenced, + &executionStatus); + ASSERT_TRUE(ret.isOk()); + } + break; + } + default: { + FAIL() << "Unsupported execution mode for AIDL interface."; } - break; - } - default: { - FAIL() << "Unsupported execution mode for AIDL interface."; - } - } - - if (testConfig.outputType != OutputType::FULLY_SPECIFIED && - executionStatus == ErrorStatus::GENERAL_FAILURE) { - if (skipped != nullptr) { - *skipped = true; - } - if (!testConfig.reportSkipping) { - return; - } - LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot " - "execute model that it does not support."; - std::cout << "[ ] Early termination of test because vendor service cannot " - "execute model that it does not support." - << std::endl; - GTEST_SKIP(); - } - if (!testConfig.measureTiming) { - EXPECT_EQ(timing, kNoTiming); - } else { - if (timing.timeOnDeviceNs != -1 && timing.timeInDriverNs != -1) { - EXPECT_LE(timing.timeOnDeviceNs, timing.timeInDriverNs); } - } - switch (testConfig.outputType) { - case OutputType::FULLY_SPECIFIED: - if (testConfig.executor == Executor::FENCED && hasZeroSizedOutput(testModel)) { - // Executor::FENCED does not support zero-sized output. - ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); - return; + if (testConfig.outputType != OutputType::FULLY_SPECIFIED && + executionStatus == ErrorStatus::GENERAL_FAILURE) { + if (skipped != nullptr) { + *skipped = true; } - // If the model output operands are fully specified, outputShapes must be either - // either empty, or have the same number of elements as the number of outputs. - ASSERT_EQ(ErrorStatus::NONE, executionStatus); - ASSERT_TRUE(outputShapes.size() == 0 || - outputShapes.size() == testModel.main.outputIndexes.size()); - break; - case OutputType::UNSPECIFIED: - if (testConfig.executor == Executor::FENCED) { - // For Executor::FENCED, the output shape must be fully specified. - ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); + if (!testConfig.reportSkipping) { return; } - // If the model output operands are not fully specified, outputShapes must have - // the same number of elements as the number of outputs. - ASSERT_EQ(ErrorStatus::NONE, executionStatus); - ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size()); - break; - case OutputType::INSUFFICIENT: - if (testConfig.executor == Executor::FENCED) { - // For Executor::FENCED, the output shape must be fully specified. - ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); - return; + LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot " + "execute model that it does not support."; + std::cout << "[ ] Early termination of test because vendor service cannot " + "execute model that it does not support." + << std::endl; + GTEST_SKIP(); + } + if (!testConfig.measureTiming) { + EXPECT_EQ(timing, kNoTiming); + } else { + if (timing.timeOnDeviceNs != -1 && timing.timeInDriverNs != -1) { + EXPECT_LE(timing.timeOnDeviceNs, timing.timeInDriverNs); } - ASSERT_EQ(ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, executionStatus); - ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size()); - // Check that all returned output dimensions are at least as fully specified as the - // union of the information about the corresponding operand in the model and in the - // request. In this test, all model outputs have known rank with all dimensions - // unspecified, and no dimensional information is provided in the request. - for (uint32_t i = 0; i < outputShapes.size(); i++) { - ASSERT_EQ(outputShapes[i].isSufficient, i != kInsufficientOutputIndex); - const auto& actual = outputShapes[i].dimensions; - const auto& golden = - testModel.main.operands[testModel.main.outputIndexes[i]].dimensions; - ASSERT_EQ(actual.size(), golden.size()); - for (uint32_t j = 0; j < actual.size(); j++) { - if (actual[j] == 0) continue; - EXPECT_EQ(actual[j], golden[j]) << "index: " << j; + } + + switch (testConfig.outputType) { + case OutputType::FULLY_SPECIFIED: + if (testConfig.executor == Executor::FENCED && hasZeroSizedOutput(testModel)) { + // Executor::FENCED does not support zero-sized output. + ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); + return; } - } - return; - case OutputType::MISSED_DEADLINE: - ASSERT_TRUE(executionStatus == ErrorStatus::MISSED_DEADLINE_TRANSIENT || - executionStatus == ErrorStatus::MISSED_DEADLINE_PERSISTENT) - << "executionStatus = " << executionStatus; - return; - } + // If the model output operands are fully specified, outputShapes must be either + // either empty, or have the same number of elements as the number of outputs. + ASSERT_EQ(ErrorStatus::NONE, executionStatus); + ASSERT_TRUE(outputShapes.size() == 0 || + outputShapes.size() == testModel.main.outputIndexes.size()); + break; + case OutputType::UNSPECIFIED: + if (testConfig.executor == Executor::FENCED) { + // For Executor::FENCED, the output shape must be fully specified. + ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); + return; + } + // If the model output operands are not fully specified, outputShapes must have + // the same number of elements as the number of outputs. + ASSERT_EQ(ErrorStatus::NONE, executionStatus); + ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size()); + break; + case OutputType::INSUFFICIENT: + if (testConfig.executor == Executor::FENCED) { + // For Executor::FENCED, the output shape must be fully specified. + ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus); + return; + } + ASSERT_EQ(ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, executionStatus); + ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size()); + // Check that all returned output dimensions are at least as fully specified as the + // union of the information about the corresponding operand in the model and in the + // request. In this test, all model outputs have known rank with all dimensions + // unspecified, and no dimensional information is provided in the request. + for (uint32_t i = 0; i < outputShapes.size(); i++) { + ASSERT_EQ(outputShapes[i].isSufficient, i != kInsufficientOutputIndex); + const auto& actual = outputShapes[i].dimensions; + const auto& golden = + testModel.main.operands[testModel.main.outputIndexes[i]].dimensions; + ASSERT_EQ(actual.size(), golden.size()); + for (uint32_t j = 0; j < actual.size(); j++) { + if (actual[j] == 0) continue; + EXPECT_EQ(actual[j], golden[j]) << "index: " << j; + } + } + return; + case OutputType::MISSED_DEADLINE: + ASSERT_TRUE(executionStatus == ErrorStatus::MISSED_DEADLINE_TRANSIENT || + executionStatus == ErrorStatus::MISSED_DEADLINE_PERSISTENT) + << "executionStatus = " << executionStatus; + return; + } - // Go through all outputs, check returned output shapes. - for (uint32_t i = 0; i < outputShapes.size(); i++) { - EXPECT_TRUE(outputShapes[i].isSufficient); - const auto& expect = testModel.main.operands[testModel.main.outputIndexes[i]].dimensions; - const auto unsignedActual = nn::toUnsigned(outputShapes[i].dimensions); - ASSERT_TRUE(unsignedActual.has_value()); - const std::vector& actual = unsignedActual.value(); - EXPECT_EQ(expect, actual); - } + // Go through all outputs, check returned output shapes. + for (uint32_t i = 0; i < outputShapes.size(); i++) { + EXPECT_TRUE(outputShapes[i].isSufficient); + const auto& expect = + testModel.main.operands[testModel.main.outputIndexes[i]].dimensions; + const auto unsignedActual = nn::toUnsigned(outputShapes[i].dimensions); + ASSERT_TRUE(unsignedActual.has_value()); + const std::vector& actual = unsignedActual.value(); + EXPECT_EQ(expect, actual); + } + + // Retrieve execution results. + const std::vector outputs = context.getOutputBuffers(testModel, request); - // Retrieve execution results. - const std::vector outputs = context.getOutputBuffers(testModel, request); + // We want "close-enough" results. + checkResults(testModel, outputs); + }; - // We want "close-enough" results. - checkResults(testModel, outputs); + executeAndCheckResults(); + + // For reusable execution tests, run the execution twice. + if (testConfig.reusable) { + SCOPED_TRACE("Second execution"); + executeAndCheckResults(); + } } void EvaluatePreparedModel(const std::shared_ptr& device, @@ -770,6 +829,13 @@ void EvaluatePreparedModel(const std::shared_ptr& device, std::vector measureTimingList; std::vector executorList; std::vector memoryTypeList; + std::vector reusableList = {false}; + + int deviceVersion; + ASSERT_TRUE(device->getInterfaceVersion(&deviceVersion).isOk()); + if (deviceVersion >= kMinAidlLevelForFL8) { + reusableList.push_back(true); + } switch (testKind) { case TestKind::GENERAL: { @@ -812,8 +878,13 @@ void EvaluatePreparedModel(const std::shared_ptr& device, for (const bool measureTiming : measureTimingList) { for (const Executor executor : executorList) { for (const MemoryType memoryType : memoryTypeList) { - const TestConfig testConfig(executor, measureTiming, outputType, memoryType); - EvaluatePreparedModel(device, preparedModel, testModel, testConfig); + for (const bool reusable : reusableList) { + if (executor == Executor::BURST && reusable) continue; + const TestConfig testConfig(executor, measureTiming, outputType, memoryType, + reusable); + SCOPED_TRACE(toString(testConfig)); + EvaluatePreparedModel(device, preparedModel, testModel, testConfig); + } } } } @@ -833,7 +904,7 @@ void EvaluatePreparedCoupledModels(const std::shared_ptr& device, for (const bool measureTiming : measureTimingList) { for (const Executor executor : executorList) { const TestConfig testConfig(executor, measureTiming, outputType, MemoryType::ASHMEM, - /*reportSkipping=*/false); + /*reusable=*/false, /*reportSkipping=*/false); bool baseSkipped = false; EvaluatePreparedModel(device, preparedModel, testModel, testConfig, &baseSkipped); bool coupledSkipped = false; diff --git a/neuralnetworks/aidl/vts/functional/Utils.cpp b/neuralnetworks/aidl/vts/functional/Utils.cpp index 325a436f79..efd5bca517 100644 --- a/neuralnetworks/aidl/vts/functional/Utils.cpp +++ b/neuralnetworks/aidl/vts/functional/Utils.cpp @@ -177,6 +177,17 @@ std::string gtestCompliantName(std::string name) { return os << toString(errorStatus); } +std::string toString(MemoryType type) { + switch (type) { + case MemoryType::ASHMEM: + return "ASHMEM"; + case MemoryType::BLOB_AHWB: + return "BLOB_AHWB"; + case MemoryType::DEVICE: + return "DEVICE"; + } +} + Request ExecutionContext::createRequest(const TestModel& testModel, MemoryType memoryType) { CHECK(memoryType == MemoryType::ASHMEM || memoryType == MemoryType::BLOB_AHWB); diff --git a/neuralnetworks/aidl/vts/functional/Utils.h b/neuralnetworks/aidl/vts/functional/Utils.h index ca81418417..0db3f8c7f8 100644 --- a/neuralnetworks/aidl/vts/functional/Utils.h +++ b/neuralnetworks/aidl/vts/functional/Utils.h @@ -111,6 +111,8 @@ class TestBlobAHWB : public TestMemoryBase { enum class MemoryType { ASHMEM, BLOB_AHWB, DEVICE }; +std::string toString(MemoryType type); + // Manages the lifetime of memory resources used in an execution. class ExecutionContext { DISALLOW_COPY_AND_ASSIGN(ExecutionContext); diff --git a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp index 29e2471777..e8debf704c 100644 --- a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp +++ b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp @@ -36,6 +36,51 @@ using ExecutionMutation = std::function; ///////////////////////// UTILITY FUNCTIONS ///////////////////////// +// Test request validation with reusable execution. +static void validateReusableExecution(const std::shared_ptr& preparedModel, + const std::string& message, const Request& request, + bool measure) { + // createReusableExecution + std::shared_ptr execution; + { + SCOPED_TRACE(message + " [createReusableExecution]"); + const auto createStatus = preparedModel->createReusableExecution( + request, measure, kOmittedTimeoutDuration, &execution); + if (!createStatus.isOk()) { + ASSERT_EQ(createStatus.getExceptionCode(), EX_SERVICE_SPECIFIC); + ASSERT_EQ(static_cast(createStatus.getServiceSpecificError()), + ErrorStatus::INVALID_ARGUMENT); + ASSERT_EQ(nullptr, execution); + return; + } else { + ASSERT_NE(nullptr, execution); + } + } + + // synchronous + { + SCOPED_TRACE(message + " [executeSynchronously]"); + ExecutionResult executionResult; + const auto executeStatus = execution->executeSynchronously(kNoDeadline, &executionResult); + ASSERT_FALSE(executeStatus.isOk()); + ASSERT_EQ(executeStatus.getExceptionCode(), EX_SERVICE_SPECIFIC); + ASSERT_EQ(static_cast(executeStatus.getServiceSpecificError()), + ErrorStatus::INVALID_ARGUMENT); + } + + // fenced + { + SCOPED_TRACE(message + " [executeFenced]"); + FencedExecutionResult executionResult; + const auto executeStatus = + execution->executeFenced({}, kNoDeadline, kNoDuration, &executionResult); + ASSERT_FALSE(executeStatus.isOk()); + ASSERT_EQ(executeStatus.getExceptionCode(), EX_SERVICE_SPECIFIC); + ASSERT_EQ(static_cast(executeStatus.getServiceSpecificError()), + ErrorStatus::INVALID_ARGUMENT); + } +} + // Primary validation function. This function will take a valid request, apply a // mutation to it to invalidate the request, then pass it to interface calls // that use the request. @@ -101,6 +146,14 @@ static void validate(const std::shared_ptr& preparedModel, ASSERT_EQ(static_cast(executeStatus.getServiceSpecificError()), ErrorStatus::INVALID_ARGUMENT); } + + int32_t aidlVersion; + ASSERT_TRUE(preparedModel->getInterfaceVersion(&aidlVersion).isOk()); + + // validate reusable execution + if (aidlVersion >= kMinAidlLevelForFL8) { + validateReusableExecution(preparedModel, message, request, measure); + } } std::shared_ptr createBurst(const std::shared_ptr& preparedModel) { diff --git a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h index 4312d3a4a1..a900590791 100644 --- a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h +++ b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h @@ -30,6 +30,8 @@ namespace aidl::android::hardware::neuralnetworks::vts::functional { using NamedDevice = Named>; using NeuralNetworksAidlTestParam = NamedDevice; +constexpr int kMinAidlLevelForFL8 = 4; + class NeuralNetworksAidlTest : public testing::TestWithParam { protected: void SetUp() override; -- cgit v1.2.3 From 018fc3cac8b2361ad28a97685f9449a99326c9cd Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Tue, 5 Oct 2021 10:17:01 -0700 Subject: Define AIDL reusable execution interface. This CL defines the AIDL interface for reusable execution. This CL also fixes a stale statement in IBurst about deadlineNs: boot_clock should be used rather than steady_clock. Bug: 202405342 Bug: 202431255 Test: NNT_static Test: VtsHalNeuralnetworksTargetTest Change-Id: I07d26909081018ffd92264d76109a66d4a0de3bd Merged-In: I07d26909081018ffd92264d76109a66d4a0de3bd (cherry picked from commit 0d9b1a9d287d3751c305742af81850b7ceea0c6b) --- .../compatibility_matrix.current.xml | 2 +- .../hardware/neuralnetworks/IExecution.aidl | 39 ++++++ .../hardware/neuralnetworks/IPreparedModel.aidl | 1 + .../android/hardware/neuralnetworks/IBurst.aidl | 8 +- .../hardware/neuralnetworks/IExecution.aidl | 153 +++++++++++++++++++++ .../hardware/neuralnetworks/IPreparedModel.aidl | 44 +++++- 6 files changed, 237 insertions(+), 10 deletions(-) create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl create mode 100644 neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 6879a95dad..db99423428 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -411,7 +411,7 @@ android.hardware.neuralnetworks - 1-3 + 1-4 IDevice .* diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl new file mode 100644 index 0000000000..ab5275e582 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.neuralnetworks; +@VintfStability +interface IExecution { + android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in long deadlineNs); + android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in ParcelFileDescriptor[] waitFor, in long deadlineNs, in long durationNs); +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl index fccb5dc98e..f89956719e 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -37,6 +37,7 @@ interface IPreparedModel { android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs); android.hardware.neuralnetworks.IBurst configureExecutionBurst(); + android.hardware.neuralnetworks.IExecution createReusableExecution(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long loopTimeoutDurationNs); const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000; const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000; } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl index decdc481f1..b089c499c6 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl @@ -78,10 +78,10 @@ interface IBurst { * runs from the time the driver sees the call to the executeSynchronously * function to the time the driver returns from the function. * @param deadlineNs The time by which the execution is expected to complete. The time is - * measured in nanoseconds since epoch of the steady clock (as from - * std::chrono::steady_clock). If the execution cannot be finished by the - * deadline, the execution may be aborted. Passing -1 means the deadline is - * omitted. Other negative values are invalid. + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the execution cannot be finished + * by the deadline, the execution may be aborted. Passing -1 means the + * deadline is omitted. Other negative values are invalid. * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent * executing a {@link OperationType::WHILE} operation. If a loop * condition model does not output false within this duration, the diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl new file mode 100644 index 0000000000..3cb9c1a592 --- /dev/null +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2021 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.neuralnetworks; + +import android.hardware.neuralnetworks.ExecutionResult; +import android.hardware.neuralnetworks.FencedExecutionResult; + +/** + * IExecution represents a reusable execution object with request and most other execution + * properties fixed. It is used to launch executions. + * + * At most one execution may occur on a reusable execution object at any given time, either by + * means of executeSynchronously or executeFenced. + * + * An IExecution object is used to control a set of executions on the same prepared model with + * the same request and properties. IExecution objects enable some optimizations: + * (1) An IExecution object can preserve resources between executions. For example, a driver can + * map a memory object when the IExecution object is created and cache the mapping for reuse in + * subsequent executions. Any cached resource can be released when the IExecution object is + * destroyed. + * (2) Because an IExecution object may be used for at most one execution at a time, any transient + * execution resources such as intermediate tensors can be allocated once when the IExecution + * object is created and freed when the IExecution object is destroyed. + * (3) An IExecution object is created for a fixed request. This enables the implementation to apply + * request-specific optimizations. For example, an implementation can avoid request validation + * and conversions when the IExecution object is reused. An implementation may also choose to + * specialize the dynamic tensor shapes in the IExecution object according to the request. + */ +@VintfStability +interface IExecution { + /** + * Performs a synchronous execution on the reusable execution object. + * + * The execution is performed synchronously with respect to the caller. executeSynchronously + * must verify the inputs to the function are correct, and the usages of memory pools allocated + * by IDevice::allocate are valid. If there is an error, executeSynchronously must immediately + * return a service specific exception with the appropriate ErrorStatus value. If the inputs to + * the function are valid and there is no error, executeSynchronously must perform the + * execution, and must not return until the execution is complete. + * + * The caller must not change the content of any data object referenced by the 'request' + * provided in {@link IPreparedModel::createReusableExecution} (described by the + * {@link DataLocation} of a {@link RequestArgument}) until executeSynchronously returns. + * executeSynchronously must not change the content of any of the data objects corresponding to + * 'request' inputs. + * + * If the execution object was configured from a prepared model wherein all tensor operands have + * fully specified dimensions, and the inputs to the function are valid, and at execution time + * every operation's input operands have legal values, then the execution should complete + * successfully: there must be no failure unless the device itself is in a bad state. + * + * If the execution object was created with measureTiming being true and the execution is + * successful, the driver may report the timing information in the returning + * {@link ExecutionResult}. The duration runs from the time the driver sees the call to the time + * the driver returns from the function. + * + * executeSynchronously may be called with an optional deadline. If the execution is not able to + * be completed before the provided deadline, the execution may be aborted, and either + * {@link ErrorStatus::MISSED_DEADLINE_TRANSIENT} or {@link + * ErrorStatus::MISSED_DEADLINE_PERSISTENT} may be returned. The error due to an abort must be + * sent the same way as other errors, described above. + * + * @param deadlineNs The time by which the execution is expected to complete. The time is + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the execution cannot be finished + * by the deadline, the execution may be aborted. Passing -1 means the + * deadline is omitted. Other negative values are invalid. + * @return ExecutionResult parcelable, containing the status of the execution, output shapes + * and timing information. + * @throws ServiceSpecificException with one of the following ErrorStatus values: + * - DEVICE_UNAVAILABLE if driver is offline or busy + * - GENERAL_FAILURE if there is an unspecified error + * - INVALID_ARGUMENT if one of the input arguments is invalid + * - MISSED_DEADLINE_* if the execution is aborted because it cannot be completed by the + * deadline + * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver + */ + ExecutionResult executeSynchronously(in long deadlineNs); + + /** + * Launch a fenced asynchronous execution on the reusable execution object. + * + * The execution is performed asynchronously with respect to the caller. executeFenced must + * verify the inputs to the function are correct, and the usages of memory pools allocated by + * IDevice::allocate are valid. If there is an error, executeFenced must immediately return a + * service specific exception with the corresponding ErrorStatus. If the inputs to the function + * are valid and there is no error, executeFenced must dispatch an asynchronous task to perform + * the execution in the background, and immediately return a {@link FencedExecutionResult} + * containing two fields: a callback (which can be used by the client to query the duration and + * runtime error status) and a sync fence (which will be signaled once the execution is + * completed). If the task has finished before the call returns, syncFence file descriptor may + * be set to -1. The execution must wait for all the sync fences (if any) in waitFor to be + * signaled before starting the actual execution. + * + * When the asynchronous task has finished its execution, it must immediately signal the + * syncFence returned from the executeFenced call. After the syncFence is signaled, the task + * must not modify the content of any data object referenced by the 'request' provided in + * IPreparedModel::createReusableExecution (described by the {@link DataLocation} of a + * {@link RequestArgument}). + * + * executeFenced may be called with an optional deadline and an optional duration. If the + * execution is not able to be completed before the provided deadline or within the timeout + * duration (measured from when all sync fences in waitFor are signaled), whichever comes + * earlier, the execution may be aborted, and either + * {@link ErrorStatus::MISSED_DEADLINE_TRANSIENT} or {@link + * ErrorStatus::MISSED_DEADLINE_PERSISTENT} may be returned. The error due to an abort must be + * sent the same way as other errors, described above. + * + * If any of the sync fences in waitFor changes to error status after the executeFenced call + * succeeds, or the execution is aborted because it cannot finish before the deadline has been + * reached or the duration has elapsed, the driver must immediately set the returned syncFence + * to error status. + * + * @param waitFor A vector of sync fence file descriptors. Execution must not start until all + * sync fences have been signaled. + * @param deadlineNs The time by which the execution is expected to complete. The time is + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the execution cannot be finished + * by the deadline, the execution may be aborted. Passing -1 means the + * deadline is omitted. Other negative values are invalid. + * @param durationNs The length of time in nanoseconds within which the execution is expected + * to complete after all sync fences in waitFor are signaled. If the + * execution cannot be finished within the duration, the execution may be + * aborted. Passing -1 means the duration is omitted. Other negative values + * are invalid. + * @return The FencedExecutionResult parcelable, containing IFencedExecutionCallback and the + * sync fence. + * @throws ServiceSpecificException with one of the following ErrorStatus values: + * - DEVICE_UNAVAILABLE if driver is offline or busy + * - GENERAL_FAILURE if there is an unspecified error + * - INVALID_ARGUMENT if one of the input arguments is invalid, including fences in error + * states. + * - MISSED_DEADLINE_* if the execution is aborted because it cannot be completed by the + * deadline + * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver + */ + FencedExecutionResult executeFenced( + in ParcelFileDescriptor[] waitFor, in long deadlineNs, in long durationNs); +} diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl index 956b626dd9..79053e527f 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -21,6 +21,7 @@ import android.hardware.neuralnetworks.ErrorStatus; import android.hardware.neuralnetworks.ExecutionResult; import android.hardware.neuralnetworks.FencedExecutionResult; import android.hardware.neuralnetworks.IBurst; +import android.hardware.neuralnetworks.IExecution; import android.hardware.neuralnetworks.Request; /** @@ -105,11 +106,12 @@ interface IPreparedModel { * IDevice::allocate are valid. If there is an error, executeFenced must immediately return a * service specific exception with the corresponding ErrorStatus. If the inputs to the function * are valid and there is no error, executeFenced must dispatch an asynchronous task to perform - * the execution in the background, assign a sync fence that will be signaled once the execution - * is completed and immediately return a callback that can be used by the client to query the - * duration and runtime error status. If the task has finished before the call returns, - * syncFence file descriptor may be set to -1. The execution must wait for all the sync fences - * (if any) in waitFor to be signaled before starting the actual execution. + * the execution in the background, and immediately return a {@link FencedExecutionResult} + * containing two fields: a callback (which can be used by the client to query the duration and + * runtime error status) and a sync fence (which will be signaled once the execution is + * completed). If the task has finished before the call returns, syncFence file descriptor may + * be set to -1. The execution must wait for all the sync fences (if any) in waitFor to be + * signaled before starting the actual execution. * * When the asynchronous task has finished its execution, it must immediately signal the * syncFence returned from the executeFenced call. After the syncFence is signaled, the task @@ -186,4 +188,36 @@ interface IPreparedModel { * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver */ IBurst configureExecutionBurst(); + + /** + * Create a reusable execution object to launch multiple executions with the same request and + * properties. + * + * createReusableExecution must verify the inputs to the function are correct, and the usages of + * memory pools allocated by IDevice::allocate are valid. If there is an error, + * createReusableExecution must immediately return a service specific exception with the + * appropriate ErrorStatus value. If the inputs to the function are valid and there is no error, + * createReusableExecution must construct a reusable execution. + * + * @param request The input and output information on which the prepared model is to be + * executed. + * @param measure Specifies whether or not to measure duration of the execution. + * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent + * executing a {@link OperationType::WHILE} operation. If a loop + * condition model does not output false within this duration, the + * computation performed on the returned reusable execution object + * must be aborted. If -1 is provided, the maximum amount + * of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other + * negative values are invalid. When provided, the duration must + * not exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}. + * @return execution An IExecution object representing a reusable execution that has been + * specialized for a fixed request. + * @throws ServiceSpecificException with one of the following ErrorStatus values: + * - DEVICE_UNAVAILABLE if driver is offline or busy + * - GENERAL_FAILURE if there is an unspecified error + * - INVALID_ARGUMENT if one of the input arguments is invalid + * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver + */ + IExecution createReusableExecution( + in Request request, in boolean measureTiming, in long loopTimeoutDurationNs); } -- cgit v1.2.3 From 11f30c81ef7d45fd97bf0dcc3f3ba2ae42689504 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Tue, 5 Oct 2021 14:10:41 -0700 Subject: Reusable execution at HAL level -- HAL. This CL modifies the canonical/AIDL adapter to use IExecution object if available. Bug: 202405342 Bug: 202431255 Test: NNT_static Test: CtsNNAPITestCases Test: VtsHalNeuralnetworksTargetTest Change-Id: I6aac3c57f97ac87a5ba3f78cfd843fcc403decff Merged-In: I6aac3c57f97ac87a5ba3f78cfd843fcc403decff (cherry picked from commit 7f5c7d293c2dad462dc9c0f1f1a160fb2c2c9a9b) --- neuralnetworks/aidl/utils/Android.bp | 37 ++- .../aidl/utils/include/nnapi/hal/aidl/Callbacks.h | 3 + .../aidl/utils/include/nnapi/hal/aidl/Execution.h | 41 +++- .../utils/include/nnapi/hal/aidl/HalInterfaces.h | 5 + .../utils/include/nnapi/hal/aidl/PreparedModel.h | 6 +- .../aidl/utils/include/nnapi/hal/aidl/Utils.h | 2 + neuralnetworks/aidl/utils/src/Callbacks.cpp | 7 +- neuralnetworks/aidl/utils/src/Device.cpp | 4 +- neuralnetworks/aidl/utils/src/Execution.cpp | 45 ++-- neuralnetworks/aidl/utils/src/PreparedModel.cpp | 158 ++++++++----- neuralnetworks/aidl/utils/test/DeviceTest.cpp | 27 +-- neuralnetworks/aidl/utils/test/ExecutionTest.cpp | 254 +++++++++++++++++++++ neuralnetworks/aidl/utils/test/MockExecution.h | 47 ++++ neuralnetworks/aidl/utils/test/MockPreparedModel.h | 5 + .../aidl/utils/test/PreparedModelTest.cpp | 194 ++++++++++++---- neuralnetworks/aidl/utils/test/TestUtils.cpp | 44 ++++ neuralnetworks/aidl/utils/test/TestUtils.h | 43 ++++ .../aidl/vts/functional/MemoryDomainTests.cpp | 5 + .../aidl/include/nnapi/hal/aidl/Execution.h | 56 +++++ .../aidl/include/nnapi/hal/aidl/PreparedModel.h | 4 + .../utils/adapter/aidl/src/PreparedModel.cpp | 99 ++++++++ 21 files changed, 925 insertions(+), 161 deletions(-) create mode 100644 neuralnetworks/aidl/utils/test/ExecutionTest.cpp create mode 100644 neuralnetworks/aidl/utils/test/MockExecution.h create mode 100644 neuralnetworks/aidl/utils/test/TestUtils.cpp create mode 100644 neuralnetworks/aidl/utils/test/TestUtils.h create mode 100644 neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp index 37ad6d6cef..9437d5c651 100644 --- a/neuralnetworks/aidl/utils/Android.bp +++ b/neuralnetworks/aidl/utils/Android.bp @@ -26,7 +26,14 @@ package { cc_defaults { name: "neuralnetworks_utils_hal_aidl_defaults", defaults: ["neuralnetworks_utils_defaults"], - srcs: ["src/*"], + srcs: [ + // AIDL utils that a driver may depend on. + "src/BufferTracker.cpp", + "src/Conversions.cpp", + "src/HalUtils.cpp", + "src/Utils.cpp", + "src/ValidateHal.cpp", + ], local_include_dirs: ["include/nnapi/hal/aidl/"], export_include_dirs: ["include"], cflags: ["-Wthread-safety"], @@ -47,6 +54,7 @@ cc_defaults { }, } +// Deprecated. Remove once all modules depending on this are migrated away. cc_library_static { name: "neuralnetworks_utils_hal_aidl_v1", defaults: ["neuralnetworks_utils_hal_aidl_defaults"], @@ -55,20 +63,26 @@ cc_library_static { ], } -cc_library_static { - name: "neuralnetworks_utils_hal_aidl_v2", - defaults: ["neuralnetworks_utils_hal_aidl_defaults"], - shared_libs: [ - "android.hardware.neuralnetworks-V2-ndk", - ], -} - cc_library_static { name: "neuralnetworks_utils_hal_aidl", defaults: ["neuralnetworks_utils_hal_aidl_defaults"], + srcs: [ + // Additional AIDL utils for the runtime. + "src/Assertions.cpp", + "src/Buffer.cpp", + "src/Burst.cpp", + "src/Callbacks.cpp", + "src/Device.cpp", + "src/Execution.cpp", + "src/InvalidDevice.cpp", + "src/PreparedModel.cpp", + "src/ProtectCallback.cpp", + "src/Service.cpp", + ], shared_libs: [ - "android.hardware.neuralnetworks-V3-ndk", + "android.hardware.neuralnetworks-V4-ndk", ], + cflags: ["-DNN_AIDL_V4_OR_ABOVE"], } // A cc_defaults that includes the latest non-experimental AIDL utilities and other AIDL libraries @@ -79,9 +93,10 @@ cc_defaults { static_libs: [ "android.hardware.common-V2-ndk", "android.hardware.graphics.common-V2-ndk", - "android.hardware.neuralnetworks-V3-ndk", + "android.hardware.neuralnetworks-V4-ndk", "neuralnetworks_utils_hal_aidl", ], + cflags: ["-DNN_AIDL_V4_OR_ABOVE"], } cc_test { diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h index 168264babf..960be2bb54 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h @@ -36,6 +36,8 @@ class PreparedModelCallback final : public BnPreparedModelCallback, public IProt public: using Data = nn::GeneralResult; + PreparedModelCallback(nn::Version featureLevel) : kFeatureLevel(featureLevel) {} + ndk::ScopedAStatus notify(ErrorStatus status, const std::shared_ptr& preparedModel) override; @@ -44,6 +46,7 @@ class PreparedModelCallback final : public BnPreparedModelCallback, public IProt Data get(); private: + const nn::Version kFeatureLevel; hal::utils::TransferValue mData; }; diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h index a77ea984b2..14802b98cc 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h @@ -17,6 +17,8 @@ #ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H +#include + #include #include #include @@ -33,17 +35,22 @@ namespace aidl::android::hardware::neuralnetworks::utils { -class Execution final : public nn::IExecution, public std::enable_shared_from_this { +// A reusable execution implementation with a cached Request, internally it is still passing the +// request to the driver in every computation. +class ExecutionWithCachedRequest final + : public nn::IExecution, + public std::enable_shared_from_this { struct PrivateConstructorTag {}; public: - static nn::GeneralResult> create( + static nn::GeneralResult> create( std::shared_ptr preparedModel, Request request, hal::utils::RequestRelocation relocation, bool measure, int64_t loopTimeoutDuration); - Execution(PrivateConstructorTag tag, std::shared_ptr preparedModel, - Request request, hal::utils::RequestRelocation relocation, bool measure, - int64_t loopTimeoutDuration); + ExecutionWithCachedRequest(PrivateConstructorTag tag, + std::shared_ptr preparedModel, Request request, + hal::utils::RequestRelocation relocation, bool measure, + int64_t loopTimeoutDuration); nn::ExecutionResult, nn::Timing>> compute( const nn::OptionalTimePoint& deadline) const override; @@ -60,6 +67,30 @@ class Execution final : public nn::IExecution, public std::enable_shared_from_th const int64_t kLoopTimeoutDuration; }; +// A reusable execution implementation that is backed by an actual AIDL IExecution object. +class Execution final : public nn::IExecution, public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + std::shared_ptr execution, + hal::utils::RequestRelocation relocation); + + Execution(PrivateConstructorTag tag, std::shared_ptr execution, + hal::utils::RequestRelocation relocation); + + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + const std::shared_ptr kExecution; + const hal::utils::RequestRelocation kRelocation; +}; + } // namespace aidl::android::hardware::neuralnetworks::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h index 3fb443c388..205d428cf4 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h @@ -61,6 +61,11 @@ #include #include +#ifdef NN_AIDL_V4_OR_ABOVE +#include +#include +#endif // NN_AIDL_V4_OR_ABOVE + namespace android::nn { namespace aidl_hal = ::aidl::android::hardware::neuralnetworks; diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h index 4035764ea4..24cd681658 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h @@ -41,10 +41,11 @@ class PreparedModel final : public nn::IPreparedModel, public: static nn::GeneralResult> create( - std::shared_ptr preparedModel); + std::shared_ptr preparedModel, nn::Version featureLevel); PreparedModel(PrivateConstructorTag tag, - std::shared_ptr preparedModel); + std::shared_ptr preparedModel, + nn::Version featureLevel); nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, @@ -78,6 +79,7 @@ class PreparedModel final : public nn::IPreparedModel, private: const std::shared_ptr kPreparedModel; + const nn::Version kFeatureLevel; }; } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h index a27487e17c..beca38b1ee 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h @@ -38,6 +38,8 @@ constexpr std::optional aidlVersionToCanonicalVersion(int aidlVersi return nn::kVersionFeatureLevel6; case 3: return nn::kVersionFeatureLevel7; + case 4: + return nn::kVersionFeatureLevel8; default: return std::nullopt; } diff --git a/neuralnetworks/aidl/utils/src/Callbacks.cpp b/neuralnetworks/aidl/utils/src/Callbacks.cpp index 8084970690..554f3faa73 100644 --- a/neuralnetworks/aidl/utils/src/Callbacks.cpp +++ b/neuralnetworks/aidl/utils/src/Callbacks.cpp @@ -38,16 +38,17 @@ namespace { // nn::kVersionFeatureLevel5. On failure, this function returns with the appropriate // nn::GeneralError. nn::GeneralResult prepareModelCallback( - ErrorStatus status, const std::shared_ptr& preparedModel) { + ErrorStatus status, const std::shared_ptr& preparedModel, + nn::Version featureLevel) { HANDLE_STATUS_AIDL(status) << "model preparation failed with " << toString(status); - return NN_TRY(PreparedModel::create(preparedModel)); + return NN_TRY(PreparedModel::create(preparedModel, featureLevel)); } } // namespace ndk::ScopedAStatus PreparedModelCallback::notify( ErrorStatus status, const std::shared_ptr& preparedModel) { - mData.put(prepareModelCallback(status, preparedModel)); + mData.put(prepareModelCallback(status, preparedModel, kFeatureLevel)); return ndk::ScopedAStatus::ok(); } diff --git a/neuralnetworks/aidl/utils/src/Device.cpp b/neuralnetworks/aidl/utils/src/Device.cpp index 5b7ec4ebd7..bad10ed347 100644 --- a/neuralnetworks/aidl/utils/src/Device.cpp +++ b/neuralnetworks/aidl/utils/src/Device.cpp @@ -229,7 +229,7 @@ nn::GeneralResult Device::prepareModel( const auto aidlDataCache = NN_TRY(convert(dataCache)); const auto aidlToken = NN_TRY(convert(token)); - const auto cb = ndk::SharedRefBase::make(); + const auto cb = ndk::SharedRefBase::make(kFeatureLevel); const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModel(aidlModel, aidlPreference, aidlPriority, aidlDeadline, @@ -247,7 +247,7 @@ nn::GeneralResult Device::prepareModelFromCache( const auto aidlDataCache = NN_TRY(convert(dataCache)); const auto aidlToken = NN_TRY(convert(token)); - const auto cb = ndk::SharedRefBase::make(); + const auto cb = ndk::SharedRefBase::make(kFeatureLevel); const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModelFromCache(aidlDeadline, aidlModelCache, aidlDataCache, diff --git a/neuralnetworks/aidl/utils/src/Execution.cpp b/neuralnetworks/aidl/utils/src/Execution.cpp index 94edd90c89..c4add636e5 100644 --- a/neuralnetworks/aidl/utils/src/Execution.cpp +++ b/neuralnetworks/aidl/utils/src/Execution.cpp @@ -35,36 +35,39 @@ namespace aidl::android::hardware::neuralnetworks::utils { -nn::GeneralResult> Execution::create( - std::shared_ptr preparedModel, Request request, - hal::utils::RequestRelocation relocation, bool measure, int64_t loopTimeoutDuration) { +nn::GeneralResult> +ExecutionWithCachedRequest::create(std::shared_ptr preparedModel, + Request request, hal::utils::RequestRelocation relocation, + bool measure, int64_t loopTimeoutDuration) { if (preparedModel == nullptr) { - return NN_ERROR() << "aidl::utils::Execution::create must have non-null preparedModel"; + return NN_ERROR() << "aidl::utils::ExecutionWithCachedRequest::create must have non-null " + "preparedModel"; } - return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), - std::move(request), std::move(relocation), measure, - loopTimeoutDuration); + return std::make_shared( + PrivateConstructorTag{}, std::move(preparedModel), std::move(request), + std::move(relocation), measure, loopTimeoutDuration); } -Execution::Execution(PrivateConstructorTag /*tag*/, - std::shared_ptr preparedModel, Request request, - hal::utils::RequestRelocation relocation, bool measure, - int64_t loopTimeoutDuration) +ExecutionWithCachedRequest::ExecutionWithCachedRequest( + PrivateConstructorTag /*tag*/, std::shared_ptr preparedModel, + Request request, hal::utils::RequestRelocation relocation, bool measure, + int64_t loopTimeoutDuration) : kPreparedModel(std::move(preparedModel)), kRequest(std::move(request)), kRelocation(std::move(relocation)), kMeasure(measure), kLoopTimeoutDuration(loopTimeoutDuration) {} -nn::ExecutionResult, nn::Timing>> Execution::compute( - const nn::OptionalTimePoint& deadline) const { +nn::ExecutionResult, nn::Timing>> +ExecutionWithCachedRequest::compute(const nn::OptionalTimePoint& deadline) const { const auto aidlDeadline = NN_TRY(convert(deadline)); return kPreparedModel->executeInternal(kRequest, kMeasure, aidlDeadline, kLoopTimeoutDuration, kRelocation); } -nn::GeneralResult> Execution::computeFenced( +nn::GeneralResult> +ExecutionWithCachedRequest::computeFenced( const std::vector& waitFor, const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& timeoutDurationAfterFence) const { const auto aidlWaitFor = NN_TRY(convert(waitFor)); @@ -75,4 +78,18 @@ nn::GeneralResult> Execu aidlTimeoutDurationAfterFence, kRelocation); } +nn::GeneralResult> Execution::create( + std::shared_ptr execution, hal::utils::RequestRelocation relocation) { + if (execution == nullptr) { + return NN_ERROR() << "aidl::utils::Execution::create must have non-null execution"; + } + + return std::make_shared(PrivateConstructorTag{}, std::move(execution), + std::move(relocation)); +} + +Execution::Execution(PrivateConstructorTag /*tag*/, std::shared_ptr execution, + hal::utils::RequestRelocation relocation) + : kExecution(std::move(execution)), kRelocation(std::move(relocation)) {} + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/src/PreparedModel.cpp b/neuralnetworks/aidl/utils/src/PreparedModel.cpp index f25c2c8825..6d1de569d0 100644 --- a/neuralnetworks/aidl/utils/src/PreparedModel.cpp +++ b/neuralnetworks/aidl/utils/src/PreparedModel.cpp @@ -54,21 +54,77 @@ nn::GeneralResult> convertFencedExecutionResul return std::make_pair(NN_TRY(nn::convert(timingLaunched)), NN_TRY(nn::convert(timingFenced))); } +nn::ExecutionResult, nn::Timing>> handleExecutionResult( + const ExecutionResult& result, const hal::utils::RequestRelocation& relocation) { + if (!result.outputSufficientSize) { + auto canonicalOutputShapes = + nn::convert(result.outputShapes).value_or(std::vector{}); + return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes)) + << "execution failed with " << nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; + } + auto [outputShapes, timing] = + NN_TRY(convertExecutionResults(result.outputShapes, result.timing)); + + if (relocation.output) { + relocation.output->flush(); + } + return std::make_pair(std::move(outputShapes), timing); +} + +nn::GeneralResult> +handleFencedExecutionResult(const FencedExecutionResult& result, + const hal::utils::RequestRelocation& relocation) { + auto resultSyncFence = nn::SyncFence::createAsSignaled(); + if (result.syncFence.get() != -1) { + resultSyncFence = nn::SyncFence::create(NN_TRY(nn::convert(result.syncFence))).value(); + } + + auto callback = result.callback; + if (callback == nullptr) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "callback is null"; + } + + // If computeFenced required the request memory to be moved into shared memory, block here until + // the fenced execution has completed and flush the memory back. + if (relocation.output) { + const auto state = resultSyncFence.syncWait({}); + if (state != nn::SyncFence::FenceState::SIGNALED) { + return NN_ERROR() << "syncWait failed with " << state; + } + relocation.output->flush(); + } + + // Create callback which can be used to retrieve the execution error status and timings. + nn::ExecuteFencedInfoCallback resultCallback = + [callback]() -> nn::GeneralResult> { + ErrorStatus errorStatus; + Timing timingLaunched; + Timing timingFenced; + const auto ret = callback->getExecutionInfo(&timingLaunched, &timingFenced, &errorStatus); + HANDLE_ASTATUS(ret) << "fenced execution callback getExecutionInfo failed"; + return convertFencedExecutionResults(errorStatus, timingLaunched, timingFenced); + }; + + return std::make_pair(std::move(resultSyncFence), std::move(resultCallback)); +} + } // namespace nn::GeneralResult> PreparedModel::create( - std::shared_ptr preparedModel) { + std::shared_ptr preparedModel, nn::Version featureLevel) { if (preparedModel == nullptr) { return NN_ERROR() << "aidl_hal::utils::PreparedModel::create must have non-null preparedModel"; } - return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel)); + return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), + featureLevel); } PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, - std::shared_ptr preparedModel) - : kPreparedModel(std::move(preparedModel)) {} + std::shared_ptr preparedModel, + nn::Version featureLevel) + : kPreparedModel(std::move(preparedModel)), kFeatureLevel(featureLevel) {} nn::ExecutionResult, nn::Timing>> PreparedModel::execute( const nn::Request& request, nn::MeasureTiming measure, @@ -101,19 +157,7 @@ PreparedModel::executeInternal(const Request& request, bool measure, int64_t dea const auto ret = kPreparedModel->executeSynchronously(request, measure, deadline, loopTimeoutDuration, &executionResult); HANDLE_ASTATUS(ret) << "executeSynchronously failed"; - if (!executionResult.outputSufficientSize) { - auto canonicalOutputShapes = - nn::convert(executionResult.outputShapes).value_or(std::vector{}); - return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes)) - << "execution failed with " << nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE; - } - auto [outputShapes, timing] = - NN_TRY(convertExecutionResults(executionResult.outputShapes, executionResult.timing)); - - if (relocation.output) { - relocation.output->flush(); - } - return std::make_pair(std::move(outputShapes), timing); + return handleExecutionResult(executionResult, relocation); } nn::GeneralResult> @@ -154,39 +198,7 @@ PreparedModel::executeFencedInternal(const Request& request, kPreparedModel->executeFenced(request, waitFor, measure, deadline, loopTimeoutDuration, timeoutDurationAfterFence, &result); HANDLE_ASTATUS(ret) << "executeFenced failed"; - - auto resultSyncFence = nn::SyncFence::createAsSignaled(); - if (result.syncFence.get() != -1) { - resultSyncFence = nn::SyncFence::create(NN_TRY(nn::convert(result.syncFence))).value(); - } - - auto callback = result.callback; - if (callback == nullptr) { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "callback is null"; - } - - // If executeFenced required the request memory to be moved into shared memory, block here until - // the fenced execution has completed and flush the memory back. - if (relocation.output) { - const auto state = resultSyncFence.syncWait({}); - if (state != nn::SyncFence::FenceState::SIGNALED) { - return NN_ERROR() << "syncWait failed with " << state; - } - relocation.output->flush(); - } - - // Create callback which can be used to retrieve the execution error status and timings. - nn::ExecuteFencedInfoCallback resultCallback = - [callback]() -> nn::GeneralResult> { - ErrorStatus errorStatus; - Timing timingLaunched; - Timing timingFenced; - const auto ret = callback->getExecutionInfo(&timingLaunched, &timingFenced, &errorStatus); - HANDLE_ASTATUS(ret) << "fenced execution callback getExecutionInfo failed"; - return convertFencedExecutionResults(errorStatus, timingLaunched, timingFenced); - }; - - return std::make_pair(std::move(resultSyncFence), std::move(resultCallback)); + return handleFencedExecutionResult(result, relocation); } nn::GeneralResult PreparedModel::createReusableExecution( @@ -202,8 +214,18 @@ nn::GeneralResult PreparedModel::createReusableExecution( auto aidlRequest = NN_TRY(convert(requestInShared)); auto aidlMeasure = NN_TRY(convert(measure)); auto aidlLoopTimeoutDuration = NN_TRY(convert(loopTimeoutDuration)); - return Execution::create(shared_from_this(), std::move(aidlRequest), std::move(relocation), - aidlMeasure, aidlLoopTimeoutDuration); + + if (kFeatureLevel.level >= nn::Version::Level::FEATURE_LEVEL_8) { + std::shared_ptr execution; + const auto ret = kPreparedModel->createReusableExecution( + aidlRequest, aidlMeasure, aidlLoopTimeoutDuration, &execution); + HANDLE_ASTATUS(ret) << "createReusableExecution failed"; + return Execution::create(std::move(execution), std::move(relocation)); + } + + return ExecutionWithCachedRequest::create(shared_from_this(), std::move(aidlRequest), + std::move(relocation), aidlMeasure, + aidlLoopTimeoutDuration); } nn::GeneralResult PreparedModel::configureExecutionBurst() const { @@ -218,4 +240,36 @@ std::any PreparedModel::getUnderlyingResource() const { return resource; } +nn::ExecutionResult, nn::Timing>> Execution::compute( + const nn::OptionalTimePoint& deadline) const { + const auto aidlDeadline = NN_TRY(convert(deadline)); + + if (kRelocation.input) { + kRelocation.input->flush(); + } + + ExecutionResult executionResult; + auto ret = kExecution->executeSynchronously(aidlDeadline, &executionResult); + HANDLE_ASTATUS(ret) << "executeSynchronously failed"; + return handleExecutionResult(executionResult, kRelocation); +} + +nn::GeneralResult> Execution::computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const { + const auto aidlWaitFor = NN_TRY(convert(waitFor)); + const auto aidlDeadline = NN_TRY(convert(deadline)); + const auto aidlTimeoutDurationAfterFence = NN_TRY(convert(timeoutDurationAfterFence)); + + if (kRelocation.input) { + kRelocation.input->flush(); + } + + FencedExecutionResult result; + const auto ret = kExecution->executeFenced(aidlWaitFor, aidlDeadline, + aidlTimeoutDurationAfterFence, &result); + HANDLE_ASTATUS(ret) << "executeFenced failed"; + return handleFencedExecutionResult(result, kRelocation); +} + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp index 0366e7dff0..fb13af8d9f 100644 --- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp +++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp @@ -17,6 +17,7 @@ #include "MockBuffer.h" #include "MockDevice.h" #include "MockPreparedModel.h" +#include "TestUtils.h" #include #include @@ -146,26 +147,7 @@ constexpr auto makeDeadObjectFailure = [] { return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT); }; -class DeviceTest : public ::testing::TestWithParam { - protected: - const nn::Version kVersion = GetParam(); -}; - -std::string printDeviceTest(const testing::TestParamInfo& info) { - const nn::Version version = info.param; - CHECK(!version.runtimeOnlyFeatures); - switch (version.level) { - case nn::Version::Level::FEATURE_LEVEL_5: - return "v1"; - case nn::Version::Level::FEATURE_LEVEL_6: - return "v2"; - case nn::Version::Level::FEATURE_LEVEL_7: - return "v3"; - default: - LOG(FATAL) << "Invalid AIDL version: " << version; - return "invalid"; - } -} +class DeviceTest : public VersionedAidlUtilsTestBase {}; } // namespace @@ -894,9 +876,6 @@ TEST_P(DeviceTest, allocateDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } -INSTANTIATE_TEST_SUITE_P(TestDevice, DeviceTest, - ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6, - nn::kVersionFeatureLevel7), - printDeviceTest); +INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(DeviceTest, kAllAidlVersions); } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/ExecutionTest.cpp b/neuralnetworks/aidl/utils/test/ExecutionTest.cpp new file mode 100644 index 0000000000..8519290145 --- /dev/null +++ b/neuralnetworks/aidl/utils/test/ExecutionTest.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2021 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 "MockExecution.h" +#include "MockFencedExecutionCallback.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace aidl::android::hardware::neuralnetworks::utils { +namespace { + +using ::testing::_; +using ::testing::DoAll; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; +using ::testing::SetArgPointee; + +const std::shared_ptr kInvalidExecution; +constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1}; + +constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); }; + +constexpr auto makeGeneralFailure = [] { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast(ErrorStatus::GENERAL_FAILURE)); +}; +constexpr auto makeGeneralTransportFailure = [] { + return ndk::ScopedAStatus::fromStatus(STATUS_NO_MEMORY); +}; +constexpr auto makeDeadObjectFailure = [] { + return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT); +}; + +auto makeFencedExecutionResult(const std::shared_ptr& callback) { + return [callback](const std::vector& /*waitFor*/, + int64_t /*deadline*/, int64_t /*duration*/, + FencedExecutionResult* fencedExecutionResult) { + *fencedExecutionResult = FencedExecutionResult{.callback = callback, + .syncFence = ndk::ScopedFileDescriptor(-1)}; + return ndk::ScopedAStatus::ok(); + }; +} + +} // namespace + +TEST(ExecutionTest, invalidExecution) { + // run test + const auto result = Execution::create(kInvalidExecution, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeSync) { + // setup call + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + const auto mockExecutionResult = ExecutionResult{ + .outputSufficientSize = true, + .outputShapes = {}, + .timing = kNoTiming, + }; + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce( + DoAll(SetArgPointee<1>(mockExecutionResult), InvokeWithoutArgs(makeStatusOk))); + + // run test + const auto result = execution->compute({}); + + // verify result + EXPECT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ExecutionTest, executeSyncError) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce(Invoke(makeGeneralFailure)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeSyncTransportFailure) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeSyncDeadObject) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeSynchronously(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ExecutionTest, executeFenced) { + // setup call + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming), + SetArgPointee<2>(ErrorStatus::NONE), Invoke(makeStatusOk))); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeFencedExecutionResult(mockCallback))); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& [syncFence, callback] = result.value(); + EXPECT_EQ(syncFence.syncWait({}), nn::SyncFence::FenceState::SIGNALED); + ASSERT_NE(callback, nullptr); + + // get results from callback + const auto callbackResult = callback(); + ASSERT_TRUE(callbackResult.has_value()) << "Failed with " << callbackResult.error().code << ": " + << callbackResult.error().message; +} + +TEST(ExecutionTest, executeFencedCallbackError) { + // setup call + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) + .Times(1) + .WillOnce(Invoke(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming), + SetArgPointee<2>(ErrorStatus::GENERAL_FAILURE), + Invoke(makeStatusOk)))); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeFencedExecutionResult(mockCallback))); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& [syncFence, callback] = result.value(); + EXPECT_NE(syncFence.syncWait({}), nn::SyncFence::FenceState::ACTIVE); + ASSERT_NE(callback, nullptr); + + // verify callback failure + const auto callbackResult = callback(); + ASSERT_FALSE(callbackResult.has_value()); + EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeFencedError) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeFencedTransportFailure) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ExecutionTest, executeFencedDeadObject) { + // setup test + const auto mockExecution = MockExecution::create(); + const auto execution = Execution::create(mockExecution, {}).value(); + EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +} // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/MockExecution.h b/neuralnetworks/aidl/utils/test/MockExecution.h new file mode 100644 index 0000000000..216f569abc --- /dev/null +++ b/neuralnetworks/aidl/utils/test/MockExecution.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H + +#include +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::utils { + +class MockExecution final : public BnExecution { + public: + static std::shared_ptr create(); + + MOCK_METHOD(ndk::ScopedAStatus, executeSynchronously, + (int64_t deadline, ExecutionResult* executionResult), (override)); + MOCK_METHOD(ndk::ScopedAStatus, executeFenced, + (const std::vector& waitFor, int64_t deadline, + int64_t duration, FencedExecutionResult* fencedExecutionResult), + (override)); +}; + +inline std::shared_ptr MockExecution::create() { + return ndk::SharedRefBase::make(); +} + +} // namespace aidl::android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H diff --git a/neuralnetworks/aidl/utils/test/MockPreparedModel.h b/neuralnetworks/aidl/utils/test/MockPreparedModel.h index a4ae2b778a..0ed9af9929 100644 --- a/neuralnetworks/aidl/utils/test/MockPreparedModel.h +++ b/neuralnetworks/aidl/utils/test/MockPreparedModel.h @@ -17,6 +17,7 @@ #ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_PREPARED_MODEL_H #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_PREPARED_MODEL_H +#include #include #include #include @@ -41,6 +42,10 @@ class MockPreparedModel final : public BnPreparedModel { (override)); MOCK_METHOD(ndk::ScopedAStatus, configureExecutionBurst, (std::shared_ptr * burst), (override)); + MOCK_METHOD(ndk::ScopedAStatus, createReusableExecution, + (const Request& request, bool measureTiming, int64_t loopTimeoutDuration, + std::shared_ptr* execution), + (override)); }; inline std::shared_ptr MockPreparedModel::create() { diff --git a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp index 8bb5c90d1e..8cfb7c123a 100644 --- a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp +++ b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp @@ -15,8 +15,10 @@ */ #include "MockBurst.h" +#include "MockExecution.h" #include "MockFencedExecutionCallback.h" #include "MockPreparedModel.h" +#include "TestUtils.h" #include #include @@ -66,21 +68,23 @@ auto makeFencedExecutionResult(const std::shared_ptr= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup call const uint32_t kNumberOfComputations = 2; const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockExecutionResult = ExecutionResult{ .outputSufficientSize = true, .outputShapes = {}, @@ -283,10 +289,12 @@ TEST(PreparedModelTest, reusableExecuteSync) { } } -TEST(PreparedModelTest, reusableExecuteSyncError) { +TEST_P(PreparedModelTest, reusableExecuteSyncError) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(Invoke(makeGeneralFailure)); @@ -303,10 +311,12 @@ TEST(PreparedModelTest, reusableExecuteSyncError) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) { +TEST_P(PreparedModelTest, reusableExecuteSyncTransportFailure) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); @@ -323,10 +333,12 @@ TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteSyncDeadObject) { +TEST_P(PreparedModelTest, reusableExecuteSyncDeadObject) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); @@ -343,11 +355,13 @@ TEST(PreparedModelTest, reusableExecuteSyncDeadObject) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, reusableExecuteFenced) { +TEST_P(PreparedModelTest, reusableExecuteFenced) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup call const uint32_t kNumberOfComputations = 2; const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockCallback = MockFencedExecutionCallback::create(); EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) .Times(kNumberOfComputations) @@ -379,10 +393,12 @@ TEST(PreparedModelTest, reusableExecuteFenced) { } } -TEST(PreparedModelTest, reusableExecuteFencedCallbackError) { +TEST_P(PreparedModelTest, reusableExecuteFencedCallbackError) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup call const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); const auto mockCallback = MockFencedExecutionCallback::create(); EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) .Times(1) @@ -413,10 +429,12 @@ TEST(PreparedModelTest, reusableExecuteFencedCallbackError) { EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteFencedError) { +TEST_P(PreparedModelTest, reusableExecuteFencedError) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); @@ -433,10 +451,12 @@ TEST(PreparedModelTest, reusableExecuteFencedError) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) { +TEST_P(PreparedModelTest, reusableExecuteFencedTransportFailure) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); @@ -453,10 +473,12 @@ TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, reusableExecuteFencedDeadObject) { +TEST_P(PreparedModelTest, reusableExecuteFencedDeadObject) { + if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); @@ -473,14 +495,14 @@ TEST(PreparedModelTest, reusableExecuteFencedDeadObject) { EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, configureExecutionBurst) { +TEST_P(PreparedModelTest, configureExecutionBurst) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); const auto mockBurst = ndk::SharedRefBase::make(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(DoAll(SetArgPointee<0>(mockBurst), Invoke(makeStatusOk))); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -491,13 +513,13 @@ TEST(PreparedModelTest, configureExecutionBurst) { EXPECT_NE(result.value(), nullptr); } -TEST(PreparedModelTest, configureExecutionBurstError) { +TEST_P(PreparedModelTest, configureExecutionBurstError) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -507,13 +529,13 @@ TEST(PreparedModelTest, configureExecutionBurstError) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, configureExecutionBurstTransportFailure) { +TEST_P(PreparedModelTest, configureExecutionBurstTransportFailure) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -523,13 +545,13 @@ TEST(PreparedModelTest, configureExecutionBurstTransportFailure) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } -TEST(PreparedModelTest, configureExecutionBurstDeadObject) { +TEST_P(PreparedModelTest, configureExecutionBurstDeadObject) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_)) .Times(1) .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto result = preparedModel->configureExecutionBurst(); @@ -539,10 +561,84 @@ TEST(PreparedModelTest, configureExecutionBurstDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } -TEST(PreparedModelTest, getUnderlyingResource) { +TEST_P(PreparedModelTest, createReusableExecution) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto mockExecution = ndk::SharedRefBase::make(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<3>(mockExecution), Invoke(makeStatusOk))); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST_P(PreparedModelTest, createReusableExecutionError) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + // setup test const auto mockPreparedModel = MockPreparedModel::create(); - const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST_P(PreparedModelTest, createReusableExecutionTransportFailure) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST_P(PreparedModelTest, createReusableExecutionDeadObject) { + if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return; + + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST_P(PreparedModelTest, getUnderlyingResource) { + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value(); // run test const auto resource = preparedModel->getUnderlyingResource(); @@ -554,4 +650,6 @@ TEST(PreparedModelTest, getUnderlyingResource) { EXPECT_EQ(maybeMock->get(), mockPreparedModel.get()); } +INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(PreparedModelTest, kAllAidlVersions); + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/TestUtils.cpp b/neuralnetworks/aidl/utils/test/TestUtils.cpp new file mode 100644 index 0000000000..9abec883a6 --- /dev/null +++ b/neuralnetworks/aidl/utils/test/TestUtils.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 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 "TestUtils.h" + +#include +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::utils { + +std::string printTestVersion(const testing::TestParamInfo& info) { + switch (info.param.level) { + case nn::Version::Level::FEATURE_LEVEL_5: + return "v1"; + case nn::Version::Level::FEATURE_LEVEL_6: + return "v2"; + case nn::Version::Level::FEATURE_LEVEL_7: + return "v3"; + case nn::Version::Level::FEATURE_LEVEL_8: + return "v4"; + default: + LOG(FATAL) << "Invalid AIDL version: " << info.param; + return "invalid"; + } +} + +} // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/test/TestUtils.h b/neuralnetworks/aidl/utils/test/TestUtils.h new file mode 100644 index 0000000000..23f734a47a --- /dev/null +++ b/neuralnetworks/aidl/utils/test/TestUtils.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H + +#include +#include +#include +#include + +namespace aidl::android::hardware::neuralnetworks::utils { + +class VersionedAidlUtilsTestBase : public ::testing::TestWithParam { + protected: + const nn::Version kVersion = GetParam(); +}; + +std::string printTestVersion(const testing::TestParamInfo& info); + +inline const auto kAllAidlVersions = + ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6, + nn::kVersionFeatureLevel7, nn::kVersionFeatureLevel8); + +#define INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(TestSuite, versions) \ + INSTANTIATE_TEST_SUITE_P(Versioned, TestSuite, versions, printTestVersion) + +} // namespace aidl::android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp index cd5475c0d3..b3e9c633e3 100644 --- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp +++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp @@ -208,6 +208,11 @@ class InvalidPreparedModel : public BnPreparedModel { return ndk::ScopedAStatus::fromServiceSpecificError( static_cast(ErrorStatus::GENERAL_FAILURE)); } + ndk::ScopedAStatus createReusableExecution(const aidl_hal::Request&, bool, int64_t, + std::shared_ptr*) override { + return ndk::ScopedAStatus::fromServiceSpecificError( + static_cast(ErrorStatus::GENERAL_FAILURE)); + } }; template diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h new file mode 100644 index 0000000000..6a9ac57fbe --- /dev/null +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H + +#include "nnapi/hal/aidl/Adapter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface +// lifetimes across processes and for protecting asynchronous calls across AIDL. + +namespace aidl::android::hardware::neuralnetworks::adapter { + +// Class that adapts nn::IExecution to BnExecution. +class Execution : public BnExecution { + public: + explicit Execution(::android::nn::SharedExecution execution); + + ndk::ScopedAStatus executeSynchronously(int64_t deadlineNs, + ExecutionResult* executionResult) override; + ndk::ScopedAStatus executeFenced(const std::vector& waitFor, + int64_t deadlineNs, int64_t durationNs, + FencedExecutionResult* fencedExecutionResult) override; + + protected: + const ::android::nn::SharedExecution kExecution; +}; + +} // namespace aidl::android::hardware::neuralnetworks::adapter + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h index 93e0427426..f92b0bc783 100644 --- a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h +++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,9 @@ class PreparedModel : public BnPreparedModel { int64_t loopTimeoutDurationNs, int64_t durationNs, FencedExecutionResult* executionResult) override; ndk::ScopedAStatus configureExecutionBurst(std::shared_ptr* burst) override; + ndk::ScopedAStatus createReusableExecution(const Request& request, bool measureTiming, + int64_t loopTimeoutDurationNs, + std::shared_ptr* execution) override; ::android::nn::SharedPreparedModel getUnderlyingPreparedModel() const; diff --git a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp index 71ed1a857b..5cab62c625 100644 --- a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp +++ b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp @@ -17,6 +17,7 @@ #include "PreparedModel.h" #include "Burst.h" +#include "Execution.h" #include #include @@ -26,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -167,6 +169,56 @@ nn::GeneralResult executeFenced( .syncFence = std::move(fileDescriptor)}; } +nn::GeneralResult createReusableExecution( + const nn::IPreparedModel& preparedModel, const Request& request, bool measureTiming, + int64_t loopTimeoutDurationNs) { + const auto nnRequest = NN_TRY(convertInput(request)); + const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO; + const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs)); + return preparedModel.createReusableExecution(nnRequest, nnMeasureTiming, nnLoopTimeoutDuration); +} + +nn::ExecutionResult executeSynchronously(const nn::IExecution& execution, + int64_t deadlineNs) { + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + + const auto result = execution.compute(nnDeadline); + + if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + const auto& [message, code, outputShapes] = result.error(); + LOG(ERROR) << "executeSynchronously failed with " << code << ": " << message; + return ExecutionResult{.outputSufficientSize = false, + .outputShapes = utils::convert(outputShapes).value(), + .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}}; + } + + const auto& [outputShapes, timing] = NN_TRY(result); + return ExecutionResult{.outputSufficientSize = true, + .outputShapes = utils::convert(outputShapes).value(), + .timing = utils::convert(timing).value()}; +} + +nn::GeneralResult executeFenced( + const nn::IExecution& execution, const std::vector& waitFor, + int64_t deadlineNs, int64_t durationNs) { + const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor)); + const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs)); + const auto nnDuration = NN_TRY(makeOptionalDuration(durationNs)); + + auto [syncFence, executeFencedInfoCallback] = + NN_TRY(execution.computeFenced(nnWaitFor, nnDeadline, nnDuration)); + + ndk::ScopedFileDescriptor fileDescriptor; + if (syncFence.hasFd()) { + auto uniqueFd = NN_TRY(nn::dupFd(syncFence.getFd())); + fileDescriptor = ndk::ScopedFileDescriptor(uniqueFd.release()); + } + + return FencedExecutionResult{.callback = ndk::SharedRefBase::make( + std::move(executeFencedInfoCallback)), + .syncFence = std::move(fileDescriptor)}; +} + } // namespace PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel) @@ -222,4 +274,51 @@ nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const { return kPreparedModel; } +ndk::ScopedAStatus PreparedModel::createReusableExecution(const Request& request, + bool measureTiming, + int64_t loopTimeoutDurationNs, + std::shared_ptr* execution) { + auto result = adapter::createReusableExecution(*kPreparedModel, request, measureTiming, + loopTimeoutDurationNs); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *execution = ndk::SharedRefBase::make(std::move(result).value()); + return ndk::ScopedAStatus::ok(); +} + +Execution::Execution(nn::SharedExecution execution) : kExecution(std::move(execution)) { + CHECK(kExecution != nullptr); +} + +ndk::ScopedAStatus Execution::executeSynchronously(int64_t deadlineNs, + ExecutionResult* executionResult) { + auto result = adapter::executeSynchronously(*kExecution, deadlineNs); + if (!result.has_value()) { + const auto& [message, code, _] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Execution::executeFenced(const std::vector& waitFor, + int64_t deadlineNs, int64_t durationNs, + FencedExecutionResult* executionResult) { + auto result = adapter::executeFenced(*kExecution, waitFor, deadlineNs, durationNs); + if (!result.has_value()) { + const auto& [message, code] = result.error(); + const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE); + return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage( + static_cast(aidlCode), message.c_str()); + } + *executionResult = std::move(result).value(); + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::neuralnetworks::adapter -- cgit v1.2.3 From 5cb52553df9d09a87d46d0655cf889b63d002797 Mon Sep 17 00:00:00 2001 From: Greg Kaiser Date: Tue, 18 Jan 2022 15:00:30 -0800 Subject: Fix copy() using iterators from different containers We fix up a std::copy that was using the wrong container for the end(). Test: TreeHugger Bug: 206867060 Change-Id: I5b7700029db6a513b6fdf03c3449be973d639df5 --- sensors/aidl/default/multihal/ConvertUtils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sensors/aidl/default/multihal/ConvertUtils.cpp b/sensors/aidl/default/multihal/ConvertUtils.cpp index 4d6697be3e..509bbb0e7b 100644 --- a/sensors/aidl/default/multihal/ConvertUtils.cpp +++ b/sensors/aidl/default/multihal/ConvertUtils.cpp @@ -131,7 +131,7 @@ void convertToHidlEvent(const AidlEvent& aidlEvent, V2_1Event* hidlEvent) { break; case AidlSensorType::POSE_6DOF: std::copy(std::begin(aidlEvent.payload.get().values), - std::end(aidlEvent.payload.get().values), + std::end(aidlEvent.payload.get().values), hidlEvent->u.pose6DOF.data()); break; case AidlSensorType::DYNAMIC_SENSOR_META: @@ -318,4 +318,4 @@ void convertToAidlEvent(const V2_1Event& hidlEvent, AidlEvent* aidlEvent) { } // namespace sensors } // namespace hardware } // namespace android -} // namespace aidl \ No newline at end of file +} // namespace aidl -- cgit v1.2.3 From ae12e389fde76d848c48035d062adbfcd74eae60 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Thu, 13 Jan 2022 18:06:21 -0800 Subject: composer: add getDisplayPhysicalOrientation Add an API to query the physical display orientation. Bug: 213237830 Test: VTS Change-Id: I4ea9ee5c8655be283e19156b0ce68e35674ac321 --- .../hardware/graphics/common/Transform.aidl | 1 + .../hardware/graphics/common/Transform.aidl | 5 ++++ .../graphics/composer3/IComposerClient.aidl | 1 + .../graphics/composer3/IComposerClient.aidl | 18 +++++++++++++++ .../VtsHalGraphicsComposer3_TargetTest.cpp | 27 ++++++++++++++++++++++ 5 files changed, 52 insertions(+) diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Transform.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Transform.aidl index 5c3d4cb16f..359c655e00 100644 --- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Transform.aidl +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Transform.aidl @@ -34,6 +34,7 @@ package android.hardware.graphics.common; @Backing(type="int") @VintfStability enum Transform { + NONE = 0, FLIP_H = 1, FLIP_V = 2, ROT_90 = 4, diff --git a/graphics/common/aidl/android/hardware/graphics/common/Transform.aidl b/graphics/common/aidl/android/hardware/graphics/common/Transform.aidl index 325816c98a..4b3a1b11fe 100644 --- a/graphics/common/aidl/android/hardware/graphics/common/Transform.aidl +++ b/graphics/common/aidl/android/hardware/graphics/common/Transform.aidl @@ -22,6 +22,11 @@ package android.hardware.graphics.common; @VintfStability @Backing(type="int") enum Transform { + /** + * Identity transform (i.e. no rotation or flip). + */ + NONE = 0, + /** * Horizontal flip. FLIP_H/FLIP_V is applied before ROT_90. */ diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl index e9d9745dff..37af84a44d 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl @@ -51,6 +51,7 @@ interface IComposerClient { int getDisplayVsyncPeriod(long display); android.hardware.graphics.composer3.DisplayContentSample getDisplayedContentSample(long display, long maxFrames, long timestamp); android.hardware.graphics.composer3.DisplayContentSamplingAttributes getDisplayedContentSamplingAttributes(long display); + android.hardware.graphics.common.Transform getDisplayPhysicalOrientation(long display); android.hardware.graphics.composer3.HdrCapabilities getHdrCapabilities(long display); int getMaxVirtualDisplayCount(); android.hardware.graphics.composer3.PerFrameMetadataKey[] getPerFrameMetadataKeys(long display); diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl index 3ab6329bff..fd2627e353 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl @@ -16,6 +16,7 @@ package android.hardware.graphics.composer3; +import android.hardware.graphics.common.Transform; import android.hardware.graphics.composer3.ClientTargetProperty; import android.hardware.graphics.composer3.ColorMode; import android.hardware.graphics.composer3.CommandResultPayload; @@ -353,6 +354,23 @@ interface IComposerClient { */ DisplayContentSamplingAttributes getDisplayedContentSamplingAttributes(long display); + /** + * Queries the physical orientation of a display. Orientation 'Transform::NONE' + * represents a display that doesn't require any transformation on layers + * to be presented at their natural orientation. + * + * @param display is the display where the physical orientation is queried. + * + * @return is one of the below values: + * Transform::NONE + * Transform::ROT_90 + * Transform::ROT_180 + * Transform::ROT_270 + * + * @exception EX_BAD_DISPLAY when an invalid display was passed in. + */ + Transform getDisplayPhysicalOrientation(long display); + /** * Returns the high dynamic range (HDR) capabilities of the given display, * which are invariant with regard to the active configuration. diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index c61693e458..6e42e86b73 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -904,6 +904,33 @@ TEST_P(GraphicsComposerAidlTest, GetDisplayName) { EXPECT_TRUE(mComposerClient->getDisplayName(mPrimaryDisplay, &displayName).isOk()); } +TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientationBadDisplay) { + Transform displayOrientation; + const auto error = + mComposerClient->getDisplayPhysicalOrientation(mInvalidDisplayId, &displayOrientation); + + EXPECT_FALSE(error.isOk()); + ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); +} + +TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation) { + const auto allowedDisplayOrientations = std::array{ + Transform::NONE, + Transform::ROT_90, + Transform::ROT_180, + Transform::ROT_270, + }; + + Transform displayOrientation; + const auto error = + mComposerClient->getDisplayPhysicalOrientation(mPrimaryDisplay, &displayOrientation); + + EXPECT_TRUE(error.isOk()); + EXPECT_NE(std::find(allowedDisplayOrientations.begin(), allowedDisplayOrientations.end(), + displayOrientation), + allowedDisplayOrientations.end()); +} + TEST_P(GraphicsComposerAidlTest, SetClientTargetSlotCount) { EXPECT_TRUE( mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk()); -- cgit v1.2.3 From c552b141e3b965712b4d4edc18ec5492abac2c0e Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 16 Dec 2021 15:37:23 -0800 Subject: WiFi: Basic support for 11be to Hostapd HAL In this commit, basic support for 11be is added to HostApd HAL. That includes: 1. Adding 320MHz bandwidth channels 2. Adding 11be to list of standards 3. Add a flag to enable/disable 11be for SoftAp Bug: 198746544 Test: Pass VTS tests, and presubmit tests Change-Id: I14e1bd8ab00692e743a3a49096fbd66aca806730 --- .../current/android/hardware/wifi/hostapd/Bandwidth.aidl | 9 +++++---- .../current/android/hardware/wifi/hostapd/Generation.aidl | 1 + .../current/android/hardware/wifi/hostapd/HwModeParams.aidl | 1 + wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl | 9 +++++---- wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl | 2 ++ .../hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl | 6 ++++++ 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl index 890d986f77..4d78640fdb 100644 --- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl +++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl @@ -41,8 +41,9 @@ enum Bandwidth { BANDWIDTH_80 = 4, BANDWIDTH_80P80 = 5, BANDWIDTH_160 = 6, - BANDWIDTH_2160 = 7, - BANDWIDTH_4320 = 8, - BANDWIDTH_6480 = 9, - BANDWIDTH_8640 = 10, + BANDWIDTH_320 = 7, + BANDWIDTH_2160 = 8, + BANDWIDTH_4320 = 9, + BANDWIDTH_6480 = 10, + BANDWIDTH_8640 = 11, } diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl index 6b60d17400..af0e960df8 100644 --- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl +++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl @@ -40,4 +40,5 @@ enum Generation { WIFI_STANDARD_11AC = 2, WIFI_STANDARD_11AX = 3, WIFI_STANDARD_11AD = 4, + WIFI_STANDARD_11BE = 5, } diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl index 844c838c44..8d8d7bb0f6 100644 --- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl +++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl @@ -43,4 +43,5 @@ parcelable HwModeParams { boolean enableHeMultiUserBeamformer; boolean enableHeTargetWakeTime; boolean enableEdmg; + boolean enable80211BE; } diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl index c9824027e9..e605153b83 100644 --- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl +++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl @@ -29,8 +29,9 @@ enum Bandwidth { BANDWIDTH_80 = 4, BANDWIDTH_80P80 = 5, BANDWIDTH_160 = 6, - BANDWIDTH_2160 = 7, - BANDWIDTH_4320 = 8, - BANDWIDTH_6480 = 9, - BANDWIDTH_8640 = 10, + BANDWIDTH_320 = 7, + BANDWIDTH_2160 = 8, + BANDWIDTH_4320 = 9, + BANDWIDTH_6480 = 10, + BANDWIDTH_8640 = 11, } diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl index 2cda55bd97..f4e3eb0668 100644 --- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl +++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl @@ -27,6 +27,7 @@ package android.hardware.wifi.hostapd; * WIFI_STANDARD_11AC = hw_mode is HOSTAPD_MODE_IEEE80211A and VHT is 1. * WIFI_STANDARD_11AX = hw_mode is HOSTAPD_MODE_IEEE80211A and High Efficiency supported. * WIFI_STANDARD_11AD = hw_mode is HOSTAPD_MODE_IEEE80211AD. + * WIFI_STANDARD_11BE = hw_mode is HOSTAPD_MODE_IEEE80211A and Extreme High Throughput supported. */ @VintfStability @Backing(type="int") @@ -37,4 +38,5 @@ enum Generation { WIFI_STANDARD_11AC = 2, WIFI_STANDARD_11AX = 3, WIFI_STANDARD_11AD = 4, + WIFI_STANDARD_11BE = 5, } diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl index 210e99ff1f..e66a24af8c 100644 --- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl +++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl @@ -68,4 +68,10 @@ parcelable HwModeParams { * Enable EDMG (802.11ay), this option is only allowed for the 60GHz band. */ boolean enableEdmg; + /** + * Whether IEEE 802.11be (Extreme High Throughput) is enabled or not. + * Note: hw_mode=a is used to specify that 5 GHz band or 6 GHz band is + * used with Extreme High Throughput. + */ + boolean enable80211BE; } -- cgit v1.2.3 From 115180e95a548cd24d53d433fc67ae30e2bee753 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 16 Dec 2021 16:03:43 -0800 Subject: WiFi: Basic support for 11be to Supplicant HAL In this commit, basic support for 11be is added to Supplicant HAL. That includes adding EHT to list of WifiTechnologies Bug: 198746544 Test: Build successful Change-Id: Ied553e502ab2dba9efbcaac80691a6d54195e942 --- .../current/android/hardware/wifi/supplicant/WifiTechnology.aidl | 1 + .../aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl index ad36e68564..bf5081ea70 100644 --- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl +++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl @@ -39,4 +39,5 @@ enum WifiTechnology { HT = 2, VHT = 3, HE = 4, + EHT = 5, } diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl index 00c16b4278..d364c7509a 100644 --- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl +++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl @@ -39,4 +39,8 @@ enum WifiTechnology { * For 802.11ax */ HE = 4, + /** + * For 802.11be + */ + EHT = 5, } -- cgit v1.2.3 From bbf7fb9322e495608b3d38f69e50081030669092 Mon Sep 17 00:00:00 2001 From: Edwin Tung Date: Mon, 27 Dec 2021 12:13:02 +0800 Subject: Add MeasurementCorrections AIDL HAL (hardware/interfaces) Bug: 208728105 Test: atest VtsHalGnssTargetTest Change-Id: I2192670951a517bd229535a083997cc9bab31287 --- .../compatibility_matrix.current.xml | 8 ++ gnss/1.1/vts/functional/Android.bp | 1 + gnss/2.0/vts/functional/Android.bp | 6 +- gnss/2.1/vts/functional/Android.bp | 1 + gnss/aidl/Android.bp | 1 + .../current/android/hardware/gnss/IGnss.aidl | 1 + .../IMeasurementCorrectionsCallback.aidl | 41 +++++++++ .../IMeasurementCorrectionsInterface.aidl | 39 ++++++++ .../MeasurementCorrections.aidl | 47 ++++++++++ .../measurement_corrections/ReflectingPlane.aidl | 41 +++++++++ .../SingleSatCorrection.aidl | 49 ++++++++++ gnss/aidl/android/hardware/gnss/IGnss.aidl | 8 ++ .../IMeasurementCorrectionsCallback.aidl | 57 ++++++++++++ .../IMeasurementCorrectionsInterface.aidl | 48 ++++++++++ .../MeasurementCorrections.aidl | 102 +++++++++++++++++++++ .../measurement_corrections/ReflectingPlane.aidl | 43 +++++++++ .../SingleSatCorrection.aidl | 85 +++++++++++++++++ gnss/aidl/default/Android.bp | 1 + gnss/aidl/default/Gnss.cpp | 11 +++ gnss/aidl/default/Gnss.h | 5 + .../default/MeasurementCorrectionsInterface.cpp | 68 ++++++++++++++ .../aidl/default/MeasurementCorrectionsInterface.h | 36 ++++++++ gnss/aidl/vts/Android.bp | 1 + gnss/aidl/vts/MeasurementCorrectionsCallback.cpp | 26 ++++++ gnss/aidl/vts/MeasurementCorrectionsCallback.h | 31 +++++++ gnss/aidl/vts/gnss_hal_test_cases.cpp | 46 +++++++++- gnss/common/utils/vts/Utils.cpp | 58 ++++++++++++ gnss/common/utils/vts/include/Utils.h | 4 + 28 files changed, 863 insertions(+), 2 deletions(-) create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl create mode 100644 gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl create mode 100644 gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl create mode 100644 gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl create mode 100644 gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl create mode 100644 gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl create mode 100644 gnss/aidl/default/MeasurementCorrectionsInterface.cpp create mode 100644 gnss/aidl/default/MeasurementCorrectionsInterface.h create mode 100644 gnss/aidl/vts/MeasurementCorrectionsCallback.cpp create mode 100644 gnss/aidl/vts/MeasurementCorrectionsCallback.h diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index a52fde458e..3d2ef2c80e 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -265,6 +265,14 @@ default + + android.hardware.gnss.measurement_corrections + 1 + + IMeasurementCorrectionsInterface + default + + android.hardware.graphics.allocator diff --git a/gnss/1.1/vts/functional/Android.bp b/gnss/1.1/vts/functional/Android.bp index c59d5e7a64..f8fad94a34 100644 --- a/gnss/1.1/vts/functional/Android.bp +++ b/gnss/1.1/vts/functional/Android.bp @@ -36,6 +36,7 @@ cc_test { "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", "android.hardware.gnss@common-vts-lib", + "android.hardware.gnss-V2-cpp", ], shared_libs: [ "android.hardware.gnss.measurement_corrections@1.0", diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp index 3bbd572841..2042dd9f17 100644 --- a/gnss/2.0/vts/functional/Android.bp +++ b/gnss/2.0/vts/functional/Android.bp @@ -39,6 +39,10 @@ cc_test { "android.hardware.gnss@2.0", "android.hardware.gnss@2.1", "android.hardware.gnss@common-vts-lib", + "android.hardware.gnss-V2-cpp", + ], + test_suites: [ + "general-tests", + "vts", ], - test_suites: ["general-tests", "vts"], } diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp index aaddd96f8c..d7b6eebbe9 100644 --- a/gnss/2.1/vts/functional/Android.bp +++ b/gnss/2.1/vts/functional/Android.bp @@ -40,6 +40,7 @@ cc_test { "android.hardware.gnss@2.0", "android.hardware.gnss@2.1", "android.hardware.gnss@common-vts-lib", + "android.hardware.gnss-V2-cpp", ], shared_libs: [ "libvintf", diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp index d90cf0b634..4d9c5cc231 100644 --- a/gnss/aidl/Android.bp +++ b/gnss/aidl/Android.bp @@ -28,6 +28,7 @@ aidl_interface { vendor_available: true, srcs: [ "android/hardware/gnss/*.aidl", + "android/hardware/gnss/measurement_corrections/*.aidl", "android/hardware/gnss/visibility_control/*.aidl", ], stability: "vintf", diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl index 281c531977..fb13e026bb 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl @@ -54,6 +54,7 @@ interface IGnss { void deleteAidingData(in android.hardware.gnss.IGnss.GnssAidingData aidingDataFlags); void setPositionMode(in android.hardware.gnss.IGnss.GnssPositionMode mode, in android.hardware.gnss.IGnss.GnssPositionRecurrence recurrence, in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs, in boolean lowPowerMode); android.hardware.gnss.IGnssAntennaInfo getExtensionGnssAntennaInfo(); + @nullable android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsInterface getExtensionMeasurementCorrections(); const int ERROR_INVALID_ARGUMENT = 1; const int ERROR_ALREADY_INIT = 2; const int ERROR_GENERIC = 3; diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl new file mode 100644 index 0000000000..c4cf13f406 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss.measurement_corrections; +@VintfStability +interface IMeasurementCorrectionsCallback { + void setCapabilitiesCb(in int capabilities); + const int CAPABILITY_LOS_SATS = 1; + const int CAPABILITY_EXCESS_PATH_LENGTH = 2; + const int CAPABILITY_REFLECTING_PLANE = 4; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl new file mode 100644 index 0000000000..5dc55960c5 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss.measurement_corrections; +@VintfStability +interface IMeasurementCorrectionsInterface { + void setCorrections(in android.hardware.gnss.measurement_corrections.MeasurementCorrections corrections); + void setCallback(in android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsCallback callback); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl new file mode 100644 index 0000000000..f32c8c27bf --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss.measurement_corrections; +@VintfStability +parcelable MeasurementCorrections { + double latitudeDegrees; + double longitudeDegrees; + double altitudeMeters; + double horizontalPositionUncertaintyMeters; + double verticalPositionUncertaintyMeters; + long toaGpsNanosecondsOfWeek; + android.hardware.gnss.measurement_corrections.SingleSatCorrection[] satCorrections; + boolean hasEnvironmentBearing; + float environmentBearingDegrees; + float environmentBearingUncertaintyDegrees; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl new file mode 100644 index 0000000000..90c3818b1c --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss.measurement_corrections; +@VintfStability +parcelable ReflectingPlane { + double latitudeDegrees; + double longitudeDegrees; + double altitudeMeters; + double azimuthDegrees; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl new file mode 100644 index 0000000000..d18c1a7339 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss.measurement_corrections; +@VintfStability +parcelable SingleSatCorrection { + int singleSatCorrectionFlags; + android.hardware.gnss.GnssConstellationType constellation; + int svid; + long carrierFrequencyHz; + float probSatIsLos; + float excessPathLengthMeters; + float excessPathLengthUncertaintyMeters; + android.hardware.gnss.measurement_corrections.ReflectingPlane reflectingPlane; + const int SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY = 1; + const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH = 2; + const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC = 4; + const int SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE = 8; +} diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index e1d46703fa..1e1c0fab96 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -28,6 +28,7 @@ import android.hardware.gnss.IGnssMeasurementInterface; import android.hardware.gnss.IGnssNavigationMessageInterface; import android.hardware.gnss.IGnssPowerIndication; import android.hardware.gnss.IGnssPsds; +import android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsInterface; import android.hardware.gnss.visibility_control.IGnssVisibilityControl; /** @@ -285,4 +286,11 @@ interface IGnss { * @return Handle to the IGnssAntennaInfo. */ IGnssAntennaInfo getExtensionGnssAntennaInfo(); + + /** + * This method returns the IMeasurementCorrectionsInterface. + * + * @return Handle to the IMeasurementCorrectionsInterface. + */ + @nullable IMeasurementCorrectionsInterface getExtensionMeasurementCorrections(); } diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl new file mode 100644 index 0000000000..d695e70451 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 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.measurement_corrections; + +/** + * GNSS measurement corrections callback interface. + */ +@VintfStability +interface IMeasurementCorrectionsCallback { + /** + * Flags to indicate supported measurement corrections capabilities + * + * Either the LOS_SATS or the EXCESS_PATH_LENGTH capability must be supported. + */ + /** + * Capability bit flag indicating that GNSS supports line-of-sight satellite identification + * measurement corrections + */ + const int CAPABILITY_LOS_SATS = 1 << 0; + /** + * Capability bit flag indicating that GNSS supports per satellite excess-path-length + * measurement corrections + */ + const int CAPABILITY_EXCESS_PATH_LENGTH = 1 << 1; + /** + * Capability bit flag indicating that GNSS supports reflecting planes measurement + * corrections + */ + const int CAPABILITY_REFLECTING_PLANE = 1 << 2; + + /** + * Callback to inform framework the measurement correction specific capabilities of the GNSS + * HAL implementation. + * + * The GNSS HAL must call this method immediately after the framework opens the measurement + * corrections interface. + * + * @param capabilities A bit field of flags indicating the capabilities of measurement + * corrections. + * It is mandatory to support either LOS_STATS or EXCESS_PATH_LENGTH capability. + */ + void setCapabilitiesCb(in int capabilities); +} diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl new file mode 100644 index 0000000000..eeabc6d399 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 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.measurement_corrections; + +import android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsCallback; +import android.hardware.gnss.measurement_corrections.MeasurementCorrections; + +/** + * Interface for measurement corrections support. + */ +@VintfStability +interface IMeasurementCorrectionsInterface { + /** + * Injects measurement corrections to be used by the HAL to improve the GNSS location output. + * + * These are NOT to be used to adjust the IGnssMeasurementCallback output values - + * those remain raw, uncorrected measurements. + * + * In general, these are injected when conditions defined by the platform are met, such as when + * GNSS Location is being requested at a sufficiently high accuracy, based on the capabilities + * of the GNSS chipset as reported in the IGnssCallback. + * + * @param corrections The computed corrections to be used by the HAL. + */ + void setCorrections(in MeasurementCorrections corrections); + + /** + * Opens the interface and provides the callback routines to the implementation of this + * interface. + * + * @param callback Callback interface for IMeasurementCorrections. + */ + void setCallback(in IMeasurementCorrectionsCallback callback); +} diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl new file mode 100644 index 0000000000..285c7d4faa --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2021 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.measurement_corrections; + +import android.hardware.gnss.measurement_corrections.SingleSatCorrection; + +/** + * A struct containing a set of measurement corrections for all used GNSS satellites at the location + * specified by latitudeDegrees, longitudeDegrees, altitudeMeters and at the time of week specified + * toaGpsNanosecondsOfWeek + */ +@VintfStability +parcelable MeasurementCorrections { + /** Represents latitude in degrees at which the corrections are computed.. */ + double latitudeDegrees; + + /** Represents longitude in degrees at which the corrections are computed.. */ + double longitudeDegrees; + + /** + * Represents altitude in meters above the WGS 84 reference ellipsoid at which the corrections + * are computed. + */ + double altitudeMeters; + + /** + * Represents the horizontal uncertainty (63% to 68% confidence) in meters on the device + * position at which the corrections are provided. + * + * This value is useful for example to judge how accurate the provided corrections are. + */ + double horizontalPositionUncertaintyMeters; + + /** + * Represents the vertical uncertainty (63% to 68% confidence) in meters on the device position + * at which the corrections are provided. + * + * This value is useful for example to judge how accurate the provided corrections are. + */ + double verticalPositionUncertaintyMeters; + + /** Time Of Applicability, GPS time of week in nanoseconds. */ + long toaGpsNanosecondsOfWeek; + + /** + * A set of SingleSatCorrection each containing measurement corrections for a satellite in view + */ + SingleSatCorrection[] satCorrections; + + /** + * Boolean indicating if environment bearing is available. + */ + boolean hasEnvironmentBearing; + + /** + * Environment bearing in degrees clockwise from true North (0.0 to 360.0], in direction of + * user motion. Environment bearing is provided when it is known with high probability that + * velocity is aligned with an environment feature, such as a building or road. + * + * If user speed is zero, environmentBearingDegrees represents bearing of most recent speed + * that was > 0. + * + * As position approaches another road, environmentBearingUncertaintyDegrees will grow, and at + * some stage hasEnvironmentBearing = false. + * + * As position moves towards an open area, environmentBearingUncertaintyDegrees will grow, and + * at some stage hasEnvironmentBearing = false. + * + * If the road is curved in the vicinity of the user location, then + * environmentBearingUncertaintyDegrees will include the amount by which the road direction + * changes in the area of position uncertainty. + * + * hasEnvironmentBearing should be checked to verify the environment bearing is available + * before calling this method. The value is undefined if hasEnvironmentBearing is false. + */ + float environmentBearingDegrees; + + /** + * Environment bearing uncertainty [0 to 180]. It represents the standard deviation of the + * physical structure in the circle of position uncertainty. hasEnvironmentBearing becomes false + * as the uncertainty value passes a predefined threshold depending on the physical structure + * around the user. + * + * hasEnvironmentBearing should be checked to verify the environment bearing is available + * before calling this method. The value is undefined if hasEnvironmentBearing is false. + */ + float environmentBearingUncertaintyDegrees; +} diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl new file mode 100644 index 0000000000..9bf2b4417d --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 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.measurement_corrections; + +/** + * A struct containing the characteristics of the reflecting plane that the satellite signal has + * bounced from. + * + * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane + * means either reflection planes serving is not supported or the satellite signal has gone + * through multiple reflections. + */ +@VintfStability +parcelable ReflectingPlane { + /** Represents latitude of the reflecting plane in degrees. */ + double latitudeDegrees; + + /** Represents longitude of the reflecting plane in degrees. */ + double longitudeDegrees; + + /** + * Represents altitude of the reflecting point in the plane in meters above the WGS 84 reference + * ellipsoid. + */ + double altitudeMeters; + + /** Represents azimuth clockwise from north of the reflecting plane in degrees. */ + double azimuthDegrees; +} diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl new file mode 100644 index 0000000000..d9f7105170 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2021 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.measurement_corrections; + +import android.hardware.gnss.GnssConstellationType; +import android.hardware.gnss.measurement_corrections.ReflectingPlane; + +/** + * A struct with measurement corrections for a single visible satellites + * + * The bit mask singleSatCorrectionFlags indicates which correction values are valid in the struct + */ +@VintfStability +parcelable SingleSatCorrection { + /** Bit mask to indicate which values are valid in a SingleSatCorrection object. */ + /** GnssSingleSatCorrectionFlags has valid satellite-is-line-of-sight-probability field. */ + const int SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY = 0x0001; + /** GnssSingleSatCorrectionFlags has valid Excess Path Length field. */ + const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH = 0x0002; + /** GnssSingleSatCorrectionFlags has valid Excess Path Length Uncertainty field. */ + const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC = 0x0004; + /** GnssSingleSatCorrectionFlags has valid Reflecting Plane field. */ + const int SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE = 0x0008; + + /** Contains GnssSingleSatCorrectionFlags bits. */ + int singleSatCorrectionFlags; + + /** + * Defines the constellation of the given satellite. + */ + GnssConstellationType constellation; + + /** + * Satellite vehicle ID number, as defined in GnssSvInfo::svid + */ + int svid; + + /** + * Carrier frequency of the signal to be corrected, for example it can be the + * GPS center frequency for L1 = 1,575,420,000 Hz, varying GLO channels, etc. + * + * For a receiver with capabilities to track multiple frequencies for the same satellite, + * multiple corrections for the same satellite may be provided. + */ + long carrierFrequencyHz; + + /** + * The probability that the satellite is estimated to be in Line-of-Sight condition at the given + * location. + */ + float probSatIsLos; + + /** + * Excess path length to be subtracted from pseudorange before using it in calculating location. + * + * Note this value is NOT to be used to adjust the GnsseasurementCallback outputs. + */ + float excessPathLengthMeters; + + /** Error estimate (1-sigma) for the Excess path length estimate */ + float excessPathLengthUncertaintyMeters; + + /** + * Defines the reflecting plane characteristics such as location and azimuth + * + * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane + * means either reflection planes serving is not supported or the satellite signal has gone + * through multiple reflections. + */ + ReflectingPlane reflectingPlane; +} diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 0031dcf92a..3be7fb929e 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -68,6 +68,7 @@ cc_binary { "GnssConfiguration.cpp", "GnssMeasurementInterface.cpp", "GnssVisibilityControl.cpp", + "MeasurementCorrectionsInterface.cpp", "service.cpp", ], static_libs: [ diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index 2c6df995f1..033088506b 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -30,6 +30,7 @@ #include "GnssNavigationMessageInterface.h" #include "GnssPsds.h" #include "GnssVisibilityControl.h" +#include "MeasurementCorrectionsInterface.h" #include "NmeaFixInfo.h" #include "Utils.h" @@ -289,4 +290,14 @@ ndk::ScopedAStatus Gnss::getExtensionGnssAntennaInfo( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Gnss::getExtensionMeasurementCorrections( + std::shared_ptr* + iMeasurementCorrections) { + ALOGD("Gnss::getExtensionMeasurementCorrections"); + + *iMeasurementCorrections = + SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index b92f4fb9ba..478dc94e4d 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +73,10 @@ class Gnss : public BnGnss { iGnssVisibilityControl) override; ndk::ScopedAStatus getExtensionGnssAntennaInfo( std::shared_ptr* iGnssAntennaInfo) override; + ndk::ScopedAStatus getExtensionMeasurementCorrections( + std::shared_ptr* iMeasurementCorrections) + override; std::shared_ptr mGnssConfiguration; std::shared_ptr mGnssPowerIndication; diff --git a/gnss/aidl/default/MeasurementCorrectionsInterface.cpp b/gnss/aidl/default/MeasurementCorrectionsInterface.cpp new file mode 100644 index 0000000000..0f1851cafe --- /dev/null +++ b/gnss/aidl/default/MeasurementCorrectionsInterface.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2021 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 "MeasurementCorrectionsInterface" + +#include "MeasurementCorrectionsInterface.h" +#include +#include + +namespace aidl::android::hardware::gnss::measurement_corrections { + +std::shared_ptr MeasurementCorrectionsInterface::sCallback = + nullptr; + +ndk::ScopedAStatus MeasurementCorrectionsInterface::setCorrections( + const MeasurementCorrections& corrections) { + ALOGD("setCorrections"); + ALOGD("corrections = lat: %f, lng: %f, alt: %f, hUnc: %f, vUnc: %f, toa: %llu, " + "satCorrections.size: %d", + corrections.latitudeDegrees, corrections.longitudeDegrees, corrections.altitudeMeters, + corrections.horizontalPositionUncertaintyMeters, + corrections.verticalPositionUncertaintyMeters, + static_cast(corrections.toaGpsNanosecondsOfWeek), + static_cast(corrections.satCorrections.size())); + for (auto singleSatCorrection : corrections.satCorrections) { + ALOGD("singleSatCorrection = flags: %d, constellation: %d, svid: %d" + ", cfHz: %" PRId64 ", probLos: %f, epl: %f, eplUnc: %f", + singleSatCorrection.singleSatCorrectionFlags, singleSatCorrection.constellation, + singleSatCorrection.svid, singleSatCorrection.carrierFrequencyHz, + singleSatCorrection.probSatIsLos, singleSatCorrection.excessPathLengthMeters, + singleSatCorrection.excessPathLengthUncertaintyMeters); + ALOGD("reflecting plane = lat: %f, lng: %f, alt: %f, azm: %f", + singleSatCorrection.reflectingPlane.latitudeDegrees, + singleSatCorrection.reflectingPlane.longitudeDegrees, + singleSatCorrection.reflectingPlane.altitudeMeters, + singleSatCorrection.reflectingPlane.azimuthDegrees); + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus MeasurementCorrectionsInterface::setCallback( + const std::shared_ptr& callback) { + ALOGD("MeasurementCorrections::setCallback"); + std::unique_lock lock(mMutex); + sCallback = callback; + auto ret = sCallback->setCapabilitiesCb( + IMeasurementCorrectionsCallback::CAPABILITY_LOS_SATS | + IMeasurementCorrectionsCallback::CAPABILITY_EXCESS_PATH_LENGTH | + IMeasurementCorrectionsCallback::CAPABILITY_REFLECTING_PLANE); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } + return ndk::ScopedAStatus::ok(); +} +} // namespace aidl::android::hardware::gnss::measurement_corrections diff --git a/gnss/aidl/default/MeasurementCorrectionsInterface.h b/gnss/aidl/default/MeasurementCorrectionsInterface.h new file mode 100644 index 0000000000..af58725050 --- /dev/null +++ b/gnss/aidl/default/MeasurementCorrectionsInterface.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::gnss::measurement_corrections { + +struct MeasurementCorrectionsInterface : public BnMeasurementCorrectionsInterface { + public: + ndk::ScopedAStatus setCorrections(const MeasurementCorrections& corrections) override; + ndk::ScopedAStatus setCallback( + const std::shared_ptr& callback) override; + + private: + // Synchronization lock for sCallback + mutable std::mutex mMutex; + // Guarded by mMutex + static std::shared_ptr sCallback; +}; + +} // namespace aidl::android::hardware::gnss::measurement_corrections diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index b23a646ae1..4244ab354d 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -39,6 +39,7 @@ cc_test { "GnssNavigationMessageCallback.cpp", "GnssPowerIndicationCallback.cpp", "GnssVisibilityControlCallback.cpp", + "MeasurementCorrectionsCallback.cpp", "VtsHalGnssTargetTest.cpp", ], shared_libs: [ diff --git a/gnss/aidl/vts/MeasurementCorrectionsCallback.cpp b/gnss/aidl/vts/MeasurementCorrectionsCallback.cpp new file mode 100644 index 0000000000..db1f7a6893 --- /dev/null +++ b/gnss/aidl/vts/MeasurementCorrectionsCallback.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2021 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 "MeasurementCorrectionsCallback" + +#include "MeasurementCorrectionsCallback.h" +#include + +android::binder::Status MeasurementCorrectionsCallback::setCapabilitiesCb(const int capabilities) { + ALOGI("Capabilities received %d", capabilities); + capabilities_cbq_.store(capabilities); + return android::binder::Status::ok(); +} diff --git a/gnss/aidl/vts/MeasurementCorrectionsCallback.h b/gnss/aidl/vts/MeasurementCorrectionsCallback.h new file mode 100644 index 0000000000..27e5b3cde2 --- /dev/null +++ b/gnss/aidl/vts/MeasurementCorrectionsCallback.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "GnssCallbackEventQueue.h" + +class MeasurementCorrectionsCallback + : public android::hardware::gnss::measurement_corrections::BnMeasurementCorrectionsCallback { + public: + MeasurementCorrectionsCallback() : capabilities_cbq_("capabilities"){}; + ~MeasurementCorrectionsCallback(){}; + android::binder::Status setCapabilitiesCb(const int capabilities) override; + + android::hardware::gnss::common::GnssCallbackEventQueue capabilities_cbq_; + int last_capabilities_; +}; diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index f5f0aa4c52..6e363f9815 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include "AGnssCallbackAidl.h" @@ -35,6 +36,8 @@ #include "GnssNavigationMessageCallback.h" #include "GnssPowerIndicationCallback.h" #include "GnssVisibilityControlCallback.h" +#include "MeasurementCorrectionsCallback.h" +#include "Utils.h" #include "gnss_hal_test.h" using android::sp; @@ -62,6 +65,8 @@ using android::hardware::gnss::IGnssPowerIndication; using android::hardware::gnss::IGnssPsds; using android::hardware::gnss::PsdsType; using android::hardware::gnss::SatellitePvt; +using android::hardware::gnss::common::Utils; +using android::hardware::gnss::measurement_corrections::IMeasurementCorrectionsInterface; using android::hardware::gnss::visibility_control::IGnssVisibilityControl; using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType; @@ -909,7 +914,6 @@ TEST_P(GnssHalTest, GnssDebugValuesSanityTest) { } /* - * TestAGnssExtension: * TestGnssVisibilityControlExtension: * 1. Gets the IGnssVisibilityControl extension. * 2. Sets GnssVisibilityControlCallback @@ -1095,3 +1099,43 @@ TEST_P(GnssHalTest, TestGnssAntennaInfo) { iGnssAntennaInfo->close(); } + +/* + * TestGnssMeasurementCorrections: + * If measurement corrections capability is supported, verifies that the measurement corrections + * capabilities are reported and the mandatory LOS_SATS or the EXCESS_PATH_LENGTH + * capability flag is set. + */ +TEST_P(GnssHalTest, TestGnssMeasurementCorrections) { + if (aidl_gnss_hal_->getInterfaceVersion() == 1) { + return; + } + if (!(aidl_gnss_cb_->last_capabilities_ & + (int)GnssCallbackAidl::CAPABILITY_MEASUREMENT_CORRECTIONS)) { + return; + } + + sp iMeasurementCorrectionsAidl; + auto status = aidl_gnss_hal_->getExtensionMeasurementCorrections(&iMeasurementCorrectionsAidl); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iMeasurementCorrectionsAidl != nullptr); + + // Setup measurement corrections callback. + auto gnssMeasurementCorrectionsCallback = sp::make(); + status = iMeasurementCorrectionsAidl->setCallback(gnssMeasurementCorrectionsCallback); + ASSERT_TRUE(status.isOk()); + + const int kTimeoutSec = 5; + EXPECT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.retrieve( + gnssMeasurementCorrectionsCallback->last_capabilities_, kTimeoutSec)); + ASSERT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.calledCount() > 0); + + ASSERT_TRUE((gnssMeasurementCorrectionsCallback->last_capabilities_ & + (MeasurementCorrectionsCallback::CAPABILITY_LOS_SATS | + MeasurementCorrectionsCallback::CAPABILITY_EXCESS_PATH_LENGTH)) != 0); + + // Set a mock MeasurementCorrections. + status = iMeasurementCorrectionsAidl->setCorrections( + Utils::getMockMeasurementCorrections_aidl()); + ASSERT_TRUE(status.isOk()); +} diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp index 06bce9d3a7..da4c07fc05 100644 --- a/gnss/common/utils/vts/Utils.cpp +++ b/gnss/common/utils/vts/Utils.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include "gtest/gtest.h" @@ -28,6 +29,12 @@ namespace common { using namespace measurement_corrections::V1_0; using V1_0::GnssLocationFlags; +using MeasurementCorrectionsAidl = + android::hardware::gnss::measurement_corrections::MeasurementCorrections; +using ReflectingPlaneAidl = android::hardware::gnss::measurement_corrections::ReflectingPlane; +using SingleSatCorrectionAidl = + android::hardware::gnss::measurement_corrections::SingleSatCorrection; + template <> int64_t Utils::getLocationTimestampMillis(const android::hardware::gnss::GnssLocation& location) { return location.timestampMillis; @@ -63,6 +70,7 @@ const MeasurementCorrections Utils::getMockMeasurementCorrections() { .singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY | GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH | GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC, + .constellation = V1_0::GnssConstellationType::GPS, .svid = 9, .carrierFrequencyHz = 1.59975e+09, @@ -114,6 +122,56 @@ Utils::getMockMeasurementCorrections_1_1() { return mockCorrections_1_1; } +const MeasurementCorrectionsAidl Utils::getMockMeasurementCorrections_aidl() { + ReflectingPlaneAidl reflectingPlane; + reflectingPlane.latitudeDegrees = 37.4220039; + reflectingPlane.longitudeDegrees = -122.0840991; + reflectingPlane.altitudeMeters = 250.35; + reflectingPlane.azimuthDegrees = 203.0; + + SingleSatCorrectionAidl singleSatCorrection1; + singleSatCorrection1.singleSatCorrectionFlags = + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE; + singleSatCorrection1.constellation = android::hardware::gnss::GnssConstellationType::GPS; + singleSatCorrection1.svid = 12; + singleSatCorrection1.carrierFrequencyHz = 1.59975e+09; + singleSatCorrection1.probSatIsLos = 0.50001; + singleSatCorrection1.excessPathLengthMeters = 137.4802; + singleSatCorrection1.excessPathLengthUncertaintyMeters = 25.5; + singleSatCorrection1.reflectingPlane = reflectingPlane; + + SingleSatCorrectionAidl singleSatCorrection2; + singleSatCorrection2.singleSatCorrectionFlags = + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH | + SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC; + singleSatCorrection2.constellation = GnssConstellationType::GPS; + singleSatCorrection2.svid = 9; + singleSatCorrection2.carrierFrequencyHz = 1.59975e+09; + singleSatCorrection2.probSatIsLos = 0.873; + singleSatCorrection2.excessPathLengthMeters = 26.294; + singleSatCorrection2.excessPathLengthUncertaintyMeters = 10.0; + + std::vector singleSatCorrections = {singleSatCorrection1, + singleSatCorrection2}; + MeasurementCorrectionsAidl mockCorrections; + mockCorrections.latitudeDegrees = 37.4219999; + mockCorrections.longitudeDegrees = -122.0840575; + mockCorrections.altitudeMeters = 30.60062531; + mockCorrections.horizontalPositionUncertaintyMeters = 9.23542; + mockCorrections.verticalPositionUncertaintyMeters = 15.02341; + mockCorrections.toaGpsNanosecondsOfWeek = 2935633453L; + mockCorrections.hasEnvironmentBearing = true; + mockCorrections.environmentBearingDegrees = 45.0; + mockCorrections.environmentBearingUncertaintyDegrees = 4.0; + mockCorrections.satCorrections = singleSatCorrections; + + return mockCorrections; +} + /* * MapConstellationType: * Given a GnssConstellationType_2_0 type constellation, maps to its equivalent diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h index 40f31d288e..4ea6cd617d 100644 --- a/gnss/common/utils/vts/include/Utils.h +++ b/gnss/common/utils/vts/include/Utils.h @@ -21,6 +21,8 @@ #include #include #include +#include + #include namespace android { @@ -36,6 +38,8 @@ struct Utils { getMockMeasurementCorrections(); static const measurement_corrections::V1_1::MeasurementCorrections getMockMeasurementCorrections_1_1(); + static const android::hardware::gnss::measurement_corrections::MeasurementCorrections + getMockMeasurementCorrections_aidl(); static V1_0::GnssConstellationType mapConstellationType( V2_0::GnssConstellationType constellation); -- cgit v1.2.3 From ad5d0702b7f4f010ae29be91362444e0ec55a85f Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Wed, 19 Jan 2022 19:01:44 +0800 Subject: Remove GnssAntennaInfo AIDL capability Since JNI is not ready yet, remove it to avoid cts fail. Bug: 215281989 Test: atest LocationManagerFineTest Change-Id: I69ced31e1de54ef9a325ba20020f1913fe3daddd --- gnss/aidl/default/Gnss.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index 2c6df995f1..797570b1e2 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -57,8 +57,7 @@ ScopedAStatus Gnss::setCallback(const std::shared_ptr& callback) int capabilities = (int)(IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST | IGnssCallback::CAPABILITY_SATELLITE_PVT | - IGnssCallback::CAPABILITY_CORRELATION_VECTOR | - IGnssCallback::CAPABILITY_ANTENNA_INFO); + IGnssCallback::CAPABILITY_CORRELATION_VECTOR); auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities); if (!status.isOk()) { -- cgit v1.2.3 From 0cf627aed2fed5d38897473a063fb97fde527fdd Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Tue, 18 Jan 2022 18:07:54 -0800 Subject: Wifi: Add vendor hal 1.6 to rc and make files This CL adds ver 1.6 in Android.bp and rc file. Those were missed when the HAL version was uprev'd to 1.6 Bug: 214108561 Test: atest VtsHalWifiV1_0TargetTest VtsHalWifiNanV1_0TargetTest VtsHalWifiApV1_0TargetTest \ VtsHalWifiV1_1TargetTest \ VtsHalWifiV1_2TargetTest VtsHalWifiNanV1_2TargetTest \ VtsHalWifiV1_3TargetTest \ VtsHalWifiApV1_4TargetTest VtsHalWifiNanV1_4TargetTest VtsHalWifiRttV1_4TargetTest \ VtsHalWifiV1_5TargetTest VtsHalWifiNanV1_5TargetTest VtsHalWifiApV1_5TargetTest Change-Id: I5ce531b92af12b54b4a25548e6fef1198fb23716 --- wifi/1.6/default/Android.bp | 2 ++ wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc | 1 + 2 files changed, 3 insertions(+) diff --git a/wifi/1.6/default/Android.bp b/wifi/1.6/default/Android.bp index 6333b6e265..d48d18332f 100644 --- a/wifi/1.6/default/Android.bp +++ b/wifi/1.6/default/Android.bp @@ -33,6 +33,7 @@ cc_defaults { "android.hardware.wifi@1.3", "android.hardware.wifi@1.4", "android.hardware.wifi@1.5", + "android.hardware.wifi@1.6", "libbase", "libcutils", "libhidlbase", @@ -84,6 +85,7 @@ cc_defaults { "android.hardware.wifi@1.3", "android.hardware.wifi@1.4", "android.hardware.wifi@1.5", + "android.hardware.wifi@1.6", "libbase", "libcutils", "libhidlbase", diff --git a/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc index bc6bb6a7e6..ee8c818d90 100644 --- a/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc +++ b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc @@ -5,6 +5,7 @@ service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service- interface android.hardware.wifi@1.3::IWifi default interface android.hardware.wifi@1.4::IWifi default interface android.hardware.wifi@1.5::IWifi default + interface android.hardware.wifi@1.6::IWifi default oneshot disabled class hal -- cgit v1.2.3