diff --git a/universal7885-common/apps/FMRadio/jni/Android.bp b/universal7885-common/apps/FMRadio/jni/Android.bp new file mode 100644 index 0000000..6068e7c --- /dev/null +++ b/universal7885-common/apps/FMRadio/jni/Android.bp @@ -0,0 +1,27 @@ +cc_library_shared { + name: "libaudiohack", + cflags: [ + "-Wno-unused-parameter", + ], + srcs: [ + "FM_AudioRoute_ctl.cpp", + ], + defaults: ["eureka_defaults"], + shared_libs: [ + "liblog", + "libutils", + "audioflinger-aidl-cpp", + "audiopolicy-aidl-cpp", + "audiopolicy-types-aidl-cpp", + "libaudiofoundation", + "libaudioutils", + "libaudioclient", + "libutils", + "libaudiopolicy", + "libaudiomanager", + ], + header_libs: [ + "libaudioclient_headers", + "jni_headers", + ], +} diff --git a/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_AudioRoute_ctl.cpp b/universal7885-common/apps/FMRadio/jni/FM_AudioRoute_ctl.cpp similarity index 100% rename from universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_AudioRoute_ctl.cpp rename to universal7885-common/apps/FMRadio/jni/FM_AudioRoute_ctl.cpp diff --git a/universal7885-common/apps/aidl-support/fm/default/Android.bp b/universal7885-common/apps/aidl-support/fm/default/Android.bp index 6c0aec3..eb6913e 100644 --- a/universal7885-common/apps/aidl-support/fm/default/Android.bp +++ b/universal7885-common/apps/aidl-support/fm/default/Android.bp @@ -1,10 +1,12 @@ cc_binary { name: "vendor.eureka.hardware.fmradio-service", srcs: [ - "FMRadio.cpp", + "FMSupport.cpp", + "FMDevControl.cpp", "service.cpp", ], defaults: ["eureka_defaults"], + static_libs: ["libfm_slsi-impl"], shared_libs: [ "libbase", "libbinder_ndk", diff --git a/universal7885-common/apps/aidl-support/fm/default/FMDevControl.cpp b/universal7885-common/apps/aidl-support/fm/default/FMDevControl.cpp new file mode 100644 index 0000000..6aa42d7 --- /dev/null +++ b/universal7885-common/apps/aidl-support/fm/default/FMDevControl.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2021 Eureka Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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 "FMDevControl.h" + +#include + +#include +#include + +namespace aidl::vendor::eureka::hardware::fmradio { + +static int fd = -1; + +::ndk::ScopedAStatus FMDevControl::open(void) { + fd = fm_radio_slsi::open_device(); + assert(fd > 0); + fm_radio_slsi::bootctrl(fd); + return ::ndk::ScopedAStatus::ok(); +} +::ndk::ScopedAStatus FMDevControl::getValue(GetType type, int *_aidl_return) { + assert(fd > 0); + switch (type) { + case GetType::GET_TYPE_FM_FREQ: + int64_t freq; + fm_radio_slsi::get_frequency(fd, &freq); + *_aidl_return = freq; + break; + case GetType::GET_TYPE_FM_UPPER_LIMIT: + *_aidl_return = fm_radio_slsi::get_upperband_limit(fd); + break; + case GetType::GET_TYPE_FM_LOWER_LIMIT: + *_aidl_return = fm_radio_slsi::get_lowerband_limit(fd); + break; + case GetType::GET_TYPE_FM_RMSSI: + *_aidl_return = fm_radio_slsi::get_rmssi(fd); + break; + case GetType::GET_TYPE_FM_BEFORE_CHANNEL: + *_aidl_return = fm_radio_slsi::before_channel(fd); + break; + case GetType::GET_TYPE_FM_NEXT_CHANNEL: + *_aidl_return = fm_radio_slsi::next_channel(fd); + break; + default: + break; + }; + return ::ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus FMDevControl::setValue(SetType type, int value) { + assert(fd > 0); + switch (type) { + case SetType::SET_TYPE_FM_FREQ: + fm_radio_slsi::set_frequency(fd, value); + break; + case SetType::SET_TYPE_FM_MUTE: + fm_radio_slsi::set_mute(fd, value); + break; + case SetType::SET_TYPE_FM_VOLUME: + fm_radio_slsi::set_volume(fd, value); + break; + case SetType::SET_TYPE_FM_THREAD: + fm_radio_slsi::fm_thread_set(fd, value); + break; + case SetType::SET_TYPE_FM_RMSSI: + fm_radio_slsi::set_rssi(fd, value); + break; + case SetType::SET_TYPE_FM_SEARCH_CANCEL: + fm_radio_slsi::stop_search(fd); + break; + default: + break; + }; + return ::ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus FMDevControl::getFreqsList(std::vector *_aidl_return){ + auto vec = fm_radio_slsi::get_freqs(fd); + for (auto i : vec) + _aidl_return->push_back(i); + return ::ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus FMDevControl::close() { + if (fd > 0) ::close(fd); + fd = -1; + return ::ndk::ScopedAStatus::ok(); +} +} // namespace aidl::vendor::eureka::hardware::fmradio diff --git a/universal7885-common/apps/aidl-support/fm/default/FMDevControl.h b/universal7885-common/apps/aidl-support/fm/default/FMDevControl.h new file mode 100644 index 0000000..1a2d9a8 --- /dev/null +++ b/universal7885-common/apps/aidl-support/fm/default/FMDevControl.h @@ -0,0 +1,31 @@ +// Copyright (C) 2021 Eureka Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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::vendor::eureka::hardware::fmradio { + +struct FMDevControl : public BnFMDevControl { +public: + FMDevControl() = default; + // Methods from aidl::vendor::eureka::hardware::fmradio::IFMRadio follow. + ::ndk::ScopedAStatus open(void) override; + ::ndk::ScopedAStatus getValue(GetType type, int *_aidl_return) override; + ::ndk::ScopedAStatus setValue(SetType type, int value) override; + ::ndk::ScopedAStatus getFreqsList(std::vector *_aidl_return) override; + ::ndk::ScopedAStatus close(void) override; +}; +} // namespace aidl::vendor::eureka::hardware::fmradio diff --git a/universal7885-common/apps/aidl-support/fm/default/FMRadio.cpp b/universal7885-common/apps/aidl-support/fm/default/FMSupport.cpp similarity index 83% rename from universal7885-common/apps/aidl-support/fm/default/FMRadio.cpp rename to universal7885-common/apps/aidl-support/fm/default/FMSupport.cpp index 9730dbb..f193acf 100644 --- a/universal7885-common/apps/aidl-support/fm/default/FMRadio.cpp +++ b/universal7885-common/apps/aidl-support/fm/default/FMSupport.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "FMRadio.h" +#include "FMSupport.h" #include #include #include @@ -30,12 +30,12 @@ constexpr const char *FM_FREQ_CTL = constexpr const char *FM_FREQ_SEEK = "/sys/devices/virtual/s610_radio/s610_radio/radio_freq_seek"; -::ndk::ScopedAStatus FMRadio::setManualFreq(float freq) { +::ndk::ScopedAStatus FMSupport::setManualFreq(float freq) { FileIO::writeline(FM_FREQ_CTL, freq * 1000); return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus FMRadio::adjustFreqByStep(Direction dir) { +::ndk::ScopedAStatus FMSupport::adjustFreqByStep(Direction dir) { std::string value = ""; if (dir == Direction::UP) { value = "1 " + std::to_string(mChannelSpacing * 10); @@ -45,21 +45,21 @@ constexpr const char *FM_FREQ_SEEK = FileIO::writeline(FM_FREQ_SEEK, value); return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus FMRadio::isAvailable(bool *_aidl_return) { +::ndk::ScopedAStatus FMSupport::isAvailable(bool *_aidl_return) { struct stat info; *_aidl_return = stat("/sys/devices/virtual/s610_radio/s610_radio/", &info) != 0; return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus FMRadio::setChannelSpacing(Space space) { +::ndk::ScopedAStatus FMSupport::setChannelSpacing(Space space) { mChannelSpacing = static_cast(space); return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus FMRadio::getFreqFromSysfs(int32_t *_aidl_return) { +::ndk::ScopedAStatus FMSupport::getFreqFromSysfs(int32_t *_aidl_return) { *_aidl_return = FileIO::readline(FM_FREQ_CTL); return ndk::ScopedAStatus::ok(); } -::ndk::ScopedAStatus FMRadio::getChannelSpacing(Space *_aidl_return) { +::ndk::ScopedAStatus FMSupport::getChannelSpacing(Space *_aidl_return) { switch (mChannelSpacing) { case 1: *_aidl_return = Space::CHANNEL_SPACING_10HZ; diff --git a/universal7885-common/apps/aidl-support/fm/default/FMRadio.h b/universal7885-common/apps/aidl-support/fm/default/FMSupport.h similarity index 89% rename from universal7885-common/apps/aidl-support/fm/default/FMRadio.h rename to universal7885-common/apps/aidl-support/fm/default/FMSupport.h index 5ff0526..cb1a463 100644 --- a/universal7885-common/apps/aidl-support/fm/default/FMRadio.h +++ b/universal7885-common/apps/aidl-support/fm/default/FMSupport.h @@ -14,13 +14,13 @@ #pragma once -#include +#include namespace aidl::vendor::eureka::hardware::fmradio { -struct FMRadio : public BnFMRadio { +struct FMSupport : public BnFMSysfsSupport { public: - FMRadio() = default; + FMSupport() = default; // Methods from aidl::vendor::eureka::hardware::fmradio::IFMRadio follow. ::ndk::ScopedAStatus setManualFreq(float freq) override; ::ndk::ScopedAStatus adjustFreqByStep(Direction dir) override; diff --git a/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/Android.bp b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/Android.bp index 83b3c29..fd85b55 100644 --- a/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/Android.bp +++ b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/Android.bp @@ -5,26 +5,7 @@ cc_library_static { ], srcs: [ "FM_Device_ctl.cpp", - "FM_AudioRoute_ctl.cpp", ], export_include_dirs: ["public"], defaults: ["eureka_defaults"], - shared_libs: [ - "libhidlbase", - "liblog", - "libutils", - "audioflinger-aidl-cpp", - "audiopolicy-aidl-cpp", - "audiopolicy-types-aidl-cpp", - "libaudiofoundation", - "libaudioutils", - "libaudioclient", - "libutils", - "libaudiopolicy", - "libaudiomanager", - ], - header_libs: [ - "libaudioclient_headers", - "jni_headers", - ], } diff --git a/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_Device_ctl.cpp b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_Device_ctl.cpp index d1c298e..4fb4a88 100644 --- a/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_Device_ctl.cpp +++ b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_Device_ctl.cpp @@ -10,12 +10,7 @@ #include #include "S610_FMRadio.h" #include "V4L2_4_4_API.h" -#include -#include - -#include #include -#include namespace fm_radio_slsi { @@ -81,7 +76,7 @@ static int set_control(const int fd, unsigned int id, int64_t val) { return FM_SUCCESS; } -int seek_frequency(int fd, unsigned int upward, +static int seek_frequency(int fd, unsigned int upward, unsigned int wrap_around, unsigned int spacing) { struct v4l2_hw_freq_seek seek {}; @@ -100,7 +95,7 @@ int seek_frequency(int fd, unsigned int upward, return FM_SUCCESS; } -int channel_search(const int fd, unsigned int upward, +static int channel_search(const int fd, unsigned int upward, unsigned int wrap_around, unsigned int spacing, int64_t *channel) { int ret; @@ -120,7 +115,16 @@ int channel_search(const int fd, unsigned int upward, return ret; } - +int next_channel(const int fd) { + int64_t ret; + channel_search(fd, 1, 0, FM_CHANNEL_SPACING_100KHZ, &ret); + return ret; +} +int before_channel(const int fd) { + int64_t ret; + channel_search(fd, 0, 0, FM_CHANNEL_SPACING_100KHZ, &ret); + return ret; +} int set_mute(const int fd, bool mute) { int ret = set_control(fd, V4L2_CID_AUDIO_MUTE, !mute); if (ret < 0) { @@ -137,7 +141,7 @@ int set_volume(int fd, int volume /* 1 ~ 15 */) { return FM_SUCCESS; } -std::unique_ptr get_freqs(const int fd) { +std::vector get_freqs(const int fd) { set_mute(fd, true); auto map = std::vector(); @@ -151,13 +155,8 @@ std::unique_ptr get_freqs(const int fd) { map.push_back(found); } - auto ptr = std::make_unique(map.size()); - for (unsigned long i = 0; i < map.size(); i++) { - ptr[i] = map[i]; - } - set_mute(fd, false); - return std::move(ptr); + return map; } static int fm_poll(int fd, struct pollfd *poll_fd) { diff --git a/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/public/fm_slsi-impl.h b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/public/fm_slsi-impl.h index 729dcee..2fe37af 100644 --- a/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/public/fm_slsi-impl.h +++ b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/public/fm_slsi-impl.h @@ -1,19 +1,17 @@ #pragma once -#include +#include namespace fm_radio_slsi { int open_device(void); int get_frequency(const int fd, int64_t *channel); int set_frequency(const int fd, int64_t channel); -int seek_frequency(int fd, unsigned int upward, unsigned int wrap_around, - unsigned int spacing); -int channel_search(const int fd, unsigned int upward, unsigned int wrap_around, - unsigned int spacing, int64_t *channel); +int next_channel(const int fd); +int before_channel(const int fd); int set_mute(const int fd, bool mute); int set_volume(int fd, int volume); -std::unique_ptr get_freqs(const int fd); +std::vector get_freqs(const int fd); void fm_thread_set(const int fd, const bool enable); unsigned int get_upperband_limit(int fd); unsigned int get_lowerband_limit(int fd); diff --git a/universal7885-common/apps/aidl-support/fm/default/service.cpp b/universal7885-common/apps/aidl-support/fm/default/service.cpp index 9128b78..38a6312 100644 --- a/universal7885-common/apps/aidl-support/fm/default/service.cpp +++ b/universal7885-common/apps/aidl-support/fm/default/service.cpp @@ -12,22 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include -#include -#include "FMRadio.h" +#include "FMSupport.h" +#include "FMDevControl.h" -using ::aidl::vendor::eureka::hardware::fmradio::FMRadio; +using ::aidl::vendor::eureka::hardware::fmradio::FMDevControl; +using ::aidl::vendor::eureka::hardware::fmradio::FMSupport; + +template static void registerAsService(std::shared_ptr service) { + const std::string instance = std::string() + C::descriptor + "/default"; + binder_status_t status = + AServiceManager_addService(service->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); + LOG(INFO) << "Register done for " << C::descriptor; +} int main() { ABinderProcess_setThreadPoolMaxThreadCount(0); - std::shared_ptr fm_service = ndk::SharedRefBase::make(); + registerAsService(ndk::SharedRefBase::make()); + registerAsService(ndk::SharedRefBase::make()); - const std::string instance = std::string() + FMRadio::descriptor + "/default"; - binder_status_t status = AServiceManager_addService(fm_service->asBinder().get(), instance.c_str()); - CHECK(status == STATUS_OK); - ABinderProcess_joinThreadPool(); return -1; // should never get here } diff --git a/universal7885-common/apps/aidl-support/fm/default/vendor.eureka.hardware.fmradio.xml b/universal7885-common/apps/aidl-support/fm/default/vendor.eureka.hardware.fmradio.xml index ea321f7..8233be1 100644 --- a/universal7885-common/apps/aidl-support/fm/default/vendor.eureka.hardware.fmradio.xml +++ b/universal7885-common/apps/aidl-support/fm/default/vendor.eureka.hardware.fmradio.xml @@ -1,6 +1,7 @@ vendor.eureka.hardware.fmradio - IFMRadio/default + IFMSysfsSupport/default + IFMDevControl/default diff --git a/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/GetType.aidl b/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/GetType.aidl new file mode 100644 index 0000000..7d7ee30 --- /dev/null +++ b/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/GetType.aidl @@ -0,0 +1,25 @@ +// Copyright (C) 2022 Eureka Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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 vendor.eureka.hardware.fmradio; + +@Backing(type="int") +enum GetType { + GET_TYPE_FM_FREQ, + GET_TYPE_FM_UPPER_LIMIT, + GET_TYPE_FM_LOWER_LIMIT, + GET_TYPE_FM_RMSSI, + GET_TYPE_FM_BEFORE_CHANNEL, + GET_TYPE_FM_NEXT_CHANNEL +} diff --git a/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/IFMDevControl.aidl b/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/IFMDevControl.aidl new file mode 100644 index 0000000..1185032 --- /dev/null +++ b/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/IFMDevControl.aidl @@ -0,0 +1,30 @@ +// Copyright (C) 2022 Eureka Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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 vendor.eureka.hardware.fmradio; + +import vendor.eureka.hardware.fmradio.GetType; +import vendor.eureka.hardware.fmradio.SetType; + +interface IFMDevControl { + void open(); + + int getValue(in GetType type); + + void setValue(in SetType type, int value); + + int[] getFreqsList(); + + void close(); +} diff --git a/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/IFMRadio.aidl b/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/IFMSysfsSupport.aidl similarity index 97% rename from universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/IFMRadio.aidl rename to universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/IFMSysfsSupport.aidl index 17310a6..f914bc5 100644 --- a/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/IFMRadio.aidl +++ b/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/IFMSysfsSupport.aidl @@ -17,7 +17,7 @@ package vendor.eureka.hardware.fmradio; import vendor.eureka.hardware.fmradio.Direction; import vendor.eureka.hardware.fmradio.Space; -interface IFMRadio { +interface IFMSysfsSupport { void adjustFreqByStep(in Direction dir); Space getChannelSpacing(); diff --git a/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/SetType.aidl b/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/SetType.aidl new file mode 100644 index 0000000..7e13d1c --- /dev/null +++ b/universal7885-common/apps/aidl-support/fm/vendor/eureka/hardware/fmradio/SetType.aidl @@ -0,0 +1,25 @@ +// Copyright (C) 2022 Eureka Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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 vendor.eureka.hardware.fmradio; + +@Backing(type="int") +enum SetType { + SET_TYPE_FM_FREQ, + SET_TYPE_FM_MUTE, + SET_TYPE_FM_VOLUME, + SET_TYPE_FM_THREAD, + SET_TYPE_FM_RMSSI, + SET_TYPE_FM_SEARCH_CANCEL, +}