Skip to content

Commit 395d42c

Browse files
authored
Merge pull request #39 from optimizely/wifi
Preemptively flush events when wifi is available if available
2 parents b780602 + 4522f30 commit 395d42c

File tree

5 files changed

+62
-11
lines changed

5 files changed

+62
-11
lines changed

.idea/dictionaries/jdeffibaugh.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

event-handler/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<intent-filter>
1818
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
1919
<action android:name="android.intent.action.BOOT_COMPLETED" />
20+
<action android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" />
2021
</intent-filter>
2122
</receiver>
2223
</application>

event-handler/src/main/java/com/optimizely/ab/android/event_handler/EventRescheduler.java

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,26 @@
1616

1717
package com.optimizely.ab.android.event_handler;
1818

19+
import android.app.AlarmManager;
1920
import android.content.BroadcastReceiver;
2021
import android.content.Context;
2122
import android.content.Intent;
23+
import android.net.wifi.WifiManager;
24+
import android.support.annotation.NonNull;
2225

2326
import com.optimizely.ab.android.shared.ServiceScheduler;
2427

2528
import org.slf4j.Logger;
2629
import org.slf4j.LoggerFactory;
2730

31+
import static android.content.Context.ALARM_SERVICE;
32+
2833
/**
2934
* Reschedules event flushing after package updates and reboots
30-
*
35+
* <p>
3136
* After the app is updated or the phone is rebooted the event flushing
3237
* jobs scheduled by {@link ServiceScheduler} are cancelled.
33-
*
38+
* <p>
3439
* This code is called by the Android Framework. The Intent Filters are registered
3540
* AndroidManifest.xml.
3641
*
@@ -46,13 +51,37 @@ public class EventRescheduler extends BroadcastReceiver {
4651
*/
4752
@Override
4853
public void onReceive(Context context, Intent intent) {
49-
if ((context != null && intent != null) && (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED) ||
50-
intent.getAction().equals(Intent.ACTION_MY_PACKAGE_REPLACED))) {
51-
intent = new Intent(context, EventIntentService.class);
52-
context.startService(intent);
53-
logger.info("Rescheduling event flushing if necessary");
54+
if (context != null && intent != null) {
55+
ServiceScheduler serviceScheduler = new ServiceScheduler(
56+
(AlarmManager) context.getSystemService(ALARM_SERVICE),
57+
new ServiceScheduler.PendingIntentFactory(context),
58+
LoggerFactory.getLogger(ServiceScheduler.class));
59+
Intent eventServiceIntent = new Intent(context, EventIntentService.class);
60+
reschedule(context, intent, eventServiceIntent, serviceScheduler);
5461
} else {
5562
logger.warn("Received invalid broadcast to event rescheduler");
5663
}
5764
}
65+
66+
void reschedule(@NonNull Context context, @NonNull Intent broadcastIntent, @NonNull Intent eventServiceIntent, @NonNull ServiceScheduler serviceScheduler) {
67+
if (broadcastIntent.getAction().equals(Intent.ACTION_BOOT_COMPLETED) ||
68+
broadcastIntent.getAction().equals(Intent.ACTION_MY_PACKAGE_REPLACED)) {
69+
context.startService(eventServiceIntent);
70+
logger.info("Rescheduling event flushing if necessary");
71+
} else if (broadcastIntent.getAction().equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)
72+
&& broadcastIntent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
73+
74+
if (serviceScheduler.isScheduled(eventServiceIntent)) {
75+
// If we get wifi and the event flushing service is scheduled preemptively
76+
// flush events before the next interval occurs. If sending fails even
77+
// with wifi the service will be rescheduled on the interval.
78+
// Wifi connection state changes all the time and starting services is expensive
79+
// so it's important to only do this if we have stored events.
80+
context.startService(eventServiceIntent);
81+
logger.info("Preemptively flushing events since wifi became available");
82+
}
83+
} else {
84+
logger.warn("Received unsupported broadcast action to event rescheduler");
85+
}
86+
}
5887
}

event-handler/src/test/java/com/optimizely/ab/android/event_handler/EventReschedulerTest.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@
1717

1818
import android.content.Context;
1919
import android.content.Intent;
20+
import android.net.wifi.WifiManager;
2021
import android.os.Build;
2122
import android.support.annotation.RequiresApi;
2223

24+
import com.optimizely.ab.android.shared.ServiceScheduler;
25+
2326
import org.junit.Before;
2427
import org.junit.Test;
2528
import org.junit.runner.RunWith;
2629
import org.mockito.runners.MockitoJUnitRunner;
2730
import org.slf4j.Logger;
28-
2931
import static org.mockito.Mockito.mock;
3032
import static org.mockito.Mockito.verify;
3133
import static org.mockito.Mockito.when;
@@ -67,7 +69,7 @@ public void onReceiveNullContext() {
6769
public void onReceiveInvalidAction() {
6870
when(intent.getAction()).thenReturn("invalid");
6971
rescheduler.onReceive(context, intent);
70-
verify(logger).warn("Received invalid broadcast to event rescheduler");
72+
verify(logger).warn("Received unsupported broadcast action to event rescheduler");
7173
}
7274

7375
@Test
@@ -84,4 +86,16 @@ public void onReceiveValidPackageReplaced() {
8486
rescheduler.onReceive(context, intent);
8587
verify(logger).info("Rescheduling event flushing if necessary");
8688
}
89+
90+
@Test
91+
public void flushOnWifiConnectionIfScheduled() {
92+
final Intent eventServiceIntent = mock(Intent.class);
93+
ServiceScheduler serviceScheduler = mock(ServiceScheduler.class);
94+
when(intent.getAction()).thenReturn(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
95+
when(intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)).thenReturn(true);
96+
when(serviceScheduler.isScheduled(eventServiceIntent)).thenReturn(true);
97+
rescheduler.reschedule(context, intent, eventServiceIntent, serviceScheduler);
98+
verify(context).startService(eventServiceIntent);
99+
verify(logger).info("Preemptively flushing events since wifi became available");
100+
}
87101
}

test-app/src/main/java/com/optimizely/ab/android/test_app/MyApplication.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ public void onCreate() {
6565
// tests setup not work and the Espresso tests will fail. Also, the project id passed here
6666
// must match the project id of the compiled in Optimizely data file in rest/raw/data_file.json.
6767
optimizelyManager = OptimizelyManager.builder(PROJECT_ID)
68-
.withEventHandlerDispatchInterval(3, TimeUnit.SECONDS)
69-
.withDataFileDownloadInterval(30, TimeUnit.SECONDS)
68+
.withEventHandlerDispatchInterval(3, TimeUnit.MINUTES)
69+
.withDataFileDownloadInterval(30, TimeUnit.MINUTES)
7070
.build();
7171
}
7272
}

0 commit comments

Comments
 (0)