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

Thomas Guillem thomas at gllm.fr
Mon Mar 23 11:33:58 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. It's
not a compatible CPU error, 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/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   | 21 +++----
 .../videolan/vlc/gui/DirectoryViewFragment.java    |  5 +-
 .../src/org/videolan/vlc/gui/MainActivity.java     | 35 ++---------
 .../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         | 41 +++++++------
 .../src/org/videolan/vlc/util/VLCInstance.java     | 69 ++++++++++++++--------
 .../org/videolan/vlc/gui/tv/MainTvActivity.java    | 24 +++-----
 21 files changed, 136 insertions(+), 196 deletions(-)

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/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..090ef6f 100644
--- a/vlc-android/src/org/videolan/vlc/audio/AudioService.java
+++ b/vlc-android/src/org/videolan/vlc/audio/AudioService.java
@@ -158,12 +158,14 @@ public class AudioService extends Service {
     public void onCreate() {
         super.onCreate();
 
-        // Get libVLC instance
-        try {
-            mLibVLC = VLCInstance.getLibVlcInstance();
-        } catch (LibVlcException e) {
-            e.printStackTrace();
+        if (!VLCInstance.testCompatibleCPU(this)) {
+            stopSelf();
+            return;
         }
+
+        // Get libVLC instance
+        mLibVLC = VLCInstance.get();
+
         mMediaListPlayer = MediaWrapperListPlayer.getInstance(mLibVLC);
 
         mCallback = new HashMap<IAudioServiceCallback, Integer>();
@@ -320,12 +322,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 +334,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/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..0c58a02 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,14 @@ public class MainActivity extends ActionBarActivity implements OnItemClickListen
 
     @Override
     protected void onCreate(Bundle 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);
+        super.onCreate(savedInstanceState);
+
+        if (!VLCInstance.testCompatibleCPU(this)) {
             finish();
-            super.onCreate(savedInstanceState);
             return;
         }
+        /* Enable the indeterminate progress feature */
+        supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
 
         mContext = this;
         /* Get the current version from package */
@@ -165,28 +156,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..cb1701e 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,14 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
+        if (!VLCInstance.testCompatibleCPU(this)) {
+            finish();
+            return;
+        }
+
+        mLibVLC = VLCInstance.get();
+
         if (LibVlcUtil.isJellyBeanMR1OrLater()) {
             // Get the media router service (Miracast)
             mMediaRouter = (MediaRouter) getSystemService(Context.MEDIA_ROUTER_SERVICE);
@@ -405,12 +413,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 +567,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 +1852,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 +2585,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 +2778,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 +2832,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..547580b 100644
--- a/vlc-android/src/org/videolan/vlc/util/VLCInstance.java
+++ b/vlc-android/src/org/videolan/vlc/util/VLCInstance.java
@@ -22,8 +22,10 @@ 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.CompatErrorActivity;
 import org.videolan.vlc.gui.NativeCrashActivity;
 
 import android.content.Context;
@@ -33,18 +35,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 +61,41 @@ 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 boolean testCompatibleCPU(Context context) {
+        if (sLibVLC == null && !LibVlcUtil.hasCompatibleCPU(context)) {
+            final Intent i = new Intent(context, CompatErrorActivity.class);
+            context.startActivity(i);
+            return false;
+        } else
+            return true;
+    }
+
+    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 +137,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..ff7b272 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;
@@ -104,24 +101,21 @@ public class MainTvActivity extends Activity implements IVideoBrowser, OnItemVie
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
+        if (!VLCInstance.testCompatibleCPU(this)) {
+            finish();
+            return;
+        }
+
         /*
          * 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