[Android] Workaround for IllegalStateException on Pie

Geoffrey Métais git at videolan.org
Mon Nov 25 11:52:16 CET 2019


vlc-android | branch: master | Geoffrey Métais <geoffrey at videolan.org> | Mon Nov 25 11:52:15 2019 +0100| [3d7f70e694abecab048b6a393bcff529374eb945] | committer: Nicolas Pomepuy

Workaround for IllegalStateException on Pie

Android 9 has a bug, sometimes, service cannot be started as soon as app
is:
https://issuetracker.google.com/issues/113122354

This fix creates a suspend function which will wait for the app to go
foreground, and use it to launch the service only when we can

> https://code.videolan.org/videolan/vlc-android/commit/3d7f70e694abecab048b6a393bcff529374eb945
---

 .../java/org/videolan/tools/KotlinExtensions.kt    | 25 ++++++++++++++++++++++
 .../src/org/videolan/vlc/RendererDelegate.kt       |  6 +++++-
 vlc-android/src/org/videolan/vlc/StartActivity.kt  |  8 +++++++
 .../providers/medialibrary/MedialibraryProvider.kt |  6 +++++-
 .../src/org/videolan/vlc/util/Kextensions.kt       | 12 -----------
 5 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/tools/src/main/java/org/videolan/tools/KotlinExtensions.kt b/tools/src/main/java/org/videolan/tools/KotlinExtensions.kt
index fb8b945e3..fc94db43d 100644
--- a/tools/src/main/java/org/videolan/tools/KotlinExtensions.kt
+++ b/tools/src/main/java/org/videolan/tools/KotlinExtensions.kt
@@ -1,5 +1,7 @@
 package org.videolan.tools
 
+import android.app.ActivityManager
+import android.app.ActivityManager.RunningAppProcessInfo
 import android.content.ClipData
 import android.content.ClipboardManager
 import android.content.Context
@@ -79,3 +81,26 @@ fun Context.copy(label: String, text: String) {
         setPrimaryClip(ClipData.newPlainText(label, text))
     }
 }
+
+suspend fun retry (
+        times: Int = 3,
+        delayTime: Long = 500L,
+        block: suspend () -> Boolean): Boolean
+{
+    repeat(times - 1) {
+        if (block()) return true
+        if (delayTime > 0L) delay(delayTime)
+    }
+    return block() // last attempt
+}
+
+suspend fun Context.awaitAppIsForegroung() : Boolean {
+    val activityManager = applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager ?: return false
+    repeat(times = 2) {
+        if (activityManager.isAppForeground()) return true
+        else yield() //dispatch next try
+    }
+    return activityManager.isAppForeground()
+}
+
+private fun ActivityManager.isAppForeground() = runningAppProcesses[0].importance <= RunningAppProcessInfo.IMPORTANCE_FOREGROUND
\ No newline at end of file
diff --git a/vlc-android/src/org/videolan/vlc/RendererDelegate.kt b/vlc-android/src/org/videolan/vlc/RendererDelegate.kt
index 11dd9d60b..26c623176 100644
--- a/vlc-android/src/org/videolan/vlc/RendererDelegate.kt
+++ b/vlc-android/src/org/videolan/vlc/RendererDelegate.kt
@@ -22,7 +22,11 @@ package org.videolan.vlc
 import kotlinx.coroutines.*
 import org.videolan.libvlc.RendererDiscoverer
 import org.videolan.libvlc.RendererItem
-import org.videolan.vlc.util.*
+import org.videolan.tools.retry
+import org.videolan.vlc.util.AppScope
+import org.videolan.vlc.util.LiveDataset
+import org.videolan.vlc.util.VLCInstance
+import org.videolan.vlc.util.isAppStarted
 import java.util.*
 
 @ObsoleteCoroutinesApi
diff --git a/vlc-android/src/org/videolan/vlc/StartActivity.kt b/vlc-android/src/org/videolan/vlc/StartActivity.kt
index 0f554a0a4..de1dbc661 100644
--- a/vlc-android/src/org/videolan/vlc/StartActivity.kt
+++ b/vlc-android/src/org/videolan/vlc/StartActivity.kt
@@ -26,6 +26,7 @@ package org.videolan.vlc
 import android.content.Context
 import android.content.Intent
 import android.net.Uri
+import android.os.Build
 import android.os.Bundle
 import android.provider.MediaStore
 import android.text.TextUtils
@@ -35,6 +36,7 @@ import androidx.fragment.app.FragmentActivity
 import kotlinx.coroutines.*
 import org.videolan.libvlc.util.AndroidUtil
 import org.videolan.medialibrary.MLServiceLocator
+import org.videolan.tools.awaitAppIsForegroung
 import org.videolan.vlc.gui.BetaWelcomeActivity
 import org.videolan.vlc.gui.MainActivity
 import org.videolan.vlc.gui.SearchActivity
@@ -196,6 +198,12 @@ class StartActivity : FragmentActivity(), CoroutineScope by MainScope() {
     }
 
     private fun startPlaybackFromApp(intent: Intent) = launch(start = CoroutineStart.UNDISPATCHED) {
+        // workaround for a Android 9 bug
+        // https://issuetracker.google.com/issues/113122354
+        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P && !awaitAppIsForegroung()) {
+            finish()
+            return at launch
+        }
         if (Permissions.canReadStorage(applicationContext) || getStoragePermission()) when {
             intent.type?.startsWith("video") == true -> try {
                 startActivity(intent.setClass(this at StartActivity, VideoPlayerActivity::class.java))
diff --git a/vlc-android/src/org/videolan/vlc/providers/medialibrary/MedialibraryProvider.kt b/vlc-android/src/org/videolan/vlc/providers/medialibrary/MedialibraryProvider.kt
index 3efaeceab..b3300123a 100644
--- a/vlc-android/src/org/videolan/vlc/providers/medialibrary/MedialibraryProvider.kt
+++ b/vlc-android/src/org/videolan/vlc/providers/medialibrary/MedialibraryProvider.kt
@@ -33,8 +33,12 @@ import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import org.videolan.medialibrary.interfaces.AbstractMedialibrary
 import org.videolan.medialibrary.media.MediaLibraryItem
+import org.videolan.tools.retry
 import org.videolan.vlc.providers.HeaderProvider
-import org.videolan.vlc.util.*
+import org.videolan.vlc.util.MEDIALIBRARY_PAGE_SIZE
+import org.videolan.vlc.util.ModelsHelper
+import org.videolan.vlc.util.Settings
+import org.videolan.vlc.util.SortModule
 import org.videolan.vlc.viewmodels.SortableModel
 
 abstract class MedialibraryProvider<T : MediaLibraryItem>(val context: Context, val model: SortableModel) : HeaderProvider(),
diff --git a/vlc-android/src/org/videolan/vlc/util/Kextensions.kt b/vlc-android/src/org/videolan/vlc/util/Kextensions.kt
index 6d7b0afb5..135efe35b 100644
--- a/vlc-android/src/org/videolan/vlc/util/Kextensions.kt
+++ b/vlc-android/src/org/videolan/vlc/util/Kextensions.kt
@@ -66,18 +66,6 @@ inline fun <reified T : ViewModel> Fragment.getModelWithActivity() = ViewModelPr
 inline fun <reified T : ViewModel> Fragment.getModel() = ViewModelProviders.of(this).get(T::class.java)
 inline fun <reified T : ViewModel> FragmentActivity.getModel() = ViewModelProviders.of(this).get(T::class.java)
 
-suspend fun retry (
-        times: Int = 3,
-        delayTime: Long = 500L,
-        block: suspend () -> Boolean): Boolean
-{
-    repeat(times - 1) {
-        if (block()) return true
-        delay(delayTime)
-    }
-    return block() // last attempt
-}
-
 fun Media?.canExpand() = this != null && (type == Media.Type.Directory || type == Media.Type.Playlist)
 suspend fun AppCompatActivity.share(media: AbstractMediaWrapper) {
     val intentShareFile = Intent(Intent.ACTION_SEND)



More information about the Android mailing list