Glimpse: Set minimum SDK to 30 (Android 11)

* Oldest supported LineageOS version would be 18.1, which is definitely
  enough for any kind of testing
* While at it fix permissions check for pre-Tiramisu

Change-Id: I9f9ba8fe0c0c8a50436810934b439fd38a2fb445
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 3ba69a3..8dd6d6d 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -17,7 +17,7 @@
 
     defaultConfig {
         applicationId = "org.lineageos.glimpse"
-        minSdk = 26
+        minSdk = 30
         targetSdk = 33
         versionCode = 1
         versionName = "1.0"
diff --git a/app/src/main/java/org/lineageos/glimpse/GlimpseApplication.kt b/app/src/main/java/org/lineageos/glimpse/GlimpseApplication.kt
index c645388..1e89b94 100644
--- a/app/src/main/java/org/lineageos/glimpse/GlimpseApplication.kt
+++ b/app/src/main/java/org/lineageos/glimpse/GlimpseApplication.kt
@@ -27,9 +27,7 @@
     }
 
     override fun newImageLoader() = ImageLoader.Builder(this).components {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-            add(ImageDecoderDecoder.Factory())
-        }
+        add(ImageDecoderDecoder.Factory())
         add(GifDecoder.Factory())
         add(VideoFrameDecoder.Factory())
     }.memoryCache {
diff --git a/app/src/main/java/org/lineageos/glimpse/ext/Configuration.kt b/app/src/main/java/org/lineageos/glimpse/ext/Configuration.kt
deleted file mode 100644
index bc83a8d..0000000
--- a/app/src/main/java/org/lineageos/glimpse/ext/Configuration.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2023 The LineageOS Project
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package org.lineageos.glimpse.ext
-
-import android.content.res.Configuration
-import android.os.Build
-
-val Configuration.isNightMode
-    get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-        isNightModeActive
-    } else when (uiMode.and(Configuration.UI_MODE_NIGHT_MASK)) {
-        Configuration.UI_MODE_NIGHT_UNDEFINED -> null
-        Configuration.UI_MODE_NIGHT_NO -> false
-        Configuration.UI_MODE_NIGHT_YES -> true
-        else -> null
-    }
diff --git a/app/src/main/java/org/lineageos/glimpse/ext/Window.kt b/app/src/main/java/org/lineageos/glimpse/ext/Window.kt
index f5f74fc..c024ce1 100644
--- a/app/src/main/java/org/lineageos/glimpse/ext/Window.kt
+++ b/app/src/main/java/org/lineageos/glimpse/ext/Window.kt
@@ -20,7 +20,7 @@
 
 fun Window.resetStatusBarAppearance() {
     windowInsetsController.isAppearanceLightStatusBars =
-        context.resources.configuration.isNightMode != true
+        !context.resources.configuration.isNightModeActive
 }
 
 fun Window.setBarsVisibility(
diff --git a/app/src/main/java/org/lineageos/glimpse/flow/AlbumsFlow.kt b/app/src/main/java/org/lineageos/glimpse/flow/AlbumsFlow.kt
index 6a0128f..a2c1b4f 100644
--- a/app/src/main/java/org/lineageos/glimpse/flow/AlbumsFlow.kt
+++ b/app/src/main/java/org/lineageos/glimpse/flow/AlbumsFlow.kt
@@ -36,9 +36,7 @@
                     ContentResolver.QUERY_ARG_SQL_SORT_ORDER to sortOrder,
                 )
             )
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-                putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, MediaStore.MATCH_INCLUDE)
-            }
+            putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, MediaStore.MATCH_INCLUDE)
         }
 
         return context.contentResolver.queryFlow(
diff --git a/app/src/main/java/org/lineageos/glimpse/flow/MediaFlow.kt b/app/src/main/java/org/lineageos/glimpse/flow/MediaFlow.kt
index 5ea8507..b5962d0 100644
--- a/app/src/main/java/org/lineageos/glimpse/flow/MediaFlow.kt
+++ b/app/src/main/java/org/lineageos/glimpse/flow/MediaFlow.kt
@@ -8,7 +8,6 @@
 import android.content.ContentResolver
 import android.content.Context
 import android.database.Cursor
-import android.os.Build
 import android.os.Bundle
 import android.provider.MediaStore
 import androidx.core.os.bundleOf
@@ -30,11 +29,8 @@
             when (it) {
                 MediaStoreBuckets.MEDIA_STORE_BUCKET_FAVORITES.id -> MediaStore.Files.FileColumns.IS_FAVORITE eq 1
 
-                MediaStoreBuckets.MEDIA_STORE_BUCKET_TRASH.id -> if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+                MediaStoreBuckets.MEDIA_STORE_BUCKET_TRASH.id ->
                     MediaStore.Files.FileColumns.IS_TRASHED eq 1
-                } else {
-                    null
-                }
 
                 else -> MediaStore.Files.FileColumns.BUCKET_ID eq Query.ARG
             }
@@ -52,16 +48,15 @@
                     ContentResolver.QUERY_ARG_SQL_SORT_ORDER to sortOrder,
                 )
             )
-            // Exclude trashed media unless we want data for the trashed album
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-                putInt(
-                    MediaStore.QUERY_ARG_MATCH_TRASHED, when (bucketId) {
-                        MediaStoreBuckets.MEDIA_STORE_BUCKET_TRASH.id -> MediaStore.MATCH_ONLY
 
-                        else -> MediaStore.MATCH_EXCLUDE
-                    }
-                )
-            }
+            // Exclude trashed media unless we want data for the trashed album
+            putInt(
+                MediaStore.QUERY_ARG_MATCH_TRASHED, when (bucketId) {
+                    MediaStoreBuckets.MEDIA_STORE_BUCKET_TRASH.id -> MediaStore.MATCH_ONLY
+
+                    else -> MediaStore.MATCH_EXCLUDE
+                }
+            )
         }
 
         return context.contentResolver.queryFlow(
diff --git a/app/src/main/java/org/lineageos/glimpse/fragments/MediaViewerFragment.kt b/app/src/main/java/org/lineageos/glimpse/fragments/MediaViewerFragment.kt
index fb74b1b..aa8aa37 100644
--- a/app/src/main/java/org/lineageos/glimpse/fragments/MediaViewerFragment.kt
+++ b/app/src/main/java/org/lineageos/glimpse/fragments/MediaViewerFragment.kt
@@ -248,15 +248,11 @@
                             R.plurals.file_deletion_confirm_message, 1, 1
                         )
                     ).setPositiveButton(android.R.string.ok) { _, _ ->
-                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-                            deleteUriContract.launch(
-                                requireContext().contentResolver.createDeleteRequest(
-                                    it.externalContentUri
-                                )
+                        deleteUriContract.launch(
+                            requireContext().contentResolver.createDeleteRequest(
+                                it.externalContentUri
                             )
-                        } else {
-                            it.delete(requireContext().contentResolver)
-                        }
+                        )
                     }
                     .setNegativeButton(android.R.string.cancel) { _, _ ->
                         // Do nothing
@@ -271,16 +267,11 @@
 
         favoriteButton.setOnClickListener {
             mediaViewerAdapter.getItemAtPosition(viewPager.currentItem).let {
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-                    favoriteContract.launch(
-                        requireContext().contentResolver.createFavoriteRequest(
-                            !it.isFavorite, it.externalContentUri
-                        )
+                favoriteContract.launch(
+                    requireContext().contentResolver.createFavoriteRequest(
+                        !it.isFavorite, it.externalContentUri
                     )
-                } else {
-                    it.favorite(requireContext().contentResolver, !it.isFavorite)
-                    favoriteButton.isSelected = !it.isFavorite
-                }
+                )
             }
         }
 
@@ -396,19 +387,16 @@
             restoreLastTrashedMediaFromTrash = { trashMedia(media, false) }
         }
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-            val contract = when (trash) {
-                true -> trashUriContract
-                false -> restoreUriFromTrashContract
-            }
-            contract.launch(
-                requireContext().contentResolver.createTrashRequest(
-                    trash, media.externalContentUri
-                )
-            )
-        } else {
-            media.trash(requireContext().contentResolver, trash)
+        val contract = when (trash) {
+            true -> trashUriContract
+            false -> restoreUriFromTrashContract
         }
+
+        contract.launch(
+            requireContext().contentResolver.createTrashRequest(
+                trash, media.externalContentUri
+            )
+        )
     }
 
     private fun updateSheetsHeight() {
diff --git a/app/src/main/java/org/lineageos/glimpse/models/Media.kt b/app/src/main/java/org/lineageos/glimpse/models/Media.kt
index a33ccf0..dce36cd 100644
--- a/app/src/main/java/org/lineageos/glimpse/models/Media.kt
+++ b/app/src/main/java/org/lineageos/glimpse/models/Media.kt
@@ -5,12 +5,9 @@
 
 package org.lineageos.glimpse.models
 
-import android.content.ContentResolver
 import android.content.ContentUris
-import android.content.ContentValues
 import android.os.Parcel
 import android.os.Parcelable
-import android.provider.MediaStore
 import java.util.Date
 import kotlin.reflect.safeCast
 
@@ -72,22 +69,6 @@
         dest.writeLong(dateAdded.time)
     }
 
-    fun delete(contentResolver: ContentResolver) {
-        contentResolver.delete(externalContentUri, null, null)
-    }
-
-    fun favorite(contentResolver: ContentResolver, value: Boolean) {
-        contentResolver.update(externalContentUri, ContentValues().apply {
-            put(MediaStore.MediaColumns.IS_FAVORITE, value)
-        }, null, null)
-    }
-
-    fun trash(contentResolver: ContentResolver, value: Boolean) {
-        contentResolver.update(externalContentUri, ContentValues().apply {
-            put(MediaStore.MediaColumns.IS_TRASHED, value)
-        }, null, null)
-    }
-
     companion object CREATOR : Parcelable.Creator<Media> {
         override fun createFromParcel(parcel: Parcel) = Media(parcel)
 
diff --git a/app/src/main/java/org/lineageos/glimpse/ui/MediaInfoBottomSheetDialog.kt b/app/src/main/java/org/lineageos/glimpse/ui/MediaInfoBottomSheetDialog.kt
index 5da22f3..3ee810c 100644
--- a/app/src/main/java/org/lineageos/glimpse/ui/MediaInfoBottomSheetDialog.kt
+++ b/app/src/main/java/org/lineageos/glimpse/ui/MediaInfoBottomSheetDialog.kt
@@ -221,13 +221,9 @@
 
             val contentResolver = fragment.requireContext().contentResolver
 
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-                editDescriptionCallback.launch(
-                    contentResolver.createWriteRequest(media.externalContentUri)
-                )
-            } else {
-                editDescription(media, description)
-            }
+            editDescriptionCallback.launch(
+                contentResolver.createWriteRequest(media.externalContentUri)
+            )
         }
 
         private fun editDescription(media: Media, description: String) {
diff --git a/app/src/main/java/org/lineageos/glimpse/utils/PermissionsUtils.kt b/app/src/main/java/org/lineageos/glimpse/utils/PermissionsUtils.kt
index 761c598..6d57ad5 100644
--- a/app/src/main/java/org/lineageos/glimpse/utils/PermissionsUtils.kt
+++ b/app/src/main/java/org/lineageos/glimpse/utils/PermissionsUtils.kt
@@ -79,11 +79,10 @@
                 add(Manifest.permission.READ_MEDIA_IMAGES)
                 add(Manifest.permission.READ_MEDIA_VIDEO)
             } else {
-                add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
+                add(Manifest.permission.READ_EXTERNAL_STORAGE)
             }
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
-                add(Manifest.permission.ACCESS_MEDIA_LOCATION)
-            }
+
+            add(Manifest.permission.ACCESS_MEDIA_LOCATION)
         }.toTypedArray()
     }
 }
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 4451cf5..1281b56 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -8,9 +8,7 @@
     <style name="Theme.Glimpse" parent="Theme.Material3.DayNight.NoActionBar">
         <item name="android:navigationBarColor">@android:color/transparent</item>
         <item name="android:statusBarColor">@android:color/transparent</item>
-        <item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">
-            shortEdges
-        </item>
+        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
         <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
     </style>