From 1fc8ee6fee669476e259dd63609189117cc818e9 Mon Sep 17 00:00:00 2001 From: Gregory Date: Thu, 28 Dec 2023 17:50:12 +0300 Subject: [PATCH 1/5] Fix all --- android/app/build.gradle | 1 + .../src/main/kotlin/dev/imranr/obtainium/MainActivity.kt | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 2559d75..a0cc750 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -109,6 +109,7 @@ dependencies { implementation "dev.rikka.tools.refine:runtime:$hidden_api_version" implementation "dev.rikka.hidden:compat:$hidden_api_version" compileOnly "dev.rikka.hidden:stub:$hidden_api_version" + implementation "org.lsposed.hiddenapibypass:hiddenapibypass:4.3" implementation "com.github.topjohnwu.libsu:core:5.2.2" } diff --git a/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt b/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt index af2da43..b711892 100644 --- a/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt +++ b/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt @@ -22,6 +22,7 @@ import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.Result import java.io.IOException import java.util.concurrent.CountDownLatch +import org.lsposed.hiddenapibypass.HiddenApiBypass import rikka.shizuku.Shizuku import rikka.shizuku.Shizuku.OnRequestPermissionResultListener import rikka.shizuku.ShizukuBinderWrapper @@ -76,7 +77,8 @@ class MainActivity: FlutterActivity() { val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL) var installFlags: Int = PackageInstallerUtils.getInstallFlags(params) - installFlags = installFlags or 0x00000004 // PackageManager.INSTALL_ALLOW_TEST + installFlags = installFlags or (0x00000002/*PackageManager.INSTALL_REPLACE_EXISTING*/ or + 0x00000004 /*PackageManager.INSTALL_ALLOW_TEST*/) PackageInstallerUtils.setInstallFlags(params, installFlags) val sessionId = packageInstaller.createSession(params) val iSession = IPackageInstallerSession.Stub.asInterface( @@ -136,7 +138,7 @@ class MainActivity: FlutterActivity() { } private fun rootInstallApk(apkFilePath: String, result: Result) { - Shell.sh("pm install -R -t " + apkFilePath).submit { out -> + Shell.sh("pm install -r -t " + apkFilePath).submit { out -> val builder = StringBuilder() for (data in out.getOut()) { builder.append(data) } result.success(builder.toString().endsWith("Success")) @@ -145,6 +147,9 @@ class MainActivity: FlutterActivity() { override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + HiddenApiBypass.addHiddenApiExemptions("") + } Shizuku.addRequestPermissionResultListener(shizukuRequestPermissionResultListener) installersChannel = MethodChannel( flutterEngine.dartExecutor.binaryMessenger, "installers") From 5ba33786ab24b6caa6aaa41fed9969171ada18bf Mon Sep 17 00:00:00 2001 From: Gregory Date: Sun, 31 Dec 2023 19:33:33 +0300 Subject: [PATCH 2/5] System font and newer dependencies --- android/app/build.gradle | 13 +++---- .../dev/imranr/obtainium/DefaultSystemFont.kt | 33 +++++++++++++++++ .../dev/imranr/obtainium/MainActivity.kt | 15 ++++---- android/build.gradle | 4 +-- assets/translations/en.json | 3 +- assets/translations/ru.json | 3 +- lib/main.dart | 15 ++++++-- lib/pages/settings.dart | 15 ++++++-- lib/providers/apps_provider.dart | 10 +++--- ...ers_provider.dart => native_provider.dart} | 36 +++++++++++++------ lib/providers/settings_provider.dart | 18 ++++++++++ 11 files changed, 127 insertions(+), 38 deletions(-) create mode 100644 android/app/src/main/kotlin/dev/imranr/obtainium/DefaultSystemFont.kt rename lib/providers/{installers_provider.dart => native_provider.dart} (61%) diff --git a/android/app/build.gradle b/android/app/build.gradle index a0cc750..c097c6d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -37,12 +37,12 @@ android { ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } sourceSets { @@ -96,16 +96,11 @@ repositories { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - def shizuku_version = '13.1.5' implementation "dev.rikka.shizuku:api:$shizuku_version" implementation "dev.rikka.shizuku:provider:$shizuku_version" - def hidden_api_version = '4.1.0' - // DO NOT UPDATE Hidden API without updating the Android tools - // and do not update Android tools without updating the whole Flutter - // (also in android/build.gradle) + def hidden_api_version = '4.3.1' implementation "dev.rikka.tools.refine:runtime:$hidden_api_version" implementation "dev.rikka.hidden:compat:$hidden_api_version" compileOnly "dev.rikka.hidden:stub:$hidden_api_version" diff --git a/android/app/src/main/kotlin/dev/imranr/obtainium/DefaultSystemFont.kt b/android/app/src/main/kotlin/dev/imranr/obtainium/DefaultSystemFont.kt new file mode 100644 index 0000000..3a2edc8 --- /dev/null +++ b/android/app/src/main/kotlin/dev/imranr/obtainium/DefaultSystemFont.kt @@ -0,0 +1,33 @@ +package dev.imranr.obtainium + +import android.util.Xml +import org.xmlpull.v1.XmlPullParser +import java.io.File +import java.io.FileInputStream + +class DefaultSystemFont { + fun get(): String? { + return try { + val file = File("/system/etc/fonts.xml") + val fileStream = FileInputStream(file) + parseFontsFileStream(fileStream) + } catch (_: Exception) { + null + } + } + + private fun parseFontsFileStream(fileStream: FileInputStream): String { + fileStream.use { stream -> + val parser = Xml.newPullParser() + parser.setInput(stream, null) + parser.nextTag() + return parseFonts(parser) + } + } + + private fun parseFonts(parser: XmlPullParser): String { + while (parser.name != "font") { parser.next() } + parser.next() + return "/system/fonts/" + parser.text.trim() + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt b/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt index b711892..f1c3659 100644 --- a/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt +++ b/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt @@ -28,7 +28,7 @@ import rikka.shizuku.Shizuku.OnRequestPermissionResultListener import rikka.shizuku.ShizukuBinderWrapper class MainActivity: FlutterActivity() { - private var installersChannel: MethodChannel? = null + private var nativeChannel: MethodChannel? = null private val SHIZUKU_PERMISSION_REQUEST_CODE = (10..200).random() private fun shizukuCheckPermission(result: Result) { @@ -52,7 +52,7 @@ class MainActivity: FlutterActivity() { requestCode: Int, grantResult: Int -> if (requestCode == SHIZUKU_PERMISSION_REQUEST_CODE) { val res = if (grantResult == PackageManager.PERMISSION_GRANTED) 1 else 0 - installersChannel!!.invokeMethod("resPermShizuku", mapOf("res" to res)) + nativeChannel!!.invokeMethod("resPermShizuku", mapOf("res" to res)) } } @@ -151,11 +151,14 @@ class MainActivity: FlutterActivity() { HiddenApiBypass.addHiddenApiExemptions("") } Shizuku.addRequestPermissionResultListener(shizukuRequestPermissionResultListener) - installersChannel = MethodChannel( - flutterEngine.dartExecutor.binaryMessenger, "installers") - installersChannel!!.setMethodCallHandler { + nativeChannel = MethodChannel( + flutterEngine.dartExecutor.binaryMessenger, "native") + nativeChannel!!.setMethodCallHandler { call, result -> - if (call.method == "checkPermissionShizuku") { + if (call.method == "getSystemFont") { + val res = DefaultSystemFont().get() + result.success(res) + } else if (call.method == "checkPermissionShizuku") { shizukuCheckPermission(result) } else if (call.method == "checkPermissionRoot") { rootCheckPermission(result) diff --git a/android/build.gradle b/android/build.gradle index 288d38b..df86a54 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -6,9 +6,9 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.2.0' + classpath "com.android.tools.build:gradle:7.4.2" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'dev.rikka.tools.refine:gradle-plugin:4.1.0' // Do not update! + classpath "dev.rikka.tools.refine:gradle-plugin:4.3.1" } } diff --git a/assets/translations/en.json b/assets/translations/en.json index defd488..1fcaf93 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -285,7 +285,8 @@ "normal": "Normal", "shizuku": "Shizuku", "root": "Root", - "shizukuBinderNotFound": "Shizuku is not running", + "shizukuBinderNotFound": "Сompatible Shizuku service wasn't found", + "tryUseSystemFont": "Try to use a system font", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index fee1a28..f46cf67 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -285,7 +285,8 @@ "normal": "Нормальный", "shizuku": "Shizuku", "root": "Суперпользователь", - "shizukuBinderNotFound": "Shizuku не запущен", + "shizukuBinderNotFound": "Совместимый сервис Shizuku не найден", + "tryUseSystemFont": "Попытаться использовать системный шрифт", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/lib/main.dart b/lib/main.dart index 21be97b..6d25a03 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; import 'package:obtainium/pages/home.dart'; import 'package:obtainium/providers/apps_provider.dart'; import 'package:obtainium/providers/logs_provider.dart'; +import 'package:obtainium/providers/native_provider.dart'; import 'package:obtainium/providers/notifications_provider.dart'; import 'package:obtainium/providers/settings_provider.dart'; import 'package:obtainium/providers/source_provider.dart'; @@ -185,6 +186,16 @@ class _ObtainiumState extends State { } existingUpdateInterval = actualUpdateInterval; } + settingsProvider.addListener(() async { + if (settingsProvider.tryUseSystemFont && + settingsProvider.appFont == "Metropolis") { + bool fontLoaded = await NativeFeatures.tryLoadSystemFont(); + if (fontLoaded) { settingsProvider.appFont = "SystemFont"; } + } else if (!settingsProvider.tryUseSystemFont && + settingsProvider.appFont != "Metropolis") { + settingsProvider.appFont = "Metropolis"; + } + }); } return DynamicColorBuilder( @@ -221,13 +232,13 @@ class _ObtainiumState extends State { colorScheme: settingsProvider.theme == ThemeSettings.dark ? darkColorScheme : lightColorScheme, - fontFamily: 'Metropolis'), + fontFamily: settingsProvider.appFont), darkTheme: ThemeData( useMaterial3: true, colorScheme: settingsProvider.theme == ThemeSettings.light ? lightColorScheme : darkColorScheme, - fontFamily: 'Metropolis'), + fontFamily: settingsProvider.appFont), home: Shortcuts(shortcuts: { LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(), }, child: const HomePage())); diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index e83ddf3..c6c6896 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -351,8 +351,6 @@ class _SettingsPageState extends State { ], ), height16, - installMethodDropdown, - height16, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -365,6 +363,7 @@ class _SettingsPageState extends State { }) ], ), + installMethodDropdown, height32, Text( tr('sourceSpecific'), @@ -409,6 +408,18 @@ class _SettingsPageState extends State { height16, localeDropdown, height16, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible(child: Text(tr('tryUseSystemFont'))), + Switch( + value: settingsProvider.tryUseSystemFont, + onChanged: (value) { + settingsProvider.tryUseSystemFont = value; + }) + ], + ), + height16, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 97e6118..1db18a5 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -33,7 +33,7 @@ import 'package:http/http.dart'; import 'package:android_intent_plus/android_intent.dart'; import 'package:flutter_archive/flutter_archive.dart'; import 'package:shared_storage/shared_storage.dart' as saf; -import 'installers_provider.dart'; +import 'native_provider.dart'; final pm = AndroidPackageManager(); @@ -523,12 +523,12 @@ class AppsProvider with ChangeNotifier { code = await AndroidPackageInstaller.installApk( apkFilePath: file.file.path); case InstallMethodSettings.shizuku: - code = (await Installers.installWithShizuku( + code = (await NativeFeatures.installWithShizuku( apkFileUri: file.file.uri.toString())) ? 0 : 1; case InstallMethodSettings.root: - code = (await Installers.installWithRoot(apkFilePath: file.file.path)) + code = (await NativeFeatures.installWithRoot(apkFilePath: file.file.path)) ? 0 : 1; } @@ -694,14 +694,14 @@ class AppsProvider with ChangeNotifier { throw ObtainiumError(tr('cancelled')); } case InstallMethodSettings.shizuku: - int code = await Installers.checkPermissionShizuku(); + int code = await NativeFeatures.checkPermissionShizuku(); if (code == -1) { throw ObtainiumError(tr('shizukuBinderNotFound')); } else if (code == 0) { throw ObtainiumError(tr('cancelled')); } case InstallMethodSettings.root: - if (!(await Installers.checkPermissionRoot())) { + if (!(await NativeFeatures.checkPermissionRoot())) { throw ObtainiumError(tr('cancelled')); } } diff --git a/lib/providers/installers_provider.dart b/lib/providers/native_provider.dart similarity index 61% rename from lib/providers/installers_provider.dart rename to lib/providers/native_provider.dart index c42e1b0..7a154bf 100644 --- a/lib/providers/installers_provider.dart +++ b/lib/providers/native_provider.dart @@ -1,12 +1,25 @@ import 'dart:async'; +import 'dart:io'; import 'package:flutter/services.dart'; -class Installers { - static const MethodChannel _channel = MethodChannel('installers'); +class NativeFeatures { + static const MethodChannel _channel = MethodChannel('native'); static bool _callbacksApplied = false; static int _resPermShizuku = -2; // not set - static Future waitWhile(bool Function() test, + static Future _readFileBytes(String path) async { + var file = File(path); + var bytes = await file.readAsBytes(); + return ByteData.view(bytes.buffer); + } + + static Future _handleCalls(MethodCall call) async { + if (call.method == 'resPermShizuku') { + _resPermShizuku = call.arguments['res']; + } + } + + static Future _waitWhile(bool Function() test, [Duration pollInterval = const Duration(milliseconds: 250)]) { var completer = Completer(); check() { @@ -20,20 +33,23 @@ class Installers { return completer.future; } - static Future handleCalls(MethodCall call) async { - if (call.method == 'resPermShizuku') { - _resPermShizuku = call.arguments['res']; - } + static Future tryLoadSystemFont() async { + var font = await _channel.invokeMethod('getSystemFont'); + if (font == null) { return false; } + var fontLoader = FontLoader('SystemFont'); + fontLoader.addFont(_readFileBytes(font)); + await fontLoader.load(); + return true; } static Future checkPermissionShizuku() async { if (!_callbacksApplied) { - _channel.setMethodCallHandler(handleCalls); + _channel.setMethodCallHandler(_handleCalls); _callbacksApplied = true; } int res = await _channel.invokeMethod('checkPermissionShizuku'); - if(res == -2) { - await waitWhile(() => _resPermShizuku == -2); + if (res == -2) { + await _waitWhile(() => _resPermShizuku == -2); res = _resPermShizuku; _resPermShizuku = -2; } diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 266f244..74164eb 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -51,6 +51,24 @@ class SettingsProvider with ChangeNotifier { notifyListeners(); } + String get appFont { + return prefs?.getString('appFont') ?? 'Metropolis'; + } + + set appFont(String appFont) { + prefs?.setString('appFont', appFont); + notifyListeners(); + } + + bool get tryUseSystemFont { + return prefs?.getBool('tryUseSystemFont') ?? false; + } + + set tryUseSystemFont(bool tryUseSystemFont) { + prefs?.setBool('tryUseSystemFont', tryUseSystemFont); + notifyListeners(); + } + InstallMethodSettings get installMethod { return InstallMethodSettings .values[prefs?.getInt('installMethod') ?? InstallMethodSettings.normal.index]; From 0f7419525567e4dfe013385c72874f470e68f20e Mon Sep 17 00:00:00 2001 From: Gregory Date: Sun, 31 Dec 2023 19:42:28 +0300 Subject: [PATCH 3/5] Replace okay with ok --- assets/translations/bs.json | 1 - assets/translations/cs.json | 1 - assets/translations/de.json | 1 - assets/translations/en.json | 1 - assets/translations/es.json | 1 - assets/translations/fa.json | 1 - assets/translations/fr.json | 1 - assets/translations/hu.json | 1 - assets/translations/it.json | 1 - assets/translations/ja.json | 1 - assets/translations/nl.json | 1 - assets/translations/pl.json | 1 - assets/translations/pt.json | 1 - assets/translations/ru.json | 1 - assets/translations/sv.json | 1 - assets/translations/tr.json | 1 - assets/translations/vi.json | 1 - assets/translations/zh.json | 1 - lib/pages/import_export.dart | 2 +- 19 files changed, 1 insertion(+), 19 deletions(-) diff --git a/assets/translations/bs.json b/assets/translations/bs.json index d03e918..0084ee8 100644 --- a/assets/translations/bs.json +++ b/assets/translations/bs.json @@ -103,7 +103,6 @@ "importErrors": "Uvezi greške", "importedXOfYApps": "{} od {} aplikacija uvezeno.", "followingURLsHadErrors": "Sljedeći URL-ovi su imali greške:", - "okay": "Dobro", "selectURL": "Odaberite URL", "selectURLs": "Odaberite URL-ove", "pick": "Odaberi", diff --git a/assets/translations/cs.json b/assets/translations/cs.json index 2e44a68..d52284b 100644 --- a/assets/translations/cs.json +++ b/assets/translations/cs.json @@ -103,7 +103,6 @@ "importErrors": "Import Errors", "importedXOfYApps": "{}importováno {}aplikací.", "followingURLsHadErrors": "U následujících adres URL došlo k chybám:", - "okay": "Okay", "selectURL": "Select URL", "selectURLs": "Select URLs", "pick": "Vybrat", diff --git a/assets/translations/de.json b/assets/translations/de.json index fae8d4d..e906d2b 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -103,7 +103,6 @@ "importErrors": "Importfehler", "importedXOfYApps": "{} von {} Apps importiert.", "followingURLsHadErrors": "Bei folgenden URLs traten Fehler auf:", - "okay": "Okay", "selectURL": "URL auswählen", "selectURLs": "URLs auswählen", "pick": "Auswählen", diff --git a/assets/translations/en.json b/assets/translations/en.json index 1fcaf93..b8889ae 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -103,7 +103,6 @@ "importErrors": "Import Errors", "importedXOfYApps": "{} of {} Apps imported.", "followingURLsHadErrors": "The following URLs had errors:", - "okay": "Okay", "selectURL": "Select URL", "selectURLs": "Select URLs", "pick": "Pick", diff --git a/assets/translations/es.json b/assets/translations/es.json index 58a5c62..90d7ca7 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -103,7 +103,6 @@ "importErrors": "Errores de Importación", "importedXOfYApps": "{} de {} Aplicaciones importadas.", "followingURLsHadErrors": "Las siguientes URLs tuvieron problemas:", - "okay": "Correcto", "selectURL": "Seleccionar URL", "selectURLs": "Seleccionar URLs", "pick": "Escoger", diff --git a/assets/translations/fa.json b/assets/translations/fa.json index 9af4cf6..9b534d2 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -103,7 +103,6 @@ "importErrors": "خطاهای وارد کردن", "importedXOfYApps": "{} از {} برنامه وارد شد.", "followingURLsHadErrors": "آدرس های اینترنتی زیر دارای خطا بودند:", - "okay": "باشه", "selectURL": "آدرس اینترنتی انتخاب شده", "selectURLs": "آدرس های اینترنتی انتخاب شده", "pick": "انتخاب", diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 6322972..7b40638 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -103,7 +103,6 @@ "importErrors": "Erreurs d'importation", "importedXOfYApps": "{} sur {} applications importées.", "followingURLsHadErrors": "Les URL suivantes comportaient des erreurs :", - "okay": "Okay", "selectURL": "Sélectionnez l'URL", "selectURLs": "Sélectionnez les URLs", "pick": "Prendre", diff --git a/assets/translations/hu.json b/assets/translations/hu.json index 8e23dd3..a38e1c5 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -103,7 +103,6 @@ "importErrors": "Importálási hibák", "importedXOfYApps": "{}/{} app importálva.", "followingURLsHadErrors": "A következő URL-ek hibákat tartalmaztak:", - "okay": "Oké", "selectURL": "Válassza ki az URL-t", "selectURLs": "Kiválasztott URL-ek", "pick": "Válasszon", diff --git a/assets/translations/it.json b/assets/translations/it.json index 34a7ea2..6e923c5 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -103,7 +103,6 @@ "importErrors": "Errori di importazione", "importedXOfYApps": "{} app di {} importate.", "followingURLsHadErrors": "I seguenti URL contengono errori:", - "okay": "Va bene", "selectURL": "Seleziona l'URL", "selectURLs": "Seleziona gli URL", "pick": "Seleziona", diff --git a/assets/translations/ja.json b/assets/translations/ja.json index 3fd43f0..9aa0ce1 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -103,7 +103,6 @@ "importErrors": "インポートエラー", "importedXOfYApps": "{} / {} アプリをインポートしました", "followingURLsHadErrors": "以下のURLでエラーが発生しました:", - "okay": "OK", "selectURL": "URLを選択", "selectURLs": "URLを選択", "pick": "選択", diff --git a/assets/translations/nl.json b/assets/translations/nl.json index 678d21d..7ca8d5c 100644 --- a/assets/translations/nl.json +++ b/assets/translations/nl.json @@ -103,7 +103,6 @@ "importErrors": "Import foutmeldingen", "importedXOfYApps": "{} van {} apps geïmporteerd.", "followingURLsHadErrors": "De volgende URL's bevatten fouten:", - "okay": "Ok", "selectURL": "Selecteer URL", "selectURLs": "Selecteer URL's", "pick": "Kies", diff --git a/assets/translations/pl.json b/assets/translations/pl.json index 2c340e0..707c5f3 100644 --- a/assets/translations/pl.json +++ b/assets/translations/pl.json @@ -103,7 +103,6 @@ "importErrors": "Błędy importowania", "importedXOfYApps": "Zaimportowano {} z {} aplikacji.", "followingURLsHadErrors": "Następujące adresy URL zawierały błędy:", - "okay": "Okej", "selectURL": "Wybierz adres URL", "selectURLs": "Wybierz adresy URL", "pick": "Wybierz", diff --git a/assets/translations/pt.json b/assets/translations/pt.json index eed4690..2c573f5 100644 --- a/assets/translations/pt.json +++ b/assets/translations/pt.json @@ -103,7 +103,6 @@ "importErrors": "Erros de Importação", "importedXOfYApps": "{} de {} Apps importados.", "followingURLsHadErrors": "As seguintes URLs apresentaram erros:", - "okay": "Ok", "selectURL": "Selecionar URL", "selectURLs": "Selecionar URLs", "pick": "Escolher", diff --git a/assets/translations/ru.json b/assets/translations/ru.json index f46cf67..f983384 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -103,7 +103,6 @@ "importErrors": "Ошибка импорта", "importedXOfYApps": "Импортировано приложений: {} из {}", "followingURLsHadErrors": "При импорте следующие URL-адреса содержали ошибки:", - "okay": "Ok", "selectURL": "Выбрать URL-адрес", "selectURLs": "Выбрать URL-адреса", "pick": "Выбрать", diff --git a/assets/translations/sv.json b/assets/translations/sv.json index e0bf922..b8205f7 100644 --- a/assets/translations/sv.json +++ b/assets/translations/sv.json @@ -103,7 +103,6 @@ "importErrors": "Importfel", "importedXOfYApps": "{} av {} Appar importerade.", "followingURLsHadErrors": "Följande URL:er hade fel:", - "okay": "Okej", "selectURL": "Välj URL", "selectURLs": "Välj URL:er", "pick": "Välj", diff --git a/assets/translations/tr.json b/assets/translations/tr.json index e78901a..4cf866f 100644 --- a/assets/translations/tr.json +++ b/assets/translations/tr.json @@ -103,7 +103,6 @@ "importErrors": "İçe Aktarma Hataları", "importedXOfYApps": "{}'den {} Uygulama İçe Aktarıldı.", "followingURLsHadErrors": "Aşağıdaki URL'lerde hatalar oluştu:", - "okay": "Tamam", "selectURL": "URL Seç", "selectURLs": "URL'leri Seç", "pick": "Seç", diff --git a/assets/translations/vi.json b/assets/translations/vi.json index a4201ce..e3af5ac 100644 --- a/assets/translations/vi.json +++ b/assets/translations/vi.json @@ -103,7 +103,6 @@ "importErrors": "Lỗi nhập", "importedXOfYApps": "{} trong số {} Ứng dụng đã được nhập.", "followingURLsHadErrors": "Các URL sau có lỗi:", - "okay": "Ôkê", "selectURL": "Chọn URL", "selectURLs": "Chọn URL", "pick": "Chọn", diff --git a/assets/translations/zh.json b/assets/translations/zh.json index c7e25cb..73252b3 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -103,7 +103,6 @@ "importErrors": "导入错误", "importedXOfYApps": "已导入 {} 中的 {} 个应用。", "followingURLsHadErrors": "下列 URL 存在错误:", - "okay": "好的", "selectURL": "选择 URL", "selectURLs": "选择 URL", "pick": "选择", diff --git a/lib/pages/import_export.dart b/lib/pages/import_export.dart index 635c720..67ac86c 100644 --- a/lib/pages/import_export.dart +++ b/lib/pages/import_export.dart @@ -590,7 +590,7 @@ class _ImportErrorDialogState extends State { onPressed: () { Navigator.of(context).pop(null); }, - child: Text(tr('okay'))) + child: Text(tr('ok'))) ], ); } From 76a91b7fe01140422cec58a2f2017a53d1c329da Mon Sep 17 00:00:00 2001 From: Gregory Date: Mon, 1 Jan 2024 18:42:38 +0300 Subject: [PATCH 4/5] Don't load font if loaded --- lib/main.dart | 2 +- lib/providers/native_provider.dart | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index 6d25a03..923bdcb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -37,7 +37,7 @@ List> supportedLocales = const [ MapEntry(Locale('fr'), 'Français'), MapEntry(Locale('es'), 'Español'), MapEntry(Locale('pl'), 'Polski'), - MapEntry(Locale('ru'), 'Русский язык'), + MapEntry(Locale('ru'), 'Русский'), MapEntry(Locale('bs'), 'Bosanski'), MapEntry(Locale('pt'), 'Brasileiro'), MapEntry(Locale('cs'), 'Česky'), diff --git a/lib/providers/native_provider.dart b/lib/providers/native_provider.dart index 7a154bf..8a1767d 100644 --- a/lib/providers/native_provider.dart +++ b/lib/providers/native_provider.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; class NativeFeatures { static const MethodChannel _channel = MethodChannel('native'); static bool _callbacksApplied = false; + static bool _systemFontLoaded = false; static int _resPermShizuku = -2; // not set static Future _readFileBytes(String path) async { @@ -34,11 +35,13 @@ class NativeFeatures { } static Future tryLoadSystemFont() async { + if (_systemFontLoaded) { return true; } var font = await _channel.invokeMethod('getSystemFont'); if (font == null) { return false; } var fontLoader = FontLoader('SystemFont'); fontLoader.addFont(_readFileBytes(font)); await fontLoader.load(); + _systemFontLoaded = true; return true; } From b74bf862778bafc9b7c316580c54357c9da750e6 Mon Sep 17 00:00:00 2001 From: Gregory Date: Wed, 3 Jan 2024 14:39:33 +0300 Subject: [PATCH 5/5] Corrections --- android/app/build.gradle | 6 +++--- .../dev/imranr/obtainium/DefaultSystemFont.kt | 21 ++++++++++++++----- .../dev/imranr/obtainium/MainActivity.kt | 4 ++-- android/build.gradle | 2 +- assets/translations/en.json | 3 ++- assets/translations/ru.json | 3 ++- lib/main.dart | 19 ++++++----------- lib/pages/settings.dart | 21 +++++++++++++++---- lib/providers/native_provider.dart | 14 ++++++------- lib/providers/settings_provider.dart | 17 ++++----------- 10 files changed, 60 insertions(+), 50 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index b5d4059..dc8cd61 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -37,12 +37,12 @@ android { ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { - jvmTarget = '17' + jvmTarget = '1.8' } sourceSets { diff --git a/android/app/src/main/kotlin/dev/imranr/obtainium/DefaultSystemFont.kt b/android/app/src/main/kotlin/dev/imranr/obtainium/DefaultSystemFont.kt index 3a2edc8..048262b 100644 --- a/android/app/src/main/kotlin/dev/imranr/obtainium/DefaultSystemFont.kt +++ b/android/app/src/main/kotlin/dev/imranr/obtainium/DefaultSystemFont.kt @@ -6,19 +6,20 @@ import java.io.File import java.io.FileInputStream class DefaultSystemFont { - fun get(): String? { + fun get(): String { return try { val file = File("/system/etc/fonts.xml") val fileStream = FileInputStream(file) parseFontsFileStream(fileStream) - } catch (_: Exception) { - null + } catch (e: Exception) { + e.message ?: "Unknown fonts.xml parsing exception" } } private fun parseFontsFileStream(fileStream: FileInputStream): String { fileStream.use { stream -> val parser = Xml.newPullParser() + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false) parser.setInput(stream, null) parser.nextTag() return parseFonts(parser) @@ -26,8 +27,18 @@ class DefaultSystemFont { } private fun parseFonts(parser: XmlPullParser): String { - while (parser.name != "font") { parser.next() } + while (!((parser.next() == XmlPullParser.END_TAG) && (parser.name == "family"))) { + if ((parser.eventType == XmlPullParser.START_TAG) && (parser.name == "font") + && (parser.getAttributeValue(null, "style") == "normal") + && (parser.getAttributeValue(null, "weight") == "400")) { + break + } + } parser.next() - return "/system/fonts/" + parser.text.trim() + val fontFile = parser.text.trim() + if (fontFile == "") { + throw NoSuchFieldException("The font filename couldn't be found in fonts.xml") + } + return "/system/fonts/$fontFile" } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt b/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt index f1c3659..2991f00 100644 --- a/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt +++ b/android/app/src/main/kotlin/dev/imranr/obtainium/MainActivity.kt @@ -77,8 +77,8 @@ class MainActivity: FlutterActivity() { val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL) var installFlags: Int = PackageInstallerUtils.getInstallFlags(params) - installFlags = installFlags or (0x00000002/*PackageManager.INSTALL_REPLACE_EXISTING*/ or - 0x00000004 /*PackageManager.INSTALL_ALLOW_TEST*/) + installFlags = installFlags or (0x00000002/*PackageManager.INSTALL_REPLACE_EXISTING*/ + or 0x00000004 /*PackageManager.INSTALL_ALLOW_TEST*/) PackageInstallerUtils.setInstallFlags(params, installFlags) val sessionId = packageInstaller.createSession(params) val iSession = IPackageInstallerSession.Stub.asInterface( diff --git a/android/build.gradle b/android/build.gradle index 994513f..5d6d8f4 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.8.10' ext { compileSdkVersion = 34 // or latest targetSdkVersion = 34 // or latest diff --git a/assets/translations/en.json b/assets/translations/en.json index cae0e06..ed5a898 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -287,7 +287,8 @@ "shizuku": "Shizuku", "root": "Root", "shizukuBinderNotFound": "Сompatible Shizuku service wasn't found", - "tryUseSystemFont": "Try to use a system font", + "useSystemFont": "Use the system font", + "systemFontError": "Error loading the system font: {}", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/ru.json b/assets/translations/ru.json index ed87a9d..67c424d 100644 --- a/assets/translations/ru.json +++ b/assets/translations/ru.json @@ -287,7 +287,8 @@ "shizuku": "Shizuku", "root": "Суперпользователь", "shizukuBinderNotFound": "Совместимый сервис Shizuku не найден", - "tryUseSystemFont": "Попытаться использовать системный шрифт", + "useSystemFont": "Использовать системный шрифт", + "systemFontError": "Ошибка загрузки системного шрифта: {}", "removeAppQuestion": { "one": "Удалить приложение?", "other": "Удалить приложения?" diff --git a/lib/main.dart b/lib/main.dart index 26c328e..b8a8d8c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,7 +5,6 @@ import 'package:flutter/services.dart'; import 'package:obtainium/pages/home.dart'; import 'package:obtainium/providers/apps_provider.dart'; import 'package:obtainium/providers/logs_provider.dart'; -import 'package:obtainium/providers/native_provider.dart'; import 'package:obtainium/providers/notifications_provider.dart'; import 'package:obtainium/providers/settings_provider.dart'; import 'package:obtainium/providers/source_provider.dart'; @@ -201,16 +200,6 @@ class _ObtainiumState extends State { context.locale.languageCode)) { settingsProvider.resetLocaleSafe(context); } - settingsProvider.addListener(() async { - if (settingsProvider.tryUseSystemFont && - settingsProvider.appFont == "Metropolis") { - bool fontLoaded = await NativeFeatures.tryLoadSystemFont(); - if (fontLoaded) { settingsProvider.appFont = "SystemFont"; } - } else if (!settingsProvider.tryUseSystemFont && - settingsProvider.appFont != "Metropolis") { - settingsProvider.appFont = "Metropolis"; - } - }); } return DynamicColorBuilder( @@ -247,13 +236,17 @@ class _ObtainiumState extends State { colorScheme: settingsProvider.theme == ThemeSettings.dark ? darkColorScheme : lightColorScheme, - fontFamily: settingsProvider.appFont), + fontFamily: settingsProvider.useSystemFont + ? 'SystemFont' + : 'Metropolis'), darkTheme: ThemeData( useMaterial3: true, colorScheme: settingsProvider.theme == ThemeSettings.light ? lightColorScheme : darkColorScheme, - fontFamily: settingsProvider.appFont), + fontFamily: settingsProvider.useSystemFont + ? 'SystemFont' + : 'Metropolis'), home: Shortcuts(shortcuts: { LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(), }, child: const HomePage())); diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index 3272275..4e0d69b 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -7,6 +7,7 @@ import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/main.dart'; import 'package:obtainium/providers/apps_provider.dart'; import 'package:obtainium/providers/logs_provider.dart'; +import 'package:obtainium/providers/native_provider.dart'; import 'package:obtainium/providers/settings_provider.dart'; import 'package:obtainium/providers/source_provider.dart'; import 'package:provider/provider.dart'; @@ -410,11 +411,23 @@ class _SettingsPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Flexible(child: Text(tr('tryUseSystemFont'))), + Flexible(child: Text(tr('useSystemFont'))), Switch( - value: settingsProvider.tryUseSystemFont, - onChanged: (value) { - settingsProvider.tryUseSystemFont = value; + value: settingsProvider.useSystemFont, + onChanged: (useSystemFont) { + if (useSystemFont) { + NativeFeatures.loadSystemFont().then((fontLoadRes) { + if (fontLoadRes == 'ok') { + settingsProvider.useSystemFont = true; + } else { + showError(ObtainiumError( + tr('systemFontError', args: [fontLoadRes]) + ), context); + } + }); + } else { + settingsProvider.useSystemFont = false; + } }) ], ), diff --git a/lib/providers/native_provider.dart b/lib/providers/native_provider.dart index 8a1767d..88e0b82 100644 --- a/lib/providers/native_provider.dart +++ b/lib/providers/native_provider.dart @@ -4,8 +4,8 @@ import 'package:flutter/services.dart'; class NativeFeatures { static const MethodChannel _channel = MethodChannel('native'); - static bool _callbacksApplied = false; static bool _systemFontLoaded = false; + static bool _callbacksApplied = false; static int _resPermShizuku = -2; // not set static Future _readFileBytes(String path) async { @@ -34,15 +34,15 @@ class NativeFeatures { return completer.future; } - static Future tryLoadSystemFont() async { - if (_systemFontLoaded) { return true; } - var font = await _channel.invokeMethod('getSystemFont'); - if (font == null) { return false; } + static Future loadSystemFont() async { + if (_systemFontLoaded) { return "ok"; } + var getFontRes = await _channel.invokeMethod('getSystemFont'); + if (getFontRes[0] != '/') { return getFontRes; } // Error var fontLoader = FontLoader('SystemFont'); - fontLoader.addFont(_readFileBytes(font)); + fontLoader.addFont(_readFileBytes(getFontRes)); await fontLoader.load(); _systemFontLoaded = true; - return true; + return "ok"; } static Future checkPermissionShizuku() async { diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index c1a8bcd..3935f9c 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -51,21 +51,12 @@ class SettingsProvider with ChangeNotifier { notifyListeners(); } - String get appFont { - return prefs?.getString('appFont') ?? 'Metropolis'; + bool get useSystemFont { + return prefs?.getBool('useSystemFont') ?? false; } - set appFont(String appFont) { - prefs?.setString('appFont', appFont); - notifyListeners(); - } - - bool get tryUseSystemFont { - return prefs?.getBool('tryUseSystemFont') ?? false; - } - - set tryUseSystemFont(bool tryUseSystemFont) { - prefs?.setBool('tryUseSystemFont', tryUseSystemFont); + set useSystemFont(bool useSystemFont) { + prefs?.setBool('useSystemFont', useSystemFont); notifyListeners(); }