Add EventServer configuration options in wizard and host editing.

This commit is contained in:
Synced Synapse 2015-06-21 15:04:54 +01:00
parent a429ec17b4
commit 68ab545651
14 changed files with 585 additions and 270 deletions

View File

@ -91,4 +91,8 @@ public interface Settings {
// Current host id
public static final String KEY_PREF_CURRENT_HOST_ID = "current_host_id";
public static final int DEFAULT_PREF_CURRENT_HOST_ID = -1;
public static final String KEY_PREF_CHECKED_EVENT_SERVER_CONNECTION = "checked_event_server_connection";
public static final boolean DEFAULT_PREF_CHECKED_EVENT_SERVER_CONNECTION = false;
}

View File

@ -21,6 +21,10 @@ import android.os.*;
import android.os.Process;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.jsonrpc.ApiCallback;
import org.xbmc.kore.jsonrpc.HostConnection;
import org.xbmc.kore.jsonrpc.method.Application;
import org.xbmc.kore.jsonrpc.type.ApplicationType;
import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.Utils;
@ -67,10 +71,10 @@ public class EventServerConnection {
};
/**
* Interface to notify users if the connection was sucessfull
* Interface to notify users if the connection was successful
*/
public interface EventServerConnectionCallback {
void OnConnect(boolean success);
void OnConnectResult(boolean success);
}
/**
@ -98,13 +102,10 @@ public class EventServerConnection {
LogUtils.LOGD(TAG, "Got an UnknownHostException, disabling EventServer");
hostInetAddress = null;
}
callback.OnConnect(hostInetAddress != null);
callback.OnConnectResult(hostInetAddress != null);
}
});
// Send Hello Packet
// sendPacket(new PacketHELO(DEVICE_NAME));
// Start pinging
commHandler.postDelayed(pingRunnable, PING_INTERVAL);
}
@ -113,14 +114,9 @@ public class EventServerConnection {
/**
* Stops the HandlerThread that is being used to send packets to Kodi
*/
@SuppressLint("NewApi")
public void quit() {
LogUtils.LOGD(TAG, "Quiting EventServer handler thread");
if (Utils.isJellybeanMR2OrLater()) {
handlerThread.quitSafely();
} else {
handlerThread.quit();
}
quitHandlerThread(handlerThread);
}
/**
@ -146,4 +142,137 @@ public class EventServerConnection {
}
});
}
/**
* Establishes a connection to the EventServer and reports the result
* @param hostInfo Host to connect to
* @param callerCallback Callback on which to post the result
* @param callerHandler Handler on which to post the callback call
*/
public static void testEventServerConnection(final HostInfo hostInfo,
final EventServerConnectionCallback callerCallback,
final Handler callerHandler) {
final HandlerThread auxThread = new HandlerThread("EventServerConnectionTest", Process.THREAD_PRIORITY_DEFAULT);
auxThread.start();
// Get the HandlerThread's Looper and use it for our Handler
final Handler auxHandler = new Handler(auxThread.getLooper());
auxHandler.post(new Runnable() {
@Override
public void run() {
// Get the InetAddress
final InetAddress hostInetAddress;
try {
hostInetAddress = InetAddress.getByName(hostInfo.getAddress());
} catch (UnknownHostException exc) {
LogUtils.LOGD(TAG, "Couldn't get host InetAddress");
reportTestResult(callerHandler, callerCallback, false);
quitHandlerThread(auxThread);
return;
}
// Send a HELO packet
Packet p = new PacketHELO(DEVICE_NAME);
try {
p.send(hostInetAddress, hostInfo.getEventServerPort());
} catch (IOException exc) {
LogUtils.LOGD(TAG, "Couldn't send HELO packet to host");
reportTestResult(callerHandler, callerCallback, false);
quitHandlerThread(auxThread);
return;
}
// The previous checks don't really test the connection, as this is UDP. Apart from checking if
// any HostUnreachable ICMP message is returned (which may or may not happen), there's no direct way
// to check if the messages were delivered, so the solution is to force something to happen on
// Kodi and them read Kodi's state to check if it was applied.
// We are going to get the mute status of Kodi via jsonrpc, change it via EventServer and check if
// it was changed via jsonrpc, reverting it back afterwards
final HostConnection auxHostConnection = new HostConnection(
new HostInfo(hostInfo.getName(), hostInfo.getAddress(),
HostConnection.PROTOCOL_HTTP, hostInfo.getHttpPort(), hostInfo.getTcpPort(),
hostInfo.getUsername(), hostInfo.getPassword(), false, 0));
final Application.GetProperties action = new Application.GetProperties(Application.GetProperties.MUTED);
final Packet mutePacket = new PacketBUTTON(ButtonCodes.MAP_REMOTE, ButtonCodes.REMOTE_MUTE,
false, true, true, (short) 0, (byte) 0);
// Get the initial mute status
action.execute(auxHostConnection, new ApiCallback<ApplicationType.PropertyValue>() {
@Override
public void onSuccess(ApplicationType.PropertyValue result) {
final boolean initialMuteStatus = result.muted;
// Switch mute status
try {
mutePacket.send(hostInetAddress, hostInfo.getEventServerPort());
} catch (IOException exc) {
LogUtils.LOGD(TAG, "Couldn't send first MUTE packet to host");
reportTestResult(callerHandler, callerCallback, false);
quitHandlerThread(auxThread);
return;
}
// Sleep a while to make sure the previous command was executed
try {
Thread.sleep(2000);
} catch (InterruptedException exc) {
// Ignore
}
// Now get the new status and compare
action.execute(auxHostConnection, new ApiCallback<ApplicationType.PropertyValue>() {
@Override
public void onSuccess(ApplicationType.PropertyValue result) {
// Report result (mute status is different)
reportTestResult(callerHandler, callerCallback, initialMuteStatus != result.muted);
// Revert mute status
try {
mutePacket.send(hostInetAddress, hostInfo.getEventServerPort());
} catch (IOException exc) {
LogUtils.LOGD(TAG, "Couldn't revert MUTE status");
}
quitHandlerThread(auxThread);
}
@Override
public void onError(int errorCode, String description) {
LogUtils.LOGD(TAG, "Got an error on Application.GetProperties: " + description);
reportTestResult(callerHandler, callerCallback, false);
quitHandlerThread(auxThread);
}
}, auxHandler);
}
@Override
public void onError(int errorCode, String description) {
LogUtils.LOGD(TAG, "Got an error on Application.GetProperties: " + description);
reportTestResult(callerHandler, callerCallback, false);
quitHandlerThread(auxThread);
}
}, auxHandler);
}
});
}
private static void reportTestResult(final Handler callerHandler,
final EventServerConnectionCallback callback,
final boolean result) {
callerHandler.post(new Runnable() {
@Override
public void run() {
callback.OnConnectResult(result);
}
});
}
@SuppressLint("NewApi")
private static void quitHandlerThread(HandlerThread handlerThread) {
if (Utils.isJellybeanMR2OrLater()) {
handlerThread.quitSafely();
} else {
handlerThread.quit();
}
}
}

View File

@ -65,6 +65,8 @@ public class HostInfo {
private String address;
private int httpPort;
private int tcpPort;
private boolean useEventServer;
private int eventServerPort;
/**
@ -99,7 +101,8 @@ public class HostInfo {
* @param password Password for basic auth
*/
public HostInfo(int id, String name, String address, int protocol, int httpPort, int tcpPort,
String username, String password, String macAddress, int wolPort) {
String username, String password, String macAddress, int wolPort,
boolean useEventServer, int eventServerPort) {
this.id = id;
this.name = name;
this.address = address;
@ -114,7 +117,8 @@ public class HostInfo {
this.macAddress = macAddress;
this.wolPort = wolPort;
this.eventServerPort = DEFAULT_EVENT_SERVER_PORT;
this.useEventServer = useEventServer;
this.eventServerPort = eventServerPort;
// For performance reasons
this.auxImageHttpAddress = getHttpURL() + "/image/";
@ -132,12 +136,13 @@ public class HostInfo {
* @param password Password for basic auth
*/
public HostInfo(String name, String address, int protocol, int httpPort,
int tcpPort, String username, String password) {
int tcpPort, String username, String password,
boolean useEventServer, int eventServerPort) {
this(-1, name, address, protocol, httpPort, tcpPort, username,
password, null, DEFAULT_WOL_PORT);
password, null, DEFAULT_WOL_PORT, useEventServer, eventServerPort);
}
public int getId() {
public int getId() {
return id;
}
@ -185,6 +190,10 @@ public class HostInfo {
return protocol;
}
public boolean getUseEventServer() {
return useEventServer;
}
public int getEventServerPort() {
return eventServerPort;
}
@ -200,6 +209,14 @@ public class HostInfo {
this.protocol = protocol;
}
/**
* Overrides the use of EventServer
* @param useEventServer Whether to use EventServer
*/
public void setUseEventServer(boolean useEventServer) {
this.useEventServer = useEventServer;
}
/**
* Returns the URL of the host
* @return HTTP URL eg. http://192.168.1.1:8080

View File

@ -142,9 +142,11 @@ public class HostManager {
String password = cursor.getString(idx++);
String macAddress = cursor.getString(idx++);
int wolPort = cursor.getInt(idx++);
boolean useEventServer = (cursor.getInt(idx++) != 0);
int eventServerPort = cursor.getInt(idx++);
hosts.add(new HostInfo(id, name, address, protocol, httpPort, tcpPort,
username, password, macAddress, wolPort));
username, password, macAddress, wolPort, useEventServer, eventServerPort));
}
}
cursor.close();
@ -307,9 +309,10 @@ public class HostManager {
*/
public HostInfo addHost(HostInfo hostInfo) {
return addHost(hostInfo.getName(), hostInfo.getAddress(), hostInfo.getProtocol(),
hostInfo.getHttpPort(), hostInfo.getTcpPort(),
hostInfo.getUsername(), hostInfo.getPassword(),
hostInfo.getMacAddress(), hostInfo.getWolPort());
hostInfo.getHttpPort(), hostInfo.getTcpPort(),
hostInfo.getUsername(), hostInfo.getPassword(),
hostInfo.getMacAddress(), hostInfo.getWolPort(),
hostInfo.getUseEventServer(), hostInfo.getEventServerPort());
}
@ -325,7 +328,8 @@ public class HostManager {
* @return Newly created {@link org.xbmc.kore.host.HostInfo}
*/
public HostInfo addHost(String name, String address, int protocol, int httpPort, int tcpPort,
String username, String password, String macAddress, int wolPort) {
String username, String password, String macAddress, int wolPort,
boolean useEventServer, int eventServerPort) {
ContentValues values = new ContentValues();
values.put(MediaContract.HostsColumns.NAME, name);
@ -337,6 +341,8 @@ public class HostManager {
values.put(MediaContract.HostsColumns.PASSWORD, password);
values.put(MediaContract.HostsColumns.MAC_ADDRESS, macAddress);
values.put(MediaContract.HostsColumns.WOL_PORT, wolPort);
values.put(MediaContract.HostsColumns.USE_EVENT_SERVER, useEventServer);
values.put(MediaContract.HostsColumns.EVENT_SERVER_PORT, eventServerPort);
Uri newUri = context.getContentResolver()
.insert(MediaContract.Hosts.CONTENT_URI, values);
@ -371,6 +377,8 @@ public class HostManager {
values.put(MediaContract.HostsColumns.PASSWORD, newHostInfo.getPassword());
values.put(MediaContract.HostsColumns.MAC_ADDRESS, newHostInfo.getMacAddress());
values.put(MediaContract.HostsColumns.WOL_PORT, newHostInfo.getWolPort());
values.put(MediaContract.HostsColumns.USE_EVENT_SERVER, newHostInfo.getUseEventServer());
values.put(MediaContract.HostsColumns.EVENT_SERVER_PORT, newHostInfo.getEventServerPort());
context.getContentResolver()
.update(MediaContract.Hosts.buildHostUri(hostId), values, null, null);

View File

@ -54,15 +54,17 @@ public class MediaContract {
* Columns for table HOSTS
*/
public interface HostsColumns {
public final static String NAME = "name";
public final static String ADDRESS = "address";
public final static String PROTOCOL = "protocol";
public final static String HTTP_PORT = "http_port";
public final static String TCP_PORT = "tcp_port";
public final static String USERNAME = "username";
public final static String PASSWORD = "password";
public final static String MAC_ADDRESS = "mac_address";
public final static String WOL_PORT = "wol_port";
String NAME = "name";
String ADDRESS = "address";
String PROTOCOL = "protocol";
String HTTP_PORT = "http_port";
String TCP_PORT = "tcp_port";
String USERNAME = "username";
String PASSWORD = "password";
String MAC_ADDRESS = "mac_address";
String WOL_PORT = "wol_port";
String USE_EVENT_SERVER = "use_event_server";
String EVENT_SERVER_PORT = "event_server_port";
}
public static class Hosts implements BaseColumns, SyncColumns, HostsColumns {
@ -86,7 +88,7 @@ public class MediaContract {
public final static String[] ALL_COLUMNS = {
_ID, UPDATED, NAME, ADDRESS, PROTOCOL, HTTP_PORT, TCP_PORT, USERNAME, PASSWORD,
MAC_ADDRESS, WOL_PORT
MAC_ADDRESS, WOL_PORT, USE_EVENT_SERVER, EVENT_SERVER_PORT
};
}
@ -95,40 +97,40 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + MOVIEID
*/
public interface MoviesColumns {
public final static String HOST_ID = "host_id";
public final static String MOVIEID = "movieid";
String HOST_ID = "host_id";
String MOVIEID = "movieid";
public final static String FANART = "fanart";
public final static String THUMBNAIL = "thumbnail";
public final static String PLAYCOUNT = "playcount";
public final static String TITLE = "title";
public final static String FILE = "file";
public final static String PLOT = "plot";
public final static String DIRECTOR = "director";
public final static String RUNTIME = "runtime";
public final static String AUDIO_CHANNELS = "audio_channels";
public final static String AUDIO_CODEC = "audio_coded";
public final static String AUDIO_LANGUAGE = "audio_language";
public final static String SUBTITLES_LANGUAGES = "subtitles_languages";
public static final String VIDEO_ASPECT = "video_aspect";
public static final String VIDEO_CODEC = "video_codec";
public static final String VIDEO_HEIGHT = "video_height";
public static final String VIDEO_WIDTH = "video_width";
public static final String COUNTRIES = "countries";
public static final String GENRES = "genres";
public static final String IMDBNUMBER = "imdbnumber";
public static final String MPAA = "mpaa";
public static final String RATING = "rating";
public static final String SET = "movie_set";
public static final String SETID = "setid";
public static final String STUDIOS = "studios";
public static final String TAGLINE = "tagline";
public static final String TOP250 = "top250";
public static final String TRAILER = "trailer";
public static final String VOTES = "votes";
public static final String WRITERS = "writers";
public static final String YEAR = "year";
public static final String DATEADDED = "dateadded";
String FANART = "fanart";
String THUMBNAIL = "thumbnail";
String PLAYCOUNT = "playcount";
String TITLE = "title";
String FILE = "file";
String PLOT = "plot";
String DIRECTOR = "director";
String RUNTIME = "runtime";
String AUDIO_CHANNELS = "audio_channels";
String AUDIO_CODEC = "audio_coded";
String AUDIO_LANGUAGE = "audio_language";
String SUBTITLES_LANGUAGES = "subtitles_languages";
String VIDEO_ASPECT = "video_aspect";
String VIDEO_CODEC = "video_codec";
String VIDEO_HEIGHT = "video_height";
String VIDEO_WIDTH = "video_width";
String COUNTRIES = "countries";
String GENRES = "genres";
String IMDBNUMBER = "imdbnumber";
String MPAA = "mpaa";
String RATING = "rating";
String SET = "movie_set";
String SETID = "setid";
String STUDIOS = "studios";
String TAGLINE = "tagline";
String TOP250 = "top250";
String TRAILER = "trailer";
String VOTES = "votes";
String WRITERS = "writers";
String YEAR = "year";
String DATEADDED = "dateadded";
}
public static class Movies implements BaseColumns, SyncColumns, MoviesColumns {
@ -174,13 +176,13 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + MOVIEID + NAME
*/
public interface MovieCastColumns {
public final static String HOST_ID = "host_id";
public final static String MOVIEID = "movieid";
public final static String NAME = "name";
String HOST_ID = "host_id";
String MOVIEID = "movieid";
String NAME = "name";
public final static String ORDER = "cast_order";
public final static String ROLE = "role";
public final static String THUMBNAIL = "thumbnail";
String ORDER = "cast_order";
String ROLE = "role";
String THUMBNAIL = "thumbnail";
}
public static class MovieCast implements BaseColumns, SyncColumns, MovieCastColumns {
@ -205,24 +207,24 @@ public class MediaContract {
* For XBMC reference use HOST_ID + TVSHOWID
*/
public interface TVShowsColumns {
public final static String HOST_ID = "host_id";
public final static String TVSHOWID = "tvshowid";
String HOST_ID = "host_id";
String TVSHOWID = "tvshowid";
public static final String FANART = "fanart";
public static final String THUMBNAIL = "thumbnail";
public static final String PLAYCOUNT = "playcount";
public static final String TITLE = "title";
public static final String DATEADDED = "dateadded";
public static final String FILE = "file";
public static final String PLOT = "plot";
public static final String EPISODE = "episode";
public static final String IMDBNUMBER = "imdbnumber";
public static final String MPAA = "mpaa";
public static final String PREMIERED = "premiered";
public static final String RATING = "rating";
public static final String STUDIO = "studio";
public static final String WATCHEDEPISODES = "watchedepisodes";
public static final String GENRES = "genres";
String FANART = "fanart";
String THUMBNAIL = "thumbnail";
String PLAYCOUNT = "playcount";
String TITLE = "title";
String DATEADDED = "dateadded";
String FILE = "file";
String PLOT = "plot";
String EPISODE = "episode";
String IMDBNUMBER = "imdbnumber";
String MPAA = "mpaa";
String PREMIERED = "premiered";
String RATING = "rating";
String STUDIO = "studio";
String WATCHEDEPISODES = "watchedepisodes";
String GENRES = "genres";
}
public static class TVShows implements BaseColumns, SyncColumns, TVShowsColumns {
@ -266,13 +268,13 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + TVSHOWID + NAME
*/
public interface TVShowCastColumns {
public final static String HOST_ID = "host_id";
public final static String TVSHOWID = "tvshowid";
public final static String NAME = "name";
String HOST_ID = "host_id";
String TVSHOWID = "tvshowid";
String NAME = "name";
public final static String ORDER = "cast_order";
public final static String ROLE = "role";
public final static String THUMBNAIL = "thumbnail";
String ORDER = "cast_order";
String ROLE = "role";
String THUMBNAIL = "thumbnail";
}
public static class TVShowCast implements BaseColumns, SyncColumns, TVShowCastColumns {
@ -297,16 +299,16 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + TVSHOWID + SEASON
*/
public interface SeasonsColumns {
public final static String HOST_ID = "host_id";
public final static String TVSHOWID = "tvshowid";
public static final String SEASON = "season";
String HOST_ID = "host_id";
String TVSHOWID = "tvshowid";
String SEASON = "season";
public static final String LABEL = "label";
public static final String FANART = "fanart";
public static final String THUMBNAIL = "thumbnail";
public static final String EPISODE = "episode";
public static final String SHOWTITLE = "showtitle";
public static final String WATCHEDEPISODES = "watchedepisodes";
String LABEL = "label";
String FANART = "fanart";
String THUMBNAIL = "thumbnail";
String EPISODE = "episode";
String SHOWTITLE = "showtitle";
String WATCHEDEPISODES = "watchedepisodes";
}
public static class Seasons implements BaseColumns, SyncColumns, SeasonsColumns {
@ -350,34 +352,34 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + EPISODEID
*/
public interface EpisodesColumns {
public final static String HOST_ID = "host_id";
public static final String EPISODEID = "episodeid";
String HOST_ID = "host_id";
String EPISODEID = "episodeid";
public final static String TVSHOWID = "tvshowid";
public static final String SEASON = "season";
public static final String EPISODE = "episode";
String TVSHOWID = "tvshowid";
String SEASON = "season";
String EPISODE = "episode";
public static final String FANART = "fanart";
public static final String THUMBNAIL = "thumbnail";
public static final String PLAYCOUNT = "playcount";
public static final String TITLE = "title";
public static final String DATEADDED = "dateadded";
public static final String FILE = "file";
public static final String PLOT = "plot";
public static final String DIRECTOR = "director";
public static final String RUNTIME = "runtime";
public static final String FIRSTAIRED = "firstaired";
public static final String RATING = "rating";
public static final String SHOWTITLE = "showtitle";
public static final String WRITER = "writer";
public final static String AUDIO_CHANNELS = "audio_channels";
public final static String AUDIO_CODEC = "audio_coded";
public final static String AUDIO_LANGUAGE = "audio_language";
public final static String SUBTITLES_LANGUAGES = "subtitles_languages";
public static final String VIDEO_ASPECT = "video_aspect";
public static final String VIDEO_CODEC = "video_codec";
public static final String VIDEO_HEIGHT = "video_height";
public static final String VIDEO_WIDTH = "video_width";
String FANART = "fanart";
String THUMBNAIL = "thumbnail";
String PLAYCOUNT = "playcount";
String TITLE = "title";
String DATEADDED = "dateadded";
String FILE = "file";
String PLOT = "plot";
String DIRECTOR = "director";
String RUNTIME = "runtime";
String FIRSTAIRED = "firstaired";
String RATING = "rating";
String SHOWTITLE = "showtitle";
String WRITER = "writer";
String AUDIO_CHANNELS = "audio_channels";
String AUDIO_CODEC = "audio_coded";
String AUDIO_LANGUAGE = "audio_language";
String SUBTITLES_LANGUAGES = "subtitles_languages";
String VIDEO_ASPECT = "video_aspect";
String VIDEO_CODEC = "video_codec";
String VIDEO_HEIGHT = "video_height";
String VIDEO_WIDTH = "video_width";
}
public static class Episodes implements BaseColumns, SyncColumns, EpisodesColumns {
@ -443,14 +445,14 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + ARTISTID
*/
public interface ArtistsColumns {
public final static String HOST_ID = "host_id";
public static final String ARTISTID = "artistid";
String HOST_ID = "host_id";
String ARTISTID = "artistid";
public static final String ARTIST = "artist";
public final String DESCRIPTION = "description";
public final String GENRE = "genre";
public final String FANART = "fanart";
public final String THUMBNAIL = "thumbnail";
String ARTIST = "artist";
String DESCRIPTION = "description";
String GENRE = "genre";
String FANART = "fanart";
String THUMBNAIL = "thumbnail";
}
public static class Artists implements BaseColumns, SyncColumns, ArtistsColumns {
@ -492,19 +494,19 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + ALBUMID
*/
public interface AlbumsColumns {
public final static String HOST_ID = "host_id";
public static final String ALBUMID = "albumid";
String HOST_ID = "host_id";
String ALBUMID = "albumid";
public static final String FANART = "fanart";
public static final String THUMBNAIL = "thumbnail";
public static final String DISPLAYARTIST = "displayartist";
public static final String RATING = "rating";
public static final String TITLE = "title";
public static final String YEAR = "year";
public static final String ALBUMLABEL = "albumlabel";
public static final String DESCRIPTION = "description";
public static final String PLAYCOUNT = "playcount";
public static final String GENRE = "genre";
String FANART = "fanart";
String THUMBNAIL = "thumbnail";
String DISPLAYARTIST = "displayartist";
String RATING = "rating";
String TITLE = "title";
String YEAR = "year";
String ALBUMLABEL = "albumlabel";
String DESCRIPTION = "description";
String PLAYCOUNT = "playcount";
String GENRE = "genre";
}
public static class Albums implements BaseColumns, SyncColumns, AlbumsColumns {
@ -565,15 +567,15 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + ALBUMID + SONGID
*/
public interface SongsColumns {
public final static String HOST_ID = "host_id";
public static final String ALBUMID = "albumid";
public static final String SONGID = "songid";
String HOST_ID = "host_id";
String ALBUMID = "albumid";
String SONGID = "songid";
public static final String DURATION = "duration";
public static final String THUMBNAIL = "thumbnail";
public static final String FILE = "file";
public static final String TRACK = "track";
public static final String TITLE = "title";
String DURATION = "duration";
String THUMBNAIL = "thumbnail";
String FILE = "file";
String TRACK = "track";
String TITLE = "title";
}
public static class Songs implements BaseColumns, SyncColumns, SongsColumns {
@ -615,11 +617,11 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + GENREID
*/
public interface AudioGenresColumns {
public final static String HOST_ID = "host_id";
public static final String GENREID = "genreid";
String HOST_ID = "host_id";
String GENREID = "genreid";
public static final String THUMBNAIL = "thumbnail";
public static final String TITLE = "title";
String THUMBNAIL = "thumbnail";
String TITLE = "title";
}
public static class AudioGenres implements BaseColumns, SyncColumns, AudioGenresColumns {
@ -661,9 +663,9 @@ public class MediaContract {
* All Other IDs refer to XBMC Ids, not Internal ones
*/
public interface AlbumArtistsColumns {
public final static String HOST_ID = "host_id";
public static final String ALBUMID = "albumid";
public static final String ARTISTID = "artistid";
String HOST_ID = "host_id";
String ALBUMID = "albumid";
String ARTISTID = "artistid";
}
public static class AlbumArtists implements BaseColumns, AlbumArtistsColumns {
@ -691,9 +693,9 @@ public class MediaContract {
* All Other IDs refer to XBMC Ids, not Internal ones
*/
public interface AlbumGenresColumns {
public final static String HOST_ID = "host_id";
public static final String ALBUMID = "albumid";
public static final String GENREID = "genreid";
String HOST_ID = "host_id";
String ALBUMID = "albumid";
String GENREID = "genreid";
}
public static class AlbumGenres implements BaseColumns, AlbumGenresColumns {
@ -721,51 +723,51 @@ public class MediaContract {
* For XBMC reference/unique key use HOST_ID + MUSICVIDEOID
*/
public interface MusicVideosColumns {
public final static String HOST_ID = "host_id";
public final static String MUSICVIDEOID = "musicvideoid";
String HOST_ID = "host_id";
String MUSICVIDEOID = "musicvideoid";
// ItemType.DetailsBase
//public static final String LABEL = "label";
//String LABEL = "label";
// MediaType.DetailsBase
public static final String FANART = "fanart";
public static final String THUMBNAIL = "thumbnail";
String FANART = "fanart";
String THUMBNAIL = "thumbnail";
// DetailsBase
//public static final String ART = "art";
public static final String PLAYCOUNT = "playcount";
//String ART = "art";
String PLAYCOUNT = "playcount";
// DetailsMedia
public static final String TITLE = "title";
String TITLE = "title";
// DetailsItem
//public static final String DATEADDED = "dateadded";
public static final String FILE = "file";
//public static final String LASTPLAYED = "lastplayed";
public static final String PLOT = "plot";
//String DATEADDED = "dateadded";
String FILE = "file";
//String LASTPLAYED = "lastplayed";
String PLOT = "plot";
// DetailsFile
public static final String DIRECTOR = "director";
//public static final String RESUME = "resume";
public static final String RUNTIME = "runtime";
//public static final String STREAMDETAILS = "streamdetails";
public final static String AUDIO_CHANNELS = "audio_channels";
public final static String AUDIO_CODEC = "audio_coded";
public final static String AUDIO_LANGUAGE = "audio_language";
public final static String SUBTITLES_LANGUAGES = "subtitles_languages";
public static final String VIDEO_ASPECT = "video_aspect";
public static final String VIDEO_CODEC = "video_codec";
public static final String VIDEO_HEIGHT = "video_height";
public static final String VIDEO_WIDTH = "video_width";
String DIRECTOR = "director";
//String RESUME = "resume";
String RUNTIME = "runtime";
//String STREAMDETAILS = "streamdetails";
String AUDIO_CHANNELS = "audio_channels";
String AUDIO_CODEC = "audio_coded";
String AUDIO_LANGUAGE = "audio_language";
String SUBTITLES_LANGUAGES = "subtitles_languages";
String VIDEO_ASPECT = "video_aspect";
String VIDEO_CODEC = "video_codec";
String VIDEO_HEIGHT = "video_height";
String VIDEO_WIDTH = "video_width";
// MusicVideo
public static final String ALBUM = "album";
public static final String ARTIST = "artist";
public static final String GENRES = "genre";
public static final String STUDIOS = "studio";
public static final String TAG = "tag";
public static final String TRACK = "track";
public static final String YEAR = "year";
String ALBUM = "album";
String ARTIST = "artist";
String GENRES = "genre";
String STUDIOS = "studio";
String TAG = "tag";
String TRACK = "track";
String YEAR = "year";
}
public static class MusicVideos implements BaseColumns, SyncColumns, MusicVideosColumns {

View File

@ -20,6 +20,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.utils.LogUtils;
@ -30,31 +31,32 @@ public class MediaDatabase extends SQLiteOpenHelper {
private static final String TAG = LogUtils.makeLogTag(MediaDatabase.class);
private static final String DB_NAME = "xbmc.sqlite";
private static final int DB_VERSION = 4;
private static final int DB_VERSION_PRE_EVENT_SERVER = 4,
DB_VERSION = 5;
/**
* Tables exposed
*/
public interface Tables {
public final static String HOSTS = "hosts";
public final static String MOVIES = "movies";
public final static String MOVIE_CAST = "movie_cast";
public final static String TVSHOWS = "tvshows";
public final static String TVSHOWS_CAST = "tvshows_cast";
public final static String SEASONS = "seasons";
public final static String EPISODES = "episodes";
public final static String ARTISTS = "artists";
public final static String ALBUMS = "albums";
public final static String SONGS = "songs";
public final static String AUDIO_GENRES = "audio_genres";
public final static String ALBUM_ARTISTS = "album_artists";
public final static String ALBUM_GENRES = "album_genres";
public final static String MUSIC_VIDEOS = "music_videos";
String HOSTS = "hosts";
String MOVIES = "movies";
String MOVIE_CAST = "movie_cast";
String TVSHOWS = "tvshows";
String TVSHOWS_CAST = "tvshows_cast";
String SEASONS = "seasons";
String EPISODES = "episodes";
String ARTISTS = "artists";
String ALBUMS = "albums";
String SONGS = "songs";
String AUDIO_GENRES = "audio_genres";
String ALBUM_ARTISTS = "album_artists";
String ALBUM_GENRES = "album_genres";
String MUSIC_VIDEOS = "music_videos";
/**
* Join to get Albums for an Artist
*/
public final static String ALBUMS_FOR_ARTIST_JOIN =
String ALBUMS_FOR_ARTIST_JOIN =
ALBUM_ARTISTS + " JOIN " + ALBUMS + " ON " +
ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.HOST_ID + "=" + ALBUMS + "." + MediaContract.Albums.HOST_ID +
" AND " +
@ -63,7 +65,7 @@ public class MediaDatabase extends SQLiteOpenHelper {
/**
* Join to get Artists for an Album
*/
public final static String ARTISTS_FOR_ALBUM_JOIN =
String ARTISTS_FOR_ALBUM_JOIN =
ALBUM_ARTISTS + " JOIN " + ARTISTS + " ON " +
ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.HOST_ID + "=" + ARTISTS + "." + MediaContract.Artists.HOST_ID +
" AND " +
@ -72,7 +74,7 @@ public class MediaDatabase extends SQLiteOpenHelper {
/**
* Join to get Album for a Genre
*/
public final static String ALBUMS_FOR_GENRE_JOIN =
String ALBUMS_FOR_GENRE_JOIN =
ALBUM_GENRES + " JOIN " + ALBUMS + " ON " +
ALBUM_GENRES + "." + MediaContract.AlbumGenres.HOST_ID + "=" + ALBUMS + "." + MediaContract.Albums.HOST_ID +
" AND " +
@ -81,7 +83,7 @@ public class MediaDatabase extends SQLiteOpenHelper {
/**
* Join to get Genres for an Album
*/
public final static String GENRES_FOR_ALBUM_JOIN =
String GENRES_FOR_ALBUM_JOIN =
ALBUM_GENRES + " JOIN " + AUDIO_GENRES + " ON " +
ALBUM_GENRES + "." + MediaContract.AlbumGenres.HOST_ID + "=" + AUDIO_GENRES + "." + MediaContract.AudioGenres.HOST_ID +
" AND " +
@ -89,13 +91,13 @@ public class MediaDatabase extends SQLiteOpenHelper {
}
private interface References {
final static String HOST_ID =
String HOST_ID =
"REFERENCES " + Tables.HOSTS + "(" + BaseColumns._ID + ")";
final static String ALBUMID =
String ALBUMID =
"REFERENCES " + Tables.ALBUMS + "(" + MediaContract.AlbumsColumns.ALBUMID + ")";
final static String ARTISTID =
String ARTISTID =
"REFERENCES " + Tables.ARTISTS + "(" + MediaContract.ArtistsColumns.ARTISTID + ")";
final static String GENREID =
String GENREID =
"REFERENCES " + Tables.AUDIO_GENRES + "(" + MediaContract.AudioGenresColumns.GENREID + ")";
}
@ -108,17 +110,19 @@ public class MediaDatabase extends SQLiteOpenHelper {
// Hosts
db.execSQL("CREATE TABLE " + Tables.HOSTS + "(" +
BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
MediaContract.SyncColumns.UPDATED + " INTEGER NOT NULL," +
MediaContract.HostsColumns.NAME + " TEXT, " +
MediaContract.HostsColumns.ADDRESS + " TEXT, " +
MediaContract.HostsColumns.PROTOCOL + " INTEGER, " +
MediaContract.HostsColumns.HTTP_PORT + " INTEGER, " +
MediaContract.HostsColumns.TCP_PORT + " INTEGER, " +
MediaContract.HostsColumns.USERNAME + " TEXT, " +
MediaContract.HostsColumns.PASSWORD + " TEXT, " +
MediaContract.HostsColumns.MAC_ADDRESS + " TEXT, " +
MediaContract.HostsColumns.WOL_PORT + " INTEGER)"
BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
MediaContract.SyncColumns.UPDATED + " INTEGER NOT NULL," +
MediaContract.HostsColumns.NAME + " TEXT, " +
MediaContract.HostsColumns.ADDRESS + " TEXT, " +
MediaContract.HostsColumns.PROTOCOL + " INTEGER, " +
MediaContract.HostsColumns.HTTP_PORT + " INTEGER, " +
MediaContract.HostsColumns.TCP_PORT + " INTEGER, " +
MediaContract.HostsColumns.USERNAME + " TEXT, " +
MediaContract.HostsColumns.PASSWORD + " TEXT, " +
MediaContract.HostsColumns.MAC_ADDRESS + " TEXT, " +
MediaContract.HostsColumns.WOL_PORT + " INTEGER, " +
MediaContract.HostsColumns.USE_EVENT_SERVER + " INTEGER, " +
MediaContract.HostsColumns.EVENT_SERVER_PORT + " INTEGER)"
);
// Movies
@ -438,7 +442,20 @@ public class MediaDatabase extends SQLiteOpenHelper {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// For now just drop old tables and recreate
switch (oldVersion) {
case DB_VERSION_PRE_EVENT_SERVER:
// Add USE_EVENT_SERVER and EVENT_SERVER_PORT columns to HOSTS table
db.execSQL("ALTER TABLE " + Tables.HOSTS +
" ADD COLUMN " + MediaContract.HostsColumns.USE_EVENT_SERVER +
" INTEGER DEFAULT 1;");
db.execSQL("ALTER TABLE " + Tables.HOSTS +
" ADD COLUMN " + MediaContract.HostsColumns.EVENT_SERVER_PORT +
" INTEGER DEFAULT " + HostInfo.DEFAULT_EVENT_SERVER_PORT + ";");
}
}
private void resetDb(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + Tables.HOSTS);
db.execSQL("DROP TABLE IF EXISTS " + Tables.MOVIES);
db.execSQL("DROP TABLE IF EXISTS " + Tables.MOVIE_CAST);
@ -454,7 +471,7 @@ public class MediaDatabase extends SQLiteOpenHelper {
db.execSQL("DROP TABLE IF EXISTS " + Tables.ALBUM_GENRES);
db.execSQL("DROP TABLE IF EXISTS " + Tables.MUSIC_VIDEOS);
onCreate(db);
}
}
/**
* Tokens to move from prefix to suffix when sorting titles

View File

@ -16,6 +16,7 @@
package org.xbmc.kore.ui;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
@ -34,7 +35,9 @@ import android.widget.Toast;
import org.xbmc.kore.R;
import org.xbmc.kore.Settings;
import org.xbmc.kore.eventclient.EventServerConnection;
import org.xbmc.kore.host.HostConnectionObserver;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.host.HostManager;
import org.xbmc.kore.jsonrpc.ApiCallback;
import org.xbmc.kore.jsonrpc.HostConnection;
@ -547,6 +550,7 @@ public class RemoteActivity extends BaseActivity
public void playerOnPlay(PlayerType.GetActivePlayersReturnType getActivePlayerResult,
PlayerType.PropertyValue getPropertiesResult,
ListType.ItemsAll getItemResult) {
checkEventServerAvailability();
String imageUrl = (TextUtils.isEmpty(getItemResult.fanart)) ?
getItemResult.thumbnail : getItemResult.fanart;
if ((imageUrl != null) && !imageUrl.equals(lastImageUrl)) {
@ -572,6 +576,7 @@ public class RemoteActivity extends BaseActivity
}
public void playerOnStop() {
checkEventServerAvailability();
if (lastImageUrl != null) {
setImageViewBackground(null);
}
@ -606,4 +611,30 @@ public class RemoteActivity extends BaseActivity
viewPager.setCurrentItem(1);
}
// TODO: Remove this method after deployment of version 1.5.0. The only objective of this is to facilitate the
// transition to using EventServer, by checking if it is available, but this needs to be done only once.
public void checkEventServerAvailability() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean checkedEventServerConnection =
preferences.getBoolean(Settings.KEY_PREF_CHECKED_EVENT_SERVER_CONNECTION,
Settings.DEFAULT_PREF_CHECKED_EVENT_SERVER_CONNECTION);
if (!checkedEventServerConnection) {
LogUtils.LOGD(TAG, "Checking EventServer connection implicitely");
// Check if EventServer is available
final HostInfo hostInfo = hostManager.getHostInfo();
EventServerConnection.testEventServerConnection(
hostInfo,
new EventServerConnection.EventServerConnectionCallback() {
@Override
public void OnConnectResult(boolean success) {
hostInfo.setUseEventServer(success);
hostManager.editHost(hostInfo.getId(), hostInfo);
}
},
new Handler());
preferences.edit()
.putBoolean(Settings.KEY_PREF_CHECKED_EVENT_SERVER_CONNECTION, true)
.apply();
}
}
}

View File

@ -171,7 +171,8 @@ public class RemoteFragment extends Fragment
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_remote, container, false);
ButterKnife.inject(this, root);
if (eventServerConnection != null) {
if (hostManager.getHostInfo().getUseEventServer() &&
(eventServerConnection != null)) {
// Setup d-pad to use EventServer
setupEventServerButton(leftButton, ButtonCodes.REMOTE_LEFT);
setupEventServerButton(rightButton, ButtonCodes.REMOTE_RIGHT);
@ -273,7 +274,7 @@ public class RemoteFragment extends Fragment
hostManager.getHostInfo(),
new EventServerConnection.EventServerConnectionCallback() {
@Override
public void OnConnect(boolean success) {
public void OnConnectResult(boolean success) {
if (!success) {
LogUtils.LOGD(TAG, "Couldnt setup EventServer, disabling it");
eventServerConnection = null;

View File

@ -108,21 +108,16 @@ public class AddHostActivity extends BaseActivity
Bundle args = new Bundle();
if (hostInfo != null) {
args.putString(HostFragmentManualConfiguration.HOST_NAME,
hostInfo.getName());
args.putString(HostFragmentManualConfiguration.HOST_ADDRESS,
hostInfo.getAddress());
args.putInt(HostFragmentManualConfiguration.HOST_HTTP_PORT,
hostInfo.getHttpPort());
args.putInt(HostFragmentManualConfiguration.HOST_TCP_PORT,
hostInfo.getTcpPort());
args.putString(HostFragmentManualConfiguration.HOST_USERNAME,
hostInfo.getUsername());
args.putString(HostFragmentManualConfiguration.HOST_PASSWORD,
hostInfo.getPassword());
args.putInt(HostFragmentManualConfiguration.HOST_PROTOCOL,
hostInfo.getProtocol());
args.putString(HostFragmentManualConfiguration.HOST_NAME, hostInfo.getName());
args.putString(HostFragmentManualConfiguration.HOST_ADDRESS, hostInfo.getAddress());
args.putInt(HostFragmentManualConfiguration.HOST_HTTP_PORT, hostInfo.getHttpPort());
args.putInt(HostFragmentManualConfiguration.HOST_TCP_PORT, hostInfo.getTcpPort());
args.putString(HostFragmentManualConfiguration.HOST_USERNAME, hostInfo.getUsername());
args.putString(HostFragmentManualConfiguration.HOST_PASSWORD, hostInfo.getPassword());
args.putInt(HostFragmentManualConfiguration.HOST_PROTOCOL, hostInfo.getProtocol());
// Ignore Mac Address and Wol Port
args.putBoolean(HostFragmentManualConfiguration.HOST_USE_EVENT_SERVER, hostInfo.getUseEventServer());
args.putInt(HostFragmentManualConfiguration.HOST_EVENT_SERVER_PORT, hostInfo.getEventServerPort());
// Send this fragment straight to test
args.putBoolean(HostFragmentManualConfiguration.GO_STRAIGHT_TO_TEST, true);

View File

@ -271,7 +271,7 @@ public class AddHostFragmentZeroconf extends Fragment {
String hostAddress = addresses[0];
int hostHttpPort = selectedServiceInfo.getPort();
HostInfo selectedHostInfo = new HostInfo(hostName, hostAddress, HostConnection.PROTOCOL_TCP,
hostHttpPort, HostInfo.DEFAULT_TCP_PORT, null, null);
hostHttpPort, HostInfo.DEFAULT_TCP_PORT, null, null, true, HostInfo.DEFAULT_EVENT_SERVER_PORT);
listener.onAddHostZeroconfFoundHost(selectedHostInfo);
}

View File

@ -26,6 +26,7 @@ import org.xbmc.kore.R;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.host.HostManager;
import org.xbmc.kore.ui.BaseActivity;
import org.xbmc.kore.utils.LogUtils;
/**
* Edits a host
@ -61,21 +62,25 @@ public class EditHostActivity extends BaseActivity implements
args.putString(HostFragmentManualConfiguration.HOST_NAME,
selectedHostInfo.getName());
args.putString(HostFragmentManualConfiguration.HOST_ADDRESS,
selectedHostInfo.getAddress());
selectedHostInfo.getAddress());
args.putInt(HostFragmentManualConfiguration.HOST_HTTP_PORT,
selectedHostInfo.getHttpPort());
selectedHostInfo.getHttpPort());
args.putInt(HostFragmentManualConfiguration.HOST_TCP_PORT,
selectedHostInfo.getTcpPort());
selectedHostInfo.getTcpPort());
args.putString(HostFragmentManualConfiguration.HOST_USERNAME,
selectedHostInfo.getUsername());
selectedHostInfo.getUsername());
args.putString(HostFragmentManualConfiguration.HOST_PASSWORD,
selectedHostInfo.getPassword());
selectedHostInfo.getPassword());
args.putInt(HostFragmentManualConfiguration.HOST_PROTOCOL,
selectedHostInfo.getProtocol());
selectedHostInfo.getProtocol());
args.putString(HostFragmentManualConfiguration.HOST_MAC_ADDRESS,
selectedHostInfo.getMacAddress());
selectedHostInfo.getMacAddress());
args.putInt(HostFragmentManualConfiguration.HOST_WOL_PORT,
selectedHostInfo.getWolPort());
selectedHostInfo.getWolPort());
args.putBoolean(HostFragmentManualConfiguration.HOST_USE_EVENT_SERVER,
selectedHostInfo.getUseEventServer());
args.putInt(HostFragmentManualConfiguration.HOST_EVENT_SERVER_PORT,
selectedHostInfo.getEventServerPort());
editFragment.setArguments(args);
}
}

View File

@ -20,6 +20,7 @@ import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
@ -32,6 +33,8 @@ import android.widget.EditText;
import android.widget.Toast;
import org.xbmc.kore.R;
import org.xbmc.kore.Settings;
import org.xbmc.kore.eventclient.EventServerConnection;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.jsonrpc.ApiCallback;
import org.xbmc.kore.jsonrpc.ApiException;
@ -62,7 +65,9 @@ public class HostFragmentManualConfiguration extends Fragment {
HOST_PASSWORD = PREFIX + ".host_password",
HOST_MAC_ADDRESS = PREFIX + ".host_mac_address",
HOST_WOL_PORT = PREFIX + ".host_wol_port",
HOST_PROTOCOL = PREFIX + ".host_protocol";
HOST_PROTOCOL = PREFIX + ".host_protocol",
HOST_USE_EVENT_SERVER = PREFIX + ".host_use_event_server",
HOST_EVENT_SERVER_PORT = PREFIX + ".host_event_server_port";
public static final String GO_STRAIGHT_TO_TEST = PREFIX + ".go_straight_to_test";
/**
@ -86,6 +91,8 @@ public class HostFragmentManualConfiguration extends Fragment {
@InjectView(R.id.xbmc_mac_address) EditText xbmcMacAddressEditText;
@InjectView(R.id.xbmc_wol_port) EditText xbmcWolPortEditText;
@InjectView(R.id.xbmc_use_tcp) CheckBox xbmcUseTcpCheckbox;
@InjectView(R.id.xbmc_use_event_server) CheckBox xbmcUseEventServerCheckbox;
@InjectView(R.id.xbmc_event_server_port) EditText xbmcEventServerPortEditText;
// Handler for callbacks
final Handler handler = new Handler();
@ -104,6 +111,13 @@ public class HostFragmentManualConfiguration extends Fragment {
}
});
xbmcUseEventServerCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
xbmcEventServerPortEditText.setEnabled(isChecked);
}
});
// Check if we were given a host info
String hostName = getArguments().getString(HOST_NAME);
String hostAddress = getArguments().getString(HOST_ADDRESS);
@ -114,6 +128,8 @@ public class HostFragmentManualConfiguration extends Fragment {
int hostProtocol = getArguments().getInt(HOST_PROTOCOL, HostConnection.PROTOCOL_TCP);
String hostMacAddress = getArguments().getString(HOST_MAC_ADDRESS);
int hostWolPort = getArguments().getInt(HOST_WOL_PORT, HostInfo.DEFAULT_WOL_PORT);
boolean hostUseEventServer = getArguments().getBoolean(HOST_USE_EVENT_SERVER, true);
int hostEventServerPort = getArguments().getInt(HOST_EVENT_SERVER_PORT, HostInfo.DEFAULT_EVENT_SERVER_PORT);
if (hostAddress != null) {
xbmcNameEditText.setText(hostName);
@ -133,6 +149,11 @@ public class HostFragmentManualConfiguration extends Fragment {
xbmcMacAddressEditText.setText(hostMacAddress);
if (hostWolPort != HostInfo.DEFAULT_WOL_PORT)
xbmcWolPortEditText.setText(String.valueOf(hostWolPort));
xbmcUseEventServerCheckbox.setChecked(hostUseEventServer);
xbmcEventServerPortEditText.setEnabled(xbmcUseEventServerCheckbox.isChecked());
if (hostEventServerPort != HostInfo.DEFAULT_EVENT_SERVER_PORT)
xbmcEventServerPortEditText.setText(String.valueOf(hostEventServerPort));
}
return root;
@ -230,6 +251,15 @@ public class HostFragmentManualConfiguration extends Fragment {
// Ignoring this exception and keeping WoL port at the default value
}
boolean xbmcUseEventServer = xbmcUseEventServerCheckbox.isChecked();
aux = xbmcEventServerPortEditText.getText().toString();
int xbmcEventServerPort;
try {
xbmcEventServerPort = TextUtils.isEmpty(aux) ? HostInfo.DEFAULT_EVENT_SERVER_PORT : Integer.valueOf(aux);
} catch (NumberFormatException exc) {
xbmcEventServerPort = -1;
}
// Check Xbmc name and address
if (TextUtils.isEmpty(xbmcName)) {
Toast.makeText(getActivity(), R.string.wizard_no_name_specified, Toast.LENGTH_SHORT).show();
@ -247,6 +277,10 @@ public class HostFragmentManualConfiguration extends Fragment {
Toast.makeText(getActivity(), R.string.wizard_invalid_tcp_port_specified, Toast.LENGTH_SHORT).show();
xbmcTcpPortEditText.requestFocus();
return;
} else if (xbmcEventServerPort <= 0) {
Toast.makeText(getActivity(), R.string.wizard_invalid_tcp_port_specified, Toast.LENGTH_SHORT).show();
xbmcEventServerPortEditText.requestFocus();
return;
}
// If username or password empty, set it to null
@ -257,7 +291,9 @@ public class HostFragmentManualConfiguration extends Fragment {
// Ok, let's try to ping the host
final HostInfo checkedHostInfo = new HostInfo(xbmcName, xbmcAddress, xbmcProtocol,
xbmcHttpPort, xbmcTcpPort, xbmcUsername, xbmcPassword);
xbmcHttpPort, xbmcTcpPort,
xbmcUsername, xbmcPassword,
xbmcUseEventServer, xbmcEventServerPort);
checkedHostInfo.setMacAddress(macAddress);
checkedHostInfo.setWolPort(xbmcWolPort);
@ -288,9 +324,9 @@ public class HostFragmentManualConfiguration extends Fragment {
if (hostInfo.getProtocol() == HostConnection.PROTOCOL_TCP) {
chainCallCheckTcpConnection(hostConnection, hostInfo);
} else {
// We're done
// No TCP, check EventServer
hostConnection.disconnect();
hostConnectionChecked(hostInfo);
chainCallCheckEventServerConnection(hostInfo);
}
}
@ -312,8 +348,8 @@ public class HostFragmentManualConfiguration extends Fragment {
// Great, we managed to connect through HTTP and TCP
LogUtils.LOGD(TAG, "Successfully connected to new host through TCP.");
hostConnection.disconnect();
// Notify connection checked through TCP
hostConnectionChecked(hostInfo);
// Check EventServer
chainCallCheckEventServerConnection(hostInfo);
}
@Override
@ -322,11 +358,39 @@ public class HostFragmentManualConfiguration extends Fragment {
LogUtils.LOGD(TAG, "Couldn't connect to host through TCP. Message: " + description);
hostConnection.disconnect();
hostInfo.setProtocol(HostConnection.PROTOCOL_HTTP);
hostConnectionChecked(hostInfo);
// Check EventServer
chainCallCheckEventServerConnection(hostInfo);
}
}, handler);
}
private void chainCallCheckEventServerConnection(final HostInfo hostInfo) {
if (hostInfo.getUseEventServer()) {
EventServerConnection.testEventServerConnection(
hostInfo,
new EventServerConnection.EventServerConnectionCallback() {
@Override
public void OnConnectResult(boolean success) {
LogUtils.LOGD(TAG, "Check ES connection: " + success);
if (success) {
hostConnectionChecked(hostInfo);
} else {
hostInfo.setUseEventServer(false);
hostConnectionChecked(hostInfo);
}
}
},
handler);
} else {
hostConnectionChecked(hostInfo);
}
PreferenceManager.getDefaultSharedPreferences(getActivity())
.edit()
.putBoolean(Settings.KEY_PREF_CHECKED_EVENT_SERVER_CONNECTION, true)
.apply();
}
/**
* The connection was checked, and hostInfo has all the correct parameters to communicate
* with it

View File

@ -67,6 +67,7 @@
android:layout_height="wrap_content"
android:layout_below="@+id/xbmc_name"
android:layout_alignRight="@id/xbmc_name"
android:layout_alignEnd="@id/xbmc_name"
android:inputType="number"
android:ems="4"
@ -79,7 +80,9 @@
android:layout_height="wrap_content"
android:layout_alignTop="@id/xbmc_http_port"
android:layout_alignLeft="@id/xbmc_name"
android:layout_alignStart="@id/xbmc_name"
android:layout_toLeftOf="@id/xbmc_http_port"
android:layout_toStartOf="@id/xbmc_http_port"
android:inputType="textNoSuggestions"
android:hint="@string/wizard_xbmc_ip"/>
@ -91,7 +94,9 @@
android:layout_height="wrap_content"
android:layout_below="@+id/xbmc_ip_address"
android:layout_alignLeft="@id/xbmc_name"
android:layout_alignStart="@id/xbmc_name"
android:layout_alignRight="@id/xbmc_name"
android:layout_alignEnd="@id/xbmc_name"
android:inputType="textNoSuggestions"
android:hint="@string/wizard_xbmc_username"/>
@ -103,7 +108,9 @@
android:layout_height="wrap_content"
android:layout_below="@+id/xbmc_username"
android:layout_alignLeft="@id/xbmc_name"
android:layout_alignStart="@id/xbmc_name"
android:layout_alignRight="@id/xbmc_name"
android:layout_alignEnd="@id/xbmc_name"
android:inputType="textPassword"
android:hint="@string/wizard_xbmc_password"/>
@ -124,6 +131,7 @@
android:layout_below="@android:id/text1"
android:layout_marginTop="8dp"
android:layout_alignRight="@id/xbmc_name"
android:layout_alignEnd="@id/xbmc_name"
android:inputType="number"
android:ems="7"
android:hint="@string/wizard_xbmc_tcp_port"/>
@ -134,17 +142,46 @@
android:layout_height="wrap_content"
android:layout_alignTop="@+id/xbmc_tcp_port"
android:layout_alignLeft="@id/xbmc_name"
android:layout_alignStart="@id/xbmc_name"
android:layout_toLeftOf="@id/xbmc_tcp_port"
android:layout_toStartOf="@id/xbmc_tcp_port"
android:text="@string/wizard_xbmc_use_tcp"/>
<EditText
android:id="@+id/xbmc_event_server_port"
style="@style/TextAppearance.EditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/xbmc_tcp_port"
android:layout_alignLeft="@id/xbmc_tcp_port"
android:layout_alignStart="@id/xbmc_tcp_port"
android:layout_alignRight="@id/xbmc_tcp_port"
android:layout_alignEnd="@id/xbmc_tcp_port"
android:inputType="number"
android:ems="7"
android:hint="@string/wizard_xbmc_event_server_port"/>
<CheckBox
android:id="@+id/xbmc_use_event_server"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/xbmc_event_server_port"
android:layout_alignLeft="@id/xbmc_name"
android:layout_alignStart="@id/xbmc_name"
android:layout_toLeftOf="@id/xbmc_event_server_port"
android:layout_toStartOf="@id/xbmc_event_server_port"
android:text="@string/wizard_xbmc_use_event_server"/>
<EditText
android:id="@+id/xbmc_wol_port"
style="@style/TextAppearance.EditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/xbmc_tcp_port"
android:layout_alignLeft="@id/xbmc_tcp_port"
android:layout_alignRight="@id/xbmc_tcp_port"
android:layout_below="@+id/xbmc_event_server_port"
android:layout_alignLeft="@id/xbmc_event_server_port"
android:layout_alignStart="@id/xbmc_event_server_port"
android:layout_alignRight="@id/xbmc_event_server_port"
android:layout_alignEnd="@id/xbmc_event_server_port"
android:inputType="number"
android:hint="@string/wizard_xbmc_wol_port"/>
@ -155,7 +192,9 @@
android:layout_height="wrap_content"
android:layout_alignTop="@+id/xbmc_wol_port"
android:layout_alignLeft="@id/xbmc_name"
android:layout_alignStart="@id/xbmc_name"
android:layout_toLeftOf="@id/xbmc_wol_port"
android:layout_toStartOf="@id/xbmc_wol_port"
android:inputType="text"
android:hint="@string/wizard_xbmc_mac_address"/>

View File

@ -98,11 +98,14 @@
<string name="wizard_xbmc_mac_address">MAC address</string>
<string name="wizard_xbmc_wol_port">WoL port (9)</string>
<string name="wizard_xbmc_use_tcp">Use TCP</string>
<string name="wizard_xbmc_event_server_port">ES Port (9777)</string>
<string name="wizard_xbmc_use_event_server">Use EventServer</string>
<string name="wizard_no_name_specified">Please specify a name for this media center, so you can identify it later.</string>
<string name="wizard_no_address_specified">Please specify the address of this media center, so I can locate it.</string>
<string name="wizard_invalid_http_port_specified">Please specify a valid HTTP port for this media center, so I can locate it.</string>
<string name="wizard_invalid_tcp_port_specified">Please specify a valid TCP port for this media center, so I can locate it.</string>
<string name="wizard_invalid_http_port_specified">Please specify a valid HTTP port for this media center.</string>
<string name="wizard_invalid_tcp_port_specified">Please specify a valid TCP port for this media center.</string>
<string name="wizard_invalid_es_port_specified">Please specify a valid EventServer port for this media center.</string>
<string name="wizard_connecting_to_xbmc_title">Connecting to %1$s…</string>
<string name="wizard_connecting_to_xbmc_message">Please wait while I try to connect to your media center…</string>