Glimpse: Handle ACTION_REVIEW_SECURE
Change-Id: I572fd755a726299acfbe4860c531c6380bf4edc2
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2dd213a..f5ec9d0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -50,6 +50,7 @@
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.provider.action.REVIEW" />
+ <action android:name="android.provider.action.REVIEW_SECURE" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
diff --git a/app/src/main/java/org/lineageos/glimpse/ViewActivity.kt b/app/src/main/java/org/lineageos/glimpse/ViewActivity.kt
index 2ed96de..8d29be6 100644
--- a/app/src/main/java/org/lineageos/glimpse/ViewActivity.kt
+++ b/app/src/main/java/org/lineageos/glimpse/ViewActivity.kt
@@ -5,6 +5,7 @@
package org.lineageos.glimpse
+import android.app.KeyguardManager
import android.content.Intent
import android.net.Uri
import android.os.Bundle
@@ -35,6 +36,9 @@
// okhttp
private val httpClient = OkHttpClient()
+ // System services
+ private val keyguardManager by lazy { getSystemService(KeyguardManager::class.java) }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -43,6 +47,12 @@
// Setup edge-to-edge
WindowCompat.setDecorFitsSystemWindows(window, false)
+ // We only want to show this activity on top of the keyguard if we're being launched with
+ // the ACTION_REVIEW_SECURE intent and the system is currently locked.
+ if (keyguardManager.isKeyguardLocked && intent.action == MediaStore.ACTION_REVIEW_SECURE) {
+ setShowWhenLocked(true)
+ }
+
handleIntent(intent)
}
@@ -50,8 +60,8 @@
ioScope.launch {
when (intent.action) {
Intent.ACTION_VIEW -> handleView(intent)
- MediaStore.ACTION_REVIEW,
- MediaStore.ACTION_REVIEW_SECURE -> handleReview(intent)
+ MediaStore.ACTION_REVIEW -> handleReview(intent)
+ MediaStore.ACTION_REVIEW_SECURE -> handleReview(intent, true)
else -> runOnUiThread {
Toast.makeText(
this@ViewActivity,
@@ -68,8 +78,9 @@
* Handle a [Intent.ACTION_VIEW] intent (view a single media, controls also read-only).
* Must be executed on [ioScope].
* @param intent The received intent
+ * @param secure Whether we should show this media in a secure manner
*/
- private fun handleView(intent: Intent) {
+ private fun handleView(intent: Intent, secure: Boolean = false) {
val uri = intent.data ?: run {
runOnUiThread {
Toast.makeText(
@@ -114,7 +125,7 @@
.beginTransaction()
.replace(
R.id.navHostFragment, MediaViewerFragment.newInstance(
- null, null, MediaUri(uri, uriType, dataType)
+ null, null, MediaUri(uri, uriType, dataType), secure
)
)
.commit()
@@ -127,20 +138,21 @@
* If uri parsing from [MediaStore] fails, fallback to [handleView].
* Must be executed on [ioScope].
* @param intent The received intent
+ * @param secure Whether we should review this media in a secure manner
*/
- private fun handleReview(intent: Intent) {
+ private fun handleReview(intent: Intent, secure: Boolean = false) {
intent.data?.let { getMediaStoreMedia(it) }?.also {
runOnUiThread {
supportFragmentManager
.beginTransaction()
.replace(
R.id.navHostFragment, MediaViewerFragment.newInstance(
- it, it.bucketId, null
+ it, it.bucketId, null, secure
)
)
.commit()
}
- } ?: handleView(intent)
+ } ?: handleView(intent, secure)
}
/**
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 6008da1..d4a474b 100644
--- a/app/src/main/java/org/lineageos/glimpse/fragments/MediaViewerFragment.kt
+++ b/app/src/main/java/org/lineageos/glimpse/fragments/MediaViewerFragment.kt
@@ -117,6 +117,7 @@
private val media by lazy { arguments?.getParcelable(KEY_MEDIA, Media::class) }
private val albumId by lazy { arguments?.getInt(KEY_ALBUM_ID, -1).takeUnless { it == -1 } }
private val mediaUri by lazy { arguments?.getParcelable(KEY_MEDIA_URI, MediaUri::class) }
+ private val secure by lazy { arguments?.getBoolean(KEY_SECURE) == true }
// Contracts
private val deleteUriContract =
@@ -194,14 +195,6 @@
this@MediaViewerFragment.mediaViewModel.mediaPosition = position
mediaUri?.also {
- dateTextView.isVisible = false
- timeTextView.isVisible = false
-
- favoriteButton.isVisible = false
- infoButton.isVisible = false
- adjustButton.isVisible = false
- deleteButton.isVisible = false
-
if (it.mediaType == MediaType.VIDEO) {
with(exoPlayerLazy.value) {
setMediaItem(MediaItem.fromUri(it.externalContentUri))
@@ -366,6 +359,18 @@
}
}
+ // Set UI elements visibility based on initial arguments
+ val shouldShowMediaButtons = mediaUri == null && !secure
+
+ dateTextView.isVisible = shouldShowMediaButtons
+ timeTextView.isVisible = shouldShowMediaButtons
+
+ favoriteButton.isVisible = shouldShowMediaButtons
+ shareButton.isVisible = !secure
+ infoButton.isVisible = shouldShowMediaButtons
+ adjustButton.isVisible = shouldShowMediaButtons
+ deleteButton.isVisible = shouldShowMediaButtons
+
updateSheetsHeight()
permissionsGatedCallback.runAfterPermissionsCheck()
@@ -460,6 +465,7 @@
private const val KEY_MEDIA = "media"
private const val KEY_ALBUM_ID = "album_id"
private const val KEY_MEDIA_URI = "media_uri"
+ private const val KEY_SECURE = "secure"
private val dateFormatter = SimpleDateFormat.getDateInstance()
private val timeFormatter = SimpleDateFormat.getTimeInstance()
@@ -472,15 +478,18 @@
* will show all medias in the device.
* @param mediaUri The [MediaUri] to display, setting this will disable any kind of
* interaction to [MediaStore] and UI will be stripped down.
+ * @param secure Whether this should be considered a secure session (no edit, no share, etc)
*/
fun createBundle(
media: Media? = null,
albumId: Int? = media?.bucketId,
mediaUri: MediaUri? = null,
+ secure: Boolean = false,
) = bundleOf(
KEY_MEDIA to media,
KEY_ALBUM_ID to albumId,
KEY_MEDIA_URI to mediaUri,
+ KEY_SECURE to secure,
)
/**
@@ -494,11 +503,13 @@
media: Media? = null,
albumId: Int? = media?.bucketId,
mediaUri: MediaUri? = null,
+ secure: Boolean = false,
) = MediaViewerFragment().apply {
arguments = createBundle(
media,
albumId,
mediaUri,
+ secure,
)
}
}