Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,25 @@
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import com.onesignal.debug.internal.logging.Logging;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

abstract class FlutterMessengerResponder {
private static final ExecutorService BACKGROUND_EXECUTOR = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable, "OneSignalFlutterBg");
thread.setDaemon(true);
return thread;
}
});

Context context;
protected MethodChannel channel;
BinaryMessenger messenger;
Expand Down Expand Up @@ -104,6 +117,20 @@ private void runOnMainThread(final Runnable runnable) {
}
}

void runOnBackgroundThread(final MethodChannel.Result result, final Runnable runnable) {
BACKGROUND_EXECUTOR.execute(new Runnable() {
@Override
public void run() {
try {
runnable.run();
} catch (Exception e) {
Logging.error("Encountered an error while handling a Flutter method call: " + e.toString(), e);
replyError(result, "OneSignal", e.getMessage(), null);
}
}
});
}

void invokeMethodOnUiThread(final String methodName, final HashMap map) {
// final MethodChannel channel = this.channel;
runOnMainThread(new Runnable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,16 @@ void onAttachedToActivity(BinaryMessenger activityMessenger) {
}

@Override
public void onMethodCall(MethodCall call, Result result) {
public void onMethodCall(final MethodCall call, final Result result) {
runOnBackgroundThread(result, new Runnable() {
@Override
public void run() {
handleMethodCall(call, result);
}
});
}

private void handleMethodCall(MethodCall call, Result result) {
if (call.method.contentEquals("OneSignal#addTrigger")) this.addTriggers(call, result);
else if (call.method.contentEquals("OneSignal#addTriggers")) this.addTriggers(call, result);
else if (call.method.contentEquals("OneSignal#removeTrigger")) this.removeTrigger(call, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ static void registerWith(BinaryMessenger messenger) {
}

@Override
public void onMethodCall(MethodCall call, Result result) {
public void onMethodCall(final MethodCall call, final Result result) {
runOnBackgroundThread(result, new Runnable() {
@Override
public void run() {
handleMethodCall(call, result);
}
});
}

private void handleMethodCall(MethodCall call, Result result) {
if (call.method.contentEquals("OneSignal#requestPermission")) this.requestPermission(result);
else if (call.method.contentEquals("OneSignal#setShared")) this.setShared(call, result);
else if (call.method.contentEquals("OneSignal#isShared"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.flutter.plugin.common.MethodChannel.Result;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import kotlin.coroutines.Continuation;
import kotlin.coroutines.CoroutineContext;
import kotlinx.coroutines.Dispatchers;
Expand All @@ -26,12 +27,13 @@ public class OneSignalNotifications extends FlutterMessengerResponder
implements MethodCallHandler, INotificationClickListener, INotificationLifecycleListener, IPermissionObserver {
private static OneSignalNotifications sharedInstance;

private final HashMap<String, INotificationWillDisplayEvent> notificationOnWillDisplayEventCache = new HashMap<>();
private final HashMap<String, INotificationWillDisplayEvent> preventedDefaultCache = new HashMap<>();
private final Map<String, INotificationWillDisplayEvent> notificationOnWillDisplayEventCache =
new ConcurrentHashMap<>();
private final Map<String, INotificationWillDisplayEvent> preventedDefaultCache = new ConcurrentHashMap<>();

// #1138: tracks if Dart requested clicks, so we can queue (not drop) them
// while the channel is detached across engine/activity lifecycles.
private boolean clickListenerRequested = false;
private volatile boolean clickListenerRequested = false;

public static OneSignalNotifications getSharedInstance() {
if (sharedInstance == null) {
Expand Down Expand Up @@ -81,7 +83,23 @@ static void registerWith(BinaryMessenger messenger) {
}

@Override
public void onMethodCall(MethodCall call, Result result) {
public void onMethodCall(final MethodCall call, final Result result) {
// These paths only use cached foreground events and must not wait behind
// SDK calls that can block during initialization.
if (call.method.contentEquals("OneSignal#displayNotification")) this.displayNotification(call, result);
Comment thread
fadi-george marked this conversation as resolved.
else if (call.method.contentEquals("OneSignal#preventDefault")) this.preventDefault(call, result);
else if (call.method.contentEquals("OneSignal#proceedWithWillDisplay"))
this.proceedWithWillDisplay(call, result);
else
runOnBackgroundThread(result, new Runnable() {
@Override
public void run() {
handleMethodCall(call, result);
}
});
}

private void handleMethodCall(MethodCall call, Result result) {
if (call.method.contentEquals("OneSignal#permission"))
replySuccess(result, OneSignal.getNotifications().getPermission());
else if (call.method.contentEquals("OneSignal#canRequest"))
Expand All @@ -91,11 +109,7 @@ else if (call.method.contentEquals("OneSignal#canRequest"))
else if (call.method.contentEquals("OneSignal#removeGroupedNotifications"))
this.removeGroupedNotifications(call, result);
else if (call.method.contentEquals("OneSignal#clearAll")) this.clearAll(call, result);
else if (call.method.contentEquals("OneSignal#displayNotification")) this.displayNotification(call, result);
else if (call.method.contentEquals("OneSignal#preventDefault")) this.preventDefault(call, result);
else if (call.method.contentEquals("OneSignal#lifecycleInit")) this.lifecycleInit(result);
else if (call.method.contentEquals("OneSignal#proceedWithWillDisplay"))
this.proceedWithWillDisplay(call, result);
else if (call.method.contentEquals("OneSignal#addNativeClickListener")) this.registerClickListener();
else replyNotImplemented(result);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,16 @@ public void onDetachedFromActivityForConfigChanges() {
}

@Override
public void onMethodCall(MethodCall call, Result result) {
public void onMethodCall(final MethodCall call, final Result result) {
runOnBackgroundThread(result, new Runnable() {
@Override
public void run() {
handleMethodCall(call, result);
}
});
}

private void handleMethodCall(MethodCall call, Result result) {
if (call.method.contentEquals("OneSignal#initialize")) this.initWithContext(call, result);
else if (call.method.contentEquals("OneSignal#consentRequired")) this.setConsentRequired(call, result);
else if (call.method.contentEquals("OneSignal#consentGiven")) this.setConsentGiven(call, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,16 @@ void onAttachedToActivity(BinaryMessenger activityMessenger) {
}

@Override
public void onMethodCall(MethodCall call, Result result) {
public void onMethodCall(final MethodCall call, final Result result) {
runOnBackgroundThread(result, new Runnable() {
@Override
public void run() {
handleMethodCall(call, result);
}
});
}

private void handleMethodCall(MethodCall call, Result result) {
if (call.method.contentEquals("OneSignal#optIn")) this.optIn(call, result);
else if (call.method.contentEquals("OneSignal#optOut")) this.optOut(call, result);
else if (call.method.contentEquals("OneSignal#pushSubscriptionId"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,16 @@ static void registerWith(BinaryMessenger messenger) {
}

@Override
public void onMethodCall(MethodCall call, Result result) {
public void onMethodCall(final MethodCall call, final Result result) {
runOnBackgroundThread(result, new Runnable() {
@Override
public void run() {
handleMethodCall(call, result);
}
});
}

private void handleMethodCall(MethodCall call, Result result) {
if (call.method.contentEquals("OneSignal#addOutcome")) this.addOutcome(call, result);
else if (call.method.contentEquals("OneSignal#addUniqueOutcome")) this.addUniqueOutcome(call, result);
else if (call.method.contentEquals("OneSignal#addOutcomeWithValue")) this.addOutcomeWithValue(call, result);
Expand Down
11 changes: 10 additions & 1 deletion android/src/main/java/com/onesignal/flutter/OneSignalUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,16 @@ void onAttachedToActivity(BinaryMessenger activityMessenger) {
}

@Override
public void onMethodCall(MethodCall call, Result result) {
public void onMethodCall(final MethodCall call, final Result result) {
runOnBackgroundThread(result, new Runnable() {
@Override
public void run() {
handleMethodCall(call, result);
}
});
}

private void handleMethodCall(MethodCall call, Result result) {
if (call.method.contentEquals("OneSignal#setLanguage")) this.setLanguage(call, result);
else if (call.method.contentEquals("OneSignal#getOnesignalId")) this.getOnesignalId(call, result);
else if (call.method.contentEquals("OneSignal#getExternalId")) this.getExternalId(call, result);
Expand Down
4 changes: 4 additions & 0 deletions examples/demo/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false
2 changes: 0 additions & 2 deletions examples/demo/ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,5 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>13.0</string>
</dict>
</plist>
7 changes: 5 additions & 2 deletions examples/demo/ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import Flutter
import UIKit

@main
@objc class AppDelegate: FlutterAppDelegate {
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
}
}
29 changes: 25 additions & 4 deletions examples/demo/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,33 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSSupportsLiveActivities</key>
<true/>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app uses your location to personalize notifications and content.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app uses your location to personalize notifications and content, even in the background.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app uses your location to personalize notifications and content.</string>
<key>NSSupportsLiveActivities</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneConfigurationName</key>
<string>flutter</string>
<key>UISceneDelegateClassName</key>
<string>FlutterSceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
Expand Down
3 changes: 2 additions & 1 deletion examples/demo/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ Future<void> main() async {
debugPrint(
'Notification foreground will display: ${event.notification.title}',
);
event.notification.display();
// event.preventDefault(); // This will prevent the notification from being displayed
// event.notification.display(); // This will override the preventDefault and display the notification
});

// Set up API service
Expand Down
Loading