Skip to content

Commit 5827264

Browse files
committed
Callback bug fix
* Fixed bug where notification opened callback would not fire when opening a notification from an app cold start. - Added tests for each possible callback app state; app cold start, app resume, and in focus.
1 parent 9013cbe commit 5827264

File tree

8 files changed

+126
-48
lines changed

8 files changed

+126
-48
lines changed

OneSignalSDK.jar

28 Bytes
Binary file not shown.

OneSignalSDK/app/build.gradle

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,25 @@ android {
1818
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
1919
}
2020
}
21+
testOptions {
22+
unitTests.all {
23+
maxParallelForks 4
24+
maxHeapSize "2048m"
25+
}
26+
}
2127
}
2228

2329
dependencies {
2430
compile fileTree(dir: 'libs', include: ['*.jar'])
2531
compile 'com.android.support:appcompat-v7:22.1.1'
26-
//compile 'com.onesignal:OneSignal:1.8.1+@aar'
32+
33+
// Use for SDK Development
2734
compile project(':onesignal')
35+
36+
// Use for released SDK
37+
//compile 'com.onesignal:OneSignal:1.10.+@aar'
38+
//compile 'com.google.android.gms:play-services:7.3.+'
39+
2840
testCompile 'junit:junit:4.12'
2941
// testCompile 'org.robolectric:shadows-support-v4:3.0'
3042
testCompile('org.robolectric:robolectric:3.0') {

OneSignalSDK/app/src/test/java/com/test/onesignal/GenerateNotificationRunner.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,22 +106,22 @@ public void beforeEachTest() throws Exception {
106106
}
107107

108108

109-
private Bundle getBaseNotifBundle() {
109+
public static Bundle getBaseNotifBundle() {
110110
return getBaseNotifBundle("UUID");
111111
}
112112

113-
private Bundle getBaseNotifBundle(String id) {
113+
public static Bundle getBaseNotifBundle(String id) {
114114
Bundle bundle = new Bundle();
115115
bundle.putString("alert", notifMessage);
116116
bundle.putString("custom", "{\"i\": \"" + id + "\"}");
117117

118118
return bundle;
119119
}
120120

121-
private Intent createOpenIntent(int notifId, Bundle bundle) {
121+
static Intent createOpenIntent(int notifId, Bundle bundle) {
122122
return new Intent()
123123
.putExtra("notificationId", notifId)
124-
.putExtra("data", NotificationBundleProcessor.bundleAsJSONObject(bundle).toString());
124+
.putExtra("onesignal_data", NotificationBundleProcessor.bundleAsJSONObject(bundle).toString());
125125
}
126126

127127
private Intent createOpenIntent(Bundle bundle) {

OneSignalSDK/app/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,19 @@
3131
package com.test.onesignal;
3232

3333
import android.app.Activity;
34+
import android.content.Intent;
3435

3536
import com.onesignal.BuildConfig;
37+
import com.onesignal.NotificationBundleProcessor;
3638
import com.onesignal.OneSignal;
3739
import com.onesignal.ShadowOneSignalRestClient;
3840
import com.onesignal.ShadowPushRegistratorGPS;
3941
import com.onesignal.example.BlankActivity;
4042

4143
import junit.framework.Assert;
4244

45+
import org.json.JSONArray;
46+
import org.json.JSONObject;
4347
import org.junit.Before;
4448
import org.junit.BeforeClass;
4549
import org.junit.Test;
@@ -61,6 +65,7 @@ public class MainOneSignalClassRunner {
6165
private static Field OneSignal_CurrentSubscription;
6266
private Activity blankActiviy;
6367
private static String callBackUseId, getCallBackRegId;
68+
private static String notificationOpenedMessage;
6469

6570
public static void GetIdsAvailable() {
6671
OneSignal.idsAvailable(new OneSignal.IdsAvailableHandler() {
@@ -92,17 +97,72 @@ public void beforeEachTest() throws Exception {
9297
ShadowOneSignalRestClient.failNext = false;
9398
ShadowOneSignalRestClient.testThread = Thread.currentThread();
9499
GetIdsAvailable();
100+
notificationOpenedMessage = null;
101+
}
102+
103+
@Test
104+
public void testOpenFromNotificationWhenAppIsDead() throws Exception {
105+
Intent intent = new Intent();
106+
intent.putExtra("onesignal_data", "[{ \"alert\": \"Test Msg\", \"custom\": { \"i\": \"UUID\" } }]");
107+
108+
blankActiviy.setIntent(intent);
109+
OneSignal.init(blankActiviy, "123456789", "b2f7f966-d8cc-11e4-bed1-df8f05be55ba", new OneSignal.NotificationOpenedHandler() {
110+
@Override
111+
public void notificationOpened(String message, JSONObject additionalData, boolean isActive) {
112+
notificationOpenedMessage = message;
113+
}
114+
});
115+
116+
Assert.assertEquals("Test Msg", notificationOpenedMessage);
117+
}
118+
119+
@Test
120+
public void testOpenFromNotificationWhenAppIsInBackground() throws Exception {
121+
OneSignal.init(blankActiviy, "123456789", "b2f7f966-d8cc-11e4-bed1-df8f05be55ba", new OneSignal.NotificationOpenedHandler() {
122+
@Override
123+
public void notificationOpened(String message, JSONObject additionalData, boolean isActive) {
124+
notificationOpenedMessage = message;
125+
}
126+
});
127+
Assert.assertNull(notificationOpenedMessage);
128+
129+
OneSignal.handleNotificationOpened(blankActiviy, new JSONArray("[{ \"alert\": \"Test Msg\", \"custom\": { \"i\": \"UUID\" } }]"));
130+
Assert.assertEquals("Test Msg", notificationOpenedMessage);
131+
}
132+
133+
@Test
134+
public void testNotificationReceivedWhenAppInFocus() throws Exception {
135+
// Tests seem to be over lapping when running them all. Wait a bit before running this test.
136+
try {Thread.sleep(1000);} catch (Throwable t) {}
137+
138+
OneSignal.init(blankActiviy, "123456789", "b2f7f966-d8cc-11e4-bed1-df8f05be55ba", new OneSignal.NotificationOpenedHandler() {
139+
@Override
140+
public void notificationOpened(String message, JSONObject additionalData, boolean isActive) {
141+
notificationOpenedMessage = message;
142+
}
143+
});
144+
try {Thread.sleep(5000);} catch (Throwable t) {}
145+
Assert.assertNull(notificationOpenedMessage);
146+
147+
NotificationBundleProcessor.Process(blankActiviy, GenerateNotificationRunner.getBaseNotifBundle());
148+
try {Thread.sleep(100);} catch (Throwable t) {}
149+
Robolectric.getForegroundThreadScheduler().runOneTask();
150+
Robolectric.getForegroundThreadScheduler().runOneTask();
151+
Assert.assertEquals("Robo test message", notificationOpenedMessage);
95152
}
96153

97154
@Test
98155
public void testInvalidGoogleProjectNumber() throws Exception {
156+
// Tests seem to be over lapping when running them all. Wait a bit before running this test.
157+
try {Thread.sleep(1000);} catch (Throwable t) {}
158+
99159
OneSignal.init(blankActiviy, "NOT A VALID Google project number", "b2f7f966-d8cc-11e4-bed1-df8f05be55ba");
100160

101161
try {Thread.sleep(5000);} catch (Throwable t) {}
162+
Robolectric.getForegroundThreadScheduler().runOneTask();
102163
Assert.assertEquals(-6, ShadowOneSignalRestClient.lastPost.getInt("notification_types"));
103164

104165
// Test that idsAvailable still fires
105-
Robolectric.getForegroundThreadScheduler().runOneTask();
106166
Assert.assertEquals(ShadowOneSignalRestClient.testUserId, callBackUseId);
107167
}
108168

@@ -196,6 +256,8 @@ public void shouldAllowMultipleSetSubscription() throws Exception {
196256
try {Thread.sleep(5000);} catch (Throwable t) {}
197257

198258
OneSignal.setSubscription(false);
259+
try {Thread.sleep(5000);} catch (Throwable t) {}
260+
199261
Assert.assertEquals(-2, ShadowOneSignalRestClient.lastPost.getInt("notification_types"));
200262

201263
// Should not resend same value

OneSignalSDK/onesignal/onesignal.iml

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
</facet>
99
<facet type="android" name="Android">
1010
<configuration>
11-
<option name="SELECTED_BUILD_VARIANT" value="debug" />
11+
<option name="SELECTED_BUILD_VARIANT" value="release" />
1212
<option name="SELECTED_TEST_ARTIFACT" value="_unit_test_" />
13-
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
14-
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
15-
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
16-
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugUnitTest" />
17-
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugUnitTestSources" />
13+
<option name="ASSEMBLE_TASK_NAME" value="assembleRelease" />
14+
<option name="COMPILE_JAVA_TASK_NAME" value="compileReleaseSources" />
15+
<option name="SOURCE_GEN_TASK_NAME" value="generateReleaseSources" />
16+
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleReleaseUnitTest" />
17+
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileReleaseUnitTestSources" />
1818
<option name="ALLOW_USER_CONFIGURATION" value="false" />
1919
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
2020
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
@@ -25,30 +25,30 @@
2525
</facet>
2626
</component>
2727
<component name="NewModuleRootManager" inherit-compiler-output="false">
28-
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
29-
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
28+
<output url="file://$MODULE_DIR$/build/intermediates/classes/release" />
29+
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/release" />
3030
<exclude-output />
3131
<content url="file://$MODULE_DIR$">
32-
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
33-
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
34-
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
35-
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
36-
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
37-
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
38-
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
39-
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
40-
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
41-
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
42-
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
43-
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
44-
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
45-
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
46-
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
47-
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
48-
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
49-
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
50-
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
51-
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
32+
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/release" isTestSource="false" generated="true" />
33+
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/release" isTestSource="false" generated="true" />
34+
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/release" isTestSource="false" generated="true" />
35+
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/release" isTestSource="false" generated="true" />
36+
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/release" type="java-resource" />
37+
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/release" type="java-resource" />
38+
<sourceFolder url="file://$MODULE_DIR$/src/release/res" type="java-resource" />
39+
<sourceFolder url="file://$MODULE_DIR$/src/release/resources" type="java-resource" />
40+
<sourceFolder url="file://$MODULE_DIR$/src/release/assets" type="java-resource" />
41+
<sourceFolder url="file://$MODULE_DIR$/src/release/aidl" isTestSource="false" />
42+
<sourceFolder url="file://$MODULE_DIR$/src/release/java" isTestSource="false" />
43+
<sourceFolder url="file://$MODULE_DIR$/src/release/jni" isTestSource="false" />
44+
<sourceFolder url="file://$MODULE_DIR$/src/release/rs" isTestSource="false" />
45+
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/res" type="java-test-resource" />
46+
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/resources" type="java-test-resource" />
47+
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/assets" type="java-test-resource" />
48+
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/aidl" isTestSource="true" />
49+
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/java" isTestSource="true" />
50+
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/jni" isTestSource="true" />
51+
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/rs" isTestSource="true" />
5252
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
5353
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
5454
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />

OneSignalSDK/onesignal/src/main/java/com/onesignal/GenerateNotification.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public void run() {
121121

122122
Intent buttonIntent = getNewBaseIntent(aNotificationId);
123123
buttonIntent.putExtra("action_button", true);
124-
buttonIntent.putExtra("data", gcmJson.toString());
124+
buttonIntent.putExtra("onesignal_data", gcmJson.toString());
125125
try {
126126
if (gcmJson.has("grp"))
127127
buttonIntent.putExtra("grp", gcmJson.getString("grp"));
@@ -142,7 +142,7 @@ public void onClick(DialogInterface dialog, int which) {
142142
JSONObject newJsonData = new JSONObject(gcmJson.toString());
143143
newJsonData.put("custom", customJson.toString());
144144

145-
finalButtonIntent.putExtra("data", newJsonData.toString());
145+
finalButtonIntent.putExtra("onesignal_data", newJsonData.toString());
146146

147147
NotificationOpenedProcessor.processIntent(context, finalButtonIntent);
148148
} catch (Throwable t) {}
@@ -294,7 +294,7 @@ private static int showNotification(JSONObject gcmBundle) {
294294
addNotificationActionButtons(gcmBundle, notifBuilder, notificationId, null);
295295

296296
if (group != null) {
297-
PendingIntent contentIntent = PendingIntent.getActivity(currentContext, random.nextInt(), getNewBaseIntent(notificationId).putExtra("data", gcmBundle.toString()).putExtra("grp", group), PendingIntent.FLAG_UPDATE_CURRENT);
297+
PendingIntent contentIntent = PendingIntent.getActivity(currentContext, random.nextInt(), getNewBaseIntent(notificationId).putExtra("onesignal_data", gcmBundle.toString()).putExtra("grp", group), PendingIntent.FLAG_UPDATE_CURRENT);
298298
notifBuilder.setContentIntent(contentIntent);
299299
PendingIntent deleteIntent = PendingIntent.getActivity(currentContext, random.nextInt(), getNewBaseDeleteIntent(notificationId).putExtra("grp", group), PendingIntent.FLAG_UPDATE_CURRENT);
300300
notifBuilder.setDeleteIntent(deleteIntent);
@@ -303,7 +303,7 @@ private static int showNotification(JSONObject gcmBundle) {
303303
createSummaryNotification(gcmBundle);
304304
}
305305
else {
306-
PendingIntent contentIntent = PendingIntent.getActivity(currentContext, random.nextInt(), getNewBaseIntent(notificationId).putExtra("data", gcmBundle.toString()), PendingIntent.FLAG_UPDATE_CURRENT);
306+
PendingIntent contentIntent = PendingIntent.getActivity(currentContext, random.nextInt(), getNewBaseIntent(notificationId).putExtra("onesignal_data", gcmBundle.toString()), PendingIntent.FLAG_UPDATE_CURRENT);
307307
notifBuilder.setContentIntent(contentIntent);
308308
PendingIntent deleteIntent = PendingIntent.getActivity(currentContext, random.nextInt(), getNewBaseDeleteIntent(notificationId), PendingIntent.FLAG_UPDATE_CURRENT);
309309
notifBuilder.setDeleteIntent(deleteIntent);
@@ -421,7 +421,7 @@ static void createSummaryNotification(Context inContext, boolean updateSummary,
421421
}
422422
Intent summaryIntent = getNewBaseIntent(summaryNotificationId)
423423
.putExtra("summary", group)
424-
.putExtra("data", summaryDataBundle.toString());
424+
.putExtra("onesignal_data", summaryDataBundle.toString());
425425

426426
PendingIntent summaryContentIntent = PendingIntent.getActivity(currentContext, random.nextInt(), summaryIntent, PendingIntent.FLAG_UPDATE_CURRENT);
427427

@@ -482,7 +482,7 @@ static void createSummaryNotification(Context inContext, boolean updateSummary,
482482

483483
NotificationCompat.Builder notifBuilder = getBaseNotificationCompatBuilder(gcmBundle, !updateSummary);
484484

485-
PendingIntent summaryContentIntent = PendingIntent.getActivity(currentContext, random.nextInt(), getNewBaseIntent(summaryNotificationId).putExtra("data", gcmBundle.toString()).putExtra("summary", group), PendingIntent.FLAG_UPDATE_CURRENT);
485+
PendingIntent summaryContentIntent = PendingIntent.getActivity(currentContext, random.nextInt(), getNewBaseIntent(summaryNotificationId).putExtra("onesignal_data", gcmBundle.toString()).putExtra("summary", group), PendingIntent.FLAG_UPDATE_CURRENT);
486486

487487
addNotificationActionButtons(gcmBundle, notifBuilder, summaryNotificationId, group);
488488
notifBuilder.setContentIntent(summaryContentIntent)
@@ -695,7 +695,7 @@ private static void addNotificationActionButtons(JSONObject gcmBundle, Notificat
695695
Intent buttonIntent = getNewBaseIntent(notificationId);
696696
buttonIntent.setAction("" + i); // Required to keep each action button from replacing extras of each other
697697
buttonIntent.putExtra("action_button", true);
698-
buttonIntent.putExtra("data", bundle.toString());
698+
buttonIntent.putExtra("onesignal_data", bundle.toString());
699699
if (groupSummary != null)
700700
buttonIntent.putExtra("summary", groupSummary);
701701
else if (gcmBundle.has("grp"))

OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationOpenedProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static void processIntent(Context inActivity, Intent inIntent) {
6767
JSONArray dataArray = null;
6868
if (!dismissed) {
6969
try {
70-
dataArray = NotificationBundleProcessor.newJsonArray(new JSONObject(intent.getStringExtra("data")));
70+
dataArray = NotificationBundleProcessor.newJsonArray(new JSONObject(intent.getStringExtra("onesignal_data")));
7171
} catch (Throwable t) {
7272
t.printStackTrace();
7373
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public interface PostNotificationResponseHandler {
141141
private static TrackGooglePurchase trackGooglePurchase;
142142
private static TrackAmazonPurchase trackAmazonPurchase;
143143

144-
public static final String VERSION = "011002";
144+
public static final String VERSION = "011003";
145145

146146
private static PushRegistrator pushRegistrator;
147147
private static AdvertisingIdentifierProvider mainAdIdProvider = new AdvertisingIdProviderGPS();
@@ -270,11 +270,15 @@ public void complete(String id) {
270270

271271
// Called from tapping on a Notification from the status bar when the activity is completely dead and not open in any state.
272272
if (appContext.getIntent() != null) {
273-
Bundle oneSignalDataBundle = appContext.getIntent().getBundleExtra("onesignal_data");
274-
if (oneSignalDataBundle != null) {
275-
JSONArray dataArray = NotificationBundleProcessor.bundleAsJsonArray(oneSignalDataBundle);
276-
openWebURLFromNotification(dataArray);
277-
runNotificationOpenedCallback(dataArray, false);
273+
String oneSignalDataJsonString = appContext.getIntent().getStringExtra("onesignal_data");
274+
if (oneSignalDataJsonString != null) {
275+
try {
276+
JSONArray dataArray = new JSONArray(oneSignalDataJsonString);
277+
openWebURLFromNotification(dataArray);
278+
runNotificationOpenedCallback(dataArray, false);
279+
} catch (JSONException e) {
280+
Log(LOG_LEVEL.ERROR, "Failed to process onesignal_data intent on app cold start.");
281+
}
278282
}
279283
}
280284

0 commit comments

Comments
 (0)