[Android] Rework the Medialibrary initialization flow

Nicolas Pomepuy git at videolan.org
Thu Feb 24 10:58:19 UTC 2022


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Wed Feb 23 13:26:23 2022 +0100| [f249782f6dd94b5fe6687c2b156a88873fca43c1] | committer: Nicolas Pomepuy

Rework the Medialibrary initialization flow

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

 .../src/org/videolan/vlc/MediaParsingService.kt    |  6 ++++
 medialibrary/jni/medialibrary.cpp                  | 18 ++++++----
 .../videolan/medialibrary/MedialibraryImpl.java    | 41 ++++++++++++----------
 .../medialibrary/interfaces/Medialibrary.java      |  1 +
 .../medialibrary/stubs/StubMedialibrary.java       |  9 +++--
 5 files changed, 49 insertions(+), 26 deletions(-)

diff --git a/application/vlc-android/src/org/videolan/vlc/MediaParsingService.kt b/application/vlc-android/src/org/videolan/vlc/MediaParsingService.kt
index 314808444..02897b4ba 100644
--- a/application/vlc-android/src/org/videolan/vlc/MediaParsingService.kt
+++ b/application/vlc-android/src/org/videolan/vlc/MediaParsingService.kt
@@ -466,6 +466,12 @@ class MediaParsingService : LifecycleService(), DevicesDiscoveryCb {
                 } else {
                     val context = this at MediaParsingService
                     var shouldInit = !dbExists()
+                    val constructed = medialibrary.construct(context)
+                    if (!constructed) {
+                        exitCommand()
+                        return
+                    }
+                    addDevices(context, action.parse, action.removeDevices)
                     val initCode = medialibrary.init(context)
                     medialibrary.setLibVLCInstance((VLCInstance.getInstance(context) as LibVLC).getInstance())
                     medialibrary.setDiscoverNetworkEnabled(true)
diff --git a/medialibrary/jni/medialibrary.cpp b/medialibrary/jni/medialibrary.cpp
index 144622ede..bf5fa223e 100644
--- a/medialibrary/jni/medialibrary.cpp
+++ b/medialibrary/jni/medialibrary.cpp
@@ -27,16 +27,21 @@ AndroidMediaLibrary *MediaLibrary_getInstance(JNIEnv *env, jobject thiz);
 static void
 MediaLibrary_setInstance(JNIEnv *env, jobject thiz, AndroidMediaLibrary *p_obj);
 
-jint
-init(JNIEnv* env, jobject thiz, jstring dbPath, jstring thumbsPath)
+void
+constructML(JNIEnv* env, jobject thiz, jstring dbPath, jstring thumbsPath)
 {
-    const char *db_utfchars = env->GetStringUTFChars(dbPath, JNI_FALSE);
     const char *thumbs_utfchars = env->GetStringUTFChars(thumbsPath, JNI_FALSE);
+    const char *db_utfchars = env->GetStringUTFChars(dbPath, JNI_FALSE);
     AndroidMediaLibrary *aml = new  AndroidMediaLibrary(myVm, &ml_fields, thiz, db_utfchars, thumbs_utfchars);
     MediaLibrary_setInstance(env, thiz, aml);
-    medialibrary::InitializeResult initCode = aml->initML();
+}
+
+jint
+init(JNIEnv* env, jobject thiz, jstring thumbsPath)
+{
+    const char *thumbs_utfchars = env->GetStringUTFChars(thumbsPath, JNI_FALSE);
+    medialibrary::InitializeResult initCode = MediaLibrary_getInstance(env, thiz)->initML();
     m_IsInitialized = initCode != medialibrary::InitializeResult::Failed;
-    env->ReleaseStringUTFChars(dbPath, db_utfchars);
     env->ReleaseStringUTFChars(thumbsPath, thumbs_utfchars);
     return (int) initCode;
 }
@@ -2014,7 +2019,8 @@ regroup(JNIEnv* env, jobject thiz, jlong id)
   * JNI stuff
   */
 static JNINativeMethod methods[] = {
-    {"nativeInit", "(Ljava/lang/String;Ljava/lang/String;)I", (void*)init },
+    {"nativeConstruct", "(Ljava/lang/String;Ljava/lang/String;)V", (void*)constructML },
+    {"nativeInit", "(Ljava/lang/String;)I", (void*)init },
     {"nativeRelease", "()V", (void*)release },
     {"nativeClearDatabase", "(Z)Z", (void*)clearDatabase },
     {"nativeAddDevice", "(Ljava/lang/String;Ljava/lang/String;Z)V", (void*)addDevice },
diff --git a/medialibrary/src/org/videolan/medialibrary/MedialibraryImpl.java b/medialibrary/src/org/videolan/medialibrary/MedialibraryImpl.java
index fa6b0cd34..7df915f5d 100644
--- a/medialibrary/src/org/videolan/medialibrary/MedialibraryImpl.java
+++ b/medialibrary/src/org/videolan/medialibrary/MedialibraryImpl.java
@@ -46,42 +46,47 @@ import java.io.File;
 public class MedialibraryImpl extends Medialibrary {
     private static final String TAG = "VLC/JMedialibrary";
 
-    public int init(Context context) {
-        if (context == null) return ML_INIT_FAILED;
-        if (mIsInitiated) return ML_INIT_ALREADY_INITIALIZED;
+    public boolean construct(Context context) {
+        if (context == null) throw new IllegalStateException("context cannot be null");
+        if (mIsInitiated) return false;
         sContext = context;
         final File extFilesDir = context.getExternalFilesDir(null);
         File dbDirectory = context.getDir("db", Context.MODE_PRIVATE);
         if (extFilesDir == null || !extFilesDir.exists()
                 || dbDirectory == null || !dbDirectory.canWrite())
-            return ML_INIT_FAILED;
+            return false;
         LibVLC.loadLibraries();
         try {
             System.loadLibrary("c++_shared");
             System.loadLibrary("mla");
         } catch (UnsatisfiedLinkError ule) {
             Log.e(TAG, "Can't load mla: " + ule);
-            return ML_INIT_FAILED;
+            return false;
         }
         final File oldDir = new File(extFilesDir + THUMBS_FOLDER_NAME);
         if (oldDir.isDirectory()) {
             //remove old thumbnails directory
-            new Thread(new Runnable() {
-                @Override
-                public void run() {
-
-                    String[] children = oldDir.list();
-                    if (children != null) {
-                        for (String child : children) {
-                            new File(oldDir, child).delete();
-                        }
+            new Thread(() -> {
+
+                String[] children = oldDir.list();
+                if (children != null) {
+                    for (String child : children) {
+                        new File(oldDir, child).delete();
                     }
-                    oldDir.delete();
                 }
+                oldDir.delete();
             }).start();
         }
+        nativeConstruct(dbDirectory + VLC_MEDIA_DB_NAME, extFilesDir + MEDIALIB_FOLDER_NAME);
+        return true;
+    }
 
-        int initCode = nativeInit(dbDirectory + VLC_MEDIA_DB_NAME, extFilesDir + MEDIALIB_FOLDER_NAME);
+    public int init(Context context) {
+        if (context == null) return ML_INIT_FAILED;
+        if (mIsInitiated) return ML_INIT_ALREADY_INITIALIZED;
+        if (sContext == null) throw new IllegalStateException("Medialibrary construct has to be called before init");
+        File dbDirectory = context.getDir("db", Context.MODE_PRIVATE);
+        int initCode = nativeInit(dbDirectory + VLC_MEDIA_DB_NAME);
         if (initCode == ML_INIT_DB_CORRUPTED) {
             Log.e(TAG, "Medialib database is corrupted. Clearing it and try to restore playlists");
             if (!nativeClearDatabase(true)) return ML_INIT_DB_UNRECOVERABLE;
@@ -130,7 +135,6 @@ public class MedialibraryImpl extends Medialibrary {
     }
 
     public void addDevice(@NonNull String uuid, @NonNull String path, boolean removable) {
-        if (!mIsInitiated) return;
         nativeAddDevice(VLCUtil.encodeVLCString(uuid), Tools.encodeVLCMrl(path), removable);
         synchronized (onDeviceChangeListeners) {
             for (OnDeviceChangeListener listener : onDeviceChangeListeners) listener.onDeviceChange();
@@ -598,7 +602,8 @@ public class MedialibraryImpl extends Medialibrary {
     }
 
     // Native methods
-    private native int nativeInit(String dbPath, String thumbsPath);
+    private native void nativeConstruct(String dbPath, String thumbsPath);
+    private native int nativeInit(String dbPath);
     private native void nativeRelease();
 
     private native boolean nativeClearDatabase(boolean keepPlaylist);
diff --git a/medialibrary/src/org/videolan/medialibrary/interfaces/Medialibrary.java b/medialibrary/src/org/videolan/medialibrary/interfaces/Medialibrary.java
index 39174677c..7b8977f9b 100644
--- a/medialibrary/src/org/videolan/medialibrary/interfaces/Medialibrary.java
+++ b/medialibrary/src/org/videolan/medialibrary/interfaces/Medialibrary.java
@@ -697,6 +697,7 @@ abstract public class Medialibrary {
         }
     }
 
+    abstract public boolean construct(Context context);
     abstract public int init(Context context);
     abstract public void start();
     abstract public void banFolder(@NonNull String path);
diff --git a/medialibrary/src/org/videolan/medialibrary/stubs/StubMedialibrary.java b/medialibrary/src/org/videolan/medialibrary/stubs/StubMedialibrary.java
index c4ebaff1f..dfd81e3a3 100644
--- a/medialibrary/src/org/videolan/medialibrary/stubs/StubMedialibrary.java
+++ b/medialibrary/src/org/videolan/medialibrary/stubs/StubMedialibrary.java
@@ -28,9 +28,14 @@ public class StubMedialibrary extends Medialibrary {
 
     private StubDataSource dt = StubDataSource.getInstance();
 
-    public int init(Context context) {
-        if (context == null) return ML_INIT_FAILED;
+    public boolean construct(Context context) {
+        if (context == null) return false;
         sContext = context;
+        return true;
+    }
+
+    public int init(Context context) {
+        if (context == null || sContext == null) return ML_INIT_FAILED;
         return ML_INIT_SUCCESS;
     }
 



More information about the Android mailing list