1616
1717package com .optimizely .ab .android .event_handler ;
1818
19+ import android .app .AlarmManager ;
1920import android .content .BroadcastReceiver ;
2021import android .content .Context ;
2122import android .content .Intent ;
23+ import android .net .wifi .WifiManager ;
24+ import android .support .annotation .NonNull ;
2225
2326import com .optimizely .ab .android .shared .ServiceScheduler ;
2427
2528import org .slf4j .Logger ;
2629import 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}
0 commit comments