Skip to content

Commit

Permalink
Periodically "prod" the message pipe, when GCM is disabled
Browse files Browse the repository at this point in the history
Added an AlarmManager alarm, to periodically "prod" the
SignalServiceMessagePipe, waking any threads that may be
stuck in blocking wait, while the device sleeping.

Fixes signalapp#6644
// FREEBIE
  • Loading branch information
Dimitris Papavasiliou committed Oct 28, 2017
1 parent 4bf91aa commit 2c02f8f
Showing 1 changed file with 96 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.thoughtcrime.securesms.service;

import android.app.Service;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
Expand Down Expand Up @@ -45,6 +50,8 @@ public class MessageRetrievalService extends Service implements InjectableType,
private NetworkRequirement networkRequirement;
private NetworkRequirementProvider networkRequirementProvider;

private ProdAlarmReceiver prodAlarmReceiver = null;

@Inject
public SignalServiceMessageReceiver receiver;

Expand All @@ -68,6 +75,7 @@ public void onCreate() {
retrievalThread.start();

setForegroundIfNecessary();
enableProddingIfNecessary();
}

public int onStartCommand(Intent intent, int flags, int startId) {
Expand All @@ -88,6 +96,11 @@ public void onDestroy() {
retrievalThread.stopThread();
}

if (prodAlarmReceiver != null) {
prodAlarmReceiver.stop();
unregisterReceiver(prodAlarmReceiver);
}

sendBroadcast(new Intent("org.thoughtcrime.securesms.RESTART"));
}

Expand All @@ -103,6 +116,14 @@ public IBinder onBind(Intent intent) {
return null;
}

private void enableProddingIfNecessary() {
if (TextSecurePreferences.isGcmDisabled(this)) {
prodAlarmReceiver = new ProdAlarmReceiver();
registerReceiver(prodAlarmReceiver,
new IntentFilter(ProdAlarmReceiver.WAKE_UP_THREADS_ACTION));
}
}

private void setForegroundIfNecessary() {
if (TextSecurePreferences.isGcmDisabled(this)) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
Expand Down Expand Up @@ -184,6 +205,72 @@ public static void registerActivityStopped(Context activity) {
return pipe;
}

public class ProdAlarmReceiver extends BroadcastReceiver {

private final int PRODDING_TIMEOUT_SECONDS = 60;

private int pipes;

public static final String WAKE_UP_THREADS_ACTION = "org.thoughtcrime.securesms.ProdAlarReceiver.WAKE_UP_THREADS";

private void setOrCancelAlarm(Context context, boolean set) {
Intent intent = new Intent(WAKE_UP_THREADS_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

alarmManager.cancel(pendingIntent);

if (set) {
Log.w(TAG, "Setting repeating alarm to prod the message pipe.");

alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + TimeUnit.SECONDS.toMillis(PRODDING_TIMEOUT_SECONDS),
TimeUnit.SECONDS.toMillis(PRODDING_TIMEOUT_SECONDS),
pendingIntent);
} else {
Log.w(TAG, "Canceling message pipe prodding alarm.");
}
}

public synchronized void incrementPipes() {
if (pipes < 0) {
return;
}

pipes++;

if (pipes == 1) {
setOrCancelAlarm(MessageRetrievalService.this, true);
}
}

public synchronized void decrementPipes() {
if (pipes < 0) {
return;
}

pipes--;

assert (pipes >= 0);

if (pipes == 0) {
setOrCancelAlarm(MessageRetrievalService.this, false);
}
}

public synchronized void stop() {
pipes = -1;
setOrCancelAlarm(MessageRetrievalService.this, false);
}

@Override
public void onReceive(Context context, Intent intent) {
Log.w(TAG, "Prodding the message pipe.");
SignalServiceMessagePipe.prod();
}

}

private class MessageRetrievalThread extends Thread implements Thread.UncaughtExceptionHandler {

private AtomicBoolean stopThread = new AtomicBoolean(false);
Expand All @@ -204,6 +291,10 @@ public void run() {

SignalServiceMessagePipe localPipe = pipe;

if (prodAlarmReceiver != null) {
prodAlarmReceiver.incrementPipes();
}

try {
while (isConnectionNecessary() && !stopThread.get()) {
try {
Expand All @@ -230,6 +321,11 @@ public void onMessage(SignalServiceEnvelope envelope) {
Log.w(TAG, e);
} finally {
Log.w(TAG, "Shutting down pipe...");

if (prodAlarmReceiver != null) {
prodAlarmReceiver.decrementPipes();
}

shutdown(localPipe);
}

Expand Down

0 comments on commit 2c02f8f

Please sign in to comment.