diff --git a/core/shared/src/main/java/de/mm20/launcher2/plugin/contracts/FilePluginContract.kt b/core/shared/src/main/java/de/mm20/launcher2/plugin/contracts/FilePluginContract.kt index 3d08f3f6..d890f63c 100644 --- a/core/shared/src/main/java/de/mm20/launcher2/plugin/contracts/FilePluginContract.kt +++ b/core/shared/src/main/java/de/mm20/launcher2/plugin/contracts/FilePluginContract.kt @@ -48,6 +48,8 @@ abstract class FilePluginContract { */ const val IsDirectory = "is_directory" + const val Owner = "owner" + const val MetaTitle = "meta_title" const val MetaArtist = "meta_artist" const val MetaAlbum = "meta_album" @@ -59,6 +61,5 @@ abstract class FilePluginContract { const val MetaAppName = "meta_app_name" const val MetaAppPackageName = "meta_app_package_name" const val MetaAppMinSdkVersion = "meta_app_min_sdk_version" - const val MetaOwner = "meta_owner" } } \ No newline at end of file diff --git a/data/files/src/main/java/de/mm20/launcher2/files/providers/PluginFileProvider.kt b/data/files/src/main/java/de/mm20/launcher2/files/providers/PluginFileProvider.kt index e07fa9ac..ad04e820 100644 --- a/data/files/src/main/java/de/mm20/launcher2/files/providers/PluginFileProvider.kt +++ b/data/files/src/main/java/de/mm20/launcher2/files/providers/PluginFileProvider.kt @@ -4,17 +4,19 @@ import android.content.Context import android.database.Cursor import android.net.Uri import android.os.CancellationSignal +import android.text.format.DateUtils import android.util.Log +import androidx.core.database.getIntOrNull +import androidx.core.database.getLongOrNull import androidx.core.database.getStringOrNull import de.mm20.launcher2.crashreporter.CrashReporter -import de.mm20.launcher2.plugin.Plugin import de.mm20.launcher2.plugin.config.SearchPluginConfig -import de.mm20.launcher2.plugin.config.StorageStrategy import de.mm20.launcher2.plugin.contracts.FilePluginContract import de.mm20.launcher2.plugin.contracts.PluginContract import de.mm20.launcher2.plugin.contracts.SearchPluginContract import de.mm20.launcher2.search.File -import kotlinx.collections.immutable.persistentMapOf +import de.mm20.launcher2.search.FileMetaType +import kotlinx.collections.immutable.toPersistentMap import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext @@ -138,6 +140,40 @@ class PluginFileProvider( val directoryIndex = cursor.getColumnIndex(FilePluginContract.FileColumns.IsDirectory).takeIf { it >= 0 } + val ownerIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.Owner).takeIf { it >= 0 } + + val metaTitleIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaTitle).takeIf { it >= 0 } + + val metaArtistIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaArtist).takeIf { it >= 0 } + + val metaAlbumIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaAlbum).takeIf { it >= 0 } + + val metaDurationIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaDuration).takeIf { it >= 0 } + + val metaYearIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaYear).takeIf { it >= 0 } + + val metaWidthIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaWidth).takeIf { it >= 0 } + + val metaHeightIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaHeight).takeIf { it >= 0 } + + val metaLocationIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaLocation).takeIf { it >= 0 } + + val metaAppNameIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaAppName).takeIf { it >= 0 } + + val metaAppPackageNameIndex = + cursor.getColumnIndex(FilePluginContract.FileColumns.MetaAppPackageName) + .takeIf { it >= 0 } + val results = mutableListOf() while (cursor.moveToNext()) { results.add( @@ -147,7 +183,42 @@ class PluginFileProvider( mimeType = typeIndex?.let { cursor.getString(it) } ?: "application/octet-stream", size = sizeIndex?.let { cursor.getLong(it) } ?: 0, - metaData = persistentMapOf(), + metaData = buildMap { + metaTitleIndex?.let { cursor.getStringOrNull(it) }?.let { + put(FileMetaType.Title, it) + } + metaArtistIndex?.let { cursor.getStringOrNull(it) }?.let { + put(FileMetaType.Artist, it) + } + metaAlbumIndex?.let { cursor.getStringOrNull(it) }?.let { + put(FileMetaType.Album, it) + } + metaDurationIndex?.let { cursor.getLongOrNull(it) }?.let { + put(FileMetaType.Duration, DateUtils.formatElapsedTime(it / 1000L)) + } + metaYearIndex?.let { cursor.getIntOrNull(it) }?.let { + put(FileMetaType.Year, it.toString()) + } + if (metaWidthIndex != null && metaHeightIndex != null) { + val width = cursor.getIntOrNull(metaWidthIndex) + val height = cursor.getIntOrNull(metaHeightIndex) + if (width != null && height != null) { + put(FileMetaType.Dimensions, "${width}x${height}") + } + } + metaLocationIndex?.let { cursor.getStringOrNull(it) }?.let { + put(FileMetaType.Location, it) + } + metaAppNameIndex?.let { cursor.getStringOrNull(it) }?.let { + put(FileMetaType.AppName, it) + } + metaAppPackageNameIndex?.let { cursor.getStringOrNull(it) }?.let { + put(FileMetaType.AppPackageName, it) + } + ownerIndex?.let { cursor.getStringOrNull(it) }?.let { + put(FileMetaType.Owner, it) + } + }.toPersistentMap(), label = cursor.getString(nameIndex), uri = Uri.parse(cursor.getString(contentUriIndex)), thumbnailUri = thumbnailUriIndex?.let { diff --git a/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/files/File.kt b/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/files/File.kt index 73ac8304..feb3eae9 100644 --- a/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/files/File.kt +++ b/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/files/File.kt @@ -1,7 +1,50 @@ package de.mm20.launcher2.sdk.files import android.net.Uri -import de.mm20.launcher2.plugin.config.StorageStrategy + +data class FileDimensions( + val width: Int, + val height: Int, +) + +data class FileMetadata( + /** + * Song title, for audio files. + */ + val title: String? = null, + /** + * Artist name, for audio files. + */ + val artist: String? = null, + /** + * Album name, for audio files. + */ + val album: String? = null, + /** + * Duration in milliseconds, for audio and video files. + */ + val duration: Long? = null, + /** + * Year, for media files. + */ + val year: Int? = null, + /** + * Dimensions in pixels, for image and video files. + */ + val dimensions: FileDimensions? = null, + /** + * Geo location, for image and video files. + */ + val location: String? = null, + /** + * App name, for APK files. + */ + val appName: String? = null, + /** + * App package name, for APK files. + */ + val appPackageName: String? = null, +) data class File( /** @@ -50,4 +93,14 @@ data class File( * If null, a default icon will be shown, depending on the file type. */ val thumbnailUri: Uri? = null, + + /** + * Name of the owner of this file (i.e. when this file was shared with the user by another person). + */ + val owner: String? = null, + + /** + * Additional metadata for this file. + */ + val metadata: FileMetadata = FileMetadata(), ) \ No newline at end of file diff --git a/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/files/FileProvider.kt b/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/files/FileProvider.kt index 3c0af293..63ac8c46 100644 --- a/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/files/FileProvider.kt +++ b/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/files/FileProvider.kt @@ -26,6 +26,17 @@ abstract class FileProvider( FilePluginContract.FileColumns.ContentUri, FilePluginContract.FileColumns.ThumbnailUri, FilePluginContract.FileColumns.IsDirectory, + FilePluginContract.FileColumns.Owner, + FilePluginContract.FileColumns.MetaTitle, + FilePluginContract.FileColumns.MetaArtist, + FilePluginContract.FileColumns.MetaAlbum, + FilePluginContract.FileColumns.MetaDuration, + FilePluginContract.FileColumns.MetaYear, + FilePluginContract.FileColumns.MetaWidth, + FilePluginContract.FileColumns.MetaHeight, + FilePluginContract.FileColumns.MetaLocation, + FilePluginContract.FileColumns.MetaAppName, + FilePluginContract.FileColumns.MetaAppPackageName, ), capacity, ) @@ -42,6 +53,17 @@ abstract class FileProvider( item.uri.toString(), item.thumbnailUri?.toString(), if (item.isDirectory) 1 else 0, + item.owner, + item.metadata.title, + item.metadata.artist, + item.metadata.album, + item.metadata.duration, + item.metadata.year, + item.metadata.dimensions?.width, + item.metadata.dimensions?.height, + item.metadata.location, + item.metadata.appName, + item.metadata.appPackageName, ) ) }