fix(mobile,Android): throttle detail progress notifications & wait on foregroundInfo (#907)

This commit is contained in:
Fynn Petersen-Frey 2022-11-01 03:02:06 +01:00 committed by GitHub
parent cfa04fadd1
commit dcefd53bfe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 18 deletions

View file

@ -43,8 +43,9 @@ class BackgroundService {
bool _errorGracePeriodExceeded = true;
int _uploadedAssetsCount = 0;
int _assetsToUploadCount = 0;
int _lastDetailProgressUpdate = 0;
String _lastPrintedProgress = "";
late final _Throttle _throttleNotificationUpdates =
_Throttle(_updateDetailProgress, const Duration(milliseconds: 400));
bool get isBackgroundInitialized {
return _isBackgroundInitialized;
@ -447,21 +448,20 @@ class BackgroundService {
}
void _onProgress(int sent, int total) {
final int now = Timeline.now;
// limit updates to 10 per second (or Android drops important notifications)
if (now > _lastDetailProgressUpdate + 100000) {
final String msg = _humanReadableBytesProgress(sent, total);
// only update if message actually differs (to stop many useless notification updates on large assets or slow connections)
if (msg != _lastPrintedProgress) {
_lastDetailProgressUpdate = now;
_lastPrintedProgress = msg;
_updateNotification(
progress: sent,
max: total,
isDetail: true,
content: msg,
);
}
_throttleNotificationUpdates(sent, total);
}
void _updateDetailProgress(int sent, int total) {
final String msg = _humanReadableBytesProgress(sent, total);
// only update if message actually differs (to stop many useless notification updates on large assets or slow connections)
if (msg != _lastPrintedProgress) {
_lastPrintedProgress = msg;
_updateNotification(
progress: sent,
max: total,
isDetail: true,
content: msg,
);
}
}
@ -532,6 +532,34 @@ class BackgroundService {
}
}
class _Throttle {
_Throttle(this._fun, Duration interval) : _interval = interval.inMicroseconds;
final void Function(int, int) _fun;
final int _interval;
int _invokedAt = 0;
Timer? _timer;
int _progress = 0;
int _total = 0;
void call(int progress, int total) {
final time = Timeline.now;
_progress = progress;
_total = total;
if (time > _invokedAt + _interval) {
_timer?.cancel();
_onTimeElapsed();
} else {
_timer ??= Timer(Duration(microseconds: _interval), _onTimeElapsed);
}
}
void _onTimeElapsed() {
_invokedAt = Timeline.now;
_fun(_progress, _total);
_timer = null;
}
}
/// entry point called by Kotlin/Java code; needs to be a top-level function
@pragma('vm:entry-point')
void _nativeEntry() {