Browse Source

Medialibrary: Add stub

merge-requests/213/head
Duncan McNamara 7 years ago
parent
commit
18f2fe8c16
  1. 11
      compile.sh
  2. 357
      medialibrary/src/org/videolan/medialibrary/Medialibrary.java
  3. 8
      medialibrary/src/org/videolan/medialibrary/ServiceLocator.java
  4. 426
      medialibrary/src/org/videolan/medialibrary/interfaces/AMedialibrary.java
  5. 6
      medialibrary/src/org/videolan/medialibrary/interfaces/media/AAlbum.java
  6. 2
      medialibrary/src/org/videolan/medialibrary/interfaces/media/AFolder.java
  7. 64
      medialibrary/src/org/videolan/medialibrary/interfaces/media/AMediaWrapper.java
  8. 6
      medialibrary/src/org/videolan/medialibrary/media/Album.java
  9. 17
      medialibrary/src/org/videolan/medialibrary/media/MediaWrapper.java
  10. 47
      medialibrary/src/org/videolan/medialibrary/stubs/StubAlbum.java
  11. 95
      medialibrary/src/org/videolan/medialibrary/stubs/StubArtist.java
  12. 357
      medialibrary/src/org/videolan/medialibrary/stubs/StubDataSource.java
  13. 74
      medialibrary/src/org/videolan/medialibrary/stubs/StubFolder.java
  14. 119
      medialibrary/src/org/videolan/medialibrary/stubs/StubGenre.java
  15. 12
      medialibrary/src/org/videolan/medialibrary/stubs/StubMediaWrapper.java
  16. 411
      medialibrary/src/org/videolan/medialibrary/stubs/StubMedialibrary.java
  17. 58
      medialibrary/src/org/videolan/medialibrary/stubs/StubPlaylist.java
  18. 4
      vlc-android/res/layout/activity_media_list_tv_item.xml
  19. 10
      vlc-android/src/org/videolan/vlc/StartActivity.kt
  20. 16
      vlc-android/src/org/videolan/vlc/gui/PlaylistActivity.kt
  21. 4
      vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt
  22. 32
      vlc-android/src/org/videolan/vlc/gui/audio/BaseAudioBrowser.kt
  23. 9
      vlc-android/src/org/videolan/vlc/gui/browser/MediaBrowserFragment.kt
  24. 6
      vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
  25. 12
      vlc-android/src/org/videolan/vlc/gui/tv/MediaHeaderAdapter.kt
  26. 2
      vlc-android/src/org/videolan/vlc/gui/tv/TvUtil.kt
  27. 5
      vlc-android/src/org/videolan/vlc/gui/tv/browser/BaseBrowserTvFragment.kt
  28. 2
      vlc-android/src/org/videolan/vlc/gui/tv/browser/FileBrowserTvFragment.kt
  29. 2
      vlc-android/src/org/videolan/vlc/gui/tv/browser/MediaBrowserTvFragment.kt
  30. 8
      vlc-android/src/org/videolan/vlc/gui/tv/details/MediaListAdapter.kt
  31. 1
      vlc-android/src/org/videolan/vlc/providers/BrowserProvider.kt
  32. 4
      vlc-android/src/org/videolan/vlc/viewmodels/tv/MainTvModel.kt

11
compile.sh

@ -66,6 +66,9 @@ while [ $# -gt 0 ]; do
run)
RUN=1
;;
test)
TEST=1
;;
--no-ml)
NO_ML=1
;;
@ -370,10 +373,14 @@ fi
#######
if [ "$RUN" = 1 ]; then
export PATH="${ANDROID_SDK}/platform-tools/:$PATH"
EXTRA=""
if [ "$TEST" = 1 ]; then
EXTRA="--ez 'extra_test_stubs' true"
fi
adb wait-for-device
if [ "$RELEASE" = 1 ]; then
adb shell am start -n org.videolan.vlc/org.videolan.vlc.StartActivity
adb shell am start -n org.videolan.vlc/org.videolan.vlc.StartActivity $EXTRA
else
adb shell am start -n org.videolan.vlc.debug/org.videolan.vlc.StartActivity
adb shell am start -n org.videolan.vlc.debug/org.videolan.vlc.StartActivity $EXTRA
fi
fi

357
medialibrary/src/org/videolan/medialibrary/Medialibrary.java

@ -1,4 +1,5 @@
/*****************************************************************************
/*
*****************************************************************************
* Medialibrary.java
*****************************************************************************
* Copyright © 2017-2018 VLC authors and VideoLAN
@ -423,308 +424,6 @@ public class Medialibrary extends AMedialibrary {
return mw;
}
@SuppressWarnings("unused")
public void onMediaAdded(AMediaWrapper[] mediaList) {
synchronized (mMediaCbs) {
for (MediaCb cb : mMediaCbs) cb.onMediaAdded();
}
}
@SuppressWarnings("unused")
public void onMediaUpdated(AMediaWrapper[] mediaList) {
synchronized (mMediaCbs) {
for (MediaCb cb : mMediaCbs) cb.onMediaModified();
}
}
@SuppressWarnings("unused")
public void onMediaDeleted() {
synchronized (mMediaCbs) {
for (MediaCb cb : mMediaCbs) cb.onMediaDeleted();
}
}
@SuppressWarnings("unused")
public void onArtistsAdded() {
synchronized (mArtistsCbs) {
for (ArtistsCb cb : mArtistsCbs) cb.onArtistsAdded();
}
}
@SuppressWarnings("unused")
public void onArtistsModified() {
synchronized (mArtistsCbs) {
for (ArtistsCb cb : mArtistsCbs) cb.onArtistsModified();
}
}
@SuppressWarnings("unused")
public void onArtistsDeleted() {
synchronized (mArtistsCbs) {
for (ArtistsCb cb : mArtistsCbs) cb.onArtistsDeleted();
}
}
@SuppressWarnings("unused")
public void onAlbumsAdded() {
synchronized (mAlbumsCbs) {
for (AlbumsCb cb : mAlbumsCbs) cb.onAlbumsAdded();
}
}
@SuppressWarnings("unused")
public void onAlbumsModified() {
synchronized (mAlbumsCbs) {
for (AlbumsCb cb : mAlbumsCbs) cb.onAlbumsModified();
}
}
@SuppressWarnings("unused")
public void onAlbumsDeleted() {
synchronized (mAlbumsCbs) {
for (AlbumsCb cb : mAlbumsCbs) cb.onAlbumsDeleted();
}
}
@SuppressWarnings("unused")
public void onGenresAdded() {
synchronized (mGenreCbs) {
for (GenresCb cb : mGenreCbs) cb.onGenresAdded();
}
}
@SuppressWarnings("unused")
public void onGenresModified() {
synchronized (mGenreCbs) {
for (GenresCb cb : mGenreCbs) cb.onGenresModified();
}
}
@SuppressWarnings("unused")
public void onGenresDeleted() {
synchronized (mGenreCbs) {
for (GenresCb cb : mGenreCbs) cb.onGenresDeleted();
}
}
@SuppressWarnings("unused")
public void onPlaylistsAdded() {
synchronized (mPlaylistCbs) {
for (PlaylistsCb cb : mPlaylistCbs) cb.onPlaylistsAdded();
}
}
@SuppressWarnings("unused")
public void onPlaylistsModified() {
synchronized (mPlaylistCbs) {
for (PlaylistsCb cb : mPlaylistCbs) cb.onPlaylistsModified();
}
}
@SuppressWarnings("unused")
public void onPlaylistsDeleted() {
synchronized (mPlaylistCbs) {
for (PlaylistsCb cb : mPlaylistCbs) cb.onPlaylistsDeleted();
}
}
public void onDiscoveryStarted(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onDiscoveryStarted(entryPoint);
}
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onDiscoveryStarted(entryPoint);
}
}
public void onDiscoveryProgress(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onDiscoveryProgress(entryPoint);
}
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onDiscoveryProgress(entryPoint);
}
}
public void onDiscoveryCompleted(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onDiscoveryCompleted(entryPoint);
}
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onDiscoveryCompleted(entryPoint);
}
}
public void onParsingStatsUpdated(int percent) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onParsingStatsUpdated(percent);
}
}
@SuppressWarnings("unused")
public void onBackgroundTasksIdleChanged(boolean isIdle) {
mIsWorking = !isIdle;
sRunning.postValue(mIsWorking);
LocalBroadcastManager.getInstance(sContext).sendBroadcast(new Intent(ACTION_IDLE).putExtra(STATE_IDLE, isIdle));
if (isIdle) {
synchronized (onMedialibraryReadyListeners) {
for (OnMedialibraryReadyListener listener : onMedialibraryReadyListeners) listener.onMedialibraryIdle();
}
}
}
@SuppressWarnings("unused")
public void onReloadStarted(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onReloadStarted(entryPoint);
}
}
@SuppressWarnings("unused")
public void onReloadCompleted(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onReloadCompleted(entryPoint);
}
}
@SuppressWarnings("unused")
public void onEntryPointBanned(String entryPoint, boolean success) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onEntryPointBanned(entryPoint, success);
}
}
@SuppressWarnings("unused")
public void onEntryPointUnbanned(String entryPoint, boolean success) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onEntryPointUnbanned(entryPoint, success);
}
}
@SuppressWarnings("unused")
void onEntryPointAdded(String entryPoint, boolean success) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onEntryPointAdded(entryPoint, success);
}
}
@SuppressWarnings("unused")
public void onEntryPointRemoved(String entryPoint, boolean success) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onEntryPointRemoved(entryPoint, success);
}
}
// public static LiveData<AMediaWrapper> lastThumb = new SingleEvent<>();
@SuppressWarnings({"unused", "unchecked"})
public void onMediaThumbnailReady(AMediaWrapper media, boolean success) {
if (success) ((MutableLiveData)lastThumb).postValue(media);
}
public void addMediaCb(MediaCb mediaUpdatedCb) {
if (!mIsInitiated) return;
synchronized (mMediaCbs) {
// if (mMediaCbs.isEmpty()) {
// nativeSetMediaAddedCbFlag(FLAG_MEDIA_ADDED_AUDIO|FLAG_MEDIA_ADDED_VIDEO);
// nativeSetMediaUpdatedCbFlag(FLAG_MEDIA_UPDATED_AUDIO|FLAG_MEDIA_UPDATED_VIDEO);
// }
mMediaCbs.add(mediaUpdatedCb);
}
}
public void removeMediaCb(MediaCb mediaUpdatedCb) {
if (!mIsInitiated) return;
synchronized (mMediaCbs) {
mMediaCbs.remove(mediaUpdatedCb);
// if (mMediaCbs.isEmpty()) {
// nativeSetMediaAddedCbFlag(0);
// nativeSetMediaUpdatedCbFlag(0);
// }
}
}
public void addArtistsCb(ArtistsCb artistsAddedCb) {
if (!mIsInitiated) return;
synchronized (mArtistsCbs) {
mArtistsCbs.add(artistsAddedCb);
}
}
public void removeArtistsCb(ArtistsCb artistsAddedCb) {
if (!mIsInitiated) return;
synchronized (mArtistsCbs) {
mArtistsCbs.remove(artistsAddedCb);
}
}
public void addAlbumsCb(AlbumsCb AlbumsAddedCb) {
if (!mIsInitiated) return;
synchronized (mAlbumsCbs) {
mAlbumsCbs.add(AlbumsAddedCb);
}
}
public void removeAlbumsCb(AlbumsCb AlbumsAddedCb) {
if (!mIsInitiated) return;
synchronized (mAlbumsCbs) {
mAlbumsCbs.remove(AlbumsAddedCb);
}
}
public void addGenreCb(GenresCb GenreCb) {
if (!mIsInitiated) return;
synchronized (mGenreCbs) {
this.mGenreCbs.add(GenreCb);
}
}
public void removeGenreCb(GenresCb GenreCb) {
if (!mIsInitiated) return;
synchronized (mGenreCbs) {
this.mGenreCbs.remove(GenreCb);
}
}
public void addPlaylistCb(PlaylistsCb playlistCb) {
if (!mIsInitiated) return;
synchronized (mPlaylistCbs) {
this.mPlaylistCbs.add(playlistCb);
}
}
public void removePlaylistCb(PlaylistsCb playlistCb) {
if (!mIsInitiated) return;
synchronized (mPlaylistCbs) {
this.mPlaylistCbs.remove(playlistCb);
}
}
public SearchAggregate search(String query) {
return mIsInitiated && !TextUtils.isEmpty(query) ? nativeSearch(query) : null;
}
@ -789,58 +488,6 @@ public class Medialibrary extends AMedialibrary {
return mIsInitiated && !TextUtils.isEmpty(query) ? nativeSearchPagedPlaylist(query, sort, desc, nbItems, offset) : null;
}
public void addDeviceDiscoveryCb(DevicesDiscoveryCb cb) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.contains(cb))
devicesDiscoveryCbList.add(cb);
}
}
public void removeDeviceDiscoveryCb(DevicesDiscoveryCb cb) {
synchronized (devicesDiscoveryCbList) {
devicesDiscoveryCbList.remove(cb);
}
}
public void addOnMedialibraryReadyListener(OnMedialibraryReadyListener cb) {
synchronized (onMedialibraryReadyListeners) {
if (!onMedialibraryReadyListeners.contains(cb))
onMedialibraryReadyListeners.add(cb);
}
}
public void removeOnMedialibraryReadyListener(OnMedialibraryReadyListener cb) {
synchronized (onMedialibraryReadyListeners) {
onMedialibraryReadyListeners.remove(cb);
}
}
public void addEntryPointsEventsCb(EntryPointsEventsCb cb) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.contains(cb))
entryPointsEventsCbList.add(cb);
}
}
public void removeEntryPointsEventsCb(EntryPointsEventsCb cb) {
synchronized (entryPointsEventsCbList) {
entryPointsEventsCbList.remove(cb);
}
}
public void addOnDeviceChangeListener(OnDeviceChangeListener listener) {
synchronized (onDeviceChangeListeners) {
if (!onDeviceChangeListeners.contains(listener))
onDeviceChangeListeners.add(listener);
}
}
public void removeOnDeviceChangeListener(OnDeviceChangeListener listener) {
synchronized (onDeviceChangeListeners) {
onDeviceChangeListeners.remove(listener);
}
}
// Native methods
private native int nativeInit(String dbPath, String thumbsPath);
private native void nativeStart();

8
medialibrary/src/org/videolan/medialibrary/ServiceLocator.java

@ -28,22 +28,18 @@ import org.videolan.medialibrary.stubs.StubPlaylist;
public class ServiceLocator {
private static ServiceLocator mServiceLocator;
private static LocatorMode mMode = LocatorMode.VLC_ANDROID;
public static void setLocatorMode(LocatorMode mode) {
ServiceLocator.mMode = mode;
}
enum LocatorMode {
public static String EXTRA_TEST_STUBS = "extra_test_stubs";
public enum LocatorMode {
VLC_ANDROID,
TESTS,
}
public static ServiceLocator getInstance() {
return mServiceLocator;
}
public static AMedialibrary getAMedialibrary() {
if (mMode == LocatorMode.VLC_ANDROID) {
return new Medialibrary();

426
medialibrary/src/org/videolan/medialibrary/interfaces/AMedialibrary.java

@ -2,18 +2,22 @@ package org.videolan.medialibrary.interfaces;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.videolan.medialibrary.ServiceLocator;
import org.videolan.medialibrary.SingleEvent;
import org.videolan.medialibrary.Tools;
import org.videolan.medialibrary.interfaces.media.AAlbum;
import org.videolan.medialibrary.interfaces.media.AArtist;
import org.videolan.medialibrary.interfaces.media.AFolder;
@ -101,7 +105,6 @@ abstract public class AMedialibrary {
@NonNull
public static AMedialibrary getInstance() {
System.out.println("This is the real medialibrary");
return instance;
}
@ -197,6 +200,382 @@ abstract public class AMedialibrary {
void onDeviceChange();
}
// If media is not in ML, find it with its path
public AMediaWrapper findMedia(AMediaWrapper mw) {
if (mIsInitiated && mw != null && mw.getId() == 0L) {
final Uri uri = mw.getUri();
final AMediaWrapper libraryMedia = getMedia(uri);
if (libraryMedia != null) {
libraryMedia.addFlags(mw.getFlags());
return libraryMedia;
}
if (TextUtils.equals("file", uri.getScheme()) &&
uri.getPath() != null && uri.getPath().startsWith("/sdcard")) {
final AMediaWrapper alternateMedia = getMedia(Tools.convertLocalUri(uri));
if (alternateMedia != null) {
alternateMedia.addFlags(mw.getFlags());
return alternateMedia;
}
}
}
return mw;
}
@SuppressWarnings("unused")
public void onMediaAdded(AMediaWrapper[] mediaList) {
synchronized (mMediaCbs) {
for (MediaCb cb : mMediaCbs) cb.onMediaAdded();
}
}
@SuppressWarnings("unused")
public void onMediaUpdated(AMediaWrapper[] mediaList) {
synchronized (mMediaCbs) {
for (MediaCb cb : mMediaCbs) cb.onMediaModified();
}
}
@SuppressWarnings("unused")
public void onMediaDeleted() {
synchronized (mMediaCbs) {
for (MediaCb cb : mMediaCbs) cb.onMediaDeleted();
}
}
@SuppressWarnings("unused")
public void onArtistsAdded() {
synchronized (mArtistsCbs) {
for (ArtistsCb cb : mArtistsCbs) cb.onArtistsAdded();
}
}
@SuppressWarnings("unused")
public void onArtistsModified() {
synchronized (mArtistsCbs) {
for (ArtistsCb cb : mArtistsCbs) cb.onArtistsModified();
}
}
@SuppressWarnings("unused")
public void onArtistsDeleted() {
synchronized (mArtistsCbs) {
for (ArtistsCb cb : mArtistsCbs) cb.onArtistsDeleted();
}
}
@SuppressWarnings("unused")
public void onAlbumsAdded() {
synchronized (mAlbumsCbs) {
for (AlbumsCb cb : mAlbumsCbs) cb.onAlbumsAdded();
}
}
@SuppressWarnings("unused")
public void onAlbumsModified() {
synchronized (mAlbumsCbs) {
for (AlbumsCb cb : mAlbumsCbs) cb.onAlbumsModified();
}
}
@SuppressWarnings("unused")
public void onAlbumsDeleted() {
synchronized (mAlbumsCbs) {
for (AlbumsCb cb : mAlbumsCbs) cb.onAlbumsDeleted();
}
}
@SuppressWarnings("unused")
public void onGenresAdded() {
synchronized (mGenreCbs) {
for (GenresCb cb : mGenreCbs) cb.onGenresAdded();
}
}
@SuppressWarnings("unused")
public void onGenresModified() {
synchronized (mGenreCbs) {
for (GenresCb cb : mGenreCbs) cb.onGenresModified();
}
}
@SuppressWarnings("unused")
public void onGenresDeleted() {
synchronized (mGenreCbs) {
for (GenresCb cb : mGenreCbs) cb.onGenresDeleted();
}
}
@SuppressWarnings("unused")
public void onPlaylistsAdded() {
synchronized (mPlaylistCbs) {
for (PlaylistsCb cb : mPlaylistCbs) cb.onPlaylistsAdded();
}
}
@SuppressWarnings("unused")
public void onPlaylistsModified() {
synchronized (mPlaylistCbs) {
for (PlaylistsCb cb : mPlaylistCbs) cb.onPlaylistsModified();
}
}
@SuppressWarnings("unused")
public void onPlaylistsDeleted() {
synchronized (mPlaylistCbs) {
for (PlaylistsCb cb : mPlaylistCbs) cb.onPlaylistsDeleted();
}
}
public void onDiscoveryStarted(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onDiscoveryStarted(entryPoint);
}
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onDiscoveryStarted(entryPoint);
}
}
public void onDiscoveryProgress(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onDiscoveryProgress(entryPoint);
}
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onDiscoveryProgress(entryPoint);
}
}
public void onDiscoveryCompleted(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onDiscoveryCompleted(entryPoint);
}
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onDiscoveryCompleted(entryPoint);
}
}
public void onParsingStatsUpdated(int percent) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onParsingStatsUpdated(percent);
}
}
@SuppressWarnings("unused")
public void onBackgroundTasksIdleChanged(boolean isIdle) {
mIsWorking = !isIdle;
sRunning.postValue(mIsWorking);
LocalBroadcastManager.getInstance(sContext).sendBroadcast(new Intent(ACTION_IDLE).putExtra(STATE_IDLE, isIdle));
if (isIdle) {
synchronized (onMedialibraryReadyListeners) {
for (OnMedialibraryReadyListener listener : onMedialibraryReadyListeners) listener.onMedialibraryIdle();
}
}
}
@SuppressWarnings("unused")
public void onReloadStarted(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onReloadStarted(entryPoint);
}
}
@SuppressWarnings("unused")
public void onReloadCompleted(String entryPoint) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.isEmpty())
for (DevicesDiscoveryCb cb : devicesDiscoveryCbList)
cb.onReloadCompleted(entryPoint);
}
}
@SuppressWarnings("unused")
public void onEntryPointBanned(String entryPoint, boolean success) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onEntryPointBanned(entryPoint, success);
}
}
@SuppressWarnings("unused")
public void onEntryPointUnbanned(String entryPoint, boolean success) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onEntryPointUnbanned(entryPoint, success);
}
}
@SuppressWarnings("unused")
void onEntryPointAdded(String entryPoint, boolean success) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onEntryPointAdded(entryPoint, success);
}
}
@SuppressWarnings("unused")
public void onEntryPointRemoved(String entryPoint, boolean success) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.isEmpty())
for (EntryPointsEventsCb cb : entryPointsEventsCbList)
cb.onEntryPointRemoved(entryPoint, success);
}
}
// public static LiveData<AMediaWrapper> lastThumb = new SingleEvent<>();
@SuppressWarnings({"unused", "unchecked"})
public void onMediaThumbnailReady(AMediaWrapper media, boolean success) {
if (success) ((MutableLiveData)lastThumb).postValue(media);
}
public void addMediaCb(MediaCb mediaUpdatedCb) {
if (!mIsInitiated) return;
synchronized (mMediaCbs) {
// if (mMediaCbs.isEmpty()) {
// nativeSetMediaAddedCbFlag(FLAG_MEDIA_ADDED_AUDIO|FLAG_MEDIA_ADDED_VIDEO);
// nativeSetMediaUpdatedCbFlag(FLAG_MEDIA_UPDATED_AUDIO|FLAG_MEDIA_UPDATED_VIDEO);
// }
mMediaCbs.add(mediaUpdatedCb);
}
}
public void removeMediaCb(MediaCb mediaUpdatedCb) {
if (!mIsInitiated) return;
synchronized (mMediaCbs) {
mMediaCbs.remove(mediaUpdatedCb);
// if (mMediaCbs.isEmpty()) {
// nativeSetMediaAddedCbFlag(0);
// nativeSetMediaUpdatedCbFlag(0);
// }
}
}
public void addArtistsCb(ArtistsCb artistsAddedCb) {
if (!mIsInitiated) return;
synchronized (mArtistsCbs) {
mArtistsCbs.add(artistsAddedCb);
}
}
public void removeArtistsCb(ArtistsCb artistsAddedCb) {
if (!mIsInitiated) return;
synchronized (mArtistsCbs) {
mArtistsCbs.remove(artistsAddedCb);
}
}
public void addAlbumsCb(AlbumsCb AlbumsAddedCb) {
if (!mIsInitiated) return;
synchronized (mAlbumsCbs) {
mAlbumsCbs.add(AlbumsAddedCb);
}
}
public void removeAlbumsCb(AlbumsCb AlbumsAddedCb) {
if (!mIsInitiated) return;
synchronized (mAlbumsCbs) {
mAlbumsCbs.remove(AlbumsAddedCb);
}
}
public void addGenreCb(GenresCb GenreCb) {
if (!mIsInitiated) return;
synchronized (mGenreCbs) {
this.mGenreCbs.add(GenreCb);
}
}
public void removeGenreCb(GenresCb GenreCb) {
if (!mIsInitiated) return;
synchronized (mGenreCbs) {
this.mGenreCbs.remove(GenreCb);
}
}
public void addPlaylistCb(PlaylistsCb playlistCb) {
if (!mIsInitiated) return;
synchronized (mPlaylistCbs) {
this.mPlaylistCbs.add(playlistCb);
}
}
public void removePlaylistCb(PlaylistsCb playlistCb) {
if (!mIsInitiated) return;
synchronized (mPlaylistCbs) {
this.mPlaylistCbs.remove(playlistCb);
}
}
public void addDeviceDiscoveryCb(DevicesDiscoveryCb cb) {
synchronized (devicesDiscoveryCbList) {
if (!devicesDiscoveryCbList.contains(cb))
devicesDiscoveryCbList.add(cb);
}
}
public void removeDeviceDiscoveryCb(DevicesDiscoveryCb cb) {
synchronized (devicesDiscoveryCbList) {
devicesDiscoveryCbList.remove(cb);
}
}
public void addOnMedialibraryReadyListener(OnMedialibraryReadyListener cb) {
synchronized (onMedialibraryReadyListeners) {
if (!onMedialibraryReadyListeners.contains(cb))
onMedialibraryReadyListeners.add(cb);
}
}
public void removeOnMedialibraryReadyListener(OnMedialibraryReadyListener cb) {
synchronized (onMedialibraryReadyListeners) {
onMedialibraryReadyListeners.remove(cb);
}
}
public void addEntryPointsEventsCb(EntryPointsEventsCb cb) {
synchronized (entryPointsEventsCbList) {
if (!entryPointsEventsCbList.contains(cb))
entryPointsEventsCbList.add(cb);
}
}
public void removeEntryPointsEventsCb(EntryPointsEventsCb cb) {
synchronized (entryPointsEventsCbList) {
entryPointsEventsCbList.remove(cb);
}
}
public void addOnDeviceChangeListener(OnDeviceChangeListener listener) {
synchronized (onDeviceChangeListeners) {
if (!onDeviceChangeListeners.contains(listener))
onDeviceChangeListeners.add(listener);
}
}
public void removeOnDeviceChangeListener(OnDeviceChangeListener listener) {
synchronized (onDeviceChangeListeners) {
onDeviceChangeListeners.remove(listener);
}
}
abstract public int init(Context context);
abstract public void start();
abstract public void banFolder(@NonNull String path);
@ -262,43 +641,6 @@ abstract public class AMedialibrary {
abstract public int getFoldersCount(int type);
abstract public void requestThumbnail(long id);
abstract public boolean increasePlayCount(long mediaId);
abstract public AMediaWrapper findMedia(AMediaWrapper mw);
abstract public void onMediaAdded(AMediaWrapper[] mediaList);
abstract public void onMediaUpdated(AMediaWrapper[] mediaList);
abstract public void onMediaDeleted();
abstract public void onArtistsAdded();
abstract public void onArtistsModified();
abstract public void onArtistsDeleted();
abstract public void onAlbumsAdded();
abstract public void onAlbumsModified();
abstract public void onAlbumsDeleted();
abstract public void onGenresAdded();
abstract public void onGenresModified();
abstract public void onGenresDeleted();
abstract public void onPlaylistsAdded();
abstract public void onPlaylistsModified();
abstract public void onPlaylistsDeleted();
abstract public void onDiscoveryStarted(String entryPoint);
abstract public void onDiscoveryProgress(String entryPoint);
abstract public void onDiscoveryCompleted(String entryPoint);
abstract public void onParsingStatsUpdated(int percent);
abstract public void onBackgroundTasksIdleChanged(boolean isIdle);
abstract public void onReloadStarted(String entryPoint);
abstract public void onReloadCompleted(String entryPoint);
abstract public void onEntryPointBanned(String entryPoint, boolean success);
abstract public void onEntryPointUnbanned(String entryPoint, boolean success);
abstract public void onEntryPointRemoved(String entryPoint, boolean success);
abstract public void onMediaThumbnailReady(AMediaWrapper Amedia, boolean success);
abstract public void addMediaCb(MediaCb mediaUpdated);
abstract public void removeMediaCb(MediaCb mediaUpdatedCb);
abstract public void addArtistsCb(ArtistsCb artictAddedCb);
abstract public void removeArtistsCb(ArtistsCb artistCb);
abstract public void addAlbumsCb(AlbumsCb albumsAddedCb);
abstract public void removeAlbumsCb(AlbumsCb albumsAddedCb);
abstract public void addGenreCb(GenresCb genresAddedCb);
abstract public void removeGenreCb(GenresCb genresAddedCb);
abstract public void addPlaylistCb(PlaylistsCb playlistsAddedCb);
abstract public void removePlaylistCb(PlaylistsCb playlistsAddedCb);
abstract public SearchAggregate search(String query);
abstract public AMediaWrapper[] searchMedia(String query);
abstract public AMediaWrapper[] searchMedia(String query, int sort, boolean desc, int nbItems, int offset);
@ -315,12 +657,4 @@ abstract public class AMedialibrary {
abstract public AGenre[] searchGenre(String query, int sort, boolean desc, int nbItems, int offset);
abstract public APlaylist[] searchPlaylist(String query);
abstract public APlaylist[] searchPlaylist(String query, int sort, boolean desc, int nbItems, int offset);
abstract public void addDeviceDiscoveryCb(DevicesDiscoveryCb cb);
abstract public void removeDeviceDiscoveryCb(DevicesDiscoveryCb cb);
abstract public void addOnMedialibraryReadyListener(OnMedialibraryReadyListener cb);
abstract public void removeOnMedialibraryReadyListener(OnMedialibraryReadyListener cb);
abstract public void addEntryPointsEventsCb(EntryPointsEventsCb cb);
abstract public void removeEntryPointsEventsCb(EntryPointsEventsCb cb);
abstract public void addOnDeviceChangeListener(OnDeviceChangeListener cb);
abstract public void removeOnDeviceChangeListener(OnDeviceChangeListener cb);
}

6
medialibrary/src/org/videolan/medialibrary/interfaces/media/AAlbum.java

@ -53,6 +53,7 @@ public abstract class AAlbum extends MediaLibraryItem {
abstract public AMediaWrapper[] getPagedTracks(int sort, boolean desc, int nbItems, int offset);
abstract public AMediaWrapper[] searchTracks(String query, int sort, boolean desc, int nbItems, int offset);
abstract public int searchTracksCount(String query);
abstract public AArtist getAlbumArtist();
@Override
public long getId() {
@ -73,11 +74,6 @@ public abstract class AAlbum extends MediaLibraryItem {
return artworkMrl;
}
public AArtist getAlbumArtist() {
//TODO
return null;
}
@Override
public int getTracksCount() {
return mTracksCount;

2
medialibrary/src/org/videolan/medialibrary/interfaces/media/AFolder.java

@ -13,7 +13,7 @@ public abstract class AFolder extends MediaLibraryItem {
public static int TYPE_FOLDER_EXTERNAL = 3;
public static int TYPE_FOLDER_STREAM = 4;
private String mMrl;
public String mMrl;
public AFolder(long id, String name, String mrl) {
super(id, name);

64
medialibrary/src/org/videolan/medialibrary/interfaces/media/AMediaWrapper.java

@ -62,45 +62,45 @@ public abstract class AMediaWrapper extends MediaLibraryItem implements Parcelab
public final static int META_APPLICATION_SPECIFIC = 250;
// threshold lentgh between song and podcast ep, set to 15 minutes
private static final long PODCAST_THRESHOLD = 900000L;
private static final long PODCAST_ABSOLUTE = 3600000L;
private String mDisplayTitle;
private String mArtist;
private String mGenre;
private String mCopyright;
private String mAlbum;
private int mTrackNumber;
private int mDiscNumber;
private String mAlbumArtist;
private String mRating;
private String mDate;
private String mSettings;
private String mNowPlaying;
private String mPublisher;
private String mEncodedBy;
private String mTrackID;
protected static final long PODCAST_THRESHOLD = 900000L;
protected static final long PODCAST_ABSOLUTE = 3600000L;
protected String mDisplayTitle;
protected String mArtist;
protected String mGenre;
protected String mCopyright;
protected String mAlbum;
protected int mTrackNumber;
protected int mDiscNumber;
protected String mAlbumArtist;
protected String mRating;
protected String mDate;
protected String mSettings;
protected String mNowPlaying;
protected String mPublisher;
protected String mEncodedBy;
protected String mTrackID;
protected String mArtworkURL;
private boolean mThumbnailGenerated;
protected boolean mThumbnailGenerated;
private final Uri mUri;
private String mFilename;
protected final Uri mUri;
protected String mFilename;
protected long mTime = 0;
private long mDisplayTime = 0;
protected long mDisplayTime = 0;
/* -1 is a valid track (Disabled) */
private int mAudioTrack = -2;
private int mSpuTrack = -2;
private long mLength = 0;
protected int mAudioTrack = -2;
protected int mSpuTrack = -2;
protected long mLength = 0;
protected int mType;
private int mWidth = 0;
private int mHeight = 0;
private Bitmap mPicture;
private boolean mIsPictureParsed;
protected int mWidth = 0;
protected int mHeight = 0;
protected Bitmap mPicture;
protected boolean mIsPictureParsed;
protected int mFlags = 0;
private long mLastModified = 0L;
private Media.Slave[] mSlaves = null;
protected long mLastModified = 0L;
protected Media.Slave[] mSlaves = null;
private long mSeen = 0L;
protected long mSeen = 0L;
public abstract void rename(String name);
public abstract long getMetaLong(int metaDataType);

6
medialibrary/src/org/videolan/medialibrary/media/Album.java

@ -4,6 +4,7 @@ import android.os.Parcel;
import org.videolan.medialibrary.interfaces.AMedialibrary;
import org.videolan.medialibrary.interfaces.media.AAlbum;
import org.videolan.medialibrary.interfaces.media.AArtist;
import org.videolan.medialibrary.interfaces.media.AMediaWrapper;
@SuppressWarnings("JniMissingFunction")
@ -43,6 +44,11 @@ public class Album extends AAlbum {
return ml.isInitiated() ? nativeGetSearchCount(ml, mId, query) : 0;
}
public AArtist getAlbumArtist() {
//TODO
return null;
}
private native AMediaWrapper[] nativeGetTracks(AMedialibrary ml, long mId, int sort, boolean desc);
private native AMediaWrapper[] nativeGetPagedTracks(AMedialibrary ml, long mId, int sort, boolean desc, int nbItems, int offset);
private native AMediaWrapper[] nativeSearch(AMedialibrary ml, long mId, String query, int sort, boolean desc, int nbItems, int offset);

17
medialibrary/src/org/videolan/medialibrary/media/MediaWrapper.java

@ -25,6 +25,7 @@ package org.videolan.medialibrary.media;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Parcel;
import android.text.TextUtils;
import androidx.annotation.Nullable;
@ -68,7 +69,7 @@ public class MediaWrapper extends AMediaWrapper {
public void removeFromHistory() {
if (mId != 0L) {
final Medialibrary ml = Medialibrary.getInstance();
final AMedialibrary ml = AMedialibrary.getInstance();
if (ml.isInitiated()) nativeRemoveFromHistory(ml, mId);
}
}
@ -248,11 +249,11 @@ public class MediaWrapper extends AMediaWrapper {
if (mId != 0 && ml.isInitiated()) nativeSetMediaThumbnail(ml, mId, Tools.encodeVLCMrl(mrl));
}
private native long nativeGetMediaLongMetadata(Medialibrary ml, long id, int metaDataType);
private native String nativeGetMediaStringMetadata(Medialibrary ml, long id, int metaDataType);
private native void nativeSetMediaStringMetadata(Medialibrary ml, long id, int metaDataType, String metadataValue);
private native void nativeSetMediaLongMetadata(Medialibrary ml, long id, int metaDataType, long metadataValue);
private native void nativeSetMediaThumbnail(Medialibrary ml, long id, String mrl);
private native void nativeSetMediaTitle(Medialibrary ml, long id, String name);
private native void nativeRemoveFromHistory(Medialibrary ml, long id);
private native long nativeGetMediaLongMetadata(AMedialibrary ml, long id, int metaDataType);
private native String nativeGetMediaStringMetadata(AMedialibrary ml, long id, int metaDataType);
private native void nativeSetMediaStringMetadata(AMedialibrary ml, long id, int metaDataType, String metadataValue);
private native void nativeSetMediaLongMetadata(AMedialibrary ml, long id, int metaDataType, long metadataValue);
private native void nativeSetMediaThumbnail(AMedialibrary ml, long id, String mrl);
private native void nativeSetMediaTitle(AMedialibrary ml, long id, String name);
private native void nativeRemoveFromHistory(AMedialibrary ml, long id);
}

47
medialibrary/src/org/videolan/medialibrary/stubs/StubAlbum.java

@ -2,11 +2,17 @@ package org.videolan.medialibrary.stubs;
import android.os.Parcel;
import org.videolan.medialibrary.interfaces.AMedialibrary;
import org.videolan.medialibrary.interfaces.media.AAlbum;
import org.videolan.medialibrary.interfaces.media.AArtist;
import org.videolan.medialibrary.interfaces.media.AMediaWrapper;
import java.util.ArrayList;
public class StubAlbum extends AAlbum {
private StubDataSource dt = StubDataSource.getInstance();
public StubAlbum(long id, String title, int releaseYear, String artworkMrl, String albumArtist, long albumArtistId, int nbTracks, int duration) {
super(id, title, releaseYear, artworkMrl, albumArtist, albumArtistId, nbTracks, duration);
}
@ -16,22 +22,53 @@ public class StubAlbum extends AAlbum {
}
public int getRealTracksCount() {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getAlbum().equals(this.getTitle())) count++;
}
return count;
}
public AArtist getAlbumArtist() {
AMedialibrary ml = AMedialibrary.getInstance();
return ml.getArtist(this.albumArtistId);
}
private ArrayList<AMediaWrapper> getAlbumTracks() {
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getAlbum().equals(this.getTitle())) results.add(media);
}
return results;
}
public AMediaWrapper[] getTracks(int sort, boolean desc) {
return null;
return dt.sortMedia(getAlbumTracks(), sort, desc);
}
public AMediaWrapper[] getPagedTracks(int sort, boolean desc, int nbItems, int offset) {
return null;
return dt.sortMedia(dt.secureSublist(getAlbumTracks(), offset, offset + nbItems), sort, desc);
}
public AMediaWrapper[] searchTracks(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getAlbum().equals(this.getTitle()) ||
media.getTitle().contains(query)) {
results.add(media);
}
}
return dt.sortMedia(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public int searchTracksCount(String query) {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getAlbum().equals(this.getTitle()) ||
media.getTitle().contains(query)) {
count++;
}
}
return count;
}
}

95
medialibrary/src/org/videolan/medialibrary/stubs/StubArtist.java

@ -6,8 +6,13 @@ import org.videolan.medialibrary.interfaces.media.AAlbum;
import org.videolan.medialibrary.interfaces.media.AArtist;
import org.videolan.medialibrary.interfaces.media.AMediaWrapper;
import java.util.ArrayList;
import java.util.Arrays;
public class StubArtist extends AArtist {
private StubDataSource dt = StubDataSource.getInstance();
public StubArtist(long id, String name, String shortBio, String artworkMrl, String musicBrainzId) {
super(id, name, shortBio, artworkMrl, musicBrainzId);
}
@ -17,42 +22,104 @@ public class StubArtist extends AArtist {
}
public AAlbum[] getAlbums(int sort, boolean desc) {
return null;
ArrayList<AAlbum> results = new ArrayList<>();
for (AAlbum album : dt.mAlbums) {
if (album.getDescription().equals(this.getTitle())) results.add(album);
}
return dt.sortAlbum(results, sort, desc);
}
public int getAlbumsCount() {
int count = 0;
for (AAlbum album : dt.mAlbums) {
if (album.getDescription().equals(this.getTitle())) count++;
}
return count;
}
public AAlbum[] getPagedAlbums(int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AAlbum> results = new ArrayList<>(Arrays.asList(getAlbums(sort, desc)));
return results.toArray(new AAlbum[0]);
}
public AAlbum[] searchAlbums(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AAlbum> results = new ArrayList<>();
for (AAlbum album : dt.mAlbums) {
if (album.getDescription().equals(this.getTitle()) ||
album.getTitle().equals(query)) {
results.add(album);
}
}
return dt.sortAlbum(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public int searchAlbumsCount(String query) {
return 0;
}
public AMediaWrapper[] searchTracks(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
int count = 0;
for (AAlbum album : dt.mAlbums) {
if (album.getDescription().equals(this.getTitle()) ||
album.getTitle().equals(query)) {
count++;
}
}
return count;
}
//TODO checkout if query is on artist or albumArtist or both
public int searchTracksCount(String query) {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getArtist().equals(this.getTitle()) ||
media.getAlbumArtist().equals(this.getTitle()) ||
media.getTitle().contains(query)) {
count++;
}
}
return count;
}
public int getAlbumsCount() {
return 0;
//TODO checkout if query is on artist or albumArtist or both (same as above)
public AMediaWrapper[] searchTracks(String query, int sort, boolean desc, int nbItems, int offset) {
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getArtist().equals(this.getTitle()) ||
media.getAlbumArtist().equals(this.getTitle()) ||
media.getTitle().contains(query)) {
results.add(media);
}
}
return dt.sortMedia(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public AMediaWrapper[] getTracks(int sort, boolean desc) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getArtist().equals(this.getTitle()) ||
media.getAlbumArtist().equals(this.getTitle())) {
results.add(media);
}
}
return dt.sortMedia(results, sort, desc);
}
public AMediaWrapper[] getPagedTracks(int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getArtist().equals(this.getTitle()) ||
media.getAlbumArtist().equals(this.getTitle())) {
results.add(media);
}
}
return dt.sortMedia(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public int getTracksCount() {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getArtist().equals(this.getTitle()) ||
media.getAlbumArtist().equals(this.getTitle())) {
count++;
}
}
return count;
}
}

357
medialibrary/src/org/videolan/medialibrary/stubs/StubDataSource.java

@ -0,0 +1,357 @@
package org.videolan.medialibrary.stubs;
import android.os.Handler;
import android.text.TextUtils;
import org.videolan.medialibrary.ServiceLocator;
import org.videolan.medialibrary.interfaces.media.AAlbum;
import org.videolan.medialibrary.interfaces.media.AArtist;
import org.videolan.medialibrary.interfaces.media.AFolder;
import org.videolan.medialibrary.interfaces.media.AGenre;
import org.videolan.medialibrary.interfaces.media.AMediaWrapper;
import org.videolan.medialibrary.interfaces.media.APlaylist;
import org.videolan.medialibrary.media.MediaLibraryItem;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static org.videolan.medialibrary.interfaces.AMedialibrary.SORT_ALBUM;
import static org.videolan.medialibrary.interfaces.AMedialibrary.SORT_ALPHA;
import static org.videolan.medialibrary.interfaces.AMedialibrary.SORT_ARTIST;
import static org.videolan.medialibrary.interfaces.AMedialibrary.SORT_DEFAULT;
import static org.videolan.medialibrary.interfaces.AMedialibrary.SORT_DURATION;
import static org.videolan.medialibrary.interfaces.AMedialibrary.SORT_FILENAME;
import static org.videolan.medialibrary.interfaces.AMedialibrary.SORT_INSERTIONDATE;
import static org.videolan.medialibrary.interfaces.AMedialibrary.SORT_LASTMODIFICATIONDATE;
import static org.videolan.medialibrary.interfaces.AMedialibrary.SORT_RELEASEDATE;
public class StubDataSource {
ArrayList<AMediaWrapper> mVideoMediaWrappers = new ArrayList<>();
ArrayList<AMediaWrapper> mAudioMediaWrappers = new ArrayList<>();
ArrayList<AMediaWrapper> mStreamMediaWrappers = new ArrayList<>();
ArrayList<AMediaWrapper> mHistory = new ArrayList<>();
ArrayList<AAlbum> mAlbums = new ArrayList<>();
ArrayList<AArtist> mArtists = new ArrayList<>();
ArrayList<AGenre> mGenres = new ArrayList<>();
ArrayList<APlaylist> mPlaylists = new ArrayList<>();
ArrayList<String> mBannedFolders = new ArrayList<>();
ArrayList<AFolder> mFolders = new ArrayList<>();
ArrayList<String> mDevices = new ArrayList<>();
private static long uuid = 2;
private static StubDataSource mInstance = null;
public static StubDataSource getInstance() {
if (mInstance == null) {
mInstance = new StubDataSource();
}
return mInstance;
}
private StubDataSource() { }
public void init() {
String baseMrl = "/storage/emulated/0/Movies/";
AMediaWrapper media;
// Video
String fileName = "058_foar_everywun_frum_boxxy.flv";
media = ServiceLocator.getAMediaWrapper(getUUID(), baseMrl + fileName, 0L, 18820L, 0,
fileName, fileName, "", "",
"", "", 416, 304, "", 0, -2,
0, 0, 1509466228L, 0L, true);
addVideo(media);
fileName = "FMA - MultiChapter.mkv";
media = ServiceLocator.getAMediaWrapper(getUUID(), baseMrl + fileName, 0L, 1467383L, 0,
"Encoded with MiniCoder", fileName, "", "",
"", "", 1280, 720, "", 0,
-2, 0, 0, 1512396147L, 0L, true);
addVideo(media);
fileName = "114_My_Heart_Will_Go_On.avi";
media = ServiceLocator.getAMediaWrapper(getUUID(), baseMrl + fileName, 0L, 20000L, 0,
"My Heart Will Go On - Celine Dion", fileName, "", "",
"", "", 352, 220, "", 0,
-2, 0, 0, 1509465852L, 0L, true);
addVideo(media);
// Audio
fileName = "01-Show Me The Way.mp3";
baseMrl = "/storage/emulated/0/Music/Peter Frampton/Shine On - CD2/";
media = ServiceLocator.getAMediaWrapper(getUUID(), baseMrl + fileName, 0L, 280244L, 1,
"01-Show Me The Way", fileName, "Peter Frampton", "Rock",
"Shine On CD2", "Peter Frampton",
0, 0, "/storage/emulated/0/Music/Peter Frampton/Shine On - CD2/Folder.jpg",
0, -2, 1, 0,
1547452796L, 0L, true);
addAudio(media, "", 1965, 400);
fileName = "01-Wind Of Change.mp3";
baseMrl = "/storage/emulated/0/Music/Peter Frampton/Shine On - CD1/";
media = ServiceLocator.getAMediaWrapper(getUUID(), baseMrl + fileName, 0L, 184271L, 1,
"01-Wind Of Change", fileName, "Peter Frampton", "Rock",
"Shine On CD1", "Peter Frampton",
0, 0, "/storage/emulated/0/Music/Peter Frampton/Shine On - CD1/Folder.jpg",
0, -2, 1, 0,
1547452786L, 0L, true);
addAudio(media, "", 1960, 250);
fileName = "03 Bloody Well Right.wma";
baseMrl = "/storage/emulated/0/Music/Supertramp/Best of/";
media = ServiceLocator.getAMediaWrapper(getUUID(), baseMrl + fileName, 0L, 257199L, 1,
"Bloody Well Right", fileName, "Supertramp", "Rock",
"The Autobiography of Supertramp", "Supertramp",
0, 0, "/storage/emulated/0/Music/Supertramp/Best of/Folder.jpg", 0,
-2, 3, 0,
1547452814L, 0L, true);
addAudio(media, "", 1970, 360);
}
<T> List<T> secureSublist(List<T> list, int offset, int nbItems) {
int min = list.size() - 1 < 0 ? 0 : list.size();
int secureOffset = (offset >= list.size()) && (offset > 0) ? min : offset;
int end = offset + nbItems;
int secureEnd = (end >= list.size()) && end > 0 ? min : end;
return list.subList(secureOffset, secureEnd);
}
class MediaComparator implements Comparator<AMediaWrapper> {
private int sort;
MediaComparator(int sort) { this.sort = sort; }
@Override //TODO checkout if types of sort are verified before being used in native
public int compare(AMediaWrapper o1, AMediaWrapper o2) {
switch(sort) {
case SORT_DEFAULT:
case SORT_ALPHA: return o1.getTitle().compareTo(o2.getTitle());
case SORT_FILENAME :return o1.getFileName().compareTo(o2.getFileName());
case SORT_DURATION: return (int)(o1.getLength() - o2.getLength());
case SORT_INSERTIONDATE: return (int)(o1.getTime() - o2.getTime()); // TODO checkout if insertiton <=> time
case SORT_LASTMODIFICATIONDATE: return (int)(o1.getLastModified() - o2.getLastModified());
case SORT_ARTIST: return o1.getArtist().compareTo(o2.getArtist());
default: return 0;
}
}
}
class ArtistComparator implements Comparator<AArtist> {
private int sort;
ArtistComparator(int sort) { this.sort = sort; }
@Override
public int compare(AArtist o1, AArtist o2) {
switch(sort) {
case SORT_DEFAULT:
case SORT_ARTIST: return o1.getTitle().compareTo(o2.getTitle());
default: return 0;
}
}
}
class AlbumComparator implements Comparator<AAlbum> {
private int sort;
AlbumComparator(int sort) { this.sort = sort; }
@Override
public int compare(AAlbum o1, AAlbum o2) {
switch (sort) {
case SORT_DEFAULT:
case SORT_ALBUM: return o1.getTitle().compareTo(o2.getTitle());
case SORT_RELEASEDATE: return o1.getReleaseYear() - o2.getReleaseYear();
case SORT_DURATION: return o1.getDuration() - o2.getDuration();
default: return 0;
}
}
}
class GenreComparator implements Comparator<AGenre> {
private int sort;
GenreComparator(int sort) { this.sort = sort; }
@Override
public int compare(AGenre o1, AGenre o2) {
switch(sort) {
case SORT_DEFAULT:
case SORT_ALPHA: return o1.getTitle().compareTo(o2.getTitle());
default: return 0;
}
}
}
class PlaylistComparator implements Comparator<APlaylist> {
private int sort;
PlaylistComparator(int sort) { this.sort = sort; }
@Override
public int compare(APlaylist o1, APlaylist o2) {
switch (sort) {
case SORT_DEFAULT:
case SORT_ALPHA: return o1.getTitle().compareTo(o2.getTitle());
case SORT_DURATION: return 0; //TODO WTF is there a duration attribute
default: return 0;
}
}
}
class FolderComparator implements Comparator<AFolder> {
private int sort;
FolderComparator(int sort) { this.sort = sort; }
@Override
public int compare(AFolder o1, AFolder o2) {
switch (sort) {
case SORT_DEFAULT:
case SORT_ALPHA: return o1.getTitle().compareTo(o2.getTitle());
default: return 0;
}
}
}
AMediaWrapper[] sortMedia(List<AMediaWrapper> arrayList, int sort, boolean desc) {
List<AMediaWrapper> array = new ArrayList<>(arrayList);
Collections.sort(array, new MediaComparator(sort));
if (desc)
Collections.reverse(array);
return array.toArray(new AMediaWrapper[0]);
}
AAlbum[] sortAlbum(List<AAlbum> arrayList, int sort, boolean desc) {
List<AAlbum> array = new ArrayList<>(arrayList);
Collections.sort(array, new AlbumComparator(sort));
if (desc)
Collections.reverse(array);
return array.toArray(new AAlbum[0]);
}
AArtist[] sortArtist(List<AArtist> arrayList, int sort, boolean desc) {
List<AArtist> array = new ArrayList<>(arrayList);
Collections.sort(array, new ArtistComparator(sort));
if (desc)
Collections.reverse(array);
return array.toArray(new AArtist[0]);
}
AGenre[] sortGenre(List<AGenre> arrayList, int sort, boolean desc) {
List<AGenre> array = new ArrayList<>(arrayList);
Collections.sort(array, new GenreComparator(sort));
if (desc)
Collections.reverse(array);
return array.toArray(new AGenre[0]);
}
APlaylist[] sortPlaylist(List<APlaylist> arrayList, int sort, boolean desc) {
List<APlaylist> array = new ArrayList<>(arrayList);
Collections.sort(array, new PlaylistComparator(sort));
if (desc)
Collections.reverse(array);
return array.toArray(new APlaylist[0]);
}
AFolder[] sortFolder(List<AFolder> arrayList, int sort, boolean desc) {
List<AFolder> array = new ArrayList<>(arrayList);
Collections.sort(array, new FolderComparator(sort));
if (desc)
Collections.reverse(array);
return array.toArray(new AFolder[0]);
}
private boolean checkUuidForMatches(long id) {
if (id == 1L || id == 2L)
return true;
for (MediaLibraryItem item : mVideoMediaWrappers) {
if (item.getId() == id)
return true;
}
for (MediaLibraryItem item : mAudioMediaWrappers) {
if (item.getId() == id)
return true;
}
for (MediaLibraryItem item : mAlbums) {
if (item.getId() == id)
return true;
}
for (MediaLibraryItem item : mArtists) {
if (item.getId() == id)
return true;
}
for (MediaLibraryItem item : mGenres) {
if (item.getId() == id)
return true;
}
for (MediaLibraryItem item : mFolders) {
if (item.getId() == id)
return true;
}
return false;
}
long getUUID() {
uuid++;
return uuid;
}
private void addAudio(AMediaWrapper media, String shortBio, int releaseYear, int albumDuration) {
addFolders(media);
mAudioMediaWrappers.add(media);
AArtist artist = ServiceLocator.getAArtist(getUUID(), media.getArtist(), shortBio, media.getArtworkMrl(), "");
mArtists.add(artist);
AArtist albumArtist = null;
if (!media.getArtist().equals(media.getAlbumArtist())) {
albumArtist = ServiceLocator.getAArtist(getUUID(), media.getAlbumArtist(), "", media.getArtworkMrl(), "");
mArtists.add(albumArtist);
}
AAlbum album;
if (albumArtist == null)
album = ServiceLocator.getAAlbum(getUUID(), media.getAlbum(), releaseYear,
media.getArtworkMrl(), artist.getTitle(),
artist.getId(), media.getTracks().length, albumDuration);
else
album = ServiceLocator.getAAlbum(getUUID(), media.getAlbum(), releaseYear,
media.getArtworkMrl(), albumArtist.getTitle(),
albumArtist.getId(), media.getTracks().length, albumDuration);
mAlbums.add(album);
ArrayList genreStrings = new ArrayList<>();
// if (!getGenresString())
mGenres.add(ServiceLocator.getAGenre(getUUID(), media.getGenre()));
}
private void addVideo(AMediaWrapper media) {
addFolders(media);
mVideoMediaWrappers.add(media);
}
private String[] getGenresString() {
ArrayList<String> results = new ArrayList<>();
for (AGenre genre : mGenres) { results.add(genre.getTitle()); }
return results.toArray(new String[0]);
}
private String[] getFoldersString() {
ArrayList<String> results = new ArrayList<>();
for (AFolder folder : mFolders) { results.add(folder.getTitle()); }
return results.toArray(new String[0]);
}
private void addFolders(AMediaWrapper media) {
String path = media.getUri().getPath();
if (path == null)
return;
String[] folderArray = path.split("/");
ArrayList<String> newFolders = new ArrayList<>(Arrays.asList(folderArray));
for (int i = 0; i < newFolders.size(); i++) {
final String mrl = TextUtils.join("/", secureSublist(newFolders, 0, i));
ArrayList<String> mlFolders = new ArrayList<>(Arrays.asList(getFoldersString()));
if (!mlFolders.contains(mrl)) {
final String name = folderArray[folderArray.length - 1];
mFolders.add(ServiceLocator.getAFolder(getUUID(), name, mrl));
}
}
}
}

74
medialibrary/src/org/videolan/medialibrary/stubs/StubFolder.java

@ -5,8 +5,14 @@ import android.os.Parcel;
import org.videolan.medialibrary.interfaces.media.AFolder;
import org.videolan.medialibrary.interfaces.media.AMediaWrapper;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
public class StubFolder extends AFolder {
private StubDataSource dt = StubDataSource.getInstance();
public StubFolder(long id, String name, String mrl) {
super(id, name, mrl);
}
@ -14,27 +20,83 @@ public class StubFolder extends AFolder {
super(in);
}
//TODO checkout results not sure att all ...
private boolean isParentFolder(String parentMrl, String childMrl) {
if (!childMrl.contains(parentMrl)) return false;
File mediaFile = new File(childMrl);
String parentPath = mediaFile.getParent();
return parentPath.equals(parentMrl);
}
//TODO WTF would media be null ??
public AMediaWrapper[] media(int type, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
ArrayList<AMediaWrapper> source;
if (type == TYPE_FOLDER_VIDEO) source = dt.mVideoMediaWrappers;
else if (type == TYPE_FOLDER_AUDIO) source = dt.mAudioMediaWrappers;
else return null;
for (AMediaWrapper media : source) {
if (isParentFolder(this.mMrl, media.getUri().getPath())) results.add(media);
}
results = new ArrayList<>(Arrays.asList(dt.sortMedia(results, sort, desc)));
return dt.secureSublist(results, offset, offset + nbItems).toArray(new AMediaWrapper[0]);
}
public int mediaCount(int type) {
return 0;
int count = 0;
ArrayList<AMediaWrapper> source;
if (type == TYPE_FOLDER_VIDEO) source = dt.mVideoMediaWrappers;
else if (type == TYPE_FOLDER_AUDIO) source = dt.mAudioMediaWrappers;
else return 0;
for (AMediaWrapper media : source) {
if (isParentFolder(this.mMrl, media.getUri().getPath())) count++;
}
return count;
}
public AFolder[] subfolders(int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AFolder> results = new ArrayList<>();
for (AFolder folder : dt.mFolders) {
if (isParentFolder(this.mMrl, folder.mMrl)) results.add(folder);
}
results = new ArrayList<>(Arrays.asList(dt.sortFolder(results, sort, desc)));
return dt.secureSublist(results, offset, offset + nbItems).toArray(new AFolder[0]);
}
public int subfoldersCount(int type) {
return 0;
int count = 0;
for (AFolder folder : dt.mFolders) {
if (isParentFolder(this.mMrl, folder.mMrl)) count++;
}
return count;
}
public AMediaWrapper[] searchTracks(String query, int mediaType, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
ArrayList<AMediaWrapper> source;
if (mediaType == TYPE_FOLDER_VIDEO) source = dt.mVideoMediaWrappers;
else if (mediaType == TYPE_FOLDER_AUDIO) source = dt.mAudioMediaWrappers;
else return null;
for (AMediaWrapper media : source) {
if (media.getTitle().contains(query) &&
isParentFolder(this.mMrl, media.getUri().getPath())) {
results.add(media);
}
}
results = new ArrayList<>(Arrays.asList(dt.sortMedia(results, sort, desc)));
return dt.secureSublist(results, offset, offset + nbItems).toArray(new AMediaWrapper[0]);
}
public int searchTracksCount(String query, int mediaType) {
return 0;
int count = 0;
ArrayList<AMediaWrapper> source;
if (mediaType == TYPE_FOLDER_VIDEO) source = dt.mVideoMediaWrappers;
else if (mediaType == TYPE_FOLDER_AUDIO) source = dt.mAudioMediaWrappers;
else return 0;
for (AMediaWrapper media : source) {
if (media.getTitle().contains(query) &&
isParentFolder(this.mMrl, media.getUri().getPath())) count++;
}
return count;
}
}

119
medialibrary/src/org/videolan/medialibrary/stubs/StubGenre.java

@ -7,52 +7,135 @@ import org.videolan.medialibrary.interfaces.media.AArtist;
import org.videolan.medialibrary.interfaces.media.AGenre;
import org.videolan.medialibrary.interfaces.media.AMediaWrapper;
import java.util.ArrayList;
import java.util.Arrays;
public class StubGenre extends AGenre {
private StubDataSource dt = StubDataSource.getInstance();
public StubGenre(long id, String title) { super(id, title); }
public StubGenre(Parcel in) { super(in); }
public AAlbum[] getAlbums(int sort, boolean desc) {
return null;
ArrayList<AAlbum> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getGenre().equals(this.getTitle())) {
for (AAlbum album : dt.mAlbums) {
if (album.getTitle().equals(media.getAlbum()) &&
!results.contains(album)) {
results.add(album);
}
}
}
}
return dt.sortAlbum(results, sort, desc);
}
public AAlbum[] getPagedAlbums(int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AAlbum> results = new ArrayList<>(Arrays.asList(getAlbums(sort, desc)));
return dt.secureSublist(results, offset, offset + nbItems).toArray(new AAlbum[0]);
}
public AArtist[] getArtists(int sort, boolean desc) {
return null;
@Override
public int getAlbumsCount() {
return getAlbums().length;
}
public AMediaWrapper[] getTracks(int sort, boolean desc) {
return null;
public AAlbum[] searchAlbums(String query, int sort, boolean desc, int nbItems, int offset) {
ArrayList<AAlbum> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getGenre().equals(this.getTitle()) &&
media.getTitle().contains(query)) {
for (AAlbum album : dt.mAlbums) {
if (album.getTitle().equals(media.getAlbum()) &&
!results.contains(album)) {
results.add(album);
}
}
}
}
results = new ArrayList<>(Arrays.asList(dt.sortAlbum(results, sort, desc)));
return dt.secureSublist(results, offset, offset + nbItems).toArray(new AAlbum[0]);
}
public AMediaWrapper[] getPagedTracks(int sort, boolean desc, int nbItems, int offset) {
return null;
public int searchAlbumsCount(String query) {
ArrayList<AAlbum> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getGenre().equals(this.getTitle()) &&
media.getTitle().contains(query)) {
for (AAlbum album : dt.mAlbums) {
if (album.getTitle().equals(media.getAlbum()) &&
!results.contains(album)) {
results.add(album);
}
}
}
}
return results.size();
}
public int getTracksCount() {
return 0;
public AArtist[] getArtists(int sort, boolean desc) {
ArrayList<AArtist> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getGenre().equals(this.getTitle())) {
for (AArtist artist : dt.mArtists) {
if ((artist.getTitle().equals(media.getArtist()) ||
artist.getTitle().equals(media.getAlbumArtist())) &&
!results.contains(artist)) {
results.add(artist);
break;
}
}
}
}
return dt.sortArtist(results, sort, desc);
}
public int getAlbumsCount() {
return 0;
public AMediaWrapper[] getTracks(int sort, boolean desc) {
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getGenre().equals(this.getTitle())) results.add(media);
}
return dt.sortMedia(results, sort, desc);
}
public AAlbum[] searchAlbums(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
public AMediaWrapper[] getPagedTracks(int sort, boolean desc, int nbItems, int offset) {
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getGenre().equals(this.getTitle())) results.add(media);
}
return dt.sortMedia(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public int searchAlbumsCount(String query) {
return 0;
public int getTracksCount() {
int count = 0;
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getGenre().equals(this.getTitle())) count++;
}
return count;
}
public AMediaWrapper[] searchTracks(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getGenre().equals(this.getTitle()) &&
media.getTitle().contains(query)) {
results.add(media);
}
}
return dt.sortMedia(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public int searchTracksCount(String query) {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getGenre().equals(this.getTitle()) &&
media.getTitle().contains(query)) {
count++;
}
}
return count;
}
}

12
medialibrary/src/org/videolan/medialibrary/stubs/StubMediaWrapper.java

@ -3,6 +3,7 @@ package org.videolan.medialibrary.stubs;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Parcel;
import android.util.SparseArray;
import org.videolan.libvlc.Media;
import org.videolan.medialibrary.interfaces.media.AMediaWrapper;
@ -30,26 +31,33 @@ public class StubMediaWrapper extends AMediaWrapper {
public StubMediaWrapper(Media media) { super(media); }
public StubMediaWrapper(Parcel in) { super(in); }
private SparseArray<Long> mMetaLong = new SparseArray<>();
private SparseArray<String> mMetaString = new SparseArray<>();
public void rename(String name) {
mTitle = name;
}
public long getMetaLong(int metaDataType) {
return 0L;
return mMetaLong.get(metaDataType);
}
public String getMetaString(int metaDataType) {
return "";
return mMetaString.get(metaDataType);
}
public boolean setLongMeta(int metaDataType, long metadataValue) {
mMetaLong.setValueAt(metaDataType, metadataValue);
return true;
}
public boolean setStringMeta(int metaDataType, String metadataValue) {
mMetaString.setValueAt(metaDataType, metadataValue);
return true;
}
public void setThumbnail(String mrl) {
//TODO
}
}

411
medialibrary/src/org/videolan/medialibrary/stubs/StubMedialibrary.java

@ -2,12 +2,12 @@ package org.videolan.medialibrary.stubs;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import androidx.annotation.NonNull;
import org.videolan.medialibrary.ServiceLocator;
import org.videolan.medialibrary.interfaces.AMedialibrary;
import org.videolan.medialibrary.interfaces.DevicesDiscoveryCb;
import org.videolan.medialibrary.interfaces.EntryPointsEventsCb;
import org.videolan.medialibrary.interfaces.media.AAlbum;
import org.videolan.medialibrary.interfaces.media.AArtist;
import org.videolan.medialibrary.interfaces.media.AFolder;
@ -16,211 +16,355 @@ import org.videolan.medialibrary.interfaces.media.AMediaWrapper;
import org.videolan.medialibrary.interfaces.media.APlaylist;
import org.videolan.medialibrary.media.SearchAggregate;
import java.util.ArrayList;
import java.util.Arrays;
public class StubMedialibrary extends AMedialibrary {
private StubDataSource dt = StubDataSource.getInstance();
private String TAG = this.getClass().getName();
public int init(Context context) {
if (context == null) return ML_INIT_FAILED;
sContext = context;
dt.init();
return ML_INIT_SUCCESS;
}
public void start() {
isMedialibraryStarted = true;
synchronized (onMedialibraryReadyListeners) {
for (OnMedialibraryReadyListener listener : onMedialibraryReadyListeners) listener.onMedialibraryReady();
}
}
public void banFolder(@NonNull String path) {
if (!dt.mBannedFolders.contains(path))
dt.mBannedFolders.add(path);
}
public void unbanFolder(@NonNull String path) {
// TODO checkout error handling for ban / unban folder
// TODO checkout probably useless as there is no folder parsing
// TODO also unban folder might trigger an action
public void unbanFolder(@NonNull String path) {
dt.mBannedFolders.remove(path);
}
public String[] getDevices() {
return null;
return new String[0];
}
public boolean addDevice(@NonNull String uuid, @NonNull String path, boolean removable) {
return false;
}
public void discover(@NonNull String path) {}
public void removeFolder(@NonNull String mrl) {}
public String[] getFoldersList() {
return null;
public void discover(@NonNull String path) {
onDiscoveryStarted(path);
onDiscoveryCompleted(path);
}
public void removeFolder(@NonNull String mrl) {}
public boolean removeDevice(String uuid, String path) {
return true;
}
public String[] getFoldersList() {
ArrayList<String> results = new ArrayList<>();
for (AFolder folder : dt.mFolders) {
results.add(folder.getTitle());
}
return results.toArray(new String[0]);
}
public AMediaWrapper[] getVideos() {
return null;
return getVideos(SORT_DEFAULT, false);
}
//TODO sublist of sorted result ...
public AMediaWrapper[] getPagedVideos(int sort, boolean desc, int nbItems, int offset) {
return null;
return dt.sortMedia(dt.secureSublist(dt.mVideoMediaWrappers, offset, offset + nbItems), sort, desc);
}
public AMediaWrapper[] getVideos(int sort, boolean desc) {
return null;
return dt.sortMedia(dt.mVideoMediaWrappers, sort, desc);
}
public AMediaWrapper[] getRecentVideos() {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getItemType() == AMediaWrapper.TYPE_VIDEO) results.add(media);
}
return results.toArray(new AMediaWrapper[0]);
}
public AMediaWrapper[] getAudio() {
return null;
return getAudio(SORT_DEFAULT, false);
}
public AMediaWrapper[] getAudio(int sort, boolean desc) {
return null;
return dt.sortMedia(dt.mAudioMediaWrappers, sort, desc);
}
public AMediaWrapper[] getPagedAudio(int sort, boolean desc, int nbitems, int offset) {
return null;
return dt.sortMedia(dt.secureSublist(dt.mAudioMediaWrappers, offset, offset + nbitems), sort, desc);
}
public AMediaWrapper[] getRecentAudio() {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getItemType() == AMediaWrapper.TYPE_AUDIO) results.add(media);
}
return results.toArray(new AMediaWrapper[0]);
}
public int getVideoCount() {
return 0;
return dt.mVideoMediaWrappers.size();
}
public int getAudioCount() {
return 0;
return dt.mAudioMediaWrappers.size();
}
public AAlbum[] getAlbums() {
return null;
return getAlbums(SORT_DEFAULT, false);
}
public AAlbum[] getAlbums(int sort, boolean desc) {
return null;
return dt.sortAlbum(dt.mAlbums, sort, desc);
}
public AAlbum[] getPagedAlbums(int sort, boolean desc, int nbItems, int offset) {
return null;
return dt.sortAlbum(dt.secureSublist(dt.mAlbums, offset, offset + nbItems), sort, desc);
}
public int getAlbumsCount() {
return 0;
return dt.mAlbums.size();
}
public int getAlbumsCount(String query) {
return 0;
int count = 0;
for (AAlbum album : dt.mAlbums) {
if (album.getTitle().contains(query)) count++;
}
return count;
}
public AAlbum getAlbum(long albumId) {
for (AAlbum album : dt.mAlbums) {
if (album.getId() == albumId) return album;
}
return null;
}
public AArtist[] getArtists(boolean all) {
return null;
return getArtists(all, SORT_DEFAULT, false);
}
private AArtist[] getAlbumArtists() {
ArrayList<AArtist> results = new ArrayList<>();
for (AAlbum album : dt.mAlbums) {
results.add(album.getAlbumArtist());
}
return results.toArray(new AArtist[0]);
}
public AArtist[] getArtists(boolean all, int sort, boolean desc) {
return null;
ArrayList<AArtist> results;
if (all) results = dt.mArtists;
else results = new ArrayList<>(Arrays.asList(getAlbumArtists()));
return dt.sortArtist(results, sort, desc);
}
public AArtist[] getPagedArtists(boolean all, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AArtist> results;
if (all) results = dt.mArtists;
else results = new ArrayList<>(Arrays.asList(getAlbumArtists()));
return dt.sortArtist(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public int getArtistsCount(boolean all) {
return 0;
int count;
if (all) count = dt.mArtists.size();
else count = getAlbumArtists().length;
return count;
}
public int getArtistsCount(String query) {
return 0;
int count = 0;
for (AArtist artist : dt.mArtists) {
if (artist.getTitle().contains(query)) count++;
}
return count;
}
public AArtist getArtist(long artistId) {
for (AArtist artist : dt.mArtists) {
if (artist.getId() == artistId) return artist;
}
return null;
}
public AGenre[] getGenres() {
return null;
return dt.mGenres.toArray(new AGenre[0]);
}
public AGenre[] getGenres(int sort, boolean desc) {
return null;
return dt.sortGenre(dt.mGenres, sort, desc);
}
public AGenre[] getPagedGenres(int sort, boolean desc, int nbItems, int offset) {
return null;
return dt.sortGenre(dt.secureSublist(dt.mGenres, offset, offset + nbItems), sort, desc);
}
public int getGenresCount() {
return 0;
return dt.mGenres.size();
}
public int getGenresCount(String query) {
return 0;
int count = 0;
for (AGenre genre : dt.mGenres) {
if (genre.getTitle().contains(query)) count++;
}
return count;
}
public AGenre getGenre(long genreId) {
for (AGenre genre : dt.mGenres) {
if (genre.getId() == genreId) return genre;
}
return null;
}
public APlaylist[] getPlaylists(int sort, boolean desc) {
return null;
public APlaylist[] getPlaylists() {
return dt.mPlaylists.toArray(new APlaylist[0]);
}
public APlaylist[] getPlaylists() {
return null;
public APlaylist[] getPlaylists(int sort, boolean desc) {
return dt.sortPlaylist(dt.mPlaylists, sort, desc);
}
public APlaylist[] getPagedPlaylists(int sort, boolean desc, int nbItems, int offset) {
return null;
return dt.sortPlaylist(dt.secureSublist(dt.mPlaylists, offset, offset + nbItems), sort, desc);
}
public int getPlaylistsCount() {
return 0;
return dt.mPlaylists.size();
}
public int getPlaylistsCount(String query) {
return 0;
int count = 0;
for (APlaylist playlist : dt.mPlaylists) {
if (playlist.getTitle().contains(query)) count ++;
}
return count;
}
public APlaylist getPlaylist(long playlistId) {
for (APlaylist playlist : dt.mPlaylists) {
if (playlist.getId() == playlistId) return playlist;
}
return null;
}
public APlaylist createPlaylist(String name) {
return null;
APlaylist playlist = ServiceLocator.getAPlaylist(dt.getUUID(), name, 0);
dt.mPlaylists.add(playlist);
onPlaylistsAdded();
return playlist;
}
public void pauseBackgroundOperations() {}
public void resumeBackgroundOperations() {}
public void reload() {}
public void reload(String entrypoint) {}
public void reload() {
Log.e(TAG, "reload: no entrypoint");
reload("");
}
public void reload(String entrypoint) {
Log.e(TAG, "reload(string entrypoint): ");
onReloadStarted(entrypoint);
onReloadCompleted(entrypoint);
onBackgroundTasksIdleChanged(true);
}
public void forceParserRetry() {}
public void forceRescan() {}
public AMediaWrapper[] lastMediaPlayed() {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mHistory) {
if (media.getItemType() == AMediaWrapper.TYPE_VIDEO ||
media.getItemType() == AMediaWrapper.TYPE_AUDIO) results.add(media);
// the native method specifies an nbItems of 100, offset 0
if (results.size() >= 100) break;
}
return results.toArray(new AMediaWrapper[0]);
}
public AMediaWrapper[] lastStreamsPlayed() {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mHistory) {
if (media.getItemType() == AMediaWrapper.TYPE_STREAM) results.add(media);
// the native method specifies an nbItems of 100, offset 0
if (results.size() >= 100) break;
}
return results.toArray(new AMediaWrapper[0]);
}
//TODO see when it would return false
public boolean clearHistory() {
dt.mHistory.clear();
return true;
}
//TODO what if two files have the same name ??
// TODO what happens in case of false return
public boolean addToHistory(String mrl, String title) {
AMediaWrapper media = getMedia(mrl, title);
if (media == null) {
media = addStream(mrl, title);
}
dt.mHistory.add(media);
increasePlayCount(media.getId());
return true;
}
// TODO Handle uri to mrl
private AMediaWrapper getMedia(String mrl, String title) {
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getTitle().equals(title)) return media;
}
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getTitle().equals(title)) return media;
}
for (AMediaWrapper media : dt.mStreamMediaWrappers) {
if (media.getTitle().equals(title)) return media;
}
return null;
}
public AMediaWrapper getMedia(long id) {
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getId() == id) return media;
}
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getId() == id) return media;
}
for (AMediaWrapper media : dt.mStreamMediaWrappers) {
if (media.getId() == id) return media;
}
return null;
}
public AMediaWrapper getMedia(Uri uri) {
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getUri().equals(uri)) return media;
}
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getUri().equals(uri)) return media;
}
for (AMediaWrapper media : dt.mStreamMediaWrappers) {
if (media.getUri().equals(uri)) return media;
}
return null;
}
@ -228,6 +372,8 @@ public class StubMedialibrary extends AMedialibrary {
return null;
}
/* TODO maybe add a list of medias not in the medialibrary which can be retrieved with mrl to
* simulate adding a media from system */
public AMediaWrapper addMedia(String mrl) {
return null;
}
@ -251,120 +397,155 @@ public class StubMedialibrary extends AMedialibrary {
public void requestThumbnail(long id) {}
public boolean increasePlayCount(long mediaId) {
for (int i = 0 ; i < dt.mVideoMediaWrappers.size() ; i++) {
AMediaWrapper media = dt.mVideoMediaWrappers.get(i);
if (media.getId() == mediaId) {
media.setSeen(media.getSeen() + 1);
dt.mVideoMediaWrappers.set(i, media);
}
}
return true;
}
public AMediaWrapper findMedia(AMediaWrapper mw) {
return null;
}
public void onMediaAdded(AMediaWrapper[] mediaList) {}
public void onMediaUpdated(AMediaWrapper[] mediaList) {}
public void onMediaDeleted() {}
public void onArtistsAdded() {}
public void onArtistsModified() {}
public void onArtistsDeleted() {}
public void onAlbumsAdded() {}
public void onAlbumsModified() {}
public void onAlbumsDeleted() {}
public void onGenresAdded() {}
public void onGenresModified() {}
public void onGenresDeleted() {}
public void onPlaylistsAdded() {}
public void onPlaylistsModified() {}
public void onPlaylistsDeleted() {}
public void onDiscoveryStarted(String entryPoint) {}
public void onDiscoveryProgress(String entryPoint) {}
public void onDiscoveryCompleted(String entryPoint) {}
public void onParsingStatsUpdated(int percent) {}
public void onBackgroundTasksIdleChanged(boolean isIdle) {}
public void onReloadStarted(String entryPoint) {}
public void onReloadCompleted(String entryPoint) {}
public void onEntryPointBanned(String entryPoint, boolean success) {}
public void onEntryPointUnbanned(String entryPoint, boolean success) {}
public void onEntryPointRemoved(String entryPoint, boolean success) {}
public void onMediaThumbnailReady(AMediaWrapper Amedia, boolean success) {}
public void addMediaCb(MediaCb mediaUpdated) {}
public void removeMediaCb(MediaCb mediaUpdatedCb) {}
public void addArtistsCb(ArtistsCb artictAddedCb) {}
public void removeArtistsCb(ArtistsCb artistCb) {}
public void addAlbumsCb(AlbumsCb albumsAddedCb) {}
public void removeAlbumsCb(AlbumsCb albumsAddedCb) {}
public void addGenreCb(GenresCb genresAddedCb) {}
public void removeGenreCb(GenresCb genresAddedCb) {}
public void addPlaylistCb(PlaylistsCb playlistsAddedCb) {}
public void removePlaylistCb(PlaylistsCb playlistsAddedCb) {}
public SearchAggregate search(String query) {
return null;
AMediaWrapper[] videos = searchVideo(query);
AMediaWrapper[] tracks = searchAudio(query);
AAlbum[] albums = searchAlbum(query);
AArtist[] artists = searchArtist(query);
AGenre[] genres = searchGenre(query);
APlaylist[] playlists = searchPlaylist(query);
return new SearchAggregate(albums, artists, genres, videos, tracks, playlists);
}
public AMediaWrapper[] searchMedia(String query) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getTitle().contains(query)) results.add(media);
}
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getTitle().contains(query)) results.add(media);
}
for (AMediaWrapper media : dt.mStreamMediaWrappers) {
if (media.getTitle().contains(query)) results.add(media);
}
return results.toArray(new AMediaWrapper[0]);
}
public AMediaWrapper[] searchMedia(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>(Arrays.asList(searchMedia(query)));
return dt.sortMedia(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public int getMediaCount(String query) {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getTitle().contains(query)) count++;
}
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getTitle().contains(query)) count++;
}
for (AMediaWrapper media : dt.mStreamMediaWrappers) {
if (media.getTitle().contains(query)) count++;
}
return count;
}
private AMediaWrapper[] searchAudio(String query) {
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getTitle().contains(query)) results.add(media);
}
return dt.sortMedia(results, SORT_DEFAULT, false);
}
public AMediaWrapper[] searchAudio(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getTitle().contains(query)) results.add(media);
}
return dt.sortMedia(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public int getAudioCount(String query) {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (media.getTitle().contains(query)) count++;
}
return count;
}
private AMediaWrapper[] searchVideo(String query) {
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getTitle().contains(query)) results.add(media);
}
return dt.sortMedia(results, SORT_DEFAULT, false);
}
public AMediaWrapper[] searchVideo(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getTitle().contains(query)) results.add(media);
}
return dt.sortMedia(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public int getVideoCount(String query) {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mVideoMediaWrappers) {
if (media.getTitle().contains(query)) count++;
}
return count;
}
public AArtist[] searchArtist(String query) {
return null;
ArrayList<AArtist> results = new ArrayList<>();
for (AArtist artist: dt.mArtists) {
if (artist.getTitle().contains(query)) results.add(artist);
}
return results.toArray(new AArtist[0]);
}
public AArtist[] searchArtist(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AArtist> results = new ArrayList<>(Arrays.asList(searchArtist(query)));
return dt.sortArtist(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public AAlbum[] searchAlbum(String query) {
return null;
ArrayList<AAlbum> results = new ArrayList<>();
for (AAlbum album: dt.mAlbums) {
if (album.getTitle().contains(query)) results.add(album);
}
return results.toArray(new AAlbum[0]);
}
public AAlbum[] searchAlbum(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AAlbum> results = new ArrayList<>(Arrays.asList(searchAlbum(query)));
return dt.sortAlbum(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public AGenre[] searchGenre(String query) {
return null;
ArrayList<AGenre> results = new ArrayList<>();
for (AGenre genre: dt.mGenres) {
if (genre.getTitle().contains(query)) results.add(genre);
}
return results.toArray(new AGenre[0]);
}
public AGenre[] searchGenre(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AGenre> results = new ArrayList<>(Arrays.asList(searchGenre(query)));
return dt.sortGenre(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public APlaylist[] searchPlaylist(String query) {
return null;
ArrayList<APlaylist> results = new ArrayList<>();
for (APlaylist playlist: dt.mPlaylists) {
if (playlist.getTitle().contains(query)) results.add(playlist);
}
return results.toArray(new APlaylist[0]);
}
public APlaylist[] searchPlaylist(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<APlaylist> results = new ArrayList<>(Arrays.asList(searchPlaylist(query)));
return dt.sortPlaylist(dt.secureSublist(results, offset, offset + nbItems), sort, desc);
}
public void addDeviceDiscoveryCb(DevicesDiscoveryCb cb) {}
public void removeDeviceDiscoveryCb(DevicesDiscoveryCb cb) {}
public void addOnMedialibraryReadyListener(OnMedialibraryReadyListener cb) {}
public void removeOnMedialibraryReadyListener(OnMedialibraryReadyListener cb) {}
public void addEntryPointsEventsCb(EntryPointsEventsCb cb) {}
public void removeEntryPointsEventsCb(EntryPointsEventsCb cb) {}
public void addOnDeviceChangeListener(OnDeviceChangeListener cb) {}
public void removeOnDeviceChangeListener(OnDeviceChangeListener cb){}
}

58
medialibrary/src/org/videolan/medialibrary/stubs/StubPlaylist.java

@ -5,10 +5,15 @@ import android.os.Parcel;
import org.videolan.medialibrary.interfaces.media.AMediaWrapper;
import org.videolan.medialibrary.interfaces.media.APlaylist;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StubPlaylist extends APlaylist {
private ArrayList<Long> mTracksId = new ArrayList<>();
private StubDataSource dt = StubDataSource.getInstance();
public StubPlaylist(long id, String name, int trackCount) {
super(id, name, trackCount);
}
@ -18,50 +23,91 @@ public class StubPlaylist extends APlaylist {
}
public AMediaWrapper[] getTracks() {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (mTracksId.contains(media.getId())) results.add(media);
}
return results.toArray(new AMediaWrapper[0]);
}
public AMediaWrapper[] getPagedTracks(int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>(Arrays.asList(getTracks()));
return dt.secureSublist(results, offset, offset + nbItems).toArray(new AMediaWrapper[0]);
}
public int getRealTracksCount() {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (mTracksId.contains(media.getId())) count++;
}
return count;
}
public boolean append(long mediaId) {
mTracksId.add(mediaId);
mTracksCount++;
return true;
}
public boolean append(long[] mediaIds) {
for (long id : mediaIds) {
append(id);
}
return true;
}
public boolean append(List<Long> mediaIds) {
for (long id : mediaIds) {
append(id);
}
return true;
}
public boolean add(long mediaId, int position) {
mTracksId.add(position, mediaId);
return true;
}
public boolean move(int oldPosition, int newPosition) {
long id = mTracksId.get(oldPosition);
mTracksId.remove(oldPosition);
mTracksId.add(newPosition, id);
return true;
}
public boolean remove(int position) {
mTracksId.remove(position);
mTracksCount--;
return true;
}
public boolean delete() {
return true;
for (int i = 0 ; i < dt.mPlaylists.size() ; i++) {
if (dt.mPlaylists.get(i).getId() == this.getId()) {
dt.mPlaylists.remove(i);
return true;
}
}
return false;
}
public AMediaWrapper[] searchTracks(String query, int sort, boolean desc, int nbItems, int offset) {
return null;
ArrayList<AMediaWrapper> results = new ArrayList<>();
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (mTracksId.contains(media.getId()) &&
media.getTitle().contains(query)) results.add(media);
}
results = new ArrayList<>(Arrays.asList(dt.sortMedia(results, sort, desc)));
return dt.secureSublist(results, offset, offset + nbItems).toArray(new AMediaWrapper[0]);
}
public int searchTracksCount(String query) {
return 0;
int count = 0;
for (AMediaWrapper media : dt.mAudioMediaWrappers) {
if (mTracksId.contains(media.getId()) &&
media.getTitle().contains(query)) count++;
}
return count;
}
}

4
vlc-android/res/layout/activity_media_list_tv_item.xml

@ -12,12 +12,12 @@
<import type="android.text.TextUtils" />
<import type="org.videolan.medialibrary.media.MediaWrapper" />
<import type="org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper" />
<variable
name="item"
type="MediaWrapper" />
type="AbstractMediaWrapper" />
<variable
name="cover"

10
vlc-android/src/org/videolan/vlc/StartActivity.kt

@ -28,11 +28,13 @@ import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.text.TextUtils
import android.util.Log
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.medialibrary.ServiceLocator
import org.videolan.vlc.gui.MainActivity
import org.videolan.vlc.gui.SearchActivity
import org.videolan.vlc.gui.helpers.UiTools
@ -94,6 +96,13 @@ class StartActivity : FragmentActivity() {
}
}
// Setting test mode with stubbed media library if required
if (intent.hasExtra(ServiceLocator.EXTRA_TEST_STUBS)
&& intent.getBooleanExtra(ServiceLocator.EXTRA_TEST_STUBS, false)) {
ServiceLocator.setLocatorMode(ServiceLocator.LocatorMode.TESTS)
Log.i(TAG, "onCreate: Setting test mode`")
}
// Start application
/* Get the current version from package */
val settings = Settings.getInstance(this)
@ -169,7 +178,6 @@ class StartActivity : FragmentActivity() {
}
companion object {
const val TAG = "VLC/StartActivity"
}
}

16
vlc-android/src/org/videolan/vlc/gui/PlaylistActivity.kt

@ -287,15 +287,9 @@ open class PlaylistActivity : AudioPlayerContainerActivity(), IEventsHandler, IL
R.id.action_mode_audio_play -> MediaUtils.openList(this, tracks, 0)
R.id.action_mode_audio_append -> MediaUtils.appendMedia(this, tracks)
R.id.action_mode_audio_add_playlist -> UiTools.addToPlaylist(this, tracks)
<<<<<<< HEAD
R.id.action_mode_audio_info -> showInfoDialog(list[0] as MediaWrapper)
R.id.action_mode_audio_set_song -> AudioUtil.setRingtone(list[0] as MediaWrapper, this)
R.id.action_mode_audio_delete -> if (isPlaylist) removeFromPlaylist(tracks, indexes) else removeItems(tracks)
=======
R.id.action_mode_audio_info -> showInfoDialog(list[0] as AMediaWrapper)
R.id.action_mode_audio_set_song -> AudioUtil.setRingtone(list[0] as AMediaWrapper, this)
R.id.action_mode_audio_delete -> removeFromPlaylist(tracks, indexes)
>>>>>>> Medialibrary: move MediaWrapper to AMediaWrapper
R.id.action_mode_audio_delete -> if (isPlaylist) removeFromPlaylist(tracks, indexes) else removeItems(tracks)
else -> return false
}
return true
@ -329,18 +323,14 @@ open class PlaylistActivity : AudioPlayerContainerActivity(), IEventsHandler, IL
private fun removeItem(position: Int, media: AMediaWrapper) {
val resId = if (isPlaylist) R.string.confirm_remove_from_playlist else R.string.confirm_delete
if (isPlaylist) {
<<<<<<< HEAD
snackerConfirm(binding.root, getString(resId, media.title), Runnable { (viewModel.playlist as Playlist).remove(position) })
=======
UiTools.snackerConfirm(binding.root, getString(resId, media.title), Runnable { (viewModel.playlist as APlaylist).remove(position) })
>>>>>>> Medialibrary: move Playlist to APlaylist
snackerConfirm(binding.root, getString(resId, media.title), Runnable { (viewModel.playlist as APlaylist).remove(position) })
} else {
val deleteAction = Runnable { deleteMedia(media) }
snackerConfirm(binding.root, getString(resId, media.title), Runnable { if (Util.checkWritePermission(this@PlaylistActivity, media, deleteAction)) deleteAction.run() })
}
}
private fun removeItems(items: List<MediaWrapper>) {
private fun removeItems(items: List<AMediaWrapper>) {
snackerConfirm(binding.root,getString(R.string.confirm_delete_several_media, items.size)) {
for (item in items) {
if (!isStarted()) break

4
vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.kt

@ -44,11 +44,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import org.videolan.medialibrary.interfaces.media.AMediaWrapper
import org.videolan.medialibrary.media.MediaLibraryItem
<<<<<<< HEAD
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.vlc.BuildConfig
=======
>>>>>>> Medialibrary: move MediaWrapper to AMediaWrapper
import org.videolan.vlc.R
import org.videolan.vlc.gui.*
import org.videolan.vlc.gui.view.FastScroller

32
vlc-android/src/org/videolan/vlc/gui/audio/BaseAudioBrowser.kt

@ -32,18 +32,10 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
<<<<<<< HEAD
import kotlinx.coroutines.*
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.tools.isStarted
=======
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import org.videolan.medialibrary.interfaces.media.AMediaWrapper
import org.videolan.medialibrary.media.MediaLibraryItem
>>>>>>> Medialibrary: move MediaWrapper to AMediaWrapper
import org.videolan.tools.isStarted
import org.videolan.vlc.R
import org.videolan.vlc.gui.ContentActivity
import org.videolan.vlc.gui.browser.MediaBrowserFragment
@ -186,39 +178,21 @@ abstract class BaseAudioBrowser<T : SortableModel> : MediaBrowserFragment<T>(),
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
val list = getCurrentAdapter()?.multiSelectHelper?.getSelection()
stopActionMode()
<<<<<<< HEAD
if (!list.isNullOrEmpty()) launch {
if (isStarted()) when (item.itemId) {
R.id.action_mode_audio_play -> MediaUtils.openList(activity, list.getTracks(), 0)
R.id.action_mode_audio_append -> MediaUtils.appendMedia(activity, list.getTracks())
R.id.action_mode_audio_add_playlist -> UiTools.addToPlaylist(requireActivity(), list.getTracks())
R.id.action_mode_audio_info -> showInfoDialog(list[0])
R.id.action_mode_audio_set_song -> AudioUtil.setRingtone(list[0] as MediaWrapper, requireActivity())
R.id.action_mode_audio_set_song -> AudioUtil.setRingtone(list[0] as AMediaWrapper, requireActivity())
R.id.action_mode_audio_delete -> removeItems(list)
}
}
=======
if (list != null && list.isNotEmpty())
runIO(Runnable {
val tracks = ArrayList<AMediaWrapper>()
for (mediaItem in list)
tracks.addAll(Arrays.asList(*mediaItem.tracks))
launch {
when (item.itemId) {
R.id.action_mode_audio_play -> MediaUtils.openList(activity, tracks, 0)
R.id.action_mode_audio_append -> MediaUtils.appendMedia(activity, tracks)
R.id.action_mode_audio_add_playlist -> UiTools.addToPlaylist(requireActivity(), tracks)
R.id.action_mode_audio_info -> showInfoDialog(list[0])
R.id.action_mode_audio_set_song -> AudioUtil.setRingtone(list[0] as AMediaWrapper, requireActivity())
}
}
})
>>>>>>> Medialibrary: move MediaWrapper to AMediaWrapper
return true
}
private suspend fun List<MediaLibraryItem>.getTracks() = withContext(Dispatchers.Default) {
ArrayList<MediaWrapper>().apply {
ArrayList<AMediaWrapper>().apply {
for (mediaItem in this@getTracks) addAll(Arrays.asList(*mediaItem.tracks))
}
}

9
vlc-android/src/org/videolan/vlc/gui/browser/MediaBrowserFragment.kt

@ -162,8 +162,8 @@ abstract class MediaBrowserFragment<T : SortableModel> : Fragment(), ActionMode.
for (item in items) {
if (!isStarted()) break
when(item) {
is MediaWrapper -> if (getWritePermission(item.uri)) deleteMedia(item)
is Playlist -> withContext(Dispatchers.IO) { item.delete() }
is AMediaWrapper -> if (getWritePermission(item.uri)) deleteMedia(item)
is APlaylist -> withContext(Dispatchers.IO) { item.delete() }
}
}
if (isStarted()) viewModel.refresh()
@ -175,15 +175,10 @@ abstract class MediaBrowserFragment<T : SortableModel> : Fragment(), ActionMode.
when {
item.itemType == MediaLibraryItem.TYPE_PLAYLIST -> UiTools.snackerConfirm(view!!, getString(R.string.confirm_delete_playlist, item.title), Runnable { MediaUtils.deletePlaylist(item as APlaylist) })
item.itemType == MediaLibraryItem.TYPE_MEDIA -> {
<<<<<<< HEAD
val deleteAction = Runnable {
if (isStarted()) launch { deleteMedia(item, false, null) }
}
val resid = if ((item as MediaWrapper).type == MediaWrapper.TYPE_DIR) R.string.confirm_delete_folder else R.string.confirm_delete
=======
val deleteAction = Runnable { deleteMedia(item, false, null) }
val resid = if ((item as AMediaWrapper).type == AMediaWrapper.TYPE_DIR) R.string.confirm_delete_folder else R.string.confirm_delete
>>>>>>> Medialibrary: move MediaWrapper to AMediaWrapper
UiTools.snackerConfirm(view!!, getString(resid, item.getTitle()), Runnable { if (Util.checkWritePermission(requireActivity(), item, deleteAction)) deleteAction.run() })
}
else -> return false

6
vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt

@ -261,12 +261,8 @@ object UiTools {
addToPlaylist(activity, list.toTypedArray(), SavePlaylistDialog.KEY_NEW_TRACKS)
}
<<<<<<< HEAD
fun addToPlaylist(activity: FragmentActivity, tracks: Array<MediaWrapper>, key: String) {
if (!activity.isStarted()) return
=======
fun addToPlaylist(activity: FragmentActivity, tracks: Array<AMediaWrapper>, key: String) {
>>>>>>> Medialibrary: move MediaWrapper to AMediaWrapper
if (!activity.isStarted()) return
val savePlaylistDialog = SavePlaylistDialog()
val args = Bundle()
args.putParcelableArray(key, tracks)

12
vlc-android/src/org/videolan/vlc/gui/tv/MediaHeaderAdapter.kt

@ -30,11 +30,7 @@ class MediaHeaderAdapter(private val onHeaderSelected: OnHeaderSelected) : Recyc
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
<<<<<<< HEAD
if (sortType == Medialibrary.SORT_ALPHA || sortType == Medialibrary.SORT_DEFAULT) {
=======
if (sortType == AMedialibrary.SORT_ALPHA) {
>>>>>>> Medialibrary: move Medialibrary to AMedialibrary
if (sortType == AMedialibrary.SORT_ALPHA || sortType == AMedialibrary.SORT_DEFAULT) {
holder.binding.headerText = alphaItems[position]
holder.binding.hasContent = items.contains(alphaItems[position])
} else {
@ -44,11 +40,7 @@ class MediaHeaderAdapter(private val onHeaderSelected: OnHeaderSelected) : Recyc
}
fun getItem(position: Int): String {
<<<<<<< HEAD
return if (sortType == Medialibrary.SORT_ALPHA || sortType == Medialibrary.SORT_DEFAULT) {
=======
return if (sortType == AMedialibrary.SORT_ALPHA) {
>>>>>>> Medialibrary: move Medialibrary to AMedialibrary
return if (sortType == AMedialibrary.SORT_ALPHA || sortType == AMedialibrary.SORT_DEFAULT) {
alphaItems[position]
} else {
items[position]

2
vlc-android/src/org/videolan/vlc/gui/tv/TvUtil.kt

@ -118,7 +118,7 @@ object TvUtil {
MediaUtils.openMedia(activity, media)
}
fun playMedia(activity: Activity, media: List<MediaWrapper>) {
fun playMedia(activity: Activity, media: List<AbstractMediaWrapper>) {
val intent = Intent(activity, AudioPlayerActivity::class.java)
intent.putExtra(AudioPlayerActivity.MEDIA_LIST, ArrayList(media))
activity.startActivity(intent)

5
vlc-android/src/org/videolan/vlc/gui/tv/browser/BaseBrowserTvFragment.kt

@ -45,10 +45,7 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.song_browser.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.*
import org.videolan.medialibrary.interfaces.AMedialibrary
import org.videolan.medialibrary.interfaces.media.AMediaWrapper
import org.videolan.medialibrary.media.MediaLibraryItem

2
vlc-android/src/org/videolan/vlc/gui/tv/browser/FileBrowserTvFragment.kt

@ -69,7 +69,7 @@ class FileBrowserTvFragment : BaseBrowserTvFragment() {
if (BuildConfig.DEBUG) Log.d("FileBrowserTvFragment", "Submit lis of ${items.size} items")
//headers
val nbColumns = if ((viewModel as BrowserModel).sort == Medialibrary.SORT_ALPHA || (viewModel as BrowserModel).sort == Medialibrary.SORT_DEFAULT) 9 else 1
val nbColumns = if ((viewModel as BrowserModel).sort == AMedialibrary.SORT_ALPHA || (viewModel as BrowserModel).sort == AMedialibrary.SORT_DEFAULT) 9 else 1
headerList.layoutManager = GridLayoutManager(requireActivity(), nbColumns)
headerAdapter.sortType = (viewModel as BrowserModel).sort

2
vlc-android/src/org/videolan/vlc/gui/tv/browser/MediaBrowserTvFragment.kt

@ -67,7 +67,7 @@ class MediaBrowserTvFragment : BaseBrowserTvFragment() {
submitList(items)
//headers
val nbColumns = if ((viewModel as MediaBrowserViewModel).sort == Medialibrary.SORT_ALPHA || (viewModel as MediaBrowserViewModel).sort == Medialibrary.SORT_DEFAULT) 9 else 1
val nbColumns = if ((viewModel as MediaBrowserViewModel).sort == AMedialibrary.SORT_ALPHA || (viewModel as MediaBrowserViewModel).sort == AMedialibrary.SORT_DEFAULT) 9 else 1
headerList.layoutManager = GridLayoutManager(requireActivity(), nbColumns)
headerAdapter.sortType = (viewModel as MediaBrowserViewModel).sort

8
vlc-android/src/org/videolan/vlc/gui/tv/details/MediaListAdapter.kt

@ -10,8 +10,8 @@ import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.vlc.BuildConfig
import org.videolan.vlc.databinding.ActivityMediaListTvItemBinding
import org.videolan.vlc.gui.DiffUtilAdapter
@ -22,7 +22,7 @@ import org.videolan.vlc.interfaces.ITVEventsHandler
@ExperimentalCoroutinesApi
@ObsoleteCoroutinesApi
class MediaListAdapter(private val type: Int, private val listener: ITVEventsHandler) : DiffUtilAdapter<MediaWrapper, MediaListAdapter.MediaListViewHolder>(), TvFocusableAdapter {
class MediaListAdapter(private val type: Int, private val listener: ITVEventsHandler) : DiffUtilAdapter<AbstractMediaWrapper, MediaListAdapter.MediaListViewHolder>(), TvFocusableAdapter {
private var focusListener: FocusableRecyclerView.FocusListener? = null
@ -56,8 +56,8 @@ class MediaListAdapter(private val type: Int, private val listener: ITVEventsHan
override fun detectMoves() = true
override fun createCB(): DiffCallback<MediaWrapper> {
return object : DiffCallback<MediaWrapper>() {
override fun createCB(): DiffCallback<AbstractMediaWrapper> {
return object : DiffCallback<AbstractMediaWrapper>() {
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
if (newItemPosition == lastMovedItemFrom) {
lastMovedItemFrom = -1

1
vlc-android/src/org/videolan/vlc/providers/BrowserProvider.kt

@ -25,6 +25,7 @@ import android.net.Uri
import android.os.Handler
import android.os.HandlerThread
import android.os.Process
import android.util.Log
import androidx.collection.SimpleArrayMap
import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.*

4
vlc-android/src/org/videolan/vlc/viewmodels/tv/MainTvModel.kt

@ -73,7 +73,7 @@ class MainTvModel(app: Application) : AndroidViewModel(app), AMedialibrary.OnMed
val videos: LiveData<List<MediaLibraryItem>> = MutableLiveData()
val audioCategories: LiveData<List<MediaLibraryItem>> = MutableLiveData()
val browsers: LiveData<List<MediaLibraryItem>> = MutableLiveData()
val history: LiveData<List<MediaWrapper>> = MutableLiveData()
val history: LiveData<List<AMediaWrapper>> = MutableLiveData()
val playlist: LiveData<List<MediaLibraryItem>> = MutableLiveData()
private val nowPlayingDelegate = NowPlayingDelegate(this)
@ -150,7 +150,7 @@ class MainTvModel(app: Application) : AndroidViewModel(app), AMedialibrary.OnMed
private fun updatePlaylists() = launch {
context.getFromMl {
getPagedPlaylists(Medialibrary.SORT_INSERTIONDATE, true, NUM_ITEMS_PREVIEW, 0)
getPagedPlaylists(AMedialibrary.SORT_INSERTIONDATE, true, NUM_ITEMS_PREVIEW, 0)
}.let {
(playlist as MutableLiveData).value = mutableListOf<MediaLibraryItem>().apply {
// add(DummyItem(HEADER_PLAYLISTS, context.getString(R.string.playlists), ""))

Loading…
Cancel
Save