Skip to content

Commit

Permalink
Stop transfer service if all transfers complete (#2950)
Browse files Browse the repository at this point in the history
  • Loading branch information
tylerjroach committed Jul 22, 2022
1 parent bd4e41d commit 99f42a7
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 27 deletions.
Expand Up @@ -49,14 +49,19 @@ public class TransferService extends Service {
static TransferNetworkLossHandler transferNetworkLossHandler;

/**
* A flag indicates whether the service is started the first time.
* A flag indicates whether or not the receiver has is started the first time.
*/
boolean isReceiverNotRegistered = true;

/**
* A flag that indicates whether or not the Foreground notification started
*/
boolean hasNotificationShown = false;

/**
* The identifier used for the notification.
*/
private int ongoingNotificationId = 1;
private int ongoingNotificationId = 3462;

/**
* This flag determines if the notification needs to be removed
Expand Down Expand Up @@ -137,7 +142,8 @@ public int onStartCommand(Intent intent, int flags, int startId) {
* b) An identifier for the ongoing notification c) Flag that determines if the notification
* needs to be removed when the service is moved out of the foreground state.
*/
if (Build.VERSION.SDK_INT >= ANDROID_OREO) {
if (Build.VERSION.SDK_INT >= ANDROID_OREO && !hasNotificationShown) {
hasNotificationShown = true;
try {
synchronized (this) {
final Notification userProvidedNotification = (Notification) intent.getParcelableExtra(INTENT_KEY_NOTIFICATION);
Expand Down
Expand Up @@ -127,4 +127,10 @@ public static TransferState getState(String stateAsString) {
+ " transfer will be have state set to UNKNOWN.");
return UNKNOWN;
}

protected static boolean isFinalState(TransferState transferState) {
return TransferState.COMPLETED.equals(transferState) ||
TransferState.FAILED.equals(transferState) ||
TransferState.CANCELED.equals(transferState);
}
}
Expand Up @@ -16,6 +16,7 @@
package com.amazonaws.mobileconnectors.s3.transferutility;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;

Expand Down Expand Up @@ -70,6 +71,11 @@ class TransferStatusUpdater {
*/
private final Handler mainHandler;

/**
* Context required to stop TransferService on all transfers completed
*/
private Context context;

/**
* The Singleton instance.
*/
Expand All @@ -88,8 +94,9 @@ class TransferStatusUpdater {
* The updater is made a singleton. Use #getInstance for getting
* the object of the updater.
*/
TransferStatusUpdater(TransferDBUtil dbUtilInstance) {
TransferStatusUpdater(TransferDBUtil dbUtilInstance, Context context) {
dbUtil = dbUtilInstance;
this.context = context;
mainHandler = new Handler(Looper.getMainLooper());
transfers = new ConcurrentHashMap<Integer, TransferRecord>();
}
Expand All @@ -103,7 +110,7 @@ class TransferStatusUpdater {
public static synchronized TransferStatusUpdater getInstance(Context context) {
if (transferStatusUpdater == null) {
dbUtil = new TransferDBUtil(context);
transferStatusUpdater = new TransferStatusUpdater(dbUtil);
transferStatusUpdater = new TransferStatusUpdater(dbUtil, context);
}
return transferStatusUpdater;
}
Expand Down Expand Up @@ -212,33 +219,44 @@ synchronized void updateState(final int id, final TransferState newState) {

synchronized (LISTENERS) {
final List<TransferListener> list = LISTENERS.get(id);
if (list == null || list.isEmpty()) {
return;
}
if (list != null && !list.isEmpty()) {
// invoke TransferListener callback on main thread
for (final TransferListener l : list) {
// If instance is TransferStatusListener, post immediately.
// Posting to main thread can cause a missed status.
if (l instanceof TransferObserver.TransferStatusListener) {
l.onStateChanged(id, newState);
} else {
mainHandler.post(new Runnable() {
@Override
public void run() {
l.onStateChanged(id, newState);
}
});
}
}

// invoke TransferListener callback on main thread
for (final TransferListener l : list) {
// If instance is TransferStatusListener, post immediately.
// Posting to main thread can cause a missed status.
if (l instanceof TransferObserver.TransferStatusListener) {
l.onStateChanged(id, newState);
} else {
mainHandler.post(new Runnable() {
@Override
public void run() {
l.onStateChanged(id, newState);
}
});
// remove all LISTENERS when the transfer is in a final state so
// as to release resources ASAP.
if (TransferState.isFinalState(newState)) {
list.clear();
}
}
}

// remove all LISTENERS when the transfer is in a final state so
// as to release resources ASAP.
if (TransferState.COMPLETED.equals(newState) ||
TransferState.FAILED.equals(newState) ||
TransferState.CANCELED.equals(newState)) {
list.clear();
// If all transfers in local map are completed,
// stop TransferService to clear foreground notification
boolean stopTransferService = true;
for (TransferRecord record: transfers.values()) {
if (!TransferState.isFinalState(record.state)) {
stopTransferService = false;
LOGGER.info("Transfers still pending, keeping TransferService running.");
}
break;
}
if (stopTransferService) {
LOGGER.info("All transfers in final state. Stopping TransferService");
context.stopService(new Intent(context, TransferService.class));
}
}

Expand Down

0 comments on commit 99f42a7

Please sign in to comment.