[Android] [PATCH] Only one way to get LibVLC instance.

Thomas Guillem thomas at gllm.fr
Mon Mar 23 11:07:28 CET 2015


There were 2 differents way to get a LibVLC instance. For now, use only
VLCInstance.get() utility method. This method will init LibVLC if it's not
already done.

This method will throw an IllegalStateException if LibVLC.init() failed. The
application will crash with the default android crash dialog instead of the
custom CompatErrorActivity. It allows the error to be reported to the google
play dev console.
---
 libvlc/src/org/videolan/libvlc/LibVLC.java         | 43 +----------
 vlc-android/AndroidManifest.xml                    |  1 -
 vlc-android/src/org/videolan/vlc/MediaLibrary.java |  8 +-
 .../videolan/vlc/RemoteControlClientReceiver.java  | 11 +--
 vlc-android/src/org/videolan/vlc/Thumbnailer.java  | 10 +--
 .../src/org/videolan/vlc/audio/AudioService.java   | 16 ++--
 .../org/videolan/vlc/gui/CompatErrorActivity.java  | 88 ----------------------
 .../videolan/vlc/gui/DirectoryViewFragment.java    |  5 +-
 .../src/org/videolan/vlc/gui/MainActivity.java     | 33 +-------
 .../org/videolan/vlc/gui/PreferencesActivity.java  |  2 +-
 .../videolan/vlc/gui/audio/EqualizerFragment.java  |  4 +-
 .../videolan/vlc/gui/dialogs/JumpToTimeDialog.java |  2 +-
 .../videolan/vlc/gui/dialogs/PickTimeFragment.java |  3 +-
 .../vlc/gui/dialogs/TimePickerDialogFragment.java  |  4 +-
 .../videolan/vlc/gui/expandable/JumpToTime.java    |  9 ++-
 .../videolan/vlc/gui/expandable/SpeedSelector.java | 12 ++-
 .../videolan/vlc/gui/network/NetworkFragment.java  |  5 +-
 .../videolan/vlc/gui/video/AdvOptionsDialog.java   |  9 ++-
 .../videolan/vlc/gui/video/MediaInfoFragment.java  | 10 ++-
 .../videolan/vlc/gui/video/VideoGridFragment.java  |  5 +-
 .../vlc/gui/video/VideoPlayerActivity.java         | 36 ++++-----
 .../src/org/videolan/vlc/util/VLCInstance.java     | 59 +++++++++------
 .../org/videolan/vlc/gui/tv/MainTvActivity.java    | 18 +----
 23 files changed, 107 insertions(+), 286 deletions(-)
 delete mode 100644 vlc-android/src/org/videolan/vlc/gui/CompatErrorActivity.java

diff --git a/libvlc/src/org/videolan/libvlc/LibVLC.java b/libvlc/src/org/videolan/libvlc/LibVLC.java
index a0f6bf3..01bed0b 100644
--- a/libvlc/src/org/videolan/libvlc/LibVLC.java
+++ b/libvlc/src/org/videolan/libvlc/LibVLC.java
@@ -61,8 +61,6 @@ public class LibVLC {
     private static final String DEFAULT_CODEC_LIST = "mediacodec,iomx,all";
     private static final boolean HAS_WINDOW_VOUT = LibVlcUtil.isGingerbreadOrLater();
 
-    private static LibVLC sInstance;
-
     /** libVLC instance C pointer */
     private long mLibVlcInstance = 0; // Read-only, reserved for JNI
     /** libvlc_media_player pointer */
@@ -155,38 +153,10 @@ public class LibVLC {
     }
 
     /**
-     * Singleton constructor of libVLC Without surface and vout to create the
-     * thumbnail and get information e.g. on the MediaLibraryActivity
-     *
-     * @return libVLC instance
-     */
-    public static LibVLC getInstance() {
-        synchronized (LibVLC.class) {
-            if (sInstance == null) {
-                /* First call */
-                sInstance = new LibVLC();
-            }
-            return sInstance;
-        }
-    }
-
-    /**
-     * Return an existing instance of libVLC Call it when it is NOT important
-     * that this fails
-     *
-     * @return libVLC instance OR null
-     */
-    public static LibVLC getExistingInstance() {
-        synchronized (LibVLC.class) {
-            return sInstance;
-        }
-    }
-
-    /**
      * Constructor
      * It is private because this class is a singleton.
      */
-    private LibVLC() {
+    public LibVLC() {
     }
 
     /**
@@ -208,17 +178,6 @@ public class LibVLC {
      */
     public native void setSurface(Surface f);
 
-    public static synchronized void restart(Context context) {
-        if (sInstance != null) {
-            try {
-                sInstance.destroy();
-                sInstance.init(context);
-            } catch (LibVlcException lve) {
-                Log.e(TAG, "Unable to reinit libvlc: " + lve);
-            }
-        }
-    }
-
     /**
      * those get/is* are called from native code to get settings values.
      */
diff --git a/vlc-android/AndroidManifest.xml b/vlc-android/AndroidManifest.xml
index 20f2499..82a6d2d 100644
--- a/vlc-android/AndroidManifest.xml
+++ b/vlc-android/AndroidManifest.xml
@@ -62,7 +62,6 @@
         <activity
             android:name=".gui.SecondaryActivity"
             android:theme="@style/Theme.VLC"/>
-        <activity android:name=".gui.CompatErrorActivity" />
         <activity android:name=".gui.PreferencesActivity"
             android:theme="@style/Theme.VLC" />
         <activity
diff --git a/vlc-android/src/org/videolan/vlc/MediaLibrary.java b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
index d87e3d7..bd277d1 100644
--- a/vlc-android/src/org/videolan/vlc/MediaLibrary.java
+++ b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
@@ -208,13 +208,7 @@ public class MediaLibrary {
 
         @Override
         public void run() {
-            LibVLC libVlcInstance;
-            try {
-                libVlcInstance = VLCInstance.getLibVlcInstance();
-            } catch (LibVlcException e1) {
-                Log.e(TAG, "ERROR: LibVLCException while trying to get instance");
-                return;
-            }
+            LibVLC libVlcInstance = VLCInstance.get();
 
             // Initialize variables
             final MediaDatabase mediaDatabase = MediaDatabase.getInstance();
diff --git a/vlc-android/src/org/videolan/vlc/RemoteControlClientReceiver.java b/vlc-android/src/org/videolan/vlc/RemoteControlClientReceiver.java
index 8af007e..eaaa524 100644
--- a/vlc-android/src/org/videolan/vlc/RemoteControlClientReceiver.java
+++ b/vlc-android/src/org/videolan/vlc/RemoteControlClientReceiver.java
@@ -44,14 +44,7 @@ public class RemoteControlClientReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
-        LibVLC mLibVLC;
-        try {
-            mLibVLC = VLCInstance.getLibVlcInstance();
-        } catch (LibVlcException e) {
-            return;
-        }
-        if(mLibVLC == null)
-            return;
+        LibVLC libVLC = VLCInstance.get();
 
         if(action.equalsIgnoreCase(Intent.ACTION_MEDIA_BUTTON)) {
 
@@ -92,7 +85,7 @@ public class RemoteControlClientReceiver extends BroadcastReceiver {
                             }
                             // one click
                             else {
-                                if (mLibVLC.isPlaying())
+                                if (libVLC.isPlaying())
                                     i = new Intent(AudioService.ACTION_REMOTE_PAUSE);
                                 else {
                                     i = new Intent(context, AudioService.class);
diff --git a/vlc-android/src/org/videolan/vlc/Thumbnailer.java b/vlc-android/src/org/videolan/vlc/Thumbnailer.java
index 3f74da7..2097be8 100644
--- a/vlc-android/src/org/videolan/vlc/Thumbnailer.java
+++ b/vlc-android/src/org/videolan/vlc/Thumbnailer.java
@@ -67,15 +67,7 @@ public class Thumbnailer implements Runnable {
     }
 
     public void start(IVideoBrowser videoBrowser) {
-        if (mLibVlc == null) {
-            try {
-                mLibVlc = VLCInstance.getLibVlcInstance();
-            } catch (LibVlcException e) {
-                Log.e(TAG, "Can't obtain libvlc instance");
-                e.printStackTrace();
-                return;
-            }
-        }
+        mLibVlc = VLCInstance.get();
 
         isStopping = false;
         if (mThread == null || mThread.getState() == State.TERMINATED) {
diff --git a/vlc-android/src/org/videolan/vlc/audio/AudioService.java b/vlc-android/src/org/videolan/vlc/audio/AudioService.java
index ca0c0ea..9d28717 100644
--- a/vlc-android/src/org/videolan/vlc/audio/AudioService.java
+++ b/vlc-android/src/org/videolan/vlc/audio/AudioService.java
@@ -159,11 +159,8 @@ public class AudioService extends Service {
         super.onCreate();
 
         // Get libVLC instance
-        try {
-            mLibVLC = VLCInstance.getLibVlcInstance();
-        } catch (LibVlcException e) {
-            e.printStackTrace();
-        }
+        mLibVLC = VLCInstance.get();
+
         mMediaListPlayer = MediaWrapperListPlayer.getInstance(mLibVLC);
 
         mCallback = new HashMap<IAudioServiceCallback, Integer>();
@@ -320,12 +317,11 @@ public class AudioService extends Service {
             audioFocusListener = new OnAudioFocusChangeListener() {
                 @Override
                 public void onAudioFocusChange(int focusChange) {
-                    LibVLC libVLC = LibVLC.getExistingInstance();
                     switch (focusChange)
                     {
                         case AudioManager.AUDIOFOCUS_LOSS:
-                            if (libVLC.isPlaying())
-                                libVLC.pause();
+                            if (mLibVLC.isPlaying())
+                                mLibVLC.pause();
                             break;
                         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
@@ -333,12 +329,12 @@ public class AudioService extends Service {
                              * Lower the volume to 36% to "duck" when an alert or something
                              * needs to be played.
                              */
-                            libVLC.setVolume(36);
+                            mLibVLC.setVolume(36);
                             break;
                         case AudioManager.AUDIOFOCUS_GAIN:
                         case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
                         case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
-                            libVLC.setVolume(100);
+                            mLibVLC.setVolume(100);
                             break;
                     }
                 }
diff --git a/vlc-android/src/org/videolan/vlc/gui/CompatErrorActivity.java b/vlc-android/src/org/videolan/vlc/gui/CompatErrorActivity.java
deleted file mode 100644
index 616cd57..0000000
--- a/vlc-android/src/org/videolan/vlc/gui/CompatErrorActivity.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.videolan.vlc.gui;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.videolan.libvlc.LibVlcUtil;
-import org.videolan.vlc.R;
-
-import android.app.Activity;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.TextView;
-
-public class CompatErrorActivity extends Activity {
-    public final static String TAG = "VLC/CompatErrorActivity";
-
-    /**
-     * Simple friendly activity to tell the user something's wrong.
-     *
-     * Intent parameters (all optional):
-     * runtimeError (bool) - Set to true if you want to show a runtime error
-     *                       (defaults to a compatibility error)
-     * message (string) - the more detailed problem
-     */
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.not_compatible);
-
-        String errorMsg = LibVlcUtil.getErrorMsg();
-        if(getIntent().getBooleanExtra("runtimeError", false))
-            if(getIntent().getStringExtra("message") != null) {
-                errorMsg = getIntent().getStringExtra("message");
-                TextView tvo = (TextView)findViewById(R.id.message);
-                tvo.setText(R.string.error_problem);
-            }
-
-        TextView tv = (TextView)findViewById(R.id.errormsg);
-        tv.setText(getResources().getString(R.string.error_message_is) + "\n" + errorMsg);
-
-        //AsyncHttpRequest asyncHttpRequest = new AsyncHttpRequest();
-        //asyncHttpRequest.execute(Build.MODEL, Build.DEVICE);
-    }
-
-    public static class AsyncHttpRequest extends AsyncTask<String, String, Boolean> {
-
-        public AsyncHttpRequest() { }
-
-        @Override
-        protected Boolean doInBackground(String... params) {
-            if (params[0].length() == 0)
-                return false;
-            HttpClient httpClient = new DefaultHttpClient();
-            HttpPost httpPost = new HttpPost("http://people.videolan.org/~jb/blacklist/vlc-devices.php");
-
-            try {
-                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
-                nameValuePairs.add(new BasicNameValuePair("model", params[0]));
-                nameValuePairs.add(new BasicNameValuePair("device", params[1]));
-                httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
-
-                httpClient.execute(httpPost);
-            } catch (ClientProtocolException e) {
-                e.printStackTrace();
-                return false;
-            } catch (IOException e) {
-                e.printStackTrace();
-                return false;
-            }
-            Log.d(TAG, "Device model sent.");
-            return true;
-        }
-
-        @Override
-        protected void onPostExecute(Boolean result) {
-
-        }
-    }
-}
diff --git a/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java b/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
index 8666384..5ec2332 100644
--- a/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
@@ -32,6 +32,7 @@ import org.videolan.vlc.audio.AudioServiceController;
 import org.videolan.vlc.gui.video.VideoPlayerActivity;
 import org.videolan.vlc.interfaces.IRefreshable;
 import org.videolan.vlc.util.Util;
+import org.videolan.vlc.util.VLCInstance;
 import org.videolan.vlc.util.VLCRunnable;
 import org.videolan.vlc.widget.SwipeRefreshLayout;
 
@@ -258,8 +259,8 @@ public class DirectoryViewFragment extends BrowserFragment implements IRefreshab
         String mediaFile = mDirectoryAdapter.getMediaLocation(p);
 
         try {
-            if (LibVLC.getExistingInstance() == null
-                    || !LibVLC.getExistingInstance().hasVideoTrack(mediaFile)) {
+            final LibVLC libVLC = VLCInstance.get();
+            if (!libVLC.hasVideoTrack(mediaFile)) {
                 List<String> mediaLocations = mDirectoryAdapter.getAllMediaLocations();
                 audioController.load(mediaLocations, mediaLocations.indexOf(mediaFile));
             } else {
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index ac6529e..4f9fd20 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -73,12 +73,9 @@ import org.videolan.vlc.VLCApplication;
 import org.videolan.vlc.audio.AudioService;
 import org.videolan.vlc.audio.AudioServiceController;
 import org.videolan.vlc.gui.SidebarAdapter.SidebarEntry;
-import org.videolan.vlc.gui.audio.AudioAlbumsSongsFragment;
 import org.videolan.vlc.gui.audio.AudioBrowserFragment;
 import org.videolan.vlc.gui.audio.AudioPlayer;
-import org.videolan.vlc.gui.audio.EqualizerFragment;
 import org.videolan.vlc.gui.network.NetworkFragment;
-import org.videolan.vlc.gui.video.MediaInfoFragment;
 import org.videolan.vlc.gui.video.VideoGridFragment;
 import org.videolan.vlc.gui.video.VideoListAdapter;
 import org.videolan.vlc.gui.video.VideoPlayerActivity;
@@ -91,10 +88,6 @@ import org.videolan.vlc.util.WeakHandler;
 import org.videolan.vlc.widget.HackyDrawerLayout;
 import org.videolan.vlc.widget.SlidingPaneLayout;
 
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-
 public class MainActivity extends ActionBarActivity implements OnItemClickListener, SearchSuggestionsAdapter.SuggestionDisplay, FilterQueryProvider {
     public final static String TAG = "VLC/MainActivity";
 
@@ -139,16 +132,10 @@ public class MainActivity extends ActionBarActivity implements OnItemClickListen
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
         /* Enable the indeterminate progress feature */
         supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
-        if (!LibVlcUtil.hasCompatibleCPU(this)) {
-            Log.e(TAG, LibVlcUtil.getErrorMsg());
-            Intent i = new Intent(this, CompatErrorActivity.class);
-            startActivity(i);
-            finish();
-            super.onCreate(savedInstanceState);
-            return;
-        }
 
         mContext = this;
         /* Get the current version from package */
@@ -165,28 +152,12 @@ public class MainActivity extends ActionBarActivity implements OnItemClickListen
             Util.commitPreferences(editor);
         }
 
-        try {
-            // Start LibVLC
-            VLCInstance.getLibVlcInstance();
-        } catch (LibVlcException e) {
-            e.printStackTrace();
-            Intent i = new Intent(this, CompatErrorActivity.class);
-            i.putExtra("runtimeError", true);
-            i.putExtra("message", "LibVLC failed to initialize (LibVlcException)");
-            startActivity(i);
-            finish();
-            super.onCreate(savedInstanceState);
-            return;
-        }
-
         /* Load media items from database and storage */
         MediaLibrary.getInstance().loadMediaItems();
 
         /* Theme must be applied before super.onCreate */
         applyTheme();
 
-        super.onCreate(savedInstanceState);
-
         /*** Start initializing the UI ***/
 
         setContentView(R.layout.main);
diff --git a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
index a46865c..d3fa303 100644
--- a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
@@ -345,7 +345,7 @@ public class PreferencesActivity extends PreferenceActivity implements OnSharedP
                 || key.equalsIgnoreCase("network_caching")
                 || key.equalsIgnoreCase("dev_hardware_decoder")) {
             VLCInstance.updateLibVlcSettings(sharedPreferences);
-            LibVLC.restart(this);
+            VLCInstance.restart(this);
         }
     }
 
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/EqualizerFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/EqualizerFragment.java
index dd6c240..5ee46b4 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/EqualizerFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/EqualizerFragment.java
@@ -46,6 +46,7 @@ import org.videolan.vlc.VLCApplication;
 import org.videolan.vlc.interfaces.OnEqualizerBarChangeListener;
 import org.videolan.vlc.util.Preferences;
 import org.videolan.vlc.util.Util;
+import org.videolan.vlc.util.VLCInstance;
 import org.videolan.vlc.widget.EqualizerBar;
 
 public class EqualizerFragment extends Fragment {
@@ -90,7 +91,8 @@ public class EqualizerFragment extends Fragment {
         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(VLCApplication.getAppContext());
         float[] bands = null;
         String[] presets = null;
-        libVlc = LibVLC.getInstance();
+        libVlc = VLCInstance.get();
+
         bands = libVlc.getBands();
         presets = libVlc.getPresets();
         if (equalizer == null)
diff --git a/vlc-android/src/org/videolan/vlc/gui/dialogs/JumpToTimeDialog.java b/vlc-android/src/org/videolan/vlc/gui/dialogs/JumpToTimeDialog.java
index bbd07f3..e2e4b4a 100644
--- a/vlc-android/src/org/videolan/vlc/gui/dialogs/JumpToTimeDialog.java
+++ b/vlc-android/src/org/videolan/vlc/gui/dialogs/JumpToTimeDialog.java
@@ -62,7 +62,7 @@ public class JumpToTimeDialog extends PickTimeFragment {
         long hours = mHours != null ? Long.parseLong(mHours.getText().toString()) * HOURS_IN_MICROS : 0l;
         long minutes = Long.parseLong(mMinutes.getText().toString()) * MINUTES_IN_MICROS ;
         long seconds = Long.parseLong(mSeconds.getText().toString()) * SECONDS_IN_MICROS;
-        LibVLC.getExistingInstance().setTime((hours +  minutes + seconds)/1000l); //Time in ms
+        mLibVLC.setTime((hours +  minutes + seconds)/1000l); //Time in ms
         dismiss();
     }
 
diff --git a/vlc-android/src/org/videolan/vlc/gui/dialogs/PickTimeFragment.java b/vlc-android/src/org/videolan/vlc/gui/dialogs/PickTimeFragment.java
index 213c2a0..9db6fd6 100644
--- a/vlc-android/src/org/videolan/vlc/gui/dialogs/PickTimeFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/dialogs/PickTimeFragment.java
@@ -38,6 +38,7 @@ import android.widget.TextView;
 import org.videolan.libvlc.LibVLC;
 import org.videolan.vlc.R;
 import org.videolan.vlc.util.AndroidDevices;
+import org.videolan.vlc.util.VLCInstance;
 
 public abstract class PickTimeFragment extends DialogFragment implements DialogInterface.OnKeyListener, View.OnClickListener, View.OnFocusChangeListener, TextView.OnEditorActionListener {
 
@@ -61,7 +62,7 @@ public abstract class PickTimeFragment extends DialogFragment implements DialogI
     protected long max = -1;
 
     public PickTimeFragment(){
-        mLibVLC = LibVLC.getInstance();
+        mLibVLC = VLCInstance.get();
     }
 
     @Override
diff --git a/vlc-android/src/org/videolan/vlc/gui/dialogs/TimePickerDialogFragment.java b/vlc-android/src/org/videolan/vlc/gui/dialogs/TimePickerDialogFragment.java
index 1d8077a..e1eeb2d 100644
--- a/vlc-android/src/org/videolan/vlc/gui/dialogs/TimePickerDialogFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/dialogs/TimePickerDialogFragment.java
@@ -32,6 +32,7 @@ import org.videolan.libvlc.LibVLC;
 import org.videolan.libvlc.LibVlcUtil;
 import org.videolan.vlc.VLCApplication;
 import org.videolan.vlc.gui.video.AdvOptionsDialog;
+import org.videolan.vlc.util.VLCInstance;
 
 import java.util.Calendar;
 
@@ -90,7 +91,8 @@ public class TimePickerDialogFragment extends DialogFragment implements TimePick
                 break;
             case ACTION_JUMP:
                 long time = ( hourOfDay * 60l + minute ) * 60000l;
-                LibVLC.getExistingInstance().setTime(time);
+                final LibVLC libVLC = VLCInstance.get();
+                libVLC.setTime(time);
                 break;
         }
     }
diff --git a/vlc-android/src/org/videolan/vlc/gui/expandable/JumpToTime.java b/vlc-android/src/org/videolan/vlc/gui/expandable/JumpToTime.java
index 1e843ef..4a1f08c 100644
--- a/vlc-android/src/org/videolan/vlc/gui/expandable/JumpToTime.java
+++ b/vlc-android/src/org/videolan/vlc/gui/expandable/JumpToTime.java
@@ -30,6 +30,7 @@ import org.videolan.libvlc.LibVLC;
 import org.videolan.vlc.R;
 import org.videolan.vlc.audio.AudioServiceController;
 import org.videolan.vlc.util.Util;
+import org.videolan.vlc.util.VLCInstance;
 import org.videolan.vlc.widget.ExpandableLayout;
 
 import android.content.Context;
@@ -88,10 +89,10 @@ public class JumpToTime extends ExpandableLayout {
     private OnClickListener mOnOkListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
-            LibVLC.getExistingInstance().setTime(
-                    1000 * (mHourWheel.getCurrentItem() * 60 * 60 +
-                            mMinWheel.getCurrentItem() * 60 +
-                            mSecWheel.getCurrentItem()));
+            final LibVLC libVLC = VLCInstance.get();
+            libVLC.setTime(1000 * (mHourWheel.getCurrentItem() * 60 * 60 +
+                           mMinWheel.getCurrentItem() * 60 +
+                           mSecWheel.getCurrentItem()));
             dismiss();
         }
     };
diff --git a/vlc-android/src/org/videolan/vlc/gui/expandable/SpeedSelector.java b/vlc-android/src/org/videolan/vlc/gui/expandable/SpeedSelector.java
index 7143bd9..f173297 100644
--- a/vlc-android/src/org/videolan/vlc/gui/expandable/SpeedSelector.java
+++ b/vlc-android/src/org/videolan/vlc/gui/expandable/SpeedSelector.java
@@ -24,6 +24,7 @@ import org.videolan.libvlc.LibVLC;
 import org.videolan.vlc.R;
 import org.videolan.vlc.util.Strings;
 import org.videolan.vlc.util.Util;
+import org.videolan.vlc.util.VLCInstance;
 import org.videolan.vlc.widget.ExpandableLayout;
 
 import android.content.Context;
@@ -50,11 +51,8 @@ public class SpeedSelector extends ExpandableLayout {
         float rate = 1.0f;
 
         //libvlc is not available in layout editor
-        if (!isInEditMode()) {
-            LibVLC libVLC = LibVLC.getExistingInstance();
-            if (libVLC != null)
-                rate = libVLC.getRate();
-        }
+        if (!isInEditMode())
+            rate = VLCInstance.get().getRate();
 
         setText(Strings.formatRateString(rate));
         mSeekbar.setProgress((int) (((Math.log(rate) / Math.log(4)) + 1) * 100));
@@ -68,7 +66,7 @@ public class SpeedSelector extends ExpandableLayout {
         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
             float rate = (float) Math.pow(4, ((double) progress / (double) 100) - 1);
             setText(Strings.formatRateString(rate));
-            LibVLC.getExistingInstance().setRate(rate);
+            VLCInstance.get().setRate(rate);
         }
 
         @Override
@@ -84,7 +82,7 @@ public class SpeedSelector extends ExpandableLayout {
         @Override
         public void onClick(View v) {
             mSeekbar.setProgress(100);
-            LibVLC.getExistingInstance().setRate(1);
+            VLCInstance.get().setRate(1);
         }
     };
 }
diff --git a/vlc-android/src/org/videolan/vlc/gui/network/NetworkFragment.java b/vlc-android/src/org/videolan/vlc/gui/network/NetworkFragment.java
index 7138957..0d73deb 100644
--- a/vlc-android/src/org/videolan/vlc/gui/network/NetworkFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/network/NetworkFragment.java
@@ -49,6 +49,7 @@ import org.videolan.vlc.gui.MainActivity;
 import org.videolan.vlc.interfaces.IRefreshable;
 import org.videolan.vlc.util.AndroidDevices;
 import org.videolan.vlc.util.Strings;
+import org.videolan.vlc.util.VLCInstance;
 import org.videolan.vlc.util.WeakHandler;
 import org.videolan.vlc.widget.SwipeRefreshLayout;
 
@@ -74,10 +75,12 @@ public class NetworkFragment extends BrowserFragment implements IRefreshable, Me
     private MediaWrapper mCurrentMedia;
     private int mSavedPosition = -1, mFavorites = 0;
     private boolean mRoot;
-    LibVLC mLibVLC = LibVLC.getExistingInstance();
+    private LibVLC mLibVLC;
 
     public void onCreate(Bundle bundle){
         super.onCreate(bundle);
+        mLibVLC = VLCInstance.get();
+
         if (bundle == null)
             bundle = getArguments();
         if (bundle != null){
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/AdvOptionsDialog.java b/vlc-android/src/org/videolan/vlc/gui/video/AdvOptionsDialog.java
index 994ac31..c111e97 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/AdvOptionsDialog.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/AdvOptionsDialog.java
@@ -51,6 +51,7 @@ import org.videolan.vlc.gui.dialogs.TimePickerDialogFragment;
 import org.videolan.vlc.interfaces.IDelayController;
 import org.videolan.vlc.util.AndroidDevices;
 import org.videolan.vlc.util.Strings;
+import org.videolan.vlc.util.VLCInstance;
 
 import java.util.Calendar;
 
@@ -150,9 +151,9 @@ public class AdvOptionsDialog extends DialogFragment implements View.OnClickList
         mHandler.sendEmptyMessage(TOGGLE_CANCEL);
         mTextColor = mSleepTitle.getCurrentTextColor();
 
-        double speed = LibVLC.getExistingInstance().getRate();
+        double speed = VLCInstance.get().getRate();
         if (speed != 1.0d) {
-            speed = 100*(1+Math.log(speed)/Math.log(4));
+            speed = 100 * (1 + Math.log(speed) / Math.log(4));
             mSeek.setProgress((int) speed);
         }
         return root;
@@ -163,7 +164,7 @@ public class AdvOptionsDialog extends DialogFragment implements View.OnClickList
         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
             float rate = (float) Math.pow(4, ((double) progress / (double) 100) - 1);
             mHandler.obtainMessage(SPEED_TEXT, Strings.formatRateString(rate)).sendToTarget();
-            LibVLC.getExistingInstance().setRate(rate);
+            VLCInstance.get().setRate(rate);
         }
 
         public void onStartTrackingTouch(SeekBar seekBar) {}
@@ -174,7 +175,7 @@ public class AdvOptionsDialog extends DialogFragment implements View.OnClickList
         @Override
         public void onClick(View v) {
             mSeek.setProgress(100);
-            LibVLC.getExistingInstance().setRate(1);
+            VLCInstance.get().setRate(1);
         }
     };
 
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java b/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java
index 5eddcbc..43fb511 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java
@@ -48,6 +48,7 @@ import org.videolan.vlc.gui.MainActivity;
 import org.videolan.vlc.util.BitmapUtil;
 import org.videolan.vlc.util.Strings;
 import org.videolan.vlc.util.Util;
+import org.videolan.vlc.util.VLCInstance;
 import org.videolan.vlc.util.WeakHandler;
 
 import java.io.File;
@@ -58,7 +59,6 @@ import java.util.concurrent.Executors;
 public class MediaInfoFragment extends ListFragment {
 
     public final static String TAG = "VLC/MediaInfoFragment";
-    LibVLC mLibVlc = null;
 
     private MediaWrapper mItem;
     private Bitmap mImage;
@@ -202,8 +202,10 @@ public class MediaInfoFragment extends ListFragment {
     Runnable mLoadImage = new Runnable() {
         @Override
         public void run() {
-            mLibVlc = LibVLC.getInstance();
-            mMedia = new Media(mLibVlc, mItem.getLocation());
+            final LibVLC libVlc = VLCInstance.get();
+            if (libVlc == null)
+                return;
+            mMedia = new Media(libVlc, mItem.getLocation());
             mMedia.parse();
             mMedia.release();
             int videoHeight = mItem.getHeight();
@@ -226,7 +228,7 @@ public class MediaInfoFragment extends ListFragment {
             // Get the thumbnail.
             mImage = Bitmap.createBitmap(width, height, Config.ARGB_8888);
 
-            byte[] b = mLibVlc.getThumbnail(mItem.getLocation(), width, height);
+            byte[] b = libVlc.getThumbnail(mItem.getLocation(), width, height);
 
             if (b == null) // We were not able to create a thumbnail for this item.
                 return;
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
index 5dd04f0..d96212c 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
@@ -72,6 +72,7 @@ import org.videolan.vlc.gui.SecondaryActivity;
 import org.videolan.vlc.interfaces.ISortable;
 import org.videolan.vlc.interfaces.IVideoBrowser;
 import org.videolan.vlc.util.Util;
+import org.videolan.vlc.util.VLCInstance;
 import org.videolan.vlc.util.VLCRunnable;
 import org.videolan.vlc.widget.SwipeRefreshLayout;
 
@@ -103,7 +104,6 @@ public class VideoGridFragment extends BrowserFragment implements ISortable, IVi
 
     private VideoListAdapter mVideoAdapter;
     private MediaLibrary mMediaLibrary;
-    private LibVLC mLibVlc;
     private Thumbnailer mThumbnailer;
     private VideoGridAnimator mAnimator;
 
@@ -129,7 +129,6 @@ public class VideoGridFragment extends BrowserFragment implements ISortable, IVi
         FragmentActivity activity = getActivity();
         if (activity != null)
             mThumbnailer = new Thumbnailer(activity, activity.getWindowManager().getDefaultDisplay());
-        mLibVlc = LibVLC.getInstance();
     }
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
@@ -352,7 +351,7 @@ public class VideoGridFragment extends BrowserFragment implements ISortable, IVi
             menu.findItem(R.id.video_list_play_from_start).setVisible(true);
 
         boolean hasInfo = false;
-        final Media media = new Media(mLibVlc, mediaWrapper.getLocation());
+        final Media media = new Media(VLCInstance.get(), mediaWrapper.getLocation());
         media.parse();
         media.release();
         if (media.getMeta(Media.Meta.Title) != null)
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
index f715e54..aea54ae 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
@@ -305,6 +305,9 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
+        mLibVLC = VLCInstance.get();
+
         if (LibVlcUtil.isJellyBeanMR1OrLater()) {
             // Get the media router service (Miracast)
             mMediaRouter = (MediaRouter) getSystemService(Context.MEDIA_ROUTER_SERVICE);
@@ -405,12 +408,6 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
         mDelayPlus = (ImageView) findViewById(R.id.player_delay_plus);
         mDelayMinus = (ImageView) findViewById(R.id.player_delay_minus);
 
-        try {
-            mLibVLC = VLCInstance.getLibVlcInstance();
-        } catch (LibVlcException e) {
-            Log.d(TAG, "LibVLC initialisation failed");
-            return;
-        }
         mMediaListPlayer = MediaWrapperListPlayer.getInstance(mLibVLC);
 
         mSurfaceView = (SurfaceView) findViewById(R.id.player_surface);
@@ -565,7 +562,8 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        unregisterReceiver(mReceiver);
+        if (mReceiver != null)
+            unregisterReceiver(mReceiver);
 
         mAudioManager = null;
     }
@@ -1849,12 +1847,16 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
         showInfo(getString(R.string.volume) + '\u00A0' + Integer.toString(vol),1000);
     }
 
-    private void updateMute () {
-        mMute = !mMute;
+    private void mute(boolean mute) {
+        mMute = mute;
         if (mMute)
             mVolSave = mLibVLC.getVolume();
         mLibVLC.setVolume(mMute ? 0 : mVolSave);
-            showInfo(mMute ? R.string.sound_off : R.string.sound_on,1000);
+    }
+
+    private void updateMute () {
+        mute(!mMute);
+        showInfo(mMute ? R.string.sound_off : R.string.sound_on,1000);
     }
 
     @TargetApi(android.os.Build.VERSION_CODES.FROYO)
@@ -2578,9 +2580,6 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
             fromStart = getIntent().getExtras().getBoolean("fromStart");
         }
 
-        if(mLibVLC == null)
-            return;
-
         /* WARNING: hack to avoid a crash in mediacodec on KitKat.
          * Disable hardware acceleration if the media has a ts extension. */
         if (mLocation != null && LibVlcUtil.isKitKatOrLater()) {
@@ -2774,7 +2773,7 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
         if (presentationDisplay != null) {
             // Show a new presentation if possible.
             Log.i(TAG, "Showing presentation on display: " + presentationDisplay);
-            mPresentation = new SecondaryDisplay(this, presentationDisplay);
+            mPresentation = new SecondaryDisplay(this, mLibVLC, presentationDisplay);
             mPresentation.setOnDismissListener(mOnDismissListener);
             try {
                 mPresentation.show();
@@ -2828,17 +2827,12 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
         private FrameLayout mSurfaceFrame;
         private LibVLC mLibVLC;
 
-        public SecondaryDisplay(Context context, Display display) {
+        public SecondaryDisplay(Context context, LibVLC libVLC, Display display) {
             super(context, display);
             if (context instanceof ActionBarActivity) {
                 setOwnerActivity((ActionBarActivity) context);
             }
-            try {
-                mLibVLC = VLCInstance.getLibVlcInstance();
-            } catch (LibVlcException e) {
-                Log.d(TAG, "LibVLC initialisation failed");
-                return;
-            }
+            mLibVLC = libVLC;
         }
 
         @Override
diff --git a/vlc-android/src/org/videolan/vlc/util/VLCInstance.java b/vlc-android/src/org/videolan/vlc/util/VLCInstance.java
index 17b6bb5..0853d51 100644
--- a/vlc-android/src/org/videolan/vlc/util/VLCInstance.java
+++ b/vlc-android/src/org/videolan/vlc/util/VLCInstance.java
@@ -22,6 +22,7 @@ package org.videolan.vlc.util;
 
 import org.videolan.libvlc.LibVLC;
 import org.videolan.libvlc.LibVlcException;
+import org.videolan.libvlc.LibVlcUtil;
 import org.videolan.vlc.VLCApplication;
 import org.videolan.vlc.VLCCrashHandler;
 import org.videolan.vlc.gui.NativeCrashActivity;
@@ -33,18 +34,22 @@ import android.preference.PreferenceManager;
 
 public class VLCInstance {
     public final static String TAG = "VLC/Util/VLCInstance";
+    private static LibVLC sLibVLC = null;
 
     /** A set of utility functions for the VLC application */
-    public static LibVLC getLibVlcInstance() throws LibVlcException {
-        LibVLC instance = LibVLC.getExistingInstance();
-        if (instance == null) {
+    public synchronized static LibVLC get() throws IllegalStateException {
+        if (sLibVLC == null) {
             Thread.setDefaultUncaughtExceptionHandler(new VLCCrashHandler());
 
-            instance = LibVLC.getInstance();
+            sLibVLC = new LibVLC();
             final Context context = VLCApplication.getAppContext();
             SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
             VLCInstance.updateLibVlcSettings(pref);
-            instance.init(context);
+            try {
+                sLibVLC.init(context);
+            } catch (LibVlcException e) {
+                throw new IllegalStateException("LibVLC initialisation failed: " + LibVlcUtil.getErrorMsg());
+            }
             LibVLC.setOnNativeCrashListener(new LibVLC.OnNativeCrashListener() {
                 @Override
                 public void onNativeCrash() {
@@ -55,22 +60,32 @@ public class VLCInstance {
                 }
             });
         }
-        return instance;
+        return sLibVLC;
     }
 
-    public static void updateLibVlcSettings(SharedPreferences pref) {
-        LibVLC instance = LibVLC.getExistingInstance();
-        if (instance == null)
+    public static synchronized void restart(Context context) throws IllegalStateException {
+        if (sLibVLC != null) {
+            try {
+                sLibVLC.destroy();
+                sLibVLC.init(context);
+            } catch (LibVlcException lve) {
+                throw new IllegalStateException("LibVLC initialisation failed: " + LibVlcUtil.getErrorMsg());
+            }
+        }
+    }
+
+    public static synchronized void updateLibVlcSettings(SharedPreferences pref) {
+        if (sLibVLC == null)
             return;
 
-        instance.setSubtitlesEncoding(pref.getString("subtitle_text_encoding", ""));
-        instance.setTimeStretching(pref.getBoolean("enable_time_stretching_audio", false));
-        instance.setFrameSkip(pref.getBoolean("enable_frame_skip", false));
-        instance.setChroma(pref.getString("chroma_format", ""));
-        instance.setVerboseMode(pref.getBoolean("enable_verbose_mode", true));
+        sLibVLC.setSubtitlesEncoding(pref.getString("subtitle_text_encoding", ""));
+        sLibVLC.setTimeStretching(pref.getBoolean("enable_time_stretching_audio", false));
+        sLibVLC.setFrameSkip(pref.getBoolean("enable_frame_skip", false));
+        sLibVLC.setChroma(pref.getString("chroma_format", ""));
+        sLibVLC.setVerboseMode(pref.getBoolean("enable_verbose_mode", true));
 
         if (pref.getBoolean("equalizer_enabled", false))
-            instance.setEqualizer(Preferences.getFloatArray(pref, "equalizer_values"));
+            sLibVLC.setEqualizer(Preferences.getFloatArray(pref, "equalizer_values"));
 
         int aout;
         try {
@@ -112,13 +127,11 @@ public class VLCInstance {
             networkCaching = 60000;
         else if(networkCaching < 0)
             networkCaching = 0;
-        instance.setAout(aout);
-        instance.setVout(vout);
-        instance.setDeblocking(deblocking);
-        instance.setNetworkCaching(networkCaching);
-        instance.setHardwareAcceleration(hardwareAcceleration);
-        instance.setDevHardwareDecoder(devHardwareDecoder);
+        sLibVLC.setAout(aout);
+        sLibVLC.setVout(vout);
+        sLibVLC.setDeblocking(deblocking);
+        sLibVLC.setNetworkCaching(networkCaching);
+        sLibVLC.setHardwareAcceleration(hardwareAcceleration);
+        sLibVLC.setDevHardwareDecoder(devHardwareDecoder);
     }
-
-
 }
diff --git a/vlc-android/tv/src/org/videolan/vlc/gui/tv/MainTvActivity.java b/vlc-android/tv/src/org/videolan/vlc/gui/tv/MainTvActivity.java
index b87853e..ae91177 100644
--- a/vlc-android/tv/src/org/videolan/vlc/gui/tv/MainTvActivity.java
+++ b/vlc-android/tv/src/org/videolan/vlc/gui/tv/MainTvActivity.java
@@ -24,14 +24,11 @@ import java.util.HashMap;
 import java.util.concurrent.BrokenBarrierException;
 import java.util.concurrent.CyclicBarrier;
 
-import org.videolan.libvlc.LibVLC;
-import org.videolan.libvlc.LibVlcException;
 import org.videolan.vlc.MediaDatabase;
 import org.videolan.vlc.MediaLibrary;
 import org.videolan.vlc.MediaWrapper;
 import org.videolan.vlc.R;
 import org.videolan.vlc.Thumbnailer;
-import org.videolan.vlc.gui.CompatErrorActivity;
 import org.videolan.vlc.gui.PreferencesActivity;
 import org.videolan.vlc.gui.tv.audioplayer.AudioPlayerActivity;
 import org.videolan.vlc.gui.tv.browser.MusicFragment;
@@ -107,21 +104,12 @@ public class MainTvActivity extends Activity implements IVideoBrowser, OnItemVie
         /*
          * skip browser and show directly Audio Player if a song is playing
          */
-        try {
-            if (VLCInstance.getLibVlcInstance() != null){
-                if (LibVLC.getExistingInstance().isPlaying()){
-                    startActivity(new Intent(this, AudioPlayerActivity.class));
-                    finish();
-                    return;
-                }
-            }
-        } catch (LibVlcException e) {
-            Intent i = new Intent(this, CompatErrorActivity.class);
-            startActivity(i);
+        if (VLCInstance.get().isPlaying()){
+            startActivity(new Intent(this, AudioPlayerActivity.class));
             finish();
-            super.onCreate(savedInstanceState);
             return;
         }
+
         mContext = this;
         setContentView(R.layout.tv_main_fragment);
 
-- 
2.1.3




More information about the Android mailing list