mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-25 18:17:20 +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_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>
|
<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 -->
|
<!-- MessageDetailsRecipient -->
|
||||||
<string name="MessageDetailsRecipient_failed_to_send">Failed to send</string>
|
<string name="MessageDetailsRecipient_failed_to_send">Failed to send</string>
|
||||||
<string name="MessageDetailsRecipient_new_safety_number">New safety number</string>
|
<string name="MessageDetailsRecipient_new_safety_number">New safety number</string>
|
||||||
@ -477,6 +480,9 @@
|
|||||||
<!-- PlayServicesProblemFragment -->
|
<!-- 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>
|
<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 -->
|
<!-- RatingManager -->
|
||||||
<string name="RatingManager_rate_this_app">Rate this app</string>
|
<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>
|
<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_contacts">Contacts</string>
|
||||||
<string name="SearchFragment_header_messages">Messages</string>
|
<string name="SearchFragment_header_messages">Messages</string>
|
||||||
|
|
||||||
|
<!-- SendJob -->
|
||||||
|
<string name="SendJob_sending_a_message">Sending a message...</string>
|
||||||
|
|
||||||
<!-- SharedContactDetailsActivity -->
|
<!-- SharedContactDetailsActivity -->
|
||||||
<string name="SharedContactDetailsActivity_add_to_contacts">Add to Contacts</string>
|
<string name="SharedContactDetailsActivity_add_to_contacts">Add to Contacts</string>
|
||||||
<string name="SharedContactDetailsActivity_invite_to_signal">Invite to Signal</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 android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.jobmanager.dependencies.ContextDependent;
|
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.MasterSecretRequirement;
|
||||||
import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirement;
|
import org.thoughtcrime.securesms.jobs.requirements.SqlCipherMigrationRequirement;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
|
import org.thoughtcrime.securesms.service.GenericForegroundService;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.UUID;
|
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_COUNT = "Job_retry_count";
|
||||||
static final String KEY_RETRY_UNTIL = "Job_retry_until";
|
static final String KEY_RETRY_UNTIL = "Job_retry_until";
|
||||||
static final String KEY_SUBMIT_TIME = "Job_submit_time";
|
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_MASTER_SECRET = "Job_requires_master_secret";
|
||||||
static final String KEY_REQUIRES_SQLCIPHER = "Job_requires_sqlcipher";
|
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));
|
initialize(new SafeData(data));
|
||||||
|
|
||||||
|
boolean foregroundRunning = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (withinRetryLimits(data)) {
|
if (withinRetryLimits(data)) {
|
||||||
if (requirementsMet(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();
|
onRun();
|
||||||
|
|
||||||
log("Successfully completed." + logSuffix());
|
log("Successfully completed." + logSuffix());
|
||||||
return Result.SUCCESS;
|
return Result.SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
@ -79,6 +92,11 @@ public abstract class Job extends Worker implements Serializable {
|
|||||||
}
|
}
|
||||||
warn("Failing due to an exception." + logSuffix(), e);
|
warn("Failing due to an exception." + logSuffix(), e);
|
||||||
return cancel();
|
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();
|
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
|
* Called after a run has finished and we've determined a retry is required, but before the next
|
||||||
* attempt is run.
|
* attempt is run.
|
||||||
@ -158,7 +184,7 @@ public abstract class Job extends Worker implements Serializable {
|
|||||||
return Result.SUCCESS;
|
return Result.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean requirementsMet(Data data) {
|
private boolean requirementsMet(@NonNull Data data) {
|
||||||
boolean met = true;
|
boolean met = true;
|
||||||
|
|
||||||
if (data.getBoolean(KEY_REQUIRES_MASTER_SECRET, false)) {
|
if (data.getBoolean(KEY_REQUIRES_MASTER_SECRET, false)) {
|
||||||
@ -172,7 +198,7 @@ public abstract class Job extends Worker implements Serializable {
|
|||||||
return met;
|
return met;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean withinRetryLimits(Data data) {
|
private boolean withinRetryLimits(@NonNull Data data) {
|
||||||
int retryCount = data.getInt(KEY_RETRY_COUNT, 0);
|
int retryCount = data.getInt(KEY_RETRY_COUNT, 0);
|
||||||
long retryUntil = data.getLong(KEY_RETRY_UNTIL, 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;
|
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) {
|
private void log(@NonNull String message) {
|
||||||
log(message, null);
|
log(message, null);
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ public class JobManager {
|
|||||||
Data.Builder dataBuilder = new Data.Builder().putInt(Job.KEY_RETRY_COUNT, jobParameters.getRetryCount())
|
Data.Builder dataBuilder = new Data.Builder().putInt(Job.KEY_RETRY_COUNT, jobParameters.getRetryCount())
|
||||||
.putLong(Job.KEY_RETRY_UNTIL, jobParameters.getRetryUntil())
|
.putLong(Job.KEY_RETRY_UNTIL, jobParameters.getRetryUntil())
|
||||||
.putLong(Job.KEY_SUBMIT_TIME, System.currentTimeMillis())
|
.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_MASTER_SECRET, jobParameters.requiresMasterSecret())
|
||||||
.putBoolean(Job.KEY_REQUIRES_SQLCIPHER, jobParameters.requiresSqlCipher());
|
.putBoolean(Job.KEY_REQUIRES_SQLCIPHER, jobParameters.requiresSqlCipher());
|
||||||
Data data = job.serialize(dataBuilder);
|
Data data = job.serialize(dataBuilder);
|
||||||
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.jobs;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
import org.thoughtcrime.securesms.jobmanager.JobParameters;
|
import org.thoughtcrime.securesms.jobmanager.JobParameters;
|
||||||
import org.thoughtcrime.securesms.jobmanager.SafeData;
|
import org.thoughtcrime.securesms.jobmanager.SafeData;
|
||||||
@ -43,6 +44,11 @@ public class PushNotificationReceiveJob extends PushReceivedJob implements Injec
|
|||||||
return dataBuilder.build();
|
return dataBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDescription() {
|
||||||
|
return context.getString(R.string.PushNotificationReceiveJob_retrieving_a_message);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRun() throws IOException {
|
public void onRun() throws IOException {
|
||||||
receiver.retrieveMessages(new SignalServiceMessageReceiver.MessageReceivedCallback() {
|
receiver.retrieveMessages(new SignalServiceMessageReceiver.MessageReceivedCallback() {
|
||||||
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.BuildConfig;
|
import org.thoughtcrime.securesms.BuildConfig;
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.TextSecureExpiredException;
|
import org.thoughtcrime.securesms.TextSecureExpiredException;
|
||||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
@ -31,6 +32,11 @@ public abstract class SendJob extends MasterSecretJob {
|
|||||||
super(context, parameters);
|
super(context, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDescription() {
|
||||||
|
return context.getString(R.string.SendJob_sending_a_message);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onRun(MasterSecret masterSecret) throws Exception {
|
public final void onRun(MasterSecret masterSecret) throws Exception {
|
||||||
if (Util.getDaysTillBuildExpiry() <= 0) {
|
if (Util.getDaysTillBuildExpiry() <= 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user