@imatis/react-native-notifications 4.1.2-imatis.7 → 4.2.4-imatis.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.buildkite/pipeline.yaml +39 -0
- package/.nvmrc +1 -0
- package/CHANGELOG.gren.md +384 -317
- package/CODEOWNERS +1 -1
- package/lib/android/.gradle/6.1.1/executionHistory/executionHistory.bin +0 -0
- package/lib/android/.gradle/6.1.1/executionHistory/executionHistory.lock +0 -0
- package/lib/android/.gradle/6.1.1/fileContent/fileContent.lock +0 -0
- package/lib/android/.gradle/6.1.1/fileHashes/fileHashes.bin +0 -0
- package/lib/android/.gradle/6.1.1/fileHashes/fileHashes.lock +0 -0
- package/lib/android/.gradle/6.1.1/fileHashes/resourceHashesCache.bin +0 -0
- package/lib/android/.gradle/6.1.1/javaCompile/classAnalysis.bin +0 -0
- package/lib/android/.gradle/6.1.1/javaCompile/jarAnalysis.bin +0 -0
- package/lib/android/.gradle/6.1.1/javaCompile/javaCompile.lock +0 -0
- package/lib/android/.gradle/6.1.1/javaCompile/taskHistory.bin +0 -0
- package/lib/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/lib/android/.gradle/buildOutputCleanup/cache.properties +1 -1
- package/lib/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
- package/lib/android/.gradle/checksums/checksums.lock +0 -0
- package/lib/android/.gradle/checksums/md5-checksums.bin +0 -0
- package/lib/android/.gradle/checksums/sha1-checksums.bin +0 -0
- package/lib/android/app/build.gradle +3 -5
- package/lib/android/app/src/main/AndroidManifest.xml +2 -1
- package/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java +17 -14
- package/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java +21 -7
- package/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java +54 -24
- package/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotificationProps.java +24 -0
- package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/AppLaunchHelperTest.java +117 -0
- package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/InitialNotificationHolderTest.java +59 -0
- package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/JsIOHelperTest.java +60 -0
- package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/notification/PushNotificationTest.java +381 -0
- package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/notificationdrawer/PushNotificationsDrawerTest.java +96 -0
- package/lib/android/app/src/test/resources/robolectric.properties +1 -0
- package/lib/android/build.gradle +1 -1
- package/lib/android/local.properties +2 -2
- package/lib/dist/commands/Commands.test.js +2 -0
- package/lib/dist/interfaces/NotificationCategory.d.ts +3 -2
- package/lib/dist/interfaces/NotificationPermissions.d.ts +2 -0
- package/lib/src/interfaces/NotificationCategory.ts +4 -2
- package/metro.config.js +0 -1
- package/package.json +10 -13
- package/react-native-notifications.podspec +6 -5
- package/react-native.config.js +8 -0
- package/android/app/src/reactNative59/reactNative59.iml +0 -11
- package/android/app/src/reactNative60/reactNative60.iml +0 -11
- package/lib/ios/RNNotifications.xcodeproj/project.xcworkspace/xcuserdata/troy.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/package-lock.json +0 -13507
package/CODEOWNERS
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
* @
|
|
1
|
+
* @DanielEliraz
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#
|
|
1
|
+
#Tue Mar 22 09:43:34 CET 2022
|
|
2
2
|
gradle.version=6.1.1
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import groovy.json.JsonSlurper
|
|
2
2
|
|
|
3
3
|
apply plugin: 'com.android.library'
|
|
4
|
-
apply plugin: 'kotlin-android'
|
|
5
|
-
apply plugin: 'kotlin-android-extensions'
|
|
6
4
|
|
|
7
5
|
def safeExtGet(prop, fallback) {
|
|
8
6
|
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
9
7
|
}
|
|
10
8
|
|
|
11
|
-
def DEFAULT_COMPILE_SDK_VERSION =
|
|
9
|
+
def DEFAULT_COMPILE_SDK_VERSION = 30
|
|
12
10
|
def DEFAULT_MIN_SDK_VERSION = 21
|
|
13
11
|
def DEFAULT_KOTLIN_VERSION = "1.3.61"
|
|
14
12
|
def DEFAULT_KOTLIN_STDLIB_VERSION = "kotlin-stdlib-jdk8"
|
|
15
13
|
def DEFAULT_FIREBASE_MESSAGING_VERSION = "21.1.0"
|
|
16
14
|
|
|
17
|
-
def androidSdkVersion = safeExtGet('
|
|
18
|
-
def androidMinSdkVersion = safeExtGet('
|
|
15
|
+
def androidSdkVersion = safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
|
|
16
|
+
def androidMinSdkVersion = safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION)
|
|
19
17
|
def androidTargetSdkVersion = safeExtGet('targetSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
|
|
20
18
|
def kotlinVersion = safeExtGet('kotlinVersion', DEFAULT_KOTLIN_VERSION)
|
|
21
19
|
def kotlinStdlib = safeExtGet('kotlinStdlib', DEFAULT_KOTLIN_STDLIB_VERSION)
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
<service android:name=".core.ProxyService"/>
|
|
12
12
|
|
|
13
13
|
<service
|
|
14
|
-
android:name=".fcm.FcmInstanceIdListenerService"
|
|
14
|
+
android:name=".fcm.FcmInstanceIdListenerService"
|
|
15
|
+
android:exported="true">
|
|
15
16
|
<intent-filter>
|
|
16
17
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
|
17
18
|
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
package/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java
CHANGED
|
@@ -2,6 +2,7 @@ package com.wix.reactnativenotifications;
|
|
|
2
2
|
|
|
3
3
|
import android.app.Activity;
|
|
4
4
|
import android.app.Application;
|
|
5
|
+
import android.content.Context;
|
|
5
6
|
import android.content.Intent;
|
|
6
7
|
import android.os.Bundle;
|
|
7
8
|
|
|
@@ -61,24 +62,13 @@ public class RNNotificationsPackage implements ReactPackage, AppLifecycleFacade.
|
|
|
61
62
|
final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(mApplication.getApplicationContext());
|
|
62
63
|
notificationsDrawer.onNewActivity(activity);
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
if (NotificationIntentAdapter.canHandleIntent(intent)) {
|
|
66
|
-
Bundle notificationData = intent.getExtras();
|
|
67
|
-
final IPushNotification pushNotification = PushNotification.get(mApplication.getApplicationContext(), notificationData);
|
|
68
|
-
if (pushNotification != null) {
|
|
69
|
-
pushNotification.onOpened();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
65
|
+
callOnOpenedIfNeed(activity);
|
|
72
66
|
}
|
|
73
67
|
|
|
74
68
|
@Override
|
|
75
69
|
public void onActivityStarted(Activity activity) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
PushNotificationProps props = new PushNotificationProps(bundle);
|
|
79
|
-
if (props.isFirebaseBackgroundPayload()) {
|
|
80
|
-
InitialNotificationHolder.getInstance().set(props);
|
|
81
|
-
}
|
|
70
|
+
if (InitialNotificationHolder.getInstance().get() == null) {
|
|
71
|
+
callOnOpenedIfNeed(activity);
|
|
82
72
|
}
|
|
83
73
|
}
|
|
84
74
|
|
|
@@ -101,4 +91,17 @@ public class RNNotificationsPackage implements ReactPackage, AppLifecycleFacade.
|
|
|
101
91
|
@Override
|
|
102
92
|
public void onActivityDestroyed(Activity activity) {
|
|
103
93
|
}
|
|
94
|
+
|
|
95
|
+
private void callOnOpenedIfNeed(Activity activity) {
|
|
96
|
+
Intent intent = activity.getIntent();
|
|
97
|
+
if (NotificationIntentAdapter.canHandleIntent(intent)) {
|
|
98
|
+
Context appContext = mApplication.getApplicationContext();
|
|
99
|
+
Bundle notificationData = NotificationIntentAdapter.cannotHandleTrampolineActivity(appContext) ?
|
|
100
|
+
NotificationIntentAdapter.extractPendingNotificationDataFromIntent(intent) : intent.getExtras();
|
|
101
|
+
final IPushNotification pushNotification = PushNotification.get(appContext, notificationData);
|
|
102
|
+
if (pushNotification != null) {
|
|
103
|
+
pushNotification.onOpened();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
104
107
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package com.wix.reactnativenotifications.core;
|
|
2
2
|
|
|
3
|
+
import android.annotation.SuppressLint;
|
|
3
4
|
import android.app.PendingIntent;
|
|
5
|
+
import android.app.TaskStackBuilder;
|
|
4
6
|
import android.content.Context;
|
|
5
7
|
import android.content.Intent;
|
|
6
8
|
import android.os.Bundle;
|
|
@@ -10,9 +12,23 @@ import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
|
|
|
10
12
|
public class NotificationIntentAdapter {
|
|
11
13
|
private static final String PUSH_NOTIFICATION_EXTRA_NAME = "pushNotification";
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
@SuppressLint("UnspecifiedImmutableFlag")
|
|
16
|
+
public static PendingIntent createPendingNotificationIntent(Context appContext, PushNotificationProps notification) {
|
|
17
|
+
if (cannotHandleTrampolineActivity(appContext)) {
|
|
18
|
+
Intent mainActivityIntent = appContext.getPackageManager().getLaunchIntentForPackage(appContext.getPackageName());
|
|
19
|
+
mainActivityIntent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
|
|
20
|
+
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(appContext);
|
|
21
|
+
taskStackBuilder.addNextIntentWithParentStack(mainActivityIntent);
|
|
22
|
+
return taskStackBuilder.getPendingIntent((int) System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
|
|
23
|
+
} else {
|
|
24
|
+
Intent intent = new Intent(appContext, ProxyService.class);
|
|
25
|
+
intent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
|
|
26
|
+
return PendingIntent.getService(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_ONE_SHOT);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public static boolean cannotHandleTrampolineActivity(Context appContext) {
|
|
31
|
+
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R && appContext.getApplicationInfo().targetSdkVersion >= 31;
|
|
16
32
|
}
|
|
17
33
|
|
|
18
34
|
public static Bundle extractPendingNotificationDataFromIntent(Intent intent) {
|
|
@@ -22,11 +38,9 @@ public class NotificationIntentAdapter {
|
|
|
22
38
|
public static boolean canHandleIntent(Intent intent) {
|
|
23
39
|
if (intent != null) {
|
|
24
40
|
Bundle notificationData = intent.getExtras();
|
|
25
|
-
|
|
41
|
+
return notificationData != null &&
|
|
26
42
|
(intent.hasExtra(PUSH_NOTIFICATION_EXTRA_NAME) ||
|
|
27
|
-
notificationData.getString("google.message_id", null) != null)
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
43
|
+
notificationData.getString("google.message_id", null) != null);
|
|
30
44
|
}
|
|
31
45
|
|
|
32
46
|
return false;
|
|
@@ -9,6 +9,8 @@ import android.content.Context;
|
|
|
9
9
|
import android.content.Intent;
|
|
10
10
|
import android.graphics.Color;
|
|
11
11
|
import android.media.AudioAttributes;
|
|
12
|
+
import android.media.AudioManager;
|
|
13
|
+
import android.media.MediaPlayer;
|
|
12
14
|
import android.net.Uri;
|
|
13
15
|
import android.os.Build;
|
|
14
16
|
import android.os.Bundle;
|
|
@@ -23,7 +25,6 @@ import com.wix.reactnativenotifications.core.AppLifecycleFacadeHolder;
|
|
|
23
25
|
import com.wix.reactnativenotifications.core.InitialNotificationHolder;
|
|
24
26
|
import com.wix.reactnativenotifications.core.JsIOHelper;
|
|
25
27
|
import com.wix.reactnativenotifications.core.NotificationIntentAdapter;
|
|
26
|
-
import com.wix.reactnativenotifications.core.ProxyService;
|
|
27
28
|
|
|
28
29
|
import static com.wix.reactnativenotifications.Defs.NOTIFICATION_OPENED_EVENT_NAME;
|
|
29
30
|
import static com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_EVENT_NAME;
|
|
@@ -65,14 +66,14 @@ public class PushNotification implements IPushNotification {
|
|
|
65
66
|
mAppLaunchHelper = appLaunchHelper;
|
|
66
67
|
mJsIOHelper = JsIOHelper;
|
|
67
68
|
mNotificationProps = createProps(bundle);
|
|
68
|
-
initDefaultChannel(context);
|
|
69
|
+
//initDefaultChannel(context);
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
@Override
|
|
72
73
|
public void onReceived() throws InvalidNotificationException {
|
|
73
74
|
if (!mAppLifecycleFacade.isAppVisible()) {
|
|
74
|
-
notifyReceivedBackgroundToJS();
|
|
75
75
|
postNotification(null);
|
|
76
|
+
notifyReceivedBackgroundToJS();
|
|
76
77
|
} else {
|
|
77
78
|
notifyReceivedToJS();
|
|
78
79
|
}
|
|
@@ -94,15 +95,22 @@ public class PushNotification implements IPushNotification {
|
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
protected int postNotification(Integer notificationId) {
|
|
97
|
-
final PendingIntent pendingIntent =
|
|
98
|
+
final PendingIntent pendingIntent = NotificationIntentAdapter.createPendingNotificationIntent(mContext, mNotificationProps);;
|
|
98
99
|
final Notification notification = buildNotification(pendingIntent);
|
|
100
|
+
|
|
99
101
|
if (mNotificationProps.getGuid().equals("-1")) {
|
|
100
102
|
cancelAllNotifications();
|
|
101
103
|
return -1;
|
|
102
104
|
}
|
|
105
|
+
|
|
103
106
|
if (mNotificationProps.getTitle() == null || mNotificationProps.getTitle().isEmpty()) {
|
|
104
107
|
return -1;
|
|
105
108
|
}
|
|
109
|
+
|
|
110
|
+
if (mNotificationProps.isDataOnlyPushNotification()) {
|
|
111
|
+
return -1;
|
|
112
|
+
}
|
|
113
|
+
|
|
106
114
|
return postNotification(notification, notificationId);
|
|
107
115
|
}
|
|
108
116
|
|
|
@@ -151,12 +159,6 @@ public class PushNotification implements IPushNotification {
|
|
|
151
159
|
return mAppVisibilityListener;
|
|
152
160
|
}
|
|
153
161
|
|
|
154
|
-
protected PendingIntent getCTAPendingIntent() {
|
|
155
|
-
final Intent cta = new Intent(mContext, ProxyService.class);
|
|
156
|
-
cta.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
157
|
-
return NotificationIntentAdapter.createPendingNotificationIntent(mContext, cta, mNotificationProps);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
162
|
protected Notification buildNotification(PendingIntent intent) {
|
|
161
163
|
return getNotificationBuilder(intent).build();
|
|
162
164
|
}
|
|
@@ -164,11 +166,15 @@ public class PushNotification implements IPushNotification {
|
|
|
164
166
|
protected Notification.Builder getNotificationBuilder(PendingIntent intent) {
|
|
165
167
|
Uri soundUri = null;
|
|
166
168
|
String sound = mNotificationProps.getSound();
|
|
167
|
-
if (sound != null) {
|
|
169
|
+
if (sound != null && sound != "") {
|
|
168
170
|
sound = sound.toLowerCase();
|
|
169
171
|
int soundResourceId = getAppResourceId(sound, "raw");
|
|
170
172
|
if (soundResourceId == 0) {
|
|
171
|
-
|
|
173
|
+
String[] soundSplited = sound.split("\\.");
|
|
174
|
+
if (soundSplited.length > 0) {
|
|
175
|
+
String soundName = soundSplited[0];
|
|
176
|
+
soundResourceId = getAppResourceId(soundName, "raw");
|
|
177
|
+
}
|
|
172
178
|
}
|
|
173
179
|
soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"+ mContext.getPackageName() + "/" + soundResourceId);
|
|
174
180
|
}
|
|
@@ -180,7 +186,8 @@ public class PushNotification implements IPushNotification {
|
|
|
180
186
|
.setContentIntent(intent)
|
|
181
187
|
.setDefaults(Notification.DEFAULT_VIBRATE)
|
|
182
188
|
.setAutoCancel(true)
|
|
183
|
-
.setPriority(Notification.PRIORITY_HIGH)
|
|
189
|
+
.setPriority(Notification.PRIORITY_HIGH)
|
|
190
|
+
.setOngoing(mNotificationProps.getOngoing());
|
|
184
191
|
|
|
185
192
|
if (soundUri != null) {
|
|
186
193
|
notification.setSound(soundUri);
|
|
@@ -191,14 +198,10 @@ public class PushNotification implements IPushNotification {
|
|
|
191
198
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
192
199
|
final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
193
200
|
String channelId = mNotificationProps.getChannelId();
|
|
194
|
-
channelId = channelId != null ? channelId : DEFAULT_CHANNEL_ID;
|
|
201
|
+
channelId = channelId != null ? channelId : DEFAULT_CHANNEL_ID + sound;
|
|
195
202
|
NotificationChannel channel = notificationManager.getNotificationChannel(channelId);
|
|
196
|
-
if (channel
|
|
197
|
-
|
|
198
|
-
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
|
199
|
-
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
|
|
200
|
-
.build();
|
|
201
|
-
channel.setSound(soundUri, audioAttributes);
|
|
203
|
+
if (channel == null && soundUri != null) {
|
|
204
|
+
initDefaultChannel(mContext, channelId, soundUri);
|
|
202
205
|
}
|
|
203
206
|
notification.setChannelId(channelId);
|
|
204
207
|
}
|
|
@@ -211,6 +214,24 @@ public class PushNotification implements IPushNotification {
|
|
|
211
214
|
Log.d(LOGTAG, e.getMessage());
|
|
212
215
|
}
|
|
213
216
|
|
|
217
|
+
if(mNotificationProps.getCriticalAlert()){
|
|
218
|
+
try {
|
|
219
|
+
MediaPlayer mMediaPlayer = new MediaPlayer();
|
|
220
|
+
mMediaPlayer.setDataSource(mContext.getApplicationContext(), soundUri);
|
|
221
|
+
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
|
|
222
|
+
|
|
223
|
+
mMediaPlayer.prepare();
|
|
224
|
+
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
|
225
|
+
public void onPrepared(MediaPlayer arg0) {
|
|
226
|
+
mMediaPlayer.seekTo(0);
|
|
227
|
+
mMediaPlayer.start();
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
} catch (Exception e) {
|
|
231
|
+
Log.d(LOGTAG, e.getMessage());
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
214
235
|
return notification;
|
|
215
236
|
}
|
|
216
237
|
|
|
@@ -264,8 +285,10 @@ public class PushNotification implements IPushNotification {
|
|
|
264
285
|
}
|
|
265
286
|
|
|
266
287
|
protected void launchOrResumeApp() {
|
|
267
|
-
|
|
268
|
-
|
|
288
|
+
if (!NotificationIntentAdapter.cannotHandleTrampolineActivity(mContext)) {
|
|
289
|
+
final Intent intent = mAppLaunchHelper.getLaunchIntent(mContext);
|
|
290
|
+
mContext.startActivity(intent);
|
|
291
|
+
}
|
|
269
292
|
}
|
|
270
293
|
|
|
271
294
|
private int getAppResourceId(String resName, String resType) {
|
|
@@ -277,9 +300,9 @@ public class PushNotification implements IPushNotification {
|
|
|
277
300
|
notificationManager.cancelAll();
|
|
278
301
|
}
|
|
279
302
|
|
|
280
|
-
private void initDefaultChannel(Context context) {
|
|
303
|
+
private void initDefaultChannel(Context context, String channelId, Uri soundUri) {
|
|
281
304
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
282
|
-
NotificationChannel defaultChannel = new NotificationChannel(
|
|
305
|
+
NotificationChannel defaultChannel = new NotificationChannel(channelId,
|
|
283
306
|
DEFAULT_CHANNEL_NAME,
|
|
284
307
|
NotificationManager.IMPORTANCE_HIGH);
|
|
285
308
|
defaultChannel.setDescription(DEFAULT_CHANNEL_NAME);
|
|
@@ -289,6 +312,13 @@ public class PushNotification implements IPushNotification {
|
|
|
289
312
|
defaultChannel.enableVibration(true);
|
|
290
313
|
defaultChannel.setShowBadge(true);
|
|
291
314
|
defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
|
315
|
+
if (soundUri != null) {
|
|
316
|
+
AudioAttributes audioAttributes = new AudioAttributes.Builder()
|
|
317
|
+
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
|
318
|
+
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
|
|
319
|
+
.build();
|
|
320
|
+
defaultChannel.setSound(soundUri, audioAttributes);
|
|
321
|
+
}
|
|
292
322
|
final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
293
323
|
notificationManager.createNotificationChannel(defaultChannel);
|
|
294
324
|
}
|
|
@@ -37,6 +37,30 @@ public class PushNotificationProps {
|
|
|
37
37
|
public boolean isFirebaseBackgroundPayload() {
|
|
38
38
|
return mBundle.containsKey("google.message_id");
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
public boolean isDataOnlyPushNotification() {
|
|
42
|
+
return getTitle() == null && getBody() == null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public Boolean getCriticalAlert() {
|
|
46
|
+
String val = mBundle.getString("criticalalert");
|
|
47
|
+
if(val != null && !val.isEmpty()){
|
|
48
|
+
return val.toLowerCase().equals("true");
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public Double getCriticalAlertVolume() {
|
|
54
|
+
String val = mBundle.getString("criticalalertvolume");
|
|
55
|
+
if(val != null && !val.isEmpty()){
|
|
56
|
+
return Double.parseDouble(val);
|
|
57
|
+
}
|
|
58
|
+
return 0.0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public Boolean getOngoing() {
|
|
62
|
+
return mBundle.getBoolean("ongoing");
|
|
63
|
+
}
|
|
40
64
|
|
|
41
65
|
@Override
|
|
42
66
|
public String toString() {
|
package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/AppLaunchHelperTest.java
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
package com.wix.reactnativenotifications.core;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.content.ComponentName;
|
|
5
|
+
import android.content.Context;
|
|
6
|
+
import android.content.Intent;
|
|
7
|
+
import android.content.pm.PackageManager;
|
|
8
|
+
|
|
9
|
+
import org.junit.Before;
|
|
10
|
+
import org.junit.Test;
|
|
11
|
+
import org.junit.runner.RunWith;
|
|
12
|
+
import org.mockito.Mock;
|
|
13
|
+
import org.mockito.MockitoAnnotations;
|
|
14
|
+
import org.robolectric.RobolectricTestRunner;
|
|
15
|
+
|
|
16
|
+
import static org.junit.Assert.assertEquals;
|
|
17
|
+
import static org.junit.Assert.assertFalse;
|
|
18
|
+
import static org.junit.Assert.assertNotNull;
|
|
19
|
+
import static org.junit.Assert.assertTrue;
|
|
20
|
+
import static org.mockito.ArgumentMatchers.eq;
|
|
21
|
+
import static org.mockito.Mockito.mock;
|
|
22
|
+
import static org.mockito.Mockito.when;
|
|
23
|
+
|
|
24
|
+
@RunWith(RobolectricTestRunner.class)
|
|
25
|
+
public class AppLaunchHelperTest {
|
|
26
|
+
|
|
27
|
+
private static final String LAUNCHED_FROM_NOTIF_BOOLEAN_EXTRA_NAME = "launchedFromNotification";
|
|
28
|
+
|
|
29
|
+
static class ActivityMock extends Activity {
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private final String APP_PACKAGE_NAME = "the.package";
|
|
33
|
+
private final String APP_MAIN_ACTIVITY_NAME = ActivityMock.class.getName();
|
|
34
|
+
|
|
35
|
+
@Mock private Context mContext;
|
|
36
|
+
@Mock private PackageManager mPackageManager;
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@Before
|
|
40
|
+
public void setup() throws Exception {
|
|
41
|
+
MockitoAnnotations.initMocks(this);
|
|
42
|
+
when(mContext.getApplicationContext()).thenReturn(mContext);
|
|
43
|
+
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
|
44
|
+
when(mContext.getPackageName()).thenReturn(APP_PACKAGE_NAME);
|
|
45
|
+
|
|
46
|
+
// Set-up the intent (mock) returned by the SDK for getLaunchIntentForPackage()
|
|
47
|
+
Intent intent = mock(Intent.class);
|
|
48
|
+
when(intent.getComponent()).thenReturn(new ComponentName(APP_PACKAGE_NAME, APP_MAIN_ACTIVITY_NAME));
|
|
49
|
+
when(mPackageManager.getLaunchIntentForPackage(eq(APP_PACKAGE_NAME))).thenReturn(intent);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@Test
|
|
53
|
+
public void getLaunchIntent__returnsCustomIntentWithNotifFlagExtra() throws Exception {
|
|
54
|
+
final AppLaunchHelper uut = getUUT();
|
|
55
|
+
Intent intent = uut.getLaunchIntent(mContext);
|
|
56
|
+
|
|
57
|
+
assertNotNull(intent);
|
|
58
|
+
assertEquals(APP_PACKAGE_NAME, intent.getComponent().getPackageName());
|
|
59
|
+
assertEquals(APP_MAIN_ACTIVITY_NAME, intent.getComponent().getClassName());
|
|
60
|
+
assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, intent.getFlags());
|
|
61
|
+
assertTrue(intent.getBooleanExtra(LAUNCHED_FROM_NOTIF_BOOLEAN_EXTRA_NAME, false));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@Test
|
|
65
|
+
public void isLaunchIntentsActivity_activityIsMainLauncherActivity_returnTrue() throws Exception {
|
|
66
|
+
Activity activity = getActivityMock(APP_MAIN_ACTIVITY_NAME);
|
|
67
|
+
|
|
68
|
+
final AppLaunchHelper uut = getUUT();
|
|
69
|
+
boolean result = uut.isLaunchIntentsActivity(activity);
|
|
70
|
+
|
|
71
|
+
assertTrue(result);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@Test
|
|
75
|
+
public void isLaunchIntentsActivity_activityIsNotMainActivity_returnFalse() throws Exception {
|
|
76
|
+
Activity activity = getActivityMock("other.activity");
|
|
77
|
+
|
|
78
|
+
final AppLaunchHelper uut = getUUT();
|
|
79
|
+
boolean result = uut.isLaunchIntentsActivity(activity);
|
|
80
|
+
|
|
81
|
+
assertFalse(result);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@Test
|
|
85
|
+
public void isLaunchIntentOfNotification_hasFlagInBundle_returnTrue() throws Exception {
|
|
86
|
+
Intent intent = mock(Intent.class);
|
|
87
|
+
when(intent.getBooleanExtra(eq(LAUNCHED_FROM_NOTIF_BOOLEAN_EXTRA_NAME), eq(false))).thenReturn(true);
|
|
88
|
+
|
|
89
|
+
final AppLaunchHelper uut = getUUT();
|
|
90
|
+
boolean result = uut.isLaunchIntentOfNotification(intent);
|
|
91
|
+
|
|
92
|
+
assertTrue(result);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@Test
|
|
96
|
+
public void isLaunchIntentOfNotification_noFlagInBundle_returnFalse() throws Exception {
|
|
97
|
+
Intent intent = mock(Intent.class);
|
|
98
|
+
|
|
99
|
+
final AppLaunchHelper uut = getUUT();
|
|
100
|
+
boolean result = uut.isLaunchIntentOfNotification(intent);
|
|
101
|
+
|
|
102
|
+
assertFalse(result);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
protected Activity getActivityMock(String activityClassName) {
|
|
106
|
+
Activity activity = mock(Activity.class);
|
|
107
|
+
when(activity.getPackageManager()).thenReturn(mPackageManager);
|
|
108
|
+
when(activity.getPackageName()).thenReturn(APP_PACKAGE_NAME);
|
|
109
|
+
when(activity.getComponentName()).thenReturn(new ComponentName(APP_PACKAGE_NAME, activityClassName));
|
|
110
|
+
when(activity.getLocalClassName()).thenReturn(activityClassName);
|
|
111
|
+
return activity;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private AppLaunchHelper getUUT() {
|
|
115
|
+
return new AppLaunchHelper();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
package com.wix.reactnativenotifications.core;
|
|
2
|
+
|
|
3
|
+
import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
|
|
4
|
+
|
|
5
|
+
import org.junit.Test;
|
|
6
|
+
import org.junit.runner.RunWith;
|
|
7
|
+
import org.mockito.junit.MockitoJUnitRunner;
|
|
8
|
+
|
|
9
|
+
import static org.junit.Assert.*;
|
|
10
|
+
import static org.mockito.Mockito.mock;
|
|
11
|
+
|
|
12
|
+
@RunWith(MockitoJUnitRunner.class)
|
|
13
|
+
public class InitialNotificationHolderTest {
|
|
14
|
+
|
|
15
|
+
@Test
|
|
16
|
+
public void initialState() throws Exception {
|
|
17
|
+
final InitialNotificationHolder uut = createUUT();
|
|
18
|
+
assertNull(uut.get());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Test
|
|
22
|
+
public void setsInitialNotification() throws Exception {
|
|
23
|
+
PushNotificationProps props = mock(PushNotificationProps.class);
|
|
24
|
+
final InitialNotificationHolder uut = createUUT();
|
|
25
|
+
uut.set(props);
|
|
26
|
+
assertEquals(props, uut.get());
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Test
|
|
30
|
+
public void clearsInitialNotification() throws Exception {
|
|
31
|
+
PushNotificationProps props = mock(PushNotificationProps.class);
|
|
32
|
+
final InitialNotificationHolder uut = createUUT();
|
|
33
|
+
uut.set(props);
|
|
34
|
+
uut.clear();
|
|
35
|
+
assertNull(uut.get());
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@Test
|
|
39
|
+
public void replacesInitialNotification() throws Exception {
|
|
40
|
+
PushNotificationProps props1 = mock(PushNotificationProps.class);
|
|
41
|
+
PushNotificationProps props2 = mock(PushNotificationProps.class);
|
|
42
|
+
final InitialNotificationHolder uut = createUUT();
|
|
43
|
+
uut.set(props1);
|
|
44
|
+
uut.set(props2);
|
|
45
|
+
assertNotEquals(props1, props2);
|
|
46
|
+
assertEquals(props2, uut.get());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@Test
|
|
50
|
+
public void isALazySingleton() throws Exception {
|
|
51
|
+
final InitialNotificationHolder instance = InitialNotificationHolder.getInstance();
|
|
52
|
+
assertNotNull(instance);
|
|
53
|
+
assertEquals(instance, InitialNotificationHolder.getInstance());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private InitialNotificationHolder createUUT() {
|
|
57
|
+
return new InitialNotificationHolder();
|
|
58
|
+
}
|
|
59
|
+
}
|
package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/JsIOHelperTest.java
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
package com.wix.reactnativenotifications.core;
|
|
2
|
+
|
|
3
|
+
import android.os.Bundle;
|
|
4
|
+
|
|
5
|
+
import com.facebook.react.bridge.ReactContext;
|
|
6
|
+
import com.facebook.react.bridge.WritableMap;
|
|
7
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
8
|
+
|
|
9
|
+
import org.junit.Before;
|
|
10
|
+
import org.junit.Test;
|
|
11
|
+
import org.junit.runner.RunWith;
|
|
12
|
+
import org.mockito.Mock;
|
|
13
|
+
import org.mockito.junit.MockitoJUnitRunner;
|
|
14
|
+
|
|
15
|
+
import static org.junit.Assert.assertFalse;
|
|
16
|
+
import static org.junit.Assert.assertTrue;
|
|
17
|
+
import static org.mockito.ArgumentMatchers.any;
|
|
18
|
+
import static org.mockito.ArgumentMatchers.anyString;
|
|
19
|
+
import static org.mockito.Mockito.mock;
|
|
20
|
+
import static org.mockito.Mockito.never;
|
|
21
|
+
import static org.mockito.Mockito.verify;
|
|
22
|
+
import static org.mockito.Mockito.when;
|
|
23
|
+
|
|
24
|
+
@RunWith(MockitoJUnitRunner.class)
|
|
25
|
+
public class JsIOHelperTest {
|
|
26
|
+
|
|
27
|
+
@Mock DeviceEventManagerModule.RCTDeviceEventEmitter mRCTDeviceEventEmitter;
|
|
28
|
+
@Mock ReactContext mReactContext;
|
|
29
|
+
|
|
30
|
+
@Before
|
|
31
|
+
public void setup() throws Exception {
|
|
32
|
+
when(mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)).thenReturn(mRCTDeviceEventEmitter);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Test
|
|
36
|
+
public void sendEventToJS_hasReactContext_emitsEventToJs() throws Exception {
|
|
37
|
+
WritableMap data = mock(WritableMap.class);
|
|
38
|
+
|
|
39
|
+
final JsIOHelper uut = createUUT();
|
|
40
|
+
boolean result = uut.sendEventToJS("my-event", data, mReactContext);
|
|
41
|
+
|
|
42
|
+
assertTrue(result);
|
|
43
|
+
verify(mRCTDeviceEventEmitter).emit("my-event", data);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Test
|
|
47
|
+
public void sendEventToJS_noReactContext_returnsFalse() throws Exception {
|
|
48
|
+
WritableMap data = mock(WritableMap.class);
|
|
49
|
+
|
|
50
|
+
final JsIOHelper uut = createUUT();
|
|
51
|
+
boolean result = uut.sendEventToJS("my-event", data, null);
|
|
52
|
+
|
|
53
|
+
assertFalse(result);
|
|
54
|
+
verify(mRCTDeviceEventEmitter, never()).emit(anyString(), any(WritableMap.class));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private JsIOHelper createUUT() {
|
|
58
|
+
return new JsIOHelper();
|
|
59
|
+
}
|
|
60
|
+
}
|