Commit 886eab98 authored by Thomas Guillem's avatar Thomas Guillem
Browse files

libvlc: Media: return null instead of a translated value

- libvlc shouldn't call vlc-android methods from introspection. Furthermore,
  getValueWrapper was not working since util.getValue() was gone.

- android-vlc shouldn't store translated values into database (what happens
  when user change language ?).

- bump DB_VERSION to 12 in order to remove translated values (and don't compare
  null with translated values).
parent a80072fb
......@@ -20,8 +20,6 @@
package org.videolan.libvlc;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Locale;
......@@ -169,10 +167,10 @@ public class Media implements Comparable<Media> {
private void extractTrackInfo(TrackInfo[] tracks) {
if (tracks == null) {
mTitle = null;
mArtist = getValueWrapper(null, UnknownStringType.Artist).trim();
mAlbum = getValueWrapper(null, UnknownStringType.Album).trim();
mGenre = getValueWrapper(null, UnknownStringType.Genre).trim();
mAlbumArtist = getValueWrapper(null, UnknownStringType.AlbumArtist).trim();
mArtist = null;
mAlbum = null;
mGenre = null;
mAlbumArtist = null;
return;
}
......@@ -186,10 +184,10 @@ public class Media implements Comparable<Media> {
} else if (track.Type == TrackInfo.TYPE_META) {
mLength = track.Length;
mTitle = track.Title != null ? track.Title.trim() : null;
mArtist = getValueWrapper(track.Artist, UnknownStringType.Artist).trim();
mAlbum = getValueWrapper(track.Album, UnknownStringType.Album).trim();
mGenre = getValueWrapper(track.Genre, UnknownStringType.Genre).trim();
mAlbumArtist = track.AlbumArtist;
mArtist = track.Artist != null ? track.Artist.trim() : null;
mAlbum = track.Album != null ? track.Album.trim() : null;
mGenre = track.Genre != null ? track.Genre.trim() : null;
mAlbumArtist = track.AlbumArtist != null ? track.AlbumArtist.trim() : null;
mArtworkURL = track.ArtworkURL;
mNowPlaying = track.NowPlaying;
if (!TextUtils.isEmpty(track.TrackNumber)) {
......@@ -234,74 +232,14 @@ public class Media implements Comparable<Media> {
mHeight = height;
mTitle = title;
mArtist = getValueWrapper(artist, UnknownStringType.Artist);
mGenre = getValueWrapper(genre, UnknownStringType.Genre);
mAlbum = getValueWrapper(album, UnknownStringType.Album);
mArtist = artist;
mGenre = genre;
mAlbum = album;
mAlbumArtist = albumArtist;
mArtworkURL = artworkURL;
mTrackNumber = trackNumber;
}
private enum UnknownStringType { Artist , Genre, Album, AlbumArtist };
/**
* Uses introspection to read VLC l10n databases, so that we can sever the
* hard-coded dependency gracefully for 3rd party libvlc apps while still
* maintaining good l10n in VLC for Android.
*
* @see org.videolan.vlc.util.Util#getValue(String, int)
*
* @param string The default string
* @param type Alias for R.string.xxx
* @return The default string if not empty or string from introspection
*/
private static String getValueWrapper(String string, UnknownStringType type) {
if(string != null && string.length() > 0) return string;
try {
Class<?> stringClass = Class.forName("org.videolan.vlc.R$string");
Class<?> utilClass = Class.forName("org.videolan.vlc.Util");
Integer value;
switch(type) {
case Album:
value = (Integer)stringClass.getField("unknown_album").get(null);
break;
case Genre:
value = (Integer)stringClass.getField("unknown_genre").get(null);
break;
case AlbumArtist:
value = (Integer)stringClass.getField("unknown_artist").get(null);
break;
case Artist:
default:
value = (Integer)stringClass.getField("unknown_artist").get(null);
break;
}
Method getValueMethod = utilClass.getDeclaredMethod("getValue", String.class, Integer.TYPE);
// Util.getValue(string, R.string.xxx);
return (String) getValueMethod.invoke(null, string, value);
} catch (ClassNotFoundException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (NoSuchFieldException e) {
} catch (NoSuchMethodException e) {
} catch (InvocationTargetException e) {
}
// VLC for Android translations not available (custom app perhaps)
// Use hardcoded English phrases.
switch(type) {
case Album:
return "Unknown Album";
case Genre:
return "Unknown Genre";
case Artist:
default:
return "Unknown Artist";
}
}
/**
* Compare the filenames to sort items
*/
......@@ -317,9 +255,9 @@ public class Media implements Comparable<Media> {
public void updateMeta(LibVLC libVLC) {
mTitle = libVLC.getMeta(libvlc_meta_Title);
mArtist = getValueWrapper(libVLC.getMeta(libvlc_meta_Artist), UnknownStringType.Artist);
mGenre = getValueWrapper(libVLC.getMeta(libvlc_meta_Genre), UnknownStringType.Genre);
mAlbum = getValueWrapper(libVLC.getMeta(libvlc_meta_Album), UnknownStringType.Album);
mArtist = libVLC.getMeta(libvlc_meta_Artist);
mGenre = libVLC.getMeta(libvlc_meta_Genre);
mAlbum = libVLC.getMeta(libvlc_meta_Album);
mNowPlaying = libVLC.getMeta(libvlc_meta_NowPlaying);
mArtworkURL = libVLC.getMeta(libvlc_meta_ArtworkURL);
}
......@@ -416,14 +354,6 @@ public class Media implements Comparable<Media> {
}
}
public String getSubtitle() {
return mType != TYPE_VIDEO ?
mNowPlaying != null ?
mNowPlaying
: mArtist + " - " + mAlbum
: "";
}
public String getReferenceArtist() {
return mAlbumArtist == null ? mArtist : mAlbumArtist;
}
......@@ -433,13 +363,13 @@ public class Media implements Comparable<Media> {
}
public Boolean isArtistUnknown() {
return (mArtist.equals(getValueWrapper(null, UnknownStringType.Artist)));
return mArtist == null;
}
public String getGenre() {
if(getValueWrapper(null, UnknownStringType.Genre).equals(mGenre))
return mGenre;
else if( mGenre.length() > 1)/* Make genres case insensitive via normalisation */
if (mGenre == null)
return null;
else if (mGenre.length() > 1)/* Make genres case insensitive via normalisation */
return Character.toUpperCase(mGenre.charAt(0)) + mGenre.substring(1).toLowerCase(Locale.getDefault());
else
return mGenre;
......@@ -458,7 +388,7 @@ public class Media implements Comparable<Media> {
}
public Boolean isAlbumUnknown() {
return (mAlbum.equals(getValueWrapper(null, UnknownStringType.Album)));
return mAlbum == null;
}
public int getTrackNumber() {
......
......@@ -51,7 +51,7 @@ public class MediaDatabase {
private SQLiteDatabase mDb;
private final String DB_NAME = "vlc_database";
private final int DB_VERSION = 11;
private final int DB_VERSION = 12;
private final int CHUNK_SIZE = 50;
private final String DIR_TABLE_NAME = "directories_table";
......@@ -467,6 +467,13 @@ public class MediaDatabase {
return true;
}
private static void safePut(ContentValues values, String key, String value) {
if (value == null)
values.putNull(key);
else
values.put(key, value);
}
/**
* Add a new media to the database. The picture can only added by update.
* @param media which you like to add to the database
......@@ -480,10 +487,10 @@ public class MediaDatabase {
values.put(MEDIA_LENGTH, media.getLength());
values.put(MEDIA_TYPE, media.getType());
values.put(MEDIA_TITLE, media.getTitle());
values.put(MEDIA_ARTIST, media.getArtist());
values.put(MEDIA_GENRE, media.getGenre());
values.put(MEDIA_ALBUM, media.getAlbum());
values.put(MEDIA_ALBUMARTIST, media.getAlbumArtist());
safePut(values, MEDIA_ARTIST, media.getArtist());
safePut(values, MEDIA_GENRE, media.getGenre());
safePut(values, MEDIA_ALBUM, media.getAlbum());
safePut(values, MEDIA_ALBUMARTIST, media.getAlbumArtist());
values.put(MEDIA_WIDTH, media.getWidth());
values.put(MEDIA_HEIGHT, media.getHeight());
values.put(MEDIA_ARTWORKURL, media.getArtworkURL());
......
......@@ -54,6 +54,7 @@ import org.videolan.vlc.gui.video.VideoPlayerActivity;
import org.videolan.vlc.interfaces.IAudioService;
import org.videolan.vlc.interfaces.IAudioServiceCallback;
import org.videolan.vlc.util.AndroidDevices;
import org.videolan.vlc.util.Util;
import org.videolan.vlc.util.VLCInstance;
import org.videolan.vlc.util.WeakHandler;
......@@ -730,8 +731,8 @@ public class AudioService extends Service {
return;
Bitmap cover = AudioUtil.getCover(this, media, 64);
String title = media.getTitle();
String artist = media.getArtist();
String album = media.getAlbum();
String artist = Util.getMediaArtist(this, media);
String album = Util.getMediaAlbum(this, media);
Notification notification;
if (media.isArtistUnknown() && media.isAlbumUnknown() && media.getNowPlaying() != null) {
......@@ -794,7 +795,7 @@ public class AudioService extends Service {
builder.setLargeIcon(cover == null ? BitmapFactory.decodeResource(getResources(), R.drawable.icon) : cover)
.setContentTitle(title)
.setContentText(LibVlcUtil.isJellyBeanOrLater() ? artist
: media.getSubtitle())
: Util.getMediaSubtitle(this, media))
.setContentInfo(album)
.setContentIntent(pendingIntent);
notification = builder.build();
......@@ -949,10 +950,10 @@ public class AudioService extends Service {
editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, media.getNowPlaying());
} else {
editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, "");
editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, media.getAlbum());
editor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, media.getArtist());
editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, Util.getMediaAlbum(this, media));
editor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, Util.getMediaArtist(this, media));
}
editor.putString(MediaMetadataRetriever.METADATA_KEY_GENRE, media.getGenre());
editor.putString(MediaMetadataRetriever.METADATA_KEY_GENRE, Util.getMediaGenre(this, media));
editor.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, media.getTitle());
editor.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, media.getLength());
// Copy the cover bitmap because the RemonteControlClient can recycle its artwork bitmap.
......@@ -964,8 +965,8 @@ public class AudioService extends Service {
//Send metadata to Pebble watch
if (mPebbleEnabled) {
final Intent i = new Intent("com.getpebble.action.NOW_PLAYING");
i.putExtra("artist", media.getArtist());
i.putExtra("album", media.getAlbum());
i.putExtra("artist", Util.getMediaArtist(this, media));
i.putExtra("album", Util.getMediaAlbum(this, media));
i.putExtra("track", media.getTitle());
sendBroadcast(i);
}
......@@ -1052,25 +1053,26 @@ public class AudioService extends Service {
@Override
public String getAlbum() throws RemoteException {
if (hasCurrentMedia())
return getCurrentMedia().getAlbum();
return Util.getMediaAlbum(AudioService.this, getCurrentMedia());
else
return null;
}
@Override
public String getArtist() throws RemoteException {
if (hasCurrentMedia())
return getCurrentMedia().isArtistUnknown() && getCurrentMedia().getNowPlaying() != null ?
getCurrentMedia().getNowPlaying()
: getCurrentMedia().getArtist();
else
if (hasCurrentMedia()) {
final Media media = getCurrentMedia();
return media.isArtistUnknown() && media.getNowPlaying() != null ?
media.getNowPlaying()
: Util.getMediaArtist(AudioService.this, media);
} else
return null;
}
@Override
public String getArtistPrev() throws RemoteException {
if (mPrevIndex != -1)
return mLibVLC.getMediaList().getMedia(mPrevIndex).getArtist();
return Util.getMediaArtist(AudioService.this, mLibVLC.getMediaList().getMedia(mPrevIndex));
else
return null;
}
......@@ -1078,7 +1080,7 @@ public class AudioService extends Service {
@Override
public String getArtistNext() throws RemoteException {
if (mNextIndex != -1)
return mLibVLC.getMediaList().getMedia(mNextIndex).getArtist();
return Util.getMediaArtist(AudioService.this, mLibVLC.getMediaList().getMedia(mNextIndex));
else
return null;
}
......@@ -1410,10 +1412,11 @@ public class AudioService extends Service {
i.setAction(ACTION_WIDGET_UPDATE);
if (hasCurrentMedia()) {
i.putExtra("title", getCurrentMedia().getTitle());
i.putExtra("artist", getCurrentMedia().isArtistUnknown() && getCurrentMedia().getNowPlaying() != null ?
getCurrentMedia().getNowPlaying()
: getCurrentMedia().getArtist());
final Media media = getCurrentMedia();
i.putExtra("title", media.getTitle());
i.putExtra("artist", media.isArtistUnknown() && media.getNowPlaying() != null ?
media.getNowPlaying()
: Util.getMediaArtist(this, media));
}
else {
i.putExtra("title", context.getString(R.string.widget_name));
......
......@@ -329,7 +329,7 @@ public class DirectoryAdapter extends BaseAdapter {
Log.d(TAG, "Loading media " + selectedNode.name);
Media m = new Media(LibVLC.getExistingInstance(), getMediaLocation(position));
holder.title.setText(m.getTitle());
holderText = m.getSubtitle();
holderText = Util.getMediaSubtitle(context, m);
} else
holder.title.setText(selectedNode.getVisibleName());
......
......@@ -27,6 +27,7 @@ import org.videolan.libvlc.Media;
import org.videolan.vlc.R;
import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.gui.audio.AudioUtil;
import org.videolan.vlc.util.Util;
import org.videolan.vlc.util.WeakHandler;
import android.content.Context;
......@@ -99,7 +100,7 @@ public class HistoryAdapter extends BaseAdapter {
Log.d(TAG, "Loading media position " + position + " - " + m.getTitle());
holder.title.setText(m.getTitle());
holderText = m.getSubtitle();
holderText = Util.getMediaSubtitle(VLCApplication.getAppContext(), m);
holder.text.setText(holderText);
Bitmap b = AudioUtil.getCover(VLCApplication.getAppContext(), m, 64);
......
......@@ -32,6 +32,7 @@ import org.videolan.vlc.audio.AudioServiceController;
import org.videolan.vlc.gui.CommonDialogs;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.util.AndroidDevices;
import org.videolan.vlc.util.Util;
import org.videolan.vlc.util.VLCRunnable;
import org.videolan.vlc.widget.FlingViewGroup;
......@@ -355,9 +356,9 @@ public class AudioAlbumsSongsFragment extends Fragment implements SwipeRefreshLa
public void run() {
for (int i = 0; i < mediaList.size(); ++i) {
Media media = mediaList.get(i);
mAlbumsAdapter.addSeparator(media.getReferenceArtist(), media);
mAlbumsAdapter.add(media.getAlbum(), null, media);
mSongsAdapter.addSeparator(media.getAlbum(), media);
mAlbumsAdapter.addSeparator(Util.getMediaReferenceArtist(activity, media), media);
mAlbumsAdapter.add(Util.getMediaAlbum(activity, media), null, media);
mSongsAdapter.addSeparator(Util.getMediaAlbum(activity, media), media);
}
mSongsAdapter.sortByAlbum();
mAlbumsAdapter.notifyDataSetChanged();
......
......@@ -59,6 +59,7 @@ import org.videolan.vlc.gui.CommonDialogs;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.interfaces.IBrowser;
import org.videolan.vlc.util.AndroidDevices;
import org.videolan.vlc.util.Util;
import org.videolan.vlc.util.VLCRunnable;
import org.videolan.vlc.util.WeakHandler;
import org.videolan.vlc.widget.FlingViewGroup;
......@@ -305,7 +306,7 @@ public class AudioBrowserFragment extends Fragment implements SwipeRefreshLayout
MainActivity activity = (MainActivity)getActivity();
AudioAlbumsSongsFragment frag = (AudioAlbumsSongsFragment)activity.showSecondaryFragment("albumsSongs");
if (frag != null) {
frag.setMediaList(mediaList, mediaList.get(0).getArtist());
frag.setMediaList(mediaList, Util.getMediaArtist(activity, mediaList.get(0)));
}
}
};
......@@ -325,7 +326,7 @@ public class AudioBrowserFragment extends Fragment implements SwipeRefreshLayout
MainActivity activity = (MainActivity)getActivity();
AudioAlbumsSongsFragment frag = (AudioAlbumsSongsFragment)activity.showSecondaryFragment("albumsSongs");
if (frag != null) {
frag.setMediaList(mediaList, mediaList.get(0).getGenre());
frag.setMediaList(mediaList, Util.getMediaGenre(activity, mediaList.get(0)));
}
}
};
......
......@@ -132,23 +132,24 @@ public class AudioBrowserListAdapter extends BaseAdapter implements SectionIndex
for (Media media : list) {
switch (type){
case TYPE_ALBUMS:
title = media.getAlbum();
subTitle = media.getReferenceArtist();
title = Util.getMediaAlbum(mContext, media);
subTitle = Util.getMediaReferenceArtist(mContext, media);
break;
case TYPE_ARTISTS:
title = media.getReferenceArtist();
title = Util.getMediaReferenceArtist(mContext, media);
subTitle = null;
break;
case TYPE_GENRES:
title = media.getGenre();
title = Util.getMediaGenre(mContext, media);
subTitle = null;
break;
case TYPE_SONGS:
default:
title = media.getTitle();
subTitle = media.getArtist();
subTitle = Util.getMediaArtist(mContext, media);
}
if (title == null) return;
if (title == null)
continue;
title = title.trim();
if (subTitle != null) subTitle = subTitle.trim();
if (mMediaItemMap.containsKey(title))
......
......@@ -109,7 +109,7 @@ public class AudioPlaylistAdapter extends ArrayAdapter<Media> {
Media media = getItem(position);
final String title = media.getTitle();
final String artist = media.getSubtitle();
final String artist = Util.getMediaSubtitle(mContext, media);
final int pos = position;
final View itemView = v;
......
......@@ -180,8 +180,8 @@ public class AudioUtil {
return Uri.decode(artworkURL).replace("file://", "");
} else if(artworkURL != null && artworkURL.startsWith("attachment://")) {
// Decode if the album art is embedded in the file
String mArtist = media.getArtist();
String mAlbum = media.getAlbum();
String mArtist = Util.getMediaArtist(context, media);
String mAlbum = Util.getMediaAlbum(context, media);
/* Parse decoded attachment */
if( mArtist.length() == 0 || mAlbum.length() == 0 ||
......@@ -237,7 +237,7 @@ public class AudioUtil {
try {
// try to load from cache
int hash = MurmurHash.hash32(media.getArtist()+media.getAlbum());
int hash = MurmurHash.hash32(Util.getMediaArtist(context, media)+Util.getMediaAlbum(context, media));
cachePath = COVER_DIR + (hash >= 0 ? "" + hash : "m" + (-hash)) + "_" + width;
// try to get the cover from the LRUCache first
......
......@@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.R;
import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.VLCCallbackTask;
import org.videolan.vlc.audio.AudioServiceController;
......@@ -184,4 +185,56 @@ public class Util {
};
task.execute();
}
private static String getMediaString(Context ctx, int id) {
if (ctx != null)
return ctx.getResources().getString(id);
else {
switch (id) {
case R.string.unknown_artist:
return "Unknown Artist";
case R.string.unknown_album:
return "Unknown Album";
case R.string.unknown_genre:
return "Unknown Genre";
default:
return "";
}
}
}
public static String getMediaArtist(Context ctx, Media media) {
final String artist = media.getArtist();
return artist != null ? artist : getMediaString(ctx, R.string.unknown_artist);
}
public static String getMediaReferenceArtist(Context ctx, Media media) {
final String artist = media.getReferenceArtist();
return artist != null ? artist : getMediaString(ctx, R.string.unknown_artist);
}
public static String getMediaAlbumArtist(Context ctx, Media media) {
final String albumArtist = media.getAlbumArtist();
return albumArtist != null ? albumArtist : getMediaString(ctx, R.string.unknown_artist);
}
public static String getMediaAlbum(Context ctx, Media media) {
final String album = media.getAlbum();
return album != null ? album : getMediaString(ctx, R.string.unknown_album);
}
public static String getMediaGenre(Context ctx, Media media) {
final String genre = media.getGenre();
return genre != null ? genre : getMediaString(ctx, R.string.unknown_genre);
}
public static String getMediaSubtitle(Context ctx, Media media) {
if (media.getType() == Media.TYPE_VIDEO)
return "";
else
return media.getNowPlaying() != null
? media.getNowPlaying()
: getMediaArtist(ctx, media) + " - " + getMediaAlbum(ctx, media);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment