mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-04-04 20:27:44 -06:00
android: Move update checker to common and make available to Android
This commit is contained in:
parent
3066887ff4
commit
26592ee8f9
@ -17,7 +17,7 @@ else
|
||||
fi
|
||||
|
||||
if [ "$GITHUB_REF_TYPE" == "tag" ]; then
|
||||
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DENABLE_QT_UPDATE_CHECKER=ON)
|
||||
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DENABLE_UPDATE_CHECKER=ON)
|
||||
fi
|
||||
|
||||
mkdir build && cd build
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
if [ "$GITHUB_REF_TYPE" == "tag" ]; then
|
||||
export EXTRA_CMAKE_FLAGS=(-DENABLE_QT_UPDATE_CHECKER=ON)
|
||||
export EXTRA_CMAKE_FLAGS=(-DENABLE_UPDATE_CHECKER=ON)
|
||||
fi
|
||||
|
||||
mkdir -p build/$BUILD_ARCH && cd build/$BUILD_ARCH
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
mkdir build && cd build
|
||||
|
||||
if [ "$GITHUB_REF_TYPE" == "tag" ]; then
|
||||
export EXTRA_CMAKE_FLAGS=(-DENABLE_QT_UPDATE_CHECKER=ON)
|
||||
export EXTRA_CMAKE_FLAGS=(-DENABLE_UPDATE_CHECKER=ON)
|
||||
fi
|
||||
|
||||
cmake .. -G Ninja \
|
||||
|
||||
@ -110,7 +110,7 @@ option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OF
|
||||
# Set bundled qt as dependent options.
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
|
||||
option(ENABLE_QT_UPDATE_CHECKER "Enable built-in update checker for the Qt frontend" OFF)
|
||||
option(ENABLE_UPDATE_CHECKER "Enable built-in update checker for the Qt / Android frontend" OFF)
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_TESTS "Enable generating tests executable" ON "NOT IOS" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_ROOM "Enable dedicated room functionality" ON "NOT ANDROID AND NOT IOS" OFF)
|
||||
|
||||
@ -143,6 +143,8 @@ foreach(KEY IN ITEMS
|
||||
"web_api_url"
|
||||
"citra_username"
|
||||
"citra_token"
|
||||
"check_for_update_on_start"
|
||||
"update_check_channel"
|
||||
)
|
||||
set(SETTING_KEY_LIST "${SETTING_KEY_LIST}\n\"${KEY}\",")
|
||||
set(SETTING_KEY_DEFINITIONS "${SETTING_KEY_DEFINITIONS}\nDEFINE_KEY(${KEY})")
|
||||
|
||||
@ -169,6 +169,11 @@ android {
|
||||
isDefault = true
|
||||
dimension = "version"
|
||||
versionNameSuffix = "-vanilla"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments += "-DENABLE_UPDATE_CHECKER=ON"
|
||||
}
|
||||
}
|
||||
}
|
||||
register("googlePlay") {
|
||||
dimension = "version"
|
||||
|
||||
@ -16,6 +16,11 @@ import org.citra.citra_emu.utils.GpuDriverHelper
|
||||
import org.citra.citra_emu.utils.PermissionsHandler
|
||||
import org.citra.citra_emu.utils.Log
|
||||
import org.citra.citra_emu.utils.MemoryUtil
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.security.KeyStore
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
import javax.net.ssl.X509TrustManager
|
||||
|
||||
class CitraApplication : Application() {
|
||||
private fun createNotificationChannel() {
|
||||
@ -59,6 +64,46 @@ class CitraApplication : Application() {
|
||||
logDeviceInfo()
|
||||
createNotificationChannel()
|
||||
NativeLibrary.playTimeManagerInit()
|
||||
|
||||
if (NativeLibrary.isUpdateCheckerEnabled()) {
|
||||
initializeCACertificates()
|
||||
}
|
||||
}
|
||||
|
||||
// needed for update checking
|
||||
private fun initializeCACertificates() {
|
||||
try {
|
||||
val factory = TrustManagerFactory.getInstance(
|
||||
TrustManagerFactory.getDefaultAlgorithm()
|
||||
)
|
||||
factory.init(null as KeyStore?)
|
||||
|
||||
val trustManager = factory.trustManagers[0] as X509TrustManager
|
||||
|
||||
val certFile = File(filesDir, "cacert.pem")
|
||||
|
||||
if (!certFile.exists()) {
|
||||
FileOutputStream(certFile).use { out ->
|
||||
trustManager.acceptedIssuers.forEach { cert ->
|
||||
out.write("-----BEGIN CERTIFICATE-----\n".toByteArray())
|
||||
|
||||
val encoded = android.util.Base64.encodeToString(
|
||||
cert.encoded,
|
||||
android.util.Base64.NO_WRAP // 👈 important
|
||||
)
|
||||
|
||||
out.write(encoded.toByteArray())
|
||||
out.write("\n-----END CERTIFICATE-----\n".toByteArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NativeLibrary.setCACertificatePath(certFile.absolutePath)
|
||||
|
||||
Log.info("[SSL] CA certs ready: ${certFile.absolutePath}")
|
||||
} catch (e: Exception) {
|
||||
Log.error("[SSL] Failed to init CA certs: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
fun logDeviceInfo() {
|
||||
|
||||
@ -527,6 +527,13 @@ object NativeLibrary {
|
||||
sEmulationActivity.clear()
|
||||
}
|
||||
|
||||
// Update checker
|
||||
external fun getUpdateTag(): String
|
||||
external fun isUpdateCheckerEnabled(): Boolean
|
||||
external fun getUpdateUrl(): String
|
||||
// Sets the path to CA certificates for SSL/TLS verification.
|
||||
external fun setCACertificatePath(path: String)
|
||||
|
||||
private val cameraPermissionLock = Object()
|
||||
private var cameraPermissionGranted = false
|
||||
const val REQUEST_CODE_NATIVE_CAMERA = 800
|
||||
|
||||
@ -138,4 +138,7 @@ object SettingKeys {
|
||||
external fun android_hide_images(): String
|
||||
external fun screen_orientation(): String
|
||||
external fun performance_overlay_position(): String
|
||||
external fun check_for_update_on_start(): String
|
||||
external fun update_check_channel(): String
|
||||
|
||||
}
|
||||
@ -56,7 +56,8 @@ enum class BooleanSetting(
|
||||
COMPRESS_INSTALLED_CIA_CONTENT(SettingKeys.compress_cia_installs(), Settings.SECTION_STORAGE, false),
|
||||
ANDROID_HIDE_IMAGES(SettingKeys.android_hide_images(), Settings.SECTION_MISC, false),
|
||||
APPLY_REGION_FREE_PATCH(SettingKeys.apply_region_free_patch(), Settings.SECTION_SYSTEM, true),
|
||||
USE_INTEGER_SCALING(SettingKeys.use_integer_scaling(), Settings.SECTION_RENDERER, false);
|
||||
USE_INTEGER_SCALING(SettingKeys.use_integer_scaling(), Settings.SECTION_RENDERER, true),
|
||||
CHECK_FOR_UPDATES(SettingKeys.check_for_update_on_start(), Settings.SECTION_THEME, true);
|
||||
|
||||
override var boolean: Boolean = defaultValue
|
||||
|
||||
|
||||
@ -56,6 +56,7 @@ enum class IntSetting(
|
||||
TURBO_LIMIT(SettingKeys.turbo_limit(), Settings.SECTION_CORE, 200),
|
||||
PERFORMANCE_OVERLAY_POSITION(SettingKeys.performance_overlay_position(), Settings.SECTION_LAYOUT, 0),
|
||||
RENDER_3D_WHICH_DISPLAY(SettingKeys.render_3d_which_display(),Settings.SECTION_RENDERER,0),
|
||||
UPDATE_CHECK_CHANNEL(SettingKeys.update_check_channel(), Settings.SECTION_THEME, 0),
|
||||
ASPECT_RATIO(SettingKeys.aspect_ratio(), Settings.SECTION_LAYOUT, 0);
|
||||
|
||||
override var int: Int = defaultValue
|
||||
|
||||
@ -246,7 +246,8 @@ class Settings {
|
||||
SECTION_STORAGE,
|
||||
SECTION_UTILITY,
|
||||
SECTION_AUDIO,
|
||||
SECTION_DEBUG
|
||||
SECTION_DEBUG,
|
||||
SECTION_THEME
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import androidx.preference.PreferenceManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.serialization.builtins.IntArraySerializer
|
||||
import org.citra.citra_emu.CitraApplication
|
||||
import org.citra.citra_emu.NativeLibrary
|
||||
import org.citra.citra_emu.R
|
||||
import org.citra.citra_emu.display.ScreenLayout
|
||||
import org.citra.citra_emu.display.StereoMode
|
||||
@ -1849,7 +1850,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||
}
|
||||
|
||||
private fun addThemeSettings(sl: ArrayList<SettingsItem>) {
|
||||
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_theme))
|
||||
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.app_settings))
|
||||
sl.apply {
|
||||
val theme: AbstractBooleanSetting = object : AbstractBooleanSetting {
|
||||
override var boolean: Boolean
|
||||
@ -1868,6 +1869,37 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||
override val defaultValue = false
|
||||
}
|
||||
|
||||
if (NativeLibrary.isUpdateCheckerEnabled()) {
|
||||
add(
|
||||
HeaderSetting(
|
||||
R.string.app_settings,
|
||||
)
|
||||
)
|
||||
add(
|
||||
SwitchSetting(
|
||||
BooleanSetting.CHECK_FOR_UPDATES,
|
||||
R.string.check_for_updates_on_start,
|
||||
R.string.check_for_updates_on_start_description,
|
||||
)
|
||||
)
|
||||
add(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.UPDATE_CHECK_CHANNEL,
|
||||
R.string.update_check_channel,
|
||||
0,
|
||||
R.array.updateCheckChannelNames,
|
||||
R.array.updateCheckChannelValues,
|
||||
IntSetting.UPDATE_CHECK_CHANNEL.key,
|
||||
IntSetting.UPDATE_CHECK_CHANNEL.defaultValue
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
add(
|
||||
HeaderSetting(
|
||||
R.string.set_up_theme_settings,
|
||||
)
|
||||
)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
add(
|
||||
SwitchSetting(
|
||||
|
||||
@ -170,8 +170,8 @@ class HomeSettingsFragment : Fragment() {
|
||||
details = homeViewModel.gamesDir
|
||||
),
|
||||
HomeSetting(
|
||||
R.string.preferences_theme,
|
||||
R.string.theme_and_color_description,
|
||||
R.string.app_settings,
|
||||
R.string.app_settings_description,
|
||||
R.drawable.ic_palette,
|
||||
{ SettingsActivity.launch(requireContext(), Settings.SECTION_THEME, "") }
|
||||
),
|
||||
|
||||
@ -21,6 +21,7 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
@ -38,6 +39,7 @@ import androidx.work.OneTimeWorkRequest
|
||||
import androidx.work.OutOfQuotaPolicy
|
||||
import androidx.work.WorkManager
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.navigation.NavigationBarView
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.TimeSource
|
||||
@ -47,6 +49,7 @@ import org.citra.citra_emu.NativeLibrary
|
||||
import org.citra.citra_emu.R
|
||||
import org.citra.citra_emu.contracts.OpenFileResultContract
|
||||
import org.citra.citra_emu.databinding.ActivityMainBinding
|
||||
import org.citra.citra_emu.features.settings.model.BooleanSetting
|
||||
import org.citra.citra_emu.features.settings.model.Settings
|
||||
import org.citra.citra_emu.features.settings.model.SettingsViewModel
|
||||
import org.citra.citra_emu.features.settings.ui.SettingsActivity
|
||||
@ -189,6 +192,13 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
}
|
||||
}
|
||||
|
||||
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
|
||||
|
||||
if (!firstTimeSetup && NativeLibrary.isUpdateCheckerEnabled() && BooleanSetting.CHECK_FOR_UPDATES.boolean) {
|
||||
checkForUpdates()
|
||||
}
|
||||
|
||||
setInsets()
|
||||
}
|
||||
|
||||
@ -270,6 +280,37 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkForUpdates() {
|
||||
Thread {
|
||||
val latestVersion = NativeLibrary.getUpdateTag()
|
||||
if (!latestVersion.isEmpty()) {
|
||||
runOnUiThread {
|
||||
showUpdateDialog(latestVersion)
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun showUpdateDialog(version: String) {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.update_available)
|
||||
.setMessage(getString(R.string.update_available_description, version))
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
val url = NativeLibrary.getUpdateUrl()
|
||||
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
|
||||
startActivity(intent)
|
||||
}
|
||||
.setNeutralButton(android.R.string.cancel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
}
|
||||
.setNegativeButton(R.string.dont_show_again) { dialog, _ ->
|
||||
BooleanSetting.CHECK_FOR_UPDATES.boolean = false
|
||||
settingsViewModel.settings.saveSetting(BooleanSetting.CHECK_FOR_UPDATES, SettingsFile.FILE_NAME_CONFIG)
|
||||
dialog.dismiss()
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
fun finishSetup(navController: NavController) {
|
||||
navController.navigate(R.id.action_firstTimeSetupFragment_to_gamesFragment)
|
||||
(binding.navigationView as NavigationBarView).setupWithNavController(navController)
|
||||
|
||||
@ -300,6 +300,10 @@ void Config::ReadValues() {
|
||||
ReadSetting("Miscellaneous", Settings::values.log_filter);
|
||||
ReadSetting("Miscellaneous", Settings::values.log_regex_filter);
|
||||
|
||||
// App settings / Theme Settings
|
||||
ReadSetting("Theme", Settings::values.update_check_channel);
|
||||
ReadSetting("Theme", Settings::values.check_for_update_on_start);
|
||||
|
||||
// Apply the log_filter setting as the logger has already been initialized
|
||||
// and doesn't pick up the filter on its own.
|
||||
Common::Log::Filter filter;
|
||||
|
||||
@ -519,6 +519,14 @@ static const char* android_config_default_file_content = (BOOST_HANA_STRING(R"(
|
||||
# 0 (default): No, 1: Yes
|
||||
)") DECLARE_KEY(android_hide_images) BOOST_HANA_STRING(R"(
|
||||
|
||||
|
||||
[Theme]
|
||||
# Update check channel for Android. 0: Stable (Default), 1: Pre-release
|
||||
)") DECLARE_KEY(update_check_channel) BOOST_HANA_STRING(R"(
|
||||
|
||||
# Whether to check for updates on startup. 0: No, 1 (default): Yes
|
||||
)") DECLARE_KEY(check_for_update_on_start) BOOST_HANA_STRING(R"(
|
||||
|
||||
[Debugging]
|
||||
# Record frame time data, can be found in the log directory. Boolean value
|
||||
)") DECLARE_KEY(record_frame_times) BOOST_HANA_STRING(R"(
|
||||
|
||||
@ -52,6 +52,10 @@
|
||||
#include "jni/camera/still_image_camera.h"
|
||||
#include "jni/config.h"
|
||||
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
#include "common/update_checker.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
#include "jni/emu_window/emu_window_gl.h"
|
||||
#endif
|
||||
@ -646,6 +650,79 @@ jstring Java_org_citra_citra_1emu_NativeLibrary_getRecommendedExtension(
|
||||
return env->NewStringUTF(j_should_compress ? compressed_ext.c_str() : uncompressed_ext.c_str());
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_citra_citra_1emu_NativeLibrary_isUpdateCheckerEnabled(
|
||||
JNIEnv* env,
|
||||
jobject obj) {
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
return JNI_TRUE;
|
||||
#else
|
||||
return JNI_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
JNIEXPORT void JNICALL Java_org_citra_citra_1emu_NativeLibrary_setCACertificatePath(
|
||||
JNIEnv* env,
|
||||
jobject obj,
|
||||
jstring path) {
|
||||
const char* path_str = env->GetStringUTFChars(path, nullptr);
|
||||
UpdateChecker::SetCACertPath(path_str);
|
||||
}
|
||||
|
||||
bool IsPrereleaseBuild() {
|
||||
return ((strstr(Common::g_build_fullname, "alpha") != nullptr) ||
|
||||
(strstr(Common::g_build_fullname, "beta") != nullptr) ||
|
||||
(strstr(Common::g_build_fullname, "rc") != nullptr));
|
||||
}
|
||||
|
||||
static bool ShouldCheckForPrereleaseUpdates() {
|
||||
const bool update_channel = Settings::values.update_check_channel.GetValue();
|
||||
const bool using_prerelease_channel =
|
||||
(update_channel == Settings::UpdateCheckChannels::PRERELEASE);
|
||||
return (IsPrereleaseBuild() || using_prerelease_channel);
|
||||
}
|
||||
|
||||
static int GetMajorVersion(const std::string& version) {
|
||||
size_t dot = version.find('.');
|
||||
try {
|
||||
return std::stoi(version.substr(0, dot));
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_citra_citra_1emu_NativeLibrary_getUpdateTag(
|
||||
JNIEnv* env,
|
||||
jobject obj) {
|
||||
const std::optional<std::string> latest_release_tag =
|
||||
UpdateChecker::GetLatestRelease(ShouldCheckForPrereleaseUpdates());
|
||||
|
||||
if (latest_release_tag && latest_release_tag.value() != Common::g_build_fullname) {
|
||||
const int latest_major_version = GetMajorVersion(latest_release_tag.value());
|
||||
const int current_major_version = GetMajorVersion(Common::g_build_fullname);
|
||||
if (current_major_version <= latest_major_version) {
|
||||
return env->NewStringUTF(latest_release_tag->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return env->NewStringUTF("");
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_citra_citra_1emu_NativeLibrary_getUpdateUrl(
|
||||
JNIEnv* env,
|
||||
jobject obj) {
|
||||
std::string update_page_url;
|
||||
if (ShouldCheckForPrereleaseUpdates()) {
|
||||
update_page_url = "https://github.com/azahar-emu/azahar/releases";
|
||||
} else {
|
||||
update_page_url = "https://azahar-emu.org/pages/download/";
|
||||
}
|
||||
|
||||
return env->NewStringUTF(update_page_url.c_str());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Java_org_citra_citra_1emu_NativeLibrary_setUserDirectory(JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jstring j_directory) {
|
||||
|
||||
@ -55,6 +55,15 @@
|
||||
<item>3</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="updateCheckChannelNames">
|
||||
<item>@string/update_check_channel_stable</item>
|
||||
<item>@string/update_check_channel_pre_release</item>
|
||||
</string-array>
|
||||
<integer-array name="updateCheckChannelValues">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="smallScreenPositions">
|
||||
<item>@string/small_screen_position_top_right</item>
|
||||
<item>@string/small_screen_position_middle_right</item>
|
||||
@ -646,4 +655,6 @@
|
||||
<item>9</item>
|
||||
</integer-array>
|
||||
|
||||
<string name="update_check_channel_stable">Stable</string>
|
||||
<string name="update_check_channel_pre_release">Pre-Release</string>
|
||||
</resources>
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
<string name="about_description">Build version, credits, and more</string>
|
||||
<string name="games_dir_selected">Application directory selected</string>
|
||||
<string name="select_citra_user_folder_home_description">Changes the files that Azahar uses to load applications</string>
|
||||
<string name="theme_and_color_description">Modify the look of the app</string>
|
||||
<string name="app_settings_description">Modify the look and behavior of the app</string>
|
||||
<string name="install_cia_title">Install CIA</string>
|
||||
|
||||
<!-- GPU driver installation -->
|
||||
@ -431,6 +431,7 @@
|
||||
<string name="preferences_audio">Audio</string>
|
||||
<string name="preferences_debug">Debug</string>
|
||||
<string name="preferences_theme">Theme and Color</string>
|
||||
<string name="preferences_app_settings">App Settings</string>
|
||||
<string name="preferences_layout">Layout</string>
|
||||
|
||||
<!-- ROM loading errors -->
|
||||
@ -948,4 +949,13 @@
|
||||
<string name="decompress_failed">Decompression failed.</string>
|
||||
<string name="compress_decompress_installed_app">Already installed applications cannot be compressed or decompressed.</string>
|
||||
|
||||
<!-- Updater -->
|
||||
<string name="app_settings">App Settings</string>
|
||||
<string name="check_for_updates_on_start">Check For Updates</string>
|
||||
<string name="check_for_updates_on_start_description">Checks for updates once on app start.</string>
|
||||
<string name="update_check_channel">Update Channel</string>
|
||||
<string name="update_available_description">A new version is available: %1$s\n\nWould you like to download it?</string>
|
||||
<string name="update_available">Update found!</string>
|
||||
<string name="dont_show_again">Don\'t Show Again</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@ -209,12 +209,6 @@ file(GLOB COMPAT_LIST
|
||||
file(GLOB_RECURSE ICONS ${PROJECT_SOURCE_DIR}/dist/icons/*)
|
||||
file(GLOB_RECURSE THEMES ${PROJECT_SOURCE_DIR}/dist/qt_themes/*)
|
||||
|
||||
if (ENABLE_QT_UPDATE_CHECKER)
|
||||
target_link_libraries(citra_qt PRIVATE httplib json-headers)
|
||||
target_sources(citra_qt PRIVATE update_checker.cpp)
|
||||
target_compile_definitions(citra_qt PUBLIC ENABLE_QT_UPDATE_CHECKER)
|
||||
endif()
|
||||
|
||||
if (ENABLE_QT_TRANSLATION)
|
||||
set(CITRA_QT_LANGUAGES "${PROJECT_SOURCE_DIR}/dist/languages" CACHE PATH "Path to the translation bundle for the Qt frontend")
|
||||
option(GENERATE_QT_TRANSLATION "Generate en.ts as the translation source file" OFF)
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <unistd.h> // for chdir
|
||||
#endif
|
||||
@ -74,8 +75,8 @@
|
||||
#include "citra_qt/qt_swizzle.h"
|
||||
#include "citra_qt/uisettings.h"
|
||||
#include "common/play_time_manager.h"
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
#include "citra_qt/update_checker.h"
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
#include "common/update_checker.h"
|
||||
#endif
|
||||
#include "citra_qt/util/clickable_label.h"
|
||||
#include "citra_qt/util/graphics_device_info.h"
|
||||
@ -180,11 +181,11 @@ bool IsPrereleaseBuild() {
|
||||
(strstr(Common::g_build_fullname, "rc") != NULL));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
static bool ShouldCheckForPrereleaseUpdates() {
|
||||
const bool update_channel = UISettings::values.update_check_channel.GetValue();
|
||||
const bool update_channel = Settings::values.update_check_channel.GetValue();
|
||||
const bool using_prerelease_channel =
|
||||
(update_channel == UISettings::UpdateCheckChannels::PRERELEASE);
|
||||
(update_channel == Settings::UpdateCheckChannels::PRERELEASE);
|
||||
return (IsPrereleaseBuild() || using_prerelease_channel);
|
||||
}
|
||||
|
||||
@ -438,8 +439,8 @@ GMainWindow::GMainWindow(Core::System& system_)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
if (UISettings::values.check_for_update_on_start) {
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
if (Settings::values.check_for_update_on_start) {
|
||||
update_future = QtConcurrent::run([]() -> QString {
|
||||
const std::optional<std::string> latest_release_tag =
|
||||
UpdateChecker::GetLatestRelease(ShouldCheckForPrereleaseUpdates());
|
||||
@ -4080,7 +4081,7 @@ void GMainWindow::OnMoviePlaybackCompleted() {
|
||||
QMessageBox::information(this, tr("Playback Completed"), tr("Movie playback completed."));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
void GMainWindow::OnEmulatorUpdateAvailable() {
|
||||
QString version_string = update_future.result();
|
||||
if (version_string.isEmpty())
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#ifdef __unix__
|
||||
#include <QDBusObjectPath>
|
||||
#endif
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
#endif
|
||||
@ -307,7 +307,7 @@ private slots:
|
||||
void OnDecreaseVolume();
|
||||
void OnIncreaseVolume();
|
||||
void OnMute();
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
void OnEmulatorUpdateAvailable();
|
||||
#endif
|
||||
void OnSwitchDiskResources(VideoCore::LoadCallbackStage stage, std::size_t value,
|
||||
@ -444,7 +444,7 @@ private:
|
||||
|
||||
std::shared_ptr<Camera::QtMultimediaCameraHandlerFactory> qt_cameras;
|
||||
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
// Prompt shown when update check succeeds
|
||||
QFuture<QString> update_future;
|
||||
QFutureWatcher<QString> update_watcher;
|
||||
|
||||
@ -577,9 +577,9 @@ void QtConfig::ReadMiscellaneousValues() {
|
||||
#ifdef __unix__
|
||||
ReadBasicSetting(Settings::values.enable_gamemode);
|
||||
#endif
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
ReadBasicSetting(UISettings::values.check_for_update_on_start);
|
||||
ReadBasicSetting(UISettings::values.update_check_channel);
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
ReadBasicSetting(Settings::values.check_for_update_on_start);
|
||||
ReadBasicSetting(Settings::values.update_check_channel);
|
||||
#endif
|
||||
|
||||
qt_config->endGroup();
|
||||
@ -1160,9 +1160,9 @@ void QtConfig::SaveMiscellaneousValues() {
|
||||
#ifdef __unix__
|
||||
WriteBasicSetting(Settings::values.enable_gamemode);
|
||||
#endif
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
WriteBasicSetting(UISettings::values.check_for_update_on_start);
|
||||
WriteBasicSetting(UISettings::values.update_check_channel);
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
WriteBasicSetting(Settings::values.check_for_update_on_start);
|
||||
WriteBasicSetting(Settings::values.update_check_channel);
|
||||
#endif
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||
#ifndef __unix__
|
||||
ui->toggle_gamemode->setVisible(false);
|
||||
#endif
|
||||
#ifndef ENABLE_QT_UPDATE_CHECKER
|
||||
#ifndef ENABLE_UPDATE_CHECKER
|
||||
ui->updates_group->setVisible(false);
|
||||
#endif
|
||||
|
||||
@ -90,11 +90,11 @@ void ConfigureGeneral::SetConfiguration() {
|
||||
ui->toggle_background_mute->setChecked(
|
||||
UISettings::values.mute_when_in_background.GetValue());
|
||||
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse.GetValue());
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
ui->toggle_update_checker->setChecked(
|
||||
UISettings::values.check_for_update_on_start.GetValue());
|
||||
Settings::values.check_for_update_on_start.GetValue());
|
||||
ui->update_channel_combobox->setCurrentIndex(
|
||||
UISettings::values.update_check_channel.GetValue());
|
||||
Settings::values.update_check_channel.GetValue());
|
||||
#endif
|
||||
#ifdef __unix__
|
||||
ui->toggle_gamemode->setChecked(Settings::values.enable_gamemode.GetValue());
|
||||
@ -182,9 +182,9 @@ void ConfigureGeneral::ApplyConfiguration() {
|
||||
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
|
||||
UISettings::values.mute_when_in_background = ui->toggle_background_mute->isChecked();
|
||||
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
UISettings::values.check_for_update_on_start = ui->toggle_update_checker->isChecked();
|
||||
UISettings::values.update_check_channel = ui->update_channel_combobox->currentIndex();
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
Settings::values.check_for_update_on_start = ui->toggle_update_checker->isChecked();
|
||||
Settings::values.update_check_channel = ui->update_channel_combobox->currentIndex();
|
||||
#endif
|
||||
#ifdef __unix__
|
||||
Settings::values.enable_gamemode = ui->toggle_gamemode->isChecked();
|
||||
|
||||
@ -59,12 +59,6 @@ enum class GameListText : s32 {
|
||||
ListEnd, ///< Keep this at the end of the enum.
|
||||
};
|
||||
|
||||
class UpdateCheckChannels {
|
||||
public:
|
||||
static constexpr int STABLE = 0;
|
||||
static constexpr int PRERELEASE = 1;
|
||||
};
|
||||
|
||||
struct Values {
|
||||
QByteArray geometry;
|
||||
QByteArray state;
|
||||
@ -89,11 +83,6 @@ struct Values {
|
||||
Settings::Setting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
|
||||
Settings::Setting<bool> mute_when_in_background{false, "muteWhenInBackground"};
|
||||
Settings::Setting<bool> hide_mouse{false, "hideInactiveMouse"};
|
||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||
Settings::Setting<bool> check_for_update_on_start{true, "check_for_update_on_start"};
|
||||
Settings::Setting<int> update_check_channel{UpdateCheckChannels::STABLE,
|
||||
"update_check_channel"};
|
||||
#endif
|
||||
|
||||
Settings::Setting<std::string> inserted_cartridge{"", "inserted_cartridge"};
|
||||
|
||||
|
||||
@ -176,4 +176,10 @@ if (SSE42_COMPILE_OPTION)
|
||||
target_compile_options(citra_common PRIVATE ${SSE42_COMPILE_OPTION})
|
||||
endif()
|
||||
|
||||
target_link_libraries(citra_common PUBLIC xxHash::xxhash)
|
||||
target_link_libraries(citra_common PUBLIC xxHash::xxhash)
|
||||
|
||||
if (ENABLE_UPDATE_CHECKER)
|
||||
target_link_libraries(citra_common PRIVATE httplib json-headers)
|
||||
target_sources(citra_common PRIVATE update_checker.cpp)
|
||||
target_compile_definitions(citra_common PUBLIC ENABLE_UPDATE_CHECKER)
|
||||
endif()
|
||||
|
||||
@ -19,6 +19,13 @@
|
||||
|
||||
namespace Settings {
|
||||
|
||||
class UpdateCheckChannels {
|
||||
public:
|
||||
static constexpr int STABLE = 0;
|
||||
static constexpr int PRERELEASE = 1;
|
||||
};
|
||||
|
||||
|
||||
enum class GraphicsAPI {
|
||||
Software = 0,
|
||||
OpenGL = 1,
|
||||
@ -642,6 +649,11 @@ struct Values {
|
||||
// Miscellaneous
|
||||
Setting<std::string> log_filter{"*:Info", Keys::log_filter};
|
||||
Setting<std::string> log_regex_filter{"", Keys::log_regex_filter};
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
Settings::Setting<bool> check_for_update_on_start{true, Keys::check_for_update_on_start};
|
||||
Settings::Setting<int> update_check_channel{UpdateCheckChannels::STABLE,
|
||||
Keys::update_check_channel};
|
||||
#endif
|
||||
|
||||
// Video Dumping
|
||||
std::string output_format;
|
||||
|
||||
@ -7,9 +7,14 @@
|
||||
#include <fmt/format.h>
|
||||
#include <httplib.h>
|
||||
#include <json.hpp>
|
||||
#include "common/logging/log.h"
|
||||
#include "logging/log.h"
|
||||
#include "update_checker.h"
|
||||
|
||||
std::string g_ca_cert_path;
|
||||
void UpdateChecker::SetCACertPath(std::string path) {
|
||||
g_ca_cert_path = std::move(path);
|
||||
}
|
||||
|
||||
std::optional<std::string> GetResponse(std::string url, std::string path) {
|
||||
constexpr std::size_t timeout_seconds = 15;
|
||||
|
||||
@ -18,6 +23,8 @@ std::optional<std::string> GetResponse(std::string url, std::string path) {
|
||||
client->set_read_timeout(timeout_seconds);
|
||||
client->set_write_timeout(timeout_seconds);
|
||||
|
||||
client->set_ca_cert_path(g_ca_cert_path.c_str());
|
||||
|
||||
if (client == nullptr) {
|
||||
LOG_ERROR(Frontend, "Invalid URL {}{}", url, path);
|
||||
return {};
|
||||
@ -50,7 +57,9 @@ std::optional<std::string> GetResponse(std::string url, std::string path) {
|
||||
}
|
||||
|
||||
std::optional<std::string> UpdateChecker::GetLatestRelease(bool include_prereleases) {
|
||||
|
||||
constexpr auto update_check_url = "http://api.github.com";
|
||||
|
||||
std::string update_check_path = "/repos/azahar-emu/azahar";
|
||||
try {
|
||||
if (include_prereleases) { // This can return either a prerelease or a stable release,
|
||||
@ -9,4 +9,5 @@
|
||||
|
||||
namespace UpdateChecker {
|
||||
std::optional<std::string> GetLatestRelease(bool);
|
||||
void SetCACertPath(std::string path);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user