build(android): support android platform (config and logging) (#3741)
Some checks failed
CodeQL / CodeQL (push) Has been cancelled
CI / GitHub Env Debug (push) Has been cancelled
CI / Release Setup (push) Has been cancelled
CI / Docker (push) Has been cancelled
CI / Homebrew (push) Has been cancelled
CI / Linux (push) Has been cancelled
CI / Linux Copr (push) Has been cancelled
CI / Linux Flatpak (push) Has been cancelled
CI / Windows (push) Has been cancelled
CI / Coverage-Homebrew-macos-13 (push) Has been cancelled
CI / Coverage-Homebrew-macos-14 (push) Has been cancelled
CI / Coverage-Homebrew-macos-15 (push) Has been cancelled
CI / Coverage-Homebrew-ubuntu-latest (push) Has been cancelled
CI / Coverage-Linux-AppImage (push) Has been cancelled
CI / Coverage-Windows-AMD64 (push) Has been cancelled
CI / Release (push) Has been cancelled
Build GH-Pages / prep (push) Has been cancelled
Build GH-Pages / call-jekyll-build (push) Has been cancelled
localize / Update Localization (push) Has been cancelled

This commit is contained in:
Nightmare
2025-07-15 02:33:36 +08:00
committed by GitHub
parent 35f0b30845
commit 4478fd2a14
2 changed files with 64 additions and 3 deletions

View File

@@ -32,7 +32,7 @@
#include <shellapi.h>
#endif
#ifndef __APPLE__
#if !defined(__ANDROID__) && !defined(__APPLE__)
// For NVENC legacy constants
#include <ffnvcodec/nvEncodeAPI.h>
#endif
@@ -1038,9 +1038,12 @@ namespace config {
}
void apply_config(std::unordered_map<std::string, std::string> &&vars) {
#ifndef __ANDROID__
// TODO: Android can possibly support this
if (!fs::exists(stream.file_apps.c_str())) {
fs::copy_file(SUNSHINE_ASSETS_DIR "/apps.json", stream.file_apps);
}
#endif
for (auto &[name, val] : vars) {
BOOST_LOG(info) << "config: '"sv << name << "' = "sv << val;
@@ -1066,7 +1069,7 @@ namespace config {
bool_f(vars, "nvenc_opengl_vulkan_on_dxgi", video.nv_opengl_vulkan_on_dxgi);
bool_f(vars, "nvenc_latency_over_power", video.nv_sunshine_high_power_mode);
#ifndef __APPLE__
#if !defined(__ANDROID__) && !defined(__APPLE__)
video.nv_legacy.preset = video.nv.quality_preset + 11;
video.nv_legacy.multipass = video.nv.two_pass == nvenc::nvenc_two_pass::quarter_resolution ? NV_ENC_TWO_PASS_QUARTER_RESOLUTION :
video.nv.two_pass == nvenc::nvenc_two_pass::full_resolution ? NV_ENC_TWO_PASS_FULL_RESOLUTION :

View File

@@ -15,11 +15,17 @@
#include <boost/log/expressions.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <display_device/logging.h>
// local includes
#include "logging.h"
// conditional includes
#ifdef __ANDROID__
#include <android/log.h>
#else
#include <display_device/logging.h>
#endif
extern "C" {
#include <libavutil/log.h>
}
@@ -97,6 +103,48 @@ namespace logging {
os << "["sv << std::put_time(&lt, "%Y-%m-%d %H:%M:%S.") << boost::format("%03u") % ms.count() << "]: "sv
<< log_type << view.attribute_values()[message].extract<std::string>();
}
#ifdef __ANDROID__
namespace sinks = boost::log::sinks;
namespace expr = boost::log::expressions;
void android_log(const std::string &message, int severity) {
android_LogPriority android_priority;
switch (severity) {
case 0:
android_priority = ANDROID_LOG_VERBOSE;
break;
case 1:
android_priority = ANDROID_LOG_DEBUG;
break;
case 2:
android_priority = ANDROID_LOG_INFO;
break;
case 3:
android_priority = ANDROID_LOG_WARN;
break;
case 4:
android_priority = ANDROID_LOG_ERROR;
break;
case 5:
android_priority = ANDROID_LOG_FATAL;
break;
default:
android_priority = ANDROID_LOG_UNKNOWN;
break;
}
__android_log_print(android_priority, "Sunshine", "%s", message.c_str());
}
// custom sink backend for android
struct android_sink_backend: public sinks::basic_sink_backend<sinks::concurrent_feeding> {
void consume(const bl::record_view &rec) {
int log_sev = rec[severity].get();
const std::string log_msg = rec[expr::smessage].get();
// log to android
android_log(log_msg, log_sev);
}
};
#endif
[[nodiscard]] std::unique_ptr<deinit_t> init(int min_log_level, const std::string &log_file) {
if (sink) {
@@ -104,8 +152,10 @@ namespace logging {
deinit();
}
#ifndef __ANDROID__
setup_av_logging(min_log_level);
setup_libdisplaydevice_logging(min_log_level);
#endif
sink = boost::make_shared<text_sink>();
@@ -113,6 +163,7 @@ namespace logging {
boost::shared_ptr<std::ostream> stream {&std::cout, boost::null_deleter()};
sink->locked_backend()->add_stream(stream);
#endif
sink->locked_backend()->add_stream(boost::make_shared<std::ofstream>(log_file));
sink->set_filter(severity >= min_log_level);
sink->set_formatter(&formatter);
@@ -122,9 +173,15 @@ namespace logging {
sink->locked_backend()->auto_flush(true);
bl::core::get()->add_sink(sink);
#ifdef __ANDROID__
auto android_sink = boost::make_shared<sinks::synchronous_sink<android_sink_backend>>();
bl::core::get()->add_sink(android_sink);
#endif
return std::make_unique<deinit_t>();
}
#ifndef __ANDROID__
void setup_av_logging(int min_log_level) {
if (min_log_level >= 1) {
av_log_set_level(AV_LOG_QUIET);
@@ -182,6 +239,7 @@ namespace logging {
}
});
}
#endif
void log_flush() {
if (sink) {