From 79f4420510d4098e44abf142761011fa30e62df2 Mon Sep 17 00:00:00 2001 From: "Alexander \"PapaTutuWawa" Date: Fri, 8 Sep 2023 19:47:39 +0200 Subject: [PATCH] feat: Move over the platform API --- .../moxxy/moxxy_native/MoxxyNativePlugin.kt | 5 + .../moxxy_native/platform/PlatformApi.kt | 127 ++++++++++++++++++ .../platform/PlatformImplementation.kt | 30 +++++ lib/moxxy_native.dart | 1 + lib/pigeon/platform.g.dart | 123 +++++++++++++++++ pigeon/platform.dart | 22 +++ 6 files changed, 308 insertions(+) create mode 100644 android/src/main/kotlin/org/moxxy/moxxy_native/platform/PlatformApi.kt create mode 100644 android/src/main/kotlin/org/moxxy/moxxy_native/platform/PlatformImplementation.kt create mode 100644 lib/pigeon/platform.g.dart create mode 100644 pigeon/platform.dart diff --git a/android/src/main/kotlin/org/moxxy/moxxy_native/MoxxyNativePlugin.kt b/android/src/main/kotlin/org/moxxy/moxxy_native/MoxxyNativePlugin.kt index fa66d28..95287b5 100644 --- a/android/src/main/kotlin/org/moxxy/moxxy_native/MoxxyNativePlugin.kt +++ b/android/src/main/kotlin/org/moxxy/moxxy_native/MoxxyNativePlugin.kt @@ -31,6 +31,8 @@ import org.moxxy.moxxy_native.notifications.showNotificationImpl import org.moxxy.moxxy_native.picker.FilePickerType import org.moxxy.moxxy_native.picker.MoxxyPickerApi import org.moxxy.moxxy_native.picker.PickerResultListener +import org.moxxy.moxxy_native.platform.MoxxyPlatformApi +import org.moxxy.moxxy_native.platform.PlatformImplementation object MoxxyEventChannels { var notificationChannel: EventChannel? = null @@ -63,16 +65,19 @@ class MoxxyNativePlugin : FlutterPlugin, ActivityAware, MoxxyPickerApi, MoxxyNot private lateinit var pickerListener: PickerResultListener private val cryptographyImplementation = CryptographyImplementation() private lateinit var contactsImplementation: ContactsImplementation + private lateinit var platformImplementation: PlatformImplementation override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { context = flutterPluginBinding.applicationContext contactsImplementation = ContactsImplementation(context!!) + platformImplementation = PlatformImplementation(context!!) // Register the pigeon handlers MoxxyPickerApi.setUp(flutterPluginBinding.binaryMessenger, this) MoxxyNotificationsApi.setUp(flutterPluginBinding.binaryMessenger, this) MoxxyCryptographyApi.setUp(flutterPluginBinding.binaryMessenger, cryptographyImplementation) MoxxyContactsApi.setUp(flutterPluginBinding.binaryMessenger, contactsImplementation) + MoxxyPlatformApi.setUp(flutterPluginBinding.binaryMessenger, platformImplementation) // Register the picker handler pickerListener = PickerResultListener(context!!) diff --git a/android/src/main/kotlin/org/moxxy/moxxy_native/platform/PlatformApi.kt b/android/src/main/kotlin/org/moxxy/moxxy_native/platform/PlatformApi.kt new file mode 100644 index 0000000..d4528d5 --- /dev/null +++ b/android/src/main/kotlin/org/moxxy/moxxy_native/platform/PlatformApi.kt @@ -0,0 +1,127 @@ +// Autogenerated from Pigeon (v11.0.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +package org.moxxy.moxxy_native.platform + +import android.util.Log +import io.flutter.plugin.common.BasicMessageChannel +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MessageCodec +import io.flutter.plugin.common.StandardMessageCodec +import java.io.ByteArrayOutputStream +import java.nio.ByteBuffer + +private fun wrapResult(result: Any?): List { + return listOf(result) +} + +private fun wrapError(exception: Throwable): List { + if (exception is FlutterError) { + return listOf( + exception.code, + exception.message, + exception.details + ) + } else { + return listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) + ) + } +} + +/** + * Error class for passing custom error details to Flutter via a thrown PlatformException. + * @property code The error code. + * @property message The error message. + * @property details The error details. Must be a datatype supported by the api codec. + */ +class FlutterError ( + val code: String, + override val message: String? = null, + val details: Any? = null +) : Throwable() +/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ +interface MoxxyPlatformApi { + fun getPersistentDataPath(): String + fun getCacheDataPath(): String + fun openBatteryOptimisationSettings() + fun isIgnoringBatteryOptimizations(): Boolean + + companion object { + /** The codec used by MoxxyPlatformApi. */ + val codec: MessageCodec by lazy { + StandardMessageCodec() + } + /** Sets up an instance of `MoxxyPlatformApi` to handle messages through the `binaryMessenger`. */ + @Suppress("UNCHECKED_CAST") + fun setUp(binaryMessenger: BinaryMessenger, api: MoxxyPlatformApi?) { + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.moxxy_native.MoxxyPlatformApi.getPersistentDataPath", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + var wrapped: List + try { + wrapped = listOf(api.getPersistentDataPath()) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.moxxy_native.MoxxyPlatformApi.getCacheDataPath", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + var wrapped: List + try { + wrapped = listOf(api.getCacheDataPath()) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.moxxy_native.MoxxyPlatformApi.openBatteryOptimisationSettings", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + var wrapped: List + try { + api.openBatteryOptimisationSettings() + wrapped = listOf(null) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.moxxy_native.MoxxyPlatformApi.isIgnoringBatteryOptimizations", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + var wrapped: List + try { + wrapped = listOf(api.isIgnoringBatteryOptimizations()) + } catch (exception: Throwable) { + wrapped = wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} diff --git a/android/src/main/kotlin/org/moxxy/moxxy_native/platform/PlatformImplementation.kt b/android/src/main/kotlin/org/moxxy/moxxy_native/platform/PlatformImplementation.kt new file mode 100644 index 0000000..63478bc --- /dev/null +++ b/android/src/main/kotlin/org/moxxy/moxxy_native/platform/PlatformImplementation.kt @@ -0,0 +1,30 @@ +package org.moxxy.moxxy_native.platform + +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.PowerManager +import android.provider.Settings + +class PlatformImplementation(private val context: Context) : MoxxyPlatformApi { + override fun getPersistentDataPath(): String { + return context.filesDir.path + } + + override fun getCacheDataPath(): String { + return context.cacheDir.path + } + + override fun openBatteryOptimisationSettings() { + val packageUri = Uri.parse("package:${context.packageName}") + val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, packageUri).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK + } + context.startActivity(intent) + } + + override fun isIgnoringBatteryOptimizations(): Boolean { + val pm = context.getSystemService(PowerManager::class.java) + return pm.isIgnoringBatteryOptimizations(context.packageName) + } +} \ No newline at end of file diff --git a/lib/moxxy_native.dart b/lib/moxxy_native.dart index 268f872..e27987f 100644 --- a/lib/moxxy_native.dart +++ b/lib/moxxy_native.dart @@ -2,3 +2,4 @@ export 'pigeon/contacts.g.dart'; export 'pigeon/cryptography.g.dart'; export 'pigeon/notifications.g.dart'; export 'pigeon/picker.g.dart'; +export 'pigeon/platform.g.dart'; diff --git a/lib/pigeon/platform.g.dart b/lib/pigeon/platform.g.dart new file mode 100644 index 0000000..1e3bd1b --- /dev/null +++ b/lib/pigeon/platform.g.dart @@ -0,0 +1,123 @@ +// Autogenerated from Pigeon (v11.0.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +class MoxxyPlatformApi { + /// Constructor for [MoxxyPlatformApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + MoxxyPlatformApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = StandardMessageCodec(); + + Future getPersistentDataPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.moxxy_native.MoxxyPlatformApi.getPersistentDataPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as String?)!; + } + } + + Future getCacheDataPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.moxxy_native.MoxxyPlatformApi.getCacheDataPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as String?)!; + } + } + + Future openBatteryOptimisationSettings() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.moxxy_native.MoxxyPlatformApi.openBatteryOptimisationSettings', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return; + } + } + + Future isIgnoringBatteryOptimizations() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.moxxy_native.MoxxyPlatformApi.isIgnoringBatteryOptimizations', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as bool?)!; + } + } +} diff --git a/pigeon/platform.dart b/pigeon/platform.dart new file mode 100644 index 0000000..2d39719 --- /dev/null +++ b/pigeon/platform.dart @@ -0,0 +1,22 @@ +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/pigeon/platform.g.dart', + kotlinOut: 'android/src/main/kotlin/org/moxxy/moxxy_native/platform/PlatformApi.kt', + kotlinOptions: KotlinOptions( + package: 'org.moxxy.moxxy_native.platform', + ), + ), +) + +@HostApi() +abstract class MoxxyPlatformApi { + String getPersistentDataPath(); + + String getCacheDataPath(); + + void openBatteryOptimisationSettings(); + + bool isIgnoringBatteryOptimizations(); +}