Skip to content

Commit

Permalink
Port NotificationManager (#1217)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeroenWeener authored Nov 10, 2023
1 parent d955c86 commit 05f587a
Show file tree
Hide file tree
Showing 15 changed files with 718 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.baseflow.permissionhandler;

import android.app.AlarmManager;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
Expand Down Expand Up @@ -35,6 +36,8 @@ public class ContextHostApiImpl implements ContextHostApi {

private final PackageManagerFlutterApiImpl packageManagerFlutterApi;

private final NotificationManagerFlutterApiImpl notificationManagerFlutterApi;

/**
* Constructs an {@link ContextHostApiImpl}.
*
Expand All @@ -45,12 +48,14 @@ public ContextHostApiImpl(
@NonNull PowerManagerFlutterApiImpl powerManagerFlutterApi,
@NonNull AlarmManagerFlutterApiImpl alarmManagerFlutterApi,
@NonNull PackageManagerFlutterApiImpl packageManagerFlutterApi,
@NonNull NotificationManagerFlutterApiImpl notificationManagerFlutterApi,
@NonNull BinaryMessenger binaryMessenger,
@NonNull InstanceManager instanceManager
) {
this.powerManagerFlutterApi = powerManagerFlutterApi;
this.alarmManagerFlutterApi = alarmManagerFlutterApi;
this.packageManagerFlutterApi = packageManagerFlutterApi;
this.notificationManagerFlutterApi = notificationManagerFlutterApi;
this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
}
Expand Down Expand Up @@ -104,6 +109,8 @@ public void startActivity(
powerManagerFlutterApi.create((PowerManager) systemService);
} else if (systemService instanceof AlarmManager) {
alarmManagerFlutterApi.create((AlarmManager) systemService);
} else if (systemService instanceof NotificationManager) {
notificationManagerFlutterApi.create((NotificationManager) systemService);
}

final UUID systemServiceUuid = instanceManager.getIdentifierForStrongReference(systemService);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.baseflow.permissionhandler;

import android.app.NotificationManager;

import androidx.annotation.NonNull;

import com.baseflow.instancemanager.InstanceManager;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.NotificationManagerFlutterApi;

import java.util.UUID;

import io.flutter.plugin.common.BinaryMessenger;

/**
* Flutter API implementation for `NotificationManager`.
*
* <p>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 NotificationManagerFlutterApiImpl {
// To ease adding additional methods, this value is added prematurely.
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final BinaryMessenger binaryMessenger;

private final InstanceManager instanceManager;

private final NotificationManagerFlutterApi api;

/**
* Constructs a {@link NotificationManagerFlutterApiImpl}.
*
* @param binaryMessenger used to communicate with Dart over asynchronous messages
* @param instanceManager maintains instances stored to communicate with attached Dart objects
*/
public NotificationManagerFlutterApiImpl(
@NonNull BinaryMessenger binaryMessenger,
@NonNull InstanceManager instanceManager
) {
this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
api = new NotificationManagerFlutterApi(binaryMessenger);
}

/**
* Stores the `NotificationManager` instance and notifies Dart to create and store a new `NotificationManager`
* instance that is attached to this one. If `instance` has already been added, this method does
* nothing.
*/
public void create(@NonNull NotificationManager instance) {
if (!instanceManager.containsInstance(instance)) {
final UUID notificationManagerInstanceUuid = instanceManager.addHostCreatedInstance(instance);
api.create(notificationManagerInstanceUuid.toString(), reply -> {});
}
}

/**
* Disposes of the `NotificationManager` instance in the instance manager and notifies Dart to do the
* same. If `instance` was already disposed, this method does nothing.
*/
public void dispose(NotificationManager instance) {
final UUID notificationManagerInstanceUuid = instanceManager.getIdentifierForStrongReference(instance);
if (notificationManagerInstanceUuid != null) {
api.dispose(notificationManagerInstanceUuid.toString(), reply -> {});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.baseflow.permissionhandler;

import android.app.NotificationManager;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationManagerCompat;

import com.baseflow.instancemanager.InstanceManager;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.NotificationManagerHostApi;

import java.util.UUID;

import io.flutter.plugin.common.BinaryMessenger;

/**
* Host API implementation for `NotificationManager`.
*
* <p>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 NotificationManagerHostApiImpl implements NotificationManagerHostApi {
// To ease adding additional methods, this value is added prematurely.
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final BinaryMessenger binaryMessenger;

private final InstanceManager instanceManager;

/**
* Constructs an {@link NotificationManagerHostApiImpl}.
*
* @param binaryMessenger used to communicate with Dart over asynchronous messages
* @param instanceManager maintains instances stored to communicate with attached Dart objects
*/
public NotificationManagerHostApiImpl(
@NonNull BinaryMessenger binaryMessenger,
@NonNull InstanceManager instanceManager
) {
this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
}

@RequiresApi(api = Build.VERSION_CODES.M)
@NonNull
@Override
public Boolean isNotificationPolicyAccessGranted(
@NonNull String instanceId
) {
final UUID instanceUuid = UUID.fromString(instanceId);
final NotificationManager notificationManager = instanceManager.getInstance(instanceUuid);

return notificationManager.isNotificationPolicyAccessGranted();
}

@RequiresApi(api = Build.VERSION_CODES.N)
@NonNull
@Override
public Boolean areNotificationsEnabled(
@NonNull String instanceId
) {
final UUID instanceUuid = UUID.fromString(instanceId);
final NotificationManager notificationManager = instanceManager.getInstance(instanceUuid);

return notificationManager.areNotificationsEnabled();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,7 @@ public void dispose(@NonNull String instanceIdArg, @NonNull Reply<Void> callback
* 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/kotlin/android/content/pm/PackageManager.
* See https://developer.android.com/reference/android/content/pm/PackageManager.
*
* Generated interface from Pigeon that represents a handler of messages from Flutter.
*/
Expand Down Expand Up @@ -1283,7 +1283,7 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PackageMan
* attached to a native instance or receiving callback methods from an
* overridden native class.
*
* See https://developer.android.com/reference/kotlin/android/content/pm/PackageManager.
* See https://developer.android.com/reference/android/content/pm/PackageManager.
*
* Generated class from Pigeon that represents Flutter messages that can be called from Java.
*/
Expand Down Expand Up @@ -1329,7 +1329,7 @@ public void dispose(@NonNull String instanceIdArg, @NonNull Reply<Void> callback
* 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/kotlin/android/provider/Settings.
* See https://developer.android.com/reference/android/provider/Settings.
*
* Generated interface from Pigeon that represents a handler of messages from Flutter.
*/
Expand Down Expand Up @@ -1381,4 +1381,139 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable SettingsHo
}
}
}
/**
* Host API for `NotificationManager`.
*
* 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/NotificationManager.
*
* Generated interface from Pigeon that represents a handler of messages from Flutter.
*/
public interface NotificationManagerHostApi {
/**
* Checks the ability to modify notification do not disturb policy for the calling package.
*
* Returns true if the calling package can modify notification policy.
*
* Apps can request policy access by sending the user to the activity that
* matches the system intent action
* [Settings.actionNotificationPolicyAccessSettings].
*
* See https://developer.android.com/reference/android/app/NotificationManager#isNotificationPolicyAccessGranted().
*/
@NonNull
Boolean isNotificationPolicyAccessGranted(@NonNull String instanceId);
/**
* Returns whether notifications from the calling package are enabled.
*
* See https://developer.android.com/reference/android/app/NotificationManager#areNotificationsEnabled().
*/
@NonNull
Boolean areNotificationsEnabled(@NonNull String instanceId);

/** The codec used by NotificationManagerHostApi. */
static @NonNull MessageCodec<Object> getCodec() {
return new StandardMessageCodec();
}
/**Sets up an instance of `NotificationManagerHostApi` to handle messages through the `binaryMessenger`. */
static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable NotificationManagerHostApi api) {
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.permission_handler_android.NotificationManagerHostApi.isNotificationPolicyAccessGranted", getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
ArrayList<Object> args = (ArrayList<Object>) message;
String instanceIdArg = (String) args.get(0);
try {
Boolean output = api.isNotificationPolicyAccessGranted(instanceIdArg);
wrapped.add(0, output);
}
catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.permission_handler_android.NotificationManagerHostApi.areNotificationsEnabled", getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
ArrayList<Object> args = (ArrayList<Object>) message;
String instanceIdArg = (String) args.get(0);
try {
Boolean output = api.areNotificationsEnabled(instanceIdArg);
wrapped.add(0, output);
}
catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
}
}
/**
* Flutter API for `NotificationManager`.
*
* 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/NotificationManager.
*
* Generated class from Pigeon that represents Flutter messages that can be called from Java.
*/
public static class NotificationManagerFlutterApi {
private final @NonNull BinaryMessenger binaryMessenger;

public NotificationManagerFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) {
this.binaryMessenger = argBinaryMessenger;
}

/** Public interface for sending reply. */
@SuppressWarnings("UnknownNullness")
public interface Reply<T> {
void reply(T reply);
}
/** The codec used by NotificationManagerFlutterApi. */
static @NonNull MessageCodec<Object> getCodec() {
return new StandardMessageCodec();
}
/** Create a new Dart instance and add it to the `InstanceManager`. */
public void create(@NonNull String instanceIdArg, @NonNull Reply<Void> callback) {
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.permission_handler_android.NotificationManagerFlutterApi.create", getCodec());
channel.send(
new ArrayList<Object>(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<Void> callback) {
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.permission_handler_android.NotificationManagerFlutterApi.dispose", getCodec());
channel.send(
new ArrayList<Object>(Collections.singletonList(instanceIdArg)),
channelReply -> callback.reply(null));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.baseflow.permissionhandler.PermissionHandlerPigeon.BuildVersionHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.ContextHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.IntentHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.NotificationManagerHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.PackageManagerHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.PowerManagerHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.SettingsHostApi;
Expand Down Expand Up @@ -76,6 +77,10 @@ private void setUp(
final SettingsHostApi settingsHostApi = new SettingsHostApiImpl(binaryMessenger, instanceManager);
SettingsHostApi.setup(binaryMessenger, settingsHostApi);

final NotificationManagerFlutterApiImpl notificationManagerFlutterApi = new NotificationManagerFlutterApiImpl(binaryMessenger, instanceManager);
final NotificationManagerHostApi notificationManagerHostApi = new NotificationManagerHostApiImpl(binaryMessenger, instanceManager);
NotificationManagerHostApi.setup(binaryMessenger, notificationManagerHostApi);

activityFlutterApi = new ActivityFlutterApiImpl(binaryMessenger, instanceManager);
activityHostApi = new ActivityHostApiImpl(
binaryMessenger,
Expand All @@ -88,6 +93,7 @@ private void setUp(
powerManagerFlutterApi,
alarmManagerFlutterApi,
packageManagerFlutterApi,
notificationManagerFlutterApi,
binaryMessenger,
instanceManager
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export 'src/android_object_mirrors/build.dart';
export 'src/android_object_mirrors/context.dart';
export 'src/android_object_mirrors/intent.dart';
export 'src/android_object_mirrors/manifest.dart';
export 'src/android_object_mirrors/notification_manager.dart';
export 'src/android_object_mirrors/package_manager.dart';
export 'src/android_object_mirrors/power_manager.dart';
export 'src/android_object_mirrors/settings.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ class Activity extends Context {
/// See https://developer.android.com/reference/android/content/Context.html#ALARM_SERVICE.
static const String alarmService = 'alarm';

/// Use with [Context.getSystemService] to retrieve a [NotificationManager]
/// for informing the user of background events.
///
/// Copy of [Context.notificationService], as static fields are not inherited
/// in Dart.
///
/// See https://developer.android.com/reference/android/content/Context.html#NOTIFICATION_SERVICE.
static const String notificationService = 'notification';

/// Standard activity result: operation succeeded.
///
/// Constant Value: -1 (0xffffffff).
Expand Down
Loading

0 comments on commit 05f587a

Please sign in to comment.