Skip to content

Commit 65b8dc6

Browse files
Karthikeyanminbi
authored andcommitted
[Pinpoint] Fix submitEvents for offline case #773; fix notification image (#776)
Make notificationImage a local variable to avoid persisting the image across push notifications/campaigns.
1 parent fd89feb commit 65b8dc6

File tree

11 files changed

+435
-104
lines changed

11 files changed

+435
-104
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
* **AWS Mobile Client**
1616
* Fixed a bug that caused repetitive sign-in using the drop-in UI to the same provider to not federate the correct credentials. See [issue #809](https://github.com/aws-amplify/aws-sdk-android/issues/809)
1717

18+
* **Amazon Pinpoint**
19+
* Fix a bug where the image that is part of a push notification is persisted in the subsequent notifications.
20+
* Fix a bug where the events recorded and stored in the device will not be deleted when the network is not available. See [issue #773](https://github.com/aws-amplify/aws-sdk-android/issues/773). With this change, the events will be kept in the local database when there is a retryable error or device is offline. For all other exceptions during `submitEvents`, the exception is logged and the events will be removed from the local database.
21+
1822
## [Release 2.13.0](https://github.com/aws/aws-sdk-android/releases/tag/release_v2.13.0)
1923

2024
### Enhancements
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
apply plugin: 'com.android.library'
2+
apply plugin: 'devicefarm'
3+
4+
android {
5+
compileSdkVersion 27
6+
7+
defaultConfig {
8+
minSdkVersion 10
9+
targetSdkVersion 27
10+
versionCode 1
11+
versionName "1.0"
12+
13+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14+
15+
}
16+
17+
buildTypes {
18+
release {
19+
minifyEnabled false
20+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21+
}
22+
}
23+
24+
}
25+
26+
dependencies {
27+
implementation fileTree(dir: 'libs', include: ['*.jar'])
28+
29+
api (project(':aws-android-sdk-pinpoint')) {
30+
exclude group: 'com.google.android', module: 'android'
31+
}
32+
33+
testImplementation 'junit:junit:4.12'
34+
androidTestImplementation 'com.android.support.test:runner:1.0.2'
35+
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
36+
androidTestImplementation project(':aws-android-sdk-testutils')
37+
}
38+
39+
devicefarm {
40+
41+
// Required. The Project must already exist. You can create a project in the AWS console.
42+
projectName "AWSAndroidKeyStoreTester"
43+
44+
// Required. You must specify either accessKey and secretKey OR roleArn. roleArn takes precedence.
45+
authentication {
46+
accessKey "$System.env.DEVICEFARM_ACCESS_KEY"
47+
secretKey "$System.env.DEVICEFARM_SECRET_KEY"
48+
}
49+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
/**
2+
* Copyright 2019-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package com.amazonaws.mobileconnectors.pinpoint.analytics;
17+
18+
import android.content.Context;
19+
import android.net.wifi.WifiManager;
20+
import android.support.test.InstrumentationRegistry;
21+
import android.support.test.runner.AndroidJUnit4;
22+
import android.util.Log;
23+
24+
import com.amazonaws.auth.CognitoCachingCredentialsProvider;
25+
import com.amazonaws.mobileconnectors.pinpoint.PinpointConfiguration;
26+
import com.amazonaws.mobileconnectors.pinpoint.PinpointManager;
27+
import com.amazonaws.regions.Regions;
28+
import com.amazonaws.testutils.AWSTestBase;
29+
30+
import org.junit.After;
31+
import org.junit.Before;
32+
import org.junit.Test;
33+
import org.junit.runner.RunWith;
34+
35+
import java.util.UUID;
36+
import java.util.concurrent.TimeUnit;
37+
38+
import static java.lang.Thread.sleep;
39+
import static junit.framework.TestCase.assertTrue;
40+
import static org.junit.Assert.assertEquals;
41+
import static org.junit.Assert.assertNotNull;
42+
43+
/**
44+
* Instrumented test, which will execute on an Android device.
45+
*
46+
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
47+
*/
48+
@RunWith(AndroidJUnit4.class)
49+
public class SubmitEventsIntegrationTest extends AWSTestBase {
50+
51+
private static Context appContext;
52+
53+
private PinpointManager pinpointManager;
54+
private PinpointConfiguration pinpointConfiguration;
55+
private CognitoCachingCredentialsProvider credentialsProvider;
56+
private WifiManager wifiManager;
57+
58+
private String appId;
59+
private Regions regions;
60+
61+
private static String TAG = SubmitEventsIntegrationTest.class.getSimpleName();
62+
63+
@Before
64+
public void setUp() throws Exception {
65+
appContext = InstrumentationRegistry.getTargetContext();
66+
appContext.deleteDatabase("awspinpoint.db");
67+
68+
wifiManager = (WifiManager) InstrumentationRegistry
69+
.getContext().getSystemService(Context.WIFI_SERVICE);
70+
assertTrue(wifiManager.setWifiEnabled(true));
71+
72+
appId = getPackageConfigure("pinpoint")
73+
.getString("AppId");
74+
regions = Regions.fromName(getPackageConfigure("pinpoint")
75+
.getString("Region"));
76+
77+
credentialsProvider = new CognitoCachingCredentialsProvider(
78+
appContext,
79+
getPackageConfigure("core")
80+
.getString("identity_pool_id"),
81+
Regions.US_EAST_1);
82+
pinpointConfiguration = new PinpointConfiguration(appContext,
83+
appId,
84+
regions,
85+
credentialsProvider);
86+
pinpointManager = new PinpointManager(pinpointConfiguration);
87+
}
88+
89+
@After
90+
public void tearDown() {
91+
assertTrue(wifiManager.setWifiEnabled(true));
92+
pinpointManager.getAnalyticsClient().closeDB();
93+
appContext.deleteDatabase("awspinpoint.db");
94+
}
95+
96+
@Test
97+
public void testPinpointManagerInitialization() {
98+
assertNotNull(pinpointManager);
99+
assertNotNull(pinpointManager.getAnalyticsClient());
100+
assertNotNull(pinpointManager.getNotificationClient());
101+
assertNotNull(pinpointManager.getPinpointContext());
102+
assertNotNull(pinpointManager.getSessionClient());
103+
assertNotNull(pinpointManager.getTargetingClient());
104+
105+
assertEquals(0, pinpointManager.getAnalyticsClient().getAllEvents().size());
106+
assertEquals(pinpointManager.getPinpointContext().getPinpointConfiguration(),
107+
pinpointConfiguration);
108+
assertEquals(pinpointManager.getPinpointContext().getApplicationContext(), appContext);
109+
}
110+
111+
@Test
112+
public void testSubmitEvents() {
113+
Log.d(TAG, "Events in database before calling recordEvent(): " +
114+
pinpointManager.getAnalyticsClient().getAllEvents().size());
115+
116+
pinpointManager.getSessionClient().startSession();
117+
for (int i = 0; i < 10; i++) {
118+
AnalyticsEvent analyticsEvent =
119+
pinpointManager.getAnalyticsClient().createEvent("EventName-" + UUID.randomUUID().toString())
120+
.withAttribute("DemoAttribute1", "DemoAttributeValue1")
121+
.withAttribute("DemoAttribute2", "DemoAttributeValue2")
122+
.withMetric("DemoMetric1", Math.random());
123+
124+
pinpointManager.getAnalyticsClient().recordEvent(analyticsEvent);
125+
}
126+
pinpointManager.getSessionClient().stopSession();
127+
128+
Log.d(TAG, "Events in database after calling submitEvents() before submitting: " +
129+
pinpointManager.getAnalyticsClient().getAllEvents().size());
130+
131+
assertEquals(12, pinpointManager.getAnalyticsClient().getAllEvents().size());
132+
133+
pinpointManager.getAnalyticsClient().submitEvents();
134+
135+
long timeSleptSoFar = 0;
136+
while (timeSleptSoFar < TimeUnit.SECONDS.toMillis(60)) {
137+
try {
138+
sleep(TimeUnit.SECONDS.toMillis(5));
139+
} catch (InterruptedException ie) {
140+
ie.printStackTrace();
141+
}
142+
timeSleptSoFar += TimeUnit.SECONDS.toMillis(5);
143+
if (pinpointManager.getAnalyticsClient().getAllEvents().size() == 0) {
144+
break;
145+
}
146+
}
147+
148+
Log.d(TAG, "Events in database after calling submitEvents() after submitting: " +
149+
pinpointManager.getAnalyticsClient().getAllEvents().size());
150+
151+
assertEquals(0, pinpointManager.getAnalyticsClient().getAllEvents().size());
152+
}
153+
154+
public void testSubmitEventsNetworkDisconnectAndReconnect() {
155+
Log.d(TAG, "Events in database before calling recordEvent(): " +
156+
pinpointManager.getAnalyticsClient().getAllEvents().size());
157+
158+
pinpointManager.getSessionClient().startSession();
159+
for (int i = 0; i < 10; i++) {
160+
AnalyticsEvent analyticsEvent =
161+
pinpointManager.getAnalyticsClient().createEvent("EventName-" + UUID.randomUUID().toString())
162+
.withAttribute("DemoAttribute1", "DemoAttributeValue1")
163+
.withAttribute("DemoAttribute2", "DemoAttributeValue2")
164+
.withMetric("DemoMetric1", Math.random());
165+
166+
pinpointManager.getAnalyticsClient().recordEvent(analyticsEvent);
167+
}
168+
pinpointManager.getSessionClient().stopSession();
169+
170+
// All event records. Now turn off the network connectivity
171+
// Set Wifi Network offline and expect submitEvents to preserve
172+
// the events in the database and not delete them.
173+
assertTrue(wifiManager.setWifiEnabled(false));
174+
try {
175+
sleep(10000);
176+
} catch (Exception ex) {
177+
ex.printStackTrace();
178+
}
179+
180+
Log.d(TAG, "Events in database after calling submitEvents() before submitting: " +
181+
pinpointManager.getAnalyticsClient().getAllEvents().size());
182+
183+
assertEquals(12, pinpointManager.getAnalyticsClient().getAllEvents().size());
184+
185+
pinpointManager.getAnalyticsClient().submitEvents();
186+
187+
// Set Wifi Network offline
188+
// Once network comes back online, submitEvents again and make
189+
// sure events are being removed from the local database.
190+
assertTrue(wifiManager.setWifiEnabled(true));
191+
try {
192+
sleep(10000);
193+
} catch (Exception ex) {
194+
ex.printStackTrace();
195+
}
196+
197+
pinpointManager.getAnalyticsClient().submitEvents();
198+
try {
199+
sleep(5000);
200+
} catch (Exception ex) {
201+
ex.printStackTrace();
202+
}
203+
204+
long timeSleptSoFar = 0;
205+
while (timeSleptSoFar < TimeUnit.SECONDS.toMillis(60)) {
206+
try {
207+
sleep(TimeUnit.SECONDS.toMillis(5));
208+
} catch (InterruptedException ie) {
209+
ie.printStackTrace();
210+
}
211+
timeSleptSoFar += TimeUnit.SECONDS.toMillis(5);
212+
if (pinpointManager.getAnalyticsClient().getAllEvents().size() == 0) {
213+
break;
214+
}
215+
}
216+
217+
Log.d(TAG, "Events in database after calling submitEvents() after submitting: " +
218+
pinpointManager.getAnalyticsClient().getAllEvents().size());
219+
220+
assertEquals(0, pinpointManager.getAnalyticsClient().getAllEvents().size());
221+
}
222+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="com.amazonaws.aws_android_sdk_pinpoint_test">
3+
<uses-permission android:name="android.permission.INTERNET"/>
4+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
5+
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
6+
</manifest>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<resources>
2+
<string name="app_name">aws-android-sdk-pinpoint-test</string>
3+
</resources>

0 commit comments

Comments
 (0)