Create a skeleton Rust broadcast radio HAL

This is to prove that rust broadcast radio HAL can be built and can
run. The skeleton Rust broadcast radio HAL will return UNKNOWN_ERROR
for all APIs.

Bug: 335514024
Test: m android.hardware.broadcastradio-rust-service
Change-Id: I763175b984c130d75cdc9506ba92c8c1b44338b5
This commit is contained in:
Weilin Xu 2024-04-16 16:26:45 -07:00
parent 31fdd9bb30
commit 6d71e46f31
7 changed files with 222 additions and 0 deletions

View file

@ -36,6 +36,9 @@ aidl_interface {
sdk_version: "module_current", sdk_version: "module_current",
min_sdk_version: "Tiramisu", min_sdk_version: "Tiramisu",
}, },
rust: {
enabled: true,
},
}, },
versions_with_info: [ versions_with_info: [
{ {
@ -68,3 +71,10 @@ java_defaults {
latest_android_hardware_broadcastradio + "-java", latest_android_hardware_broadcastradio + "-java",
], ],
} }
rust_defaults {
name: "latest_android_hardware_broadcastradio_rust",
rustlibs: [
latest_android_hardware_broadcastradio + "-rust",
],
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
rust_binary {
name: "android.hardware.broadcastradio-rust-service",
relative_install_path: "hw",
vendor: true,
srcs: ["src/*.rs"],
crate_root: "src/main.rs",
defaults: [
"latest_android_hardware_broadcastradio_rust",
],
vintf_fragments: ["broadcastradio-rust-service.xml"],
init_rc: ["broadcastradio-rust-service.rc"],
rustlibs: [
"libbinder_rs",
],
}

View file

@ -0,0 +1,13 @@
# Rust Skeleton BroadcastRadio HAL implementation.
WARNING: This is not a reference BroadcastRadio HAL implementation and does
not contain any actual implementation.
This folder contains a skeleton broadcast radio HAL implementation in Rust to
demonstrate how vendor may implement a Rust broadcast radio HAL. To run this
broadcast radio HAL, include `android.hardware.broadcastradio-rust-service`
in your image.
This implementation returns `StatusCode::UNKNOWN_ERROR` for all operations
and does not pass VTS/CTS. Vendor must replace the logic in
`default_broadcastradio_hal.rs` with the actual implementation

View file

@ -0,0 +1,5 @@
service vendor.broadcastradio-default /vendor/bin/hw/android.hardware.broadcastradio-service.default
interface aidl android.hardware.broadcastradio.IBroadcastRadio/amfm
class hal
user audioserver
group audio

View file

@ -0,0 +1,23 @@
<!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.broadcastradio</name>
<version>2</version>
<fqname>IBroadcastRadio/amfm</fqname>
</hal>
</manifest>

View file

@ -0,0 +1,107 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use android_hardware_broadcastradio::aidl::android::hardware::broadcastradio::{
AmFmRegionConfig::AmFmRegionConfig,
AnnouncementType::AnnouncementType,
ConfigFlag::ConfigFlag,
DabTableEntry::DabTableEntry,
IAnnouncementListener::IAnnouncementListener,
IBroadcastRadio::IBroadcastRadio,
ICloseHandle::ICloseHandle,
ITunerCallback::ITunerCallback,
ProgramFilter::ProgramFilter,
ProgramSelector::ProgramSelector,
Properties::Properties,
VendorKeyValue::VendorKeyValue,
};
use binder::{Interface, Result as BinderResult, StatusCode, Strong};
use std::vec::Vec;
/// This struct is defined to implement IBroadcastRadio AIDL interface.
pub struct DefaultBroadcastRadioHal;
impl Interface for DefaultBroadcastRadioHal {}
impl IBroadcastRadio for DefaultBroadcastRadioHal {
fn getAmFmRegionConfig(&self, _full : bool) -> BinderResult<AmFmRegionConfig> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn getDabRegionConfig(&self) -> BinderResult<Vec<DabTableEntry>> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn getProperties(&self) -> BinderResult<Properties> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn getImage(&self, _id : i32) -> BinderResult<Vec<u8>> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn setTunerCallback(&self, _callback : &Strong<dyn ITunerCallback>) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn unsetTunerCallback(&self) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn tune(&self, _program : &ProgramSelector) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn seek(&self, _direction_up : bool, _skip_sub_channel : bool) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn step(&self, _direction_up : bool) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn cancel(&self) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn startProgramListUpdates(&self, _filter : &ProgramFilter) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn stopProgramListUpdates(&self) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn isConfigFlagSet(&self, _flag : ConfigFlag) -> BinderResult<bool> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn setConfigFlag(&self, _flag : ConfigFlag, _value : bool) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn setParameters(&self, _parameters : &[VendorKeyValue]) -> BinderResult<Vec<VendorKeyValue>> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn getParameters(&self, _parameters : &[String]) -> BinderResult<Vec<VendorKeyValue>> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
fn registerAnnouncementListener(&self, _listener : &Strong<dyn IAnnouncementListener>,
_enabled : &[AnnouncementType]) -> BinderResult<Strong<dyn ICloseHandle>> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mod default_broadcastradio_hal;
use android_hardware_broadcastradio::aidl::android::hardware::broadcastradio::IBroadcastRadio::BnBroadcastRadio;
use crate::default_broadcastradio_hal::DefaultBroadcastRadioHal;
fn main() {
binder::ProcessState::start_thread_pool();
let my_service = DefaultBroadcastRadioHal;
let service_name = "android.hardware.broadcastradio.IBroadcastRadio/amfm";
let my_service_binder = BnBroadcastRadio::new_binder(
my_service,
binder::BinderFeatures::default(),
);
binder::add_service(service_name, my_service_binder.as_binder())
.expect(format!("Failed to register {}?", service_name).as_str());
// Does not return.
binder::ProcessState::join_thread_pool()
}