mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-26 19:24:18 +01:00
Rework OS to allow passing a language
This commit is contained in:
parent
a4a6511177
commit
3fffde3061
@ -8,6 +8,7 @@
|
|||||||
#include <android/asset_manager_jni.h>
|
#include <android/asset_manager_jni.h>
|
||||||
#include <sys/system_properties.h>
|
#include <sys/system_properties.h>
|
||||||
#include "skyline/common.h"
|
#include "skyline/common.h"
|
||||||
|
#include "skyline/common/languages.h"
|
||||||
#include "skyline/common/signal.h"
|
#include "skyline/common/signal.h"
|
||||||
#include "skyline/common/settings.h"
|
#include "skyline/common/settings.h"
|
||||||
#include "skyline/common/trace.h"
|
#include "skyline/common/trace.h"
|
||||||
@ -52,7 +53,16 @@ static std::string GetTimeZoneName() {
|
|||||||
return "GMT";
|
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
|
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;
|
Fps = AverageFrametimeMs = AverageFrametimeDeviationMs = 0;
|
||||||
|
|
||||||
@ -74,7 +84,16 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
|||||||
perfetto::TrackEvent::Register();
|
perfetto::TrackEvent::Register();
|
||||||
|
|
||||||
try {
|
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;
|
OsWeak = os;
|
||||||
GpuWeak = os->state.gpu;
|
GpuWeak = os->state.gpu;
|
||||||
InputWeak = os->state.input;
|
InputWeak = os->state.input;
|
||||||
|
41
app/src/main/cpp/skyline/common/languages.h
Normal file
41
app/src/main/cpp/skyline/common/languages.h
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,21 @@
|
|||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
namespace skyline::kernel {
|
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) {
|
void OS::Execute(int romFd, loader::RomFormat romType) {
|
||||||
auto romFile{std::make_shared<vfs::OsBacking>(romFd)};
|
auto romFile{std::make_shared<vfs::OsBacking>(romFd)};
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <common/languages.h>
|
||||||
#include "vfs/filesystem.h"
|
#include "vfs/filesystem.h"
|
||||||
#include "loader/loader.h"
|
#include "loader/loader.h"
|
||||||
#include "services/serviceman.h"
|
#include "services/serviceman.h"
|
||||||
@ -18,13 +19,22 @@ namespace skyline::kernel {
|
|||||||
std::string deviceTimeZone; //!< The timezone name (e.g. Europe/London)
|
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)
|
std::shared_ptr<vfs::FileSystem> assetFileSystem; //!< A filesystem to be used for accessing emulator assets (like tzdata)
|
||||||
service::ServiceManager serviceManager;
|
service::ServiceManager serviceManager;
|
||||||
|
languages::SystemLanguage systemLanguage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param logger An instance of the Logger class
|
* @param logger An instance of the Logger class
|
||||||
* @param settings An instance of the Settings class
|
* @param settings An instance of the Settings class
|
||||||
* @param window The ANativeWindow object to draw the screen to
|
* @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
|
* @brief Execute a particular ROM file
|
||||||
|
@ -4,13 +4,15 @@
|
|||||||
#include <common/uuid.h>
|
#include <common/uuid.h>
|
||||||
#include <mbedtls/sha1.h>
|
#include <mbedtls/sha1.h>
|
||||||
#include <loader/loader.h>
|
#include <loader/loader.h>
|
||||||
|
#include <os.h>
|
||||||
#include <kernel/types/KProcess.h>
|
#include <kernel/types/KProcess.h>
|
||||||
#include <services/account/IAccountServiceForApplication.h>
|
#include <services/account/IAccountServiceForApplication.h>
|
||||||
#include <services/am/storage/IStorage.h>
|
#include <services/am/storage/IStorage.h>
|
||||||
#include "IApplicationFunctions.h"
|
#include "IApplicationFunctions.h"
|
||||||
|
|
||||||
namespace skyline::service::am {
|
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) {
|
Result IApplicationFunctions::PopLaunchParameter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
constexpr u32 LaunchParameterMagic{0xC79497CA}; //!< The magic of the application launch parameters
|
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) {
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,44 +1,25 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#include <common/languages.h>
|
||||||
#include "ISettingsServer.h"
|
#include "ISettingsServer.h"
|
||||||
|
|
||||||
namespace skyline::service::settings {
|
namespace skyline::service::settings {
|
||||||
ISettingsServer::ISettingsServer(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
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) {
|
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);
|
response.Push<i32>(constant::OldLanguageCodeListSize);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISettingsServer::MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISettingsServer::GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
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);
|
response.Push<i32>(constant::NewLanguageCodeListSize);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -3,43 +3,36 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <services/serviceman.h>
|
#include <services/base_service.h>
|
||||||
|
|
||||||
namespace skyline::service {
|
namespace skyline::service::settings {
|
||||||
namespace constant {
|
/**
|
||||||
constexpr size_t OldLanguageCodeListSize{15}; //!< The size of the pre 4.0.0 language code list
|
* @brief ISettingsServer or 'set' provides access to user settings
|
||||||
constexpr size_t NewLanguageCodeListSize{17}; //!< The size of the post 4.0.0 language code list
|
* @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
|
* @brief Reads the available language codes that an application can use (pre 4.0.0)
|
||||||
* @url https://switchbrew.org/wiki/Settings_services#set
|
|
||||||
*/
|
*/
|
||||||
class ISettingsServer : public BaseService {
|
Result GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
public:
|
|
||||||
ISettingsServer(const DeviceState &state, ServiceManager &manager);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads the available language codes that an application can use (pre 4.0.0)
|
* @brief Converts a language code list index to its corresponding language code
|
||||||
*/
|
*/
|
||||||
Result GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
Result MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Converts a language code list index to its corresponding language code
|
* @brief Reads the available language codes that an application can use (post 4.0.0)
|
||||||
*/
|
*/
|
||||||
Result MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
Result GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
|
||||||
/**
|
SERVICE_DECL(
|
||||||
* @brief Reads the available language codes that an application can use (post 4.0.0)
|
SFUNC(0x1, ISettingsServer, GetAvailableLanguageCodes),
|
||||||
*/
|
SFUNC(0x2, ISettingsServer, MakeLanguageCode),
|
||||||
Result GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
SFUNC(0x5, ISettingsServer, GetAvailableLanguageCodes2)
|
||||||
|
)
|
||||||
SERVICE_DECL(
|
};
|
||||||
SFUNC(0x1, ISettingsServer, GetAvailableLanguageCodes),
|
|
||||||
SFUNC(0x2, ISettingsServer, MakeLanguageCode),
|
|
||||||
SFUNC(0x5, ISettingsServer, GetAvailableLanguageCodes2)
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
|||||||
* @param appFilesPath The full path to the app files directory
|
* @param appFilesPath The full path to the app files directory
|
||||||
* @param assetManager The asset manager used for accessing app assets
|
* @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
|
* @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)
|
val preferenceFd = ParcelFileDescriptor.open(File("${applicationInfo.dataDir}/shared_prefs/${applicationInfo.packageName}_preferences.xml"), ParcelFileDescriptor.MODE_READ_WRITE)
|
||||||
|
|
||||||
emulationThread = Thread {
|
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)
|
if (shouldFinish)
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
emulationThread.join()
|
emulationThread.join()
|
||||||
|
@ -37,4 +37,6 @@ class Settings @Inject constructor(@ApplicationContext private val context : Con
|
|||||||
var filter by sharedPreferences(context, 0)
|
var filter by sharedPreferences(context, 0)
|
||||||
|
|
||||||
var maxRefreshRate by sharedPreferences(context, false)
|
var maxRefreshRate by sharedPreferences(context, false)
|
||||||
|
|
||||||
|
var systemLanguage by sharedPreferences(context, "1")
|
||||||
}
|
}
|
||||||
|
@ -34,4 +34,44 @@
|
|||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
</string-array>
|
</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>
|
</resources>
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
<string name="docked_enabled">The system will emulate being in docked mode</string>
|
<string name="docked_enabled">The system will emulate being in docked mode</string>
|
||||||
<string name="username">Username</string>
|
<string name="username">Username</string>
|
||||||
<string name="username_default">@string/app_name</string>
|
<string name="username_default">@string/app_name</string>
|
||||||
|
<string name="system_language">System language</string>
|
||||||
<!-- Settings - Keys -->
|
<!-- Settings - Keys -->
|
||||||
<string name="keys">Keys</string>
|
<string name="keys">Keys</string>
|
||||||
<string name="prod_keys">Production Keys</string>
|
<string name="prod_keys">Production Keys</string>
|
||||||
|
@ -72,6 +72,13 @@
|
|||||||
app:key="username_value"
|
app:key="username_value"
|
||||||
app:limit="31"
|
app:limit="31"
|
||||||
app:title="@string/username" />
|
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>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:key="category_presentation"
|
android:key="category_presentation"
|
||||||
|
Loading…
Reference in New Issue
Block a user