diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt index ee0527d6c..048a5a38f 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AppAdapterHandler.kt @@ -33,10 +33,12 @@ import deckers.thibault.aves.utils.LogUtils import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch import java.io.File import java.util.* -import kotlin.collections.ArrayList import kotlin.math.roundToInt class AppAdapterHandler(private val context: Context) : MethodCallHandler { @@ -46,6 +48,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler { when (call.method) { "getPackages" -> ioScope.launch { safe(call, result, ::getPackages) } "getAppIcon" -> ioScope.launch { safeSuspend(call, result, ::getAppIcon) } + "getAppInstaller" -> ioScope.launch { safe(call, result, ::getAppInstaller) } "copyToClipboard" -> ioScope.launch { safe(call, result, ::copyToClipboard) } "edit" -> safe(call, result, ::edit) "open" -> safe(call, result, ::open) @@ -161,6 +164,23 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler { } } + private fun getAppInstaller(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) { + val packageName = context.packageName + val pm = context.packageManager + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val info = pm.getInstallSourceInfo(packageName) + result.success(info.initiatingPackageName ?: info.installingPackageName) + } else { + @Suppress("deprecation") + result.success(pm.getInstallerPackageName(packageName)) + } + } catch (e: Exception) { + result.error("getAppInstaller-exception", "failed to get installer for packageName=$packageName", e.message) + return + } + } + private fun copyToClipboard(call: MethodCall, result: MethodChannel.Result) { val uri = call.argument("uri")?.let { Uri.parse(it) } val label = call.argument("label") diff --git a/lib/services/android_app_service.dart b/lib/services/android_app_service.dart index 425d13483..d61979773 100644 --- a/lib/services/android_app_service.dart +++ b/lib/services/android_app_service.dart @@ -14,6 +14,8 @@ abstract class AndroidAppService { Future getAppIcon(String packageName, double size); + Future getAppInstaller(); + Future copyToClipboard(String uri, String? label); Future edit(String uri, String mimeType); @@ -73,6 +75,16 @@ class PlatformAndroidAppService implements AndroidAppService { return Uint8List(0); } + @override + Future getAppInstaller() async { + try { + return await platform.invokeMethod('getAppInstaller'); + } on PlatformException catch (e, stack) { + await reportService.recordError(e, stack); + } + return null; + } + @override Future copyToClipboard(String uri, String? label) async { try { diff --git a/lib/widgets/about/bug_report.dart b/lib/widgets/about/bug_report.dart index 4b77272c3..20a08aaa9 100644 --- a/lib/widgets/about/bug_report.dart +++ b/lib/widgets/about/bug_report.dart @@ -158,6 +158,7 @@ class _BugReportState extends State with FeedbackMixin { Future _getInfo(BuildContext context) async { final packageInfo = await PackageInfo.fromPlatform(); final androidInfo = await DeviceInfoPlugin().androidInfo; + final installer = await androidAppService.getAppInstaller(); final hasPlayServices = await availability.hasPlayServices; final flavor = context.read().toString().split('.')[1]; return [ @@ -169,6 +170,7 @@ class _BugReportState extends State with FeedbackMixin { 'Google Play services: ${hasPlayServices ? 'ready' : 'not available'}', 'System locales: ${WidgetsBinding.instance!.window.locales.join(', ')}', 'Aves locale: ${settings.locale ?? 'system'} -> ${settings.appliedLocale}', + 'Installer: $installer', ].join('\n'); }