Skip to content

Commit

Permalink
source: disable analysis for widget, screen saver; disabling analysis…
Browse files Browse the repository at this point in the history
… also disables entry discovery
  • Loading branch information
deckerst committed Oct 7, 2024
1 parent 618b63b commit 211f803
Show file tree
Hide file tree
Showing 17 changed files with 64 additions and 86 deletions.
15 changes: 5 additions & 10 deletions android/app/src/main/kotlin/deckers/thibault/aves/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -296,14 +296,11 @@ open class MainActivity : FlutterFragmentActivity() {
open fun extractIntentData(intent: Intent?): FieldMap {
when (val action = intent?.action) {
Intent.ACTION_MAIN -> {
val fields = HashMap<String, Any?>()
if (intent.getBooleanExtra(EXTRA_KEY_SAFE_MODE, false)) {
fields[INTENT_DATA_KEY_SAFE_MODE] = true
}
fields[INTENT_DATA_KEY_PAGE] = intent.getStringExtra(EXTRA_KEY_PAGE)
fields[INTENT_DATA_KEY_FILTERS] = extractFiltersFromIntent(intent)
fields[INTENT_DATA_KEY_EXPLORER_PATH] = intent.getStringExtra(EXTRA_KEY_EXPLORER_PATH)
return fields
return hashMapOf(
INTENT_DATA_KEY_PAGE to intent.getStringExtra(EXTRA_KEY_PAGE),
INTENT_DATA_KEY_FILTERS to extractFiltersFromIntent(intent),
INTENT_DATA_KEY_EXPLORER_PATH to intent.getStringExtra(EXTRA_KEY_EXPLORER_PATH),
)
}

Intent.ACTION_VIEW,
Expand Down Expand Up @@ -557,7 +554,6 @@ open class MainActivity : FlutterFragmentActivity() {
const val INTENT_DATA_KEY_MIME_TYPE = "mimeType"
const val INTENT_DATA_KEY_PAGE = "page"
const val INTENT_DATA_KEY_QUERY = "query"
const val INTENT_DATA_KEY_SAFE_MODE = "safeMode"
const val INTENT_DATA_KEY_SECURE_URIS = "secureUris"
const val INTENT_DATA_KEY_URI = "uri"
const val INTENT_DATA_KEY_WIDGET_ID = "widgetId"
Expand All @@ -566,7 +562,6 @@ open class MainActivity : FlutterFragmentActivity() {
const val EXTRA_KEY_EXPLORER_PATH = "explorerPath"
const val EXTRA_KEY_FILTERS_ARRAY = "filters"
const val EXTRA_KEY_FILTERS_STRING = "filtersString"
const val EXTRA_KEY_SAFE_MODE = "safeMode"
const val EXTRA_KEY_WIDGET_ID = "widgetId"

// dart page routes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,11 @@ class MediaStoreStreamHandler(private val context: Context, arguments: Any?) : E

private var knownEntries: Map<Long?, Int?>? = null
private var directory: String? = null
private var safe: Boolean = false

init {
if (arguments is Map<*, *>) {
knownEntries = (arguments["knownEntries"] as? Map<*, *>?)?.map { (it.key as Number?)?.toLong() to it.value as Int? }?.toMap()
directory = arguments["directory"] as String?
// do not use kotlin.collections `getOrDefault` as it crashes on API <24
// and there is no warning from Android Studio
safe = arguments["safe"] as Boolean? ?: false
}
}

Expand Down Expand Up @@ -63,7 +59,7 @@ class MediaStoreStreamHandler(private val context: Context, arguments: Any?) : E
}

private fun fetchAll() {
MediaStoreImageProvider().fetchAll(context, knownEntries ?: emptyMap(), directory, safe) { success(it) }
MediaStoreImageProvider().fetchAll(context, knownEntries ?: emptyMap(), directory) { success(it) }
endOfStream()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.content.Context
import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever
import android.net.Uri
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
import com.drew.metadata.avi.AviDirectory
import com.drew.metadata.exif.ExifIFD0Directory
import com.drew.metadata.jpeg.JpegDirectory
Expand All @@ -29,6 +28,7 @@ import deckers.thibault.aves.utils.StorageUtils
import deckers.thibault.aves.utils.UriUtils.tryParseId
import org.beyka.tiffbitmapfactory.TiffBitmapFactory
import java.io.IOException
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface

class SourceEntry {
private val origin: Int
Expand Down Expand Up @@ -116,8 +116,8 @@ class SourceEntry {
// metadata retrieval
// expects entry with: uri, mimeType
// finds: width, height, orientation/rotation, date, title, duration
fun fillPreCatalogMetadata(context: Context, safe: Boolean): SourceEntry {
if (isSvg || safe) return this
fun fillPreCatalogMetadata(context: Context): SourceEntry {
if (isSvg) return this
if (isVideo) {
fillVideoByMediaMetadataRetriever(context)
if (isSized && hasDuration) return this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ internal class FileImageProvider : ImageProvider() {
return
}
}
entry.fillPreCatalogMetadata(context, safe = false)
entry.fillPreCatalogMetadata(context)

if (allowUnsized || entry.isSized || entry.isSvg || entry.isVideo) {
callback.onSuccess(entry.toMap())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,9 @@ class MediaStoreImageProvider : ImageProvider() {
context: Context,
knownEntries: Map<Long?, Int?>,
directory: String?,
safe: Boolean,
handleNewEntry: NewEntryHandler,
) {
Log.d(LOG_TAG, "fetching all media store items for ${knownEntries.size} known entries, directory=$directory safe=$safe")
Log.d(LOG_TAG, "fetching all media store items for ${knownEntries.size} known entries, directory=$directory")
val isModified = fun(contentId: Long, dateModifiedSecs: Int): Boolean {
val knownDate = knownEntries[contentId]
return knownDate == null || knownDate < dateModifiedSecs
Expand Down Expand Up @@ -84,8 +83,8 @@ class MediaStoreImageProvider : ImageProvider() {
} else {
handleNew = handleNewEntry
}
fetchFrom(context, isModified, handleNew, IMAGE_CONTENT_URI, IMAGE_PROJECTION, selection, selectionArgs, safe = safe)
fetchFrom(context, isModified, handleNew, VIDEO_CONTENT_URI, VIDEO_PROJECTION, selection, selectionArgs, safe = safe)
fetchFrom(context, isModified, handleNew, IMAGE_CONTENT_URI, IMAGE_PROJECTION, selection, selectionArgs)
fetchFrom(context, isModified, handleNew, VIDEO_CONTENT_URI, VIDEO_PROJECTION, selection, selectionArgs)
}

// the provided URI can point to the wrong media collection,
Expand Down Expand Up @@ -208,7 +207,6 @@ class MediaStoreImageProvider : ImageProvider() {
selection: String? = null,
selectionArgs: Array<String>? = null,
fileMimeType: String? = null,
safe: Boolean = false,
): Boolean {
var found = false
val orderBy = "${MediaStore.MediaColumns.DATE_MODIFIED} DESC"
Expand Down Expand Up @@ -302,7 +300,7 @@ class MediaStoreImageProvider : ImageProvider() {
// missing some attributes such as width, height, orientation.
// Also, the reported size of raw images is inconsistent across devices
// and Android versions (sometimes the raw size, sometimes the decoded size).
val entry = SourceEntry(entryMap).fillPreCatalogMetadata(context, safe)
val entry = SourceEntry(entryMap).fillPreCatalogMetadata(context)
entryMap = entry.toMap()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ open class UnknownContentProvider : ImageProvider() {
return
}

val entry = SourceEntry(fields).fillPreCatalogMetadata(context, safe = false)
val entry = SourceEntry(fields).fillPreCatalogMetadata(context)
if (allowUnsized || entry.isSized || entry.isSvg || entry.isVideo) {
callback.onSuccess(entry.toMap())
} else {
Expand Down
1 change: 0 additions & 1 deletion lib/model/app/intent.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class IntentDataKeys {
static const mimeType = 'mimeType';
static const page = 'page';
static const query = 'query';
static const safeMode = 'safeMode';
static const secureUris = 'secureUris';
static const uri = 'uri';
static const widgetId = 'widgetId';
Expand Down
17 changes: 8 additions & 9 deletions lib/model/source/collection_source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import 'package:collection/collection.dart';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/foundation.dart';

enum SourceInitializationState { none, directory, full }
enum SourceScope { none, album, full }

mixin SourceBase {
EventBus get eventBus;
Expand Down Expand Up @@ -93,7 +93,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place
_rawEntries.forEach((v) => v.dispose());
}

set safeMode(bool enabled);
set canAnalyze(bool enabled);

final EventBus _eventBus = EventBus();

Expand Down Expand Up @@ -427,13 +427,12 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place
eventBus.fire(EntryMovedEvent(MoveType.move, movedEntries));
}

SourceInitializationState get initState => SourceInitializationState.none;
SourceScope get scope => SourceScope.none;

Future<void> init({
AnalysisController? analysisController,
String? directory,
AlbumFilter? albumFilter,
bool loadTopEntriesFirst = false,
bool canAnalyze = true,
});

Future<Set<String>> refreshUris(Set<String> changedUris, {AnalysisController? analysisController});
Expand Down Expand Up @@ -518,13 +517,13 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place

// monitoring

bool _monitoring = true;
bool _canRefresh = true;

void pauseMonitoring() => _monitoring = false;
void pauseMonitoring() => _canRefresh = false;

void resumeMonitoring() => _monitoring = true;
void resumeMonitoring() => _canRefresh = true;

bool get isMonitoring => _monitoring;
bool get canRefresh => _canRefresh;

// filter summary

Expand Down
46 changes: 21 additions & 25 deletions lib/model/source/media_store_source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,34 @@ class MediaStoreSource extends CollectionSource {
final Debouncer _changeDebouncer = Debouncer(delay: ADurations.mediaContentChangeDebounceDelay);
final Set<String> _changedUris = {};
int? _lastGeneration;
SourceInitializationState _initState = SourceInitializationState.none;
bool _safeMode = false;
SourceScope _scope = SourceScope.none;
bool _canAnalyze = true;

@override
set safeMode(bool enabled) => _safeMode = enabled;
set canAnalyze(bool enabled) => _canAnalyze = enabled;

@override
SourceInitializationState get initState => _initState;
SourceScope get scope => _scope;

@override
Future<void> init({
AnalysisController? analysisController,
String? directory,
AlbumFilter? albumFilter,
bool loadTopEntriesFirst = false,
bool canAnalyze = true,
}) async {
await reportService.log('$runtimeType init directory=$directory');
if (_initState == SourceInitializationState.none) {
await reportService.log('$runtimeType init album=${albumFilter?.album}');
if (_scope == SourceScope.none) {
await _loadEssentials();
}
if (_initState != SourceInitializationState.full) {
_initState = directory != null ? SourceInitializationState.directory : SourceInitializationState.full;
if (_scope != SourceScope.full) {
_scope = albumFilter != null ? SourceScope.album : SourceScope.full;
}
addDirectories(albums: settings.pinnedFilters.whereType<AlbumFilter>().map((v) => v.album).toSet());
await updateGeneration();
unawaited(_loadEntries(
analysisController: analysisController,
directory: directory,
directory: albumFilter?.album,
loadTopEntriesFirst: loadTopEntriesFirst,
canAnalyze: canAnalyze && !_safeMode,
));
}

Expand Down Expand Up @@ -80,7 +78,6 @@ class MediaStoreSource extends CollectionSource {
AnalysisController? analysisController,
String? directory,
required bool loadTopEntriesFirst,
required bool canAnalyze,
}) async {
unawaited(reportService.log('$runtimeType load start'));
final stopwatch = Stopwatch()..start();
Expand Down Expand Up @@ -158,6 +155,12 @@ class MediaStoreSource extends CollectionSource {
knownDateByContentId[contentId] = 0;
});

if (!_canAnalyze) {
// it can discover new entries only if it can analyze them
state = SourceState.ready;
return;
}

// items to add to the collection
final newEntries = <AvesEntry>{};

Expand All @@ -169,7 +172,7 @@ class MediaStoreSource extends CollectionSource {

// fetch new & modified entries
debugPrint('$runtimeType load ${stopwatch.elapsed} fetch new entries');
mediaStoreService.getEntries(_safeMode, knownDateByContentId, directory: directory).listen(
mediaStoreService.getEntries(knownDateByContentId, directory: directory).listen(
(entry) {
// when discovering modified entry with known content ID,
// reuse known entry ID to overwrite it while preserving favourites, etc.
Expand Down Expand Up @@ -210,11 +213,7 @@ class MediaStoreSource extends CollectionSource {
if (analysisIds != null) {
analysisEntries = visibleEntries.where((entry) => analysisIds.contains(entry.id)).toSet();
}
if (canAnalyze) {
await analyze(analysisController, entries: analysisEntries);
} else {
state = SourceState.ready;
}
await analyze(analysisController, entries: analysisEntries);

// the home page may not reflect the current derived filters
// as the initial addition of entries is silent,
Expand All @@ -234,7 +233,7 @@ class MediaStoreSource extends CollectionSource {
// sometimes yields an entry with its temporary path: `/data/sec/camera/!@#$%^..._temp.jpg`
@override
Future<Set<String>> refreshUris(Set<String> changedUris, {AnalysisController? analysisController}) async {
if (_initState == SourceInitializationState.none || !isMonitoring || !isReady) return changedUris;
if (_scope == SourceScope.none || !canRefresh || !isReady) return changedUris;

state = SourceState.loading;

Expand Down Expand Up @@ -272,7 +271,8 @@ class MediaStoreSource extends CollectionSource {
if (volume != null) {
if (existingEntry != null) {
entriesToRefresh.add(existingEntry);
} else {
} else if (_canAnalyze) {
// it can discover new entries only if it can analyze them
sourceEntry.id = localMediaDb.nextId;
newEntries.add(sourceEntry);
}
Expand Down Expand Up @@ -329,10 +329,6 @@ class MediaStoreSource extends CollectionSource {
}

void onStoreChanged(String? uri) {
// dismiss changes if the source is only loaded to view a specific directory
// to let the main instance handle the change in the database
if (_initState == SourceInitializationState.directory) return;

if (uri != null) _changedUris.add(uri);
if (_changedUris.isNotEmpty) {
_changeDebouncer(() async {
Expand Down
5 changes: 2 additions & 3 deletions lib/services/media/media_store_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ abstract class MediaStoreService {
Future<int?> getGeneration();

// knownEntries: map of contentId -> dateModifiedSecs
Stream<AvesEntry> getEntries(bool safe, Map<int?, int?> knownEntries, {String? directory});
Stream<AvesEntry> getEntries(Map<int?, int?> knownEntries, {String? directory});

// returns media URI
Future<Uri?> scanFile(String path, String mimeType);
Expand Down Expand Up @@ -77,13 +77,12 @@ class PlatformMediaStoreService implements MediaStoreService {
}

@override
Stream<AvesEntry> getEntries(bool safe, Map<int?, int?> knownEntries, {String? directory}) {
Stream<AvesEntry> getEntries(Map<int?, int?> knownEntries, {String? directory}) {
try {
return _stream
.receiveBroadcastStream(<String, dynamic>{
'knownEntries': knownEntries,
'directory': directory,
'safe': safe,
})
.where((event) => event is Map)
.map((event) => AvesEntry.fromMap(event as Map));
Expand Down
3 changes: 2 additions & 1 deletion lib/widget_common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ Future<AvesEntry?> _getWidgetEntry(int widgetId, bool reuseEntry) async {
readyCompleter.complete();
}
});
await source.init(canAnalyze: false);
source.canAnalyze = false;
await source.init();
await readyCompleter.future;

final entries = CollectionLens(source: source, filters: filters).sortedEntries;
Expand Down
2 changes: 1 addition & 1 deletion lib/widgets/aves_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {

Future<void> _onAnalysisCompletion() async {
debugPrint('Analysis completed');
if (_mediaStoreSource.initState != SourceInitializationState.none) {
if (_mediaStoreSource.scope != SourceScope.none) {
await _mediaStoreSource.loadCatalogMetadata();
await _mediaStoreSource.loadAddresses();
_mediaStoreSource.updateDerivedFilters();
Expand Down
3 changes: 2 additions & 1 deletion lib/widgets/dialogs/pick_dialogs/album_pick_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ Future<String?> pickAlbum({
required MoveType? moveType,
}) async {
final source = context.read<CollectionSource>();
if (source.initState != SourceInitializationState.full) {
if (source.scope != SourceScope.full) {
await reportService.log('Complete source initialization to pick album');
// source may not be fully initialized in view mode
source.canAnalyze = true;
await source.init();
}
final filter = await Navigator.maybeOf(context)?.push(
Expand Down
Loading

0 comments on commit 211f803

Please sign in to comment.