Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(#12): resume scheduler after background restriction removed #13

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions src/com/github/iusmac/sevensim/scheduler/AlarmReceiver.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.github.iusmac.sevensim.scheduler;

import android.app.ActivityManager;
import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;

import com.github.iusmac.sevensim.Logger;
import com.github.iusmac.sevensim.ForegroundService;
Expand All @@ -13,6 +16,7 @@
import java.time.LocalDateTime;

import javax.inject.Inject;
import javax.inject.Provider;

/**
* This static broadcast receiver will be triggered exclusively by the {@link AlarmManager}, with
Expand All @@ -24,6 +28,12 @@ public final class AlarmReceiver extends Hilt_AlarmReceiver {
@Inject
Logger.Factory loggerFactory;

@Inject
ActivityManager mActivityManager;

@Inject
Provider<SubscriptionScheduler> mSubscriptionSchedulerProvider;

private Logger mLogger;

@Override
Expand All @@ -32,7 +42,9 @@ public void onReceive(final Context context, final Intent intent) {

mLogger = loggerFactory.create(getClass().getSimpleName());

mLogger.d("onReceive() : intent=" + intent);
final boolean isBgRestricted = mActivityManager.isBackgroundRestricted();

mLogger.d("onReceive() : isBgRestricted=%s,intent=%s.", isBgRestricted, intent);

final LocalDateTime now = LocalDateTime.now();

Expand All @@ -43,7 +55,44 @@ public void onReceive(final Context context, final Intent intent) {
ForegroundService.syncAllSubscriptionsEnabledState(context, now, overrideUserPreference);

// Schedule the next iteration processing of weekly repeat schedules to happen no earlier
// than one minute from now as we already processed schedules at this time
ForegroundService.updateNextWeeklyRepeatScheduleProcessingIter(context, now.plusMinutes(1));
// than one minute from now as we already processed schedules at this time. Note that, if
// the background usage is restricted, we won't be able to re-schedule using foreground
// service. Therefore, we're going to do this here, otherwise when the user will remove
// the background restriction for the app, the next schedule iteration processing will
// actually never happen again because it was never re-scheduled.
// Also note that, we *DO NOT* want to execute the above tasks here. This to avoid holding
// this BroadcastReceiver for too long, as it could cause the system to consider it
// non-responsive and ANR the entire app. Instead, we *want* them to be handled by the
// foreground service, which will detect background restriction and inform the user about
// the issue via a notification.
if (!isBgRestricted) {
ForegroundService.updateNextWeeklyRepeatScheduleProcessingIter(context,
now.plusMinutes(1));
} else {
final PendingResult result = goAsync();
AsyncHandler.post(() -> {
try {
mSubscriptionSchedulerProvider.get()
.updateNextWeeklyRepeatScheduleProcessingIter(now.plusMinutes(1));
} finally {
result.finish();
}
});
}
}

private static class AsyncHandler {
static final Handler sHandler;

static {
final HandlerThread handlerThread = new HandlerThread(
AlarmReceiver.class.getSimpleName() + "Thread");
handlerThread.start();
sHandler = Handler.createAsync(handlerThread.getLooper());
}

static void post(final Runnable r) {
sHandler.post(r);
}
}
}