Rework OS to allow passing a language

This commit is contained in:
sspacelynx 2021-08-28 12:30:34 +02:00 committed by ◱ Mark
parent a4a6511177
commit 3fffde3061
12 changed files with 173 additions and 63 deletions

View File

@ -8,6 +8,7 @@
#include <android/asset_manager_jni.h>
#include <sys/system_properties.h>
#include "skyline/common.h"
#include "skyline/common/languages.h"
#include "skyline/common/signal.h"
#include "skyline/common/settings.h"
#include "skyline/common/trace.h"
@ -52,7 +53,16 @@ static std::string GetTimeZoneName() {
return "GMT";
}
extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(JNIEnv *env, jobject instance, jstring romUriJstring, jint romType, jint romFd, jint preferenceFd, jstring appFilesPathJstring, jobject assetManager) {
extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
JNIEnv *env, jobject instance,
jstring romUriJstring,
jint romType,
jint romFd,
jint preferenceFd,
jint systemLanguage,
jstring appFilesPathJstring,
jobject assetManager
) {
skyline::signal::ScopedStackBlocker stackBlocker; // We do not want anything to unwind past JNI code as there are invalid stack frames which can lead to a segmentation fault
Fps = AverageFrametimeMs = AverageFrametimeDeviationMs = 0;
@ -74,7 +84,16 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
perfetto::TrackEvent::Register();
try {
auto os{std::make_shared<skyline::kernel::OS>(jvmManager, logger, settings, std::string(appFilesPath), GetTimeZoneName(), std::make_shared<skyline::vfs::AndroidAssetFileSystem>(AAssetManager_fromJava(env, assetManager)))};
auto os{
std::make_shared<skyline::kernel::OS>(
jvmManager,
logger,
settings,
std::string(appFilesPath),
GetTimeZoneName(),
static_cast<skyline::languages::SystemLanguage>(systemLanguage),
std::make_shared<skyline::vfs::AndroidAssetFileSystem>(AAssetManager_fromJava(env, assetManager))
)};
OsWeak = os;
GpuWeak = os->state.gpu;
InputWeak = os->state.input;

View File

@ -0,0 +1,41 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <common.h>
namespace skyline {
using LanguageCode = u64;
namespace constant {
constexpr size_t OldLanguageCodeListSize{15}; //!< The size of the pre 4.0.0 language code list
constexpr size_t NewLanguageCodeListSize{17}; //!< The size of the post 4.0.0 language code list
}
namespace languages {
constexpr std::array<LanguageCode, constant::NewLanguageCodeListSize> LanguageCodeList{
util::MakeMagic<LanguageCode>("ja"),
util::MakeMagic<LanguageCode>("en-US"),
util::MakeMagic<LanguageCode>("fr"),
util::MakeMagic<LanguageCode>("de"),
util::MakeMagic<LanguageCode>("it"),
util::MakeMagic<LanguageCode>("es"),
util::MakeMagic<LanguageCode>("zh-CN"),
util::MakeMagic<LanguageCode>("ko"),
util::MakeMagic<LanguageCode>("nl"),
util::MakeMagic<LanguageCode>("pt"),
util::MakeMagic<LanguageCode>("ru"),
util::MakeMagic<LanguageCode>("zh-TW"),
util::MakeMagic<LanguageCode>("en-GB"),
util::MakeMagic<LanguageCode>("fr-CA"),
util::MakeMagic<LanguageCode>("es-419"),
util::MakeMagic<LanguageCode>("zh-Hans"),
util::MakeMagic<LanguageCode>("zh-Hant"),
};
constexpr LanguageCode GetLanguageCode(SystemLanguage language) {
return LanguageCodeList.at(static_cast<size_t>(language));
}
}
}

View File

@ -13,7 +13,21 @@
#include "os.h"
namespace skyline::kernel {
OS::OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, std::string appFilesPath, std::string deviceTimeZone, std::shared_ptr<vfs::FileSystem> assetFileSystem) : state(this, jvmManager, settings, logger), appFilesPath(std::move(appFilesPath)), deviceTimeZone(std::move(deviceTimeZone)), assetFileSystem(std::move(assetFileSystem)), serviceManager(state) {}
OS::OS(
std::shared_ptr<JvmManager> &jvmManager,
std::shared_ptr<Logger> &logger,
std::shared_ptr<Settings> &settings,
std::string appFilesPath,
std::string deviceTimeZone,
languages::SystemLanguage systemLanguage,
std::shared_ptr<vfs::FileSystem> assetFileSystem
)
: state(this, jvmManager, settings, logger),
appFilesPath(std::move(appFilesPath)),
deviceTimeZone(std::move(deviceTimeZone)),
assetFileSystem(std::move(assetFileSystem)),
serviceManager(state),
systemLanguage(systemLanguage) {}
void OS::Execute(int romFd, loader::RomFormat romType) {
auto romFile{std::make_shared<vfs::OsBacking>(romFd)};

View File

@ -3,6 +3,7 @@
#pragma once
#include <common/languages.h>
#include "vfs/filesystem.h"
#include "loader/loader.h"
#include "services/serviceman.h"
@ -18,13 +19,22 @@ namespace skyline::kernel {
std::string deviceTimeZone; //!< The timezone name (e.g. Europe/London)
std::shared_ptr<vfs::FileSystem> assetFileSystem; //!< A filesystem to be used for accessing emulator assets (like tzdata)
service::ServiceManager serviceManager;
languages::SystemLanguage systemLanguage;
/**
* @param logger An instance of the Logger class
* @param settings An instance of the Settings class
* @param window The ANativeWindow object to draw the screen to
*/
OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, std::string appFilesPath, std::string deviceTimeZone, std::shared_ptr<vfs::FileSystem> assetFileSystem);
OS(
std::shared_ptr<JvmManager> &jvmManager,
std::shared_ptr<Logger> &logger,
std::shared_ptr<Settings> &settings,
std::string appFilesPath,
std::string deviceTimeZone,
languages::SystemLanguage systemLanguage,
std::shared_ptr<vfs::FileSystem> assetFileSystem
);
/**
* @brief Execute a particular ROM file

View File

@ -4,13 +4,15 @@
#include <common/uuid.h>
#include <mbedtls/sha1.h>
#include <loader/loader.h>
#include <os.h>
#include <kernel/types/KProcess.h>
#include <services/account/IAccountServiceForApplication.h>
#include <services/am/storage/IStorage.h>
#include "IApplicationFunctions.h"
namespace skyline::service::am {
IApplicationFunctions::IApplicationFunctions(const DeviceState &state, ServiceManager &manager) : gpuErrorEvent(std::make_shared<type::KEvent>(state, false)), BaseService(state, manager) {}
IApplicationFunctions::IApplicationFunctions(const DeviceState &state, ServiceManager &manager)
: gpuErrorEvent(std::make_shared<type::KEvent>(state, false)), BaseService(state, manager) {}
Result IApplicationFunctions::PopLaunchParameter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
constexpr u32 LaunchParameterMagic{0xC79497CA}; //!< The magic of the application launch parameters
@ -32,7 +34,7 @@ namespace skyline::service::am {
}
Result IApplicationFunctions::GetDesiredLanguage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(util::MakeMagic<u64>("en-US"));
response.Push(languages::GetLanguageCode(state.os->systemLanguage));
return {};
}

View File

@ -1,44 +1,25 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <common/languages.h>
#include "ISettingsServer.h"
namespace skyline::service::settings {
ISettingsServer::ISettingsServer(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
constexpr std::array<u64, constant::NewLanguageCodeListSize> LanguageCodeList{
util::MakeMagic<u64>("ja"),
util::MakeMagic<u64>("en-US"),
util::MakeMagic<u64>("fr"),
util::MakeMagic<u64>("de"),
util::MakeMagic<u64>("it"),
util::MakeMagic<u64>("es"),
util::MakeMagic<u64>("zh-CN"),
util::MakeMagic<u64>("ko"),
util::MakeMagic<u64>("nl"),
util::MakeMagic<u64>("pt"),
util::MakeMagic<u64>("ru"),
util::MakeMagic<u64>("zh-TW"),
util::MakeMagic<u64>("en-GB"),
util::MakeMagic<u64>("fr-CA"),
util::MakeMagic<u64>("es-419"),
util::MakeMagic<u64>("zh-Hans"),
util::MakeMagic<u64>("zh-Hant"),
};
Result ISettingsServer::GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
request.outputBuf.at(0).copy_from(span(LanguageCodeList).first(constant::OldLanguageCodeListSize));
request.outputBuf.at(0).copy_from(span(languages::LanguageCodeList).first(constant::OldLanguageCodeListSize));
response.Push<i32>(constant::OldLanguageCodeListSize);
return {};
}
Result ISettingsServer::MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u64>(LanguageCodeList.at(request.Pop<i32>()));
response.Push<u64>(languages::LanguageCodeList.at(request.Pop<i32>()));
return {};
}
Result ISettingsServer::GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
request.outputBuf.at(0).copy_from(LanguageCodeList);
request.outputBuf.at(0).copy_from(languages::LanguageCodeList);
response.Push<i32>(constant::NewLanguageCodeListSize);
return {};
}

View File

@ -3,43 +3,36 @@
#pragma once
#include <services/serviceman.h>
#include <services/base_service.h>
namespace skyline::service {
namespace constant {
constexpr size_t OldLanguageCodeListSize{15}; //!< The size of the pre 4.0.0 language code list
constexpr size_t NewLanguageCodeListSize{17}; //!< The size of the post 4.0.0 language code list
}
namespace skyline::service::settings {
/**
* @brief ISettingsServer or 'set' provides access to user settings
* @url https://switchbrew.org/wiki/Settings_services#set
*/
class ISettingsServer : public BaseService {
public:
ISettingsServer(const DeviceState &state, ServiceManager &manager);
namespace settings {
/**
* @brief ISettingsServer or 'set' provides access to user settings
* @url https://switchbrew.org/wiki/Settings_services#set
* @brief Reads the available language codes that an application can use (pre 4.0.0)
*/
class ISettingsServer : public BaseService {
public:
ISettingsServer(const DeviceState &state, ServiceManager &manager);
Result GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Reads the available language codes that an application can use (pre 4.0.0)
*/
Result GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Converts a language code list index to its corresponding language code
*/
Result MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Converts a language code list index to its corresponding language code
*/
Result MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Reads the available language codes that an application can use (post 4.0.0)
*/
Result GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Reads the available language codes that an application can use (post 4.0.0)
*/
Result GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
SERVICE_DECL(
SFUNC(0x1, ISettingsServer, GetAvailableLanguageCodes),
SFUNC(0x2, ISettingsServer, MakeLanguageCode),
SFUNC(0x5, ISettingsServer, GetAvailableLanguageCodes2)
)
};
}
SERVICE_DECL(
SFUNC(0x1, ISettingsServer, GetAvailableLanguageCodes),
SFUNC(0x2, ISettingsServer, MakeLanguageCode),
SFUNC(0x5, ISettingsServer, GetAvailableLanguageCodes2)
)
};
}

View File

@ -70,7 +70,7 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
* @param appFilesPath The full path to the app files directory
* @param assetManager The asset manager used for accessing app assets
*/
private external fun executeApplication(romUri : String, romType : Int, romFd : Int, preferenceFd : Int, appFilesPath : String, assetManager : AssetManager)
private external fun executeApplication(romUri : String, romType : Int, romFd : Int, preferenceFd : Int, language : Int, appFilesPath : String, assetManager : AssetManager)
/**
* @return If it successfully caused the [emulationThread] to gracefully stop
@ -173,7 +173,7 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
val preferenceFd = ParcelFileDescriptor.open(File("${applicationInfo.dataDir}/shared_prefs/${applicationInfo.packageName}_preferences.xml"), ParcelFileDescriptor.MODE_READ_WRITE)
emulationThread = Thread {
executeApplication(rom.toString(), romType, romFd.detachFd(), preferenceFd.detachFd(), applicationContext.filesDir.canonicalPath + "/", assets)
executeApplication(rom.toString(), romType, romFd.detachFd(), preferenceFd.detachFd(), Integer.parseInt(settings.systemLanguage), applicationContext.filesDir.canonicalPath + "/", assets)
if (shouldFinish)
runOnUiThread {
emulationThread.join()

View File

@ -37,4 +37,6 @@ class Settings @Inject constructor(@ApplicationContext private val context : Con
var filter by sharedPreferences(context, 0)
var maxRefreshRate by sharedPreferences(context, false)
var systemLanguage by sharedPreferences(context, "1")
}

View File

@ -34,4 +34,44 @@
<item>1</item>
<item>2</item>
</string-array>
<string-array name="system_languages">
<item>Japanese (日本語)</item>
<item>English</item>
<item>French (français)</item>
<item>German (Deutsch)</item>
<item>Italian (italiano)</item>
<item>Spanish (español)</item>
<item>Chinese</item>
<item>Korean (한국어)</item>
<item>Dutch (Nederlands)</item>
<item>Portuguese (português)</item>
<item>Russian (Русский)</item>
<item>Taiwanese</item>
<item>British English</item>
<item>Canadian English</item>
<item>Latin American Spanish</item>
<item>Simplified Chinese</item>
<item>Traditional Chinese (正體中文)</item>
<item>Brazilian Portuguese (português do Brasil)</item>
</string-array>
<string-array name="system_lang_values">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
<item>10</item>
<item>11</item>
<item>12</item>
<item>13</item>
<item>14</item>
<item>15</item>
<item>16</item>
<item>17</item>
</string-array>
</resources>

View File

@ -43,6 +43,7 @@
<string name="docked_enabled">The system will emulate being in docked mode</string>
<string name="username">Username</string>
<string name="username_default">@string/app_name</string>
<string name="system_language">System language</string>
<!-- Settings - Keys -->
<string name="keys">Keys</string>
<string name="prod_keys">Production Keys</string>

View File

@ -72,6 +72,13 @@
app:key="username_value"
app:limit="31"
app:title="@string/username" />
<ListPreference
android:defaultValue="1"
android:entries="@array/system_languages"
android:entryValues="@array/system_lang_values"
app:key="system_language"
app:title="@string/system_language"
app:useSimpleSummaryProvider="true" />
</PreferenceCategory>
<PreferenceCategory
android:key="category_presentation"