mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-21 00:50:58 +02:00
fix(playback): retain ReplayGain for SAF descriptor leases
Carry the original display name through playback leases to format-aware metadata reads. Cache successful normalization results by source identity, bound the cache, and retry transient read failures. Add regressions for descriptor hints, album gain fallback, and failed-read retries.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:spotiflac_android/services/playback_normalization.dart';
|
||||
|
||||
void main() {
|
||||
test(
|
||||
'descriptor normalization uses hint and caches by original URI',
|
||||
() async {
|
||||
var reads = 0;
|
||||
final cache = PlaybackNormalizationCache(
|
||||
readMetadata: (path, {displayName}) async {
|
||||
reads++;
|
||||
expect(path, '/proc/self/fd/42');
|
||||
expect(displayName, 'Song.flac');
|
||||
return {
|
||||
'replaygain_track_gain': '-6.00 dB',
|
||||
'replaygain_album_gain': '-3.00 dB',
|
||||
};
|
||||
},
|
||||
);
|
||||
expect(
|
||||
await cache.volumeFor(
|
||||
'/proc/self/fd/42',
|
||||
displayName: 'Song.flac',
|
||||
cacheKey: 'content://music/song',
|
||||
),
|
||||
closeTo(0.501187, 0.000001),
|
||||
);
|
||||
expect(
|
||||
await cache.volumeFor(
|
||||
'/proc/self/fd/99',
|
||||
displayName: 'Song.flac',
|
||||
cacheKey: 'content://music/song',
|
||||
),
|
||||
closeTo(0.501187, 0.000001),
|
||||
);
|
||||
expect(reads, 1);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'failed descriptor metadata does not poison local fallback cache',
|
||||
() async {
|
||||
var reads = 0;
|
||||
final cache = PlaybackNormalizationCache(
|
||||
readMetadata: (path, {displayName}) async {
|
||||
reads++;
|
||||
if (path.startsWith('/proc/')) {
|
||||
return {'error': 'descriptor access denied'};
|
||||
}
|
||||
return {'replaygain_album_gain': '-6.00 dB'};
|
||||
},
|
||||
);
|
||||
expect(
|
||||
await cache.volumeFor(
|
||||
'/proc/self/fd/42',
|
||||
displayName: 'Song.mp3',
|
||||
cacheKey: 'song',
|
||||
),
|
||||
1.0,
|
||||
);
|
||||
expect(
|
||||
await cache.volumeFor('/cache/Song.mp3', cacheKey: 'song'),
|
||||
closeTo(0.501187, 0.000001),
|
||||
);
|
||||
expect(reads, 2);
|
||||
},
|
||||
);
|
||||
|
||||
test('exceptions are retried and positive gain only attenuates', () async {
|
||||
var reads = 0;
|
||||
final cache = PlaybackNormalizationCache(
|
||||
readMetadata: (path, {displayName}) async {
|
||||
if (++reads == 1) throw StateError('temporarily unavailable');
|
||||
return {'replaygain_track_gain': '+6.00 dB'};
|
||||
},
|
||||
);
|
||||
expect(await cache.volumeFor('song'), 1.0);
|
||||
expect(await cache.volumeFor('song'), 1.0);
|
||||
expect(reads, 2);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user