mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-31 05:23:28 +01:00 
			
		
		
		
	System font and newer dependencies
This commit is contained in:
		| @@ -37,12 +37,12 @@ android { | |||||||
|     ndkVersion flutter.ndkVersion |     ndkVersion flutter.ndkVersion | ||||||
|  |  | ||||||
|     compileOptions { |     compileOptions { | ||||||
|         sourceCompatibility JavaVersion.VERSION_1_8 |         sourceCompatibility JavaVersion.VERSION_17 | ||||||
|         targetCompatibility JavaVersion.VERSION_1_8 |         targetCompatibility JavaVersion.VERSION_17 | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     kotlinOptions { |     kotlinOptions { | ||||||
|         jvmTarget = '1.8' |         jvmTarget = '17' | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     sourceSets { |     sourceSets { | ||||||
| @@ -96,16 +96,11 @@ repositories { | |||||||
| } | } | ||||||
|  |  | ||||||
| dependencies { | dependencies { | ||||||
|     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" |  | ||||||
|  |  | ||||||
|     def shizuku_version = '13.1.5' |     def shizuku_version = '13.1.5' | ||||||
|     implementation "dev.rikka.shizuku:api:$shizuku_version" |     implementation "dev.rikka.shizuku:api:$shizuku_version" | ||||||
|     implementation "dev.rikka.shizuku:provider:$shizuku_version" |     implementation "dev.rikka.shizuku:provider:$shizuku_version" | ||||||
|  |  | ||||||
|     def hidden_api_version = '4.1.0' |     def hidden_api_version = '4.3.1' | ||||||
|     // 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) |  | ||||||
|     implementation "dev.rikka.tools.refine:runtime:$hidden_api_version" |     implementation "dev.rikka.tools.refine:runtime:$hidden_api_version" | ||||||
|     implementation "dev.rikka.hidden:compat:$hidden_api_version" |     implementation "dev.rikka.hidden:compat:$hidden_api_version" | ||||||
|     compileOnly "dev.rikka.hidden:stub:$hidden_api_version" |     compileOnly "dev.rikka.hidden:stub:$hidden_api_version" | ||||||
|   | |||||||
| @@ -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() | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -28,7 +28,7 @@ import rikka.shizuku.Shizuku.OnRequestPermissionResultListener | |||||||
| import rikka.shizuku.ShizukuBinderWrapper | import rikka.shizuku.ShizukuBinderWrapper | ||||||
|  |  | ||||||
| class MainActivity: FlutterActivity() { | class MainActivity: FlutterActivity() { | ||||||
|     private var installersChannel: MethodChannel? = null |     private var nativeChannel: MethodChannel? = null | ||||||
|     private val SHIZUKU_PERMISSION_REQUEST_CODE = (10..200).random() |     private val SHIZUKU_PERMISSION_REQUEST_CODE = (10..200).random() | ||||||
|  |  | ||||||
|     private fun shizukuCheckPermission(result: Result) { |     private fun shizukuCheckPermission(result: Result) { | ||||||
| @@ -52,7 +52,7 @@ class MainActivity: FlutterActivity() { | |||||||
|             requestCode: Int, grantResult: Int -> |             requestCode: Int, grantResult: Int -> | ||||||
|         if (requestCode == SHIZUKU_PERMISSION_REQUEST_CODE) { |         if (requestCode == SHIZUKU_PERMISSION_REQUEST_CODE) { | ||||||
|             val res = if (grantResult == PackageManager.PERMISSION_GRANTED) 1 else 0 |             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("") |             HiddenApiBypass.addHiddenApiExemptions("") | ||||||
|         } |         } | ||||||
|         Shizuku.addRequestPermissionResultListener(shizukuRequestPermissionResultListener) |         Shizuku.addRequestPermissionResultListener(shizukuRequestPermissionResultListener) | ||||||
|         installersChannel = MethodChannel( |         nativeChannel = MethodChannel( | ||||||
|             flutterEngine.dartExecutor.binaryMessenger, "installers") |             flutterEngine.dartExecutor.binaryMessenger, "native") | ||||||
|         installersChannel!!.setMethodCallHandler { |         nativeChannel!!.setMethodCallHandler { | ||||||
|             call, result -> |             call, result -> | ||||||
|             if (call.method == "checkPermissionShizuku") { |             if (call.method == "getSystemFont") { | ||||||
|  |                 val res = DefaultSystemFont().get() | ||||||
|  |                 result.success(res) | ||||||
|  |             } else if (call.method == "checkPermissionShizuku") { | ||||||
|                 shizukuCheckPermission(result) |                 shizukuCheckPermission(result) | ||||||
|             } else if (call.method == "checkPermissionRoot") { |             } else if (call.method == "checkPermissionRoot") { | ||||||
|                 rootCheckPermission(result) |                 rootCheckPermission(result) | ||||||
|   | |||||||
| @@ -6,9 +6,9 @@ buildscript { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     dependencies { |     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 "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" | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -285,7 +285,8 @@ | |||||||
|     "normal": "Normal", |     "normal": "Normal", | ||||||
|     "shizuku": "Shizuku", |     "shizuku": "Shizuku", | ||||||
|     "root": "Root", |     "root": "Root", | ||||||
|     "shizukuBinderNotFound": "Shizuku is not running", |     "shizukuBinderNotFound": "Сompatible Shizuku service wasn't found", | ||||||
|  |     "tryUseSystemFont": "Try to use a system font", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Remove App?", |         "one": "Remove App?", | ||||||
|         "other": "Remove Apps?" |         "other": "Remove Apps?" | ||||||
|   | |||||||
| @@ -285,7 +285,8 @@ | |||||||
|     "normal": "Нормальный", |     "normal": "Нормальный", | ||||||
|     "shizuku": "Shizuku", |     "shizuku": "Shizuku", | ||||||
|     "root": "Суперпользователь", |     "root": "Суперпользователь", | ||||||
|     "shizukuBinderNotFound": "Shizuku не запущен", |     "shizukuBinderNotFound": "Совместимый сервис Shizuku не найден", | ||||||
|  |     "tryUseSystemFont": "Попытаться использовать системный шрифт", | ||||||
|     "removeAppQuestion": { |     "removeAppQuestion": { | ||||||
|         "one": "Удалить приложение?", |         "one": "Удалить приложение?", | ||||||
|         "other": "Удалить приложения?" |         "other": "Удалить приложения?" | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; | |||||||
| import 'package:obtainium/pages/home.dart'; | import 'package:obtainium/pages/home.dart'; | ||||||
| import 'package:obtainium/providers/apps_provider.dart'; | import 'package:obtainium/providers/apps_provider.dart'; | ||||||
| import 'package:obtainium/providers/logs_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/notifications_provider.dart'; | ||||||
| import 'package:obtainium/providers/settings_provider.dart'; | import 'package:obtainium/providers/settings_provider.dart'; | ||||||
| import 'package:obtainium/providers/source_provider.dart'; | import 'package:obtainium/providers/source_provider.dart'; | ||||||
| @@ -185,6 +186,16 @@ class _ObtainiumState extends State<Obtainium> { | |||||||
|         } |         } | ||||||
|         existingUpdateInterval = actualUpdateInterval; |         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( |     return DynamicColorBuilder( | ||||||
| @@ -221,13 +232,13 @@ class _ObtainiumState extends State<Obtainium> { | |||||||
|               colorScheme: settingsProvider.theme == ThemeSettings.dark |               colorScheme: settingsProvider.theme == ThemeSettings.dark | ||||||
|                   ? darkColorScheme |                   ? darkColorScheme | ||||||
|                   : lightColorScheme, |                   : lightColorScheme, | ||||||
|               fontFamily: 'Metropolis'), |               fontFamily: settingsProvider.appFont), | ||||||
|           darkTheme: ThemeData( |           darkTheme: ThemeData( | ||||||
|               useMaterial3: true, |               useMaterial3: true, | ||||||
|               colorScheme: settingsProvider.theme == ThemeSettings.light |               colorScheme: settingsProvider.theme == ThemeSettings.light | ||||||
|                   ? lightColorScheme |                   ? lightColorScheme | ||||||
|                   : darkColorScheme, |                   : darkColorScheme, | ||||||
|               fontFamily: 'Metropolis'), |               fontFamily: settingsProvider.appFont), | ||||||
|           home: Shortcuts(shortcuts: <LogicalKeySet, Intent>{ |           home: Shortcuts(shortcuts: <LogicalKeySet, Intent>{ | ||||||
|             LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(), |             LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(), | ||||||
|           }, child: const HomePage())); |           }, child: const HomePage())); | ||||||
|   | |||||||
| @@ -351,8 +351,6 @@ class _SettingsPageState extends State<SettingsPage> { | |||||||
|                               ], |                               ], | ||||||
|                             ), |                             ), | ||||||
|                             height16, |                             height16, | ||||||
|                             installMethodDropdown, |  | ||||||
|                             height16, |  | ||||||
|                             Row( |                             Row( | ||||||
|                               mainAxisAlignment: MainAxisAlignment.spaceBetween, |                               mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|                               children: [ |                               children: [ | ||||||
| @@ -365,6 +363,7 @@ class _SettingsPageState extends State<SettingsPage> { | |||||||
|                                     }) |                                     }) | ||||||
|                               ], |                               ], | ||||||
|                             ), |                             ), | ||||||
|  |                             installMethodDropdown, | ||||||
|                             height32, |                             height32, | ||||||
|                             Text( |                             Text( | ||||||
|                               tr('sourceSpecific'), |                               tr('sourceSpecific'), | ||||||
| @@ -409,6 +408,18 @@ class _SettingsPageState extends State<SettingsPage> { | |||||||
|                             height16, |                             height16, | ||||||
|                             localeDropdown, |                             localeDropdown, | ||||||
|                             height16, |                             height16, | ||||||
|  |                             Row( | ||||||
|  |                               mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                               children: [ | ||||||
|  |                                 Flexible(child: Text(tr('tryUseSystemFont'))), | ||||||
|  |                                 Switch( | ||||||
|  |                                     value: settingsProvider.tryUseSystemFont, | ||||||
|  |                                     onChanged: (value) { | ||||||
|  |                                       settingsProvider.tryUseSystemFont = value; | ||||||
|  |                                     }) | ||||||
|  |                               ], | ||||||
|  |                             ), | ||||||
|  |                             height16, | ||||||
|                             Row( |                             Row( | ||||||
|                               mainAxisAlignment: MainAxisAlignment.spaceBetween, |                               mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|                               children: [ |                               children: [ | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ import 'package:http/http.dart'; | |||||||
| import 'package:android_intent_plus/android_intent.dart'; | import 'package:android_intent_plus/android_intent.dart'; | ||||||
| import 'package:flutter_archive/flutter_archive.dart'; | import 'package:flutter_archive/flutter_archive.dart'; | ||||||
| import 'package:shared_storage/shared_storage.dart' as saf; | import 'package:shared_storage/shared_storage.dart' as saf; | ||||||
| import 'installers_provider.dart'; | import 'native_provider.dart'; | ||||||
|  |  | ||||||
| final pm = AndroidPackageManager(); | final pm = AndroidPackageManager(); | ||||||
|  |  | ||||||
| @@ -523,12 +523,12 @@ class AppsProvider with ChangeNotifier { | |||||||
|         code = await AndroidPackageInstaller.installApk( |         code = await AndroidPackageInstaller.installApk( | ||||||
|             apkFilePath: file.file.path); |             apkFilePath: file.file.path); | ||||||
|       case InstallMethodSettings.shizuku: |       case InstallMethodSettings.shizuku: | ||||||
|         code = (await Installers.installWithShizuku( |         code = (await NativeFeatures.installWithShizuku( | ||||||
|                 apkFileUri: file.file.uri.toString())) |                 apkFileUri: file.file.uri.toString())) | ||||||
|             ? 0 |             ? 0 | ||||||
|             : 1; |             : 1; | ||||||
|       case InstallMethodSettings.root: |       case InstallMethodSettings.root: | ||||||
|         code = (await Installers.installWithRoot(apkFilePath: file.file.path)) |         code = (await NativeFeatures.installWithRoot(apkFilePath: file.file.path)) | ||||||
|             ? 0 |             ? 0 | ||||||
|             : 1; |             : 1; | ||||||
|     } |     } | ||||||
| @@ -694,14 +694,14 @@ class AppsProvider with ChangeNotifier { | |||||||
|               throw ObtainiumError(tr('cancelled')); |               throw ObtainiumError(tr('cancelled')); | ||||||
|             } |             } | ||||||
|           case InstallMethodSettings.shizuku: |           case InstallMethodSettings.shizuku: | ||||||
|             int code = await Installers.checkPermissionShizuku(); |             int code = await NativeFeatures.checkPermissionShizuku(); | ||||||
|             if (code == -1) { |             if (code == -1) { | ||||||
|               throw ObtainiumError(tr('shizukuBinderNotFound')); |               throw ObtainiumError(tr('shizukuBinderNotFound')); | ||||||
|             } else if (code == 0) { |             } else if (code == 0) { | ||||||
|               throw ObtainiumError(tr('cancelled')); |               throw ObtainiumError(tr('cancelled')); | ||||||
|             } |             } | ||||||
|           case InstallMethodSettings.root: |           case InstallMethodSettings.root: | ||||||
|             if (!(await Installers.checkPermissionRoot())) { |             if (!(await NativeFeatures.checkPermissionRoot())) { | ||||||
|               throw ObtainiumError(tr('cancelled')); |               throw ObtainiumError(tr('cancelled')); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,12 +1,25 @@ | |||||||
| import 'dart:async'; | import 'dart:async'; | ||||||
|  | import 'dart:io'; | ||||||
| import 'package:flutter/services.dart'; | import 'package:flutter/services.dart'; | ||||||
| 
 | 
 | ||||||
| class Installers { | class NativeFeatures { | ||||||
|   static const MethodChannel _channel = MethodChannel('installers'); |   static const MethodChannel _channel = MethodChannel('native'); | ||||||
|   static bool _callbacksApplied = false; |   static bool _callbacksApplied = false; | ||||||
|   static int _resPermShizuku = -2;  // not set |   static int _resPermShizuku = -2;  // not set | ||||||
| 
 | 
 | ||||||
|   static Future waitWhile(bool Function() test, |   static Future<ByteData> _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)]) { |       [Duration pollInterval = const Duration(milliseconds: 250)]) { | ||||||
|     var completer = Completer(); |     var completer = Completer(); | ||||||
|     check() { |     check() { | ||||||
| @@ -20,20 +33,23 @@ class Installers { | |||||||
|     return completer.future; |     return completer.future; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static Future handleCalls(MethodCall call) async { |   static Future<bool> tryLoadSystemFont() async { | ||||||
|     if (call.method == 'resPermShizuku') { |     var font = await _channel.invokeMethod('getSystemFont'); | ||||||
|       _resPermShizuku = call.arguments['res']; |     if (font == null) { return false; } | ||||||
|     } |     var fontLoader = FontLoader('SystemFont'); | ||||||
|  |     fontLoader.addFont(_readFileBytes(font)); | ||||||
|  |     await fontLoader.load(); | ||||||
|  |     return true; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static Future<int> checkPermissionShizuku() async { |   static Future<int> checkPermissionShizuku() async { | ||||||
|     if (!_callbacksApplied) { |     if (!_callbacksApplied) { | ||||||
|       _channel.setMethodCallHandler(handleCalls); |       _channel.setMethodCallHandler(_handleCalls); | ||||||
|       _callbacksApplied = true; |       _callbacksApplied = true; | ||||||
|     } |     } | ||||||
|     int res = await _channel.invokeMethod('checkPermissionShizuku'); |     int res = await _channel.invokeMethod('checkPermissionShizuku'); | ||||||
|     if(res == -2) { |     if (res == -2) { | ||||||
|       await waitWhile(() => _resPermShizuku == -2); |       await _waitWhile(() => _resPermShizuku == -2); | ||||||
|       res = _resPermShizuku; |       res = _resPermShizuku; | ||||||
|       _resPermShizuku = -2; |       _resPermShizuku = -2; | ||||||
|     } |     } | ||||||
| @@ -51,6 +51,24 @@ class SettingsProvider with ChangeNotifier { | |||||||
|     notifyListeners(); |     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 { |   InstallMethodSettings get installMethod { | ||||||
|     return InstallMethodSettings |     return InstallMethodSettings | ||||||
|         .values[prefs?.getInt('installMethod') ?? InstallMethodSettings.normal.index]; |         .values[prefs?.getInt('installMethod') ?? InstallMethodSettings.normal.index]; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user