mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 20:15:21 +00:00
Show foreground notification for jobs when network is restricted.
Occasionally a job may be run when the app is in a network-restricted mode, like a form of doze. When this happens, jobs can timeout due to lack of network access, causing a cascade of job delays. This is particularly bad in the case of message retrieval. To prevent this, if a job that normally requires network detects that no network is available when running, then we start a foreground notification.
This commit is contained in:
parent
c86c2c51bb
commit
e4b56d4e40
@ -371,6 +371,9 @@
|
||||
<string name="InviteActivity_no_app_to_share_to">It looks like you don\'t have any apps to share to.</string>
|
||||
<string name="InviteActivity_friends_dont_let_friends_text_unencrypted">Friends don\'t let friends chat unencrypted.</string>
|
||||
|
||||
<!-- Job -->
|
||||
<string name="Job_working_in_the_background">Working in the background...</string>
|
||||
|
||||
<!-- MessageDetailsRecipient -->
|
||||
<string name="MessageDetailsRecipient_failed_to_send">Failed to send</string>
|
||||
<string name="MessageDetailsRecipient_new_safety_number">New safety number</string>
|
||||
@ -477,6 +480,9 @@
|
||||
<!-- PlayServicesProblemFragment -->
|
||||
<string name="PlayServicesProblemFragment_the_version_of_google_play_services_you_have_installed_is_not_functioning">The version of Google Play Services you have installed is not functioning correctly. Please reinstall Google Play Services and try again.</string>
|
||||
|
||||
<!-- PushNotificationReceiveJob -->
|
||||
<string name="PushNotificationReceiveJob_retrieving_a_message">Retrieving a message...</string>
|
||||
|
||||
<!-- RatingManager -->
|
||||
<string name="RatingManager_rate_this_app">Rate this app</string>
|
||||
<string name="RatingManager_if_you_enjoy_using_this_app_please_take_a_moment">If you enjoy using this app, please take a moment to help us by rating it.</string>
|
||||
@ -556,6 +562,9 @@
|
||||
<string name="SearchFragment_header_contacts">Contacts</string>
|
||||
<string name="SearchFragment_header_messages">Messages</string>
|
||||
|
||||
<!-- SendJob -->
|
||||
<string name="SendJob_sending_a_message">Sending a message...</string>
|
||||
|
||||
<!-- SharedContactDetailsActivity -->
|
||||
<string name="SharedContactDetailsActivity_add_to_contacts">Add to Contacts</string>
|
||||
<string name="SharedContactDetailsActivity_invite_to_signal">Invite to Signal</string>
|
||||
|
@ -5,10 +5,13 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.jobmanager.dependencies.ContextDependent;
|
||||
import org.thoughtcrime.securesms.jobmanager.requirements.NetworkRequirement;
|
||||
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
||||
import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirement;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.service.GenericForegroundService;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
@ -26,6 +29,7 @@ public abstract class Job extends Worker implements Serializable {
|
||||
static final String KEY_RETRY_COUNT = "Job_retry_count";
|
||||
static final String KEY_RETRY_UNTIL = "Job_retry_until";
|
||||
static final String KEY_SUBMIT_TIME = "Job_submit_time";
|
||||
static final String KEY_REQUIRES_NETWORK = "Job_requires_network";
|
||||
static final String KEY_REQUIRES_MASTER_SECRET = "Job_requires_master_secret";
|
||||
static final String KEY_REQUIRES_SQLCIPHER = "Job_requires_sqlcipher";
|
||||
|
||||
@ -58,10 +62,19 @@ public abstract class Job extends Worker implements Serializable {
|
||||
|
||||
initialize(new SafeData(data));
|
||||
|
||||
boolean foregroundRunning = false;
|
||||
|
||||
try {
|
||||
if (withinRetryLimits(data)) {
|
||||
if (requirementsMet(data)) {
|
||||
if (needsForegroundService(data)) {
|
||||
Log.i(TAG, "Running a foreground service with description '" + getDescription() + "' to aid in job execution." + logSuffix());
|
||||
GenericForegroundService.startForegroundTask(getApplicationContext(), getDescription());
|
||||
foregroundRunning = true;
|
||||
}
|
||||
|
||||
onRun();
|
||||
|
||||
log("Successfully completed." + logSuffix());
|
||||
return Result.SUCCESS;
|
||||
} else {
|
||||
@ -79,6 +92,11 @@ public abstract class Job extends Worker implements Serializable {
|
||||
}
|
||||
warn("Failing due to an exception." + logSuffix(), e);
|
||||
return cancel();
|
||||
} finally {
|
||||
if (foregroundRunning) {
|
||||
Log.i(TAG, "Stopping the foreground service." + logSuffix());
|
||||
GenericForegroundService.stopForegroundTask(getApplicationContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,6 +113,14 @@ public abstract class Job extends Worker implements Serializable {
|
||||
onAdded();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A string that represents what the task does. Will be shown in a foreground notification
|
||||
* if necessary.
|
||||
*/
|
||||
protected String getDescription() {
|
||||
return getApplicationContext().getString(R.string.Job_working_in_the_background);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after a run has finished and we've determined a retry is required, but before the next
|
||||
* attempt is run.
|
||||
@ -158,7 +184,7 @@ public abstract class Job extends Worker implements Serializable {
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
|
||||
private boolean requirementsMet(Data data) {
|
||||
private boolean requirementsMet(@NonNull Data data) {
|
||||
boolean met = true;
|
||||
|
||||
if (data.getBoolean(KEY_REQUIRES_MASTER_SECRET, false)) {
|
||||
@ -172,7 +198,7 @@ public abstract class Job extends Worker implements Serializable {
|
||||
return met;
|
||||
}
|
||||
|
||||
private boolean withinRetryLimits(Data data) {
|
||||
private boolean withinRetryLimits(@NonNull Data data) {
|
||||
int retryCount = data.getInt(KEY_RETRY_COUNT, 0);
|
||||
long retryUntil = data.getLong(KEY_RETRY_UNTIL, 0);
|
||||
|
||||
@ -183,6 +209,13 @@ public abstract class Job extends Worker implements Serializable {
|
||||
return System.currentTimeMillis() < retryUntil;
|
||||
}
|
||||
|
||||
private boolean needsForegroundService(@NonNull Data data) {
|
||||
NetworkRequirement networkRequirement = new NetworkRequirement(getApplicationContext());
|
||||
boolean requiresNetwork = data.getBoolean(KEY_REQUIRES_NETWORK, false);
|
||||
|
||||
return requiresNetwork && !networkRequirement.isPresent();
|
||||
}
|
||||
|
||||
private void log(@NonNull String message) {
|
||||
log(message, null);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public class JobManager {
|
||||
Data.Builder dataBuilder = new Data.Builder().putInt(Job.KEY_RETRY_COUNT, jobParameters.getRetryCount())
|
||||
.putLong(Job.KEY_RETRY_UNTIL, jobParameters.getRetryUntil())
|
||||
.putLong(Job.KEY_SUBMIT_TIME, System.currentTimeMillis())
|
||||
.putBoolean(Job.KEY_REQUIRES_NETWORK, jobParameters.requiresNetwork())
|
||||
.putBoolean(Job.KEY_REQUIRES_MASTER_SECRET, jobParameters.requiresMasterSecret())
|
||||
.putBoolean(Job.KEY_REQUIRES_SQLCIPHER, jobParameters.requiresSqlCipher());
|
||||
Data data = job.serialize(dataBuilder);
|
||||
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.jobs;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobParameters;
|
||||
import org.thoughtcrime.securesms.jobmanager.SafeData;
|
||||
@ -43,6 +44,11 @@ public class PushNotificationReceiveJob extends PushReceivedJob implements Injec
|
||||
return dataBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDescription() {
|
||||
return context.getString(R.string.PushNotificationReceiveJob_retrieving_a_message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun() throws IOException {
|
||||
receiver.retrieveMessages(new SignalServiceMessageReceiver.MessageReceivedCallback() {
|
||||
|
@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.TextSecureExpiredException;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
@ -31,6 +32,11 @@ public abstract class SendJob extends MasterSecretJob {
|
||||
super(context, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDescription() {
|
||||
return context.getString(R.string.SendJob_sending_a_message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onRun(MasterSecret masterSecret) throws Exception {
|
||||
if (Util.getDaysTillBuildExpiry() <= 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user