From 84ac0f9e7941422f03e17bf8881f5e55be944797 Mon Sep 17 00:00:00 2001 From: Jeroen Weener Date: Thu, 9 Nov 2023 16:26:08 +0100 Subject: [PATCH] Refactor: Port `canScheduleExactAlarms` (Android) (#1214) * Port Android `Manifest.permission` and `Manifest.permission_group` (#1196) * Port `Manifest.permission` and `Manifest.permission_group` * Use Dart conventions for `Manifest` variables * Implement `checkPermissionStatus` * Change entry point of getting an `Activity`, implement `requestPermission` * Expose `requestCode` * Update tests * Update main.dart * Update CHANGELOG.md * Elaborate on concern * Replace `AndroidActivity` with `ActivityAware` * Delete test * Apply small fixes * Elaborate on missing Android activity * Regenerate pigeon files * Make small adjustments based on review * Update documentation * Update documentation * Implement `Settings` mirror * Implement `Uri` mirror * Add `Intent` constructor and update `Uri` implementation * Implement `Intent` methods * Implement `startActivity`, `getPackageName` for `Context` * Copy new `Context` methods to `Activity` * Implement `openAppSettings` in `PermissionHandlerAndroid` * Follow-up changes * Run `dart format .` * Add `startActivityForResult` * Add actions to `Settings` * Update TODOs * Run `dart format .` * Implement `getSystemService` * Add `Build` * Implement `PowerManager` * Fix bug with `PowerManager`, update `PermissionHandlerAndroid` * Run `dart format .` * Add sdk check to `isIgnoringBatteryOptimizations` * Implement `AlarmManager` --- .../ActivityHostApiImpl.java | 7 + .../AlarmManagerFlutterApiImpl.java | 66 ++++ .../AlarmManagerHostApiImpl.java | 52 +++ .../permissionhandler/ContextHostApiImpl.java | 7 + .../PermissionHandlerPigeon.java | 98 +++++ .../PermissionHandlerPlugin.java | 7 + .../lib/permission_handler_android.dart | 1 + .../src/android_object_mirrors/activity.dart | 9 + .../android_object_mirrors/alarm_manager.dart | 49 +++ .../src/android_object_mirrors/context.dart | 4 + .../android_permission_handler_api_impls.dart | 62 +++ .../lib/src/permission_handler.pigeon.dart | 303 +++++++++++---- .../pigeons/android_permission_handler.dart | 31 ++ .../test/test_permission_handler.pigeon.dart | 356 +++++++++++++----- 14 files changed, 872 insertions(+), 180 deletions(-) create mode 100644 permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/AlarmManagerFlutterApiImpl.java create mode 100644 permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/AlarmManagerHostApiImpl.java create mode 100644 permission_handler_android/lib/src/android_object_mirrors/alarm_manager.dart diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ActivityHostApiImpl.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ActivityHostApiImpl.java index 694b6a8d3..f5fe7a45a 100644 --- a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ActivityHostApiImpl.java +++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ActivityHostApiImpl.java @@ -1,6 +1,7 @@ package com.baseflow.permissionhandler; import android.app.Activity; +import android.app.AlarmManager; import android.content.Intent; import android.os.PowerManager; @@ -56,6 +57,8 @@ public class ActivityHostApiImpl implements private final PowerManagerFlutterApiImpl powerManagerFlutterApi; + private final AlarmManagerFlutterApiImpl alarmManagerFlutterApi; + /** * Callbacks to complete a pending permission request. *

@@ -80,9 +83,11 @@ public class ActivityHostApiImpl implements */ public ActivityHostApiImpl( @NonNull PowerManagerFlutterApiImpl powerManagerFlutterApi, + @NonNull AlarmManagerFlutterApiImpl alarmManagerFlutterApi, @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager ) { + this.alarmManagerFlutterApi = alarmManagerFlutterApi; this.powerManagerFlutterApi = powerManagerFlutterApi; this.binaryMessenger = binaryMessenger; this.instanceManager = instanceManager; @@ -237,6 +242,8 @@ public boolean onActivityResult( if (systemService instanceof PowerManager) { powerManagerFlutterApi.create((PowerManager) systemService); + } else if (systemService instanceof AlarmManager) { + alarmManagerFlutterApi.create((AlarmManager) systemService); } final UUID systemServiceUuid = instanceManager.getIdentifierForStrongReference(systemService); diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/AlarmManagerFlutterApiImpl.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/AlarmManagerFlutterApiImpl.java new file mode 100644 index 000000000..df8436432 --- /dev/null +++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/AlarmManagerFlutterApiImpl.java @@ -0,0 +1,66 @@ +package com.baseflow.permissionhandler; + +import android.app.AlarmManager; + +import androidx.annotation.NonNull; + +import com.baseflow.instancemanager.InstanceManager; +import com.baseflow.permissionhandler.PermissionHandlerPigeon.AlarmManagerFlutterApi; + +import java.util.UUID; + +import io.flutter.plugin.common.BinaryMessenger; + +/** + * Flutter API implementation for `AlarmManager`. + * + *

This class may handle adding native instances that are attached to a Dart instance or passing + * arguments of callbacks methods to a Dart instance. + */ +public class AlarmManagerFlutterApiImpl { + // To ease adding additional methods, this value is added prematurely. + @SuppressWarnings({"unused", "FieldCanBeLocal"}) + private final BinaryMessenger binaryMessenger; + + private final InstanceManager instanceManager; + + private final AlarmManagerFlutterApi api; + + /** + * Constructs a {@link AlarmManagerFlutterApiImpl}. + * + * @param binaryMessenger used to communicate with Dart over asynchronous messages + * @param instanceManager maintains instances stored to communicate with attached Dart objects + */ + public AlarmManagerFlutterApiImpl( + @NonNull BinaryMessenger binaryMessenger, + @NonNull InstanceManager instanceManager + ) { + this.binaryMessenger = binaryMessenger; + this.instanceManager = instanceManager; + api = new AlarmManagerFlutterApi(binaryMessenger); + } + + /** + * Stores the `AlarmManager` instance and notifies Dart to create and store a new `AlarmManager` + * instance that is attached to this one. If `instance` has already been added, this method does + * nothing. + */ + public void create(@NonNull AlarmManager instance) { + if (!instanceManager.containsInstance(instance)) { + final UUID alarmManagerInstanceUuid = instanceManager.addHostCreatedInstance(instance); + api.create(alarmManagerInstanceUuid.toString(), reply -> {}); + } + } + + /** + * Disposes of the `AlarmManager` instance in the instance manager and notifies Dart to do the + * same. If `instance` was already disposed, this method does nothing. + */ + public void dispose(AlarmManager instance) { + final UUID alarmManagerInstanceUuid = instanceManager.getIdentifierForStrongReference(instance); + if (alarmManagerInstanceUuid != null) { + api.dispose(alarmManagerInstanceUuid.toString(), reply -> {}); + } + } +} diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/AlarmManagerHostApiImpl.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/AlarmManagerHostApiImpl.java new file mode 100644 index 000000000..bd21db762 --- /dev/null +++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/AlarmManagerHostApiImpl.java @@ -0,0 +1,52 @@ +package com.baseflow.permissionhandler; + +import android.os.Build; +import android.app.AlarmManager; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + +import com.baseflow.instancemanager.InstanceManager; +import com.baseflow.permissionhandler.PermissionHandlerPigeon.AlarmManagerHostApi; + +import java.util.UUID; + +import io.flutter.plugin.common.BinaryMessenger; + +/** + * Host API implementation for `AlarmManager`. + * + *

This class may handle instantiating and adding native object instances that are attached to a + * Dart instance or handle method calls on the associated native class or an instance of the class. + */ +public class AlarmManagerHostApiImpl implements AlarmManagerHostApi { + // To ease adding additional methods, this value is added prematurely. + @SuppressWarnings({"unused", "FieldCanBeLocal"}) + private final BinaryMessenger binaryMessenger; + + private final InstanceManager instanceManager; + + /** + * Constructs an {@link AlarmManagerHostApiImpl}. + * + * @param binaryMessenger used to communicate with Dart over asynchronous messages + * @param instanceManager maintains instances stored to communicate with attached Dart objects + */ + public AlarmManagerHostApiImpl( + @NonNull BinaryMessenger binaryMessenger, + @NonNull InstanceManager instanceManager + ) { + this.binaryMessenger = binaryMessenger; + this.instanceManager = instanceManager; + } + + @RequiresApi(api = Build.VERSION_CODES.S) + @NonNull + @Override + public Boolean canScheduleExactAlarms(@NonNull String instanceId) { + final UUID instanceUuid = UUID.fromString(instanceId); + final AlarmManager alarmManager = instanceManager.getInstance(instanceUuid); + + return alarmManager.canScheduleExactAlarms(); + } +} diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ContextHostApiImpl.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ContextHostApiImpl.java index c15644750..a4c8df5ed 100644 --- a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ContextHostApiImpl.java +++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ContextHostApiImpl.java @@ -1,5 +1,6 @@ package com.baseflow.permissionhandler; +import android.app.AlarmManager; import android.content.Context; import android.content.Intent; import android.os.PowerManager; @@ -29,6 +30,8 @@ public class ContextHostApiImpl implements ContextHostApi { private final PowerManagerFlutterApiImpl powerManagerFlutterApi; + private final AlarmManagerFlutterApiImpl alarmManagerFlutterApi; + /** * Constructs an {@link ContextHostApiImpl}. * @@ -37,10 +40,12 @@ public class ContextHostApiImpl implements ContextHostApi { */ public ContextHostApiImpl( @NonNull PowerManagerFlutterApiImpl powerManagerFlutterApi, + @NonNull AlarmManagerFlutterApiImpl alarmManagerFlutterApi, @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager ) { this.powerManagerFlutterApi = powerManagerFlutterApi; + this.alarmManagerFlutterApi = alarmManagerFlutterApi; this.binaryMessenger = binaryMessenger; this.instanceManager = instanceManager; } @@ -92,6 +97,8 @@ public void startActivity( if (systemService instanceof PowerManager) { powerManagerFlutterApi.create((PowerManager) systemService); + } else if (systemService instanceof AlarmManager) { + alarmManagerFlutterApi.create((AlarmManager) systemService); } final UUID systemServiceUuid = instanceManager.getIdentifierForStrongReference(systemService); diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPigeon.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPigeon.java index a753a32fa..40c1597cd 100644 --- a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPigeon.java +++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPigeon.java @@ -1225,4 +1225,102 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable BuildVersi } } } + /** + * Host API for `AlarmManager`. + * + * This class may handle instantiating and adding native object instances that + * are attached to a Dart instance or handle method calls on the associated + * native class or an instance of the class. + * + * See https://developer.android.com/reference/android/app/AlarmManager. + * + * Generated interface from Pigeon that represents a handler of messages from Flutter. + */ + public interface AlarmManagerHostApi { + /** + * Called to check if the application can schedule exact alarms. + * + * See https://developer.android.com/reference/android/app/AlarmManager#canScheduleExactAlarms(). + */ + @NonNull + Boolean canScheduleExactAlarms(@NonNull String instanceId); + + /** The codec used by AlarmManagerHostApi. */ + static @NonNull MessageCodec getCodec() { + return new StandardMessageCodec(); + } + /**Sets up an instance of `AlarmManagerHostApi` to handle messages through the `binaryMessenger`. */ + static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable AlarmManagerHostApi api) { + { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, "dev.flutter.pigeon.permission_handler_android.AlarmManagerHostApi.canScheduleExactAlarms", getCodec()); + if (api != null) { + channel.setMessageHandler( + (message, reply) -> { + ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + String instanceIdArg = (String) args.get(0); + try { + Boolean output = api.canScheduleExactAlarms(instanceIdArg); + wrapped.add(0, output); + } + catch (Throwable exception) { + ArrayList wrappedError = wrapError(exception); + wrapped = wrappedError; + } + reply.reply(wrapped); + }); + } else { + channel.setMessageHandler(null); + } + } + } + } + /** + * Flutter API for `AlarmManager`. + * + * This class may handle instantiating and adding Dart instances that are + * attached to a native instance or receiving callback methods from an + * overridden native class. + * + * See https://developer.android.com/reference/android/app/AlarmManager. + * + * Generated class from Pigeon that represents Flutter messages that can be called from Java. + */ + public static class AlarmManagerFlutterApi { + private final @NonNull BinaryMessenger binaryMessenger; + + public AlarmManagerFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) { + this.binaryMessenger = argBinaryMessenger; + } + + /** Public interface for sending reply. */ + @SuppressWarnings("UnknownNullness") + public interface Reply { + void reply(T reply); + } + /** The codec used by AlarmManagerFlutterApi. */ + static @NonNull MessageCodec getCodec() { + return new StandardMessageCodec(); + } + /** Create a new Dart instance and add it to the `InstanceManager`. */ + public void create(@NonNull String instanceIdArg, @NonNull Reply callback) { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, "dev.flutter.pigeon.permission_handler_android.AlarmManagerFlutterApi.create", getCodec()); + channel.send( + new ArrayList(Collections.singletonList(instanceIdArg)), + channelReply -> callback.reply(null)); + } + /** Dispose of the Dart instance and remove it from the `InstanceManager`. */ + public void dispose(@NonNull String instanceIdArg, @NonNull Reply callback) { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, "dev.flutter.pigeon.permission_handler_android.AlarmManagerFlutterApi.dispose", getCodec()); + channel.send( + new ArrayList(Collections.singletonList(instanceIdArg)), + channelReply -> callback.reply(null)); + } + } } diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java index e8c2ab094..f76c52c66 100644 --- a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java +++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java @@ -11,6 +11,7 @@ import com.baseflow.instancemanager.InstanceManagerPigeon.InstanceManagerHostApi; import com.baseflow.instancemanager.JavaObjectHostApiImpl; import com.baseflow.permissionhandler.PermissionHandlerPigeon.ActivityHostApi; +import com.baseflow.permissionhandler.PermissionHandlerPigeon.AlarmManagerHostApi; import com.baseflow.permissionhandler.PermissionHandlerPigeon.BuildVersionHostApi; import com.baseflow.permissionhandler.PermissionHandlerPigeon.ContextHostApi; import com.baseflow.permissionhandler.PermissionHandlerPigeon.IntentHostApi; @@ -62,9 +63,14 @@ private void setUp( final PowerManagerHostApi powerManagerHostApi = new PowerManagerHostApiImpl(binaryMessenger, instanceManager); PowerManagerHostApi.setup(binaryMessenger, powerManagerHostApi); + final AlarmManagerFlutterApiImpl alarmManagerFlutterApi = new AlarmManagerFlutterApiImpl(binaryMessenger, instanceManager); + final AlarmManagerHostApi alarmManagerHostApi = new AlarmManagerHostApiImpl(binaryMessenger, instanceManager); + AlarmManagerHostApi.setup(binaryMessenger, alarmManagerHostApi); + activityFlutterApi = new ActivityFlutterApiImpl(binaryMessenger, instanceManager); activityHostApi = new ActivityHostApiImpl( powerManagerFlutterApi, + alarmManagerFlutterApi, binaryMessenger, instanceManager ); @@ -73,6 +79,7 @@ private void setUp( contextFlutterApi = new ContextFlutterApiImpl(binaryMessenger, instanceManager); final ContextHostApiImpl contextHostApi = new ContextHostApiImpl( powerManagerFlutterApi, + alarmManagerFlutterApi, binaryMessenger, instanceManager ); diff --git a/permission_handler_android/lib/permission_handler_android.dart b/permission_handler_android/lib/permission_handler_android.dart index efce2d675..0d3cc7464 100644 --- a/permission_handler_android/lib/permission_handler_android.dart +++ b/permission_handler_android/lib/permission_handler_android.dart @@ -1,4 +1,5 @@ export 'src/android_object_mirrors/activity.dart'; +export 'src/android_object_mirrors/alarm_manager.dart'; export 'src/android_object_mirrors/build.dart'; export 'src/android_object_mirrors/context.dart'; export 'src/android_object_mirrors/intent.dart'; diff --git a/permission_handler_android/lib/src/android_object_mirrors/activity.dart b/permission_handler_android/lib/src/android_object_mirrors/activity.dart index 30ecda27a..727f522cd 100644 --- a/permission_handler_android/lib/src/android_object_mirrors/activity.dart +++ b/permission_handler_android/lib/src/android_object_mirrors/activity.dart @@ -27,6 +27,15 @@ class Activity extends JavaObject { final ActivityHostApiImpl _hostApi; + /// Use with [Context.getSystemService] to retrieve a [PowerManager] for + /// controlling power management, including "wake locks," which let you keep + /// the device on while you're running long tasks. + static const String powerService = 'power'; + + /// Use with [Context.getSystemService] to retrieve an [AlarmManager] for + /// receiving intents at a time of your choosing. + static const String alarmService = 'alarm'; + /// Standard activity result: operation succeeded. /// /// Constant Value: -1 (0xffffffff). diff --git a/permission_handler_android/lib/src/android_object_mirrors/alarm_manager.dart b/permission_handler_android/lib/src/android_object_mirrors/alarm_manager.dart new file mode 100644 index 000000000..7758c4b16 --- /dev/null +++ b/permission_handler_android/lib/src/android_object_mirrors/alarm_manager.dart @@ -0,0 +1,49 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_instance_manager/flutter_instance_manager.dart'; +import 'package:permission_handler_android/src/android_permission_handler_api_impls.dart'; + +import 'build.dart'; + +/// This class provides access to the system alarm services. +/// +/// These allow you to schedule your application to be run at some point in the +/// future. +/// +/// When an alarm goes off, the Intent that had been registered for it is +/// broadcast by the system, automatically starting the target application if it +/// is not already running. +/// +/// Registered alarms are retained while the device is asleep (and can +/// optionally wake the device up if they go off during that time), but will be +/// cleared if it is turned off and rebooted. +/// +/// See https://developer.android.com/reference/android/app/AlarmManager. +class AlarmManager extends JavaObject { + /// Instantiates an [AlarmManager] without creating and attaching to an + /// instance of the associated native class. + AlarmManager.detached({ + BinaryMessenger? binaryMessenger, + InstanceManager? instanceManager, + }) : _hostApi = AlarmManagerHostApiImpl( + binaryMessenger: binaryMessenger, + instanceManager: instanceManager, + ), + super.detached(); + + final AlarmManagerHostApiImpl _hostApi; + + /// Called to check if the application can schedule exact alarms. + /// + /// Always returns true on devices running Android versions older than + /// [Build.versionCodes.s]. + /// + /// See https://developer.android.com/reference/android/app/AlarmManager#canScheduleExactAlarms(). + Future canScheduleExactAlarms() async { + final int sdkVersion = await Build.version.sdkInt; + if (sdkVersion < Build.versionCodes.s) { + return true; + } + + return _hostApi.canScheduleExactAlarmsFromInstance(this); + } +} diff --git a/permission_handler_android/lib/src/android_object_mirrors/context.dart b/permission_handler_android/lib/src/android_object_mirrors/context.dart index 742c83dd1..2f54ba902 100644 --- a/permission_handler_android/lib/src/android_object_mirrors/context.dart +++ b/permission_handler_android/lib/src/android_object_mirrors/context.dart @@ -34,6 +34,10 @@ class Context extends JavaObject { /// the device on while you're running long tasks. static const String powerService = 'power'; + /// Use with [Context.getSystemService] to retrieve an [AlarmManager] for + /// receiving intents at a time of your choosing. + static const String alarmService = 'alarm'; + /// Determine whether the application has been granted a particular permission. /// /// See https://developer.android.com/reference/android/content/Context#checkSelfPermission(java.lang.String). diff --git a/permission_handler_android/lib/src/android_permission_handler_api_impls.dart b/permission_handler_android/lib/src/android_permission_handler_api_impls.dart index b75162d03..7139d1dc3 100644 --- a/permission_handler_android/lib/src/android_permission_handler_api_impls.dart +++ b/permission_handler_android/lib/src/android_permission_handler_api_impls.dart @@ -11,11 +11,14 @@ class AndroidPermissionHandlerFlutterApis { ActivityFlutterApiImpl? activityFlutterApi, ContextFlutterApiImpl? contextFlutterApi, PowerManagerFlutterApiImpl? powerManagerFlutterApi, + AlarmManagerFlutterApiImpl? alarmManagerFlutterApi, }) { this.activityFlutterApi = activityFlutterApi ?? ActivityFlutterApiImpl(); this.contextFlutterApi = contextFlutterApi ?? ContextFlutterApiImpl(); this.powerManagerFlutterApi = powerManagerFlutterApi ?? PowerManagerFlutterApiImpl(); + this.alarmManagerFlutterApi = + alarmManagerFlutterApi ?? AlarmManagerFlutterApiImpl(); } static bool _haveBeenSetUp = false; @@ -38,12 +41,16 @@ class AndroidPermissionHandlerFlutterApis { /// Flutter API for [PowerManager]. late final PowerManagerFlutterApiImpl powerManagerFlutterApi; + /// Flutter API for [AlarmManager]. + late final AlarmManagerFlutterApiImpl alarmManagerFlutterApi; + /// Ensures all the Flutter APIs have been setup to receive calls from native code. void ensureSetUp() { if (!_haveBeenSetUp) { ActivityFlutterApi.setup(activityFlutterApi); ContextFlutterApi.setup(contextFlutterApi); PowerManagerFlutterApi.setup(powerManagerFlutterApi); + AlarmManagerFlutterApi.setup(alarmManagerFlutterApi); _haveBeenSetUp = true; } @@ -531,3 +538,58 @@ class BuildVersionHostApiImpl extends BuildVersionHostApi { /// Maintains instances stored to communicate with native language objects. final InstanceManager instanceManager; } + +/// Host API implementation of AlarmManager. +class AlarmManagerHostApiImpl extends AlarmManagerHostApi { + /// Creates a new instance of [AlarmManagerHostApiImpl]. + AlarmManagerHostApiImpl({ + this.binaryMessenger, + InstanceManager? instanceManager, + }) : instanceManager = instanceManager ?? JavaObject.globalInstanceManager, + super(binaryMessenger: binaryMessenger); + + /// Sends binary data across the Flutter platform barrier. + /// + /// If it is null, the default BinaryMessenger will be used which routes to + /// the host platform. + final BinaryMessenger? binaryMessenger; + + /// Maintains instances stored to communicate with native language objects. + final InstanceManager instanceManager; + + /// Called to check if the application can schedule exact alarms. + /// + /// See https://developer.android.com/reference/android/app/AlarmManager#canScheduleExactAlarms(). + Future canScheduleExactAlarmsFromInstance( + AlarmManager alarmManager, + ) async { + return await canScheduleExactAlarms( + instanceManager.getIdentifier(alarmManager)!, + ); + } +} + +/// Flutter API implementation of AlarmManager. +class AlarmManagerFlutterApiImpl extends AlarmManagerFlutterApi { + /// Constructs a new instance of [AlarmManagerFlutterApiImpl]. + AlarmManagerFlutterApiImpl({ + InstanceManager? instanceManager, + }) : _instanceManager = instanceManager ?? JavaObject.globalInstanceManager; + + /// Maintains instances stored to communicate with native language objects. + final InstanceManager _instanceManager; + + @override + void create(String instanceId) { + final AlarmManager alarmManager = AlarmManager.detached(); + _instanceManager.addHostCreatedInstance( + alarmManager, + instanceId, + ); + } + + @override + void dispose(String instanceId) { + _instanceManager.remove(instanceId); + } +} diff --git a/permission_handler_android/lib/src/permission_handler.pigeon.dart b/permission_handler_android/lib/src/permission_handler.pigeon.dart index 3f6ca1d0e..fdf6d0f19 100644 --- a/permission_handler_android/lib/src/permission_handler.pigeon.dart +++ b/permission_handler_android/lib/src/permission_handler.pigeon.dart @@ -94,9 +94,9 @@ class _ActivityHostApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 128: return ActivityResultPigeon.decode(readValue(buffer)!); - case 129: + case 129: return PermissionRequestResult.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -124,12 +124,14 @@ class ActivityHostApi { /// Gets whether the application should show UI with rationale before requesting a permission. /// /// See https://developer.android.com/reference/android/app/Activity#shouldShowRequestPermissionRationale(java.lang.String). - Future shouldShowRequestPermissionRationale(String arg_instanceId, String arg_permission) async { + Future shouldShowRequestPermissionRationale( + String arg_instanceId, String arg_permission) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.shouldShowRequestPermissionRationale', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.shouldShowRequestPermissionRationale', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_permission]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_permission]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -154,12 +156,14 @@ class ActivityHostApi { /// Determine whether the application has been granted a particular permission. /// /// See https://developer.android.com/reference/android/app/Activity#checkSelfPermission(java.lang.String). - Future checkSelfPermission(String arg_instanceId, String arg_permission) async { + Future checkSelfPermission( + String arg_instanceId, String arg_permission) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.checkSelfPermission', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.checkSelfPermission', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_permission]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_permission]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -187,12 +191,15 @@ class ActivityHostApi { /// https://developer.android.com/reference/android/app/Activity#requestPermissions(java.lang.String[],%20int) /// and /// https://developer.android.com/reference/android/app/Activity#onRequestPermissionsResult(int,%20java.lang.String[],%20int[]). - Future requestPermissions(String arg_instanceId, List arg_permissions, int? arg_requestCode) async { + Future requestPermissions(String arg_instanceId, + List arg_permissions, int? arg_requestCode) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.requestPermissions', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.requestPermissions', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_permissions, arg_requestCode]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_permissions, arg_requestCode]) + as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -217,12 +224,15 @@ class ActivityHostApi { /// Launch a new activity. /// /// See https://developer.android.com/reference/android/content/Context#startActivity(android.content.Intent). - Future startActivity(String arg_instanceId, String arg_intentInstanceId) async { + Future startActivity( + String arg_instanceId, String arg_intentInstanceId) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivity', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivity', + codec, binaryMessenger: _binaryMessenger); final List? replyList = - await channel.send([arg_instanceId, arg_intentInstanceId]) as List?; + await channel.send([arg_instanceId, arg_intentInstanceId]) + as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -244,7 +254,8 @@ class ActivityHostApi { /// See https://developer.android.com/reference/android/content/Context#getPackageName(). Future getPackageName(String arg_instanceId) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageName', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageName', + codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_instanceId]) as List?; @@ -276,12 +287,14 @@ class ActivityHostApi { /// Returns the instance ID of the service. /// /// See https://developer.android.com/reference/android/content/Context#getSystemService(java.lang.String). - Future getSystemService(String arg_instanceId, String arg_name) async { + Future getSystemService( + String arg_instanceId, String arg_name) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getSystemService', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getSystemService', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_name]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_name]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -306,12 +319,15 @@ class ActivityHostApi { /// Start an activity for which the application would like a result when it finished. /// /// See https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int). - Future startActivityForResult(String arg_instanceId, String arg_intentInstanceId, int? arg_requestCode) async { + Future startActivityForResult(String arg_instanceId, + String arg_intentInstanceId, int? arg_requestCode) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivityForResult', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivityForResult', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_intentInstanceId, arg_requestCode]) as List?; + final List? replyList = await channel.send( + [arg_instanceId, arg_intentInstanceId, arg_requestCode]) + as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -350,17 +366,19 @@ abstract class ActivityFlutterApi { /// Dispose of the Dart instance and remove it from the `InstanceManager`. void dispose(String instanceId); - static void setup(ActivityFlutterApi? api, {BinaryMessenger? binaryMessenger}) { + static void setup(ActivityFlutterApi? api, + {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityFlutterApi.create', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityFlutterApi.create', + codec, binaryMessenger: binaryMessenger); if (api == null) { channel.setMessageHandler(null); } else { channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityFlutterApi.create was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityFlutterApi.create was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -372,14 +390,15 @@ abstract class ActivityFlutterApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityFlutterApi.dispose', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityFlutterApi.dispose', + codec, binaryMessenger: binaryMessenger); if (api == null) { channel.setMessageHandler(null); } else { channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityFlutterApi.dispose was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityFlutterApi.dispose was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -412,12 +431,14 @@ class ContextHostApi { /// Determine whether the application has been granted a particular permission. /// /// See https://developer.android.com/reference/android/content/Context#checkSelfPermission(java.lang.String). - Future checkSelfPermission(String arg_instanceId, String arg_permission) async { + Future checkSelfPermission( + String arg_instanceId, String arg_permission) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.checkSelfPermission', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.checkSelfPermission', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_permission]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_permission]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -442,12 +463,15 @@ class ContextHostApi { /// Launch a new activity. /// /// See https://developer.android.com/reference/android/content/Context#startActivity(android.content.Intent). - Future startActivity(String arg_instanceId, String arg_intentInstanceId) async { + Future startActivity( + String arg_instanceId, String arg_intentInstanceId) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.startActivity', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.startActivity', + codec, binaryMessenger: _binaryMessenger); final List? replyList = - await channel.send([arg_instanceId, arg_intentInstanceId]) as List?; + await channel.send([arg_instanceId, arg_intentInstanceId]) + as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -469,7 +493,8 @@ class ContextHostApi { /// See https://developer.android.com/reference/android/content/Context#getPackageName(). Future getPackageName(String arg_instanceId) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageName', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageName', + codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_instanceId]) as List?; @@ -501,12 +526,14 @@ class ContextHostApi { /// Returns the instance ID of the service. /// /// See https://developer.android.com/reference/android/content/Context#getSystemService(java.lang.String). - Future getSystemService(String arg_instanceId, String arg_name) async { + Future getSystemService( + String arg_instanceId, String arg_name) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getSystemService', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getSystemService', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_name]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_name]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -545,17 +572,19 @@ abstract class ContextFlutterApi { /// Dispose of the Dart instance and remove it from the `InstanceManager`. void dispose(String instanceId); - static void setup(ContextFlutterApi? api, {BinaryMessenger? binaryMessenger}) { + static void setup(ContextFlutterApi? api, + {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextFlutterApi.create', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextFlutterApi.create', + codec, binaryMessenger: binaryMessenger); if (api == null) { channel.setMessageHandler(null); } else { channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ContextFlutterApi.create was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ContextFlutterApi.create was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -567,14 +596,15 @@ abstract class ContextFlutterApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextFlutterApi.dispose', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextFlutterApi.dispose', + codec, binaryMessenger: binaryMessenger); if (api == null) { channel.setMessageHandler(null); } else { channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ContextFlutterApi.dispose was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ContextFlutterApi.dispose was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -613,8 +643,8 @@ class UriHostApi { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.permission_handler_android.UriHostApi.parse', codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_uriString]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_uriString]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -641,7 +671,8 @@ class UriHostApi { /// See https://developer.android.com/reference/android/net/Uri#toString(). Future toStringAsync(String arg_instanceId) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.UriHostApi.toStringAsync', codec, + 'dev.flutter.pigeon.permission_handler_android.UriHostApi.toStringAsync', + codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_instanceId]) as List?; @@ -689,7 +720,8 @@ class IntentHostApi { /// See https://developer.android.com/reference/android/content/Intent#Intent(). Future create(String arg_instanceId) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.create', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.create', + codec, binaryMessenger: _binaryMessenger); final List? replyList = await channel.send([arg_instanceId]) as List?; @@ -714,10 +746,11 @@ class IntentHostApi { /// See https://developer.android.com/reference/android/content/Intent#setAction(java.lang.String). Future setAction(String arg_instanceId, String arg_action) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.setAction', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.setAction', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_action]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_action]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -739,10 +772,11 @@ class IntentHostApi { /// See https://developer.android.com/reference/android/content/Intent#setData(android.net.Uri). Future setData(String arg_instanceId, String arg_uriInstanceId) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.setData', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.setData', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_uriInstanceId]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_uriInstanceId]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -768,10 +802,11 @@ class IntentHostApi { /// See https://developer.android.com/reference/android/content/Intent#addCategory(java.lang.String). Future addCategory(String arg_instanceId, String arg_category) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.addCategory', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.addCategory', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_category]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_category]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -793,10 +828,11 @@ class IntentHostApi { /// See https://developer.android.com/reference/android/content/Intent#addFlags(int). Future addFlags(String arg_instanceId, int arg_flags) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.addFlags', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.addFlags', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_flags]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_flags]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -841,12 +877,14 @@ class PowerManagerHostApi { /// be applied. /// /// See https://developer.android.com/reference/android/os/PowerManager#isIgnoringBatteryOptimizations(java.lang.String). - Future isIgnoringBatteryOptimizations(String arg_instanceId, String arg_packageName) async { + Future isIgnoringBatteryOptimizations( + String arg_instanceId, String arg_packageName) async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.PowerManagerHostApi.isIgnoringBatteryOptimizations', codec, + 'dev.flutter.pigeon.permission_handler_android.PowerManagerHostApi.isIgnoringBatteryOptimizations', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([arg_instanceId, arg_packageName]) as List?; + final List? replyList = await channel + .send([arg_instanceId, arg_packageName]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -885,17 +923,19 @@ abstract class PowerManagerFlutterApi { /// Dispose of the Dart instance and remove it from the `InstanceManager`. void dispose(String instanceId); - static void setup(PowerManagerFlutterApi? api, {BinaryMessenger? binaryMessenger}) { + static void setup(PowerManagerFlutterApi? api, + {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.PowerManagerFlutterApi.create', codec, + 'dev.flutter.pigeon.permission_handler_android.PowerManagerFlutterApi.create', + codec, binaryMessenger: binaryMessenger); if (api == null) { channel.setMessageHandler(null); } else { channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.PowerManagerFlutterApi.create was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.PowerManagerFlutterApi.create was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -907,14 +947,15 @@ abstract class PowerManagerFlutterApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.PowerManagerFlutterApi.dispose', codec, + 'dev.flutter.pigeon.permission_handler_android.PowerManagerFlutterApi.dispose', + codec, binaryMessenger: binaryMessenger); if (api == null) { channel.setMessageHandler(null); } else { channel.setMessageHandler((Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.PowerManagerFlutterApi.dispose was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.PowerManagerFlutterApi.dispose was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -954,10 +995,10 @@ class BuildVersionHostApi { /// See https://developer.android.com/reference/android/os/Build.VERSION#SDK_INT. Future sdkInt() async { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.BuildVersionHostApi.sdkInt', codec, + 'dev.flutter.pigeon.permission_handler_android.BuildVersionHostApi.sdkInt', + codec, binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send(null) as List?; + final List? replyList = await channel.send(null) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', @@ -979,3 +1020,113 @@ class BuildVersionHostApi { } } } + +/// Host API for `AlarmManager`. +/// +/// This class may handle instantiating and adding native object instances that +/// are attached to a Dart instance or handle method calls on the associated +/// native class or an instance of the class. +/// +/// See https://developer.android.com/reference/android/app/AlarmManager. +class AlarmManagerHostApi { + /// Constructor for [AlarmManagerHostApi]. 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. + AlarmManagerHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = StandardMessageCodec(); + + /// Called to check if the application can schedule exact alarms. + /// + /// See https://developer.android.com/reference/android/app/AlarmManager#canScheduleExactAlarms(). + Future canScheduleExactAlarms(String arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.permission_handler_android.AlarmManagerHostApi.canScheduleExactAlarms', + codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_instanceId]) 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?)!; + } + } +} + +/// Flutter API for `AlarmManager`. +/// +/// This class may handle instantiating and adding Dart instances that are +/// attached to a native instance or receiving callback methods from an +/// overridden native class. +/// +/// See https://developer.android.com/reference/android/app/AlarmManager. +abstract class AlarmManagerFlutterApi { + static const MessageCodec codec = StandardMessageCodec(); + + /// Create a new Dart instance and add it to the `InstanceManager`. + void create(String instanceId); + + /// Dispose of the Dart instance and remove it from the `InstanceManager`. + void dispose(String instanceId); + + static void setup(AlarmManagerFlutterApi? api, + {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.permission_handler_android.AlarmManagerFlutterApi.create', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.permission_handler_android.AlarmManagerFlutterApi.create was null.'); + final List args = (message as List?)!; + final String? arg_instanceId = (args[0] as String?); + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.permission_handler_android.AlarmManagerFlutterApi.create was null, expected non-null String.'); + api.create(arg_instanceId!); + return; + }); + } + } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.permission_handler_android.AlarmManagerFlutterApi.dispose', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.permission_handler_android.AlarmManagerFlutterApi.dispose was null.'); + final List args = (message as List?)!; + final String? arg_instanceId = (args[0] as String?); + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.permission_handler_android.AlarmManagerFlutterApi.dispose was null, expected non-null String.'); + api.dispose(arg_instanceId!); + return; + }); + } + } + } +} diff --git a/permission_handler_android/pigeons/android_permission_handler.dart b/permission_handler_android/pigeons/android_permission_handler.dart index fda46cac0..ee38f13ec 100644 --- a/permission_handler_android/pigeons/android_permission_handler.dart +++ b/permission_handler_android/pigeons/android_permission_handler.dart @@ -345,3 +345,34 @@ abstract class BuildVersionHostApi { /// See https://developer.android.com/reference/android/os/Build.VERSION#SDK_INT. int sdkInt(); } + +/// Host API for `AlarmManager`. +/// +/// This class may handle instantiating and adding native object instances that +/// are attached to a Dart instance or handle method calls on the associated +/// native class or an instance of the class. +/// +/// See https://developer.android.com/reference/android/app/AlarmManager. +@HostApi(dartHostTestHandler: 'AlarmManagerTestHostApi') +abstract class AlarmManagerHostApi { + /// Called to check if the application can schedule exact alarms. + /// + /// See https://developer.android.com/reference/android/app/AlarmManager#canScheduleExactAlarms(). + bool canScheduleExactAlarms(String instanceId); +} + +/// Flutter API for `AlarmManager`. +/// +/// This class may handle instantiating and adding Dart instances that are +/// attached to a native instance or receiving callback methods from an +/// overridden native class. +/// +/// See https://developer.android.com/reference/android/app/AlarmManager. +@FlutterApi() +abstract class AlarmManagerFlutterApi { + /// Create a new Dart instance and add it to the `InstanceManager`. + void create(String instanceId); + + /// Dispose of the Dart instance and remove it from the `InstanceManager`. + void dispose(String instanceId); +} diff --git a/permission_handler_android/test/test_permission_handler.pigeon.dart b/permission_handler_android/test/test_permission_handler.pigeon.dart index 6749de231..451e85149 100644 --- a/permission_handler_android/test/test_permission_handler.pigeon.dart +++ b/permission_handler_android/test/test_permission_handler.pigeon.dart @@ -28,9 +28,9 @@ class _ActivityTestHostApiCodec extends StandardMessageCodec { @override Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { - case 128: + case 128: return ActivityResultPigeon.decode(readValue(buffer)!); - case 129: + case 129: return PermissionRequestResult.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -46,13 +46,15 @@ class _ActivityTestHostApiCodec extends StandardMessageCodec { /// /// See https://developer.android.com/reference/android/app/Activity. abstract class ActivityTestHostApi { - static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = _ActivityTestHostApiCodec(); /// Gets whether the application should show UI with rationale before requesting a permission. /// /// See https://developer.android.com/reference/android/app/Activity#shouldShowRequestPermissionRationale(java.lang.String). - bool shouldShowRequestPermissionRationale(String instanceId, String permission); + bool shouldShowRequestPermissionRationale( + String instanceId, String permission); /// Determine whether the application has been granted a particular permission. /// @@ -65,7 +67,8 @@ abstract class ActivityTestHostApi { /// https://developer.android.com/reference/android/app/Activity#requestPermissions(java.lang.String[],%20int) /// and /// https://developer.android.com/reference/android/app/Activity#onRequestPermissionsResult(int,%20java.lang.String[],%20int[]). - Future requestPermissions(String instanceId, List permissions, int? requestCode); + Future requestPermissions( + String instanceId, List permissions, int? requestCode); /// Launch a new activity. /// @@ -89,19 +92,25 @@ abstract class ActivityTestHostApi { /// Start an activity for which the application would like a result when it finished. /// /// See https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int). - Future startActivityForResult(String instanceId, String intentInstanceId, int? requestCode); + Future startActivityForResult( + String instanceId, String intentInstanceId, int? requestCode); - static void setup(ActivityTestHostApi? api, {BinaryMessenger? binaryMessenger}) { + static void setup(ActivityTestHostApi? api, + {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.shouldShowRequestPermissionRationale', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.shouldShowRequestPermissionRationale', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.shouldShowRequestPermissionRationale was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.shouldShowRequestPermissionRationale was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -109,21 +118,26 @@ abstract class ActivityTestHostApi { final String? arg_permission = (args[1] as String?); assert(arg_permission != null, 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.shouldShowRequestPermissionRationale was null, expected non-null String.'); - final bool output = api.shouldShowRequestPermissionRationale(arg_instanceId!, arg_permission!); + final bool output = api.shouldShowRequestPermissionRationale( + arg_instanceId!, arg_permission!); return [output]; }); } } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.checkSelfPermission', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.checkSelfPermission', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.checkSelfPermission was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.checkSelfPermission was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -131,44 +145,55 @@ abstract class ActivityTestHostApi { final String? arg_permission = (args[1] as String?); assert(arg_permission != null, 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.checkSelfPermission was null, expected non-null String.'); - final int output = api.checkSelfPermission(arg_instanceId!, arg_permission!); + final int output = + api.checkSelfPermission(arg_instanceId!, arg_permission!); return [output]; }); } } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.requestPermissions', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.requestPermissions', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.requestPermissions was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.requestPermissions was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.requestPermissions was null, expected non-null String.'); - final List? arg_permissions = (args[1] as List?)?.cast(); + final List? arg_permissions = + (args[1] as List?)?.cast(); assert(arg_permissions != null, 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.requestPermissions was null, expected non-null List.'); final int? arg_requestCode = (args[2] as int?); - final PermissionRequestResult output = await api.requestPermissions(arg_instanceId!, arg_permissions!, arg_requestCode); + final PermissionRequestResult output = await api.requestPermissions( + arg_instanceId!, arg_permissions!, arg_requestCode); return [output]; }); } } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivity', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivity', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivity was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivity was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -183,14 +208,18 @@ abstract class ActivityTestHostApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageName', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageName', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageName was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageName was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -202,14 +231,18 @@ abstract class ActivityTestHostApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getSystemService', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getSystemService', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getSystemService was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getSystemService was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -217,21 +250,26 @@ abstract class ActivityTestHostApi { final String? arg_name = (args[1] as String?); assert(arg_name != null, 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getSystemService was null, expected non-null String.'); - final String output = api.getSystemService(arg_instanceId!, arg_name!); + final String output = + api.getSystemService(arg_instanceId!, arg_name!); return [output]; }); } } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivityForResult', codec, + 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivityForResult', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivityForResult was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivityForResult was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -240,7 +278,8 @@ abstract class ActivityTestHostApi { assert(arg_intentInstanceId != null, 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.startActivityForResult was null, expected non-null String.'); final int? arg_requestCode = (args[2] as int?); - final ActivityResultPigeon output = await api.startActivityForResult(arg_instanceId!, arg_intentInstanceId!, arg_requestCode); + final ActivityResultPigeon output = await api.startActivityForResult( + arg_instanceId!, arg_intentInstanceId!, arg_requestCode); return [output]; }); } @@ -256,7 +295,8 @@ abstract class ActivityTestHostApi { /// /// See https://developer.android.com/reference/android/content/Context. abstract class ContextTestHostApi { - static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); /// Determine whether the application has been granted a particular permission. @@ -283,17 +323,22 @@ abstract class ContextTestHostApi { /// See https://developer.android.com/reference/android/content/Context#getSystemService(java.lang.String). String getSystemService(String instanceId, String name); - static void setup(ContextTestHostApi? api, {BinaryMessenger? binaryMessenger}) { + static void setup(ContextTestHostApi? api, + {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.checkSelfPermission', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.checkSelfPermission', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.checkSelfPermission was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.checkSelfPermission was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -301,21 +346,26 @@ abstract class ContextTestHostApi { final String? arg_permission = (args[1] as String?); assert(arg_permission != null, 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.checkSelfPermission was null, expected non-null String.'); - final int output = api.checkSelfPermission(arg_instanceId!, arg_permission!); + final int output = + api.checkSelfPermission(arg_instanceId!, arg_permission!); return [output]; }); } } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.startActivity', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.startActivity', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.startActivity was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.startActivity was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -330,14 +380,18 @@ abstract class ContextTestHostApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageName', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageName', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageName was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageName was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -349,14 +403,18 @@ abstract class ContextTestHostApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getSystemService', codec, + 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getSystemService', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.getSystemService was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.getSystemService was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -364,7 +422,8 @@ abstract class ContextTestHostApi { final String? arg_name = (args[1] as String?); assert(arg_name != null, 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.getSystemService was null, expected non-null String.'); - final String output = api.getSystemService(arg_instanceId!, arg_name!); + final String output = + api.getSystemService(arg_instanceId!, arg_name!); return [output]; }); } @@ -380,7 +439,8 @@ abstract class ContextTestHostApi { /// /// See https://developer.android.com/reference/android/net/Uri. abstract class UriTestHostApi { - static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); /// Creates a Uri which parses the given encoded URI string. @@ -403,14 +463,18 @@ abstract class UriTestHostApi { static void setup(UriTestHostApi? api, {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.UriHostApi.parse', codec, + 'dev.flutter.pigeon.permission_handler_android.UriHostApi.parse', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.UriHostApi.parse was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.UriHostApi.parse was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -425,14 +489,18 @@ abstract class UriTestHostApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.UriHostApi.toStringAsync', codec, + 'dev.flutter.pigeon.permission_handler_android.UriHostApi.toStringAsync', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.UriHostApi.toStringAsync was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.UriHostApi.toStringAsync was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -453,7 +521,8 @@ abstract class UriTestHostApi { /// /// See https://developer.android.com/reference/android/content/Intent. abstract class IntentTestHostApi { - static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); /// Creates an empty intent. @@ -485,17 +554,22 @@ abstract class IntentTestHostApi { /// See https://developer.android.com/reference/android/content/Intent#addFlags(int). void addFlags(String instanceId, int flags); - static void setup(IntentTestHostApi? api, {BinaryMessenger? binaryMessenger}) { + static void setup(IntentTestHostApi? api, + {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.create', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.create', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.create was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.create was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -507,14 +581,18 @@ abstract class IntentTestHostApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.setAction', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.setAction', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.setAction was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.setAction was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -529,14 +607,18 @@ abstract class IntentTestHostApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.setData', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.setData', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.setData was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.setData was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -551,14 +633,18 @@ abstract class IntentTestHostApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.addCategory', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.addCategory', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.addCategory was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.addCategory was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -573,14 +659,18 @@ abstract class IntentTestHostApi { } { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.addFlags', codec, + 'dev.flutter.pigeon.permission_handler_android.IntentHostApi.addFlags', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.addFlags was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.IntentHostApi.addFlags was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -604,7 +694,8 @@ abstract class IntentTestHostApi { /// /// See https://developer.android.com/reference/android/os/PowerManager. abstract class PowerManagerTestHostApi { - static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); /// Returns whether the given application package name is on the device's power allowlist. @@ -619,17 +710,22 @@ abstract class PowerManagerTestHostApi { /// See https://developer.android.com/reference/android/os/PowerManager#isIgnoringBatteryOptimizations(java.lang.String). bool isIgnoringBatteryOptimizations(String instanceId, String packageName); - static void setup(PowerManagerTestHostApi? api, {BinaryMessenger? binaryMessenger}) { + static void setup(PowerManagerTestHostApi? api, + {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.PowerManagerHostApi.isIgnoringBatteryOptimizations', codec, + 'dev.flutter.pigeon.permission_handler_android.PowerManagerHostApi.isIgnoringBatteryOptimizations', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, - 'Argument for dev.flutter.pigeon.permission_handler_android.PowerManagerHostApi.isIgnoringBatteryOptimizations was null.'); + 'Argument for dev.flutter.pigeon.permission_handler_android.PowerManagerHostApi.isIgnoringBatteryOptimizations was null.'); final List args = (message as List?)!; final String? arg_instanceId = (args[0] as String?); assert(arg_instanceId != null, @@ -637,7 +733,8 @@ abstract class PowerManagerTestHostApi { final String? arg_packageName = (args[1] as String?); assert(arg_packageName != null, 'Argument for dev.flutter.pigeon.permission_handler_android.PowerManagerHostApi.isIgnoringBatteryOptimizations was null, expected non-null String.'); - final bool output = api.isIgnoringBatteryOptimizations(arg_instanceId!, arg_packageName!); + final bool output = api.isIgnoringBatteryOptimizations( + arg_instanceId!, arg_packageName!); return [output]; }); } @@ -653,7 +750,8 @@ abstract class PowerManagerTestHostApi { /// /// See https://developer.android.com/reference/android/os/Build.VERSION. abstract class BuildVersionTestHostApi { - static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance; + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); /// The SDK version of the software currently running on this hardware device. @@ -666,15 +764,20 @@ abstract class BuildVersionTestHostApi { /// See https://developer.android.com/reference/android/os/Build.VERSION#SDK_INT. int sdkInt(); - static void setup(BuildVersionTestHostApi? api, {BinaryMessenger? binaryMessenger}) { + static void setup(BuildVersionTestHostApi? api, + {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.permission_handler_android.BuildVersionHostApi.sdkInt', codec, + 'dev.flutter.pigeon.permission_handler_android.BuildVersionHostApi.sdkInt', + codec, binaryMessenger: binaryMessenger); if (api == null) { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - _testBinaryMessengerBinding!.defaultBinaryMessenger.setMockDecodedMessageHandler(channel, (Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { // ignore message final int output = api.sdkInt(); return [output]; @@ -683,3 +786,48 @@ abstract class BuildVersionTestHostApi { } } } + +/// Host API for `AlarmManager`. +/// +/// This class may handle instantiating and adding native object instances that +/// are attached to a Dart instance or handle method calls on the associated +/// native class or an instance of the class. +/// +/// See https://developer.android.com/reference/android/app/AlarmManager. +abstract class AlarmManagerTestHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; + static const MessageCodec codec = StandardMessageCodec(); + + /// Called to check if the application can schedule exact alarms. + /// + /// See https://developer.android.com/reference/android/app/AlarmManager#canScheduleExactAlarms(). + bool canScheduleExactAlarms(String instanceId); + + static void setup(AlarmManagerTestHostApi? api, + {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.permission_handler_android.AlarmManagerHostApi.canScheduleExactAlarms', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.permission_handler_android.AlarmManagerHostApi.canScheduleExactAlarms was null.'); + final List args = (message as List?)!; + final String? arg_instanceId = (args[0] as String?); + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.permission_handler_android.AlarmManagerHostApi.canScheduleExactAlarms was null, expected non-null String.'); + final bool output = api.canScheduleExactAlarms(arg_instanceId!); + return [output]; + }); + } + } + } +}