diff --git a/.classpath b/.classpath index 51769745..149cb3c9 100644 --- a/.classpath +++ b/.classpath @@ -1,9 +1,20 @@ - - - - - - + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore index 0e69a217..7e78a6f9 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ local.properties .buildpath *.DS_Store bin/jarlist.cache -test/test-reports/ \ No newline at end of file +test/test-reports/ +/target/ diff --git a/.project b/.project index f38a678f..30ba1f9b 100644 --- a/.project +++ b/.project @@ -1,33 +1,23 @@ - Connect-SDK-Android-Core + Connect-SDK-Java-Core - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - org.eclipse.jdt.core.javabuilder - com.android.ide.eclipse.adt.ApkBuilder + org.eclipse.m2e.core.maven2Builder - com.android.ide.eclipse.adt.AndroidNature + org.eclipse.m2e.core.maven2Nature org.eclipse.jdt.core.javanature diff --git a/AndroidManifest.xml b/AndroidManifest.xml deleted file mode 100644 index 0651a857..00000000 --- a/AndroidManifest.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/README.md b/README.md index 2a64b7dd..fdff72db 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -#Connect SDK Core (Android) +#Connect SDK Core + +This is a fork from the Android version of Connect SDK. In this version all dependencies to android are removed. + The Connect SDK Core contains all of the core classes required for basic operation of Connect SDK. The core also includes support for some select protocols which do not have any heavy and/or external dependencies. These protocols include: - Apple TV - DIAL @@ -10,8 +13,7 @@ The Connect SDK Core contains all of the core classes required for basic operati ##General Information For more information about Connect SDK, visit the [main repository](https://github.com/ConnectSDK/Connect-SDK-Android). -##Setup -Unless you are doing very specialized work to extend the SDK, you should not need to make direct use of this repository. Instead, clone the [main repository](https://github.com/ConnectSDK/Connect-SDK-Android), which includes this repository as a submodule. +For details on this fork, visit the [project page](http://sprehn.github.io/Connect-SDK-Java-Core/). ##License Copyright (c) 2013-2015 LG Electronics. diff --git a/libs/java-websocket-patch.jar b/libs/java-websocket-patch.jar deleted file mode 100644 index 22cda9f4..00000000 Binary files a/libs/java-websocket-patch.jar and /dev/null differ diff --git a/libs/javax.jmdns_3.4.1-patch2.jar b/libs/javax.jmdns_3.4.1-patch2.jar deleted file mode 100644 index be0fb34f..00000000 Binary files a/libs/javax.jmdns_3.4.1-patch2.jar and /dev/null differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..e60a4216 --- /dev/null +++ b/pom.xml @@ -0,0 +1,114 @@ + + 4.0.0 + Connect-SDK-Java-Core + Connect-SDK-Java-Core + 1.1-SNAPSHOT + + + UTF-8 + + + + + clojars.org + http://clojars.org/repo + + + + + src + + + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-site-plugin + 3.3 + + true + + + + + com.github.github + site-maven-plugin + 0.12 + + + + site + + site-deploy + + github + site built + ${site.path} + true + + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + org.codehaus.mojo + findbugs-maven-plugin + 3.0.4 + + Max + + + + + + + + org.json + json + 20140107 + + + javax.jmdns + jmdns + 3.4.1 + + + org.java-websocket + java-websocket + 1.3.1 + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.xpp3 + 1.1.4c_7 + + + org.slf4j + slf4j-api + 1.7.21 + + + org.apache.httpcomponents + httpclient + 4.5.2 + + + + https://github.com/sprehn/Connect-SDK-Java-Core + scm:git:https://github.com/sprehn/Connect-SDK-Java-Core.git + + \ No newline at end of file diff --git a/project.properties b/project.properties deleted file mode 100644 index c24522b5..00000000 --- a/project.properties +++ /dev/null @@ -1,16 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Project target. -target=android-22 -android.library=true -android.library.reference.1=.. diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index 96a442e5..00000000 Binary files a/res/drawable-hdpi/ic_launcher.png and /dev/null differ diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 359047df..00000000 Binary files a/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 71c6d760..00000000 Binary files a/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/res/values-v11/styles.xml b/res/values-v11/styles.xml deleted file mode 100644 index 3c02242a..00000000 --- a/res/values-v11/styles.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/res/values-v14/styles.xml b/res/values-v14/styles.xml deleted file mode 100644 index a91fd037..00000000 --- a/res/values-v14/styles.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/res/values/strings.xml b/res/values/strings.xml deleted file mode 100644 index 41274ae5..00000000 --- a/res/values/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - Connect-SDK-Android-Core - - diff --git a/res/values/styles.xml b/res/values/styles.xml deleted file mode 100644 index 6ce89c7b..00000000 --- a/res/values/styles.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - diff --git a/src/com/connectsdk/core/AppInfo.java b/src/com/connectsdk/core/AppInfo.java index de157657..9d4543e8 100644 --- a/src/com/connectsdk/core/AppInfo.java +++ b/src/com/connectsdk/core/AppInfo.java @@ -57,6 +57,7 @@ public AppInfo(String id) { * Gets the ID of the app on the first screen device. Format is different * depending on the platform. (ex. youtube.leanback.v4, 0000001134, netflix, * etc). + * @return ID of the app on the first screen device */ public String getId() { return id; @@ -66,6 +67,7 @@ public String getId() { * Sets the ID of the app on the first screen device. Format is different * depending on the platform. (ex. youtube.leanback.v4, 0000001134, netflix, * etc). + * @param id ID of the app on the first screen device */ public void setId(String id) { this.id = id; @@ -74,6 +76,7 @@ public void setId(String id) { /** * Gets the user-friendly name of the app (ex. YouTube, Browser, Netflix, * etc). + * @return user-friendly name of the app */ public String getName() { return name; @@ -82,17 +85,18 @@ public String getName() { /** * Sets the user-friendly name of the app (ex. YouTube, Browser, Netflix, * etc). + * @param name user-friendly name of the app */ public void setName(String name) { this.name = name.trim(); } - /** Gets the raw data from the first screen device about the app. */ + /** @return the raw data from the first screen device about the app. */ public JSONObject getRawData() { return raw; } - /** Sets the raw data from the first screen device about the app. */ + /** @param data the raw data from the first screen device about the app. */ public void setRawData(JSONObject data) { raw = data; } @@ -110,20 +114,29 @@ public JSONObject toJSONObject() throws JSONException { // @endcond - /** - * Compares two AppInfo objects. - * - * @param o - * Other AppInfo object to compare. - * - * @return true if both AppInfo id values are equal - */ @Override - public boolean equals(Object o) { - if (o instanceof AppInfo) { - AppInfo ai = (AppInfo) o; - return this.id.equals(ai.id); - } - return super.equals(o); + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppInfo other = (AppInfo) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + } diff --git a/src/com/connectsdk/core/ChannelInfo.java b/src/com/connectsdk/core/ChannelInfo.java index 0211b580..4145fc3f 100644 --- a/src/com/connectsdk/core/ChannelInfo.java +++ b/src/com/connectsdk/core/ChannelInfo.java @@ -23,8 +23,6 @@ import org.json.JSONException; import org.json.JSONObject; -import android.util.Log; - /** * Normalized reference object for information about a TVs channels. This object is required to set the channel on a TV. */ @@ -45,98 +43,69 @@ public class ChannelInfo implements JSONSerializable { public ChannelInfo() { } - /** Gets the raw data from the first screen device about the channel. In most cases, this is an NSDictionary. */ + /** @return the raw data from the first screen device about the channel. In most cases, this is an NSDictionary. */ public JSONObject getRawData() { return rawData; } - /** Sets the raw data from the first screen device about the channel. In most cases, this is an NSDictionary. */ + /** + * @param rawData the raw data from the first screen device about the channel. In most cases, this is an + * NSDictionary. + */ public void setRawData(JSONObject rawData) { this.rawData = rawData; } - /** Gets the user-friendly name of the channel */ + /** @return the user-friendly name of the channel */ public String getName() { return channelName; } - /** Sets the user-friendly name of the channel */ + /** @param channelName the user-friendly name of the channel */ public void setName(String channelName) { this.channelName = channelName; } - /** Gets the TV's unique ID for the channel */ + /** @return the TV's unique ID for the channel */ public String getId() { return channelId; } - /** Sets the TV's unique ID for the channel */ + /** @param channelId the TV's unique ID for the channel */ public void setId(String channelId) { this.channelId = channelId; } - /** Gets the TV channel's number (likely to be a combination of the major & minor numbers) */ + /** @return the TV channel's number (likely to be a combination of the major & minor numbers) */ public String getNumber() { return channelNumber; } - /** Sets the TV channel's number (likely to be a combination of the major & minor numbers) */ + /** @param channelNumber the TV channel's number (likely to be a combination of the major & minor numbers) */ public void setNumber(String channelNumber) { this.channelNumber = channelNumber; } - /** Gets the TV channel's minor number */ + /** @return the TV channel's minor number */ public int getMinorNumber() { return minorNumber; } - /** Sets the TV channel's minor number */ + /** @param minorNumber the TV channel's minor number */ public void setMinorNumber(int minorNumber) { this.minorNumber = minorNumber; } - /** Gets the TV channel's major number */ + /** @return the TV channel's major number */ public int getMajorNumber() { return majorNumber; } - /** Sets the TV channel's major number */ + /** @param majorNumber the TV channel's major number */ public void setMajorNumber(int majorNumber) { this.majorNumber = majorNumber; } - /** - * Compares two ChannelInfo objects. - * - * @param channelInfo ChannelInfo object to compare. - * - * @return YES if both ChannelInfo number & name values are equal - */ - @Override - public boolean equals(Object o) { - if (o instanceof ChannelInfo) { - ChannelInfo other = (ChannelInfo) o; - - if (this.channelId != null) { - if (this.channelId.equals(other.channelId)) - return true; - } else if (this.channelName != null && this.channelNumber != null) { - return this.channelName.equals(other.channelName) - && this.channelNumber.equals(other.channelNumber) - && this.majorNumber == other.majorNumber - && this.minorNumber == other.minorNumber; - } - - Log.d(Util.T, "Could not compare channel values, no data to compare against"); - Log.d(Util.T, "This channel info: \n" + this.rawData.toString()); - Log.d(Util.T, "Other channel info: \n" + other.rawData.toString()); - - return false; - } - - return super.equals(o); - } - // @cond INTERNAL @Override public JSONObject toJSONObject() throws JSONException { @@ -152,4 +121,51 @@ public JSONObject toJSONObject() throws JSONException { return obj; } // @endcond + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + if (channelId != null) { + result = prime * result + channelId.hashCode(); + } else { + result = prime * result + ((channelName == null) ? 0 : channelName.hashCode()); + result = prime * result + ((channelNumber == null) ? 0 : channelNumber.hashCode()); + result = prime * result + majorNumber; + result = prime * result + minorNumber; + } + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ChannelInfo other = (ChannelInfo) obj; + + if (channelId != null) { + if (channelId.equals(other.channelId)) + return true; + } + + if (channelName == null) { + if (other.channelName != null) + return false; + } else if (!channelName.equals(other.channelName)) + return false; + if (channelNumber == null) { + if (other.channelNumber != null) + return false; + } else if (!channelNumber.equals(other.channelNumber)) + return false; + if (majorNumber != other.majorNumber) + return false; + if (minorNumber != other.minorNumber) + return false; + return true; + } } diff --git a/src/com/connectsdk/core/Context.java b/src/com/connectsdk/core/Context.java new file mode 100644 index 00000000..d8362304 --- /dev/null +++ b/src/com/connectsdk/core/Context.java @@ -0,0 +1,11 @@ +package com.connectsdk.core; + +import java.net.InetAddress; + +/** Interface that must be implemented for the library to interface with surrounding environment. */ +public interface Context { + public String getPackageName(); + public String getDataDir(); + public String getApplicationName(); + public InetAddress getIpAddress(); +} diff --git a/src/com/connectsdk/core/ExternalInputInfo.java b/src/com/connectsdk/core/ExternalInputInfo.java index f093a5ef..8db1599b 100644 --- a/src/com/connectsdk/core/ExternalInputInfo.java +++ b/src/com/connectsdk/core/ExternalInputInfo.java @@ -40,52 +40,52 @@ public class ExternalInputInfo implements JSONSerializable { public ExternalInputInfo() { } - /** Gets the ID of the external input on the first screen device. */ + /** @return the ID of the external input on the first screen device. */ public String getId() { return id; } - /** Sets the ID of the external input on the first screen device. */ + /** @param inputId the ID of the external input on the first screen device. */ public void setId(String inputId) { this.id = inputId; } - /** Gets the user-friendly name of the external input (ex. AV, HDMI1, etc). */ + /** @return the user-friendly name of the external input (ex. AV, HDMI1, etc). */ public String getName() { return name; } - /** Sets the user-friendly name of the external input (ex. AV, HDMI1, etc). */ + /** @param inputName the user-friendly name of the external input (ex. AV, HDMI1, etc). */ public void setName(String inputName) { this.name = inputName; } - /** Sets the raw data from the first screen device about the external input. */ + /** @param rawData the raw data from the first screen device about the external input. */ public void setRawData(JSONObject rawData) { this.rawData = rawData; } - /** Gets the raw data from the first screen device about the external input. */ + /** @return the raw data from the first screen device about the external input. */ public JSONObject getRawData() { return rawData; } - /** Whether the DeviceService is currently connected to this external input. */ + /** @return true if the DeviceService is currently connected to this external input. */ public boolean isConnected() { return connected; } - /** Sets whether the DeviceService is currently connected to this external input. */ + /** @param connected whether the DeviceService is currently connected to this external input. */ public void setConnected(boolean connected) { this.connected = connected; } - /** Gets the URL to an icon representing this external input. */ + /** @return the URL to an icon representing this external input. */ public String getIconURL() { return iconURL; } - /** Sets the URL to an icon representing this external input. */ + /** @param iconURL the URL to an icon representing this external input. */ public void setIconURL(String iconURL) { this.iconURL = iconURL; } @@ -105,20 +105,36 @@ public JSONObject toJSONObject() throws JSONException { } // @endcond - /** - * Compares two ExternalInputInfo objects. - * - * @param externalInputInfo ExternalInputInfo object to compare. - * - * @return YES if both ExternalInputInfo id & name values are equal - */ @Override - public boolean equals(Object o) { - if (o instanceof ExternalInputInfo) { - ExternalInputInfo eii = (ExternalInputInfo) o; - return this.id.equals(eii.id) && - this.name.equals(eii.name); - } - return false; + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ExternalInputInfo other = (ExternalInputInfo) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; } + + } diff --git a/src/com/connectsdk/core/ImageInfo.java b/src/com/connectsdk/core/ImageInfo.java index 88fdd95e..d4d9a7db 100644 --- a/src/com/connectsdk/core/ImageInfo.java +++ b/src/com/connectsdk/core/ImageInfo.java @@ -29,7 +29,7 @@ public class ImageInfo { /** * Default constructor method. - * @param url + * @param url the url */ public ImageInfo(String url) { @@ -37,12 +37,6 @@ public ImageInfo(String url) { this.url = url; } - /** - * Default constructor method. - * @param url, type, width, height - * add type of file, width and height of image. - */ - public ImageInfo(String url, ImageType type, int width, int height) { this(url); this.type = type; @@ -50,7 +44,6 @@ public ImageInfo(String url, ImageType type, int width, int height) { this.height = height; } - public enum ImageType { Thumb, Video_Poster, Album_Art, Unknown } @@ -60,75 +53,36 @@ public enum ImageType { private int width; private int height; - /** - * Gets URL address of an image file. - * - */ - public String getUrl() { return url; } - - /** - * Sets URL address of an image file. - * - */ - public void setUrl(String url) { this.url = url; - } - - /** - * Gets a type of an image file. - * - */ + } public ImageType getType() { return type; } - /** - * Sets a type of an image file. - * - */ - + public void setType(ImageType type) { this.type = type; } - /** - * Gets a width of an image. - * - */ - + public int getWidth() { return width; } - /** - * Sets a width of an image. - * - */ - public void setWidth(int width) { this.width = width; } - /** - * Gets a height of an image. - * - */ - public int getHeight() { return height; } - /** - * Sets a height of an image. - * - */ - public void setHeight(int height) { this.height = height; } diff --git a/src/com/connectsdk/core/Log.java b/src/com/connectsdk/core/Log.java new file mode 100644 index 00000000..3ae22e0e --- /dev/null +++ b/src/com/connectsdk/core/Log.java @@ -0,0 +1,31 @@ +package com.connectsdk.core; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class Log { + + private static final Logger l = LoggerFactory.getLogger(Log.class); + + public static int d(java.lang.String tag, java.lang.String msg) { + l.debug(String.format("%s - %s", tag, msg)); + return 0; + } + + public static int w(java.lang.String tag, java.lang.String msg) { + l.warn(String.format("%s - %s", tag, msg)); + return 0; + } + + public static int e(java.lang.String tag, java.lang.String msg) { + l.error(String.format("%s - %s",tag, msg)); + return 0; + } + + public static int e(java.lang.String tag, java.lang.String msg, java.lang.Throwable tr) { + l.error(String.format("%s - %s",tag, msg), tr); + return 0; + } + + +} diff --git a/src/com/connectsdk/core/MediaInfo.java b/src/com/connectsdk/core/MediaInfo.java index b05c2cbf..32796de8 100644 --- a/src/com/connectsdk/core/MediaInfo.java +++ b/src/com/connectsdk/core/MediaInfo.java @@ -20,8 +20,6 @@ package com.connectsdk.core; -import android.support.annotation.NonNull; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -154,58 +152,35 @@ public MediaInfo(String url, String mimeType, String title, String description, this.allImages = allImages; } - /** - * Gets type of a media file. - */ public String getMimeType() { return mimeType; } - /** - * Sets type of a media file. - * - * This method is deprecated - */ @Deprecated public void setMimeType(String mimeType) { this.mimeType = mimeType; } - /** - * Gets title for a media file. - */ public String getTitle() { return title; } - /** - * Sets title of a media file. - * - * This method is deprecated - */ @Deprecated public void setTitle(String title) { this.title = title; } - /** - * Gets description for a media. - */ public String getDescription() { return description; } - /** - * Sets description for a media. - * This method is deprecated - */ @Deprecated public void setDescription(String description) { this.description = description; } /** - * Gets list of ImageInfo objects for images representing a media (ex. icon, poster). + * @return list of ImageInfo objects for images representing a media (ex. icon, poster). * Where first ([0]) is icon image, and second ([1]) is poster image. */ public List getImages() { @@ -216,40 +191,26 @@ public List getImages() { * Sets list of ImageInfo objects for images representing a media (ex. icon, poster). * Where first ([0]) is icon image, and second ([1]) is poster image. * - * This method is deprecated + * @param images the pair of images */ @Deprecated public void setImages(List images) { this.allImages = images; } - /** - * Gets duration of a media file. - */ public long getDuration() { return duration; } - /** - * Sets duration of a media file. - * This method is deprecated - */ @Deprecated public void setDuration(long duration) { this.duration = duration; } - /** - * Gets URL address of a media file. - */ public String getUrl() { return url; } - /** - * Sets URL address of a media file. - * This method is deprecated - */ @Deprecated public void setUrl(String url) { this.url = url; @@ -259,11 +220,6 @@ public SubtitleInfo getSubtitleInfo() { return subtitleInfo; } - /** - * Stores ImageInfo objects. - * - * This method is deprecated - */ @Deprecated public void addImages(ImageInfo... images) { if (images == null) { diff --git a/src/com/connectsdk/core/NonNull.java b/src/com/connectsdk/core/NonNull.java new file mode 100644 index 00000000..7658b124 --- /dev/null +++ b/src/com/connectsdk/core/NonNull.java @@ -0,0 +1,16 @@ +package com.connectsdk.core; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.CLASS; +/** + * Denotes that a parameter, field or method return value can never be null. + *

+ * This is a marker annotation and it has no specific attributes. + */ +@Retention(CLASS) +@Target({METHOD, PARAMETER, FIELD}) +public @interface NonNull { +} \ No newline at end of file diff --git a/src/com/connectsdk/core/PointF.java b/src/com/connectsdk/core/PointF.java new file mode 100644 index 00000000..8112afc6 --- /dev/null +++ b/src/com/connectsdk/core/PointF.java @@ -0,0 +1,11 @@ +package com.connectsdk.core; + +public class PointF { + public PointF(float x, float y) { + this.x = x; + this.y = y; + } + + public float x; + public float y; +} diff --git a/src/com/connectsdk/core/ProgramInfo.java b/src/com/connectsdk/core/ProgramInfo.java index 57e42312..31f778bf 100644 --- a/src/com/connectsdk/core/ProgramInfo.java +++ b/src/com/connectsdk/core/ProgramInfo.java @@ -31,60 +31,76 @@ public class ProgramInfo { private Object rawData; // @endcond - /** Gets the ID of the program on the first screen device. Format is different depending on the platform. */ + /** Returns the ID of the program on the first screen device. Format is different depending on the platform. + * @return the ID */ public String getId() { return id; } - /** Sets the ID of the program on the first screen device. Format is different depending on the platform. */ + /** Sets the ID of the program on the first screen device. Format is different depending on the platform. + * @param id the ID */ public void setId(String id) { this.id = id; } - /** Gets the user-friendly name of the program (ex. Sesame Street, Cosmos, Game of Thrones, etc). */ + /** @return the user-friendly name of the program (ex. Sesame Street, Cosmos, Game of Thrones, etc). */ public String getName() { return name; } - /** Sets the user-friendly name of the program (ex. Sesame Street, Cosmos, Game of Thrones, etc). */ + /** Sets the user-friendly name of the program (ex. Sesame Street, Cosmos, Game of Thrones, etc). + * @param name the name */ public void setName(String name) { this.name = name; } - /** Gets the reference to the ChannelInfo object that this program is associated with */ public ChannelInfo getChannelInfo() { return channelInfo; } - /** Sets the reference to the ChannelInfo object that this program is associated with */ public void setChannelInfo(ChannelInfo channelInfo) { this.channelInfo = channelInfo; } - /** Gets the raw data from the first screen device about the program. In most cases, this is an NSDictionary. */ + /** @return the raw data from the first screen device about the program. In most cases, this is an NSDictionary. */ public Object getRawData() { return rawData; } - /** Sets the raw data from the first screen device about the program. In most cases, this is an NSDictionary. */ public void setRawData(Object rawData) { this.rawData = rawData; } - /** - * Compares two ProgramInfo objects. - * - * @param programInfo ProgramInfo object to compare. - * - * @return true if both ProgramInfo id & name values are equal - */ @Override - public boolean equals(Object o) { - if (o instanceof ProgramInfo) { - ProgramInfo pi = (ProgramInfo) o; - return pi.id.equals(pi.id) && - pi.name.equals(pi.name); - } - return super.equals(o); + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ProgramInfo other = (ProgramInfo) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + } diff --git a/src/com/connectsdk/core/SubtitleInfo.java b/src/com/connectsdk/core/SubtitleInfo.java index d14bfa7f..3ea33818 100644 --- a/src/com/connectsdk/core/SubtitleInfo.java +++ b/src/com/connectsdk/core/SubtitleInfo.java @@ -19,22 +19,22 @@ */ package com.connectsdk.core; -import android.support.annotation.NonNull; - /** * Normalized reference object for information about a subtitle track. It's used in `MediaInfo` class. * The only one required parameter is `url`, others can be `null`. This class is immutable and has * a builder for easy construction. * * Different services support specific subtitle formats: - * - `DLNAService` supports only SRT subtitles. Since there is no official specification for them, - * subtitles may not work on all DLNA-compatible devices - * - `NetcastTVService` supports only SRT subtitles and has the same restrictions as `DLNAService` - * - `CastService` supports only WebVTT subtitles and it has additional requirements - * @see {@link https://developers.google.com/cast/docs/android_sender#cors-requirements} - * - `FireTVService` supports only WebVTT subtitles - * - `WebOSTVService` supports WebVTT subtitles. Server providing subtitles should - * support CORS headers, similarly to Cast service's requirements. + *

    + *
  • `DLNAService` supports only SRT subtitles. Since there is no official specification for them, + * subtitles may not work on all DLNA-compatible devices
  • + *
  • `NetcastTVService` supports only SRT subtitles and has the same restrictions as `DLNAService`
  • + *
  • `CastService` supports only WebVTT subtitles and it has additional + * requirements
  • + *
  • `FireTVService` supports only WebVTT subtitles
  • + *
  • `WebOSTVService` supports WebVTT subtitles. Server providing subtitles should + * support CORS headers, similarly to Cast service's requirements.
  • + *
* */ public class SubtitleInfo { diff --git a/src/com/connectsdk/core/TextInputStatusInfo.java b/src/com/connectsdk/core/TextInputStatusInfo.java index b31237a2..e43587d7 100644 --- a/src/com/connectsdk/core/TextInputStatusInfo.java +++ b/src/com/connectsdk/core/TextInputStatusInfo.java @@ -55,7 +55,8 @@ public void setFocused(boolean focused) { this.focused = focused; } - /** Gets the type of keyboard that should be displayed to the user. */ + /** Gets the type of keyboard that should be displayed to the user. + * @return the keyboard type */ public TextInputType getTextInputType() { TextInputType textInputType = TextInputType.DEFAULT; @@ -77,7 +78,8 @@ else if (contentType.equals("email")) { return textInputType; } - /** Sets the type of keyboard that should be displayed to the user. */ + /** Sets the type of keyboard that should be displayed to the user. + * @param textInputType the keyboard type*/ public void setTextInputType(TextInputType textInputType) { switch (textInputType) { case NUMBER: @@ -135,12 +137,12 @@ public void setHiddenText(boolean hiddenText) { this.hiddenText = hiddenText; } - /** Gets the raw data from the first screen device about the text input status. */ + /** @return the raw data from the first screen device about the text input status. */ public JSONObject getRawData() { return rawData; } - /** Sets the raw data from the first screen device about the text input status. */ + /** @param data the raw data from the first screen device about the text input status. */ public void setRawData(JSONObject data) { rawData = data; } diff --git a/src/com/connectsdk/core/Util.java b/src/com/connectsdk/core/Util.java index 75378138..d43a0497 100644 --- a/src/com/connectsdk/core/Util.java +++ b/src/com/connectsdk/core/Util.java @@ -20,78 +20,52 @@ package com.connectsdk.core; -import java.net.InetAddress; -import java.net.UnknownHostException; + + import java.util.Date; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import org.apache.http.conn.util.InetAddressUtils; -import android.content.Context; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.os.Handler; -import android.os.Looper; - import com.connectsdk.service.capability.listeners.ErrorListener; import com.connectsdk.service.capability.listeners.ResponseListener; import com.connectsdk.service.command.ServiceCommandError; -public final class Util { - static public String T = "Connect SDK"; - static private Handler handler; - static private final int NUM_OF_THREADS = 20; +public final class Util { + static public final String T = "Connect SDK"; - static private Executor executor; + static private ExecutorService executor; - static { - createExecutor(); + /** + * Configure Util on component start. + * + * @param e must not be null + */ + public static void init(ExecutorService e) { + executor = e; } - static void createExecutor() { - Util.executor = Executors.newFixedThreadPool(NUM_OF_THREADS, new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread th = new Thread(r); - th.setName("2nd Screen BG"); - return th; - } - }); + public static void uninit() { + executor = null; } public static void runOnUI(Runnable runnable) { - if (handler == null) { - handler = new Handler(Looper.getMainLooper()); - } - - handler.post(runnable); + // no UI in openhab + runInBackground(runnable, true); } public static void runInBackground(Runnable runnable, boolean forceNewThread) { - if (forceNewThread || isMain()) { - executor.execute(runnable); - } else { - runnable.run(); - } - + executor.execute(runnable); } public static void runInBackground(Runnable runnable) { runInBackground(runnable, false); } - public static Executor getExecutor() { - return executor; - } - - public static boolean isMain() { - return Looper.myLooper() == Looper.getMainLooper(); - } + public static void postSuccess(final ResponseListener listener, final T object) { if (listener == null) @@ -117,15 +91,7 @@ public void run() { listener.onError(error); } }); - } - - public static byte[] convertIpAddress(int ip) { - return new byte[] { - (byte) (ip & 0xFF), - (byte) ((ip >> 8) & 0xFF), - (byte) ((ip >> 16) & 0xFF), - (byte) ((ip >> 24) & 0xFF)}; - } + } public static long getTime() { return TimeUnit.MILLISECONDS.toSeconds(new Date().getTime()); @@ -135,21 +101,5 @@ public static boolean isIPv4Address(String ipAddress) { return InetAddressUtils.isIPv4Address(ipAddress); } - public static boolean isIPv6Address(String ipAddress) { - return InetAddressUtils.isIPv6Address(ipAddress); - } - - public static InetAddress getIpAddress(Context context) throws UnknownHostException { - WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); - WifiInfo wifiInfo = wifiMgr.getConnectionInfo(); - int ip = wifiInfo.getIpAddress(); - - if (ip == 0) { - return null; - } - else { - byte[] ipAddress = convertIpAddress(ip); - return InetAddress.getByAddress(ipAddress); - } - } + } \ No newline at end of file diff --git a/src/com/connectsdk/device/ConnectableDevice.java b/src/com/connectsdk/device/ConnectableDevice.java index d63230e5..a12e8fa4 100644 --- a/src/com/connectsdk/device/ConnectableDevice.java +++ b/src/com/connectsdk/device/ConnectableDevice.java @@ -31,8 +31,7 @@ import org.json.JSONException; import org.json.JSONObject; -import android.util.Log; - +import com.connectsdk.core.Log; import com.connectsdk.core.Util; import com.connectsdk.discovery.DiscoveryManager; import com.connectsdk.service.DeviceService; @@ -97,7 +96,7 @@ public class ConnectableDevice implements DeviceServiceListener { Map services; - public boolean featuresReady = false; + //public boolean featuresReady = false; public ConnectableDevice() { services = new ConcurrentHashMap(); @@ -152,8 +151,8 @@ public void setServiceDescription(ServiceDescription serviceDescription) { // @endcond /** - * set desirable pairing type for all services - * @param pairingType + * Set desirable pairing type for all services. + * @param pairingType the pairing type */ public void setPairingType(PairingType pairingType) { Collection services = getServices(); @@ -232,7 +231,7 @@ private synchronized List getMismatchCapabilities(List capabilit return list; } - /** Array of all currently discovered DeviceServices this ConnectableDevice has associated with it. */ + /** @return Collection of all currently discovered DeviceServices this ConnectableDevice has associated with it. */ public Collection getServices() { return services.values(); } @@ -263,9 +262,10 @@ public void removeServiceByName(String serviceName) { } /** - * Returns a DeviceService from the ConnectableDevice instance. serviceUUID is used as the identifier because only one instance of each DeviceService type may be attached to a single ConnectableDevice instance. + * Get DeviceService from the ConnectableDevice instance. serviceUUID is used as the identifier because only one instance of each DeviceService type may be attached to a single ConnectableDevice instance. * * @param serviceUUID UUID of the DeviceService to be returned + * @return DeviceService from the ConnectableDevice instance */ public DeviceService getServiceWithUUID(String serviceUUID) { for (DeviceService service : getServices()) { @@ -370,7 +370,7 @@ public boolean isConnected() { // @endcond /** - * Whether the device has any DeviceServices that require an active connection (websocket, HTTP registration, etc) + * @return true, if the device has any DeviceServices that require an active connection (websocket, HTTP registration, etc) */ public boolean isConnectable() { for (DeviceService service: services.values()) { @@ -399,7 +399,7 @@ public void cancelPairing() { } } - /** A combined list of all capabilities that are supported among the detected DeviceServices. */ + /** @return A combined list of all capabilities that are supported among the detected DeviceServices. */ public synchronized List getCapabilities() { List caps = new ArrayList(); @@ -422,6 +422,7 @@ public synchronized List getCapabilities() { * Example: `Launcher.App.Any` * * @param capability Capability to test against + * @return true if the capbaility exists */ public boolean hasCapability(String capability) { boolean hasCap = false; @@ -442,6 +443,7 @@ public boolean hasCapability(String capability) { * See hasCapability: for a description of the wildcard feature provided by this method. * * @param capabilities Array of capabilities to test against + * @return true if at least one capability exists */ public boolean hasAnyCapability(String... capabilities) { for (DeviceService service : services.values()) { @@ -458,6 +460,7 @@ public boolean hasAnyCapability(String... capabilities) { * See hasCapability: for a description of the wildcard feature provided by this method. * * @param capabilities Array of capabilities to test against + * @return true if the device has all those capabilities */ public synchronized boolean hasCapabilities(List capabilities) { String[] arr = new String[capabilities.size()]; @@ -471,6 +474,7 @@ public synchronized boolean hasCapabilities(List capabilities) { * See hasCapability: for a description of the wildcard feature provided by this method. * * @param capabilites Array of capabilities to test against + * @return true if the device has all those capabilities */ public synchronized boolean hasCapabilities(String... capabilites) { boolean hasCaps = true; @@ -485,140 +489,12 @@ public synchronized boolean hasCapabilities(String... capabilites) { return hasCaps; } - /** - * Accessor for highest priority Launcher object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public Launcher getLauncher() { - return getCapability(Launcher.class); - } - - /** - * Accessor for highest priority MediaPlayer object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public MediaPlayer getMediaPlayer() { - return getCapability(MediaPlayer.class); - } - - /** - * Accessor for highest priority MediaControl object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public MediaControl getMediaControl() { - return getCapability(MediaControl.class); - } - - /** - * Accessor for highest priority PlaylistControl object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public PlaylistControl getPlaylistControl() { - return getCapability(PlaylistControl.class); - } - - /** - * Accessor for highest priority VolumeControl object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public VolumeControl getVolumeControl() { - return getCapability(VolumeControl.class); - } - - /** - * Accessor for highest priority WebAppLauncher object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public WebAppLauncher getWebAppLauncher() { - return getCapability(WebAppLauncher.class); - } - - /** - * Accessor for highest priority TVControl object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public TVControl getTVControl() { - return getCapability(TVControl.class); - } - - /** - * Accessor for highest priority ToastControl object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public ToastControl getToastControl() { - return getCapability(ToastControl.class); - } - - /** - * Accessor for highest priority TextInputControl object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public TextInputControl getTextInputControl() { - return getCapability(TextInputControl.class); - } - - /** - * Accessor for highest priority MouseControl object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public MouseControl getMouseControl() { - return getCapability(MouseControl.class); - } - - /** - * Accessor for highest priority ExternalInputControl object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public ExternalInputControl getExternalInputControl() { - return getCapability(ExternalInputControl.class); - } - - /** - * Accessor for highest priority PowerLauncher object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public PowerControl getPowerControl() { - return getCapability(PowerControl.class); - } - - /** - * Accessor for highest priority KeyControl object - * This method is deprecated. Use - * `ConnectableDevice#getCapability(Class controllerClass)` method instead - */ - @Deprecated - public KeyControl getKeyControl() { - return getCapability(KeyControl.class); - } /** * Get a capability with the highest priority from a device. If device doesn't have such * capability then returns null. * @param controllerClass type of capability + * @param a capability methods class * @return capability implementation */ public T getCapability(Class controllerClass) { @@ -659,7 +535,7 @@ public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; } - /** Gets the Current IP address of the ConnectableDevice. */ + /** @return the Current IP address of the ConnectableDevice. */ public String getIpAddress() { return ipAddress; } @@ -673,7 +549,7 @@ public void setFriendlyName(String friendlyName) { this.friendlyName = friendlyName; } - /** Gets an estimate of the ConnectableDevice's current friendly name. */ + /** @return an estimate of the ConnectableDevice's current friendly name. */ public String getFriendlyName() { return friendlyName; } @@ -681,13 +557,13 @@ public String getFriendlyName() { /** * Sets the last IP address this ConnectableDevice was discovered at. * - * @param lastKnownIPAddress Last known IP address of the device & it's services + * @param lastKnownIPAddress Last known IP address of the device & it's services */ public void setLastKnownIPAddress(String lastKnownIPAddress) { this.lastKnownIPAddress = lastKnownIPAddress; } - /** Gets the last IP address this ConnectableDevice was discovered at. */ + /** @return the last IP address this ConnectableDevice was discovered at. */ public String getLastKnownIPAddress() { return lastKnownIPAddress; } @@ -695,13 +571,13 @@ public String getLastKnownIPAddress() { /** * Sets the name of the last wireless network this ConnectableDevice was discovered on. * - * @param lastSeenOnWifi Last Wi-Fi network this device & it's services were discovered on + * @param lastSeenOnWifi Last Wi-Fi network this device & it's services were discovered on */ public void setLastSeenOnWifi(String lastSeenOnWifi) { this.lastSeenOnWifi = lastSeenOnWifi; } - /** Gets the name of the last wireless network this ConnectableDevice was discovered on. */ + /** @return the name of the last wireless network this ConnectableDevice was discovered on. */ public String getLastSeenOnWifi() { return lastSeenOnWifi; } @@ -715,7 +591,7 @@ public void setLastConnected(long lastConnected) { this.lastConnected = lastConnected; } - /** Gets the last time (in milli seconds from 1970) that this ConnectableDevice was connected to. */ + /** @return the last time (in milli seconds from 1970) that this ConnectableDevice was connected to. */ public long getLastConnected() { return lastConnected; } @@ -729,7 +605,7 @@ public void setLastDetection(long lastDetection) { this.lastDetection = lastDetection; } - /** Gets the last time (in milli seconds from 1970) that this ConnectableDevice was detected. */ + /** @return the last time (in milli seconds from 1970) that this ConnectableDevice was detected. */ public long getLastDetection() { return lastDetection; } @@ -743,7 +619,7 @@ public void setModelName(String modelName) { this.modelName = modelName; } - /** Gets an estimate of the ConnectableDevice's current model name. */ + /** @return an estimate of the ConnectableDevice's current model name. */ public String getModelName() { return modelName; } @@ -757,7 +633,7 @@ public void setModelNumber(String modelNumber) { this.modelNumber = modelNumber; } - /** Gets an estimate of the ConnectableDevice's current model number. */ + /** @return an estimate of the ConnectableDevice's current model number. */ public String getModelNumber() { return modelNumber; } @@ -771,7 +647,7 @@ public void setId(String id) { } /** - * Universally unique id of this particular ConnectableDevice object, persists between sessions in ConnectableDeviceStore for connected devices + * @return universally unique id of this particular ConnectableDevice object, persists between sessions in ConnectableDeviceStore for connected devices */ public String getId() { if (this.id == null) diff --git a/src/com/connectsdk/device/ConnectableDeviceListener.java b/src/com/connectsdk/device/ConnectableDeviceListener.java index ff1fbbaa..ef00a7e5 100644 --- a/src/com/connectsdk/device/ConnectableDeviceListener.java +++ b/src/com/connectsdk/device/ConnectableDeviceListener.java @@ -61,13 +61,13 @@ public interface ConnectableDeviceListener { public void onPairingRequired(ConnectableDevice device, DeviceService service, PairingType pairingType); /** - * When a ConnectableDevice finds & loses DeviceServices, that ConnectableDevice will experience a change in its collective capabilities list. When such a change occurs, this message will be sent with arrays of capabilities that were added & removed. + * When a ConnectableDevice finds & loses DeviceServices, that ConnectableDevice will experience a change in its collective capabilities list. When such a change occurs, this message will be sent with arrays of capabilities that were added & removed. * * This message will allow you to decide when to stop/start interacting with a ConnectableDevice, based off of its supported capabilities. * * @param device ConnectableDevice that has experienced a change in capabilities - * @param added List of capabilities that are new to the ConnectableDevice - * @param removed List of capabilities that the ConnectableDevice has lost + * @param added capabilities that are new to the ConnectableDevice + * @param removed capabilities that the ConnectableDevice has lost */ public void onCapabilityUpdated(ConnectableDevice device, List added, List removed); diff --git a/src/com/connectsdk/device/ConnectableDeviceStore.java b/src/com/connectsdk/device/ConnectableDeviceStore.java index 44fc843b..db10fcfa 100644 --- a/src/com/connectsdk/device/ConnectableDeviceStore.java +++ b/src/com/connectsdk/device/ConnectableDeviceStore.java @@ -63,7 +63,7 @@ public interface ConnectableDeviceStore { public void updateDevice(ConnectableDevice device); /** - * A JSONObject of all ConnectableDevices in the ConnectableDeviceStore. To gt a strongly-typed ConnectableDevice object, use the `getDevice(String);` method. + * @return a JSONObject of all ConnectableDevices in the ConnectableDeviceStore. To get a strongly-typed ConnectableDevice object, use the `getDevice(String);` method. */ public JSONObject getStoredDevices(); diff --git a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java index 6ff0b0f4..c0899774 100644 --- a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java +++ b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java @@ -21,10 +21,18 @@ package com.connectsdk.device; import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.File; +import java.io.FileInputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.InputStreamReader; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.io.FileOutputStream; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -33,10 +41,8 @@ import org.json.JSONException; import org.json.JSONObject; -import android.content.Context; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Environment; - +import com.connectsdk.core.Context; +import com.connectsdk.core.Log; import com.connectsdk.core.Util; import com.connectsdk.service.DeviceService; import com.connectsdk.service.config.ServiceConfig; @@ -88,10 +94,6 @@ public class DefaultConnectableDeviceStore implements ConnectableDeviceStore { /** Current version of the ConnectableDeviceStore, may be necessary for migrations */ public int version; - /** - * Max length of time for a ConnectableDevice to remain in the ConnectableDeviceStore without being discovered. Default is 3 days, and modifications to this value will trigger a scan for old devices. - */ - public long maxStoreDuration = TimeUnit.DAYS.toSeconds(3); // @cond INTERNAL private String fileFullPath; @@ -99,24 +101,9 @@ public class DefaultConnectableDeviceStore implements ConnectableDeviceStore { private Map storedDevices = new ConcurrentHashMap(); private Map activeDevices = new ConcurrentHashMap(); - private boolean waitToWrite = false; - public DefaultConnectableDeviceStore(Context context) { - String dirPath; - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - dirPath = Environment.getExternalStorageDirectory().getAbsolutePath(); - } - else { - dirPath = Environment.MEDIA_UNMOUNTED; - } - fileFullPath = dirPath + DIRPATH + FILENAME; - - try { - fileFullPath = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).applicationInfo.dataDir + "/" + FILENAME; - } catch (NameNotFoundException e) { - e.printStackTrace(); - } - + fileFullPath = context.getDataDir() + "/" + FILENAME; + load(); } // @endcond @@ -289,29 +276,21 @@ public ServiceConfig getServiceConfig(ServiceDescription serviceDescription) { private void load() { String line; - BufferedReader in = null; - File file = new File(fileFullPath); if (!file.exists()) { version = CURRENT_VERSION; - created = Util.getTime(); updated = Util.getTime(); } else { - boolean encounteredException = false; - - try { - in = new BufferedReader(new FileReader(file)); - + try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))){ + StringBuilder sb = new StringBuilder(); while ((line = in.readLine()) != null) { sb.append(line); } - in.close(); - JSONObject data = new JSONObject(sb.toString()); JSONArray deviceArray = data.optJSONArray(KEY_DEVICES); if (deviceArray != null) { @@ -324,32 +303,22 @@ private void load() { version = data.optInt(KEY_VERSION, CURRENT_VERSION); created = data.optLong(KEY_CREATED, 0); updated = data.optLong(KEY_UPDATED, 0); - } catch (IOException e) { + } catch (IOException|JSONException e) { e.printStackTrace(); - - // it is likely that the device store has been corrupted - encounteredException = true; - } catch (JSONException e) { - e.printStackTrace(); - - // it is likely that the device store has been corrupted - encounteredException = true; - } - - if (encounteredException && storedDevices == null) { - file.delete(); - - version = CURRENT_VERSION; - - created = Util.getTime(); - updated = Util.getTime(); - } + } } } - private void store() { + private synchronized void store() { updated = Util.getTime(); + File output = new File(fileFullPath); + + if (!output.exists() && !output.getParentFile().mkdirs()) { + Log.e(Util.T, "Failed to create folders structure to device store "+output.getParentFile().toString()); + return; + } + JSONObject deviceStore = new JSONObject(); try { deviceStore.put(KEY_VERSION, version); @@ -357,42 +326,16 @@ private void store() { deviceStore.put(KEY_UPDATED, updated); JSONArray deviceArray = new JSONArray(storedDevices.values()); deviceStore.put(KEY_DEVICES, deviceArray); - } catch (JSONException e) { + + + try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output), StandardCharsets.UTF_8))) { + out.write(deviceStore.toString()); + } + } catch (JSONException|IOException e) { e.printStackTrace(); - } - - if (!waitToWrite) - writeStoreToDisk(deviceStore); + } } - private synchronized void writeStoreToDisk(final JSONObject deviceStore) { - final long lastUpdate = updated; - waitToWrite = true; - - Util.runInBackground(new Runnable() { - - @Override - public void run() { - FileWriter out; - try { - File output = new File(fileFullPath); - - if (!output.exists()) - output.getParentFile().mkdirs(); - out = new FileWriter(output); - out.write(deviceStore.toString()); - out.close(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - waitToWrite = false; - } - - if (lastUpdate < updated) - writeStoreToDisk(deviceStore); - } - }); - } // @endcond } diff --git a/src/com/connectsdk/device/DevicePicker.java b/src/com/connectsdk/device/DevicePicker.java deleted file mode 100644 index 9e4c655b..00000000 --- a/src/com/connectsdk/device/DevicePicker.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * DevicePicker - * Connect SDK - * - * Copyright (c) 2014 LG Electronics. - * Created by Hyun Kook Khang on 19 Jan 2014 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.device; - -import android.app.Activity; -import android.app.AlertDialog; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; -import android.widget.TextView; - -/** - * ###Overview - * The DevicePicker is provided by the DiscoveryManager as a simple way for you to present a list of available devices to your users. - * - * ###In Depth - * By calling the getPickerDialog you will get a reference to the AlertDialog that will be updated automatically updated as compatible devices are discovered. - */ -public class DevicePicker { - Activity activity; - ConnectableDevice device; - - /** - * Creates a new DevicePicker - * - * @param activity Activity that DevicePicker will appear in - */ - public DevicePicker(Activity activity) { - this.activity = activity; - } - - public ListView getListView() { - return new DevicePickerListView(activity); - } - - /** - * Sets a selected device. - * - * @param device Device that has been selected. - */ - public void pickDevice(ConnectableDevice device) { - this.device = device; - } - - /** - * Cancels pairing with the currently selected device. - */ - public void cancelPicker() { - if (device != null) { - device.cancelPairing(); - } - device = null; - } - - /** - * This method will return an AlertDialog that contains a ListView with an item for each discovered ConnectableDevice. - * - * @param message The title for the AlertDialog - * @param listener The listener for the ListView to get the item that was clicked on - */ - public AlertDialog getPickerDialog(String message, final OnItemClickListener listener) { - final DevicePickerListView view = new DevicePickerListView(activity); - - TextView title = (TextView) activity.getLayoutInflater().inflate(android.R.layout.simple_list_item_1, null); - title.setText(message); - - final AlertDialog pickerDialog = new AlertDialog.Builder(activity) - .setCustomTitle(title) - .setCancelable(true) - .setView(view) - .create(); - - view.setOnItemClickListener(new OnItemClickListener () { - @Override - public void onItemClick(AdapterView arg0, View arg1, int arg2, - long arg3) { - listener.onItemClick(arg0, arg1, arg2, arg3); - pickerDialog.dismiss(); - } - }); - - return pickerDialog; - } -} diff --git a/src/com/connectsdk/device/DevicePickerAdapter.java b/src/com/connectsdk/device/DevicePickerAdapter.java deleted file mode 100644 index 48010a41..00000000 --- a/src/com/connectsdk/device/DevicePickerAdapter.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * DevicePickerAdaper - * Connect SDK - * - * Copyright (c) 2014 LG Electronics. - * Created by Hyun Kook Khang on 19 Jan 2014 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.device; - -import java.util.HashMap; - -import com.connectsdk.discovery.DiscoveryManager; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.graphics.Color; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TextView; - - -public class DevicePickerAdapter extends ArrayAdapter { - int resource, textViewResourceId, subTextViewResourceId; - HashMap currentDevices = new HashMap(); - Context context; - - DevicePickerAdapter(Context context) { - this(context, android.R.layout.simple_list_item_2); - } - - DevicePickerAdapter(Context context, int resource) { - this(context, resource, android.R.id.text1, android.R.id.text2); - } - - DevicePickerAdapter(Context context, int resource, int textViewResourceId, int subTextViewResourceId) { - super(context, resource, textViewResourceId); - this.context = context; - this.resource = resource; - this.textViewResourceId = textViewResourceId; - this.subTextViewResourceId = subTextViewResourceId; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View view = convertView; - - if (convertView == null) { - view = View.inflate(getContext(), resource, null); - } - - ConnectableDevice device = this.getItem(position); - String text; - if (device.getFriendlyName() != null) { - text = device.getFriendlyName(); - } - else { - text = device.getModelName(); - } - - view.setBackgroundColor(Color.BLACK); - - TextView textView = (TextView) view.findViewById(textViewResourceId); - textView.setText(text); - textView.setTextColor(Color.WHITE); - - boolean isDebuggable = (0 != (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)); - boolean hasNoFilters = DiscoveryManager.getInstance().getCapabilityFilters().size() == 0; - - String serviceNames = device.getConnectedServiceNames(); - boolean hasServiceNames = (serviceNames != null && serviceNames.length() > 0); - - boolean shouldShowServiceNames = hasServiceNames && (isDebuggable || hasNoFilters); - - TextView subTextView = (TextView) view.findViewById(subTextViewResourceId); - - if (shouldShowServiceNames) { - subTextView.setText(serviceNames); - subTextView.setTextColor(Color.WHITE); - } else { - subTextView.setText(null); - } - - return view; - } -} diff --git a/src/com/connectsdk/device/DevicePickerListView.java b/src/com/connectsdk/device/DevicePickerListView.java deleted file mode 100644 index 373a9c8a..00000000 --- a/src/com/connectsdk/device/DevicePickerListView.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * DevicePickerListView - * Connect SDK - * - * Copyright (c) 2014 LG Electronics. - * Created by Hyun Kook Khang on 19 Jan 2014 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.device; - -import android.content.Context; -import android.widget.ListView; - -import com.connectsdk.core.Util; -import com.connectsdk.discovery.DiscoveryManager; -import com.connectsdk.discovery.DiscoveryManagerListener; -import com.connectsdk.service.command.ServiceCommandError; - -public class DevicePickerListView extends ListView implements DiscoveryManagerListener { - DevicePickerAdapter pickerAdapter; - - public DevicePickerListView(Context context) { - super(context); - - pickerAdapter = new DevicePickerAdapter(context); - - setAdapter(pickerAdapter); - - DiscoveryManager.getInstance().addListener(this); - } - - @Override - public void onDiscoveryFailed(DiscoveryManager manager, ServiceCommandError error) { - Util.runOnUI(new Runnable () { - @Override - public void run() { - pickerAdapter.clear(); - } - }); - } - - @Override - public void onDeviceAdded(DiscoveryManager manager, final ConnectableDevice device) { - Util.runOnUI(new Runnable () { - @Override - public void run() { - int index = -1; - for (int i = 0; i < pickerAdapter.getCount(); i++) { - ConnectableDevice d = pickerAdapter.getItem(i); - - String newDeviceName = device.getFriendlyName(); - String dName = d.getFriendlyName(); - - if (newDeviceName == null) { - newDeviceName = device.getModelName(); - } - - if (dName == null) { - dName = d.getModelName(); - } - - if (d.getIpAddress().equals(device.getIpAddress())) { - pickerAdapter.remove(d); - pickerAdapter.insert(device, i); - return; - } - - if (newDeviceName.compareToIgnoreCase(dName) < 0) { - index = i; - pickerAdapter.insert(device, index); - break; - } - } - - if (index == -1) - pickerAdapter.add(device); - } - }); - } - - @Override - public void onDeviceUpdated(DiscoveryManager manager, final ConnectableDevice device) { - Util.runOnUI(new Runnable () { - @Override - public void run() { - pickerAdapter.notifyDataSetChanged(); - } - }); - } - - @Override - public void onDeviceRemoved(DiscoveryManager manager, final ConnectableDevice device) { - Util.runOnUI(new Runnable () { - @Override - public void run() { - pickerAdapter.remove(device); - } - }); - } -} diff --git a/src/com/connectsdk/device/DevicePickerListener.java b/src/com/connectsdk/device/DevicePickerListener.java index 08e08073..f5d57d01 100644 --- a/src/com/connectsdk/device/DevicePickerListener.java +++ b/src/com/connectsdk/device/DevicePickerListener.java @@ -3,13 +3,13 @@ public interface DevicePickerListener { /** * Called when the user selects a device. - * @param device + * @param device the selected device */ public void onPickDevice(ConnectableDevice device); /** * Called when the picker fails or was cancelled by the user. - * @param true if picker was canceled by user, false if due to error + * @param canceled true if picker was canceled by user, false if due to error */ public void onPickDeviceFailed(boolean canceled); } diff --git a/src/com/connectsdk/device/PairingDialog.java b/src/com/connectsdk/device/PairingDialog.java deleted file mode 100644 index c066e1cd..00000000 --- a/src/com/connectsdk/device/PairingDialog.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * PairingDialog - * Connect SDK - * - * Copyright (c) 2014 LG Electronics. - * Created by Hyun Kook Khang on 19 Jan 2014 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.device; - -import com.connectsdk.service.DeviceService; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.text.InputType; -import android.widget.EditText; -import android.widget.TextView; - - -public class PairingDialog { - Activity activity; - ConnectableDevice device; - - public PairingDialog(Activity activity, ConnectableDevice device) { - this.activity = activity; - this.device = device; - } - - public AlertDialog getSimplePairingDialog(int titleResId, int messageResId) { - return new AlertDialog.Builder(activity) - .setTitle(titleResId) - .setMessage(messageResId) - .setPositiveButton(android.R.string.cancel, null) - .create(); - } - - public AlertDialog getPairingDialog(int resId) { - return getPairingDialog(activity.getString(resId)); - } - - public AlertDialog getPairingDialog(String message) { - TextView title = (TextView) activity.getLayoutInflater().inflate(android.R.layout.simple_list_item_1, null); - title.setText(message); - - final EditText input = new EditText(activity); - input.setInputType(InputType.TYPE_CLASS_NUMBER); - - return new AlertDialog.Builder(activity) - .setCustomTitle(title) - .setView(input) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - String value = input.getText().toString().trim(); - for (DeviceService service : device.getServices()) - service.sendPairingKey(value); - } - }) - .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - dialog.cancel(); - // pickerDialog.dismiss(); - } - }) - .create(); - } -} diff --git a/src/com/connectsdk/device/SimpleDevicePicker.java b/src/com/connectsdk/device/SimpleDevicePicker.java deleted file mode 100644 index 4aa3aeac..00000000 --- a/src/com/connectsdk/device/SimpleDevicePicker.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * SimpleDevicePicker - * Connect SDK - * - * Copyright (c) 2014 LG Electronics. - * Created by Jason Lai on 19 Jan 2014 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.device; - -import java.util.List; - -import android.app.Activity; -import android.app.Dialog; -import android.content.res.Resources; -import android.util.Log; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.Toast; - -import com.connectsdk.core.Util; -import com.connectsdk.service.DeviceService; -import com.connectsdk.service.DeviceService.PairingType; -import com.connectsdk.service.command.ServiceCommandError; - -/** - * A device picker that automatically connects to the device - * and automatically displays pairing dialogs when needed. - * - * NOTE: Most methods MUST be called from the main ui thread. - */ -public class SimpleDevicePicker implements ConnectableDeviceListener { - protected Activity activity; - protected DevicePicker picker; - protected Dialog pickerDialog; - protected Dialog pairingDialog; - - // Device that we're in the process of connecting to - protected ConnectableDevice pendingDevice; - - // Connected, active device - protected ConnectableDevice activeDevice; - - protected int selectDeviceResId; - protected int simplePairingTitleResId; - protected int simplePairingPromptResId; - protected int pinPairingPromptResId; - protected int connectionFailedResId; - - SimpleDevicePickerListener listener; - private PairingType pairingType; - - public SimpleDevicePicker(Activity activity) { - this.activity = activity; - this.picker = new DevicePicker(activity); - - loadStringIds(); - } - - public void setPairingType(PairingType pairingType) { - this.pairingType = pairingType; - } - - /** - * Get the currently selected device - * @return current connected device - */ - public ConnectableDevice getCurrentDevice() { - return activeDevice; - } - - protected void loadStringIds() { - selectDeviceResId = getStringId("connect_sdk_picker_select_device"); - simplePairingTitleResId = getStringId("connect_sdk_pairing_simple_title_tv"); - simplePairingPromptResId = getStringId("connect_sdk_pairing_simple_prompt_tv"); - pinPairingPromptResId = getStringId("connect_sdk_pairing_pin_prompt_tv"); - connectionFailedResId = getStringId("connect_sdk_connection_failed"); - } - - protected int getStringId(String key) { - // First try to get resource from application - int id = this.activity.getResources().getIdentifier(key, "string", activity.getPackageName()); - - // Then try to get from Connect SDK library - if (id == 0) { - id = this.activity.getResources().getIdentifier(key, "string", "com.connectsdk"); - } - - if (id == 0) { - Log.w("ConnectSDK", "missing string resource for \"" + key + "\""); - - throw new Resources.NotFoundException(key); - } - - return id; - } - - public void setListener(SimpleDevicePickerListener listener) { - this.listener = listener; - } - - protected void cleanupPending() { - if (pendingDevice != null) { - pendingDevice.removeListener(this); - pendingDevice = null; - } - } - - protected void cleanupActive() { - if (activeDevice != null) { - activeDevice.removeListener(this); - activeDevice = null; - } - } - - public void showPicker() { - cleanupPending(); // remove any currently pending device - hidePicker(); - - pickerDialog = picker.getPickerDialog(activity.getString(selectDeviceResId), new OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapter, View view, int pos, - long id) { - ConnectableDevice device = (ConnectableDevice) adapter.getItemAtPosition(pos); - - selectDevice(device); - } - }); - - pickerDialog.show(); - } - - public void hidePicker() { - if (pickerDialog != null) { - pickerDialog.dismiss(); - pickerDialog = null; - } - } - - /** - * Connect to a device - * - * @param device - */ - public void selectDevice(ConnectableDevice device) { - if (device != null) { - pendingDevice = device; - pendingDevice.addListener(this); - - if (listener != null) { - // Give listener a chance to setup device before connecting - listener.onPrepareDevice(device); - } - - if (!device.isConnected()) { - device.setPairingType(pairingType); - device.connect(); - } else { - onDeviceReady(device); - } - } else { - cleanupPending(); - } - } - - protected Dialog createSimplePairingDialog() { - PairingDialog dialog = new PairingDialog(activity, pendingDevice); - return dialog.getSimplePairingDialog(simplePairingTitleResId, simplePairingPromptResId); - } - - protected Dialog createPinPairingDialog() { - PairingDialog dialog = new PairingDialog(activity, pendingDevice); - return dialog.getPairingDialog(pinPairingPromptResId); - } - - protected void showPairingDialog(PairingType pairingType) { - switch (pairingType) { - case FIRST_SCREEN: - pairingDialog = createSimplePairingDialog(); - break; - - case PIN_CODE: - case MIXED: - pairingDialog = createPinPairingDialog(); - break; - - case NONE: - default: - break; - } - - if (pairingDialog != null) { - pairingDialog.show(); - } - } - - /** - * Hide the current pairing dialog and cancels the pairing attempt. - */ - public void hidePairingDialog() { - // cancel pairing - if (pairingDialog != null) { - pairingDialog.dismiss(); - pairingDialog = null; - } - } - - - @Override - public void onDeviceReady(final ConnectableDevice device) { - Util.runOnUI(new Runnable() { - @Override - public void run() { - hidePairingDialog(); - - if (device == pendingDevice) { - activeDevice = pendingDevice; - - if (listener != null) { - listener.onPickDevice(pendingDevice); - } - pendingDevice = null; - } - } - }); - } - - @Override - public void onDeviceDisconnected(final ConnectableDevice device) { - if (device == pendingDevice) { - pickFailed(device); - } - - if (device == activeDevice) { - cleanupActive(); - } - } - - @Override - public void onCapabilityUpdated(ConnectableDevice device, List added, List removed) { - } - - @Override - public void onConnectionFailed(ConnectableDevice device, ServiceCommandError error) { - if (device == pendingDevice) { - pickFailed(device); - } - - if (device == activeDevice) { - cleanupActive(); - } - } - - @Override - public void onPairingRequired(ConnectableDevice device, DeviceService service, final PairingType pairingType) { - Log.d("SimpleDevicePicker", "pairing required for device " + device.getFriendlyName()); - - Util.runOnUI(new Runnable() { - @Override - public void run() { - showPairingDialog(pairingType); - } - }); - } - - protected void pickFailed(final ConnectableDevice device) { - Util.runOnUI(new Runnable() { - @Override - public void run() { - if (pendingDevice == device) { - // Device failed before successfully picking device - if (listener != null) { - listener.onPickDeviceFailed(false); - } - } - - cleanupPending(); - - Toast.makeText(activity, connectionFailedResId, Toast.LENGTH_SHORT).show(); - } - }); - } -} diff --git a/src/com/connectsdk/device/SimpleDevicePickerListener.java b/src/com/connectsdk/device/SimpleDevicePickerListener.java index 6d5ddd47..3182602c 100644 --- a/src/com/connectsdk/device/SimpleDevicePickerListener.java +++ b/src/com/connectsdk/device/SimpleDevicePickerListener.java @@ -6,20 +6,20 @@ public interface SimpleDevicePickerListener extends DevicePickerListener { * This callback can be used to prepare the device (request permissions, etc) * just before attempting to connect. * - * @param device + * @param device selected device */ public void onPrepareDevice(ConnectableDevice device); /** * Called when device is ready to use (requested permissions approved). - * @param device + * @param device that is ready to use */ public void onPickDevice(ConnectableDevice device); /** * Called when the picker is canceled by the user or if pairing * was unsuccessful. - * @param true if picker was canceled by user, false if due to error + * @param canceled true if picker was canceled by user, false if due to error */ public void onPickDeviceFailed(boolean canceled); } diff --git a/src/com/connectsdk/discovery/CapabilityFilter.java b/src/com/connectsdk/discovery/CapabilityFilter.java index f9e99745..3c558a6a 100644 --- a/src/com/connectsdk/discovery/CapabilityFilter.java +++ b/src/com/connectsdk/discovery/CapabilityFilter.java @@ -44,34 +44,32 @@ * * ###Examples * Filter for all devices that support video playback AND any media controls AND volume up/down. - * -@code - List capabilities = new ArrayList(); - capabilities.add(MediaPlayer.Display_Video); - capabilities.add(MediaControl.Any); - capabilities.add(VolumeControl.Volume_Up_Down); - - CapabilityFilter filter = - new CapabilityFilter(capabilities); - - DiscoveryManager.getInstance().setCapabilityFilters(filter); -@endcode + * + * List<String> capabilities = new ArrayList<String>(); + * capabilities.add(MediaPlayer.Display_Video); + * capabilities.add(MediaControl.Any); + * capabilities.add(VolumeControl.Volume_Up_Down); + * + * CapabilityFilter filter = + * new CapabilityFilter(capabilities); + * + * DiscoveryManager.getInstance().setCapabilityFilters(filter); + * * * Filter for all devices that support (video playback AND any media controls AND volume up/down) OR (image display). + * + * CapabilityFilter videoFilter = + * new CapabilityFilter( + * MediaPlayer.Display_Video, + * MediaControl.Any, + * VolumeControl.Volume_Up_Down); * -@code - CapabilityFilter videoFilter = - new CapabilityFilter( - MediaPlayer.Display_Video, - MediaControl.Any, - VolumeControl.Volume_Up_Down); - - CapabilityFilter imageFilter = - new CapabilityFilter( - MediaPlayer.Display_Image); - - DiscoveryManager.getInstance().setCapabilityFilters(videoFilter, imageFilter); -@endcode + * CapabilityFilter imageFilter = + * new CapabilityFilter( + * MediaPlayer.Display_Image); + * + * DiscoveryManager.getInstance().setCapabilityFilters(videoFilter, imageFilter); + * */ public class CapabilityFilter { diff --git a/src/com/connectsdk/discovery/DiscoveryManager.java b/src/com/connectsdk/discovery/DiscoveryManager.java index 21b26d98..7dc29d1d 100644 --- a/src/com/connectsdk/discovery/DiscoveryManager.java +++ b/src/com/connectsdk/discovery/DiscoveryManager.java @@ -1,10 +1,10 @@ /* * DiscoveryManager * Connect SDK - * + * * Copyright (c) 2014 LG Electronics. * Created by Hyun Kook Khang on 19 Jan 2014 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -33,17 +33,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.MulticastLock; -import android.util.Log; - -import com.connectsdk.DefaultPlatform; +import com.connectsdk.core.Context; +import com.connectsdk.core.Log; import com.connectsdk.core.Util; import com.connectsdk.device.ConnectableDevice; import com.connectsdk.device.ConnectableDeviceListener; @@ -61,29 +52,36 @@ /** * ###Overview * - * At the heart of Connect SDK is DiscoveryManager, a multi-protocol service discovery engine with a pluggable architecture. Much of your initial experience with Connect SDK will be with the DiscoveryManager class, as it consolidates discovered service information into ConnectableDevice objects. + * At the heart of Connect SDK is DiscoveryManager, a multi-protocol service discovery engine with a pluggable + * architecture. Much of your initial experience with Connect SDK will be with the DiscoveryManager class, as it + * consolidates discovered service information into ConnectableDevice objects. * * ###In depth - * DiscoveryManager supports discovering services of differing protocols by using DiscoveryProviders. Many services are discoverable over [SSDP][0] and are registered to be discovered with the SSDPDiscoveryProvider class. + * DiscoveryManager supports discovering services of differing protocols by using DiscoveryProviders. Many services are + * discoverable over [SSDP][0] and are registered to be discovered with the SSDPDiscoveryProvider class. * - * As services are discovered on the network, the DiscoveryProviders will notify DiscoveryManager. DiscoveryManager is capable of attributing multiple services, if applicable, to a single ConnectableDevice instance. Thus, it is possible to have a mixed-mode ConnectableDevice object that is theoretically capable of more functionality than a single service can provide. + * As services are discovered on the network, the DiscoveryProviders will notify DiscoveryManager. DiscoveryManager is + * capable of attributing multiple services, if applicable, to a single ConnectableDevice instance. Thus, it is possible + * to have a mixed-mode ConnectableDevice object that is theoretically capable of more functionality than a single + * service can provide. * - * DiscoveryManager keeps a running list of all discovered devices and maintains a filtered list of devices that have satisfied any of your CapabilityFilters. This filtered list is used by the DevicePicker when presenting the user with a list of devices. + * DiscoveryManager keeps a running list of all discovered devices and maintains a filtered list of devices that have + * satisfied any of your CapabilityFilters. This filtered list is used by the DevicePicker when presenting the user with + * a list of devices. * - * Only one instance of the DiscoveryManager should be in memory at a time. To assist with this, DiscoveryManager has static method at sharedManager. + * Only one instance of the DiscoveryManager should be in memory at a time. To assist with this, DiscoveryManager has + * static method at sharedManager. * * Example: * - * @capability kMediaControlPlay - * - @code - DiscoveryManager.init(getApplicationContext()); - DiscoveryManager discoveryManager = DiscoveryManager.getInstance(); - discoveryManager.addListener(this); - discoveryManager.start(); - @endcode + * + * DiscoveryManager.init(getApplicationContext()); + * DiscoveryManager discoveryManager = DiscoveryManager.getInstance(); + * discoveryManager.addListener(this); + * discoveryManager.start(); + * * - * [0]: http://tools.ietf.org/html/draft-cai-ssdp-v1-03 + * [0]: http://tools.ietf.org/html/draft-cai-ssdp-v1-03 */ public class DiscoveryManager implements ConnectableDeviceListener, DiscoveryProviderListener, ServiceConfigListener { @@ -107,15 +105,13 @@ public enum PairingLevel { // @cond INTERNAL - public static String CONNECT_SDK_VERSION = "1.6.0"; + public static final String CONNECT_SDK_VERSION = "1.6.0"; private static DiscoveryManager instance; Context context; ConnectableDeviceStore connectableDeviceStore; - int rescanInterval = 10; - private ConcurrentHashMap allDevices; private ConcurrentHashMap compatibleDevices; @@ -125,24 +121,22 @@ public enum PairingLevel { private CopyOnWriteArrayList discoveryListeners; List capabilityFilters; - MulticastLock multicastLock; - BroadcastReceiver receiver; - boolean isBroadcastReceiverRegistered = false; - - Timer rescanTimer; - - PairingLevel pairingLevel; + + private PairingLevel pairingLevel; private boolean mSearching = false; // @endcond /** - * Initilizes the Discovery manager with a valid context. This should be done as soon as possible and it should use getApplicationContext() as the Discovery manager could persist longer than the current Activity. + * Initilizes the Discovery manager with a valid context. This should be done as soon as possible and it should use + * getApplicationContext() as the Discovery manager could persist longer than the current Activity. * - @code - DiscoveryManager.init(getApplicationContext()); - @endcode + * + * DiscoveryManager.init(getApplicationContext()); + * + * + * @param context a valid context */ public static synchronized void init(Context context) { instance = new DiscoveryManager(context); @@ -153,25 +147,30 @@ public static synchronized void destroy() { } /** - * Initilizes the Discovery manager with a valid context. This should be done as soon as possible and it should use getApplicationContext() as the Discovery manager could persist longer than the current Activity. - * + * Initilizes the Discovery manager with a valid context. This should be done as soon as possible and it should use + * getApplicationContext() as the Discovery manager could persist longer than the current Activity. + * * This accepts a ConnectableDeviceStore to use instead of the default device store. * - @code - MyConnectableDeviceStore myDeviceStore = new MyConnectableDeviceStore(); - DiscoveryManager.init(getApplicationContext(), myDeviceStore); - @endcode + * + * MyConnectableDeviceStore myDeviceStore = new MyConnectableDeviceStore(); + * DiscoveryManager.init(getApplicationContext(), myDeviceStore); + * + * + * @param context a valid context + * @param connectableDeviceStore a device store */ public static synchronized void init(Context context, ConnectableDeviceStore connectableDeviceStore) { instance = new DiscoveryManager(context, connectableDeviceStore); } /** - * Get a shared instance of DiscoveryManager. + * @return a shared instance of DiscoveryManager. */ public static synchronized DiscoveryManager getInstance() { - if (instance == null) + if (instance == null) { throw new Error("Call DiscoveryManager.init(Context) first"); + } return instance; } @@ -181,6 +180,7 @@ public static synchronized DiscoveryManager getInstance() { * Create a new instance of DiscoveryManager. * Direct use of this constructor is not recommended. In most cases, * you should use DiscoveryManager.getInstance() instead. + * @param context a valid context */ public DiscoveryManager(Context context) { this(context, new DefaultConnectableDeviceStore(context)); @@ -190,6 +190,9 @@ public DiscoveryManager(Context context) { * Create a new instance of DiscoveryManager. * Direct use of this constructor is not recommended. In most cases, * you should use DiscoveryManager.getInstance() instead. + * + * @param context a valid context + * @param connectableDeviceStore a device store */ public DiscoveryManager(Context context, ConnectableDeviceStore connectableDeviceStore) { this.context = context; @@ -203,91 +206,97 @@ public DiscoveryManager(Context context, ConnectableDeviceStore connectableDevic discoveryListeners = new CopyOnWriteArrayList(); - WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); - multicastLock = wifiMgr.createMulticastLock(Util.T); - multicastLock.setReferenceCounted(true); +// WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); +// multicastLock = wifiMgr.createMulticastLock(Util.T); +// multicastLock.setReferenceCounted(true); capabilityFilters = new ArrayList(); pairingLevel = PairingLevel.OFF; - receiver = new BroadcastReceiver() { - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - - if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { - NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); - - switch (networkInfo.getState()) { - case CONNECTED: - if (mSearching) { - for (DiscoveryProvider provider : discoveryProviders) { - provider.restart(); - } - } - - break; - - case DISCONNECTED: - Log.w(Util.T, "Network connection is disconnected"); - - for (DiscoveryProvider provider : discoveryProviders) { - provider.reset(); - } - - allDevices.clear(); - - for (ConnectableDevice device: compatibleDevices.values()) { - handleDeviceLoss(device); - } - compatibleDevices.clear(); - - break; - - case CONNECTING: - break; - case DISCONNECTING: - break; - case SUSPENDED: - break; - case UNKNOWN: - break; - } - } - } - }; - - registerBroadcastReceiver(); +// receiver = new BroadcastReceiver() { +// +// @Override +// public void onReceive(Context context, Intent intent) { +// String action = intent.getAction(); +// +// if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { +// NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); +// +// switch (networkInfo.getState()) { +// case CONNECTED: +// if (mSearching) { +// for (DiscoveryProvider provider : discoveryProviders) { +// provider.restart(); +// } +// } +// +// break; +// +// case DISCONNECTED: +// Log.w(Util.T, "Network connection is disconnected"); +// +// for (DiscoveryProvider provider : discoveryProviders) { +// provider.reset(); +// } +// +// allDevices.clear(); +// +// for (ConnectableDevice device : compatibleDevices.values()) { +// handleDeviceLoss(device); +// } +// compatibleDevices.clear(); +// +// break; +// +// case CONNECTING: +// break; +// case DISCONNECTING: +// break; +// case SUSPENDED: +// break; +// case UNKNOWN: +// break; +// } +// } +// } +// }; + + //registerBroadcastReceiver(); } // @endcond - private void registerBroadcastReceiver() { - if (!isBroadcastReceiverRegistered) { - isBroadcastReceiverRegistered = true; - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - context.registerReceiver(receiver, intentFilter); - } - } - - private void unregisterBroadcastReceiver() { - if (isBroadcastReceiverRegistered) { - isBroadcastReceiverRegistered = false; - - context.unregisterReceiver(receiver); - } - } +// private void registerBroadcastReceiver() { +// if (!isBroadcastReceiverRegistered) { +// isBroadcastReceiverRegistered = true; +// +// IntentFilter intentFilter = new IntentFilter(); +// intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); +// context.registerReceiver(receiver, intentFilter); +// } +// } +// +// private void unregisterBroadcastReceiver() { +// if (isBroadcastReceiverRegistered) { +// isBroadcastReceiverRegistered = false; +// +// context.unregisterReceiver(receiver); +// } +// } /** - * Listener which should receive discovery updates. It is not necessary to set this listener property unless you are implementing your own device picker. Connect SDK provides a default DevicePicker which acts as a DiscoveryManagerListener, and should work for most cases. + * It is not necessary to set this listener property unless you are + * implementing your own device picker. Connect SDK provides a default DevicePicker which acts as a + * DiscoveryManagerListener, and should work for most cases. * - * If you have provided a capabilityFilters array, the listener will only receive update messages for ConnectableDevices which satisfy at least one of the CapabilityFilters. If no capabilityFilters array is provided, the listener will receive update messages for all ConnectableDevice objects that are discovered. + * If you have provided a capabilityFilters array, the listener will only receive update messages for + * ConnectableDevices which satisfy at least one of the CapabilityFilters. If no capabilityFilters array is + * provided, the listener will receive update messages for all ConnectableDevice objects that are discovered. + * + * @param listener Listener which should receive discovery updates */ public void addListener(DiscoveryManagerListener listener) { // notify listener of all devices so far - for (ConnectableDevice device: compatibleDevices.values()) { + for (ConnectableDevice device : compatibleDevices.values()) { listener.onDeviceAdded(this, device); } discoveryListeners.add(listener); @@ -295,25 +304,27 @@ public void addListener(DiscoveryManagerListener listener) { /** * Removes a previously added listener + * + * @param listener Listener which should be removed */ public void removeListener(DiscoveryManagerListener listener) { discoveryListeners.remove(listener); } - public void setCapabilityFilters(CapabilityFilter ... capabilityFilters) { + public void setCapabilityFilters(CapabilityFilter... capabilityFilters) { setCapabilityFilters(Arrays.asList(capabilityFilters)); } public void setCapabilityFilters(List capabilityFilters) { this.capabilityFilters = capabilityFilters; - for (ConnectableDevice device: compatibleDevices.values()) { + for (ConnectableDevice device : compatibleDevices.values()) { handleDeviceLoss(device); } compatibleDevices.clear(); - for (ConnectableDevice device: allDevices.values()) { + for (ConnectableDevice device : allDevices.values()) { if (deviceIsCompatible(device)) { compatibleDevices.put(device.getIpAddress(), device); @@ -323,7 +334,7 @@ public void setCapabilityFilters(List capabilityFilters) { } /** - * Returns the list of capability filters. + * @return the list of capability filters. */ public List getCapabilityFilters() { return capabilityFilters; @@ -336,7 +347,7 @@ public boolean deviceIsCompatible(ConnectableDevice device) { boolean isCompatible = false; - for (CapabilityFilter filter: this.capabilityFilters) { + for (CapabilityFilter filter : this.capabilityFilters) { if (device.hasCapabilities(filter.capabilities)) { isCompatible = true; break; @@ -348,29 +359,47 @@ public boolean deviceIsCompatible(ConnectableDevice device) { // @cond INTERNAL /** - * Registers a commonly-used set of DeviceServices with DiscoveryManager. This method will be called on first call of startDiscovery if no DeviceServices have been registered. + * Registers a commonly-used set of DeviceServices with DiscoveryManager. This method will be called on first call + * of startDiscovery if no DeviceServices have been registered. * * - CastDiscoveryProvider - * + CastService + * + CastService * - SSDPDiscoveryProvider - * + DIALService - * + DLNAService (limited to LG TVs, currently) - * + NetcastTVService - * + RokuService - * + WebOSTVService - * + MultiScreenService + * + DIALService + * + DLNAService (limited to LG TVs, currently) + * + NetcastTVService + * + RokuService + * + WebOSTVService + * + MultiScreenService * - ZeroconfDiscoveryProvider - * + AirPlayService + * + AirPlayService */ @SuppressWarnings("unchecked") public void registerDefaultDeviceTypes() { - final HashMap devicesList = DefaultPlatform.getDeviceServiceMap(); - - for (HashMap.Entry entry : devicesList.entrySet()) { + final HashMap devicesList = new HashMap(); + devicesList.put("com.connectsdk.service.WebOSTVService", + "com.connectsdk.discovery.provider.SSDPDiscoveryProvider"); + //devicesList.put("com.connectsdk.service.NetcastTVService", + // "com.connectsdk.discovery.provider.SSDPDiscoveryProvider"); + //devicesList.put("com.connectsdk.service.DLNAService", + // "com.connectsdk.discovery.provider.SSDPDiscoveryProvider"); + //devicesList.put("com.connectsdk.service.DIALService", + // "com.connectsdk.discovery.provider.SSDPDiscoveryProvider"); + // devicesList.put("com.connectsdk.service.RokuService", + // "com.connectsdk.discovery.provider.SSDPDiscoveryProvider"); + // devicesList.put("com.connectsdk.service.CastService", + // "com.connectsdk.discovery.provider.CastDiscoveryProvider"); + // devicesList.put("com.connectsdk.service.AirPlayService", + // "com.connectsdk.discovery.provider.ZeroconfDiscoveryProvider"); + // devicesList.put("com.connectsdk.service.FireTVService", + // "com.connectsdk.discovery.provider.FireTVDiscoveryProvider"); + + for (Map.Entry entry : devicesList.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); - try { - registerDeviceService((Class) Class.forName(key), (Class)Class.forName(value)); + try { + registerDeviceService((Class) Class.forName(key), + (Class) Class.forName(value)); } catch (ClassNotFoundException e) { e.printStackTrace(); } @@ -378,17 +407,22 @@ public void registerDefaultDeviceTypes() { } /** - * Registers a DeviceService with DiscoveryManager and tells it which DiscoveryProvider to use to find it. Each DeviceService has a JSONObject of discovery parameters that its DiscoveryProvider will use to find it. + * Registers a DeviceService with DiscoveryManager and tells it which DiscoveryProvider to use to find it. Each + * DeviceService has a JSONObject of discovery parameters that its DiscoveryProvider will use to find it. * * @param deviceClass Class for object that should be instantiated when DeviceService is found - * @param discoveryClass Class for object that should discover this DeviceService. If a DiscoveryProvider of this class already exists, then the existing DiscoveryProvider will be used. + * @param discoveryClass Class for object that should discover this DeviceService. If a DiscoveryProvider of this + * class already exists, then the existing DiscoveryProvider will be used. */ - public void registerDeviceService(Class deviceClass, Class discoveryClass) { - if (!DeviceService.class.isAssignableFrom(deviceClass)) + public void registerDeviceService(Class deviceClass, + Class discoveryClass) { + if (!DeviceService.class.isAssignableFrom(deviceClass)) { return; + } - if (!DiscoveryProvider.class.isAssignableFrom(discoveryClass)) + if (!DiscoveryProvider.class.isAssignableFrom(discoveryClass)) { return; + } try { DiscoveryProvider discoveryProvider = null; @@ -416,8 +450,8 @@ public void registerDeviceService(Class deviceClass, Cl deviceClasses.put(serviceId, deviceClass); discoveryProvider.addDeviceFilter(discoveryFilter); - if (mSearching){ - discoveryProvider.restart(); + if (mSearching) { + discoveryProvider.restart(); } } catch (SecurityException e) { e.printStackTrace(); @@ -437,7 +471,8 @@ public void registerDeviceService(Class deviceClass, Cl } /** - * Unregisters a DeviceService with DiscoveryManager. If no other DeviceServices are set to being discovered with the associated DiscoveryProvider, then that DiscoveryProvider instance will be stopped and shut down. + * Unregisters a DeviceService with DiscoveryManager. If no other DeviceServices are set to being discovered with + * the associated DiscoveryProvider, then that DiscoveryProvider instance will be stopped and shut down. * * @param deviceClass Class for DeviceService that should no longer be discovered * @param discoveryClass Class for DiscoveryProvider that is discovering DeviceServices of deviceClass type @@ -454,15 +489,16 @@ public void unregisterDeviceService(Class deviceClass, Class discoveryClas try { DiscoveryProvider discoveryProvider = null; - for (DiscoveryProvider dp: discoveryProviders) { + for (DiscoveryProvider dp : discoveryProviders) { if (dp.getClass().isAssignableFrom(discoveryClass)) { discoveryProvider = dp; break; } } - if (discoveryProvider == null) + if (discoveryProvider == null) { return; + } Method m = deviceClass.getMethod("discoveryFilter"); Object result = m.invoke(null); @@ -498,15 +534,16 @@ public void unregisterDeviceService(Class deviceClass, Class discoveryClas * Start scanning for devices on the local network. */ public void start() { - if (mSearching) + if (mSearching) { return; + } if (discoveryProviders == null) { return; } mSearching = true; - multicastLock.acquire(); +// multicastLock.acquire(); Util.runOnUI(new Runnable() { @@ -516,25 +553,28 @@ public void run() { registerDefaultDeviceTypes(); } - ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); - - if (mWifi.isConnected()) { +// ConnectivityManager connManager = (ConnectivityManager) context +// .getSystemService(Context.CONNECTIVITY_SERVICE); +// NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); +// +// if (mWifi.isConnected()) { for (DiscoveryProvider provider : discoveryProviders) { provider.start(); } - } else { - Log.w(Util.T, "Wifi is not connected yet"); - - Util.runOnUI(new Runnable() { - - @Override - public void run() { - for (DiscoveryManagerListener listener : discoveryListeners) - listener.onDiscoveryFailed(DiscoveryManager.this, new ServiceCommandError(0, "No wifi connection", null)); - } - }); - } +// } else { +// Log.w(Util.T, "Wifi is not connected yet"); +// +// Util.runOnUI(new Runnable() { +// +// @Override +// public void run() { +// for (DiscoveryManagerListener listener : discoveryListeners) { +// listener.onDiscoveryFailed(DiscoveryManager.this, +// new ServiceCommandError(0, "No wifi connection", null)); +// } +// } +// }); +// } } }); } @@ -543,8 +583,9 @@ public void run() { * Stop scanning for devices. */ public void stop() { - if (!mSearching) + if (!mSearching) { return; + } mSearching = false; @@ -552,32 +593,41 @@ public void stop() { provider.stop(); } - if (multicastLock.isHeld()) { - multicastLock.release(); - } +// if (multicastLock.isHeld()) { +// multicastLock.release(); +// } } /** - * ConnectableDeviceStore object which loads & stores references to all discovered devices. Pairing codes/keys, SSL certificates, recent access times, etc are kept in the device store. + * ConnectableDeviceStore is a protocol which may be implemented as needed. A default implementation, + * DefaultConnectableDeviceStore, exists for convenience and will be used if no other device store is provided. * - * ConnectableDeviceStore is a protocol which may be implemented as needed. A default implementation, DefaultConnectableDeviceStore, exists for convenience and will be used if no other device store is provided. + * In order to satisfy user privacy concerns, you should provide a UI element in your app which exposes the + * ConnectableDeviceStore removeAll method. * - * In order to satisfy user privacy concerns, you should provide a UI element in your app which exposes the ConnectableDeviceStore removeAll method. + * To disable the ConnectableDeviceStore capabilities of Connect SDK, set this value to nil. This may be done at the + * time of instantiation with `DiscoveryManager.init(context, null);`. + * + * @param connectableDeviceStore ConnectableDeviceStore object which loads & stores references to all discovered devices. Pairing codes/keys, SSL + * certificates, recent access times, etc are kept in the device store. * - * To disable the ConnectableDeviceStore capabilities of Connect SDK, set this value to nil. This may be done at the time of instantiation with `DiscoveryManager.init(context, null);`. */ public void setConnectableDeviceStore(ConnectableDeviceStore connectableDeviceStore) { this.connectableDeviceStore = connectableDeviceStore; } /** - * ConnectableDeviceStore object which loads & stores references to all discovered devices. Pairing codes/keys, SSL certificates, recent access times, etc are kept in the device store. + * ConnectableDeviceStore is a protocol which may be implemented as needed. A default implementation, + * DefaultConnectableDeviceStore, exists for convenience and will be used if no other device store is provided. * - * ConnectableDeviceStore is a protocol which may be implemented as needed. A default implementation, DefaultConnectableDeviceStore, exists for convenience and will be used if no other device store is provided. + * In order to satisfy user privacy concerns, you should provide a UI element in your app which exposes the + * ConnectableDeviceStore removeAll method. * - * In order to satisfy user privacy concerns, you should provide a UI element in your app which exposes the ConnectableDeviceStore removeAll method. - * - * To disable the ConnectableDeviceStore capabilities of Connect SDK, set this value to nil. This may be done at the time of instantiation with `DiscoveryManager.init(context, null);`. + * To disable the ConnectableDeviceStore capabilities of Connect SDK, set this value to nil. This may be done at the + * time of instantiation with `DiscoveryManager.init(context, null);`. + * + * @return ConnectableDeviceStore object which loads & stores references to all discovered devices. Pairing codes/keys, SSL + * certificates, recent access times, etc are kept in the device store. */ public ConnectableDeviceStore getConnectableDeviceStore() { return connectableDeviceStore; @@ -585,12 +635,13 @@ public ConnectableDeviceStore getConnectableDeviceStore() { // @cond INTERNAL public void handleDeviceAdd(ConnectableDevice device) { - if (!deviceIsCompatible(device)) + if (!deviceIsCompatible(device)) { return; + } compatibleDevices.put(device.getIpAddress(), device); - for (DiscoveryManagerListener listenter: discoveryListeners) { + for (DiscoveryManagerListener listenter : discoveryListeners) { listenter.onDeviceAdded(this, device); } } @@ -598,22 +649,20 @@ public void handleDeviceAdd(ConnectableDevice device) { public void handleDeviceUpdate(ConnectableDevice device) { if (deviceIsCompatible(device)) { if (device.getIpAddress() != null && compatibleDevices.containsKey(device.getIpAddress())) { - for (DiscoveryManagerListener listenter: discoveryListeners) { + for (DiscoveryManagerListener listenter : discoveryListeners) { listenter.onDeviceUpdated(this, device); } - } - else { + } else { handleDeviceAdd(device); } - } - else { + } else { compatibleDevices.remove(device.getIpAddress()); handleDeviceLoss(device); } } public void handleDeviceLoss(ConnectableDevice device) { - for (DiscoveryManagerListener listenter: discoveryListeners) { + for (DiscoveryManagerListener listenter : discoveryListeners) { listenter.onDeviceRemoved(this, device); } @@ -640,36 +689,49 @@ public boolean isNetcast(ServiceDescription description) { // @endcond /** - * List of all devices discovered by DiscoveryManager. Each ConnectableDevice object is keyed against its current IP address. + * @return List of all devices discovered by DiscoveryManager. Each ConnectableDevice object is keyed against its current IP + * address. */ public Map getAllDevices() { return allDevices; } /** - * Filtered list of discovered ConnectableDevices, limited to devices that match at least one of the CapabilityFilters in the capabilityFilters array. Each ConnectableDevice object is keyed against its current IP address. + * @return Filtered list of discovered ConnectableDevices, limited to devices that match at least one of the + * CapabilityFilters in the capabilityFilters array. Each ConnectableDevice object is keyed against its current IP + * address. */ public Map getCompatibleDevices() { return compatibleDevices; } /** - * The pairingLevel property determines whether capabilities that require pairing (such as entering a PIN) will be available. + * The pairingLevel property determines whether capabilities that require pairing (such as entering a PIN) will be + * available. * - * If pairingLevel is set to ConnectableDevicePairingLevelOn, ConnectableDevices that require pairing will prompt the user to pair when connecting to the ConnectableDevice. + * If pairingLevel is set to ConnectableDevicePairingLevelOn, ConnectableDevices that require pairing will prompt + * the user to pair when connecting to the ConnectableDevice. * - * If pairingLevel is set to ConnectableDevicePairingLevelOff (the default), connecting to the device will avoid requiring pairing if possible but some capabilities may not be available. + * If pairingLevel is set to ConnectableDevicePairingLevelOff (the default), connecting to the device will avoid + * requiring pairing if possible but some capabilities may not be available. + * + * @return the pairing level */ public PairingLevel getPairingLevel() { return pairingLevel; } /** - * The pairingLevel property determines whether capabilities that require pairing (such as entering a PIN) will be available. + * The pairingLevel property determines whether capabilities that require pairing (such as entering a PIN) will be + * available. * - * If pairingLevel is set to ConnectableDevicePairingLevelOn, ConnectableDevices that require pairing will prompt the user to pair when connecting to the ConnectableDevice. + * If pairingLevel is set to ConnectableDevicePairingLevelOn, ConnectableDevices that require pairing will prompt + * the user to pair when connecting to the ConnectableDevice. * - * If pairingLevel is set to ConnectableDevicePairingLevelOff (the default), connecting to the device will avoid requiring pairing if possible but some capabilities may not be available. + * If pairingLevel is set to ConnectableDevicePairingLevelOff (the default), connecting to the device will avoid + * requiring pairing if possible but some capabilities may not be available. + * + * @param pairingLevel the pairing level */ public void setPairingLevel(PairingLevel pairingLevel) { this.pairingLevel = pairingLevel; @@ -681,7 +743,7 @@ public Context getContext() { } public void onDestroy() { - unregisterBroadcastReceiver(); + //unregisterBroadcastReceiver(); } public List getDiscoveryProviders() { @@ -705,14 +767,26 @@ public void onCapabilityUpdated(ConnectableDevice device, List added, Li handleDeviceUpdate(device); } - @Override public void onConnectionFailed(ConnectableDevice device, ServiceCommandError error) { } - @Override public void onDeviceDisconnected(ConnectableDevice device) { } - @Override public void onDeviceReady(ConnectableDevice device) { } - @Override public void onPairingRequired(ConnectableDevice device, DeviceService service, PairingType pairingType) { } + @Override + public void onConnectionFailed(ConnectableDevice device, ServiceCommandError error) { + } + + @Override + public void onDeviceDisconnected(ConnectableDevice device) { + } + + @Override + public void onDeviceReady(ConnectableDevice device) { + } + + @Override + public void onPairingRequired(ConnectableDevice device, DeviceService service, PairingType pairingType) { + } @Override public void onServiceAdded(DiscoveryProvider provider, ServiceDescription serviceDescription) { - Log.d(Util.T, "Service added: " + serviceDescription.getFriendlyName() + " (" + serviceDescription.getServiceID() + ")"); + Log.d(Util.T, "Service added: " + serviceDescription.getFriendlyName() + " (" + + serviceDescription.getServiceID() + ")"); boolean deviceIsNew = !allDevices.containsKey(serviceDescription.getIpAddress()); ConnectableDevice device = null; @@ -740,8 +814,8 @@ public void onServiceAdded(DiscoveryProvider provider, ServiceDescription servic device.setFriendlyName(serviceDescription.getFriendlyName()); device.setLastDetection(Util.getTime()); device.setLastKnownIPAddress(serviceDescription.getIpAddress()); - // TODO: Implement the currentSSID Property in DiscoveryManager -// device.setLastSeenOnWifi(currentSSID); + // TODO: Implement the currentSSID Property in DiscoveryManager + // device.setLastSeenOnWifi(currentSSID); addServiceDescriptionToDevice(serviceDescription, device); @@ -753,11 +827,12 @@ public void onServiceAdded(DiscoveryProvider provider, ServiceDescription servic return; } - if (deviceIsNew) + if (deviceIsNew) { handleDeviceAdd(device); - else + } else { handleDeviceUpdate(device); - } + } + } @Override public void onServiceRemoved(DiscoveryProvider provider, ServiceDescription serviceDescription) { @@ -771,15 +846,14 @@ public void onServiceRemoved(DiscoveryProvider provider, ServiceDescription serv ConnectableDevice device = allDevices.get(serviceDescription.getIpAddress()); - if (device != null) { + if (device != null) { device.removeServiceWithId(serviceDescription.getServiceID()); if (device.getServices().isEmpty()) { allDevices.remove(serviceDescription.getIpAddress()); handleDeviceLoss(device); - } - else { + } else { handleDeviceUpdate(device); } } @@ -788,32 +862,38 @@ public void onServiceRemoved(DiscoveryProvider provider, ServiceDescription serv @Override public void onServiceDiscoveryFailed(DiscoveryProvider provider, ServiceCommandError error) { Log.w(Util.T, "DiscoveryProviderListener, Service Discovery Failed"); - } + } @SuppressWarnings("unchecked") public void addServiceDescriptionToDevice(ServiceDescription desc, ConnectableDevice device) { - Log.d(Util.T, "Adding service " + desc.getServiceID() + " to device with address " + device.getIpAddress() + " and id " + device.getId()); + Log.d(Util.T, "Adding service " + desc.getServiceID() + " to device with address " + device.getIpAddress() + + " and id " + device.getId()); Class deviceServiceClass = deviceClasses.get(desc.getServiceID()); - if (deviceServiceClass == null) + if (deviceServiceClass == null) { return; + } if (deviceServiceClass == DLNAService.class) { - if (desc.getLocationXML() == null) + if (desc.getLocationXML() == null) { return; + } } else if (deviceServiceClass == NetcastTVService.class) { - if (!isNetcast(desc)) + if (!isNetcast(desc)) { return; - } + } + } ServiceConfig serviceConfig = null; - if (connectableDeviceStore != null) + if (connectableDeviceStore != null) { serviceConfig = connectableDeviceStore.getServiceConfig(desc); + } - if (serviceConfig == null) + if (serviceConfig == null) { serviceConfig = new ServiceConfig(desc); + } serviceConfig.setListener(DiscoveryManager.this); @@ -836,8 +916,9 @@ public void addServiceDescriptionToDevice(ServiceDescription desc, ConnectableDe DeviceService alreadyAddedService = device.getServiceByName(desc.getServiceID()); - if (alreadyAddedService != null) + if (alreadyAddedService != null) { alreadyAddedService.setServiceDescription(desc); + } return; } diff --git a/src/com/connectsdk/discovery/DiscoveryProvider.java b/src/com/connectsdk/discovery/DiscoveryProvider.java index 99aa4fc0..63f8ed2a 100644 --- a/src/com/connectsdk/discovery/DiscoveryProvider.java +++ b/src/com/connectsdk/discovery/DiscoveryProvider.java @@ -20,8 +20,6 @@ package com.connectsdk.discovery; -import java.util.List; - /** * ###Overview @@ -64,10 +62,12 @@ public interface DiscoveryProvider { */ public void reset(); - /** Adds a DiscoveryProviderListener, which should be the DiscoveryManager */ + /** Adds a DiscoveryProviderListener, which should be the DiscoveryManager + * @param listener the listener */ public void addListener(DiscoveryProviderListener listener); - /** Removes a DiscoveryProviderListener. */ + /** Removes a DiscoveryProviderListener. + * @param listener the listener */ public void removeListener(DiscoveryProviderListener listener); /** @@ -85,14 +85,7 @@ public interface DiscoveryProvider { public void removeDeviceFilter(DiscoveryFilter filter); /** - * Set filters for a list of particular DeviceServices - * - * @param filters filters to be used for discovering a list of particular DeviceServices - */ - public void setFilters(List filters); - - /** - * Whether or not the DiscoveryProvider has any services it is supposed to be searching for. If YES, then the DiscoveryProvider will be stopped and de-referenced by the DiscoveryManager. + * @return true if the DiscoveryProvider has any services it is supposed to be searching for. If YES, then the DiscoveryProvider will be stopped and de-referenced by the DiscoveryManager. */ public boolean isEmpty(); } diff --git a/src/com/connectsdk/discovery/DiscoveryProviderListener.java b/src/com/connectsdk/discovery/DiscoveryProviderListener.java index 4e51e46b..c0434cbd 100644 --- a/src/com/connectsdk/discovery/DiscoveryProviderListener.java +++ b/src/com/connectsdk/discovery/DiscoveryProviderListener.java @@ -32,7 +32,7 @@ public interface DiscoveryProviderListener { * This method is called when the DiscoveryProvider discovers a service that matches one of its DeviceService filters. The ServiceDescription is created and passed to the listener (which should be the DiscoveryManager). The ServiceDescription is used to create a DeviceService, which is then attached to a ConnectableDevice object. * * @param provider DiscoveryProvider that found the service - * @param description ServiceDescription of the service that was found + * @param serviceDescription ServiceDescription of the service that was found */ public void onServiceAdded(DiscoveryProvider provider, ServiceDescription serviceDescription); @@ -40,7 +40,7 @@ public interface DiscoveryProviderListener { * This method is called when the DiscoveryProvider's internal mechanism loses reference to a service that matches one of its DeviceService filters. * * @param provider DiscoveryProvider that lost the service - * @param description ServiceDescription of the service that was lost + * @param serviceDescription ServiceDescription of the service that was lost */ public void onServiceRemoved(DiscoveryProvider provider, ServiceDescription serviceDescription); diff --git a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java index dfc14abe..0cac0bff 100644 --- a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java @@ -20,24 +20,9 @@ package com.connectsdk.discovery.provider; -import android.content.Context; -import android.util.Log; - -import com.connectsdk.core.Util; -import com.connectsdk.discovery.DiscoveryFilter; -import com.connectsdk.discovery.DiscoveryProvider; -import com.connectsdk.discovery.DiscoveryProviderListener; -import com.connectsdk.discovery.provider.ssdp.SSDPClient; -import com.connectsdk.discovery.provider.ssdp.SSDPDevice; -import com.connectsdk.discovery.provider.ssdp.SSDPPacket; -import com.connectsdk.service.config.ServiceDescription; - -import org.xml.sax.SAXException; - import java.io.IOException; import java.net.InetAddress; import java.net.URL; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -45,55 +30,64 @@ import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.parsers.ParserConfigurationException; -public class SSDPDiscoveryProvider implements DiscoveryProvider { - Context context; +import org.xml.sax.SAXException; + +import com.connectsdk.core.Context; +import com.connectsdk.core.Log; +import com.connectsdk.core.Util; +import com.connectsdk.discovery.DiscoveryFilter; +import com.connectsdk.discovery.DiscoveryProvider; +import com.connectsdk.discovery.DiscoveryProviderListener; +import com.connectsdk.discovery.provider.ssdp.SSDPClient; +import com.connectsdk.discovery.provider.ssdp.SSDPDevice; +import com.connectsdk.discovery.provider.ssdp.SSDPPacket; +import com.connectsdk.service.config.ServiceDescription; - boolean needToStartSearch = false; +public class SSDPDiscoveryProvider implements DiscoveryProvider { + private Context context; - private CopyOnWriteArrayList serviceListeners; + private CopyOnWriteArrayList serviceListeners = new CopyOnWriteArrayList(); - ConcurrentHashMap foundServices = new ConcurrentHashMap(); - ConcurrentHashMap discoveredServices = new ConcurrentHashMap(); + private ConcurrentHashMap foundServices = new ConcurrentHashMap(); + private ConcurrentHashMap discoveredServices = new ConcurrentHashMap(); - List serviceFilters; + private List serviceFilters = new CopyOnWriteArrayList(); private SSDPClient ssdpClient; private Timer scanTimer; - private Pattern uuidReg; + private Pattern uuidReg = Pattern.compile("(?<=uuid:)(.+?)(?=(::)|$)"); private Thread responseThread; private Thread notifyThread; - - boolean isRunning = false; + private ScheduledExecutorService executorService; + private boolean isRunning = false; public SSDPDiscoveryProvider(Context context) { this.context = context; - - uuidReg = Pattern.compile("(?<=uuid:)(.+?)(?=(::)|$)"); - - serviceListeners = new CopyOnWriteArrayList(); - serviceFilters = new CopyOnWriteArrayList(); } private void openSocket() { - if (ssdpClient != null && ssdpClient.isConnected()) + if (ssdpClient != null && ssdpClient.isConnected()) { return; + } try { - InetAddress source = Util.getIpAddress(context); - if (source == null) + InetAddress source = context.getIpAddress(); + if (source == null) { return; + } ssdpClient = createSocket(source); - } catch (UnknownHostException e) { - e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } @@ -105,13 +99,18 @@ protected SSDPClient createSocket(InetAddress source) throws IOException { @Override public void start() { - if (isRunning) + if (isRunning) { return; + } isRunning = true; openSocket(); - + if (!serviceFilters.isEmpty()) { + // three tasks for each service filter + int poolSize = serviceFilters.size() * 3; + executorService = Executors.newScheduledThreadPool(poolSize); + } scanTimer = new Timer(); scanTimer.schedule(new TimerTask() { @@ -121,8 +120,8 @@ public void run() { } }, 100, RESCAN_INTERVAL); - responseThread = new Thread(mResponseHandler); - notifyThread = new Thread(mRespNotifyHandler); + responseThread = new Thread(mResponseHandler, "Connect SDK Response"); + notifyThread = new Thread(mRespNotifyHandler, "Connect SDK Notify"); responseThread.start(); notifyThread.start(); @@ -147,8 +146,9 @@ public void sendSearch() { notifyListenersOfLostService(service); } - if (foundServices.containsKey(key)) + if (foundServices.containsKey(key)) { foundServices.remove(key); + } } rescan(); @@ -177,6 +177,10 @@ public void stop() { ssdpClient.close(); ssdpClient = null; } + + if (executorService != null && !executorService.isShutdown()) { + executorService.shutdown(); + } } @Override @@ -194,26 +198,31 @@ public void reset() { @Override public void rescan() { - for (DiscoveryFilter searchTarget : serviceFilters) { - final String message = SSDPClient.getSSDPSearchMessage(searchTarget.getServiceFilter()); - - Timer timer = new Timer(); - /* Send 3 times like WindowsMedia */ - for (int i = 0; i < 3; i++) { - TimerTask task = new TimerTask() { - - @Override - public void run() { - try { - if (ssdpClient != null) - ssdpClient.send(message); - } catch (IOException e) { - e.printStackTrace(); + if (executorService == null || executorService.isShutdown()) { + Log.w(Util.T, "There are no filters added"); + } else { + if (executorService.isTerminated() || executorService.isShutdown()) { + if (!serviceFilters.isEmpty()) { + int poolSize = serviceFilters.size() * 3; + executorService = Executors.newScheduledThreadPool(poolSize); + } + } + for (DiscoveryFilter filter : serviceFilters) { + final String message = SSDPClient.getSSDPSearchMessage(filter.getServiceFilter()); + /* Send 3 times like WindowsMedia */ + for (int i = 0; i < 3; i++) { + executorService.schedule(new Runnable() { + @Override + public void run() { + try { + if (ssdpClient != null) + ssdpClient.send(message); + } catch (IOException ex) { + Log.e(Util.T, ex.getMessage()); + } } - } - }; - - timer.schedule(task, i * 1000); + }, i, TimeUnit.SECONDS); + } } } @@ -233,11 +242,6 @@ public void removeDeviceFilter(DiscoveryFilter filter) { serviceFilters.remove(filter); } - @Override - public void setFilters(List filters) { - serviceFilters = filters; - } - @Override public boolean isEmpty() { return serviceFilters.size() == 0; @@ -250,6 +254,9 @@ public void run() { try { handleSSDPPacket(new SSDPPacket(ssdpClient.responseReceive())); } catch (IOException e) { + if ("Socket closed".equals(e.getMessage())) { // expected during shutdown + break; + } e.printStackTrace(); break; } catch (RuntimeException e) { @@ -267,6 +274,9 @@ public void run() { try { handleSSDPPacket(new SSDPPacket(ssdpClient.multicastReceive())); } catch (IOException e) { + if ("Socket closed".equals(e.getMessage())) { // expected during shutdown + break; + } e.printStackTrace(); break; } catch (RuntimeException e) { @@ -279,37 +289,43 @@ public void run() { private void handleSSDPPacket(SSDPPacket ssdpPacket) { // Debugging stuff -// Util.runOnUI(new Runnable() { -// -// @Override -// public void run() { -// Log.d("Connect SDK Socket", "Packet received | type = " + ssdpPacket.type); -// -// for (String key : ssdpPacket.data.keySet()) { -// Log.d("Connect SDK Socket", " " + key + " = " + ssdpPacket.data.get(key)); -// } -// Log.d("Connect SDK Socket", "__________________________________________"); -// } -// }); + // Util.runOnUI(new Runnable() { + // + // @Override + // public void run() { + // Log.d("Connect SDK Socket", "Packet received | type = " + ssdpPacket.getType() + " data = " + + // ssdpPacket.getData()); + // + // for (String key : ssdpPacket.getData().keySet()) { + // Log.d("Connect SDK Socket", " " + key + " = " + ssdpPacket.getData().get(key)); + // } + // Log.d("Connect SDK Socket", "__________________________________________"); + // } + // }); // End Debugging stuff - if (ssdpPacket == null || ssdpPacket.getData().size() == 0 || ssdpPacket.getType() == null) + if (ssdpPacket == null || ssdpPacket.getData().size() == 0 || ssdpPacket.getType() == null) { return; + } String serviceFilter = ssdpPacket.getData().get(ssdpPacket.getType().equals(SSDPClient.NOTIFY) ? "NT" : "ST"); - if (serviceFilter == null || SSDPClient.MSEARCH.equals(ssdpPacket.getType()) || !isSearchingForFilter(serviceFilter)) + if (serviceFilter == null || SSDPClient.MSEARCH.equals(ssdpPacket.getType()) + || !isSearchingForFilter(serviceFilter)) { return; + } String usnKey = ssdpPacket.getData().get("USN"); - if (usnKey == null || usnKey.length() == 0) + if (usnKey == null || usnKey.length() == 0) { return; + } Matcher m = uuidReg.matcher(usnKey); - if (!m.find()) + if (!m.find()) { return; + } String uuid = m.group(); @@ -324,8 +340,9 @@ private void handleSSDPPacket(SSDPPacket ssdpPacket) { } else { String location = ssdpPacket.getData().get("LOCATION"); - if (location == null || location.length() == 0) + if (location == null || location.length() == 0) { return; + } ServiceDescription foundService = foundServices.get(uuid); ServiceDescription discoverdService = discoveredServices.get(uuid); @@ -344,8 +361,9 @@ private void handleSSDPPacket(SSDPPacket ssdpPacket) { getLocationData(location, uuid, serviceFilter); } - if (foundService != null) + if (foundService != null) { foundService.setLastDetection(new Date().getTime()); + } } } @@ -375,30 +393,28 @@ public void run() { if (device != null) { device.UUID = uuid; - boolean hasServices = containsServicesWithFilter(device, serviceFilter); - - if (hasServices) { - final ServiceDescription service = discoveredServices.get(uuid); - - if (service != null) { - service.setServiceFilter(serviceFilter); - service.setFriendlyName(device.friendlyName); - service.setModelName(device.modelName); - service.setModelNumber(device.modelNumber); - service.setModelDescription(device.modelDescription); - service.setManufacturer(device.manufacturer); - service.setApplicationURL(device.applicationURL); - service.setServiceList(device.serviceList); - service.setResponseHeaders(device.headers); - service.setLocationXML(device.locationXML); - service.setServiceURI(device.serviceURI); - service.setPort(device.port); - - foundServices.put(uuid, service); - - notifyListenersOfNewService(service); - } + + final ServiceDescription service = discoveredServices.get(uuid); + + if (service != null) { + service.setServiceFilter(serviceFilter); + service.setFriendlyName(device.friendlyName); + service.setModelName(device.modelName); + service.setModelNumber(device.modelNumber); + service.setModelDescription(device.modelDescription); + service.setManufacturer(device.manufacturer); + service.setApplicationURL(device.applicationURL); + service.setServiceList(device.serviceList); + service.setResponseHeaders(device.headers); + service.setLocationXML(device.locationXML); + service.setServiceURI(device.serviceURI); + service.setPort(device.port); + + foundServices.put(uuid, service); + + notifyListenersOfNewService(service); } + } discoveredServices.remove(uuid); @@ -459,8 +475,9 @@ public List serviceIdsForFilter(String filter) { if (ssdpFilter.equals(filter)) { String serviceId = serviceFilter.getServiceId(); - if (serviceId != null) + if (serviceId != null) { serviceIds.add(serviceId); + } } } @@ -471,24 +488,14 @@ public boolean isSearchingForFilter(String filter) { for (DiscoveryFilter serviceFilter : serviceFilters) { String ssdpFilter = serviceFilter.getServiceFilter(); - if (ssdpFilter.equals(filter)) + if (ssdpFilter.equals(filter)) { return true; + } } return false; } - public boolean containsServicesWithFilter(SSDPDevice device, String filter) { -// List servicesRequired = new ArrayList(); -// -// for (JSONObject serviceFilter : serviceFilters) { -// } - - // TODO Implement this method. Not sure why needs to happen since there are now required services. - - return true; - } - @Override public void addListener(DiscoveryProviderListener listener) { serviceListeners.add(listener); diff --git a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java index a72381fc..9c287408 100644 --- a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java @@ -20,9 +20,16 @@ package com.connectsdk.discovery.provider; +import com.connectsdk.core.Context; +import com.connectsdk.core.Log; +import com.connectsdk.core.Util; +import com.connectsdk.discovery.DiscoveryFilter; +import com.connectsdk.discovery.DiscoveryProvider; +import com.connectsdk.discovery.DiscoveryProviderListener; +import com.connectsdk.service.config.ServiceDescription; + import java.io.IOException; import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -35,15 +42,6 @@ import javax.jmdns.ServiceEvent; import javax.jmdns.ServiceListener; -import android.content.Context; -import android.util.Log; - -import com.connectsdk.core.Util; -import com.connectsdk.discovery.DiscoveryFilter; -import com.connectsdk.discovery.DiscoveryProvider; -import com.connectsdk.discovery.DiscoveryProviderListener; -import com.connectsdk.service.config.ServiceDescription; - public class ZeroconfDiscoveryProvider implements DiscoveryProvider { private static final String HOSTNAME = "connectsdk"; @@ -52,10 +50,11 @@ public class ZeroconfDiscoveryProvider implements DiscoveryProvider { private Timer scanTimer; - List serviceFilters; + private List serviceFilters = new CopyOnWriteArrayList(); - ConcurrentHashMap foundServices; - CopyOnWriteArrayList serviceListeners; + private ConcurrentHashMap foundServices = new ConcurrentHashMap(8, 0.75f, 2); + private CopyOnWriteArrayList serviceListeners = new CopyOnWriteArrayList(); + boolean isRunning = false; @@ -75,10 +74,9 @@ public void serviceResolved(ServiceEvent ev) { ServiceDescription foundService = foundServices.get(ipAddress); - boolean isNew = foundService == null; boolean listUpdateFlag = false; - if (isNew) { + if (foundService == null) { // is New foundService = new ServiceDescription(); foundService.setUUID(ipAddress); foundService.setServiceFilter(ev.getInfo().getType()); @@ -88,8 +86,7 @@ public void serviceResolved(ServiceEvent ev) { foundService.setFriendlyName(friendlyName); listUpdateFlag = true; - } - else { + } else { if (!foundService.getFriendlyName().equals(friendlyName)) { foundService.setFriendlyName(friendlyName); listUpdateFlag = true; @@ -136,16 +133,7 @@ public void serviceAdded(ServiceEvent event) { }; public ZeroconfDiscoveryProvider(Context context) { - foundServices = new ConcurrentHashMap(8, 0.75f, 2); - - serviceListeners = new CopyOnWriteArrayList(); - serviceFilters = new CopyOnWriteArrayList(); - - try { - srcAddress = Util.getIpAddress(context); - } catch (UnknownHostException e) { - e.printStackTrace(); - } + srcAddress = context.getIpAddress(); } @Override @@ -216,7 +204,9 @@ public void stop() { if (jmdns != null) { for (DiscoveryFilter searchTarget : serviceFilters) { String filter = searchTarget.getServiceFilter(); - jmdns.removeServiceListener(filter, jmdnsListener); + if (filter != null && !filter.isEmpty()) { + jmdns.removeServiceListener(filter, jmdnsListener); + } } } } @@ -245,7 +235,9 @@ public void rescan() { if (jmdns != null) { for (DiscoveryFilter searchTarget : serviceFilters) { String filter = searchTarget.getServiceFilter(); - jmdns.addServiceListener(filter, jmdnsListener); + if (filter != null && !filter.isEmpty()) { + jmdns.addServiceListener(filter, jmdnsListener); + } } } } catch (IOException e) { @@ -277,10 +269,6 @@ public void removeDeviceFilter(DiscoveryFilter filter) { serviceFilters.remove(filter); } - @Override - public void setFilters(List filters) { - serviceFilters = filters; - } @Override public boolean isEmpty() { diff --git a/src/com/connectsdk/discovery/provider/ssdp/Action.java b/src/com/connectsdk/discovery/provider/ssdp/Action.java deleted file mode 100644 index ce87cfae..00000000 --- a/src/com/connectsdk/discovery/provider/ssdp/Action.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Action - * Connect SDK - * - * Copyright (c) 2014 LG Electronics. - * Copyright (c) 2011 stonker.lee@gmail.com https://code.google.com/p/android-dlna/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.discovery.provider.ssdp; - -import java.util.List; - - -public class Action { - /* Required. Name of action. */ - String mName; - - /* Required. */ - List mArgumentList; - - public Action(String name) { - this.mName = name; - } -} \ No newline at end of file diff --git a/src/com/connectsdk/discovery/provider/ssdp/Argument.java b/src/com/connectsdk/discovery/provider/ssdp/Argument.java deleted file mode 100644 index 4f6b9608..00000000 --- a/src/com/connectsdk/discovery/provider/ssdp/Argument.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Argument - * Connect SDK - * - * Copyright (c) 2014 LG Electronics. - * Copyright (c) 2011 stonker.lee@gmail.com https://code.google.com/p/android-dlna/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.discovery.provider.ssdp; - -public class Argument { - public static final String TAG = "argument"; - public static final String TAG_NAME = "name"; - public static final String TAG_DIRECTION = "direction"; - public static final String TAG_RETVAL = "retval"; - public static final String TAG_RELATED_STATE_VARIABLE = "relatedStateVariable"; - - /* Required. Name of formal parameter. */ - String mName; - /* Required. Defines whether argument is an input or output paramter. */ - String mDirection; - /* Optional. Identifies at most one output argument as the return value. */ - String mRetval; - /* Required. Must be the same of a state variable. */ - String mRelatedStateVariable; -} \ No newline at end of file diff --git a/src/com/connectsdk/discovery/provider/ssdp/Icon.java b/src/com/connectsdk/discovery/provider/ssdp/Icon.java index 923fa596..9058595d 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/Icon.java +++ b/src/com/connectsdk/discovery/provider/ssdp/Icon.java @@ -2,20 +2,20 @@ public class Icon { static final String TAG = "icon"; - static final String TAG_MIME_TYPE = "mimetype"; - static final String TAG_WIDTH = "width"; - static final String TAG_HEIGHT = "height"; - static final String TAG_DEPTH = "depth"; - static final String TAG_URL = "url"; + //static final String TAG_MIME_TYPE = "mimetype"; + //static final String TAG_WIDTH = "width"; + //static final String TAG_HEIGHT = "height"; + //static final String TAG_DEPTH = "depth"; + //static final String TAG_URL = "url"; /* Required. Icon's MIME type. */ - String mimetype; + //String mimetype; /* Required. Horizontal dimension of icon in pixels. */ - String width; + //String width; /* Required. Vertical dimension of icon in pixels. */ - String height; + //String height; /* Required. Number of color bits per pixel. */ - String depth; + //String depth; /* Required. Pointer to icon image. */ - String url; + //String url; } diff --git a/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java index 234e2528..7de3b022 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java +++ b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java @@ -1,10 +1,10 @@ /* * SSDPClient * Connect SDK - * + * * Copyright (c) 2014 LG Electronics. * Created by Hyun Kook Khang on 6 Jan 2015 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -29,6 +29,7 @@ import java.net.NetworkInterface; import java.net.SocketAddress; import java.net.SocketException; +import java.nio.charset.Charset; public class SSDPClient { /* New line definition */ @@ -62,7 +63,6 @@ public class SSDPClient { SocketAddress multicastGroup; NetworkInterface networkInterface; InetAddress localInAddress; - int timeout = 0; static int MX = 5; @@ -83,15 +83,19 @@ public SSDPClient(InetAddress source, MulticastSocket mcSocket, DatagramSocket d datagramSocket.bind(new InetSocketAddress(localInAddress, 0)); } - /** Used to send SSDP packet */ + /** Used to send SSDP packet. + * @param data the data + * @throws IOException in case of network problems */ public void send(String data) throws IOException { - DatagramPacket dp = new DatagramPacket(data.getBytes(), data.length(), multicastGroup); - + byte[] buffer = data.getBytes(Charset.forName("US-ASCII")); + DatagramPacket dp = new DatagramPacket(buffer, buffer.length, multicastGroup); datagramSocket.send(dp); } - /** Used to receive SSDP Response packet */ + /** Used to receive SSDP Response packet. + * @return response + * @throws IOException in case of network problems */ public DatagramPacket responseReceive() throws IOException { byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); @@ -101,7 +105,9 @@ public DatagramPacket responseReceive() throws IOException { return dp; } - /** Used to receive SSDP Multicast packet */ + /** Used to receive SSDP Multicast packet. + * @return multicast packet + * @throws IOException in case of network problems */ public DatagramPacket multicastReceive() throws IOException { byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); @@ -120,7 +126,7 @@ public boolean isConnected() { return datagramSocket != null && multicastSocket != null && datagramSocket.isConnected() && multicastSocket.isConnected(); } - /** Close the socket */ + /** Close the socket. */ public void close() { if (multicastSocket != null) { try { @@ -132,8 +138,7 @@ public void close() { } if (datagramSocket != null) { - datagramSocket.disconnect(); - datagramSocket.close(); + datagramSocket.close(); } } diff --git a/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java b/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java index ddccba81..1cd3afa5 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java +++ b/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java @@ -26,6 +26,7 @@ import java.io.InputStream; import java.net.URL; import java.net.URLConnection; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -66,7 +67,7 @@ public class SSDPDevice { /* Optional. */ public List serviceList = new ArrayList(); - public String ST; +// public String ST; public String applicationURL; public String serviceURI; @@ -99,7 +100,6 @@ public SSDPDevice(URL urlObject, String ST) throws IOException, ParserConfigurat public void parse(URL url) throws IOException, ParserConfigurationException, SAXException { SAXParserFactory factory = SAXParserFactory.newInstance(); - SAXParser saxParser; SSDPDeviceDescriptionParser parser = new SSDPDeviceDescriptionParser(this); @@ -111,18 +111,14 @@ public void parse(URL url) throws IOException, ParserConfigurationException, SAX } InputStream in = new BufferedInputStream(urlConnection.getInputStream()); - Scanner s = null; - try { - s = new Scanner(in).useDelimiter("\\A"); + + try (Scanner s = new Scanner(in, "UTF-8")) { + s.useDelimiter("\\A"); locationXML = s.hasNext() ? s.next() : ""; - saxParser = factory.newSAXParser(); - saxParser.parse(new ByteArrayInputStream(locationXML.getBytes()), parser); - } finally { - in.close(); - if (s != null) - s.close(); - } + SAXParser saxParser = factory.newSAXParser(); + saxParser.parse(new ByteArrayInputStream(locationXML.getBytes(StandardCharsets.UTF_8)), parser); + } headers = urlConnection.getHeaderFields(); } diff --git a/src/com/connectsdk/discovery/provider/ssdp/Service.java b/src/com/connectsdk/discovery/provider/ssdp/Service.java index 2bfa6cc0..86a7394d 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/Service.java +++ b/src/com/connectsdk/discovery/provider/ssdp/Service.java @@ -20,7 +20,7 @@ package com.connectsdk.discovery.provider.ssdp; -import java.util.List; + //import com.connectsdk.core.upnp.parser.Parser; @@ -44,8 +44,8 @@ public class Service { /* Relative. Relative URL for eventing. */ public String eventSubURL; - public List actionList; - public List serviceStateTable; + + //public List serviceStateTable; /* * We don't get SCPD, control and eventSub descriptions at service creation. diff --git a/src/com/connectsdk/discovery/provider/ssdp/StateVariable.java b/src/com/connectsdk/discovery/provider/ssdp/StateVariable.java deleted file mode 100644 index 10b2ea5d..00000000 --- a/src/com/connectsdk/discovery/provider/ssdp/StateVariable.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * StateVariable - * Connect SDK - * - * Copyright (c) 2014 LG Electronics. - * Copyright (c) 2011 stonker.lee@gmail.com https://code.google.com/p/android-dlna/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.discovery.provider.ssdp; - -public class StateVariable { - public static final String TAG = "stateVariable"; - public static final String TAG_NAME = "name"; - public static final String TAG_DATA_TYPE = "dataType"; - - /* Optional. Defines whether event messages will be generated when the value - * of this state variable changes. Defaut value is "yes". - */ - String mSendEvents = "yes"; - - /* Optional. Defines whether event messages will be delivered using - * multicast eventing. Default value is "no". - */ - String mMulticast = "no"; - - /* Required. Name of state variable. */ - String mName; - - /* Required. Same as data types defined by XML Schema. */ - String mDataType; - -} \ No newline at end of file diff --git a/src/com/connectsdk/etc/helper/HttpConnection.java b/src/com/connectsdk/etc/helper/HttpConnection.java index d0b4d784..284bea63 100644 --- a/src/com/connectsdk/etc/helper/HttpConnection.java +++ b/src/com/connectsdk/etc/helper/HttpConnection.java @@ -29,6 +29,7 @@ import java.net.ProtocolException; import java.net.Socket; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -111,7 +112,7 @@ public void execute() throws IOException { } try { BufferedReader reader = - new BufferedReader(new InputStreamReader(connection.getInputStream())); + new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)); String line; StringBuilder sb = new StringBuilder(); while (null != (line = reader.readLine())) { @@ -131,7 +132,7 @@ public void execute() throws IOException { @Override public void setPayload(String payload) { - this.payload = payload.getBytes(); + this.payload = payload.getBytes(StandardCharsets.UTF_8); connection.setDoOutput(true); } @@ -186,9 +187,9 @@ public void execute() throws IOException { int port = uri.getPort() > 0 ? uri.getPort() : 80; Socket socket = new Socket(uri.getHost(), port); PrintWriter writer = - new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); + new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),StandardCharsets.UTF_8), true); BufferedReader reader = - new BufferedReader(new InputStreamReader(socket.getInputStream())); + new BufferedReader(new InputStreamReader(socket.getInputStream(),StandardCharsets.UTF_8)); // send request writer.print(method.name()); diff --git a/src/com/connectsdk/service/AirPlayService.java b/src/com/connectsdk/service/AirPlayService.java index 46eb038e..768f379b 100644 --- a/src/com/connectsdk/service/AirPlayService.java +++ b/src/com/connectsdk/service/AirPlayService.java @@ -20,11 +20,8 @@ package com.connectsdk.service; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.util.Log; - import com.connectsdk.core.ImageInfo; +import com.connectsdk.core.Log; import com.connectsdk.core.MediaInfo; import com.connectsdk.core.Util; import com.connectsdk.discovery.DiscoveryFilter; @@ -45,9 +42,11 @@ import com.connectsdk.service.sessions.LaunchSession; import com.connectsdk.service.sessions.LaunchSession.LaunchSessionType; +import org.apache.http.client.HttpClient; import org.apache.http.protocol.HTTP; import org.json.JSONObject; +import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -55,6 +54,7 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -66,12 +66,14 @@ import java.util.TimerTask; import java.util.UUID; +import javax.imageio.ImageIO; + public class AirPlayService extends DeviceService implements MediaPlayer, MediaControl { public static final String X_APPLE_SESSION_ID = "X-Apple-Session-ID"; public static final String ID = "AirPlay"; private static final long KEEP_ALIVE_PERIOD = 15000; - private final static String CHARSET = "UTF-8"; + //private final static String CHARSET = "UTF-8"; private String mSessionId; @@ -214,7 +216,7 @@ public void onGetPlaybackPositionFailed(ServiceCommandError error) { /** * AirPlay has the same response for Buffering and Finished states that's why this method * always returns Finished state for video which is not ready to play. - * @param listener + * @param listener the play state listener */ @Override public void getPlayState(final PlayStateListener listener) { @@ -381,33 +383,10 @@ public void onError(ServiceCommandError error) { try { URL imagePath = new URL(url); - HttpURLConnection connection = (HttpURLConnection) imagePath.openConnection(); - connection.setInstanceFollowRedirects(true); - connection.setDoInput(true); - connection.connect(); - - int responseCode = connection.getResponseCode(); - boolean redirect = (responseCode == HttpURLConnection.HTTP_MOVED_TEMP - || responseCode == HttpURLConnection.HTTP_MOVED_PERM - || responseCode == HttpURLConnection.HTTP_SEE_OTHER); - - if(redirect) { - String newPath = connection.getHeaderField("Location"); - URL newImagePath = new URL(newPath); - connection = (HttpURLConnection) newImagePath.openConnection(); - connection.setInstanceFollowRedirects(true); - connection.setDoInput(true); - connection.connect(); - } - - InputStream input = connection.getInputStream(); - Bitmap myBitmap = BitmapFactory.decodeStream(input); - + BufferedImage image = ImageIO.read(imagePath); ByteArrayOutputStream stream = new ByteArrayOutputStream(); - myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); + ImageIO.write(image, "jpg", stream); payload = stream.toByteArray(); - } catch (MalformedURLException e) { - e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { @@ -632,7 +611,7 @@ String getAuthenticate(String method, String digestURI, String authStr) { String digestAuthentication(String md5) { try { MessageDigest md = MessageDigest.getInstance("MD5"); - byte[] digest = md.digest(md5.getBytes()); + byte[] digest = md.digest(md5.getBytes(StandardCharsets.UTF_8)); StringBuffer sb = new StringBuffer(); for (byte b : digest) { sb.append(String.format("%02x", b & 0xFF)); diff --git a/src/com/connectsdk/service/DIALService.java b/src/com/connectsdk/service/DIALService.java index 475bcb93..e010a8d7 100644 --- a/src/com/connectsdk/service/DIALService.java +++ b/src/com/connectsdk/service/DIALService.java @@ -20,9 +20,8 @@ package com.connectsdk.service; -import android.util.Log; - import com.connectsdk.core.AppInfo; +import com.connectsdk.core.Log; import com.connectsdk.core.Util; import com.connectsdk.discovery.DiscoveryFilter; import com.connectsdk.etc.helper.DeviceServiceReachability; @@ -54,6 +53,7 @@ public class DIALService extends DeviceService implements Launcher { public static final String ID = "DIAL"; private static final String APP_NETFLIX = "Netflix"; + private static final String APP_YOUTUBE = "YouTube"; private static List registeredApps = new ArrayList(); @@ -115,11 +115,11 @@ public CapabilityPriorityLevel getLauncherCapabilityLevel() { } @Override - public void launchApp(String appId, AppLaunchListener listener) { + public void launchApp(String appId, ResponseListener listener) { launchApp(appId, null, listener); } - private void launchApp(String appId, JSONObject params, AppLaunchListener listener) { + private void launchApp(String appId, JSONObject params, ResponseListener listener) { if (appId == null || appId.length() == 0) { Util.postError(listener, new ServiceCommandError(0, "Must pass a valid appId", null)); return; @@ -133,12 +133,12 @@ private void launchApp(String appId, JSONObject params, AppLaunchListener listen } @Override - public void launchAppWithInfo(AppInfo appInfo, AppLaunchListener listener) { + public void launchAppWithInfo(AppInfo appInfo, ResponseListener listener) { launchAppWithInfo(appInfo, null, listener); } @Override - public void launchAppWithInfo(final AppInfo appInfo, Object params, final AppLaunchListener listener) { + public void launchAppWithInfo(final AppInfo appInfo, Object params, final ResponseListener listener) { ServiceCommand> command = new ServiceCommand>(getCommandProcessor(), requestURL(appInfo.getName()), params, new ResponseListener() { @@ -163,7 +163,7 @@ public void onSuccess(Object object) { } @Override - public void launchBrowser(String url, AppLaunchListener listener) { + public void launchBrowser(String url, ResponseListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); } @@ -199,16 +199,16 @@ public void onError(ServiceCommandError error) { } @Override - public void launchYouTube(String contentId, AppLaunchListener listener) { + public void launchYouTube(String contentId, ResponseListener listener) { launchYouTube(contentId, (float) 0.0, listener); } @Override - public void launchYouTube(String contentId, float startTime, AppLaunchListener listener) { + public void launchYouTube(String contentId, float startTime, ResponseListener listener) { String params = null; - AppInfo appInfo = new AppInfo("YouTube"); + AppInfo appInfo = new AppInfo(APP_YOUTUBE); appInfo.setName(appInfo.getId()); - + //JSONObject jsonParams = null; if (contentId != null && contentId.length() > 0) { if (startTime < 0.0) { if (listener != null) { @@ -219,6 +219,16 @@ public void launchYouTube(String contentId, float startTime, AppLaunchListener l } String pairingCode = java.util.UUID.randomUUID().toString(); + /* + jsonParams = new JSONObject(); + try { + //jsonParams.put("pairingCode", pairingCode); + jsonParams.put("v", contentId); + jsonParams.put("t", startTime); + } catch (JSONException e) { + Log.e(Util.T, "Launch YouTube error", e); + } + */ params = String.format(Locale.US, "pairingCode=%s&v=%s&t=%.1f", pairingCode, contentId, startTime); } @@ -226,12 +236,12 @@ public void launchYouTube(String contentId, float startTime, AppLaunchListener l } @Override - public void launchHulu(String contentId, AppLaunchListener listener) { + public void launchHulu(String contentId, ResponseListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); } @Override - public void launchNetflix(final String contentId, AppLaunchListener listener) { + public void launchNetflix(final String contentId, ResponseListener listener) { JSONObject params = null; if (contentId != null && contentId.length() > 0) { @@ -251,7 +261,7 @@ public void launchNetflix(final String contentId, AppLaunchListener listener) { } @Override - public void launchAppStore(String appId, AppLaunchListener listener) { + public void launchAppStore(String appId, ResponseListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); } diff --git a/src/com/connectsdk/service/DLNAService.java b/src/com/connectsdk/service/DLNAService.java index 5911571e..b418f126 100644 --- a/src/com/connectsdk/service/DLNAService.java +++ b/src/com/connectsdk/service/DLNAService.java @@ -20,12 +20,9 @@ package com.connectsdk.service; -import android.content.Context; -import android.text.Html; -import android.util.Log; -import android.util.Xml; - +import com.connectsdk.core.Context; import com.connectsdk.core.ImageInfo; +import com.connectsdk.core.Log; import com.connectsdk.core.MediaInfo; import com.connectsdk.core.SubtitleInfo; import com.connectsdk.core.Util; @@ -53,10 +50,12 @@ import org.json.JSONException; import org.json.JSONObject; +import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserFactory; import java.io.IOException; import java.io.StringReader; @@ -82,6 +81,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; @@ -746,10 +746,14 @@ protected String getMetadata(String mediaURL, SubtitleInfo subtitle, String mime } doc.appendChild(didlRoot); - return xmlToString(doc, false); - } catch (Exception e) { - return null; - } + + return xmlToString(doc, false); + } catch (TransformerException | ParserConfigurationException | DOMException | MalformedURLException | UnsupportedEncodingException | URISyntaxException e) { + e.printStackTrace(); + return null; + } + + } String encodeURL(String mediaURL) throws MalformedURLException, URISyntaxException, UnsupportedEncodingException { @@ -901,19 +905,22 @@ public LaunchSession decodeLaunchSession(String type, JSONObject sessionObj) thr return null; } - private boolean isXmlEncoded(final String xml) { + /* private boolean isXmlEncoded(final String xml) { if (xml == null || xml.length() < 4) { return false; } return xml.trim().substring(0, 4).equals("<"); - } + }*/ String parseData(String response, String key) { - if (isXmlEncoded(response)) { - response = Html.fromHtml(response).toString(); - } - XmlPullParser parser = Xml.newPullParser(); + + // commented out to remove dependency to Html and Spanned - review if this is acutally required + //if (isXmlEncoded(response)) { + // response = Html.fromHtml(response).toString(); + //} try { + XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); + parser.setInput(new StringReader(response)); int event; boolean isFound = false; @@ -1123,12 +1130,9 @@ public void subscribeServices() { @Override public void run() { String myIpAddress = null; - try { - myIpAddress = Util.getIpAddress(context).getHostAddress(); - } catch (UnknownHostException e) { - e.printStackTrace(); - } - + + myIpAddress = context.getIpAddress().getHostAddress(); + List serviceList = serviceDescription.getServiceList(); if (serviceList != null) { diff --git a/src/com/connectsdk/service/DeviceService.java b/src/com/connectsdk/service/DeviceService.java index 90afe919..4d8b8f64 100644 --- a/src/com/connectsdk/service/DeviceService.java +++ b/src/com/connectsdk/service/DeviceService.java @@ -30,8 +30,6 @@ import org.json.JSONException; import org.json.JSONObject; -import android.util.SparseArray; - import com.connectsdk.core.Util; import com.connectsdk.device.ConnectableDevice; import com.connectsdk.discovery.DiscoveryFilter; @@ -62,7 +60,7 @@ * * Immediately after discovery of a DeviceService, DiscoveryManager will set the DeviceService's Listener to the ConnectableDevice that owns the DeviceService. You should not change the Listener unless you intend to manage the lifecycle of that service. The DeviceService will proxy all of its Listener method calls through the ConnectableDevice's ConnectableDeviceListener. * - * ####Connection & Pairing + * ####Connection & Pairing * Your ConnectableDevice object will let you know if you need to connect or pair to any services. * * ####Capabilities @@ -128,7 +126,7 @@ public enum PairingType { // @cond INTERNAL protected DeviceServiceListener listener; - public SparseArray> requests = new SparseArray>(); + //public SparseArray> requests = new SparseArray>(); public DeviceService(ServiceDescription serviceDescription, ServiceConfig serviceConfig) { this.serviceDescription = serviceDescription; @@ -281,7 +279,7 @@ public void disconnect() { } - /** Whether the DeviceService is currently connected */ + /** @return true, if the DeviceService is currently connected */ public boolean isConnected() { return true; } @@ -385,6 +383,7 @@ public void run() { * Example: `Launcher.App.Any` * * @param capability Capability to test against + * @return true, if capability exists */ public boolean hasCapability(String capability) { Matcher m = CapabilityMethods.ANY_PATTERN.matcher(capability); @@ -409,6 +408,7 @@ public boolean hasCapability(String capability) { * See hasCapability: for a description of the wildcard feature provided by this method. * * @param capabilities Set of capabilities to test against + * @return true, if at least one capability exists */ public boolean hasAnyCapability(String... capabilities) { for (String capability : capabilities) { @@ -425,6 +425,7 @@ public boolean hasAnyCapability(String... capabilities) { * See hasCapability: for a description of the wildcard feature provided by this method. * * @param capabilities List of capabilities to test against + * @return true, if all capabilities exist */ public boolean hasCapabilities(List capabilities) { String[] arr = new String[capabilities.size()]; @@ -438,6 +439,7 @@ public boolean hasCapabilities(List capabilities) { * See hasCapability: for a description of the wildcard feature provided by this method. * * @param capabilities Set of capabilities to test against + * @return true, if all capabilities exist */ public boolean hasCapabilities(String... capabilities) { boolean hasCaps = true; @@ -486,17 +488,18 @@ public JSONObject toJSONObject() { return jsonObj; } - /** Name of the DeviceService (webOS, Chromecast, etc) */ + /** @return name of the DeviceService (webOS, Chromecast, etc) */ public String getServiceName() { return serviceDescription.getServiceID(); } // @cond INTERNAL - /** + /* * Create a LaunchSession from a serialized JSON object. * May return null if the session was not the one that created the session. * * Intended for internal use. + * */ public LaunchSession decodeLaunchSession(String type, JSONObject sessionObj) throws JSONException { return null; diff --git a/src/com/connectsdk/service/NetcastTVService.java b/src/com/connectsdk/service/NetcastTVService.java index 90471146..6702f0af 100644 --- a/src/com/connectsdk/service/NetcastTVService.java +++ b/src/com/connectsdk/service/NetcastTVService.java @@ -20,14 +20,13 @@ package com.connectsdk.service; -import android.graphics.PointF; -import android.util.Log; - import com.connectsdk.core.AppInfo; import com.connectsdk.core.ChannelInfo; import com.connectsdk.core.ExternalInputInfo; import com.connectsdk.core.ImageInfo; +import com.connectsdk.core.Log; import com.connectsdk.core.MediaInfo; +import com.connectsdk.core.PointF; import com.connectsdk.core.Util; import com.connectsdk.device.ConnectableDevice; import com.connectsdk.discovery.DiscoveryFilter; @@ -74,6 +73,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -489,7 +489,7 @@ public void onError(ServiceCommandError error) { } @Override - public void launchApp(final String appId, final AppLaunchListener listener) { + public void launchApp(final String appId, final ResponseListener listener) { getAppInfoForId(appId, new AppInfoListener() { @Override @@ -525,7 +525,7 @@ public void onSuccess(List object) { }); } - private void launchApplication(final String appName, final String auid, final String contentId, final Launcher.AppLaunchListener listener) { + private void launchApplication(final String appName, final String auid, final String contentId, final ResponseListener listener) { JSONObject jsonObj = new JSONObject(); try { @@ -572,12 +572,12 @@ public void onError(ServiceCommandError error) { } @Override - public void launchAppWithInfo(AppInfo appInfo, Launcher.AppLaunchListener listener) { + public void launchAppWithInfo(AppInfo appInfo, ResponseListener listener) { launchAppWithInfo(appInfo, null, listener); } @Override - public void launchAppWithInfo(AppInfo appInfo, Object params, Launcher.AppLaunchListener listener) { + public void launchAppWithInfo(AppInfo appInfo, Object params, ResponseListener listener) { String appName = HttpMessage.encode(appInfo.getName()); String appId = appInfo.getId(); String contentId = null; @@ -597,7 +597,7 @@ public void launchAppWithInfo(AppInfo appInfo, Object params, Launcher.AppLaunch } @Override - public void launchBrowser(String url, final Launcher.AppLaunchListener listener) { + public void launchBrowser(String url, final ResponseListener listener) { if (!(url == null || url.length() == 0)) Log.w(Util.T, "Netcast TV does not support deeplink for Browser"); @@ -619,12 +619,12 @@ public void onError(ServiceCommandError error) { } @Override - public void launchYouTube(String contentId, Launcher.AppLaunchListener listener) { + public void launchYouTube(String contentId, ResponseListener listener) { launchYouTube(contentId, (float)0.0, listener); } @Override - public void launchYouTube(final String contentId, float startTime, final AppLaunchListener listener) { + public void launchYouTube(final String contentId, float startTime, final ResponseListener listener) { if (getDIALService() != null) { getDIALService().getLauncher().launchYouTube(contentId, startTime, listener); return; @@ -650,7 +650,7 @@ public void onError(ServiceCommandError error) { } @Override - public void launchHulu(final String contentId, final Launcher.AppLaunchListener listener) { + public void launchHulu(final String contentId, final ResponseListener listener) { final String appName = "Hulu"; getApplication(appName, new AppInfoListener() { @@ -668,7 +668,7 @@ public void onError(ServiceCommandError error) { } @Override - public void launchNetflix(final String contentId, final Launcher.AppLaunchListener listener) { + public void launchNetflix(final String contentId, final ResponseListener listener) { if (!serviceDescription.getModelNumber().equals("4.0")) { launchApp("Netflix", listener); return; @@ -734,7 +734,7 @@ public void onError(ServiceCommandError error) { } @Override - public void launchAppStore(final String appId, final AppLaunchListener listener) { + public void launchAppStore(final String appId, final ResponseListener listener) { if (!serviceDescription.getModelNumber().equals("4.0")) { launchApp("LG Smart World", listener); // TODO: this will not work in Korea, use Korean name instead return; @@ -997,7 +997,7 @@ public void onSuccess(Object response) { try { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); - InputStream stream = new ByteArrayInputStream(strObj.getBytes("UTF-8")); + InputStream stream = new ByteArrayInputStream(strObj.getBytes(StandardCharsets.UTF_8)); SAXParser saxParser = saxParserFactory.newSAXParser(); NetcastChannelParser parser = new NetcastChannelParser(); @@ -1019,13 +1019,9 @@ public void onSuccess(Object response) { } Util.postSuccess(listener, channelList); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + } } @Override @@ -1073,8 +1069,8 @@ public void onSuccess(List channelList) { String sourceIndex = (String) rawData.get("sourceIndex"); int physicalNum = (Integer) rawData.get("physicalNumber"); - if (Integer.valueOf(major) == majorNumber - && Integer.valueOf(minor) == minorNumber) { + if (Integer.parseInt(major) == majorNumber + && Integer.parseInt(minor) == minorNumber) { params.put("name", "HandleChannelChange"); params.put("major", major); params.put("minor", minor); @@ -1113,7 +1109,7 @@ public void onSuccess(Object response) { try { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); - InputStream stream = new ByteArrayInputStream(strObj.getBytes("UTF-8")); + InputStream stream = new ByteArrayInputStream(strObj.getBytes(StandardCharsets.UTF_8)); SAXParser saxParser = saxParserFactory.newSAXParser(); NetcastChannelParser parser = new NetcastChannelParser(); @@ -1128,15 +1124,9 @@ public void onSuccess(Object response) { Util.postSuccess(listener, channel); } - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (JSONException e) { + } catch (ParserConfigurationException | SAXException | JSONException | IOException e) { e.printStackTrace(); - } + } } @Override @@ -1402,7 +1392,7 @@ public CapabilityPriorityLevel getExternalInputControlPriorityLevel() { } @Override - public void launchInputPicker(final AppLaunchListener listener) { + public void launchInputPicker(final ResponseListener listener) { final String appName = "Input List"; final String encodedStr = HttpMessage.encode(appName); @@ -1410,7 +1400,7 @@ public void launchInputPicker(final AppLaunchListener listener) { @Override public void onSuccess(final AppInfo appInfo) { - Launcher.AppLaunchListener launchListener = new Launcher.AppLaunchListener() { + ResponseListener launchListener = new ResponseListener() { @Override public void onSuccess(LaunchSession session) { @@ -2060,60 +2050,48 @@ public void powerOn(ResponseListener listener) { private JSONObject parseVolumeXmlToJSON(String data) { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); try { - InputStream stream = new ByteArrayInputStream(data.getBytes("UTF-8")); + InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); SAXParser saxParser = saxParserFactory.newSAXParser(); NetcastVolumeParser handler = new NetcastVolumeParser(); saxParser.parse(stream, handler); return handler.getVolumeStatus(); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - } catch (IOException e) { + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); - } + } return null; } private int parseAppNumberXmlToJSON(String data) { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); try { - InputStream stream = new ByteArrayInputStream(data.getBytes("UTF-8")); + InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); SAXParser saxParser = saxParserFactory.newSAXParser(); NetcastAppNumberParser handler = new NetcastAppNumberParser(); saxParser.parse(stream, handler); return handler.getApplicationNumber(); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + } return 0; } private JSONArray parseApplicationsXmlToJSON(String data) { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); try { - InputStream stream = new ByteArrayInputStream(data.getBytes("UTF-8")); + InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); SAXParser saxParser = saxParserFactory.newSAXParser(); NetcastApplicationsParser handler = new NetcastApplicationsParser(); saxParser.parse(stream, handler); return handler.getApplications(); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + } return null; } @@ -2349,10 +2327,10 @@ protected void updateCapabilities() { List capabilities = new ArrayList(); if (DiscoveryManager.getInstance().getPairingLevel() == PairingLevel.ON) { - Collections.addAll(capabilities, TextInputControl.Capabilities); - Collections.addAll(capabilities, MouseControl.Capabilities); - Collections.addAll(capabilities, KeyControl.Capabilities); - Collections.addAll(capabilities, MediaPlayer.Capabilities); + capabilities.addAll(TextInputControl.Capabilities); + capabilities.addAll(MouseControl.Capabilities); + capabilities.addAll(KeyControl.Capabilities); + capabilities.addAll(MediaPlayer.Capabilities); capabilities.add(PowerControl.Off); @@ -2395,7 +2373,7 @@ protected void updateCapabilities() { capabilities.add(AppStore_Params); } } else { - Collections.addAll(capabilities, MediaPlayer.Capabilities); + capabilities.addAll(MediaPlayer.Capabilities); capabilities.add(Play); capabilities.add(Pause); capabilities.add(Stop); diff --git a/src/com/connectsdk/service/RokuService.java b/src/com/connectsdk/service/RokuService.java index 8853a17a..aa1e3d5d 100644 --- a/src/com/connectsdk/service/RokuService.java +++ b/src/com/connectsdk/service/RokuService.java @@ -20,11 +20,10 @@ package com.connectsdk.service; -import android.text.TextUtils; -import android.util.Log; import com.connectsdk.core.AppInfo; import com.connectsdk.core.ImageInfo; +import com.connectsdk.core.Log; import com.connectsdk.core.MediaInfo; import com.connectsdk.core.Util; import com.connectsdk.device.ConnectableDevice; @@ -60,6 +59,7 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -145,7 +145,7 @@ public void close(ResponseListener responseListener) { } @Override - public void launchApp(String appId, AppLaunchListener listener) { + public void launchApp(String appId, ResponseListener listener) { if (appId == null) { Util.postError(listener, new ServiceCommandError(0, "Must supply a valid app id", null)); @@ -159,14 +159,13 @@ public void launchApp(String appId, AppLaunchListener listener) { } @Override - public void launchAppWithInfo(AppInfo appInfo, - Launcher.AppLaunchListener listener) { + public void launchAppWithInfo(AppInfo appInfo, ResponseListener listener) { launchAppWithInfo(appInfo, null, listener); } @Override public void launchAppWithInfo(final AppInfo appInfo, Object params, - final Launcher.AppLaunchListener listener) { + final ResponseListener listener) { if (appInfo == null || appInfo.getId() == null) { Util.postError(listener, new ServiceCommandError(-1, "Cannot launch app without valid AppInfo object", @@ -265,7 +264,7 @@ public void onSuccess(Object response) { .newInstance(); InputStream stream; try { - stream = new ByteArrayInputStream(msg.getBytes("UTF-8")); + stream = new ByteArrayInputStream(msg.getBytes(StandardCharsets.UTF_8)); SAXParser saxParser = saxParserFactory.newSAXParser(); RokuApplicationListParser parser = new RokuApplicationListParser(); @@ -274,15 +273,9 @@ public void onSuccess(Object response) { List appList = parser.getApplicationList(); Util.postSuccess(listener, appList); - } catch (UnsupportedEncodingException e) { + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + } } @Override @@ -330,19 +323,17 @@ public ServiceSubscription subscribeAppState( } @Override - public void launchBrowser(String url, Launcher.AppLaunchListener listener) { + public void launchBrowser(String url, ResponseListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); } @Override - public void launchYouTube(String contentId, - Launcher.AppLaunchListener listener) { + public void launchYouTube(String contentId, ResponseListener listener) { launchYouTube(contentId, (float) 0.0, listener); } @Override - public void launchYouTube(String contentId, float startTime, - AppLaunchListener listener) { + public void launchYouTube(String contentId, float startTime, ResponseListener listener) { if (getDIALService() != null) { getDIALService().getLauncher().launchYouTube(contentId, startTime, listener); @@ -355,8 +346,7 @@ public void launchYouTube(String contentId, float startTime, } @Override - public void launchNetflix(final String contentId, - final Launcher.AppLaunchListener listener) { + public void launchNetflix(final String contentId, final ResponseListener listener) { getAppList(new AppListListener() { @Override @@ -387,7 +377,7 @@ public void onError(ServiceCommandError error) { @Override public void launchHulu(final String contentId, - final Launcher.AppLaunchListener listener) { + final ResponseListener listener) { getAppList(new AppListListener() { @Override @@ -414,7 +404,7 @@ public void onError(ServiceCommandError error) { } @Override - public void launchAppStore(final String appId, AppLaunchListener listener) { + public void launchAppStore(final String appId, ResponseListener listener) { AppInfo appInfo = new AppInfo("11"); appInfo.setName("Channel Store"); @@ -677,16 +667,16 @@ public void onError(ServiceCommandError error) { param = String.format( "15985?t=v&u=%s&k=(null)&videoName=%s&videoFormat=%s", HttpMessage.encode(url), - TextUtils.isEmpty(title) ? "(null)" : HttpMessage.encode(title), + (title != null && !title.isEmpty()) ? "(null)" : HttpMessage.encode(title), HttpMessage.encode(mediaFormat)); } else { // if (mimeType.contains("audio")) { param = String .format("15985?t=a&u=%s&k=(null)&songname=%s&artistname=%s&songformat=%s&albumarturl=%s", HttpMessage.encode(url), - TextUtils.isEmpty(title) ? "(null)" : HttpMessage.encode(title), - TextUtils.isEmpty(description) ? "(null)" : HttpMessage.encode(description), + (title != null && !title.isEmpty()) ? "(null)" : HttpMessage.encode(title), + (description != null && !description.isEmpty()) ? "(null)" : HttpMessage.encode(description), HttpMessage.encode(mediaFormat), - TextUtils.isEmpty(iconSrc) ? "(null)" : HttpMessage.encode(iconSrc)); + (iconSrc != null && !iconSrc.isEmpty()) ? "(null)" : HttpMessage.encode(iconSrc)); } String uri = requestURL(action, param); diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index 2e5c9e0b..7e9563e8 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -1,10 +1,10 @@ /* * WebOSTVService * Connect SDK - * + * * Copyright (c) 2014 LG Electronics. * Created by Hyun Kook Khang on 19 Jan 2014 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -20,7 +20,7 @@ package com.connectsdk.service; -import java.io.ByteArrayOutputStream; + import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; @@ -33,22 +33,14 @@ import org.json.JSONException; import org.json.JSONObject; -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.pm.PackageManager.NameNotFoundException; -import android.graphics.Bitmap; -import android.graphics.PointF; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.support.annotation.NonNull; -import android.util.Base64; -import android.util.Log; - import com.connectsdk.core.AppInfo; import com.connectsdk.core.ChannelInfo; import com.connectsdk.core.ExternalInputInfo; import com.connectsdk.core.ImageInfo; +import com.connectsdk.core.Log; import com.connectsdk.core.MediaInfo; +import com.connectsdk.core.NonNull; +import com.connectsdk.core.PointF; import com.connectsdk.core.ProgramInfo; import com.connectsdk.core.ProgramList; import com.connectsdk.core.Util; @@ -89,8 +81,9 @@ import com.connectsdk.service.webos.WebOSTVServiceSocketClient; import com.connectsdk.service.webos.WebOSTVServiceSocketClient.WebOSTVServiceSocketClientListener; -@SuppressLint("DefaultLocale") -public class WebOSTVService extends DeviceService implements Launcher, MediaControl, MediaPlayer, VolumeControl, TVControl, ToastControl, ExternalInputControl, MouseControl, TextInputControl, PowerControl, KeyControl, WebAppLauncher, PlaylistControl { +public class WebOSTVService extends DeviceService + implements Launcher, MediaControl, MediaPlayer, VolumeControl, TVControl, ToastControl, ExternalInputControl, + MouseControl, TextInputControl, PowerControl, KeyControl, WebAppLauncher, PlaylistControl { public static final String ID = "webOS TV"; private static final String MEDIA_PLAYER_ID = "MediaPlayer"; @@ -104,14 +97,6 @@ public enum Open implements WebOSTVServicePermission { CONTROL_INPUT_MEDIA_PLAYBACK } - public static final WebOSTVServicePermission[] OPEN = { - Open.LAUNCH, - Open.LAUNCH_WEB, - Open.APP_TO_APP, - Open.CONTROL_AUDIO, - Open.CONTROL_INPUT_MEDIA_PLAYBACK - }; - public enum Protected implements WebOSTVServicePermission { CONTROL_POWER, READ_INSTALLED_APPS, @@ -124,20 +109,7 @@ public enum Protected implements WebOSTVServicePermission { READ_TV_CHANNEL_LIST, WRITE_NOTIFICATION_TOAST } - - public static final WebOSTVServicePermission[] PROTECTED = { - Protected.CONTROL_POWER, - Protected.READ_INSTALLED_APPS, - Protected.CONTROL_DISPLAY, - Protected.CONTROL_INPUT_JOYSTICK, - Protected.CONTROL_INPUT_MEDIA_RECORDING, - Protected.CONTROL_INPUT_TV, - Protected.READ_INPUT_DEVICE_LIST, - Protected.READ_NETWORK_STATE, - Protected.READ_TV_CHANNEL_LIST, - Protected.WRITE_NOTIFICATION_TOAST - }; - + public enum PersonalActivity implements WebOSTVServicePermission { CONTROL_INPUT_TEXT, CONTROL_MOUSE_AND_KEYBOARD, @@ -145,48 +117,26 @@ public enum PersonalActivity implements WebOSTVServicePermission { READ_RUNNING_APPS } - public static final WebOSTVServicePermission[] PERSONAL_ACTIVITY = { - PersonalActivity.CONTROL_INPUT_TEXT, - PersonalActivity.CONTROL_MOUSE_AND_KEYBOARD, - PersonalActivity.READ_CURRENT_CHANNEL, - PersonalActivity.READ_RUNNING_APPS - }; } - public final static String[] kWebOSTVServiceOpenPermissions = { - "LAUNCH", - "LAUNCH_WEBAPP", - "APP_TO_APP", - "CONTROL_AUDIO", - "CONTROL_INPUT_MEDIA_PLAYBACK" - }; - - public final static String[] kWebOSTVServiceProtectedPermissions = { - "CONTROL_POWER", - "READ_INSTALLED_APPS", - "CONTROL_DISPLAY", - "CONTROL_INPUT_JOYSTICK", - "CONTROL_INPUT_MEDIA_RECORDING", - "CONTROL_INPUT_TV", - "READ_INPUT_DEVICE_LIST", - "READ_NETWORK_STATE", - "READ_TV_CHANNEL_LIST", - "WRITE_NOTIFICATION_TOAST" - }; + public final static String[] kWebOSTVServiceOpenPermissions = { "LAUNCH", "LAUNCH_WEBAPP", "APP_TO_APP", + "CONTROL_AUDIO", "CONTROL_INPUT_MEDIA_PLAYBACK" }; - public final static String[] kWebOSTVServicePersonalActivityPermissions = { - "CONTROL_INPUT_TEXT", - "CONTROL_MOUSE_AND_KEYBOARD", - "READ_CURRENT_CHANNEL", - "READ_RUNNING_APPS" - }; + public final static String[] kWebOSTVServiceProtectedPermissions = { "CONTROL_POWER", "READ_INSTALLED_APPS", + "CONTROL_DISPLAY", "CONTROL_INPUT_JOYSTICK", "CONTROL_INPUT_MEDIA_RECORDING", "CONTROL_INPUT_TV", + "READ_INPUT_DEVICE_LIST", "READ_NETWORK_STATE", "READ_TV_CHANNEL_LIST", "WRITE_NOTIFICATION_TOAST" }; + public final static String[] kWebOSTVServicePersonalActivityPermissions = { "CONTROL_INPUT_TEXT", + "CONTROL_MOUSE_AND_KEYBOARD", "READ_CURRENT_CHANNEL", "READ_RUNNING_APPS" }; - public interface SecureAccessTestListener extends ResponseListener { } + public interface SecureAccessTestListener extends ResponseListener { + } - public interface ACRAuthTokenListener extends ResponseListener { } + public interface ACRAuthTokenListener extends ResponseListener { + } - public interface LaunchPointsListener extends ResponseListener { } + public interface LaunchPointsListener extends ResponseListener { + } static String FOREGROUND_APP = "ssap://com.webos.applicationManager/getForegroundAppInfo"; static String APP_STATUS = "ssap://com.webos.service.appstatus/getAppStatus"; @@ -233,52 +183,39 @@ public void setPairingType(PairingType pairingType) { public CapabilityPriorityLevel getPriorityLevel(Class clazz) { if (clazz.equals(MediaPlayer.class)) { return getMediaPlayerCapabilityLevel(); - } - else if (clazz.equals(MediaControl.class)) { + } else if (clazz.equals(MediaControl.class)) { return getMediaControlCapabilityLevel(); - } - else if (clazz.equals(Launcher.class)) { + } else if (clazz.equals(Launcher.class)) { return getLauncherCapabilityLevel(); - } - else if (clazz.equals(TVControl.class)) { + } else if (clazz.equals(TVControl.class)) { return getTVControlCapabilityLevel(); - } - else if (clazz.equals(VolumeControl.class)) { + } else if (clazz.equals(VolumeControl.class)) { return getVolumeControlCapabilityLevel(); - } - else if (clazz.equals(ExternalInputControl.class)) { + } else if (clazz.equals(ExternalInputControl.class)) { return getExternalInputControlPriorityLevel(); - } - else if (clazz.equals(MouseControl.class)) { + } else if (clazz.equals(MouseControl.class)) { return getMouseControlCapabilityLevel(); - } - else if (clazz.equals(TextInputControl.class)) { + } else if (clazz.equals(TextInputControl.class)) { return getTextInputControlCapabilityLevel(); - } - else if (clazz.equals(PowerControl.class)) { + } else if (clazz.equals(PowerControl.class)) { return getPowerControlCapabilityLevel(); - } - else if (clazz.equals(KeyControl.class)) { + } else if (clazz.equals(KeyControl.class)) { return getKeyControlCapabilityLevel(); - } - else if (clazz.equals(ToastControl.class)) { + } else if (clazz.equals(ToastControl.class)) { return getToastControlCapabilityLevel(); - } - else if (clazz.equals(WebAppLauncher.class)) { + } else if (clazz.equals(WebAppLauncher.class)) { return getWebAppLauncherCapabilityLevel(); - } - else if (clazz.equals(PlaylistControl.class)) { + } else if (clazz.equals(PlaylistControl.class)) { return getPlaylistControlCapabilityLevel(); } return CapabilityPriorityLevel.NOT_SUPPORTED; } - + @Override public void setServiceDescription(ServiceDescription serviceDescription) { super.setServiceDescription(serviceDescription); - if (this.serviceDescription.getVersion() == null && this.serviceDescription.getResponseHeaders() != null) - { + if (this.serviceDescription.getVersion() == null && this.serviceDescription.getResponseHeaders() != null) { String serverInfo = serviceDescription.getResponseHeaders().get("Server").get(0); String systemOS = serverInfo.split(" ")[0]; String[] versionComponents = systemOS.split("/"); @@ -295,11 +232,13 @@ private DeviceService getDLNAService() { ConnectableDevice device = null; DeviceService service = null; - if (allDevices != null && allDevices.size() > 0) + if (allDevices != null && allDevices.size() > 0) { device = allDevices.get(this.serviceDescription.getIpAddress()); + } - if (device != null) + if (device != null) { service = device.getServiceByName("DLNA"); + } return service; } @@ -311,7 +250,8 @@ public static DiscoveryFilter discoveryFilter() { @Override public boolean isConnected() { if (DiscoveryManager.getInstance().getPairingLevel() == PairingLevel.ON) { - return this.socket != null && this.socket.isConnected() && (((WebOSTVServiceConfig)serviceConfig).getClientKey() != null); + return this.socket != null && this.socket.isConnected() + && (((WebOSTVServiceConfig) serviceConfig).getClientKey() != null); } else { return this.socket != null && this.socket.isConnected(); } @@ -324,8 +264,9 @@ public void connect() { this.socket.setListener(mSocketListener); } - if (!this.isConnected()) + if (!this.isConnected()) { this.socket.connect(); + } } @Override @@ -336,8 +277,9 @@ public void disconnect() { @Override public void run() { - if (listener != null) + if (listener != null) { listener.onDisconnect(WebOSTVService.this, null); + } } }); @@ -347,8 +289,9 @@ public void run() { socket = null; } - if (mAppToAppIdMappings != null) + if (mAppToAppIdMappings != null) { mAppToAppIdMappings.clear(); + } if (mWebAppSessions != null) { Enumeration iterator = mWebAppSessions.elements(); @@ -379,14 +322,17 @@ public void onRegistrationFailed(final ServiceCommandError error) { @Override public void run() { - if (listener != null) + if (listener != null) { listener.onConnectionFailure(WebOSTVService.this, error); + } } }); } @Override - public Boolean onReceiveMessage(JSONObject message) { return true; } + public Boolean onReceiveMessage(JSONObject message) { + return true; + } @Override public void onFailWithError(final ServiceCommandError error) { @@ -398,8 +344,9 @@ public void onFailWithError(final ServiceCommandError error) { @Override public void run() { - if (listener != null) + if (listener != null) { listener.onConnectionFailure(WebOSTVService.this, error); + } } }); } @@ -419,8 +366,9 @@ public void onCloseWithError(final ServiceCommandError error) { @Override public void run() { - if (listener != null) + if (listener != null) { listener.onDisconnect(WebOSTVService.this, error); + } } }); } @@ -432,8 +380,9 @@ public void onBeforeRegister(final PairingType pairingType) { @Override public void run() { - if (listener != null) + if (listener != null) { listener.onPairingRequired(WebOSTVService.this, pairingType, null); + } } }); } @@ -459,7 +408,7 @@ public CapabilityPriorityLevel getLauncherCapabilityLevel() { } @Override - public void launchApp(String appId, AppLaunchListener listener) { + public void launchApp(String appId, ResponseListener listener) { AppInfo appInfo = new AppInfo(); appInfo.setId(appId); @@ -467,12 +416,12 @@ public void launchApp(String appId, AppLaunchListener listener) { } @Override - public void launchAppWithInfo(AppInfo appInfo, Launcher.AppLaunchListener listener) { + public void launchAppWithInfo(AppInfo appInfo, ResponseListener listener) { launchAppWithInfo(appInfo, null, listener); } @Override - public void launchAppWithInfo(final AppInfo appInfo, Object params, final Launcher.AppLaunchListener listener) { + public void launchAppWithInfo(final AppInfo appInfo, Object params, final ResponseListener listener) { String uri = "ssap://system.launcher/launch"; JSONObject payload = new JSONObject(); @@ -491,11 +440,13 @@ public void launchAppWithInfo(final AppInfo appInfo, Object params, final Launch try { payload.put("id", appId); - if (contentId != null) + if (contentId != null) { payload.put("contentId", contentId); + } - if (params != null) + if (params != null) { payload.put("params", params); + } } catch (JSONException e) { e.printStackTrace(); } @@ -521,13 +472,13 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = new ServiceCommand>(this, uri, payload, true, responseListener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, responseListener); request.send(); } - @Override - public void launchBrowser(String url, final Launcher.AppLaunchListener listener) { + public void launchBrowser(String url, final ResponseListener listener) { String uri = "ssap://system.launcher/open"; JSONObject payload = new JSONObject(); @@ -559,17 +510,18 @@ public void onError(ServiceCommandError error) { e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(this, uri, payload, true, responseListener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, responseListener); request.send(); } @Override - public void launchYouTube(String contentId, Launcher.AppLaunchListener listener) { - launchYouTube(contentId, (float)0.0, listener); + public void launchYouTube(String contentId, ResponseListener listener) { + launchYouTube(contentId, (float) 0.0, listener); } @Override - public void launchYouTube(final String contentId, float startTime, final AppLaunchListener listener) { + public void launchYouTube(final String contentId, float startTime, final ResponseListener listener) { JSONObject params = new JSONObject(); if (contentId != null && contentId.length() > 0) { @@ -579,22 +531,25 @@ public void launchYouTube(final String contentId, float startTime, final AppLaun } try { - params.put("contentId", String.format("%s&pairingCode=%s&t=%.1f", contentId, UUID.randomUUID().toString(), startTime)); + params.put("contentId", + String.format("%s&pairingCode=%s&t=%.1f", contentId, UUID.randomUUID().toString(), startTime)); } catch (JSONException e) { e.printStackTrace(); } } - AppInfo appInfo = new AppInfo() {{ - setId("youtube.leanback.v4"); - setName("YouTube"); - }}; + AppInfo appInfo = new AppInfo() { + { + setId("youtube.leanback.v4"); + setName("YouTube"); + } + }; launchAppWithInfo(appInfo, params, listener); } @Override - public void launchHulu(String contentId, Launcher.AppLaunchListener listener) { + public void launchHulu(String contentId, ResponseListener listener) { JSONObject params = new JSONObject(); try { @@ -603,18 +558,21 @@ public void launchHulu(String contentId, Launcher.AppLaunchListener listener) { e.printStackTrace(); } - AppInfo appInfo = new AppInfo() {{ - setId("hulu"); - setName("Hulu"); - }}; + AppInfo appInfo = new AppInfo() { + { + setId("hulu"); + setName("Hulu"); + } + }; launchAppWithInfo(appInfo, params, listener); } @Override - public void launchNetflix(String contentId, Launcher.AppLaunchListener listener) { + public void launchNetflix(String contentId, ResponseListener listener) { JSONObject params = new JSONObject(); - String netflixContentId = "m=http%3A%2F%2Fapi.netflix.com%2Fcatalog%2Ftitles%2Fmovies%2F" + contentId + "&source_type=4"; + String netflixContentId = "m=http%3A%2F%2Fapi.netflix.com%2Fcatalog%2Ftitles%2Fmovies%2F" + contentId + + "&source_type=4"; try { params.put("contentId", netflixContentId); @@ -622,16 +580,18 @@ public void launchNetflix(String contentId, Launcher.AppLaunchListener listener) e.printStackTrace(); } - AppInfo appInfo = new AppInfo() {{ - setId("netflix"); - setName("Netflix"); - }}; + AppInfo appInfo = new AppInfo() { + { + setId("netflix"); + setName("Netflix"); + } + }; launchAppWithInfo(appInfo, params, listener); } @Override - public void launchAppStore(String appId, AppLaunchListener listener) { + public void launchAppStore(String appId, ResponseListener listener) { AppInfo appInfo = new AppInfo("com.webos.app.discovery"); appInfo.setName("LG Store"); @@ -664,7 +624,8 @@ public void closeApp(LaunchSession launchSession, ResponseListener liste e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(launchSession.getService(), uri, payload, true, listener); + ServiceCommand> request = new ServiceCommand>( + launchSession.getService(), uri, payload, true, listener); request.send(); } @@ -683,15 +644,16 @@ public void onSuccess(Object response) { JSONArray apps = (JSONArray) jsonObj.get("apps"); List appList = new ArrayList(); - for (int i = 0; i < apps.length(); i++) - { + for (int i = 0; i < apps.length(); i++) { final JSONObject appObj = apps.getJSONObject(i); - AppInfo appInfo = new AppInfo() {{ - setId(appObj.getString("id")); - setName(appObj.getString("title")); - setRawData(appObj); - }}; + AppInfo appInfo = new AppInfo() { + { + setId(appObj.getString("id")); + setName(appObj.getString("title")); + setRawData(appObj); + } + }; appList.add(appInfo); } @@ -708,8 +670,9 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, responseListener); - request.send(); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, responseListener); + request.send(); } private ServiceCommand getRunningApp(boolean isSubscription, final AppInfoListener listener) { @@ -719,12 +682,14 @@ private ServiceCommand getRunningApp(boolean isSubscription, fi @Override public void onSuccess(Object response) { - final JSONObject jsonObj = (JSONObject)response; - AppInfo app = new AppInfo() {{ - setId(jsonObj.optString("appId")); - setName(jsonObj.optString("appName")); - setRawData(jsonObj); - }}; + final JSONObject jsonObj = (JSONObject) response; + AppInfo app = new AppInfo() { + { + setId(jsonObj.optString("appId")); + setName(jsonObj.optString("appName")); + setRawData(jsonObj); + } + }; Util.postSuccess(listener, app); } @@ -735,10 +700,11 @@ public void onError(ServiceCommandError error) { } }; - if (isSubscription) + if (isSubscription) { request = new URLServiceSubscription(this, FOREGROUND_APP, null, true, responseListener); - else + } else { request = new ServiceCommand(this, FOREGROUND_APP, null, true, responseListener); + } request.send(); @@ -755,7 +721,8 @@ public ServiceSubscription subscribeRunningApp(AppInfoListener return (URLServiceSubscription) getRunningApp(true, listener); } - private ServiceCommand getAppState(boolean subscription, LaunchSession launchSession, final AppStateListener listener) { + private ServiceCommand getAppState(boolean subscription, LaunchSession launchSession, + final AppStateListener listener) { ServiceCommand request; JSONObject params = new JSONObject(); @@ -786,7 +753,8 @@ public void onSuccess(Object object) { }; if (subscription) { - request = new URLServiceSubscription(this, APP_STATE, params, true, responseListener); + request = new URLServiceSubscription(this, APP_STATE, params, true, + responseListener); } else { request = new ServiceCommand(this, APP_STATE, params, true, responseListener); } @@ -802,13 +770,13 @@ public void getAppState(LaunchSession launchSession, AppStateListener listener) } @Override - public ServiceSubscription subscribeAppState(LaunchSession launchSession, AppStateListener listener) { + public ServiceSubscription subscribeAppState(LaunchSession launchSession, + AppStateListener listener) { return (URLServiceSubscription) getAppState(true, launchSession, listener); } - /****************** - TOAST CONTROL + * TOAST CONTROL *****************/ @Override public ToastControl getToastControl() { @@ -826,15 +794,13 @@ public void showToast(String message, ResponseListener listener) { } @Override - public void showToast(String message, String iconData, String iconExtension, ResponseListener listener) - { + public void showToast(String message, String iconData, String iconExtension, ResponseListener listener) { JSONObject payload = new JSONObject(); try { payload.put("message", message); - if (iconData != null) - { + if (iconData != null) { payload.put("iconData", iconData); payload.put("iconExtension", iconExtension); } @@ -846,12 +812,14 @@ public void showToast(String message, String iconData, String iconExtension, Res } @Override - public void showClickableToastForApp(String message, AppInfo appInfo, JSONObject params, ResponseListener listener) { + public void showClickableToastForApp(String message, AppInfo appInfo, JSONObject params, + ResponseListener listener) { showClickableToastForApp(message, appInfo, params, null, null, listener); } @Override - public void showClickableToastForApp(String message, AppInfo appInfo, JSONObject params, String iconData, String iconExtension, ResponseListener listener) { + public void showClickableToastForApp(String message, AppInfo appInfo, JSONObject params, String iconData, + String iconExtension, ResponseListener listener) { JSONObject payload = new JSONObject(); try { @@ -883,7 +851,8 @@ public void showClickableToastForURL(String message, String url, ResponseListene } @Override - public void showClickableToastForURL(String message, String url, String iconData, String iconExtension, ResponseListener listener) { + public void showClickableToastForURL(String message, String url, String iconData, String iconExtension, + ResponseListener listener) { JSONObject payload = new JSONObject(); try { @@ -907,42 +876,14 @@ public void showClickableToastForURL(String message, String url, String iconData } private void sendToast(JSONObject payload, ResponseListener listener) { - if (!payload.has("iconData")) - { - Context context = DiscoveryManager.getInstance().getContext(); - - try { - Drawable drawable = context.getPackageManager().getApplicationIcon(context.getPackageName()); - - if(drawable != null) { - BitmapDrawable bitDw = ((BitmapDrawable) drawable); - Bitmap bitmap = bitDw.getBitmap(); - - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); - - byte[] bitmapByte = stream.toByteArray(); - bitmapByte = Base64.encode(bitmapByte,Base64.NO_WRAP); - String bitmapData = new String(bitmapByte); - - payload.put("iconData", bitmapData); - payload.put("iconExtension", "png"); - } - } catch (NameNotFoundException e) { - e.printStackTrace(); - } catch (JSONException e) { - e.printStackTrace(); - } - } - String uri = "palm://system.notifications/createToast"; - ServiceCommand> request = new ServiceCommand>(this, uri, payload, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, listener); request.send(); } - /****************** - VOLUME CONTROL + * VOLUME CONTROL *****************/ @Override public VolumeControl getVolumeControl() { @@ -961,7 +902,8 @@ public void volumeUp() { @Override public void volumeUp(ResponseListener listener) { String uri = "ssap://audio/volumeUp"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } @@ -973,12 +915,13 @@ public void volumeDown() { @Override public void volumeDown(ResponseListener listener) { String uri = "ssap://audio/volumeDown"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } - public void setVolume(int volume) { + public void setVolume(int volume) { setVolume(volume, null); } @@ -986,7 +929,7 @@ public void setVolume(int volume) { public void setVolume(float volume, ResponseListener listener) { String uri = "ssap://audio/setVolume"; JSONObject payload = new JSONObject(); - int intVolume = (int) Math.round(volume*100.0f); + int intVolume = Math.round(volume * 100.0f); try { payload.put("volume", intVolume); @@ -994,7 +937,8 @@ public void setVolume(float volume, ResponseListener listener) { e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(this, uri, payload, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, listener); request.send(); } @@ -1007,7 +951,7 @@ private ServiceCommand getVolume(boolean isSubscription, final V public void onSuccess(Object response) { try { - JSONObject jsonObj = (JSONObject)response; + JSONObject jsonObj = (JSONObject) response; int iVolume = (Integer) jsonObj.get("volume"); float fVolume = (float) (iVolume / 100.0); @@ -1023,10 +967,11 @@ public void onError(ServiceCommandError error) { } }; - if (isSubscription) + if (isSubscription) { request = new URLServiceSubscription(this, VOLUME, null, true, responseListener); - else + } else { request = new ServiceCommand(this, VOLUME, null, true, responseListener); + } request.send(); @@ -1038,8 +983,8 @@ public void getVolume(VolumeListener listener) { getVolume(false, listener); } - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public ServiceSubscription subscribeVolume(VolumeListener listener) { return (ServiceSubscription) getVolume(true, listener); } @@ -1055,11 +1000,13 @@ public void setMute(boolean isMute, ResponseListener listener) { e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(this, uri, payload, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, listener); request.send(); } - private ServiceCommand> getMuteStatus(boolean isSubscription, final MuteListener listener) { + private ServiceCommand> getMuteStatus(boolean isSubscription, + final MuteListener listener) { ServiceCommand> request; ResponseListener responseListener = new ResponseListener() { @@ -1067,7 +1014,7 @@ private ServiceCommand> getMuteStatus(boolean isSubscri @Override public void onSuccess(Object response) { try { - JSONObject jsonObj = (JSONObject)response; + JSONObject jsonObj = (JSONObject) response; boolean isMute = (Boolean) jsonObj.get("mute"); Util.postSuccess(listener, isMute); } catch (JSONException e) { @@ -1081,10 +1028,11 @@ public void onError(ServiceCommandError error) { } }; - if (isSubscription) + if (isSubscription) { request = new URLServiceSubscription>(this, MUTE, null, true, responseListener); - else + } else { request = new ServiceCommand>(this, MUTE, null, true, responseListener); + } request.send(); @@ -1096,13 +1044,14 @@ public void getMute(MuteListener listener) { getMuteStatus(false, listener); } - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public ServiceSubscription subscribeMute(MuteListener listener) { return (ServiceSubscription) getMuteStatus(true, listener); } - private ServiceCommand> getVolumeStatus(boolean isSubscription, final VolumeStatusListener listener) { + private ServiceCommand> getVolumeStatus(boolean isSubscription, + final VolumeStatusListener listener) { ServiceCommand> request; ResponseListener responseListener = new ResponseListener() { @@ -1127,10 +1076,12 @@ public void onError(ServiceCommandError error) { } }; - if (isSubscription) - request = new URLServiceSubscription>(this, VOLUME_STATUS, null, true, responseListener); - else + if (isSubscription) { + request = new URLServiceSubscription>(this, VOLUME_STATUS, null, true, + responseListener); + } else { request = new ServiceCommand>(this, VOLUME_STATUS, null, true, responseListener); + } request.send(); @@ -1146,9 +1097,8 @@ public ServiceSubscription subscribeVolumeStatus(VolumeSta return (ServiceSubscription) getVolumeStatus(true, listener); } - /****************** - MEDIA PLAYER + * MEDIA PLAYER *****************/ @Override public MediaPlayer getMediaPlayer() { @@ -1166,8 +1116,7 @@ public void getMediaInfo(MediaInfoListener listener) { } @Override - public ServiceSubscription subscribeMediaInfo( - MediaInfoListener listener) { + public ServiceSubscription subscribeMediaInfo(MediaInfoListener listener) { listener.onError(ServiceCommandError.notSupported()); return null; } @@ -1194,12 +1143,14 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = new ServiceCommand>(this, uri, params, true, responseListener); + ServiceCommand> request = new ServiceCommand>(this, uri, + params, true, responseListener); request.send(); } @Override - public void displayImage(final String url, final String mimeType, final String title, final String description, final String iconSrc, final MediaPlayer.LaunchListener listener) { + public void displayImage(final String url, final String mimeType, final String title, final String description, + final String iconSrc, final MediaPlayer.LaunchListener listener) { if ("4.0.0".equalsIgnoreCase(this.serviceDescription.getVersion())) { DeviceService dlnaService = this.getDLNAService(); @@ -1215,20 +1166,23 @@ public void displayImage(final String url, final String mimeType, final String t JSONObject params = null; try { - params = new JSONObject() {{ - put("target", url); - put("title", title == null ? NULL : title); - put("description", description == null ? NULL : description); - put("mimeType", mimeType == null ? NULL : mimeType); - put("iconSrc", iconSrc == null ? NULL : iconSrc); - }}; + params = new JSONObject() { + { + put("target", url); + put("title", title == null ? NULL : title); + put("description", description == null ? NULL : description); + put("mimeType", mimeType == null ? NULL : mimeType); + put("iconSrc", iconSrc == null ? NULL : iconSrc); + } + }; } catch (JSONException ex) { ex.printStackTrace(); Util.postError(listener, new ServiceCommandError(-1, ex.getLocalizedMessage(), ex)); } - if (params != null) + if (params != null) { this.displayMedia(params, listener); + } } else { final WebAppSession.LaunchListener webAppLaunchListener = new WebAppSession.LaunchListener() { @@ -1282,19 +1236,15 @@ public void displayImage(MediaInfo mediaInfo, MediaPlayer.LaunchListener listene } @Override - public void playMedia(String url, String mimeType, String title, String description, - String iconSrc, boolean shouldLoop, MediaPlayer.LaunchListener listener) { - MediaInfo mediaInfo = new MediaInfo.Builder(url, mimeType) - .setTitle(title) - .setDescription(description) - .setIcon(iconSrc) - .build(); + public void playMedia(String url, String mimeType, String title, String description, String iconSrc, + boolean shouldLoop, MediaPlayer.LaunchListener listener) { + MediaInfo mediaInfo = new MediaInfo.Builder(url, mimeType).setTitle(title).setDescription(description) + .setIcon(iconSrc).build(); playMedia(mediaInfo, shouldLoop, listener); } @Override - public void playMedia(MediaInfo mediaInfo, boolean shouldLoop, - MediaPlayer.LaunchListener listener) { + public void playMedia(MediaInfo mediaInfo, boolean shouldLoop, MediaPlayer.LaunchListener listener) { if ("4.0.0".equalsIgnoreCase(this.serviceDescription.getVersion())) { playMediaByNativeApp(mediaInfo, shouldLoop, listener); } else { @@ -1302,8 +1252,7 @@ public void playMedia(MediaInfo mediaInfo, boolean shouldLoop, } } - private void playMediaByWebApp(final MediaInfo mediaInfo, final boolean shouldLoop, - final LaunchListener listener) { + private void playMediaByWebApp(final MediaInfo mediaInfo, final boolean shouldLoop, final LaunchListener listener) { final WebAppSession.LaunchListener webAppLaunchListener = new WebAppSession.LaunchListener() { @Override @@ -1331,8 +1280,7 @@ public void onSuccess(WebAppSession webAppSession) { }); } - private void playMediaByNativeApp(MediaInfo mediaInfo, boolean shouldLoop, - LaunchListener listener) { + private void playMediaByNativeApp(MediaInfo mediaInfo, boolean shouldLoop, LaunchListener listener) { DeviceService dlnaService = this.getDLNAService(); if (dlnaService != null) { @@ -1355,8 +1303,7 @@ private void playMediaByNativeApp(MediaInfo mediaInfo, boolean shouldLoop, } try { - JSONObject params = - createPlayMediaJsonRequestForSsap(mediaInfo, shouldLoop, iconSrc); + JSONObject params = createPlayMediaJsonRequestForSsap(mediaInfo, shouldLoop, iconSrc); displayMedia(params, listener); } catch (JSONException ex) { Util.postError(listener, new ServiceCommandError(-1, ex.getLocalizedMessage(), ex)); @@ -1365,43 +1312,47 @@ private void playMediaByNativeApp(MediaInfo mediaInfo, boolean shouldLoop, } @NonNull - private JSONObject createPlayMediaJsonRequestForSsap(final MediaInfo mediaInfo, final boolean - shouldLoop, final String iconSrc) throws JSONException { - return new JSONObject() {{ - put("target", mediaInfo.getUrl()); - put("title", getJsonValue(mediaInfo.getTitle())); - put("description", getJsonValue(mediaInfo.getDescription())); - put("mimeType", getJsonValue(mediaInfo.getMimeType())); - put("iconSrc", getJsonValue(iconSrc)); - put("loop", shouldLoop); - }}; + private JSONObject createPlayMediaJsonRequestForSsap(final MediaInfo mediaInfo, final boolean shouldLoop, + final String iconSrc) throws JSONException { + return new JSONObject() { + { + put("target", mediaInfo.getUrl()); + put("title", getJsonValue(mediaInfo.getTitle())); + put("description", getJsonValue(mediaInfo.getDescription())); + put("mimeType", getJsonValue(mediaInfo.getMimeType())); + put("iconSrc", getJsonValue(iconSrc)); + put("loop", shouldLoop); + } + }; } private Object getJsonValue(Object value) { return value == null ? JSONObject.NULL : value; } - - @Override + @Override public void closeMedia(LaunchSession launchSession, ResponseListener listener) { JSONObject payload = new JSONObject(); try { - if (launchSession.getAppId() != null && launchSession.getAppId().length() > 0) + if (launchSession.getAppId() != null && launchSession.getAppId().length() > 0) { payload.put("id", launchSession.getAppId()); + } - if (launchSession.getSessionId() != null && launchSession.getSessionId().length() > 0) + if (launchSession.getSessionId() != null && launchSession.getSessionId().length() > 0) { payload.put("sessionId", launchSession.getSessionId()); + } } catch (JSONException e) { e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(launchSession.getService(), CLOSE_MEDIA_URI, payload, true, listener); + ServiceCommand> request = new ServiceCommand>( + launchSession.getService(), CLOSE_MEDIA_URI, payload, true, listener); request.send(); } /****************** - MEDIA CONTROL + * MEDIA CONTROL *****************/ @Override public MediaControl getMediaControl() { @@ -1416,7 +1367,8 @@ public CapabilityPriorityLevel getMediaControlCapabilityLevel() { @Override public void play(ResponseListener listener) { String uri = "ssap://media.controls/play"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } @@ -1424,7 +1376,8 @@ public void play(ResponseListener listener) { @Override public void pause(ResponseListener listener) { String uri = "ssap://media.controls/pause"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } @@ -1432,7 +1385,8 @@ public void pause(ResponseListener listener) { @Override public void stop(ResponseListener listener) { String uri = "ssap://media.controls/stop"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } @@ -1440,7 +1394,8 @@ public void stop(ResponseListener listener) { @Override public void rewind(ResponseListener listener) { String uri = "ssap://media.controls/rewind"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } @@ -1448,7 +1403,8 @@ public void rewind(ResponseListener listener) { @Override public void fastForward(ResponseListener listener) { String uri = "ssap://media.controls/fastForward"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } @@ -1479,7 +1435,7 @@ public void getPosition(PositionListener listener) { } /****************** - TV CONTROL + * TV CONTROL *****************/ @Override public TVControl getTVControl() { @@ -1499,7 +1455,8 @@ public void channelUp() { public void channelUp(ResponseListener listener) { String uri = "ssap://tv/channelUp"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } @@ -1511,14 +1468,16 @@ public void channelDown() { public void channelDown(ResponseListener listener) { String uri = "ssap://tv/channelDown"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } /** * Sets current channel + * * @param channelInfo must not be null - * @param listener + * @param listener the response listener * @throws NullPointerException if channelInfo is null */ @Override @@ -1540,7 +1499,8 @@ public void setChannel(ChannelInfo channelInfo, ResponseListener listene e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(this, uri, payload, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, listener); request.send(); } @@ -1558,11 +1518,13 @@ public void setChannelById(String channelId, ResponseListener listener) e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(this, uri, payload, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, listener); request.send(); } - private ServiceCommand> getCurrentChannel(boolean isSubscription, final ChannelListener listener) { + private ServiceCommand> getCurrentChannel(boolean isSubscription, + final ChannelListener listener) { ServiceCommand> request; ResponseListener responseListener = new ResponseListener() { @@ -1583,9 +1545,9 @@ public void onError(ServiceCommandError error) { if (isSubscription) { request = new URLServiceSubscription>(this, CHANNEL, null, true, responseListener); - } - else + } else { request = new ServiceCommand>(this, CHANNEL, null, true, responseListener); + } request.send(); @@ -1597,13 +1559,14 @@ public void getCurrentChannel(ChannelListener listener) { getCurrentChannel(false, listener); } - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public ServiceSubscription subscribeCurrentChannel(ChannelListener listener) { return (ServiceSubscription) getCurrentChannel(true, listener); } - private ServiceCommand> getChannelList(boolean isSubscription, final ChannelListListener listener) { + private ServiceCommand> getChannelList(boolean isSubscription, + final ChannelListListener listener) { ServiceCommand> request; ResponseListener responseListener = new ResponseListener() { @@ -1611,7 +1574,7 @@ private ServiceCommand> getChannelList(boolean isSubscr @Override public void onSuccess(Object response) { try { - JSONObject jsonObj = (JSONObject)response; + JSONObject jsonObj = (JSONObject) response; ArrayList list = new ArrayList(); JSONArray array = (JSONArray) jsonObj.get("channelList"); @@ -1634,10 +1597,12 @@ public void onError(ServiceCommandError error) { } }; - if (isSubscription) - request = new URLServiceSubscription>(this, CHANNEL_LIST, null, true, responseListener); - else + if (isSubscription) { + request = new URLServiceSubscription>(this, CHANNEL_LIST, null, true, + responseListener); + } else { request = new ServiceCommand>(this, CHANNEL_LIST, null, true, responseListener); + } request.send(); @@ -1654,8 +1619,9 @@ public ServiceSubscription subscribeChannelList(final Chann return (ServiceSubscription) getChannelList(true, listener); } - private ServiceCommand> getChannelCurrentProgramInfo(boolean isSubscription, final ProgramInfoListener listener) { - String uri ="ssap://tv/getChannelCurrentProgramInfo"; + private ServiceCommand> getChannelCurrentProgramInfo(boolean isSubscription, + final ProgramInfoListener listener) { + String uri = "ssap://tv/getChannelCurrentProgramInfo"; ServiceCommand> request; @@ -1663,7 +1629,7 @@ private ServiceCommand> getChannelCurrentProgramInfo(bo @Override public void onSuccess(Object response) { - JSONObject jsonObj = (JSONObject)response; + JSONObject jsonObj = (JSONObject) response; ProgramInfo programInfo = parseRawProgramInfo(jsonObj); Util.postSuccess(listener, programInfo); @@ -1675,16 +1641,17 @@ public void onError(ServiceCommandError error) { } }; - if (isSubscription) + if (isSubscription) { request = new URLServiceSubscription>(this, uri, null, true, responseListener); - else + } else { request = new ServiceCommand>(this, uri, null, true, responseListener); + } request.send(); return request; } - + public void getChannelCurrentProgramInfo(ProgramInfoListener listener) { getChannelCurrentProgramInfo(false, listener); } @@ -1694,7 +1661,8 @@ public ServiceSubscription subscribeChannelCurrentProgramIn return (ServiceSubscription) getChannelCurrentProgramInfo(true, listener); } - private ServiceCommand> getProgramList(boolean isSubscription, final ProgramListListener listener) { + private ServiceCommand> getProgramList(boolean isSubscription, + final ProgramListListener listener) { ServiceCommand> request; ResponseListener responseListener = new ResponseListener() { @@ -1702,7 +1670,7 @@ private ServiceCommand> getProgramList(boolean isSubscr @Override public void onSuccess(Object response) { try { - JSONObject jsonObj = (JSONObject)response; + JSONObject jsonObj = (JSONObject) response; JSONObject jsonChannel = (JSONObject) jsonObj.get("channel"); ChannelInfo channel = parseRawChannelData(jsonChannel); JSONArray programList = (JSONArray) jsonObj.get("programList"); @@ -1719,10 +1687,11 @@ public void onError(ServiceCommandError error) { } }; - if (isSubscription) + if (isSubscription) { request = new URLServiceSubscription>(this, PROGRAM, null, true, responseListener); - else + } else { request = new ServiceCommand>(this, PROGRAM, null, true, responseListener); + } request.send(); @@ -1747,33 +1716,36 @@ public void getProgramList(ProgramListListener listener) { getProgramList(false, listener); } - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public ServiceSubscription subscribeProgramList(ProgramListListener listener) { return (ServiceSubscription) getProgramList(true, listener); } @Override public void set3DEnabled(final boolean enabled, final ResponseListener listener) { - String uri; - if (enabled) + String uri; + if (enabled) { uri = "ssap://com.webos.service.tv.display/set3DOn"; - else + } else { uri = "ssap://com.webos.service.tv.display/set3DOff"; + } - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } - private ServiceCommand get3DEnabled(boolean isSubscription, final State3DModeListener listener) { + private ServiceCommand get3DEnabled(boolean isSubscription, + final State3DModeListener listener) { String uri = "ssap://com.webos.service.tv.display/get3DStatus"; ResponseListener responseListener = new ResponseListener() { @Override public void onSuccess(Object response) { - JSONObject jsonObj = (JSONObject)response; + JSONObject jsonObj = (JSONObject) response; JSONObject status; try { @@ -1793,10 +1765,11 @@ public void onError(ServiceCommandError error) { }; ServiceCommand request; - if (isSubscription) + if (isSubscription) { request = new URLServiceSubscription(this, uri, null, true, responseListener); - else + } else { request = new ServiceCommand(this, uri, null, true, responseListener); + } request.send(); @@ -1808,15 +1781,14 @@ public void get3DEnabled(final State3DModeListener listener) { get3DEnabled(false, listener); } - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public ServiceSubscription subscribe3DEnabled(final State3DModeListener listener) { return (ServiceSubscription) get3DEnabled(true, listener); } - /************** - EXTERNAL INPUT + * EXTERNAL INPUT **************/ @Override public ExternalInputControl getExternalInput() { @@ -1829,13 +1801,15 @@ public CapabilityPriorityLevel getExternalInputControlPriorityLevel() { } @Override - public void launchInputPicker(final AppLaunchListener listener) { - final AppInfo appInfo = new AppInfo() {{ - setId("com.webos.app.inputpicker"); - setName("InputPicker"); - }}; + public void launchInputPicker(final ResponseListener listener) { + final AppInfo appInfo = new AppInfo() { + { + setId("com.webos.app.inputpicker"); + setName("InputPicker"); + } + }; - launchAppWithInfo(appInfo, null, new AppLaunchListener() { + launchAppWithInfo(appInfo, null, new ResponseListener() { @Override public void onSuccess(LaunchSession object) { listener.onSuccess(object); @@ -1863,7 +1837,7 @@ public void getExternalInputList(final ExternalInputListListener listener) { @Override public void onSuccess(Object response) { try { - JSONObject jsonObj = (JSONObject)response; + JSONObject jsonObj = (JSONObject) response; JSONArray devices = (JSONArray) jsonObj.get("devices"); Util.postSuccess(listener, externalnputInfoFromJSONArray(devices)); } catch (JSONException e) { @@ -1877,34 +1851,34 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, responseListener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, responseListener); request.send(); } @Override - public void setExternalInput(ExternalInputInfo externalInputInfo , final ResponseListener listener) { + public void setExternalInput(ExternalInputInfo externalInputInfo, final ResponseListener listener) { String uri = "ssap://tv/switchInput"; JSONObject payload = new JSONObject(); try { - if (externalInputInfo != null && externalInputInfo .getId() != null) { + if (externalInputInfo != null && externalInputInfo.getId() != null) { payload.put("inputId", externalInputInfo.getId()); - } - else { + } else { Log.w(Util.T, "ExternalInputInfo has no id"); } } catch (JSONException e) { e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(this, uri, payload, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, listener); request.send(); } - /************** - MOUSE CONTROL + * MOUSE CONTROL **************/ @Override public MouseControl getMouseControl() { @@ -1928,16 +1902,18 @@ public void onConnected() { @Override public void disconnectMouse() { - if (mouseSocket == null) + if (mouseSocket == null) { return; + } mouseSocket.disconnect(); mouseSocket = null; } private void connectMouse(final WebOSTVMouseSocketConnection.WebOSTVMouseSocketListener successHandler) { - if (mouseSocket != null) + if (mouseSocket != null) { return; + } String uri = "ssap://com.webos.service.networkinput/getPointerInputSocket"; @@ -1946,7 +1922,7 @@ private void connectMouse(final WebOSTVMouseSocketConnection.WebOSTVMouseSocketL @Override public void onSuccess(Object response) { try { - JSONObject jsonObj = (JSONObject)response; + JSONObject jsonObj = (JSONObject) response; String socketPath = (String) jsonObj.get("socketPath"); mouseSocket = new WebOSTVMouseSocketConnection(socketPath, successHandler); } catch (JSONException e) { @@ -1960,7 +1936,8 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, listener); request.send(); } @@ -1968,8 +1945,7 @@ public void onError(ServiceCommandError error) { public void click() { if (mouseSocket != null) { mouseSocket.click(); - } - else { + } else { connectMouse(new WebOSTVMouseSocketConnection.WebOSTVMouseSocketListener() { @Override public void onConnected() { @@ -1983,8 +1959,7 @@ public void onConnected() { public void move(final double dx, final double dy) { if (mouseSocket != null) { mouseSocket.move(dx, dy); - } - else { + } else { connectMouse(new WebOSTVMouseSocketConnection.WebOSTVMouseSocketListener() { @Override public void onConnected() { @@ -2003,8 +1978,7 @@ public void move(PointF diff) { public void scroll(final double dx, final double dy) { if (mouseSocket != null) { mouseSocket.scroll(dx, dy); - } - else { + } else { connectMouse(new WebOSTVMouseSocketConnection.WebOSTVMouseSocketListener() { @Override public void onConnected() { @@ -2019,9 +1993,8 @@ public void scroll(PointF diff) { scroll(diff.x, diff.y); } - /************** - KEYBOARD CONTROL + * KEYBOARD CONTROL **************/ @Override public TextInputControl getTextInputControl() { @@ -2085,9 +2058,8 @@ public void sendDelete() { } } - /************** - POWER CONTROL + * POWER CONTROL **************/ @Override public PowerControl getPowerControl() { @@ -2115,7 +2087,8 @@ public void onError(ServiceCommandError error) { }; String uri = "ssap://system/turnOff"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, responseListener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, responseListener); request.send(); } @@ -2125,9 +2098,8 @@ public void powerOn(ResponseListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); } - /************** - KEY CONTROL + * KEY CONTROL **************/ @Override public KeyControl getKeyControl() { @@ -2143,8 +2115,7 @@ private void sendSpecialKey(final String key, final ResponseListener lis if (mouseSocket != null) { mouseSocket.button(key); Util.postSuccess(listener, null); - } - else { + } else { connectMouse(new WebOSTVMouseSocketConnection.WebOSTVMouseSocketListener() { @Override public void onConnected() { @@ -2180,8 +2151,7 @@ public void ok(final ResponseListener listener) { if (mouseSocket != null) { mouseSocket.click(); Util.postSuccess(listener, null); - } - else { + } else { connectMouse(new WebOSTVMouseSocketConnection.WebOSTVMouseSocketListener() { @Override public void onConnected() { @@ -2202,9 +2172,8 @@ public void home(ResponseListener listener) { sendSpecialKey("HOME", listener); } - /************** - Web App Launcher + * Web App Launcher **************/ @Override @@ -2227,7 +2196,9 @@ public void launchWebApp(String webAppId, boolean relaunchIfRunning, WebAppSessi launchWebApp(webAppId, null, relaunchIfRunning, listener); } - public void launchWebApp(final String webAppId, final JSONObject params, final WebAppSession.LaunchListener listener) { + @Override + public void launchWebApp(final String webAppId, final JSONObject params, + final WebAppSession.LaunchListener listener) { if (webAppId == null || webAppId.length() == 0) { Util.postError(listener, new ServiceCommandError(-1, "You need to provide a valid webAppId.", null)); @@ -2242,8 +2213,9 @@ public void launchWebApp(final String webAppId, final JSONObject params, final W try { payload.put("webAppId", webAppId); - if (params != null) + if (params != null) { payload.put("urlParams", params); + } } catch (JSONException e) { e.printStackTrace(); } @@ -2257,9 +2229,9 @@ public void onSuccess(final Object response) { LaunchSession launchSession = null; WebOSWebAppSession webAppSession = _webAppSession; - if (webAppSession != null) + if (webAppSession != null) { launchSession = webAppSession.launchSession; - else { + } else { launchSession = LaunchSession.launchSessionForAppId(webAppId); webAppSession = new WebOSWebAppSession(launchSession, WebOSTVService.this); mWebAppSessions.put(webAppId, webAppSession); @@ -2279,12 +2251,14 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = new ServiceCommand>(this, uri, payload, true, responseListener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, responseListener); request.send(); } @Override - public void launchWebApp(final String webAppId, final JSONObject params, boolean relaunchIfRunning, final WebAppSession.LaunchListener listener) { + public void launchWebApp(final String webAppId, final JSONObject params, boolean relaunchIfRunning, + final WebAppSession.LaunchListener listener) { if (webAppId == null) { Util.postError(listener, new ServiceCommandError(0, "Must pass a web App id", null)); return; @@ -2302,7 +2276,7 @@ public void onError(ServiceCommandError error) { @Override public void onSuccess(AppInfo appInfo) { - // TODO: this will only work on pinned apps, currently + // TODO: this will only work on pinned apps, currently if (appInfo.getId().indexOf(webAppId) != -1) { LaunchSession launchSession = LaunchSession.launchSessionForAppId(webAppId); launchSession.setSessionType(LaunchSessionType.WebApp); @@ -2336,38 +2310,49 @@ public void closeWebApp(LaunchSession launchSession, final ResponseListener> request = new ServiceCommand>(this, uri, payload, true, listener); + ServiceCommand> request = new ServiceCommand>(this, uri, + payload, true, listener); request.send(); } - public void connectToWebApp(final WebOSWebAppSession webAppSession, final boolean joinOnly, final ResponseListener connectionListener) { - if (mWebAppSessions == null) + public void connectToWebApp(final WebOSWebAppSession webAppSession, final boolean joinOnly, + final ResponseListener connectionListener) { + if (mWebAppSessions == null) { mWebAppSessions = new ConcurrentHashMap(); + } - if (mAppToAppIdMappings == null) + if (mAppToAppIdMappings == null) { mAppToAppIdMappings = new ConcurrentHashMap(); + } if (webAppSession == null || webAppSession.launchSession == null) { - Util.postError(connectionListener, new ServiceCommandError(0, "You must provide a valid LaunchSession object", null)); + Util.postError(connectionListener, + new ServiceCommandError(0, "You must provide a valid LaunchSession object", null)); return; } String _appId = webAppSession.launchSession.getAppId(); String _idKey = null; - if (webAppSession.launchSession.getSessionType() == LaunchSession.LaunchSessionType.WebApp) + if (webAppSession.launchSession.getSessionType() == LaunchSession.LaunchSessionType.WebApp) { _idKey = "webAppId"; - else + } else { _idKey = "appId"; + } if (_appId == null || _appId.length() == 0) { - Util.postError(connectionListener, new ServiceCommandError(-1, "You must provide a valid web app session", null)); + Util.postError(connectionListener, + new ServiceCommandError(-1, "You must provide a valid web app session", null)); return; } @@ -2388,13 +2373,14 @@ public void connectToWebApp(final WebOSWebAppSession webAppSession, final boolea @Override public void onSuccess(final Object response) { - JSONObject jsonObj = (JSONObject)response; + JSONObject jsonObj = (JSONObject) response; String state = jsonObj.optString("state"); if (!state.equalsIgnoreCase("CONNECTED")) { if (joinOnly && state.equalsIgnoreCase("WAITING_FOR_APP")) { - Util.postError(connectionListener, new ServiceCommandError(0, "Web app is not currently running", null)); + Util.postError(connectionListener, + new ServiceCommandError(0, "Web app is not currently running", null)); } return; @@ -2403,8 +2389,9 @@ public void onSuccess(final Object response) { String fullAppId = jsonObj.optString("appId"); if (fullAppId != null && fullAppId.length() != 0) { - if (webAppSession.launchSession.getSessionType() == LaunchSessionType.WebApp) + if (webAppSession.launchSession.getSessionType() == LaunchSessionType.WebApp) { mAppToAppIdMappings.put(fullAppId, appId); + } webAppSession.setFullAppId(fullAppId); } @@ -2426,8 +2413,9 @@ public void onError(ServiceCommandError error) { boolean appChannelDidClose = false; - if (error != null && error.getPayload() != null) + if (error != null && error.getPayload() != null) { appChannelDidClose = error.getPayload().toString().contains("app channel closed"); + } if (appChannelDidClose) { if (webAppSession.getWebAppSessionListener() != null) { @@ -2445,7 +2433,8 @@ public void run() { } }; - webAppSession.appToAppSubscription = new URLServiceSubscription>(webAppSession.socket, uri, payload, true, responseListener); + webAppSession.appToAppSubscription = new URLServiceSubscription>(webAppSession.socket, + uri, payload, true, responseListener); webAppSession.appToAppSubscription.subscribe(); } @@ -2463,7 +2452,7 @@ public void pinWebApp(String webAppId, final ResponseListener listener) } return; } - + String uri = "ssap://webapp/pinWebApp"; JSONObject payload = new JSONObject(); @@ -2480,8 +2469,7 @@ public void onSuccess(final Object response) { JSONObject obj = (JSONObject) response; if (obj.has("pairingType")) { notifyPairingRequired(); - } - else if (listener != null) { + } else if (listener != null) { listener.onSuccess(response); } } @@ -2492,8 +2480,8 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = - new URLServiceSubscription>(this, uri, payload, true, responseListener); + ServiceCommand> request = new URLServiceSubscription>(this, + uri, payload, true, responseListener); request.send(); } @@ -2522,8 +2510,7 @@ public void onSuccess(final Object response) { JSONObject obj = (JSONObject) response; if (obj.has("pairingType")) { notifyPairingRequired(); - } - else if (listener != null) { + } else if (listener != null) { listener.onSuccess(response); } } @@ -2534,12 +2521,13 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = - new URLServiceSubscription>(this, uri, payload, true, responseListener); + ServiceCommand> request = new URLServiceSubscription>(this, + uri, payload, true, responseListener); request.send(); } - private ServiceCommand isWebAppPinned(boolean isSubscription, String webAppId, final WebAppPinStatusListener listener) { + private ServiceCommand isWebAppPinned(boolean isSubscription, String webAppId, + final WebAppPinStatusListener listener) { if (webAppId == null || webAppId.length() == 0) { if (listener != null) { listener.onError(new ServiceCommandError(-1, "You must provide a valid web app id", null)); @@ -2576,10 +2564,11 @@ public void onError(ServiceCommandError error) { }; ServiceCommand request; - if (isSubscription) + if (isSubscription) { request = new URLServiceSubscription(this, uri, payload, true, responseListener); - else + } else { request = new ServiceCommand(this, uri, payload, true, responseListener); + } request.send(); @@ -2592,9 +2581,9 @@ public void isWebAppPinned(String webAppId, WebAppPinStatusListener listener) { } @Override - public ServiceSubscription subscribeIsWebAppPinned( - String webAppId, WebAppPinStatusListener listener) { - return (URLServiceSubscription)isWebAppPinned(true, webAppId, listener); + public ServiceSubscription subscribeIsWebAppPinned(String webAppId, + WebAppPinStatusListener listener) { + return (URLServiceSubscription) isWebAppPinned(true, webAppId, listener); } /* Join a native/installed webOS app */ @@ -2655,11 +2644,13 @@ public void joinWebApp(String webAppId, WebAppSession.LaunchListener listener) { } private WebOSWebAppSession webAppSessionForLaunchSession(LaunchSession launchSession) { - if (mWebAppSessions == null) + if (mWebAppSessions == null) { mWebAppSessions = new ConcurrentHashMap(); + } - if (launchSession.getService() == null) + if (launchSession.getService() == null) { launchSession.setService(this); + } WebOSWebAppSession webAppSession = mWebAppSessions.get(launchSession.getAppId()); @@ -2690,11 +2681,13 @@ private void sendMessage(Object message, LaunchSession launchSession, ResponseLi String appId = launchSession.getAppId(); String fullAppId = appId; - if (launchSession.getSessionType() == LaunchSessionType.WebApp) + if (launchSession.getSessionType() == LaunchSessionType.WebApp) { fullAppId = mAppToAppIdMappings.get(appId); + } if (fullAppId == null || fullAppId.length() == 0) { - Util.postError(listener, new ServiceCommandError(-1, "You must provide a valid LaunchSession to send messages to", null)); + Util.postError(listener, + new ServiceCommandError(-1, "You must provide a valid LaunchSession to send messages to", null)); return; } @@ -2709,51 +2702,52 @@ private void sendMessage(Object message, LaunchSession launchSession, ResponseLi e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(this, null, payload, true, listener); + ServiceCommand> request = new ServiceCommand>(this, null, + payload, true, listener); sendCommand(request); } public void sendMessage(String message, LaunchSession launchSession, ResponseListener listener) { if (message != null && message.length() > 0) { sendMessage((Object) message, launchSession, listener); - } - else { + } else { Util.postError(listener, new ServiceCommandError(0, "Cannot send a null message", null)); } } public void sendMessage(JSONObject message, LaunchSession launchSession, ResponseListener listener) { - if (message != null && message.length() > 0) + if (message != null && message.length() > 0) { sendMessage((Object) message, launchSession, listener); - else + } else { Util.postError(listener, new ServiceCommandError(0, "Cannot send a null message", null)); + } } - - /************** - SYSTEM CONTROL - **************/ + /* ************* + * SYSTEM CONTROL + ************* */ public void getServiceInfo(final ServiceInfoListener listener) { String uri = "ssap://api/getServiceList"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, new ResponseListener() { + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, new ResponseListener() { - @Override - public void onSuccess(Object response) { - try { - JSONObject jsonObj = (JSONObject)response; - JSONArray services = (JSONArray) jsonObj.get("services"); - Util.postSuccess(listener, services); - } catch (JSONException e) { - e.printStackTrace(); - } - } + @Override + public void onSuccess(Object response) { + try { + JSONObject jsonObj = (JSONObject) response; + JSONArray services = (JSONArray) jsonObj.get("services"); + Util.postSuccess(listener, services); + } catch (JSONException e) { + e.printStackTrace(); + } + } - @Override - public void onError(ServiceCommandError error) { - Util.postError(listener, error); - } - }); + @Override + public void onError(ServiceCommandError error) { + Util.postError(listener, error); + } + }); request.send(); } @@ -2761,24 +2755,25 @@ public void onError(ServiceCommandError error) { public void getSystemInfo(final SystemInfoListener listener) { String uri = "ssap://system/getSystemInfo"; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, new ResponseListener() { + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, new ResponseListener() { - @Override - public void onSuccess(Object response) { - try { - JSONObject jsonObj = (JSONObject)response; - JSONObject features = (JSONObject) jsonObj.get("features"); - Util.postSuccess(listener, features); - } catch (JSONException e) { - e.printStackTrace(); - } - } + @Override + public void onSuccess(Object response) { + try { + JSONObject jsonObj = (JSONObject) response; + JSONObject features = (JSONObject) jsonObj.get("features"); + Util.postSuccess(listener, features); + } catch (JSONException e) { + e.printStackTrace(); + } + } - @Override - public void onError(ServiceCommandError error) { - Util.postError(listener, error); - } - }); + @Override + public void onError(ServiceCommandError error) { + Util.postError(listener, error); + } + }); request.send(); } @@ -2806,7 +2801,8 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, responseListener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, responseListener); request.send(); } @@ -2833,7 +2829,8 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, responseListener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, responseListener); request.send(); } @@ -2860,12 +2857,13 @@ public void onError(ServiceCommandError error) { } }; - ServiceCommand> request = new ServiceCommand>(this, uri, null, true, responseListener); + ServiceCommand> request = new ServiceCommand>(this, uri, null, + true, responseListener); request.send(); } /****************** - PLAYLIST CONTROL + * PLAYLIST CONTROL *****************/ @Override public PlaylistControl getPlaylistControl() { @@ -2889,32 +2887,34 @@ public void setPlayMode(PlayMode playMode, ResponseListener listener) { @Override public void sendCommand(ServiceCommand command) { - if (socket != null) + if (socket != null) { socket.sendCommand(command); + } } @Override public void unsubscribe(URLServiceSubscription subscription) { - if (socket != null) + if (socket != null) { socket.unsubscribe(subscription); + } } @Override protected void updateCapabilities() { List capabilities = new ArrayList(); - Collections.addAll(capabilities, VolumeControl.Capabilities); - Collections.addAll(capabilities, MediaPlayer.Capabilities); + capabilities.addAll(VolumeControl.Capabilities); + capabilities.addAll(MediaPlayer.Capabilities); if (DiscoveryManager.getInstance().getPairingLevel() == PairingLevel.ON) { - Collections.addAll(capabilities, TextInputControl.Capabilities); - Collections.addAll(capabilities, MouseControl.Capabilities); - Collections.addAll(capabilities, KeyControl.Capabilities); - Collections.addAll(capabilities, MediaPlayer.Capabilities); - Collections.addAll(capabilities, Launcher.Capabilities); - Collections.addAll(capabilities, TVControl.Capabilities); - Collections.addAll(capabilities, ExternalInputControl.Capabilities); - Collections.addAll(capabilities, ToastControl.Capabilities); + capabilities.addAll(TextInputControl.Capabilities); + capabilities.addAll(MouseControl.Capabilities); + capabilities.addAll(KeyControl.Capabilities); + capabilities.addAll(MediaPlayer.Capabilities); + capabilities.addAll(Launcher.Capabilities); + capabilities.addAll(TVControl.Capabilities); + capabilities.addAll(ExternalInputControl.Capabilities); + capabilities.addAll(ToastControl.Capabilities); capabilities.add(PowerControl.Off); } else { capabilities.add(Application); @@ -2934,8 +2934,7 @@ protected void updateCapabilities() { } if (serviceDescription != null) { - if (serviceDescription.getVersion() != null - && (serviceDescription.getVersion().contains("4.0.0") + if (serviceDescription.getVersion() != null && (serviceDescription.getVersion().contains("4.0.0") || serviceDescription.getVersion().contains("4.0.1"))) { capabilities.add(Launch); capabilities.add(Launch_Params); @@ -2954,8 +2953,8 @@ protected void updateCapabilities() { capabilities.add(MediaPlayer.Subtitle_SRT); } } else { - Collections.addAll(capabilities, WebAppLauncher.Capabilities); - Collections.addAll(capabilities, MediaControl.Capabilities); + capabilities.addAll(WebAppLauncher.Capabilities); + capabilities.addAll(MediaControl.Capabilities); capabilities.add(MediaPlayer.Subtitle_WebVTT); @@ -2972,8 +2971,9 @@ protected void updateCapabilities() { } public List getPermissions() { - if (permissions != null) + if (permissions != null) { return permissions; + } List defaultPermissions = new ArrayList(); Collections.addAll(defaultPermissions, kWebOSTVServiceOpenPermissions); @@ -3009,7 +3009,7 @@ private ProgramInfo parseRawProgramInfo(JSONObject programRawData) { ProgramInfo programInfo = new ProgramInfo(); programInfo.setRawData(programRawData); - + programId = programRawData.optString("programId"); programName = programRawData.optString("programName"); ChannelInfo channelInfo = parseRawChannelData(programRawData); @@ -3032,23 +3032,27 @@ private ChannelInfo parseRawChannelData(JSONObject channelRawData) { channelInfo.setRawData(channelRawData); try { - if (!channelRawData.isNull("channelName")) + if (!channelRawData.isNull("channelName")) { channelName = (String) channelRawData.get("channelName"); + } - if (!channelRawData.isNull("channelId")) + if (!channelRawData.isNull("channelId")) { channelId = (String) channelRawData.get("channelId"); + } channelNumber = channelRawData.optString("channelNumber"); - if (!channelRawData.isNull("majorNumber")) + if (!channelRawData.isNull("majorNumber")) { majorNumber = (Integer) channelRawData.get("majorNumber"); - else + } else { majorNumber = parseMajorNumber(channelNumber); + } - if (!channelRawData.isNull("minorNumber")) + if (!channelRawData.isNull("minorNumber")) { minorNumber = (Integer) channelRawData.get("minorNumber"); - else + } else { minorNumber = parseMinorNumber(channelNumber); + } channelInfo.setName(channelName); channelInfo.setId(channelId); @@ -3066,19 +3070,19 @@ private ChannelInfo parseRawChannelData(JSONObject channelRawData) { private int parseMinorNumber(String channelNumber) { if (channelNumber != null) { String tokens[] = channelNumber.split("-"); - return Integer.valueOf(tokens[tokens.length-1]); - } - else + return Integer.parseInt(tokens[tokens.length - 1]); + } else { return 0; + } } private int parseMajorNumber(String channelNumber) { if (channelNumber != null) { String tokens[] = channelNumber.split("-"); - return Integer.valueOf(tokens[0]); - } - else + return Integer.parseInt(tokens[0]); + } else { return 0; + } } private List externalnputInfoFromJSONArray(JSONArray inputList) { @@ -3109,15 +3113,15 @@ private List externalnputInfoFromJSONArray(JSONArray inputLis return externalInputInfoList; } -// @Override -// public LaunchSession decodeLaunchSession(String type, JSONObject obj) throws JSONException { -// if ("webostv".equals(type)) { -// LaunchSession launchSession = LaunchSession.launchSessionFromJSONObject(obj); -// launchSession.setService(this); -// return launchSession; -// } -// return null; -// } + // @Override + // public LaunchSession decodeLaunchSession(String type, JSONObject obj) throws JSONException { + // if ("webostv".equals(type)) { + // LaunchSession launchSession = LaunchSession.launchSessionFromJSONObject(obj); + // launchSession.setService(this); + // return launchSession; + // } + // return null; + // } @Override public void getPlayState(PlayStateListener listener) { @@ -3143,7 +3147,9 @@ public void sendPairingKey(String pairingKey) { } } - public static interface ServiceInfoListener extends ResponseListener { } + public static interface ServiceInfoListener extends ResponseListener { + } - public static interface SystemInfoListener extends ResponseListener { } + public static interface SystemInfoListener extends ResponseListener { + } } diff --git a/src/com/connectsdk/service/airplay/PListParser.java b/src/com/connectsdk/service/airplay/PListParser.java index f4764a48..50d40674 100644 --- a/src/com/connectsdk/service/airplay/PListParser.java +++ b/src/com/connectsdk/service/airplay/PListParser.java @@ -20,13 +20,13 @@ package com.connectsdk.service.airplay; -import android.util.Xml; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; import java.io.IOException; import java.io.InputStream; @@ -49,7 +49,7 @@ public class PListParser { public JSONObject parse(String text) throws XmlPullParserException, IOException, JSONException { - XmlPullParser parser = Xml.newPullParser(); + XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); Reader stream = new StringReader(text); parser.setInput(stream); @@ -60,7 +60,7 @@ public JSONObject parse(String text) throws XmlPullParserException, IOException, public JSONObject parse(InputStream in) throws XmlPullParserException, IOException, JSONException { try { - XmlPullParser parser = Xml.newPullParser(); + XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(in, null); parser.nextTag(); @@ -174,7 +174,7 @@ private String readData(XmlPullParser parser) throws IOException, XmlPullParserE private int readInteger(XmlPullParser parser) throws IOException, XmlPullParserException { parser.require(XmlPullParser.START_TAG, ns, TAG_INTEGER); - int value = Integer.valueOf(readText(parser)); + int value = Integer.parseInt(readText(parser)); parser.require(XmlPullParser.END_TAG, ns, TAG_INTEGER); return value; } diff --git a/src/com/connectsdk/service/capability/CapabilityMethods.java b/src/com/connectsdk/service/capability/CapabilityMethods.java index f7529577..f5c8be4c 100644 --- a/src/com/connectsdk/service/capability/CapabilityMethods.java +++ b/src/com/connectsdk/service/capability/CapabilityMethods.java @@ -33,7 +33,7 @@ public interface CapabilityMethods { * CapabilityPriorityLevel values are used by ConnectableDevice to find the most suitable DeviceService capability to be presented to the user. Values of VeryLow and VeryHigh are not in use internally the SDK. Connect SDK uses Low, Normal, and High internally. * * Default behavior: - * If you are unsatisfied with the default priority levels & behavior of Connect SDK, it is possible to subclass a particular DeviceService and provide your own value for each capability. That DeviceService subclass would need to be registered with DiscoveryManager. + * If you are unsatisfied with the default priority levels & behavior of Connect SDK, it is possible to subclass a particular DeviceService and provide your own value for each capability. That DeviceService subclass would need to be registered with DiscoveryManager. */ public enum CapabilityPriorityLevel { NOT_SUPPORTED (0), diff --git a/src/com/connectsdk/service/capability/ExternalInputControl.java b/src/com/connectsdk/service/capability/ExternalInputControl.java index 381476b6..ccc87c4d 100644 --- a/src/com/connectsdk/service/capability/ExternalInputControl.java +++ b/src/com/connectsdk/service/capability/ExternalInputControl.java @@ -20,10 +20,12 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import com.connectsdk.core.ExternalInputInfo; -import com.connectsdk.service.capability.Launcher.AppLaunchListener; import com.connectsdk.service.capability.listeners.ResponseListener; import com.connectsdk.service.sessions.LaunchSession; @@ -35,17 +37,18 @@ public interface ExternalInputControl extends CapabilityMethods { public final static String List = "ExternalInputControl.List"; public final static String Set = "ExternalInputControl.Set"; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Picker_Launch, Picker_Close, List, Set - }; + )); public ExternalInputControl getExternalInput(); public CapabilityPriorityLevel getExternalInputControlPriorityLevel(); - public void launchInputPicker(AppLaunchListener listener); + public void launchInputPicker(ResponseListener listener); public void closeInputPicker(LaunchSession launchSessionm, ResponseListener listener); public void getExternalInputList(ExternalInputListListener listener); diff --git a/src/com/connectsdk/service/capability/KeyControl.java b/src/com/connectsdk/service/capability/KeyControl.java index 90cdb518..bab6672f 100644 --- a/src/com/connectsdk/service/capability/KeyControl.java +++ b/src/com/connectsdk/service/capability/KeyControl.java @@ -20,6 +20,10 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + import com.connectsdk.service.capability.listeners.ResponseListener; public interface KeyControl extends CapabilityMethods { @@ -72,7 +76,8 @@ public static KeyCode createFromInteger(int keyCode) { } } - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Up, Down, Left, @@ -80,8 +85,7 @@ public static KeyCode createFromInteger(int keyCode) { OK, Back, Home, - KeyCode, - }; + KeyCode)); public KeyControl getKeyControl(); public CapabilityPriorityLevel getKeyControlCapabilityLevel(); diff --git a/src/com/connectsdk/service/capability/Launcher.java b/src/com/connectsdk/service/capability/Launcher.java index 828ca3b8..d76cca67 100644 --- a/src/com/connectsdk/service/capability/Launcher.java +++ b/src/com/connectsdk/service/capability/Launcher.java @@ -20,6 +20,9 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import com.connectsdk.core.AppInfo; @@ -49,7 +52,8 @@ public interface Launcher extends CapabilityMethods { public final static String RunningApp = "Launcher.RunningApp"; public final static String RunningApp_Subscribe = "Launcher.RunningApp.Subscribe"; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Application, Application_Params, Application_Close, @@ -68,14 +72,14 @@ public interface Launcher extends CapabilityMethods { AppState_Subscribe, RunningApp, RunningApp_Subscribe - }; + )); public Launcher getLauncher(); public CapabilityPriorityLevel getLauncherCapabilityLevel(); - public void launchAppWithInfo(AppInfo appInfo, AppLaunchListener listener); - public void launchAppWithInfo(AppInfo appInfo, Object params, AppLaunchListener listener); - public void launchApp(String appId, AppLaunchListener listener); + public void launchAppWithInfo(AppInfo appInfo, ResponseListener listener); + public void launchAppWithInfo(AppInfo appInfo, Object params, ResponseListener listener); + public void launchApp(String appId, ResponseListener listener); public void closeApp(LaunchSession launchSession, ResponseListener listener); @@ -87,20 +91,14 @@ public interface Launcher extends CapabilityMethods { public void getAppState(LaunchSession launchSession, AppStateListener listener); public ServiceSubscription subscribeAppState(LaunchSession launchSession, AppStateListener listener); - public void launchBrowser(String url, AppLaunchListener listener); - public void launchYouTube(String contentId, AppLaunchListener listener); - public void launchYouTube(String contentId, float startTime, AppLaunchListener listener); - public void launchNetflix(String contentId, AppLaunchListener listener); - public void launchHulu(String contentId, AppLaunchListener listener); - public void launchAppStore(String appId, AppLaunchListener listener); - - /** - * Success listener that is called upon successfully launching an app. - * - * Passes a LaunchSession Object containing important information about the app's launch session - */ - public static interface AppLaunchListener extends ResponseListener { } + public void launchBrowser(String url, ResponseListener listener); + public void launchYouTube(String contentId, ResponseListener listener); + public void launchYouTube(String contentId, float startTime, ResponseListener listener); + public void launchNetflix(String contentId, ResponseListener listener); + public void launchHulu(String contentId, ResponseListener listener); + public void launchAppStore(String appId, ResponseListener listener); + /** * Success listener that is called upon requesting info about the current running app. * diff --git a/src/com/connectsdk/service/capability/MediaControl.java b/src/com/connectsdk/service/capability/MediaControl.java index a7fb7a60..9fac2632 100644 --- a/src/com/connectsdk/service/capability/MediaControl.java +++ b/src/com/connectsdk/service/capability/MediaControl.java @@ -20,6 +20,10 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + import com.connectsdk.service.capability.listeners.ResponseListener; import com.connectsdk.service.command.ServiceSubscription; @@ -57,7 +61,8 @@ public interface MediaControl extends CapabilityMethods { public static final int PLAYER_STATE_BUFFERING = 4; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Play, Pause, Stop, @@ -69,8 +74,8 @@ public interface MediaControl extends CapabilityMethods { Duration, PlayState, PlayState_Subscribe, - Position, - }; + Position + )); /** * Enumerates possible playback status @@ -193,44 +198,49 @@ else if (transportState.equals("NO_MEDIA_PRESENT")) { /** * This method is deprecated. - * Use `PlaylistControl#previous(ResponseListener listener)` instead. + * Use `PlaylistControl#previous(ResponseListener<Object> listener)` instead. + * @param listener the listener */ @Deprecated public void previous(ResponseListener listener); /** * This method is deprecated. - * Use `PlaylistControl#next(ResponseListener listener)` instead. + * Use `PlaylistControl#next(ResponseListener<Object> listener)` instead. + * @param listener the listener */ @Deprecated public void next(ResponseListener listener); /** * @param position The new position, in milliseconds from the beginning of the stream - * @param listener (optional) ResponseListener< Object > with methods to be called on success + * @param listener (optional) ResponseListener<Object> with methods to be called on success * or failure */ public void seek(long position, ResponseListener listener); /** - * Get the current media duration in milliseconds + * Get the current media duration in milliseconds. + * @param listener the listener that receives the result */ public void getDuration(DurationListener listener); /** - * Get the current playback position in milliseconds + * Get the current playback position in milliseconds. + * @param listener the listener that receives the result */ public void getPosition(PositionListener listener); /** - * Get the current state of playback + * Get the current state of playback. + * @param listener the listener that receives the result */ public void getPlayState(PlayStateListener listener); /** * Subscribe for playback state changes * @param listener receives play state notifications - * @return ServiceSubscription + * @return ServiceSubscription<PlayStateListener> */ public ServiceSubscription subscribePlayState(PlayStateListener listener); diff --git a/src/com/connectsdk/service/capability/MediaPlayer.java b/src/com/connectsdk/service/capability/MediaPlayer.java index a45715c0..854c1023 100644 --- a/src/com/connectsdk/service/capability/MediaPlayer.java +++ b/src/com/connectsdk/service/capability/MediaPlayer.java @@ -20,6 +20,10 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + import com.connectsdk.core.MediaInfo; import com.connectsdk.service.capability.listeners.ResponseListener; import com.connectsdk.service.command.ServiceSubscription; @@ -57,7 +61,8 @@ public interface MediaPlayer extends CapabilityMethods { public final static String MediaInfo_Get = "MediaPlayer.MediaInfo.Get"; public final static String MediaInfo_Subscribe = "MediaPlayer.MediaInfo.Subscribe"; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Display_Image, Play_Video, Play_Audio, @@ -68,7 +73,7 @@ public interface MediaPlayer extends CapabilityMethods { MetaData_MimeType, MediaInfo_Get, MediaInfo_Subscribe - }; + )); public MediaPlayer getMediaPlayer(); @@ -87,6 +92,12 @@ public interface MediaPlayer extends CapabilityMethods { /** * This method is deprecated. * Use `MediaPlayer#displayImage(MediaInfo mediaInfo, LaunchListener listener)` instead. + * @param url the url + * @param mimeType the mime type + * @param title the title + * @param description description + * @param iconSrc the icon src + * @param listener the listener */ @Deprecated public void displayImage(String url, String mimeType, String title, String description, String iconSrc, LaunchListener listener); @@ -95,6 +106,13 @@ public interface MediaPlayer extends CapabilityMethods { * This method is deprecated. * Use `MediaPlayer#playMedia(MediaInfo mediaInfo, boolean shouldLoop, LaunchListener listener)` * instead. + * @param url the url + * @param mimeType the mime type + * @param title the title + * @param description description + * @param iconSrc the icon src + * @param shouldLoop should it loop + * @param listener the listener */ @Deprecated public void playMedia(String url, String mimeType, String title, String description, String iconSrc, boolean shouldLoop, LaunchListener listener); diff --git a/src/com/connectsdk/service/capability/MouseControl.java b/src/com/connectsdk/service/capability/MouseControl.java index b34e632a..1c60d0f0 100644 --- a/src/com/connectsdk/service/capability/MouseControl.java +++ b/src/com/connectsdk/service/capability/MouseControl.java @@ -20,7 +20,11 @@ package com.connectsdk.service.capability; -import android.graphics.PointF; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import com.connectsdk.core.PointF; public interface MouseControl extends CapabilityMethods { @@ -32,13 +36,14 @@ public interface MouseControl extends CapabilityMethods { public final static String Move = "MouseControl.Move"; public final static String Scroll = "MouseControl.Scroll"; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Connect, Disconnect, Click, Move, Scroll - }; + )); public MouseControl getMouseControl(); public CapabilityPriorityLevel getMouseControlCapabilityLevel(); diff --git a/src/com/connectsdk/service/capability/PlaylistControl.java b/src/com/connectsdk/service/capability/PlaylistControl.java index 76a30e36..8e41088a 100644 --- a/src/com/connectsdk/service/capability/PlaylistControl.java +++ b/src/com/connectsdk/service/capability/PlaylistControl.java @@ -94,7 +94,7 @@ public static enum PlayMode { /** * Set order of playing tracks * - * @param playMode + * @param playMode the play mode * @param listener optional response listener */ public void setPlayMode(PlayMode playMode, ResponseListener listener); diff --git a/src/com/connectsdk/service/capability/PowerControl.java b/src/com/connectsdk/service/capability/PowerControl.java index de37d8c7..7664562d 100644 --- a/src/com/connectsdk/service/capability/PowerControl.java +++ b/src/com/connectsdk/service/capability/PowerControl.java @@ -20,6 +20,10 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + import com.connectsdk.service.capability.listeners.ResponseListener; public interface PowerControl extends CapabilityMethods { @@ -28,10 +32,11 @@ public interface PowerControl extends CapabilityMethods { public final static String Off = "PowerControl.Off"; public final static String On = "PowerControl.On"; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Off, On - }; + )); public PowerControl getPowerControl(); public CapabilityPriorityLevel getPowerControlCapabilityLevel(); diff --git a/src/com/connectsdk/service/capability/TVControl.java b/src/com/connectsdk/service/capability/TVControl.java index a69f1a40..bb5828b3 100644 --- a/src/com/connectsdk/service/capability/TVControl.java +++ b/src/com/connectsdk/service/capability/TVControl.java @@ -20,6 +20,9 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import com.connectsdk.core.ChannelInfo; @@ -45,7 +48,8 @@ public interface TVControl extends CapabilityMethods { public final static String Set_3D = "TVControl.3D.Set"; public final static String Subscribe_3D = "TVControl.3D.Subscribe"; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Channel_Get, Channel_Set, Channel_Up, @@ -59,7 +63,7 @@ public interface TVControl extends CapabilityMethods { Get_3D, Set_3D, Subscribe_3D - }; + )); public TVControl getTVControl(); public CapabilityPriorityLevel getTVControlCapabilityLevel(); diff --git a/src/com/connectsdk/service/capability/TextInputControl.java b/src/com/connectsdk/service/capability/TextInputControl.java index aae0802c..d4dc1bdf 100644 --- a/src/com/connectsdk/service/capability/TextInputControl.java +++ b/src/com/connectsdk/service/capability/TextInputControl.java @@ -20,6 +20,10 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + import com.connectsdk.core.TextInputStatusInfo; import com.connectsdk.service.capability.listeners.ResponseListener; import com.connectsdk.service.command.ServiceSubscription; @@ -32,12 +36,13 @@ public interface TextInputControl extends CapabilityMethods { public final static String Send_Delete = "TextInputControl.Delete"; public final static String Subscribe = "TextInputControl.Subscribe"; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Send, Send_Enter, Send_Delete, Subscribe - }; + )); public TextInputControl getTextInputControl(); public CapabilityPriorityLevel getTextInputControlCapabilityLevel(); @@ -51,7 +56,7 @@ public interface TextInputControl extends CapabilityMethods { /** * Response block that is fired on any change of keyboard visibility. * - * Passes TextInputStatusInfo object that provides keyboard type & visibility information + * Passes TextInputStatusInfo object that provides keyboard type & visibility information */ public static interface TextInputStatusListener extends ResponseListener { } } diff --git a/src/com/connectsdk/service/capability/ToastControl.java b/src/com/connectsdk/service/capability/ToastControl.java index 98a718ec..05dcb123 100644 --- a/src/com/connectsdk/service/capability/ToastControl.java +++ b/src/com/connectsdk/service/capability/ToastControl.java @@ -20,6 +20,10 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + import org.json.JSONObject; import com.connectsdk.core.AppInfo; @@ -33,12 +37,13 @@ public interface ToastControl extends CapabilityMethods { public final static String Show_Clickable_Toast_App_Params = "ToastControl.Show.Clickable.App.Params"; public final static String Show_Clickable_Toast_URL = "ToastControl.Show.Clickable.URL"; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Show_Toast, Show_Clickable_Toast_App, Show_Clickable_Toast_App_Params, Show_Clickable_Toast_URL - }; + )); public ToastControl getToastControl(); public CapabilityPriorityLevel getToastControlCapabilityLevel(); diff --git a/src/com/connectsdk/service/capability/VolumeControl.java b/src/com/connectsdk/service/capability/VolumeControl.java index 7aec7bb8..f41f3717 100644 --- a/src/com/connectsdk/service/capability/VolumeControl.java +++ b/src/com/connectsdk/service/capability/VolumeControl.java @@ -20,6 +20,11 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + + import com.connectsdk.service.capability.listeners.ResponseListener; import com.connectsdk.service.command.ServiceSubscription; @@ -33,8 +38,9 @@ public interface VolumeControl extends CapabilityMethods { public final static String Mute_Get = "VolumeControl.Mute.Get"; public final static String Mute_Set = "VolumeControl.Mute.Set"; public final static String Mute_Subscribe = "VolumeControl.Mute.Subscribe"; - - public final static String[] Capabilities = { + + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Volume_Get, Volume_Set, Volume_Up_Down, @@ -42,7 +48,8 @@ public interface VolumeControl extends CapabilityMethods { Mute_Get, Mute_Set, Mute_Subscribe - }; + )); + public VolumeControl getVolumeControl(); public CapabilityPriorityLevel getVolumeControlCapabilityLevel(); diff --git a/src/com/connectsdk/service/capability/WebAppLauncher.java b/src/com/connectsdk/service/capability/WebAppLauncher.java index 81d94804..b779688b 100644 --- a/src/com/connectsdk/service/capability/WebAppLauncher.java +++ b/src/com/connectsdk/service/capability/WebAppLauncher.java @@ -20,6 +20,10 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + import org.json.JSONObject; import com.connectsdk.service.capability.listeners.ResponseListener; @@ -44,7 +48,8 @@ public interface WebAppLauncher extends CapabilityMethods { public final static String Close = "WebAppLauncher.Close"; public final static String Pin = "WebAppLauncher.Pin"; - public final static String[] Capabilities = { + public final static Collection Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Launch, Launch_Params, Message_Send, @@ -56,7 +61,7 @@ public interface WebAppLauncher extends CapabilityMethods { Join, Close, Pin - }; + )); public WebAppLauncher getWebAppLauncher(); public CapabilityPriorityLevel getWebAppLauncherCapabilityLevel(); diff --git a/src/com/connectsdk/service/capability/listeners/ErrorListener.java b/src/com/connectsdk/service/capability/listeners/ErrorListener.java index b7af9f58..2e00c396 100644 --- a/src/com/connectsdk/service/capability/listeners/ErrorListener.java +++ b/src/com/connectsdk/service/capability/listeners/ErrorListener.java @@ -39,14 +39,13 @@ * ####Result * The capability method will immediately invoke the ErrorListener and pass off an ServiceCommandError object with a status code of ConnectStatusCodeArgumentError. * - * @param error ServiceCommandError object describing the nature of the problem. Error descriptions are not localized and mostly intended for developer use. It is not recommended to display most error descriptions in UI elements. */ public interface ErrorListener { /** * Method to return the error that was generated. Will pass an error object with a helpful status code and error message. * - * @param error ServiceCommandError describing the error + * @param error ServiceCommandError object describing the nature of the problem. Error descriptions are not localized and mostly intended for developer use. It is not recommended to display most error descriptions in UI elements. */ public void onError(ServiceCommandError error); } diff --git a/src/com/connectsdk/service/capability/listeners/ResponseListener.java b/src/com/connectsdk/service/capability/listeners/ResponseListener.java index f70b6305..4889650b 100644 --- a/src/com/connectsdk/service/capability/listeners/ResponseListener.java +++ b/src/com/connectsdk/service/capability/listeners/ResponseListener.java @@ -22,15 +22,16 @@ /** * Generic asynchronous operation response success handler block. If there is any response data to be processed, it will be provided via the responseObject parameter. - * - * @param responseObject Contains the output data as a generic object reference. This value may be any of a number of types as defined by T in subclasses of ResponseListener. It is also possible that responseObject will be nil for operations that don't require data to be returned (move mouse, send key code, etc). */ public interface ResponseListener extends ErrorListener { /** * Returns the success of the call of type T. + * Contains the output data as a generic object reference. + * This value may be any of a number of types as defined by T in subclasses of ResponseListener. + * It is also possible that responseObject will be null for operations that don't require data to be returned (move mouse, send key code, etc). * - * @param object Response object, can be any number of object types, depending on the protocol/capability/etc + * @param responseObject Response object, can be any number of object types, depending on the protocol/capability/etc, even null */ - abstract public void onSuccess(T object); + abstract public void onSuccess(T responseObject); } diff --git a/src/com/connectsdk/service/config/WebOSTVServiceConfig.java b/src/com/connectsdk/service/config/WebOSTVServiceConfig.java index 3d2be275..d7307608 100644 --- a/src/com/connectsdk/service/config/WebOSTVServiceConfig.java +++ b/src/com/connectsdk/service/config/WebOSTVServiceConfig.java @@ -27,10 +27,11 @@ import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import javax.xml.bind.DatatypeConverter; + import org.json.JSONException; import org.json.JSONObject; -import android.util.Base64; public class WebOSTVServiceConfig extends ServiceConfig { @@ -99,7 +100,8 @@ private String exportCertificateToPEM(X509Certificate cert) { try { if (cert == null) return null; - return Base64.encodeToString(cert.getEncoded(), Base64.DEFAULT); + //return java.util.Base64.getEncoder().encodeToString(cert.getEncoded()); // only available in java 1.8 + return DatatypeConverter.printBase64Binary(cert.getEncoded()); } catch (CertificateEncodingException e) { e.printStackTrace(); return null; diff --git a/src/com/connectsdk/service/netcast/NetcastHttpServer.java b/src/com/connectsdk/service/netcast/NetcastHttpServer.java index 5b2e7f6d..73560f74 100644 --- a/src/com/connectsdk/service/netcast/NetcastHttpServer.java +++ b/src/com/connectsdk/service/netcast/NetcastHttpServer.java @@ -26,10 +26,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.ServerSocket; import java.net.Socket; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.List; @@ -44,9 +46,8 @@ import org.json.JSONObject; import org.xml.sax.SAXException; -import android.util.Log; - import com.connectsdk.core.ChannelInfo; +import com.connectsdk.core.Log; import com.connectsdk.core.TextInputStatusInfo; import com.connectsdk.core.Util; import com.connectsdk.service.NetcastTVService; @@ -92,8 +93,7 @@ public void start() { } Socket connectionSocket = null; - BufferedReader inFromClient = null; - DataOutputStream outToClient = null; + try { connectionSocket = welcomeSocket.accept(); @@ -108,9 +108,7 @@ public void start() { int c; StringBuilder sb = new StringBuilder(); - try { - inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); - + try (BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream(), StandardCharsets.UTF_8));){ while ((str = inFromClient.readLine()) != null) { if (str.equals("")) { break; @@ -136,15 +134,11 @@ public void start() { SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); String date = dateFormat.format(calendar.getTime()); - String androidOSVersion = android.os.Build.VERSION.RELEASE; + //String androidOSVersion = android.os.Build.VERSION.RELEASE; - PrintWriter out = null; - - try { - outToClient = new DataOutputStream(connectionSocket.getOutputStream()); - out = new PrintWriter(outToClient); + try(PrintWriter out = new PrintWriter(new OutputStreamWriter(connectionSocket.getOutputStream(),StandardCharsets.US_ASCII))) { out.println("HTTP/1.1 200 OK"); - out.println("Server: Android/" + androidOSVersion + " UDAP/2.0 ConnectSDK/1.2.1"); + //out.println("Server: Android/" + androidOSVersion + " UDAP/2.0 ConnectSDK/1.2.1"); out.println("Cache-Control: no-store, no-cache, must-revalidate"); out.println("Date: " + date); out.println("Connection: Close"); @@ -153,25 +147,12 @@ public void start() { out.flush(); } catch (IOException ex) { ex.printStackTrace(); - } finally { - try { - inFromClient.close(); - out.close(); - outToClient.close(); - connectionSocket.close(); - } catch (IOException ex) { - ex.printStackTrace(); - } - } + } SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); InputStream stream = null; - try { - stream = new ByteArrayInputStream(body.getBytes("UTF-8")); - } catch (UnsupportedEncodingException ex) { - ex.printStackTrace(); - } + stream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)); NetcastPOSTRequestParser handler = new NetcastPOSTRequestParser(); diff --git a/src/com/connectsdk/service/netcast/NetcastPOSTRequestParser.java b/src/com/connectsdk/service/netcast/NetcastPOSTRequestParser.java index d113bf2a..90e8e189 100644 --- a/src/com/connectsdk/service/netcast/NetcastPOSTRequestParser.java +++ b/src/com/connectsdk/service/netcast/NetcastPOSTRequestParser.java @@ -27,32 +27,32 @@ import org.xml.sax.helpers.DefaultHandler; public class NetcastPOSTRequestParser extends DefaultHandler { - public JSONObject object; - public JSONObject subObject; + private JSONObject object; + private JSONObject subObject; - boolean textEditMode = false; - boolean keyboardVisibleMode = false; + private boolean textEditMode = false; + private boolean keyboardVisibleMode = false; - public String value; + private String value; - public final String CHANNEL_TYPE = "chtype"; - public final String MAJOR = "major"; - public final String MINOR = "minor"; - public final String DISPLAY_MAJOR = "displayMajor"; - public final String DISPLAY_MINOR = "displayMinor"; - public final String SOURCE_INDEX = "sourceIndex"; - public final String PHYSICAL_NUM = "physicalNum"; - public final String CHANNEL_NAME = "chname"; - public final String PROGRAM_NAME = "progName"; - public final String AUDIO_CHANNEL = "audioCh"; - public final String INPUT_SOURCE_NAME = "inputSourceName"; - public final String INPUT_SOURCE_TYPE = "inputSourceType"; - public final String LABEL_NAME = "labelName"; - public final String INPUT_SOURCE_INDEX = "inputSourceIdx"; + private static final String CHANNEL_TYPE = "chtype"; + private static final String MAJOR = "major"; + private static final String MINOR = "minor"; + private static final String DISPLAY_MAJOR = "displayMajor"; + private static final String DISPLAY_MINOR = "displayMinor"; + private static final String SOURCE_INDEX = "sourceIndex"; + private static final String PHYSICAL_NUM = "physicalNum"; + private static final String CHANNEL_NAME = "chname"; + private static final String PROGRAM_NAME = "progName"; + private static final String AUDIO_CHANNEL = "audioCh"; + private static final String INPUT_SOURCE_NAME = "inputSourceName"; + private static final String INPUT_SOURCE_TYPE = "inputSourceType"; + private static final String LABEL_NAME = "labelName"; + private static final String INPUT_SOURCE_INDEX = "inputSourceIdx"; - public final String VALUE = "value"; - public final String MODE = "mode"; - public final String STATE = "state"; + private static final String VALUE = "value"; + private static final String MODE = "mode"; + private static final String STATE = "state"; public NetcastPOSTRequestParser() { object = new JSONObject(); diff --git a/src/com/connectsdk/service/sessions/LaunchSession.java b/src/com/connectsdk/service/sessions/LaunchSession.java index 63070820..1f772899 100644 --- a/src/com/connectsdk/service/sessions/LaunchSession.java +++ b/src/com/connectsdk/service/sessions/LaunchSession.java @@ -68,6 +68,7 @@ public LaunchSession() { * Instantiates a LaunchSession object for a given app ID. * * @param appId System-specific, unique ID of the app + * @return the launch session */ public static LaunchSession launchSessionForAppId(String appId) { LaunchSession launchSession = new LaunchSession(); @@ -89,7 +90,7 @@ public static LaunchSession launchSessionFromJSONObject(JSONObject json) { } // @endcond - /** System-specific, unique ID of the app (ex. youtube.leanback.v4, 0000134, hulu) */ + /** @return System-specific, unique ID of the app (ex. youtube.leanback.v4, 0000134, hulu) */ public String getAppId() { return appId; } @@ -103,7 +104,7 @@ public void setAppId(String appId) { this.appId = appId; } - /** User-friendly name of the app (ex. YouTube, Browser, Hulu) */ + /** @return User-friendly name of the app (ex. YouTube, Browser, Hulu) */ public String getAppName() { return appName; } @@ -117,7 +118,7 @@ public void setAppName(String appName) { this.appName = appName; } - /** Unique ID for the session (only provided by certain protocols) */ + /** @return Unique ID for the session (only provided by certain protocols) */ public String getSessionId() { return sessionId; } @@ -131,7 +132,7 @@ public void setSessionId(String sessionId) { this.sessionId = sessionId; } - /** DeviceService responsible for launching the session. */ + /** @return DeviceService responsible for launching the session. */ public DeviceService getService() { return service; } @@ -145,7 +146,7 @@ public void setService(DeviceService service) { this.service = service; } - /** Raw data from the first screen device about the session. In most cases, this is a JSONObject. */ + /** @return Raw data from the first screen device about the session. In most cases, this is a JSONObject. */ public Object getRawData() { return rawData; } @@ -160,7 +161,7 @@ public void setRawData(Object rawData) { } /** - * When closing a LaunchSession, the DeviceService relies on the sessionType to determine the method of closing the session. + * @return When closing a LaunchSession, the DeviceService relies on the sessionType to determine the method of closing the session. */ public LaunchSessionType getSessionType() { return sessionType; @@ -177,7 +178,7 @@ public void setSessionType(LaunchSessionType sessionType) { /** * Close the app/media associated with the session. - * @param listener + * @param listener the response listener */ public void close (ResponseListener listener) { service.closeLaunchSession(this, listener); @@ -225,16 +226,5 @@ public void fromJSONObject(JSONObject obj) throws JSONException { // @endcond - /** - * Compares two LaunchSession objects. - * - * @param launchSession LaunchSession object to compare. - * - * @return true if both LaunchSession id and sessionId values are equal - */ - @Override - public boolean equals(Object launchSession) { - // TODO Auto-generated method stub - return super.equals(launchSession); - } + } diff --git a/src/com/connectsdk/service/sessions/WebAppSession.java b/src/com/connectsdk/service/sessions/WebAppSession.java index ddd77b3f..90c8c6ce 100644 --- a/src/com/connectsdk/service/sessions/WebAppSession.java +++ b/src/com/connectsdk/service/sessions/WebAppSession.java @@ -44,7 +44,7 @@ * with web app * * MediaPlayer and MediaControl are provided to allow for the most common first - * screen use cases -- a media player (audio, video, & images). + * screen use cases -- a media player (audio, video, & images). * * The Connect SDK JavaScript Bridge has been produced to provide normalized * support for these capabilities across protocols (Chromecast, webOS, etc). @@ -66,15 +66,13 @@ public enum WebAppStatus { } /** - * Success block that is called upon successfully getting a web app's status. - * - * @param status The current running & foreground status of the web app + * Called upon successfully getting a web app's status. */ public static interface WebAppPinStatusListener extends ResponseListener { } /** * LaunchSession object containing key session information. Much of this - * information is required for web app messaging & closing the web app. + * information is required for web app messaging & closing the web app. */ public LaunchSession launchSession; @@ -99,7 +97,7 @@ public WebAppSession(LaunchSession launchSession, DeviceService service) { } /** - * DeviceService that was responsible for launching this web app. + * @param service DeviceService that was responsible for launching this web app. */ protected void setService(DeviceService service) { } @@ -108,8 +106,8 @@ protected void setService(DeviceService service) { /** * Subscribes to changes in the web app's status. * - * @param listener - * (optional) MessageListener to be called on app status change + * @param listener (optional) MessageListener to be called on app status change + * @return the subscription */ public ServiceSubscription subscribeWebAppStatus( MessageListener listener) { @@ -122,8 +120,7 @@ public ServiceSubscription subscribeWebAppStatus( /** * Establishes a communication channel with the web app. * - * @param connectionListener - * (optional) ResponseListener to be called on success + * @param connectionListener (optional) ResponseListener to be called on success */ public void connect(ResponseListener connectionListener) { Util.postError(connectionListener, ServiceCommandError.notSupported()); @@ -132,7 +129,7 @@ public void connect(ResponseListener connectionListener) { /** * Establishes a communication channel with a currently running web app. * - * @param connectionListener + * @param connectionListener (optional) ResponseListener to be called on success */ public void join(ResponseListener connectionListener) { Util.postError(connectionListener, ServiceCommandError.notSupported()); @@ -146,6 +143,8 @@ public void disconnectFromWebApp() { /** * Pin the web app on the launcher. + * @param webAppId the web app id + * @param listener (optional) ResponseListener to be called on success */ public void pinWebApp(String webAppId, ResponseListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); @@ -155,6 +154,7 @@ public void pinWebApp(String webAppId, ResponseListener listener) { * UnPin the web app on the launcher. * * @param webAppId NSString webAppId to be unpinned. + * @param listener (optional) ResponseListener to be called on success */ public void unPinWebApp(String webAppId, ResponseListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); @@ -162,6 +162,8 @@ public void unPinWebApp(String webAppId, ResponseListener listener) { /** * To check if the web app is pinned or not + * @param webAppId the web app id + * @param listener (optional) ResponseListener to be called on success */ public void isWebAppPinned(String webAppId, WebAppPinStatusListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); @@ -169,6 +171,9 @@ public void isWebAppPinned(String webAppId, WebAppPinStatusListener listener) { /** * Subscribe to check if the web app is pinned or not + * @param webAppId the web app id + * @param listener (optional) ResponseListener to be called on success + * @return the subscription */ public ServiceSubscription subscribeIsWebAppPinned(String webAppId, WebAppPinStatusListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); @@ -178,8 +183,7 @@ public ServiceSubscription subscribeIsWebAppPinned(Stri /** * Closes the web app on the first screen device. * - * @param listener - * (optional) ResponseListener to be called on success + * @param listener (optional) ResponseListener to be called on success */ public void close(ResponseListener listener) { if (listener != null) @@ -190,6 +194,7 @@ public void close(ResponseListener listener) { * Sends a simple string to the web app. The Connect SDK JavaScript Bridge * will receive this message and hand it off as a string object. * + * @param message the message * @param listener * (optional) ResponseListener to be called on success */ @@ -202,7 +207,8 @@ public void sendMessage(String message, ResponseListener listener) { * Sends a JSON object to the web app. The Connect SDK JavaScript Bridge * will receive this message and hand it off as a JavaScript object. * - * @param success + * @param message the message + * @param listener * (optional) ResponseListener to be called on success */ public void sendMessage(JSONObject message, @@ -459,6 +465,7 @@ public void setPlayMode(PlayMode playMode, ResponseListener listener) { * When messages are received from a web app, they are parsed into the * appropriate object type (string vs JSON/NSDictionary) and routed to the * WebAppSessionListener. + * @return the session listener */ public WebAppSessionListener getWebAppSessionListener() { return webAppListener; @@ -493,7 +500,7 @@ public static interface LaunchListener extends * Success block that is called upon successfully getting a web app's * status. * - * Passes a WebAppStatus of the current running & foreground status of the + * Passes a WebAppStatus of the current running & foreground status of the * web app */ public static interface StatusListener extends diff --git a/src/com/connectsdk/service/sessions/WebOSWebAppSession.java b/src/com/connectsdk/service/sessions/WebOSWebAppSession.java index 23960992..f1b7c046 100644 --- a/src/com/connectsdk/service/sessions/WebOSWebAppSession.java +++ b/src/com/connectsdk/service/sessions/WebOSWebAppSession.java @@ -20,9 +20,6 @@ package com.connectsdk.service.sessions; -import android.support.annotation.NonNull; -import android.util.Log; - import java.util.Enumeration; import java.util.List; import java.util.Locale; @@ -33,7 +30,9 @@ import org.json.JSONObject; import com.connectsdk.core.ImageInfo; +import com.connectsdk.core.Log; import com.connectsdk.core.MediaInfo; +import com.connectsdk.core.NonNull; import com.connectsdk.core.SubtitleInfo; import com.connectsdk.core.Util; import com.connectsdk.service.DeviceService; diff --git a/src/com/connectsdk/service/upnp/DLNAEventParser.java b/src/com/connectsdk/service/upnp/DLNAEventParser.java index 6100ad14..d97ff7dc 100644 --- a/src/com/connectsdk/service/upnp/DLNAEventParser.java +++ b/src/com/connectsdk/service/upnp/DLNAEventParser.java @@ -8,15 +8,14 @@ import org.json.JSONObject; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; - -import android.util.Xml; +import org.xmlpull.v1.XmlPullParserFactory; public class DLNAEventParser { private static final String ns = null; public JSONObject parse(InputStream in) throws XmlPullParserException, IOException, JSONException { try { - XmlPullParser parser = Xml.newPullParser(); + XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(in, null); parser.nextTag(); diff --git a/src/com/connectsdk/service/upnp/DLNAHttpServer.java b/src/com/connectsdk/service/upnp/DLNAHttpServer.java index abd7c4cb..550c2f5b 100644 --- a/src/com/connectsdk/service/upnp/DLNAHttpServer.java +++ b/src/com/connectsdk/service/upnp/DLNAHttpServer.java @@ -17,10 +17,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.ServerSocket; import java.net.Socket; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -86,70 +88,47 @@ private void processRequests() { if (welcomeSocket == null || welcomeSocket.isClosed()) { break; } - - Socket connectionSocket = null; - BufferedReader inFromClient = null; - DataOutputStream outToClient = null; - - try { - connectionSocket = welcomeSocket.accept(); - } catch (IOException ex) { - ex.printStackTrace(); - // this socket may have been closed, so we'll stop - break; - } - - int c = 0; - String body = null; + try (Socket connectionSocket = welcomeSocket.accept()) { + - try { - inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); - - StringBuilder sb = new StringBuilder(); + int c = 0; - while ((c = inFromClient.read()) != -1) { - sb.append((char)c); + try (BufferedReader inFromClient = new BufferedReader( + new InputStreamReader(connectionSocket.getInputStream(), StandardCharsets.UTF_8)) ){ + - if (sb.toString().endsWith("\r\n\r\n")) - break; - } - sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(); - while ((c = inFromClient.read()) != -1) { - sb.append((char)c); - body = sb.toString(); + while ((c = inFromClient.read()) != -1) { + sb.append((char) c); - if (body.endsWith("")) - break; - } - } catch (IOException ex) { - ex.printStackTrace(); - } + if (sb.toString().endsWith("\r\n\r\n")) + break; + } + sb = new StringBuilder(); - PrintWriter out = null; + while ((c = inFromClient.read()) != -1) { + sb.append((char) c); + body = sb.toString(); - try { - outToClient = new DataOutputStream(connectionSocket.getOutputStream()); - out = new PrintWriter(outToClient); - out.println("HTTP/1.1 200 OK"); - out.println("Connection: Close"); - out.println("Content-Length: 0"); - out.println(); - out.flush(); - } catch (IOException ex) { - ex.printStackTrace(); - } finally { - try { - inFromClient.close(); - out.close(); - outToClient.close(); - connectionSocket.close(); + if (body.endsWith("")) + break; + } } catch (IOException ex) { ex.printStackTrace(); - } catch (NullPointerException ex) { - ex.printStackTrace(); } + + try (PrintWriter out = new PrintWriter( + new OutputStreamWriter(connectionSocket.getOutputStream(), StandardCharsets.UTF_8))) { + out.println("HTTP/1.1 200 OK"); + out.println("Connection: Close"); + out.println("Content-Length: 0"); + out.println(); + out.flush(); + } + } catch (IOException e) { + e.printStackTrace(); } if (body == null) @@ -157,11 +136,7 @@ private void processRequests() { InputStream stream = null; - try { - stream = new ByteArrayInputStream(body.getBytes("UTF-8")); - } catch (UnsupportedEncodingException ex) { - ex.printStackTrace(); - } + stream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)); JSONArray propertySet; DLNANotifyParser parser = new DLNANotifyParser(); @@ -177,13 +152,9 @@ private void processRequests() { handleLastChange(lastChange); } } - } catch (XmlPullParserException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (JSONException e) { + } catch (XmlPullParserException | IOException | JSONException e) { e.printStackTrace(); - } + } } } @@ -207,7 +178,7 @@ private void handleEntry(JSONObject entry) throws JSONException { String transportState = entry.getString("TransportState"); PlayStateStatus status = PlayStateStatus.convertTransportStateToPlayStateStatus(transportState); - for (URLServiceSubscription sub: subscriptions) { + for (URLServiceSubscription sub : subscriptions) { if (sub.getTarget().equalsIgnoreCase("playState")) { for (int j = 0; j < sub.getListeners().size(); j++) { @SuppressWarnings("unchecked") @@ -218,7 +189,8 @@ private void handleEntry(JSONObject entry) throws JSONException { } } - if ((entry.has("Volume")&&!entry.has("channel"))||(entry.has("Volume")&&entry.getString("channel").equals("Master"))) { + if ((entry.has("Volume") && !entry.has("channel")) + || (entry.has("Volume") && entry.getString("channel").equals("Master"))) { int intVolume = entry.getInt("Volume"); float volume = (float) intVolume / 100; @@ -233,13 +205,14 @@ private void handleEntry(JSONObject entry) throws JSONException { } } - if ((entry.has("Mute")&&!entry.has("channel"))||(entry.has("Mute")&&entry.getString("channel").equals("Master"))) { + if ((entry.has("Mute") && !entry.has("channel")) + || (entry.has("Mute") && entry.getString("channel").equals("Master"))) { String muteStatus = entry.getString("Mute"); boolean mute; try { mute = (Integer.parseInt(muteStatus) == 1); - } catch(NumberFormatException e) { + } catch (NumberFormatException e) { mute = Boolean.parseBoolean(muteStatus); } diff --git a/src/com/connectsdk/service/upnp/DLNAMediaInfoParser.java b/src/com/connectsdk/service/upnp/DLNAMediaInfoParser.java index b4e3cce2..1e2595d2 100644 --- a/src/com/connectsdk/service/upnp/DLNAMediaInfoParser.java +++ b/src/com/connectsdk/service/upnp/DLNAMediaInfoParser.java @@ -1,12 +1,11 @@ package com.connectsdk.service.upnp; -import android.util.Xml; - import com.connectsdk.core.ImageInfo; import com.connectsdk.core.MediaInfo; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; import java.io.IOException; import java.io.StringReader; @@ -36,9 +35,10 @@ private static String getData(String str, String data) { if (str.contains(LT)) return ""; - XmlPullParser parser = Xml.newPullParser(); try { + XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(new StringReader(str)); diff --git a/src/com/connectsdk/service/upnp/DLNANotifyParser.java b/src/com/connectsdk/service/upnp/DLNANotifyParser.java index 4e6471fc..ed56b7cd 100644 --- a/src/com/connectsdk/service/upnp/DLNANotifyParser.java +++ b/src/com/connectsdk/service/upnp/DLNANotifyParser.java @@ -4,21 +4,21 @@ import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; - -import android.util.Xml; +import org.xmlpull.v1.XmlPullParserFactory; public class DLNANotifyParser { private static final String ns = null; public JSONArray parse(InputStream in) throws XmlPullParserException, IOException, JSONException { try { - XmlPullParser parser = Xml.newPullParser(); + XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(in, null); parser.nextTag(); @@ -62,12 +62,8 @@ private JSONObject readProperty(XmlPullParser parser) throws IOException, XmlPul JSONObject event; InputStream stream = null; - try { - stream = new ByteArrayInputStream(eventStr.getBytes("UTF-8")); - } catch (UnsupportedEncodingException ex) { - ex.printStackTrace(); - } - + + stream = new ByteArrayInputStream(eventStr.getBytes(StandardCharsets.UTF_8)); DLNAEventParser eventParser = new DLNAEventParser(); event = eventParser.parse(stream); diff --git a/src/com/connectsdk/service/webos/WebOSTVKeyboardInput.java b/src/com/connectsdk/service/webos/WebOSTVKeyboardInput.java index 78beb3c9..d0935b24 100644 --- a/src/com/connectsdk/service/webos/WebOSTVKeyboardInput.java +++ b/src/com/connectsdk/service/webos/WebOSTVKeyboardInput.java @@ -45,8 +45,6 @@ public class WebOSTVKeyboardInput { static String ENTER = "ENTER"; static String DELETE = "DELETE"; - boolean canReplaceText = false; - public WebOSTVKeyboardInput(WebOSTVService service) { this.service = service; waiting = false; diff --git a/src/com/connectsdk/service/webos/WebOSTVMouseSocketConnection.java b/src/com/connectsdk/service/webos/WebOSTVMouseSocketConnection.java index f1d33b44..14b06962 100644 --- a/src/com/connectsdk/service/webos/WebOSTVMouseSocketConnection.java +++ b/src/com/connectsdk/service/webos/WebOSTVMouseSocketConnection.java @@ -27,7 +27,7 @@ import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; -import android.util.Log; +import com.connectsdk.core.Log; public class WebOSTVMouseSocketConnection { public interface WebOSTVMouseSocketListener { diff --git a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index 14e83f6e..003dcb8e 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -1,6 +1,7 @@ package com.connectsdk.service.webos; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; @@ -11,6 +12,7 @@ import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Arrays; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; @@ -18,27 +20,19 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; +import javax.xml.bind.DatatypeConverter; import org.java_websocket.WebSocket; -import org.java_websocket.client.DefaultSSLWebSocketClientFactory; +//2016-01-01: Moved from 1.3.0 to 1.3.1-snapshot +//import org.java_websocket.client.DefaultSSLWebSocketClientFactory; import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Build; -import android.util.Base64; -import android.util.Log; -import android.util.SparseArray; -import android.view.Display; -import android.view.WindowManager; - +import com.connectsdk.core.Context; +import com.connectsdk.core.Log; import com.connectsdk.core.Util; import com.connectsdk.discovery.DiscoveryManager; import com.connectsdk.service.DeviceService.PairingType; @@ -51,7 +45,6 @@ import com.connectsdk.service.command.URLServiceSubscription; import com.connectsdk.service.config.WebOSTVServiceConfig; -@SuppressLint("DefaultLocale") public class WebOSTVServiceSocketClient extends WebSocketClient implements ServiceCommandProcessor { static final String WEBOS_PAIRING_PROMPT = "PROMPT"; @@ -82,11 +75,10 @@ public enum State { // Queue of commands that should be sent once register is complete LinkedHashSet>> commandQueue = new LinkedHashSet>>(); - public SparseArray> requests = new SparseArray>(); - + private HashMap> requests = new HashMap>(); + boolean mConnectSucceeded = false; - Boolean mConnected; - + public WebOSTVServiceSocketClient(WebOSTVService service, URI uri) { super(uri); @@ -121,6 +113,7 @@ public State getState() { return state; } + @Override public void connect() { synchronized (this) { if (state != State.INITIAL) { @@ -145,8 +138,9 @@ public void disconnectWithError(ServiceCommandError error) { state = State.INITIAL; - if (mListener != null) + if (mListener != null) { mListener.onCloseWithError(error); + } } public void clearRequests() { @@ -161,10 +155,10 @@ private void setDefaultManifest() { try { manifest.put("manifestVersion", 1); -// manifest.put("appId", 1); -// manifest.put("vendorId", 1); -// manifest.put("localizedAppNames", 1); - manifest.put("permissions", convertStringListToJSONArray(permissions)); + // manifest.put("appId", 1); + // manifest.put("vendorId", 1); + // manifest.put("localizedAppNames", 1); + manifest.put("permissions", convertStringListToJSONArray(permissions)); } catch (JSONException e) { e.printStackTrace(); } @@ -173,7 +167,7 @@ private void setDefaultManifest() { private JSONArray convertStringListToJSONArray(List list) { JSONArray jsonArray = new JSONArray(); - for(String str: list) { + for (String str : list) { jsonArray.put(str); } @@ -218,8 +212,9 @@ protected void handleConnected() { protected void handleConnectError(Exception ex) { System.err.println("connect error: " + ex.toString()); - if (mListener != null) + if (mListener != null) { mListener.onFailWithError(new ServiceCommandError(0, "connection error", null)); + } } protected void handleMessage(String data) { @@ -236,11 +231,13 @@ protected void handleMessage(String data) { protected void handleMessage(JSONObject message) { Boolean shouldProcess = true; - if (mListener != null) + if (mListener != null) { shouldProcess = mListener.onReceiveMessage(message); + } - if (!shouldProcess) + if (!shouldProcess) { return; + } String type = message.optString("type"); Object payload = message.opt("payload"); @@ -252,31 +249,31 @@ protected void handleMessage(JSONObject message) { if (isInteger(strId)) { id = Integer.valueOf(strId); - try - { + try { request = (ServiceCommand>) requests.get(id); - } catch (ClassCastException ex) - { + } catch (ClassCastException ex) { // since request is assigned to null, don't need to do anything here } } - if (type.length() == 0) + if (type.length() == 0) { return; + } if ("response".equals(type)) { if (request != null) { -// Log.d(Util.T, "Found requests need to handle response"); + // Log.d(Util.T, "Found requests need to handle response"); if (payload != null) { Util.postSuccess(request.getResponseListener(), payload); - } - else { - Util.postError(request.getResponseListener(), new ServiceCommandError(-1, "JSON parse error", null)); + } else { + Util.postError(request.getResponseListener(), + new ServiceCommandError(-1, "JSON parse error", null)); } if (!(request instanceof URLServiceSubscription)) { - if (!(payload instanceof JSONObject && ((JSONObject) payload).has("pairingType"))) + if (!(payload instanceof JSONObject && ((JSONObject) payload).has("pairingType"))) { requests.remove(id); + } } } else { System.err.println("no matching request id: " + strId + ", payload: " + payload.toString()); @@ -292,23 +289,26 @@ protected void handleMessage(JSONObject message) { // Track SSL certificate // Not the prettiest way to get it, but we don't have direct access to the SSLEngine - ((WebOSTVServiceConfig) mService.getServiceConfig()).setServerCertificate(customTrustManager.getLastCheckedCertificate()); + ((WebOSTVServiceConfig) mService.getServiceConfig()) + .setServerCertificate(customTrustManager.getLastCheckedCertificate()); handleRegistered(); - if (id != null) + if (id != null) { requests.remove(id); + } } } else if ("error".equals(type)) { String error = message.optString("error"); - if (error.length() == 0) + if (error.length() == 0) { return; + } int errorCode = -1; String errorDesc = null; try { - String [] parts = error.split(" ", 2); + String[] parts = error.split(" ", 2); errorCode = Integer.parseInt(parts[0]); errorDesc = parts[1]; } catch (Exception e) { @@ -323,28 +323,29 @@ protected void handleMessage(JSONObject message) { Log.d(Util.T, "Error Desc: " + errorDesc); if (request != null) { - Util.postError(request.getResponseListener(), new ServiceCommandError(errorCode, errorDesc, payload)); + Util.postError(request.getResponseListener(), + new ServiceCommandError(errorCode, errorDesc, payload)); - if (!(request instanceof URLServiceSubscription)) + if (!(request instanceof URLServiceSubscription)) { requests.remove(id); + } } } } else if ("hello".equals(type)) { - JSONObject jsonObj = (JSONObject)payload; + JSONObject jsonObj = (JSONObject) payload; if (mService.getServiceConfig().getServiceUUID() != null) { if (!mService.getServiceConfig().getServiceUUID().equals(jsonObj.optString("deviceUUID"))) { - ((WebOSTVServiceConfig)mService.getServiceConfig()).setClientKey(null); - ((WebOSTVServiceConfig)mService.getServiceConfig()).setServerCertificate((String)null); + ((WebOSTVServiceConfig) mService.getServiceConfig()).setClientKey(null); + ((WebOSTVServiceConfig) mService.getServiceConfig()).setServerCertificate((X509Certificate) null); mService.getServiceConfig().setServiceUUID(null); mService.getServiceDescription().setIpAddress(null); mService.getServiceDescription().setUUID(null); disconnect(); } - } - else { + } else { String uuid = jsonObj.optString("deviceUUID"); mService.getServiceConfig().setServiceUUID(uuid); mService.getServiceDescription().setUUID(uuid); @@ -357,8 +358,7 @@ protected void handleMessage(JSONObject message) { private void helloTV() { Context context = DiscoveryManager.getInstance().getContext(); - PackageManager packageManager = context.getPackageManager(); - + // app Id String packageName = context.getPackageName(); @@ -366,41 +366,37 @@ private void helloTV() { String sdkVersion = DiscoveryManager.CONNECT_SDK_VERSION; // Device Model - String deviceModel = Build.MODEL; + //String deviceModel = null; //Build.MODEL; // OS Version - String OSVersion = String.valueOf(android.os.Build.VERSION.SDK_INT); + //String OSVersion = null; //String.valueOf(android.os.Build.VERSION.SDK_INT); // resolution - WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - Display display = wm.getDefaultDisplay(); + // WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + // Display display = wm.getDefaultDisplay(); - @SuppressWarnings("deprecation") - int width = display.getWidth(); // deprecated, but still needed for supporting API levels 10-12 + // @SuppressWarnings("deprecation") + // int width = display.getWidth(); // deprecated, but still needed for supporting API levels 10-12 - @SuppressWarnings("deprecation") - int height = display.getHeight(); // deprecated, but still needed for supporting API levels 10-12 + // @SuppressWarnings("deprecation") + // int height = display.getHeight(); // deprecated, but still needed for supporting API levels 10-12 - String screenResolution = String.format("%dx%d", width, height); + String screenResolution = String.format("%dx%d", 0, 0); // app Name - ApplicationInfo applicationInfo; - try { - applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0); - } catch (final NameNotFoundException e) { - applicationInfo = null; - } - String applicationName = (String) (applicationInfo != null ? packageManager.getApplicationLabel(applicationInfo) : "(unknown)"); + + String applicationName = context.getApplicationName(); // app Region - Locale current = context.getResources().getConfiguration().locale; + // Locale current = context.getResources().getConfiguration().locale; + Locale current = Locale.getDefault(); String appRegion = current.getDisplayCountry(); JSONObject payload = new JSONObject(); try { payload.put("sdkVersion", sdkVersion); - payload.put("deviceModel", deviceModel); - payload.put("OSVersion", OSVersion); + //ayload.put("deviceModel", deviceModel); + //payload.put("OSVersion", OSVersion); payload.put("resolution", screenResolution); payload.put("appId", packageName); payload.put("appName", applicationName); @@ -420,7 +416,8 @@ private void helloTV() { e.printStackTrace(); } - ServiceCommand> request = new ServiceCommand>(this, null, sendData, true, null); + ServiceCommand> request = new ServiceCommand>(this, null, + sendData, true, null); this.sendCommandImmediately(request); } @@ -430,27 +427,30 @@ protected void sendRegister() { @Override public void onError(ServiceCommandError error) { state = State.INITIAL; - - if (mListener != null) + + if (mListener != null) { mListener.onRegistrationFailed(error); + } } @Override public void onSuccess(Object object) { if (object instanceof JSONObject) { - JSONObject jsonObj = (JSONObject)object; + JSONObject jsonObj = (JSONObject) object; String type = jsonObj.optString("pairingType"); PairingType pairingType = getPairingTypeFromString(type); - if (mListener != null) + if (mListener != null) { mListener.onBeforeRegister(pairingType); + } } } }; int dataId = this.nextRequestId++; - ServiceCommand> command = new ServiceCommand>(this, null, null, listener); + ServiceCommand> command = new ServiceCommand>(this, null, + null, listener); command.setRequestId(dataId); JSONObject headers = new JSONObject(); @@ -464,8 +464,8 @@ public void onSuccess(Object object) { mService.setServiceConfig(new WebOSTVServiceConfig(mService.getServiceConfig().getServiceUUID())); } - if (((WebOSTVServiceConfig)mService.getServiceConfig()).getClientKey() != null) { - payload.put("client-key", ((WebOSTVServiceConfig)mService.getServiceConfig()).getClientKey()); + if (((WebOSTVServiceConfig) mService.getServiceConfig()).getClientKey() != null) { + payload.put("client-key", ((WebOSTVServiceConfig) mService.getServiceConfig()).getClientKey()); } String pairingTypeString = getPairingTypeString(); @@ -517,37 +517,40 @@ public void sendPairingKey(String pairingKey) { @Override public void onError(ServiceCommandError error) { state = State.INITIAL; - - if (mListener != null) + + if (mListener != null) { mListener.onFailWithError(error); + } } @Override - public void onSuccess(Object object) { } + public void onSuccess(Object object) { + } }; - + String uri = "ssap://pairing/setPin"; int dataId = this.nextRequestId++; - - ServiceCommand> command = new ServiceCommand>(this, null, null, listener); + + ServiceCommand> command = new ServiceCommand>(this, null, + null, listener); command.setRequestId(dataId); - + JSONObject headers = new JSONObject(); JSONObject payload = new JSONObject(); - + try { headers.put("type", "request"); headers.put("id", dataId); headers.put("uri", uri); - + payload.put("pin", pairingKey); } catch (JSONException e) { e.printStackTrace(); } requests.put(dataId, command); - + sendMessage(headers, payload); } @@ -555,7 +558,8 @@ protected void handleRegistered() { state = State.REGISTERED; if (!commandQueue.isEmpty()) { - LinkedHashSet>> tempHashSet = new LinkedHashSet>>(commandQueue); + LinkedHashSet>> tempHashSet = new LinkedHashSet>>( + commandQueue); for (ServiceCommand> command : tempHashSet) { Log.d(Util.T, "executing queued command for " + command.getTarget()); @@ -564,29 +568,31 @@ protected void handleRegistered() { } } - if (mListener != null) + if (mListener != null) { mListener.onConnect(); + } -// ConnectableDevice storedDevice = connectableDeviceStore.getDevice(mService.getServiceConfig().getServiceUUID()); -// if (storedDevice == null) { -// storedDevice = new ConnectableDevice( -// mService.getServiceDescription().getIpAddress(), -// mService.getServiceDescription().getFriendlyName(), -// mService.getServiceDescription().getModelName(), -// mService.getServiceDescription().getModelNumber()); -// } -// storedDevice.addService(WebOSTVService.this); -// connectableDeviceStore.addDevice(storedDevice); + // ConnectableDevice storedDevice = + // connectableDeviceStore.getDevice(mService.getServiceConfig().getServiceUUID()); + // if (storedDevice == null) { + // storedDevice = new ConnectableDevice( + // mService.getServiceDescription().getIpAddress(), + // mService.getServiceDescription().getFriendlyName(), + // mService.getServiceDescription().getModelName(), + // mService.getServiceDescription().getModelNumber()); + // } + // storedDevice.addService(WebOSTVService.this); + // connectableDeviceStore.addDevice(storedDevice); } + @Override @SuppressWarnings("unchecked") public void sendCommand(ServiceCommand command) { Integer requestId; if (command.getRequestId() == -1) { requestId = this.nextRequestId++; command.setRequestId(requestId); - } - else { + } else { requestId = command.getRequestId(); } @@ -594,7 +600,7 @@ public void sendCommand(ServiceCommand command) { if (state == State.REGISTERED) { this.sendCommandImmediately(command); - } else if (state == State.CONNECTING || state == State.DISCONNECTING){ + } else if (state == State.CONNECTING || state == State.DISCONNECTING) { Log.d(Util.T, "queuing command for " + command.getTarget()); commandQueue.add((ServiceCommand>) command); } else { @@ -604,17 +610,17 @@ public void sendCommand(ServiceCommand command) { } } + @Override public void unsubscribe(URLServiceSubscription subscription) { int requestId = subscription.getRequestId(); if (requests.get(requestId) != null) { JSONObject headers = new JSONObject(); - try{ + try { headers.put("type", "unsubscribe"); headers.put("id", String.valueOf(requestId)); - } catch (JSONException e) - { + } catch (JSONException e) { // Safe to ignore e.printStackTrace(); } @@ -624,74 +630,73 @@ public void unsubscribe(URLServiceSubscription subscription) { } } - public void unsubscribe(ServiceSubscription subscription) { } + @Override + public void unsubscribe(ServiceSubscription subscription) { + } protected void sendCommandImmediately(ServiceCommand command) { JSONObject headers = new JSONObject(); JSONObject payload = (JSONObject) command.getPayload(); String payloadType = ""; - try - { + try { payloadType = payload.getString("type"); - } catch (Exception ex) - { + } catch (Exception ex) { // ignore } - if (payloadType.equals("p2p")) - { + if (payloadType.equals("p2p")) { Iterator iterator = payload.keys(); - while (iterator.hasNext()) - { + while (iterator.hasNext()) { String key = (String) iterator.next(); - try - { + try { headers.put(key, payload.get(key)); - } catch (JSONException ex) - { + } catch (JSONException ex) { // ignore } } this.sendMessage(headers, null); - } - else if (payloadType.equals("hello")) { + } else if (payloadType.equals("hello")) { this.send(payload.toString()); - } - else { - try - { + } else { + try { headers.put("type", command.getHttpMethod()); headers.put("id", String.valueOf(command.getRequestId())); headers.put("uri", command.getTarget()); - } catch (JSONException ex) - { + } catch (JSONException ex) { // TODO: handle this } - this.sendMessage(headers, payload); } } + // 2016-01-01: Moved from 1.3.0 to 1.3.1-snapshot private void setSSLContext(SSLContext sslContext) { - setWebSocketFactory(new DefaultSSLWebSocketClientFactory(sslContext)); + // setWebSocketFactory(new DefaultSSLWebSocketClientFactory(sslContext)); + try { + super.setSocket(sslContext.getSocketFactory().createSocket()); + } catch (IOException e) { + Log.e("SSL Setup", "failed to setup ssl socket", e); + } + } protected void setupSSL() { try { SSLContext sslContext = SSLContext.getInstance("TLS"); customTrustManager = new TrustManager(); - sslContext.init(null, new TrustManager [] {customTrustManager}, null); + sslContext.init(null, new TrustManager[] { customTrustManager }, null); setSSLContext(sslContext); if (!(mService.getServiceConfig() instanceof WebOSTVServiceConfig)) { mService.setServiceConfig(new WebOSTVServiceConfig(mService.getServiceConfig().getServiceUUID())); } - customTrustManager.setExpectedCertificate(((WebOSTVServiceConfig)mService.getServiceConfig()).getServerCertificate()); + customTrustManager.setExpectedCertificate( + ((WebOSTVServiceConfig) mService.getServiceConfig()).getServerCertificate()); } catch (KeyException e) { } catch (NoSuchAlgorithmException e) { } @@ -702,12 +707,12 @@ public boolean isConnected() { } public void sendMessage(JSONObject packet, JSONObject payload) { -// JSONObject packet = new JSONObject(); + // JSONObject packet = new JSONObject(); try { -// for (Map.Entry entry : headers.entrySet()) { -// packet.put(entry.getKey(), entry.getValue()); -// } + // for (Map.Entry entry : headers.entrySet()) { + // packet.put(entry.getKey(), entry.getValue()); + // } if (payload != null) { packet.put("payload", payload); @@ -722,8 +727,7 @@ public void sendMessage(JSONObject packet, JSONObject payload) { Log.d(Util.T, "webOS Socket [OUT] : " + message); this.send(message); - } - else { + } else { System.err.println("connection lost"); handleConnectionLost(false, null); } @@ -733,17 +737,18 @@ public void sendMessage(JSONObject packet, JSONObject payload) { private void handleConnectionLost(boolean cleanDisconnect, Exception ex) { ServiceCommandError error = null; - if (ex != null || !cleanDisconnect) + if (ex != null || !cleanDisconnect) { error = new ServiceCommandError(0, "conneciton error", ex); + } - if (mListener != null) + if (mListener != null) { mListener.onCloseWithError(error); + } - for (int i = 0; i < requests.size(); i++) { - ServiceCommand> request = (ServiceCommand>) requests.get(requests.keyAt(i)); - - if (request != null) + for(ServiceCommand request : requests.values()){ + if (request != null) { Util.postError(request.getResponseListener(), new ServiceCommandError(0, "connection lost", null)); + } } clearRequests(); @@ -754,7 +759,7 @@ public void setServerCertificate(X509Certificate cert) { mService.setServiceConfig(new WebOSTVServiceConfig(mService.getServiceConfig().getServiceUUID())); } - ((WebOSTVServiceConfig)mService.getServiceConfig()).setServerCertificate(cert); + ((WebOSTVServiceConfig) mService.getServiceConfig()).setServerCertificate(cert); } public void setServerCertificate(String cert) { @@ -762,7 +767,7 @@ public void setServerCertificate(String cert) { mService.setServiceConfig(new WebOSTVServiceConfig(mService.getServiceConfig().getServiceUUID())); } - ((WebOSTVServiceConfig)mService.getServiceConfig()).setServerCertificate(loadCertificateFromPEM(cert)); + ((WebOSTVServiceConfig) mService.getServiceConfig()).setServerCertificate(loadCertificateFromPEM(cert)); } public X509Certificate getServerCertificate() { @@ -770,7 +775,7 @@ public X509Certificate getServerCertificate() { mService.setServiceConfig(new WebOSTVServiceConfig(mService.getServiceConfig().getServiceUUID())); } - return ((WebOSTVServiceConfig)mService.getServiceConfig()).getServerCertificate(); + return ((WebOSTVServiceConfig) mService.getServiceConfig()).getServerCertificate(); } public String getServerCertificateInString() { @@ -778,12 +783,13 @@ public String getServerCertificateInString() { mService.setServiceConfig(new WebOSTVServiceConfig(mService.getServiceConfig().getServiceUUID())); } - return exportCertificateToPEM(((WebOSTVServiceConfig)mService.getServiceConfig()).getServerCertificate()); + return exportCertificateToPEM(((WebOSTVServiceConfig) mService.getServiceConfig()).getServerCertificate()); } private String exportCertificateToPEM(X509Certificate cert) { try { - return Base64.encodeToString(cert.getEncoded(), Base64.DEFAULT); + //return java.util.Base64.getEncoder().encodeToString(cert.getEncoded()); // only available in java 1.8 + return DatatypeConverter.printBase64Binary(cert.getEncoded()); } catch (CertificateEncodingException e) { e.printStackTrace(); return null; @@ -796,7 +802,7 @@ private X509Certificate loadCertificateFromPEM(String pemString) { certFactory = CertificateFactory.getInstance("X.509"); ByteArrayInputStream inputStream = new ByteArrayInputStream(pemString.getBytes("US-ASCII")); - return (X509Certificate)certFactory.generateCertificate(inputStream); + return (X509Certificate) certFactory.generateCertificate(inputStream); } catch (CertificateException e) { e.printStackTrace(); return null; @@ -807,16 +813,16 @@ private X509Certificate loadCertificateFromPEM(String pemString) { } public static boolean isInteger(String s) { - try { - Integer.parseInt(s); - } catch(NumberFormatException e) { - return false; + try { + Integer.parseInt(s); + } catch (NumberFormatException e) { + return false; } // only got here if we didn't return false return true; } - class TrustManager implements X509TrustManager { + private static class TrustManager implements X509TrustManager { X509Certificate expectedCert; X509Certificate lastCheckedCert; @@ -824,13 +830,12 @@ public void setExpectedCertificate(X509Certificate cert) { this.expectedCert = cert; } - public X509Certificate getLastCheckedCertificate () { + public X509Certificate getLastCheckedCertificate() { return lastCheckedCert; } @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) - throws CertificateException { + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override @@ -843,8 +848,8 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) throws lastCheckedCert = cert; if (expectedCert != null) { - byte [] certBytes = cert.getEncoded(); - byte [] expectedCertBytes = expectedCert.getEncoded(); + byte[] certBytes = cert.getEncoded(); + byte[] expectedCertBytes = expectedCert.getEncoded(); Log.d(Util.T, "Device presented cert " + cert.getSubjectDN()); @@ -867,11 +872,15 @@ public X509Certificate[] getAcceptedIssuers() { public interface WebOSTVServiceSocketClientListener { public void onConnect(); + public void onCloseWithError(ServiceCommandError error); + public void onFailWithError(ServiceCommandError error); public void onBeforeRegister(PairingType pairingType); + public void onRegistrationFailed(ServiceCommandError error); + public Boolean onReceiveMessage(JSONObject message); } diff --git a/test/.project b/test/.project deleted file mode 100644 index 46046dd0..00000000 --- a/test/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - Connect-SDK-Android-Core-Test - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/test/README.md b/test/README.md deleted file mode 100644 index 027c2168..00000000 --- a/test/README.md +++ /dev/null @@ -1,36 +0,0 @@ -#Connect SDK Core Test project (Android) -The Test project contains unit tests for The Connect SDK Core. - -##General Information -For more information about Connect SDK, visit the [main repository](https://github.com/ConnectSDK/Connect-SDK-Android). - -##Setup and run from Eclipse -1. Go to Eclipse Menu -> File -> Import -> (General) Existing projects into workspace -2. Open project properties and make sure that java compiler has version 1.6 -3. Open project properties -> Java Build Path -> Projects and add a reference to Connect-SDK-Android-Core project -4. Open project properties -> Java Build Path -> Libraries and add all jars from libs folder and add android.jar from sdk/platforms/android-19 -5. Open project properties -> Java Build Path -> Order and Export and put android.jar at the bottom of the list. -6. Run as Eclipse JUnit Test - -##Run from command line -1. Add a system variable ANDROID_HOME which contains a path to Android SDK -2. Go to Connect-SDK-Core project folder and build it: ant clean debug -3. Go to test folder and execute: ant - - -##License -Copyright (c) 2013-2014 LG Electronics. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -> http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - - diff --git a/test/src/com/connectsdk/core/MediaInfoTest.java b/test/src/com/connectsdk/core/MediaInfoTest.java deleted file mode 100644 index 39f45dcc..00000000 --- a/test/src/com/connectsdk/core/MediaInfoTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * MediaInfoTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 20 Jul 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.connectsdk.core; - -import junit.framework.Assert; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class MediaInfoTest { - - @Test - public void testMediaInfoBuilderWithRequiredParameters() { - String url = "http://127.0.0.1/"; - String mimeType = "video/mp4"; - MediaInfo mediaInfo = new MediaInfo.Builder(url, mimeType).build(); - - Assert.assertEquals(url, mediaInfo.getUrl()); - Assert.assertEquals(mimeType, mediaInfo.getMimeType()); - Assert.assertNull(mediaInfo.getDescription()); - Assert.assertEquals(0, mediaInfo.getDuration()); - Assert.assertNull(mediaInfo.getImages()); - Assert.assertNull(mediaInfo.getSubtitleInfo()); - Assert.assertNull(mediaInfo.getTitle()); - } - - @Test - public void testMediaInfoBuilderWithAllParameters() { - String url = "http://127.0.0.1/"; - String mimeType = "video/mp4"; - String description = "description"; - String iconUrl = "http://iconurl"; - - SubtitleInfo subtitle = new SubtitleInfo.Builder("").build(); - String title = "title"; - MediaInfo mediaInfo = new MediaInfo - .Builder(url, mimeType) - .setDescription(description) - .setIcon(iconUrl) - .setSubtitleInfo(subtitle) - .setTitle(title) - .build(); - - Assert.assertEquals(url, mediaInfo.getUrl()); - Assert.assertEquals(mimeType, mediaInfo.getMimeType()); - Assert.assertEquals(description, mediaInfo.getDescription()); - Assert.assertEquals(iconUrl, mediaInfo.getImages().get(0).getUrl()); - Assert.assertEquals(1, mediaInfo.getImages().size()); - Assert.assertEquals(subtitle, mediaInfo.getSubtitleInfo()); - Assert.assertEquals(title, mediaInfo.getTitle()); - } - - @Test - public void testMediaInfoBuilderWithNullIconShouldNotReturnNullImagesList() { - String url = "http://127.0.0.1/"; - String mimeType = "video/mp4"; - MediaInfo mediaInfo = new MediaInfo.Builder(url, mimeType) - .setIcon((String) null) - .build(); - - Assert.assertEquals(url, mediaInfo.getUrl()); - Assert.assertEquals(mimeType, mediaInfo.getMimeType()); - Assert.assertNull(mediaInfo.getDescription()); - Assert.assertEquals(0, mediaInfo.getDuration()); - Assert.assertNull(mediaInfo.getImages()); - Assert.assertNull(mediaInfo.getSubtitleInfo()); - Assert.assertNull(mediaInfo.getTitle()); - } -} diff --git a/test/src/com/connectsdk/core/SubtitleInfoTest.java b/test/src/com/connectsdk/core/SubtitleInfoTest.java deleted file mode 100644 index 942d1b91..00000000 --- a/test/src/com/connectsdk/core/SubtitleInfoTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SubtitleTrackTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 20 Jul 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.connectsdk.core; - -import junit.framework.Assert; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class SubtitleInfoTest { - - @Test - public void testCreateSubtitleWithRequiredParameters() { - String url = "http://127.0.0.1/"; - SubtitleInfo subtitle = new SubtitleInfo.Builder(url).build(); - - Assert.assertEquals(url, subtitle.getUrl()); - Assert.assertNull(subtitle.getMimeType()); - Assert.assertNull(subtitle.getLabel()); - Assert.assertNull(subtitle.getLanguage()); - } - - @Test - public void testCreateSubtitleWithAllParameters() { - String url = "http://127.0.0.1/"; - String mimetype = "text/vtt"; - String label = "label"; - String language = "en"; - SubtitleInfo subtitle = new SubtitleInfo - .Builder(url) - .setMimeType(mimetype) - .setLabel(label) - .setLanguage(language) - .build(); - - Assert.assertEquals(url, subtitle.getUrl()); - Assert.assertEquals(mimetype, subtitle.getMimeType()); - Assert.assertEquals(label, subtitle.getLabel()); - Assert.assertEquals(language, subtitle.getLanguage()); - } -} diff --git a/test/src/com/connectsdk/core/TestUtil.java b/test/src/com/connectsdk/core/TestUtil.java deleted file mode 100644 index f8e0c310..00000000 --- a/test/src/com/connectsdk/core/TestUtil.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.connectsdk.core; - -import org.apache.tools.ant.filters.StringInputStream; -import org.mockito.Mockito; - -import java.io.IOException; -import java.net.URI; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.TimeUnit; - -/** - * Created by oleksii.frolov on 1/30/2015. - */ -public final class TestUtil { - - public static URL getMockUrl(final String content, String applicationUrl) throws IOException { - final URLConnection mockConnection = Mockito.mock(URLConnection.class); - Mockito.when(mockConnection.getInputStream()).thenReturn(new StringInputStream(content)); - Mockito.when(mockConnection.getHeaderField("Application-URL")).thenReturn(applicationUrl); - - final URLStreamHandler handler = new URLStreamHandler() { - - @Override - protected URLConnection openConnection(final URL arg0) - throws IOException { - return mockConnection; - } - }; - return new URL("http", "hostname", 80, "", handler); - } - - public static void runUtilBackgroundTasks() { - ExecutorService executor = (ExecutorService) Util.getExecutor(); - executor.shutdown(); - try { - executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); - } catch (InterruptedException e) { - e.printStackTrace(); - } - Util.createExecutor(); - } - - /** - * Compare 2 URLs with custom parameters order - * @param expectedUrl - * @param targetUrl - * @return true if URLs equal - */ - public static boolean compareUrls(String expectedUrl, String targetUrl) { - URI expectedURI = URI.create(expectedUrl).normalize(); - URI targetURI = URI.create(targetUrl).normalize(); - - String[] expectedQuery = expectedURI.getQuery().split("&"); - List targetQuery = new LinkedList( - Arrays.asList(targetURI.getQuery().split("&"))); - - for (String item : expectedQuery) { - if (!targetQuery.remove(item)) { - return false; - } - } - - if (!targetQuery.isEmpty()) { - return false; - } - - String schemeExpected = expectedURI.getScheme(); - String scheme = targetURI.getScheme(); - - String hostExpected = expectedURI.getHost(); - String host = targetURI.getHost(); - - String pathExpected = expectedURI.getPath(); - String path = targetURI.getPath(); - - int portExpected = expectedURI.getPort(); - int port = targetURI.getPort(); - - return schemeExpected.equals(scheme) && hostExpected.equals(host) - && pathExpected.equals(path) && portExpected == port; - } -} diff --git a/test/src/com/connectsdk/device/ConnectableDeviceTest.java b/test/src/com/connectsdk/device/ConnectableDeviceTest.java deleted file mode 100644 index b46bc373..00000000 --- a/test/src/com/connectsdk/device/ConnectableDeviceTest.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.connectsdk.device; - -import com.connectsdk.discovery.DiscoveryManager; -import com.connectsdk.service.AirPlayService; -import com.connectsdk.service.DIALService; -import com.connectsdk.service.DLNAService; -import com.connectsdk.service.DeviceService; -import com.connectsdk.service.NetcastTVService; -import com.connectsdk.service.RokuService; -import com.connectsdk.service.WebOSTVService; -import com.connectsdk.service.capability.Launcher; -import com.connectsdk.service.capability.MediaPlayer; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class ConnectableDeviceTest { - - private ConnectableDevice device; - - @Before - public void setUp() { - DiscoveryManager.init(Robolectric.application); - device = new ConnectableDevice(); - } - - @Test - public void testHasCapabilityWithEmptyServices() { - Assert.assertFalse(device.hasCapability(MediaPlayer.Display_Image)); - } - - @Test - public void testHasCapabilityWithServices() { - DeviceService service = Mockito.mock(DeviceService.class); - Mockito.when(service.hasCapability(MediaPlayer.Display_Image)).thenReturn(Boolean.TRUE); - device.services.put("service", service); - Assert.assertTrue(device.hasCapability(MediaPlayer.Display_Image)); - } - - @Test - public void testHasAnyCapabilities() { - DeviceService service = Mockito.mock(DeviceService.class); - String[] capabilities = {Launcher.Browser, Launcher.YouTube}; - Mockito.when(service.hasAnyCapability(capabilities)).thenReturn(Boolean.TRUE); - device.services.put("service", service); - Assert.assertTrue(device.hasAnyCapability(capabilities)); - } - - @Test - public void testHasAnyCapabilitiesWithoutServices() { - DeviceService service = Mockito.mock(DeviceService.class); - String[] capabilities = {Launcher.Browser, Launcher.YouTube}; - Mockito.when(service.hasAnyCapability(capabilities)).thenReturn(Boolean.FALSE); - device.services.put("service", service); - Assert.assertFalse(device.hasAnyCapability(capabilities)); - } - - @Test - public void testHasCapabilities() { - DeviceService service = Mockito.mock(DeviceService.class); - Mockito.when(service.hasCapability(Launcher.Browser)).thenReturn(Boolean.TRUE); - Mockito.when(service.hasCapability(Launcher.YouTube)).thenReturn(Boolean.TRUE); - device.services.put("service", service); - - List capabilities = new ArrayList(); - capabilities.add(Launcher.Browser); - capabilities.add(Launcher.YouTube); - - Assert.assertTrue(device.hasCapabilities(capabilities)); - } - - @Test - public void testSetPromptPairingType() throws IOException { - // given - addAllCoreServicesToDevice(); - - // when - device.setPairingType(DeviceService.PairingType.FIRST_SCREEN); - - // then - Assert.assertEquals(DeviceService.PairingType.FIRST_SCREEN, device.getServiceByName(WebOSTVService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.PIN_CODE, device.getServiceByName(NetcastTVService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(DLNAService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(DIALService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(RokuService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.PIN_CODE, device.getServiceByName(AirPlayService.ID).getPairingType()); - } - - @Test - public void testSetPinPairingType() throws IOException { - // given - addAllCoreServicesToDevice(); - - // when - device.setPairingType(DeviceService.PairingType.PIN_CODE); - - // then - Assert.assertEquals(DeviceService.PairingType.PIN_CODE, device.getServiceByName(WebOSTVService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.PIN_CODE, device.getServiceByName(NetcastTVService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(DLNAService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(DIALService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(RokuService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.PIN_CODE, device.getServiceByName(AirPlayService.ID).getPairingType()); - } - - @Test - public void testNonePairingType() throws IOException { - // given - addAllCoreServicesToDevice(); - - // when - device.setPairingType(DeviceService.PairingType.NONE); - - // then - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(WebOSTVService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.PIN_CODE, device.getServiceByName(NetcastTVService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(DLNAService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(DIALService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.NONE, device.getServiceByName(RokuService.ID).getPairingType()); - Assert.assertEquals(DeviceService.PairingType.PIN_CODE, device.getServiceByName(AirPlayService.ID).getPairingType()); - } - - private void addAllCoreServicesToDevice() throws IOException { - DeviceService webOSService = new WebOSTVService(createServiceDescription(WebOSTVService.ID), Mockito.mock(ServiceConfig.class)); - DeviceService netCastService = new NetcastTVService(createServiceDescription(NetcastTVService.ID), Mockito.mock(ServiceConfig.class)); - DeviceService dialService = new DIALService(createServiceDescription(DIALService.ID), Mockito.mock(ServiceConfig.class)); - DeviceService dlnaSrevice = new DLNAService(createServiceDescription(DLNAService.ID), Mockito.mock(ServiceConfig.class)); - DeviceService rokuService = new RokuService(createServiceDescription(RokuService.ID), Mockito.mock(ServiceConfig.class)); - DeviceService airPlayService = new AirPlayService(createServiceDescription(AirPlayService.ID), Mockito.mock(ServiceConfig.class)); - device.services.put(WebOSTVService.ID, webOSService); - device.services.put(NetcastTVService.ID, netCastService); - device.services.put(DIALService.ID, dialService); - device.services.put(DLNAService.ID, dlnaSrevice); - device.services.put(RokuService.ID, rokuService); - device.services.put(AirPlayService.ID, airPlayService); - } - - private ServiceDescription createServiceDescription(String serviceId) { - ServiceDescription description = new ServiceDescription(); - description.setFriendlyName(""); - description.setManufacturer(""); - description.setUUID(""); - description.setModelDescription(""); - description.setModelName(""); - description.setModelNumber(""); - description.setServiceID(serviceId); - return description; - } - -} diff --git a/test/src/com/connectsdk/discovery/DiscoveryFilterParameterizedTest.java b/test/src/com/connectsdk/discovery/DiscoveryFilterParameterizedTest.java deleted file mode 100644 index 9aab9c57..00000000 --- a/test/src/com/connectsdk/discovery/DiscoveryFilterParameterizedTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.connectsdk.discovery; - -import junit.framework.Assert; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.util.Arrays; -import java.util.Collection; - -/** - * Created by oleksii.frolov on 2/12/2015. - */ -@RunWith(Parameterized.class) -public class DiscoveryFilterParameterizedTest { - - private final String mIdA; - private final String mFilterA; - private final String mIdB; - private final String mFilterB; - private final Boolean mResult; - - @Parameterized.Parameters - public static Collection configs() { - return Arrays.asList(new Object[][] { - {"id", "filter", "id", "filter", Boolean.TRUE}, - {"id", "filter", "id", "another", Boolean.FALSE}, - {"id", "filter", "another", "filter", Boolean.FALSE}, - {null, "filter", null, "filter", Boolean.TRUE}, - {"id", null, "id", null, Boolean.TRUE}, - {null, null, null, null, Boolean.TRUE}, - {"id", "filter", null, "filter", Boolean.FALSE}, - }); - } - - public DiscoveryFilterParameterizedTest(String idA, String filterA, String idB, String filterB, Boolean result) { - this.mIdA = idA; - this.mFilterA = filterA; - this.mIdB = idB; - this.mFilterB = filterB; - this.mResult = result; - } - - @Test - public void testEquals() { - DiscoveryFilter filterA = new DiscoveryFilter(mIdA, mFilterA); - DiscoveryFilter filterB = new DiscoveryFilter(mIdB, mFilterB); - Assert.assertEquals(mResult.booleanValue(), filterA.equals(filterB)); - Assert.assertEquals(mResult.booleanValue(), filterB.equals(filterA)); - } - - @Test - public void testHashCode() { - DiscoveryFilter filterA = new DiscoveryFilter(mIdA, mFilterA); - DiscoveryFilter filterB = new DiscoveryFilter(mIdB, mFilterB); - Assert.assertEquals(mResult.booleanValue(), filterA.hashCode() == filterB.hashCode()); - } -} diff --git a/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java b/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java deleted file mode 100644 index 9d01633e..00000000 --- a/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.connectsdk.discovery; - -import com.connectsdk.discovery.provider.SSDPDiscoveryProvider; -import com.connectsdk.discovery.provider.ZeroconfDiscoveryProvider; -import com.connectsdk.service.DIALService; -import com.connectsdk.service.DLNAService; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.util.Objects; - -/** - * Created by oleksii.frolov on 2/16/2015. - */ - -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) -public class DiscoveryManagerTest { - - DiscoveryManager discovery; - - @Before - public void setUp() { - discovery = new DiscoveryManager(Robolectric.application); - } - - @Test - public void testUnregisterDeviceServiceWithWrongArguments() { - discovery.deviceClasses.put("service", DIALService.class); - Assert.assertEquals(1, discovery.deviceClasses.size()); - - discovery.unregisterDeviceService(Objects.class, Object.class); - Assert.assertEquals(1, discovery.deviceClasses.size()); - - discovery.unregisterDeviceService(DLNAService.class, SSDPDiscoveryProvider.class); - Assert.assertEquals(1, discovery.deviceClasses.size()); - - discovery.unregisterDeviceService(DIALService.class, SSDPDiscoveryProvider.class); - Assert.assertEquals(1, discovery.deviceClasses.size()); - } - - @Test - public void testUnregisterDeviceServiceWithWrongProvider() { - discovery.discoveryProviders.add(new SSDPDiscoveryProvider(Robolectric.application)); - discovery.deviceClasses.put(DIALService.ID, DIALService.class); - Assert.assertEquals(1, discovery.discoveryProviders.size()); - Assert.assertEquals(1, discovery.deviceClasses.size()); - - discovery.unregisterDeviceService(DIALService.class, ZeroconfDiscoveryProvider.class); - Assert.assertEquals(1, discovery.deviceClasses.size()); - Assert.assertEquals(1, discovery.discoveryProviders.size()); - } - - @Test - public void testUnregisterDeviceServiceWithWrongServiceID() { - discovery.discoveryProviders.add(new SSDPDiscoveryProvider(Robolectric.application)); - discovery.deviceClasses.put(DLNAService.ID, DIALService.class); - Assert.assertEquals(1, discovery.discoveryProviders.size()); - Assert.assertEquals(1, discovery.deviceClasses.size()); - - discovery.unregisterDeviceService(DIALService.class, SSDPDiscoveryProvider.class); - Assert.assertEquals(1, discovery.deviceClasses.size()); - Assert.assertEquals(1, discovery.discoveryProviders.size()); - } - - @Test - public void testUnregisterDeviceService() { - discovery.discoveryProviders.add(new SSDPDiscoveryProvider(Robolectric.application)); - discovery.deviceClasses.put(DIALService.ID, DIALService.class); - Assert.assertEquals(1, discovery.discoveryProviders.size()); - Assert.assertEquals(1, discovery.deviceClasses.size()); - - discovery.unregisterDeviceService(DIALService.class, SSDPDiscoveryProvider.class); - Assert.assertEquals(0, discovery.deviceClasses.size()); - Assert.assertEquals(0, discovery.discoveryProviders.size()); - } - - @Test - public void testRegisterDeviceService() { - Assert.assertEquals(0, discovery.discoveryProviders.size()); - Assert.assertEquals(0, discovery.deviceClasses.size()); - - discovery.registerDeviceService(DIALService.class, SSDPDiscoveryProvider.class); - Assert.assertEquals(1, discovery.discoveryProviders.size()); - Assert.assertEquals(1, discovery.deviceClasses.size()); - } - - @Test - public void testRegisterDeviceServiceWithNullValues() { - Assert.assertEquals(0, discovery.discoveryProviders.size()); - Assert.assertEquals(0, discovery.deviceClasses.size()); - - try { - discovery.registerDeviceService(null, SSDPDiscoveryProvider.class); - Assert.fail("NullPointerException must be casted"); - } catch (NullPointerException e) {} - - try { - discovery.registerDeviceService(DLNAService.class, null); - Assert.fail("NullPointerException must be casted"); - } catch (NullPointerException e) {} - - Assert.assertEquals(0, discovery.discoveryProviders.size()); - Assert.assertEquals(0, discovery.deviceClasses.size()); - } -} diff --git a/test/src/com/connectsdk/discovery/provider/DiscoveryFilterTest.java b/test/src/com/connectsdk/discovery/provider/DiscoveryFilterTest.java deleted file mode 100644 index 4f74c061..00000000 --- a/test/src/com/connectsdk/discovery/provider/DiscoveryFilterTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.connectsdk.discovery.provider; - -import com.connectsdk.discovery.DiscoveryFilter; - -import junit.framework.Assert; - -import org.junit.Test; - -/** - * Created by oleksii.frolov on 2/12/2015. - */ -public class DiscoveryFilterTest { - - @Test - public void testEqualsWithNullObject() { - DiscoveryFilter filter = new DiscoveryFilter("DLNA", "filter"); - Assert.assertFalse(filter.equals(null)); - } - - @Test - public void testEqualsWithWrongObject() { - DiscoveryFilter filter = new DiscoveryFilter("DLNA", "filter"); - Assert.assertFalse(filter.equals(new Object())); - } -} diff --git a/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java b/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java deleted file mode 100755 index df497254..00000000 --- a/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java +++ /dev/null @@ -1,215 +0,0 @@ -package com.connectsdk.discovery.provider; - -import android.content.Context; - -import com.connectsdk.core.TestUtil; -import com.connectsdk.discovery.DiscoveryFilter; -import com.connectsdk.discovery.provider.ssdp.SSDPClient; -import com.connectsdk.service.config.ServiceDescription; -import com.connectsdk.shadow.WifiInfoShadow; - -import org.json.JSONException; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.InetAddress; -import java.net.URL; -import java.util.ArrayList; - -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE,shadows={WifiInfoShadow.class}) -public class SSDPDiscoveryProviderTest{ - - - SSDPDiscoveryProvider dp; - private SSDPClient ssdpClient = Mockito.mock(SSDPClient.class); - - class StubSSDPDiscoveryProvider extends SSDPDiscoveryProvider { - - public StubSSDPDiscoveryProvider(Context context) { - super(context); - - } - - @Override - protected SSDPClient createSocket(InetAddress source) throws IOException { - return ssdpClient; - } - - } - - @Before - public void setUp() throws Exception { - byte[] data = new byte[1]; - when(ssdpClient.responseReceive()).thenReturn(new DatagramPacket(data, 1)); - when(ssdpClient.multicastReceive()).thenReturn(new DatagramPacket(data, 1)); - dp = new StubSSDPDiscoveryProvider(Robolectric.application); - assertNotNull(dp); - } - @After - public void tearDown() throws Exception { - dp.stop(); - } - - @Test - public void testStop() throws JSONException, InterruptedException, IOException{ - //Test Desc. : Test to verify if the sendSearch is stopped then the dataGramSocket is disconnected and closed. - - dp.start(); - dp.stop(); - verify(ssdpClient, Mockito.times(1)).close(); - } - - @Test - public void testAddDeviceFilter() throws JSONException { - //Test Desc. : Test to verify if the deviceFilter is added properly. - - DiscoveryFilter filter = new DiscoveryFilter("DLNA", "urn:schemas-upnp-org:device:MediaRenderer:1"); - dp.addDeviceFilter(filter); - Assert.assertTrue(dp.serviceFilters.contains(filter)); - } - - @Test - public void testRemoveDeviceFilters() throws JSONException { - //Test Desc. : Test to verify if the deviceFilter is removed properly. - - DiscoveryFilter filter = new DiscoveryFilter("DLNA", "urn:schemas-upnp-org:device:MediaRenderer:1"); - dp.serviceFilters.add(filter); - dp.removeDeviceFilter(filter); - Assert.assertFalse(dp.serviceFilters.contains(filter)); - } - - @Test - public void testRemoveDeviceFiltersWithEmptyFilterString() throws JSONException { - DiscoveryFilter filter = new DiscoveryFilter("DLNA", null); - dp.serviceFilters.add(filter); - dp.removeDeviceFilter(filter); - Assert.assertFalse(dp.serviceFilters.contains(filter)); - } - - @Test - public void testRemoveDeviceFiltersWithEmptyId() throws JSONException { - DiscoveryFilter filter = new DiscoveryFilter(null, "urn:schemas-upnp-org:device:MediaRenderer:1"); - dp.serviceFilters.add(filter); - dp.removeDeviceFilter(filter); - Assert.assertFalse(dp.serviceFilters.contains(filter)); - } - - @Test - public void testRemoveDeviceFiltersWithDifferentFilterStrings() throws JSONException { - DiscoveryFilter filter = new DiscoveryFilter("DLNA", "urn:schemas-upnp-org:device:MediaRenderer:1"); - dp.serviceFilters.add(filter); - dp.removeDeviceFilter(new DiscoveryFilter("DLNA", null)); - Assert.assertTrue(dp.serviceFilters.contains(filter)); - } - - @Test - public void testIsEmpty() throws JSONException { - //Test Desc.: Verify if the serviceFilters is empty prior to calling the scheduled timer task start() which adds the searchTarget as filter into the ServiceFilters. - - DiscoveryFilter filter = new DiscoveryFilter("DLNA", "urn:schemas-upnp-org:device:MediaRenderer:1"); - Assert.assertTrue(dp.isEmpty()); - dp.serviceFilters.add(filter); - Assert.assertFalse(dp.isEmpty()); - } - - @Test - public void testGetLocationDataFromEmptyLocation() { - try { - dp.getLocationData((String)null, null, null); - } catch (Exception e) { - Assert.fail(e.getClass().getSimpleName()); - } - TestUtil.runUtilBackgroundTasks(); - Assert.assertTrue(dp.foundServices.isEmpty()); - } - - @Test - public void testGetLocationDataFrom() throws IOException, InterruptedException { - String uuid = "0f574021-141a-ebe8-eeac-bcf7b973615a"; - String serviceFilter = "urn:lge-com:service:webos-second-screen:1"; - String deviceDescription = - "\n" + - "\n" + - "1\n" + - "0\n" + - "\n" + - "\n" + - "" + uuid + "\n" + - "" + serviceFilter + "\n" + - "Adnan TV\n" + - "\n" + - ""; - String applicationUrl = "http://appurl/"; - URL location = TestUtil.getMockUrl(deviceDescription, applicationUrl); - - ServiceDescription foundService = new ServiceDescription(); - foundService.setUUID(uuid); - foundService.setServiceFilter(serviceFilter); - foundService.setIpAddress("hostname"); - foundService.setPort(80); - - dp.discoveredServices.put(uuid, foundService); - - try { - dp.getLocationData(location, uuid, serviceFilter); - } catch (Exception e) { - Assert.fail(e.getClass().getSimpleName()); - } - TestUtil.runUtilBackgroundTasks(); - Assert.assertFalse(dp.foundServices.isEmpty()); - Assert.assertEquals("Adnan TV", dp.foundServices.get(uuid).getFriendlyName()); - } - - @Test - public void testServiceIdsForFilter() throws JSONException { - //Test Desc. : Verify if SSDPDiscoveryProvider. serviceIdForFilter returns the serviceId for the specified filter added in ServiceFilters list. - - DiscoveryFilter filter = new DiscoveryFilter("DLNA", "urn:schemas-upnp-org:device:MediaRenderer:1"); - dp.serviceFilters.add(filter); - ArrayList expectedResult = new ArrayList(); - expectedResult.add(filter.getServiceId()); - Assert.assertEquals(expectedResult, dp.serviceIdsForFilter(filter.getServiceFilter())); - - } - - @Test - public void testIsSearchingForFilter() throws JSONException { - //Test Desc. : Verify if SSDPDiscoveryProvider. IsSearchingForFilter returns the expected result. - - DiscoveryFilter filter = new DiscoveryFilter("DLNA", "urn:schemas-upnp-org:device:MediaRenderer:1"); - dp.serviceFilters.add(filter); - Assert.assertTrue(dp.isSearchingForFilter(filter.getServiceFilter())); - - } - - @Test - public void testReset() throws IOException{ - //Test Desc. : Verify if JmdnsRegistry reset the services found for SSDPDiscoveryProvider. - - - Assert.assertTrue(dp.foundServices.isEmpty()); - dp.start(); - Assert.assertTrue(dp.foundServices.isEmpty()); - - dp.reset(); - Assert.assertTrue(dp.foundServices.isEmpty()); - - } - - -} diff --git a/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java b/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java deleted file mode 100644 index b9173d5c..00000000 --- a/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java +++ /dev/null @@ -1,316 +0,0 @@ -package com.connectsdk.discovery.provider; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.net.InetAddress; - -import javax.jmdns.JmDNS; -import javax.jmdns.ServiceEvent; -import javax.jmdns.ServiceInfo; -import javax.jmdns.ServiceListener; -import javax.jmdns.impl.JmDNSImpl; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import android.content.Context; - -import com.connectsdk.discovery.DiscoveryFilter; -import com.connectsdk.discovery.DiscoveryManager; -import com.connectsdk.discovery.DiscoveryProvider; -import com.connectsdk.discovery.DiscoveryProviderListener; -import com.connectsdk.service.config.ServiceDescription; -import com.connectsdk.shadow.WifiInfoShadow; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE, shadows = { WifiInfoShadow.class }) -public class ZeroConfDiscoveryPrividerTest { - - private ZeroconfDiscoveryProvider dp; - private JmDNS mDNS; - private ServiceEvent eventMock; - - // stub classes are used to allow mocking inside Robolectric test - class StubJmDNS extends JmDNSImpl { - - public StubJmDNS() throws IOException { - this(null, null); - } - - public StubJmDNS(InetAddress address, String name) throws IOException { - super(address, name); - } - } - - abstract class StubServiceEvent extends ServiceEvent { - - public StubServiceEvent(Object eventSource) { - super(eventSource); - } - } - - abstract class StubServiceInfo extends javax.jmdns.ServiceInfo {} - - class StubZeroConfDiscoveryProvider extends ZeroconfDiscoveryProvider { - - public StubZeroConfDiscoveryProvider(Context context) { - super(context); - } - - @Override - protected JmDNS createJmDNS() { - return mDNS; - } - } - - @Before - public void setUp() { - dp = new StubZeroConfDiscoveryProvider(Robolectric.application); - mDNS = mock(StubJmDNS.class); - eventMock = mock(StubServiceEvent.class); - - dp.jmdns = mDNS; - } - - @Test - public void testStartShouldAddDeviceFilter() throws Exception { - DiscoveryFilter filter = new DiscoveryFilter("Apple TV", "_testservicetype._tcp.local."); - - dp.addDeviceFilter(filter); - dp.start(); - - Thread.sleep(500); - verify(mDNS).addServiceListener(filter.getServiceFilter(), dp.jmdnsListener); - } - - @Test - public void testStartShouldCancelPreviousSearch() throws Exception { - DiscoveryFilter filter = new DiscoveryFilter("Apple TV", "_testservicetype._tcp.local."); - - dp.addDeviceFilter(filter); - dp.stop(); - - verify(mDNS).removeServiceListener(filter.getServiceFilter(), dp.jmdnsListener); - } - - @Test - public void testJmdnsServiceAdded() throws Exception { - // Test Desc.: Verify when service added to the JmdnsServiceListener - // then "service information is queried from registry with injected - // event mock object. - - dp.jmdnsListener.serviceAdded(eventMock); - dp.start(); - - verify(eventMock, atLeastOnce()).getType(); - verify(eventMock, atLeastOnce()).getName(); - verify(mDNS, timeout(100)).requestServiceInfo(eventMock.getType(), - eventMock.getName(), 1); - } - - @Test - public void testAddListener() throws Exception { - // Test Desc.: Verify ZeroConfDiscoveryProvider addListener - Adds a - // DiscoveryProviderListener instance which is the DiscoveryManager Impl - // to ServiceListeners List. - - DiscoveryManager listenerMock = mock(DiscoveryManager.class); - - Assert.assertFalse(dp.serviceListeners.contains(listenerMock)); - dp.addListener(listenerMock); - - Assert.assertTrue(dp.serviceListeners.contains(listenerMock)); - } - - @Test - public void testRemoveListener() throws Exception { - // Test Desc.: Verify ZeroConfDiscoveryProvider RemoveListener - Removes - // a DiscoveryProviderListener instance which is the DiscoveryManager - // Impl from ServiceListeners List. - - DiscoveryManager listenerMock = mock(DiscoveryManager.class); - - Assert.assertFalse(dp.serviceListeners.contains(listenerMock)); - dp.serviceListeners.add(listenerMock); - Assert.assertTrue(dp.serviceListeners.contains(listenerMock)); - - dp.removeListener(listenerMock); - - Assert.assertFalse(dp.serviceListeners.contains(listenerMock)); - } - - @Test - public void testFiltersAreEmptyByDefault() throws Exception { - // Test Desc.: Verify if the serviceFilters is empty prior to calling - // the scheduled timer task start() which adds the searchTarget as - // filter into the ServiceFilters. - - DiscoveryFilter filter = new DiscoveryFilter("Apple TV", "_testservicetype._tcp.local."); - Assert.assertTrue(dp.isEmpty()); - - dp.serviceFilters.add(filter); - - Assert.assertFalse(dp.isEmpty()); - } - - @Test - public void testStopZeroConfService() throws Exception { - // Test Desc. : Verify if on stop() of ZeroConfDiscoveryProvider - // Service, implicitly invoke the removeServiceListener() on JmDns - // instance, - - DiscoveryFilter filter = new DiscoveryFilter("Apple TV", "_testservicetype._tcp.local."); - dp.serviceFilters.add(filter); - - ServiceListener listener = dp.jmdnsListener; - - verify(mDNS, Mockito.never()).removeServiceListener( - filter.getServiceFilter(), listener); - dp.stop(); - verify(mDNS, Mockito.times(1)).removeServiceListener( - filter.getServiceFilter(), listener); - } - - @Test - public void testReset() throws Exception { - // Test Desc. : Verify if JmdnsRegistry reset the services found for - // ZeroConfDiscoveryProvider. - - ServiceDescription serviceDesc = new ServiceDescription(); - dp.foundServices.put("service", serviceDesc); - Assert.assertFalse(dp.foundServices.isEmpty()); - - dp.reset(); - Assert.assertTrue(dp.foundServices.isEmpty()); - } - - @Test - public void testAddDeviceFilter() throws Exception { - // Test Desc. : Verify if ZeroConfDiscoveryProvider. AddDeviceFilter - // adds the specified device filter to serviceFilters list. - - DiscoveryFilter filter = new DiscoveryFilter("Test TV", "_testservicetype._tcp.local."); - - Assert.assertFalse(dp.serviceFilters.contains(filter)); - dp.addDeviceFilter(filter); - - Assert.assertTrue(dp.serviceFilters.contains(filter)); - } - - @Test - public void testRemoveDeviceFilter() throws Exception { - // Test Desc. : Verify if ZeroConfDiscoveryProvider. removeDeviceFilter - // removes the entry specified device filter from to serviceFilters - // list. - - DiscoveryFilter filter = new DiscoveryFilter("Test TV", "_testservicetype._tcp.local."); - - dp.serviceFilters.add(filter); - Assert.assertFalse(dp.serviceFilters.isEmpty()); - - dp.removeDeviceFilter(filter); - - Assert.assertTrue(dp.serviceFilters.isEmpty()); - } - - @Test - public void testServiceIdForFilter() throws Exception { - // Test Desc. : Verify if ZeroConfDiscoveryProvider. serviceIdForFilter - // returns the serviceId for the specified filter added in - // ServiceFilters list. - - DiscoveryFilter filter = new DiscoveryFilter("Test TV", "_testservicetype._tcp.local."); - dp.serviceFilters.add(filter); - - String serviceId = dp.serviceIdForFilter(filter.getServiceFilter()); - - Assert.assertEquals("Test TV", serviceId); - } - - private ServiceEvent createMockedServiceEvent(String ip, String name) { - ServiceEvent event = mock(StubServiceEvent.class); - ServiceInfo info = mock(StubServiceInfo.class); - when(event.getInfo()).thenReturn(info); - when(info.getHostAddress()).thenReturn(ip); - when(info.getPort()).thenReturn(7000); - when(info.getName()).thenReturn(name); - return event; - } - - @Test - public void testServiceResolveEvent() throws Exception { - // given - ServiceEvent event = createMockedServiceEvent("192.168.0.1", "Test TV"); - DiscoveryProviderListener listener = mock(DiscoveryProviderListener.class); - dp.addListener(listener); - - // when - dp.jmdnsListener.serviceResolved(event); - - // then - verify(listener).onServiceAdded(any(DiscoveryProvider.class), any(ServiceDescription.class)); - } - - @Test - public void testServiceResolveEventWhenThereIsFoundService() throws Exception { - // given - String uuid = "192.168.0.1"; - String name = "Test TV"; - ServiceDescription serviceDescription = new ServiceDescription("_testservicetype._tcp.local.", uuid, uuid); - serviceDescription.setFriendlyName(name); - ServiceEvent event = createMockedServiceEvent(uuid, name); - dp.foundServices.put(uuid, serviceDescription); - DiscoveryProviderListener listener = mock(DiscoveryProviderListener.class); - dp.addListener(listener); - - // when - dp.jmdnsListener.serviceResolved(event); - - // then - verify(listener, never()).onServiceAdded(any(DiscoveryProvider.class), any(ServiceDescription.class)); - } - - @Test - public void testServiceRemoveEvent() throws Exception { - // given - String uuid = "192.168.0.1"; - String name = "Test TV"; - ServiceDescription serviceDescription = new ServiceDescription("_testservicetype._tcp.local.", uuid, uuid); - serviceDescription.setFriendlyName(name); - ServiceEvent event = createMockedServiceEvent(uuid, name); - DiscoveryProviderListener listener = mock(DiscoveryProviderListener.class); - dp.addListener(listener); - dp.foundServices.put(uuid, serviceDescription); - - // when - dp.jmdnsListener.serviceRemoved(event); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - - // then - verify(listener).onServiceRemoved(any(DiscoveryProvider.class), any(ServiceDescription.class)); - } - - @Test - public void testStateAfterConstruction() { - Assert.assertNotNull(dp.foundServices); - Assert.assertNotNull(dp.serviceFilters); - Assert.assertNotNull(dp.serviceListeners); - Assert.assertTrue(dp.foundServices.isEmpty()); - Assert.assertTrue(dp.serviceFilters.isEmpty()); - Assert.assertTrue(dp.serviceListeners.isEmpty()); - Assert.assertNotNull(dp.srcAddress); - } -} diff --git a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java deleted file mode 100644 index 5f638446..00000000 --- a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.connectsdk.discovery.provider.ssdp; - -import com.connectsdk.core.Util; -import com.connectsdk.shadow.WifiInfoShadow; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.MulticastSocket; -import java.net.NetworkInterface; -import java.net.SocketAddress; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE ,shadows = { WifiInfoShadow.class }) -public class SSDPClientTest { - - InetAddress localAddress; - SSDPClient ssdpClient; - - private DatagramSocket wildSocket = Mockito.mock(DatagramSocket.class); - private MulticastSocket mLocalSocket = Mockito.mock(MulticastSocket.class); - - public SSDPClientTest() { - super(); - } - - @Before - public void setUp() throws IOException { - localAddress = Util.getIpAddress(Robolectric.application); - ssdpClient = new SSDPClient(localAddress, mLocalSocket, wildSocket); - } - - @Test - public void testSend() throws Exception { - //Verify is ssdpClient.send() is sending correct SSDP packet to DatagramSocket - - String stringData = "some data"; - DatagramPacket dp = new DatagramPacket(stringData.getBytes(), - stringData.length(), new InetSocketAddress("239.255.255.250",1900)); - ssdpClient.send(stringData); - - ArgumentCaptor argument = ArgumentCaptor.forClass(DatagramPacket.class); - Mockito.verify(wildSocket).send(argument.capture()); - - Assert.assertEquals(dp.getAddress(), argument.getValue().getAddress()); - Assert.assertEquals(dp.getPort(), argument.getValue().getPort()); - Assert.assertEquals(new String(dp.getData()), new String(argument.getValue().getData())); - } - - @Test - public void testResponseRecieve() throws IOException { - //Verify is ssdpClient.responseReceive() receive SSDP Response packet to DatagramSocket - - byte[] buf = new byte[1024]; - DatagramPacket dp = new DatagramPacket(buf, buf.length); - ssdpClient.responseReceive(); - - ArgumentCaptor argument = ArgumentCaptor.forClass(DatagramPacket.class); - Mockito.verify(wildSocket).receive(argument.capture()); - Assert.assertEquals(dp.getLength(), argument.getValue().getLength()); - Assert.assertEquals(new String(dp.getData()), new String(argument.getValue().getData())); - - } - - @Test - public void testNotifyReceive() throws IOException { - //Verify is ssdpClient.NotifyReceive() receive SSDP Notify packet to DatagramSocket. - - byte[] buf = new byte[1024]; - DatagramPacket dp = new DatagramPacket(buf, buf.length); - ssdpClient.multicastReceive(); - - ArgumentCaptor argument = ArgumentCaptor.forClass(DatagramPacket.class); - Mockito.verify(mLocalSocket).receive(argument.capture()); - Assert.assertEquals(dp.getLength(), argument.getValue().getLength()); - Assert.assertEquals(new String(dp.getData()), new String(argument.getValue().getData())); - - } - - - @Test - public void testClose() throws IOException { - wildSocket.connect(localAddress, 1903); - mLocalSocket.connect(localAddress, 1904); - ssdpClient.close(); - - Mockito.verify(mLocalSocket, Mockito.times(1)).leaveGroup(Mockito.any(SocketAddress.class),Mockito.any(NetworkInterface.class)); - Mockito.verify(mLocalSocket, Mockito.times(1)).close(); - Mockito.verify(wildSocket, Mockito.times(1)).disconnect(); - Mockito.verify(wildSocket, Mockito.times(1)).close(); - - - } - - @Test - public void testSetTimeout() throws Exception { - Integer testTimeout = 1000; - ssdpClient.setTimeout(testTimeout); - - ArgumentCaptor argument = ArgumentCaptor.forClass(Integer.class); - Mockito.verify(wildSocket, Mockito.times(1)).setSoTimeout(argument.capture()); - Assert.assertEquals(testTimeout, new Integer(argument.getValue())); - - } - - -} diff --git a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPDeviceTest.java b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPDeviceTest.java deleted file mode 100644 index 86677a2f..00000000 --- a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPDeviceTest.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.connectsdk.discovery.provider.ssdp; - -import com.connectsdk.core.TestUtil; - -import junit.framework.Assert; - -import org.junit.Test; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.UnknownHostException; - -import javax.xml.parsers.ParserConfigurationException; - -/** - * Created by oleksii.frolov on 1/30/2015. - */ -public class SSDPDeviceTest { - - String deviceDescription = - "\n" + - "\n" + - "1\n" + - "0\n" + - "\n" + - "\n" + - "urn:schemas-upnp-org:device:Basic:1\n" + - "Adnan TV\n" + - "LG Electronics\n" + - "http://www.lge.com\n" + - "\n" + - "LG Smart TV\n" + - "http://www.lge.com\n" + - "WEBOS1\n" + - "\n" + - "uuid:86ea12c3-4ad7-2117-edbd-8177429fe21e\n" + - "\n" + - "\n" + - "urn:lge-com:service:webos-second-screen:1\n" + - "\n" + - "urn:lge-com:serviceId:webos-second-screen-3000-3001\n" + - "\n" + - "\n" + - "/WebOS_SecondScreen/86ea12c3-4ad7-2117-edbd-8177429fe21e/scpd.xml\n" + - "\n" + - "\n" + - "/WebOS_SecondScreen/86ea12c3-4ad7-2117-edbd-8177429fe21e/control.xml\n" + - "\n" + - "\n" + - "/WebOS_SecondScreen/86ea12c3-4ad7-2117-edbd-8177429fe21e/event.xml\n" + - "\n" + - "\n" + - "\n" + - "\n" + - ""; - - String deviceSmallDescription = - "\n" + - "\n" + - "1\n" + - "0\n" + - "\n" + - "\n" + - "urn:schemas-upnp-org:device:Basic:1\n" + - "\n" + - ""; - - @Test - public void testCreateDeviceWithNullUrl() { - try { - new SSDPDevice((String)null, null); - Assert.fail("MalformedURLException should be thrown"); - } catch (MalformedURLException e) { - // OK - } catch (Exception e) { - Assert.fail("MalformedURLException should be thrown"); - } - } - - @Test - public void testCreateDeviceWithWrongUrl() { - try { - new SSDPDevice("http://unknown.host", null); - Assert.fail("MalformedURLException should be thrown"); - } catch (UnknownHostException e) { - // OK - } catch (Exception e) { - Assert.fail("MalformedURLException should be thrown"); - } - } - - @Test - public void testCreateDeviceFromPlainTextContent() { - try { - new SSDPDevice(TestUtil.getMockUrl("plain text", null), null); - Assert.fail("SAXParseException should be thrown"); - } catch (SAXParseException e) { - // OK - } catch (Exception e) { - Assert.fail("SAXParseException should be thrown"); - } - } - - @Test - public void testCreateDeviceFrom() throws IOException, ParserConfigurationException, SAXException { - SSDPDevice device = new SSDPDevice(TestUtil.getMockUrl(deviceDescription, "http://application_url/"), null); - Assert.assertEquals("urn:schemas-upnp-org:device:Basic:1", device.deviceType); - Assert.assertEquals("Adnan TV", device.friendlyName); - Assert.assertEquals("LG Electronics", device.manufacturer); - Assert.assertNull(device.modelDescription); - Assert.assertEquals(deviceDescription, device.locationXML); - Assert.assertEquals("http://application_url/", device.applicationURL); - Assert.assertEquals("hostname", device.ipAddress); - Assert.assertEquals(80, device.port); - Assert.assertEquals("http://hostname", device.serviceURI); - Assert.assertEquals("http://hostname:80", device.baseURL); - Assert.assertEquals("WEBOS1", device.modelNumber); - } - - @Test - public void testCreateDeviceFromSmallDescription() throws IOException, ParserConfigurationException, SAXException { - SSDPDevice device = new SSDPDevice(TestUtil.getMockUrl(deviceSmallDescription, "http://application_url"), null); - Assert.assertEquals("urn:schemas-upnp-org:device:Basic:1", device.deviceType); - Assert.assertNull(device.friendlyName); - Assert.assertNull(device.manufacturer); - Assert.assertNull(device.modelDescription); - Assert.assertEquals(deviceSmallDescription, device.locationXML); - Assert.assertEquals("http://application_url/", device.applicationURL); - Assert.assertEquals("hostname", device.ipAddress); - Assert.assertEquals(80, device.port); - Assert.assertEquals("http://hostname", device.serviceURI); - Assert.assertEquals("http://hostname:80", device.baseURL); - Assert.assertNull(device.modelNumber); - } - -} diff --git a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java deleted file mode 100644 index d9e4d23d..00000000 --- a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.connectsdk.discovery.provider.ssdp; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.net.DatagramPacket; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) -public class SSDPPacketTest { - - DatagramPacket mDatagramPacket; - SSDPPacket ssdpPacket; - - public SSDPPacketTest() { - super(); - } - - @Before - public void setUp(){ - String testDatagramData = ""; - mDatagramPacket = new DatagramPacket(testDatagramData.getBytes(), 0); - } - - - @Test - public void testParseDatagram() { - String testDatagramData = - "NOTIFY * HTTP/1.1\r\n" + - "HOST: 239.255.255.250:1900\r\n" + - "NT: nt_value\r\n" + - "NTS: ssdp:byebye\r\n" + - "USN: uuid:advertisement_UUID\r\n\r\n"; - mDatagramPacket = new DatagramPacket(testDatagramData.getBytes(), 0); - ssdpPacket = new SSDPPacket(mDatagramPacket); - Assert.assertEquals("NOTIFY * HTTP/1.1", ssdpPacket.getType()); - Assert.assertEquals("239.255.255.250:1900", ssdpPacket.getData().get("HOST")); - Assert.assertEquals("nt_value", ssdpPacket.getData().get("NT")); - Assert.assertEquals("ssdp:byebye", ssdpPacket.getData().get("NTS")); - Assert.assertEquals("uuid:advertisement_UUID", ssdpPacket.getData().get("USN")); - } - - - @Test - public void testParseLowercaseDatagram() { - String testDatagramData = - "NOTIFY * HTTP/1.1\r\n" + - "host: 239.255.255.250:1900\r\n" + - "nt: nt_value\r\n" + - "Nts: ssdp:byebye\r\n" + - "uSN: uuid:advertisement_UUID\r\n\r\n"; - mDatagramPacket = new DatagramPacket(testDatagramData.getBytes(), 0); - ssdpPacket = new SSDPPacket(mDatagramPacket); - Assert.assertEquals("NOTIFY * HTTP/1.1", ssdpPacket.getType()); - Assert.assertEquals("239.255.255.250:1900", ssdpPacket.getData().get("HOST")); - Assert.assertEquals("nt_value", ssdpPacket.getData().get("NT")); - Assert.assertEquals("ssdp:byebye", ssdpPacket.getData().get("NTS")); - Assert.assertEquals("uuid:advertisement_UUID", ssdpPacket.getData().get("USN")); - } - - - @Test - public void testParseEmptyDatagram() { - String testDatagramData = "Unknown"; - mDatagramPacket = new DatagramPacket(testDatagramData.getBytes(), 0); - ssdpPacket = new SSDPPacket(mDatagramPacket); - Assert.assertNull(ssdpPacket.getType()); - Assert.assertTrue(ssdpPacket.getData().isEmpty()); - } - - @Test - public void testParseGarbage() { - String testDatagramData = "\n\r\n\r\r\n\n\r\n\r\n::::sdkfjh::\r\n:\r\n::\r\nKEY:\r\nsdf\r\n\u000E¾<ƒÄ\f^‹Ã_Ã\u0007Ì\u0001ÜLÿ›îÿ$\u0004‰P\u0004‹T$\b‰H\u001B\f\f‰\r\n"; - try { - mDatagramPacket = new DatagramPacket(testDatagramData.getBytes(), 0); - ssdpPacket = new SSDPPacket(mDatagramPacket); - Assert.assertEquals("", ssdpPacket.getData().get("KEY")); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } - } - - @Test - public void testParseDatagramWithoutLineEnd() { - String testDatagramData = "key:value"; - mDatagramPacket = new DatagramPacket(testDatagramData.getBytes(), 0); - ssdpPacket = new SSDPPacket(mDatagramPacket); - Assert.assertEquals(null, ssdpPacket.getData().get("key")); - } -} diff --git a/test/src/com/connectsdk/service/AirPlayServiceTest.java b/test/src/com/connectsdk/service/AirPlayServiceTest.java deleted file mode 100644 index 1f9f4a8c..00000000 --- a/test/src/com/connectsdk/service/AirPlayServiceTest.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.connectsdk.service; - -import com.connectsdk.service.capability.MediaControl; -import com.connectsdk.service.command.ServiceCommand; -import com.connectsdk.service.command.ServiceCommandError; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.io.IOException; - -/** - * Created by Oleksii Frolov on 3/19/2015. - */ -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class AirPlayServiceTest { - - private StubAirPlayService service; - - class StubAirPlayService extends AirPlayService { - - private Object response; - - public StubAirPlayService(ServiceDescription serviceDescription, ServiceConfig serviceConfig) throws IOException { - super(serviceDescription, serviceConfig); - } - - public void setResponse(Object response) { - this.response = response; - } - - @Override - public void sendCommand(ServiceCommand serviceCommand) { - serviceCommand.getResponseListener().onSuccess(response); - } - - } - - @Before - public void setUp() throws IOException { - service = new StubAirPlayService(Mockito.mock(ServiceDescription.class), Mockito.mock(ServiceConfig.class)); - } - - @Test - public void testGetPlayStateFinished() throws InterruptedException { - service.setResponse( - "" + - "" + - "" + - "" + - "" - ); - service.getPlayState(new MediaControl.PlayStateListener() { - @Override - public void onSuccess(MediaControl.PlayStateStatus object) { - Assert.assertEquals(MediaControl.PlayStateStatus.Finished, object); - } - - @Override - public void onError(ServiceCommandError error) { - Assert.fail(); - } - }); - } - - @Test - public void testGetPlayStatePlaying() throws InterruptedException { - service.setResponse( - "" + - "" + - "" + - "rate" + - "1" + - "" + - "" - ); - service.getPlayState(new MediaControl.PlayStateListener() { - @Override - public void onSuccess(MediaControl.PlayStateStatus object) { - Assert.assertEquals(MediaControl.PlayStateStatus.Playing, object); - } - - @Override - public void onError(ServiceCommandError error) { - Assert.fail(); - } - }); - } - - @Test - public void testDigestAuthentication() { - Assert.assertEquals(null, service.digestAuthentication(null)); - Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e", service.digestAuthentication("")); - Assert.assertEquals("202cb962ac59075b964b07152d234b70", service.digestAuthentication("123")); - Assert.assertEquals("7b613f0aafa3e72b11d5e08c8c51f03f", service.digestAuthentication("526b828b08a7b3e36498d2ecec4b5e49")); - } - - @Test - public void testGetAuthenticate() { - // Assume that a password is AirPlay - service.password = "AirPlay"; - Assert.assertEquals("Digest username=\"AirPlay\", realm=\"AirPlay\", nonce=\"MTMzMTMwODI0MCDEJP5Jo7HFo81rbAcKNKw2\", uri=\"/play\", response=\"85c25341d6e62d402f6600340fc44ce0\"", - service.getAuthenticate("Digest", "/play", "Digest realm=\"AirPlay\", nonce=\"MTMzMTMwODI0MCDEJP5Jo7HFo81rbAcKNKw2\"")); - } - - @Test - public void testInitialPairingType() { - Assert.assertEquals(DeviceService.PairingType.PIN_CODE, service.getPairingType()); - } - - @Test - public void testPairingTypeSetter() { - service.setPairingType(DeviceService.PairingType.PIN_CODE); - Assert.assertEquals(DeviceService.PairingType.PIN_CODE, service.getPairingType()); - } - - @Test - public void testGetDuration() { - service.setResponse( - "duration: 83.124794\n" + - "position: 14.467000"); - service.getDuration(new MediaControl.DurationListener() { - @Override - public void onSuccess(Long duration) { - Assert.assertEquals(83000, duration.longValue()); - } - - @Override - public void onError(ServiceCommandError error) { - Assert.fail(); - } - }); - } - - @Test - public void testGetDurationWithComma() { - service.setResponse( - "duration: 83,124794\n" + - "position: 14,467000"); - service.getDuration(new MediaControl.DurationListener() { - @Override - public void onSuccess(Long duration) { - Assert.assertEquals(0, duration.longValue()); - } - - @Override - public void onError(ServiceCommandError error) { - Assert.fail(); - } - }); - } - - @Test - public void testGetDurationWithWrongData() { - service.setResponse("zxcmnb"); - service.getDuration(new MediaControl.DurationListener() { - @Override - public void onSuccess(Long duration) { - Assert.assertEquals(0, duration.longValue()); - } - - @Override - public void onError(ServiceCommandError error) { - Assert.fail(); - } - }); - } - -} diff --git a/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java b/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java deleted file mode 100644 index 0e6bc222..00000000 --- a/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * DIALServiceSendCommandTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 14 May 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.service; - -import com.connectsdk.core.TestUtil; -import com.connectsdk.etc.helper.HttpConnection; -import com.connectsdk.etc.helper.HttpMessage; -import com.connectsdk.service.capability.listeners.ResponseListener; -import com.connectsdk.service.command.ServiceCommand; -import com.connectsdk.service.command.ServiceCommandError; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.io.IOException; - - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class DIALServiceSendCommandTest { - - public static final String COMMAND_URL = "http://host:8080/path"; - - StubDIALService service; - - HttpConnection httpConnection; - - class StubDIALService extends DIALService { - - String connectionTarget; - - public StubDIALService(ServiceDescription serviceDescription, ServiceConfig serviceConfig) { - super(serviceDescription, serviceConfig); - } - - @Override - HttpConnection createHttpConnection(String target) throws IOException { - this.connectionTarget = target; - return httpConnection; - } - } - - @Before - public void setUp() { - httpConnection = Mockito.mock(HttpConnection.class); - service = new StubDIALService(Mockito.mock(ServiceDescription.class), - Mockito.mock(ServiceConfig.class)); - } - - @Test - public void testSendSimpleGetCommand() throws Exception { - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, null, listener); - command.setHttpMethod(ServiceCommand.TYPE_GET); - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - - Assert.assertEquals(COMMAND_URL, service.connectionTarget); - Mockito.verify(httpConnection, Mockito.times(0)).setMethod(Mockito.any(HttpConnection.Method.class)); - Mockito.verify(httpConnection, Mockito.times(1)).execute(); - } - - @Test - public void testSendSimpleDeleteCommand() throws Exception { - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, null, listener); - command.setHttpMethod(ServiceCommand.TYPE_DEL); - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - - Assert.assertEquals(COMMAND_URL, service.connectionTarget); - Mockito.verify(httpConnection, Mockito.times(1)).setMethod(Mockito.eq(HttpConnection - .Method.DELETE)); - Mockito.verify(httpConnection, Mockito.times(1)).execute(); - } - - @Test - public void testSendSimplePostCommand() throws Exception { - Object payload = "postdata"; - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, payload, listener); - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - - Assert.assertEquals(COMMAND_URL, service.connectionTarget); - Mockito.verify(httpConnection, Mockito.times(1)) - .setHeader(Mockito.eq(HttpMessage.CONTENT_TYPE_HEADER), - Mockito.eq("text/plain; charset=\"utf-8\"")); - Mockito.verify(httpConnection, Mockito.times(1)).setMethod(Mockito.eq(HttpConnection.Method.POST)); - Mockito.verify(httpConnection, Mockito.times(1)).setPayload(Mockito.eq(payload.toString())); - Mockito.verify(httpConnection, Mockito.times(1)).execute(); - } - - @Test - public void testSendPostCommandWithEmptyPayload() throws Exception { - Object payload = null; - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, payload, listener); - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - - Assert.assertEquals(COMMAND_URL, service.connectionTarget); - Mockito.verify(httpConnection, Mockito.times(1)).setMethod(Mockito.eq(HttpConnection.Method.POST)); - Mockito.verify(httpConnection, Mockito.times(0)).setPayload(Mockito.anyString()); - Mockito.verify(httpConnection, Mockito.times(1)).execute(); - } - - @Test - public void testSendCommand200ShouldInvokeSuccess() throws Exception { - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, null, listener); - String response = "responsedata"; - Mockito.when(httpConnection.getResponseCode()).thenReturn(200); - Mockito.when(httpConnection.getResponseString()).thenReturn(response); - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - - Mockito.verify(listener).onSuccess(Mockito.eq(response)); - } - - @Test - public void testSendCommand201ShouldInvokeSuccess() throws Exception { - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, null, listener); - String response = "responsedata"; - Mockito.when(httpConnection.getResponseCode()).thenReturn(201); - Mockito.when(httpConnection.getResponseHeader(Mockito.eq("Location"))).thenReturn(response); - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - - Mockito.verify(listener).onSuccess(Mockito.eq(response)); - } - - @Test - public void testSendCommand400ShouldInvokeError() throws Exception { - verifyFailedConnection(400); - } - - @Test - public void testSendCommand404ShouldInvokeError() throws Exception { - verifyFailedConnection(404); - } - - @Test - public void testSendCommand500ShouldInvokeError() throws Exception { - verifyFailedConnection(500); - } - - private void verifyFailedConnection(int code) throws IOException { - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, null, listener); - String response = "responsedata"; - Mockito.when(httpConnection.getResponseCode()).thenReturn(code); - Mockito.when(httpConnection.getResponseString()).thenReturn(response); - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - - Mockito.verify(listener).onError(Mockito.any(ServiceCommandError.class)); - } - -} diff --git a/test/src/com/connectsdk/service/DIALServiceTest.java b/test/src/com/connectsdk/service/DIALServiceTest.java deleted file mode 100644 index 2c2956b4..00000000 --- a/test/src/com/connectsdk/service/DIALServiceTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * DIALServiceTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 06 Aug 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.service; - -import com.connectsdk.service.capability.Launcher; -import com.connectsdk.service.command.ServiceCommand; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) -public class DIALServiceTest { - - private static final String APPLICATION_URL = "http://applicationurl"; - - private DIALService service; - private ServiceDescription serviceDescription; - private ServiceConfig serviceConfig; - private ServiceCommand.ServiceCommandProcessor commandProcessor; - - @Before - public void setUp() { - serviceDescription = Mockito.mock(ServiceDescription.class); - Mockito.when(serviceDescription.getApplicationURL()).thenReturn(APPLICATION_URL); - serviceConfig = Mockito.mock(ServiceConfig.class); - commandProcessor = Mockito.mock(ServiceCommand.ServiceCommandProcessor.class); - service = new DIALService(serviceDescription, serviceConfig); - service.setCommandProcessor(commandProcessor); - } - - @Test - public void testLaunchNetflixWithContentParameter() { - Launcher.AppLaunchListener listener = Mockito.mock(Launcher.AppLaunchListener.class); - String content = "123"; - String expectedPayload = "{\"v\":\""+content+"\"}"; - - service.launchNetflix(content, listener); - - verifyNetflixCommand(expectedPayload); - } - - @Test - public void testLaunchNetflixWithoutContentParameter() { - service.launchNetflix(null, Mockito.mock(Launcher.AppLaunchListener.class)); - - verifyNetflixCommand(null); - } - - @Test - public void testLaunchNetflixWithEmptyContentParameter() { - service.launchNetflix("", Mockito.mock(Launcher.AppLaunchListener.class)); - - verifyNetflixCommand(null); - } - - private void verifyNetflixCommand(String expectedPayload) { - ArgumentCaptor argCommand = ArgumentCaptor.forClass(ServiceCommand.class); - Mockito.verify(commandProcessor).sendCommand(argCommand.capture()); - ServiceCommand command = argCommand.getValue(); - - Assert.assertEquals(APPLICATION_URL + "/Netflix", command.getTarget()); - Assert.assertEquals(ServiceCommand.TYPE_POST, command.getHttpMethod()); - Assert.assertSame(commandProcessor, command.getCommandProcessor()); - if (expectedPayload != null) { - Assert.assertEquals(expectedPayload, command.getPayload().toString()); - } else { - Assert.assertNull(command.getPayload()); - } - } - -} diff --git a/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java b/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java deleted file mode 100644 index b715e1e9..00000000 --- a/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * DLNAServiceSendCommandTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 14 May 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.connectsdk.service; - -import com.connectsdk.core.TestUtil; -import com.connectsdk.etc.helper.HttpConnection; -import com.connectsdk.etc.helper.HttpMessage; -import com.connectsdk.service.capability.listeners.ResponseListener; -import com.connectsdk.service.command.ServiceCommand; -import com.connectsdk.service.command.ServiceCommandError; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.io.IOException; - - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class DLNAServiceSendCommandTest { - - public static final String COMMAND_URL = "http://host:8080/path"; - - StubDLNAService service; - - HttpConnection httpConnection; - - class StubDLNAService extends DLNAService { - - String connectionTarget; - - public StubDLNAService(ServiceDescription serviceDescription, ServiceConfig serviceConfig) { - super(serviceDescription, serviceConfig); - } - - @Override - HttpConnection createHttpConnection(String target) throws IOException { - this.connectionTarget = target; - return httpConnection; - } - } - - @Before - public void setUp() { - httpConnection = Mockito.mock(HttpConnection.class); - service = new StubDLNAService(Mockito.mock(ServiceDescription.class), - Mockito.mock(ServiceConfig.class)); - } - - @Test - public void testSendSimplePostCommand() throws Exception { - Object payload = DLNAService.AV_TRANSPORT_URN; - - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, payload, listener); - service.avTransportURL = COMMAND_URL; - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - - Assert.assertEquals(COMMAND_URL, service.connectionTarget); - - Mockito.verify(httpConnection, Mockito.times(1)).setMethod(Mockito.eq(HttpConnection.Method.POST)); - Mockito.verify(httpConnection, Mockito.times(1)).setPayload(Mockito.eq(payload.toString())); - Mockito.verify(httpConnection, Mockito.times(1)).execute(); - } - - @Test - public void testSendPostCommandWithNullPayload() throws Exception { - Object payload = null; - - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, payload, listener); - service.avTransportURL = COMMAND_URL; - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - - Mockito.verify(httpConnection, Mockito.times(0)).execute(); - Mockito.verify(listener).onError(Mockito.any(ServiceCommandError.class)); - } - - @Test - public void testSendPostCommandWithWrongPayload() throws Exception { - Object payload = "payload"; - - ResponseListener listener = Mockito.mock(ResponseListener.class); - ServiceCommand> command = - new ServiceCommand>(service, COMMAND_URL, payload, listener); - service.avTransportURL = COMMAND_URL; - - service.sendCommand(command); - TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - - Mockito.verify(httpConnection, Mockito.times(0)).execute(); - Mockito.verify(listener).onError(Mockito.any(ServiceCommandError.class)); - } - -} diff --git a/test/src/com/connectsdk/service/DLNAServiceTest.java b/test/src/com/connectsdk/service/DLNAServiceTest.java deleted file mode 100644 index a5ee87c0..00000000 --- a/test/src/com/connectsdk/service/DLNAServiceTest.java +++ /dev/null @@ -1,460 +0,0 @@ -package com.connectsdk.service; - -import com.connectsdk.core.SubtitleInfo; -import com.connectsdk.core.TestUtil; -import com.connectsdk.discovery.provider.ssdp.Service; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; -import com.connectsdk.service.upnp.DLNAHttpServer; - -import junit.framework.Assert; - -import org.custommonkey.xmlunit.DetailedDiff; -import org.custommonkey.xmlunit.XMLUnit; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.xml.sax.SAXException; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by oleksii.frolov on 1/13/2015. - */ -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) -public class DLNAServiceTest { - - private DLNAService service; - - private DLNAHttpServer dlnaServer; - - @Before - public void setUp() { - dlnaServer = Mockito.mock(DLNAHttpServer.class); - service = new DLNAService(Mockito.mock(ServiceDescription.class), - Mockito.mock(ServiceConfig.class), Robolectric.application, dlnaServer); - } - - @Test - public void testParseData() { - String tag = "TrackDuration"; - String response = "\n" + - "\n" + - " \n" + - " \n" + - " 1\n" + - " 0:00:52\n" + - " <DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"><item id=\"1000\" parentID=\"0\" restricted=\"0\"><dc:title>Sintel Trailer</dc:title><dc:description>Blender Open Movie Project</dc:description><res protocolInfo=\"http-get:*:video/mp4:DLNA.ORG_OP=01\">http://ec2-54-201-108-205.us-west-2.compute.amazonaws.com/samples/media/video.mp4</res><upnp:albumArtURI>http://ec2-54-201-108-205.us-west-2.compute.amazonaws.com/samples/media/videoIcon.jpg</upnp:albumArtURI><upnp:class>object.item.videoItem</upnp:class></item></DIDL-Lite>\n" + - " http://ec2-54-201-108-205.us-west-2.compute.amazonaws.com/samples/media/video.mp4\n" + - " 0:00:00\n" + - " NOT_IMPLEMENTED\n" + - " 2147483647\n" + - " 2147483647\n" + - " \n" + - " \n" + - ""; - String value = service.parseData(response, tag); - Assert.assertEquals("0:00:52", value); - } - - @Test - public void testParseDataWithError() { - String tag = "errorCode"; - String response = "\nSOAP-ENV:ClientUPnPError402Invalid Args"; - String value = service.parseData(response, tag); - Assert.assertEquals("402", value); - } - - @Test - public void testParseData3Symbols() { - String tag = "errorCode"; - String response = "<"; - String value = null; - try { - value = service.parseData(response, tag); - } catch (Exception e) { - Assert.fail("exception thrown: " + e); - } - Assert.assertEquals("", value); - } - - @Test - public void testGetMetadata() throws Exception { - String title = ""; - String description = "description"; - String mime = "audio/mpeg"; - String mediaURL = "http://host.com/media"; - String iconURL = "http://host.com/icon"; - - String expectedXML = "<DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " + - "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:sec=\"http://www.sec.co.kr/\" " + - "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" + - "<item id=\"1000\" parentID=\"0\" restricted=\"0\">" + - "<dc:title><title></dc:title>" + - "<dc:description>" + description + "</dc:description>" + - "<res protocolInfo=\"http-get:*:audio/mpeg:DLNA.ORG_OP=01\">" + mediaURL + "</res>" + - "<upnp:albumArtURI>" + iconURL + "</upnp:albumArtURI>" + - "<upnp:class>object.item.audioItem</upnp:class><" + - "/item></DIDL-Lite>"; - - String actualXML = service.getMetadata(mediaURL, null, mime, title, description, iconURL); - assertXMLEquals(expectedXML, actualXML); - } - - @Test - public void testGetMessageXml() throws Exception { - String method = "GetPosition"; - String serviceURN = "http://serviceurn/"; - - String expectedXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + - "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " + - "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + - "<s:Body>" + - "<u:" + method + " xmlns:u=\"" + serviceURN + "\">" + - "<key>value</key>" + - "</u:" + method + ">" + - "</s:Body>" + - "</s:Envelope>"; - - Map<String, String> params = new HashMap<String, String>(); - params.put("key", "value"); - String actualXML = service.getMessageXml(serviceURN, method, null, params); - assertXMLEquals(expectedXML, actualXML); - } - - @Test - public void testGetMessageXmlWithMetadataWithAllParametersExceptSubtitle() throws Exception { - String method = "SetAVTransportUri"; - String serviceURN = "http://serviceurn/"; - - String expectedXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + - "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " + - "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + - "<s:Body>" + - "<u:" + method + " xmlns:u=\"" + serviceURN + "\">" + - "<CurrentURIMetaData>" + - "<DIDL-Lite " + - "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " + - "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " + - "xmlns:sec=\"http://www.sec.co.kr/\" " + - "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" + - "<item id=\"1000\" parentID=\"0\" restricted=\"0\">" + - "<dc:title>&amp;\"title\"</dc:title>" + - "<dc:description>&amp;</dc:description>" + - "<res protocolInfo=\"http-get:*:audio/mpeg:DLNA.ORG_OP=01\">http://url/t&amp;t</res>" + - "<upnp:albumArtURI>http://host/image</upnp:albumArtURI>" + - "<upnp:class>object.item.audioItem</upnp:class>" + - "</item></DIDL-Lite>" + - "</CurrentURIMetaData>" + - "</u:" + method + "></s:Body></s:Envelope>"; - - String metadata = service.getMetadata("http://url/t&t", null, "audio/mpeg", "&\"title\"", "&", "http://host/image"); - Map<String, String> params = new LinkedHashMap<String, String>(); - params.put("CurrentURIMetaData", metadata); - - String actualXML = service.getMessageXml(serviceURN, method, null, params); - assertXMLEquals(expectedXML, actualXML); - } - - @Test - public void testGetMessageXmlWithMetadataWithAllParameters() throws Exception { - String method = "SetAVTransportUri"; - String serviceURN = "http://serviceurn/"; - String subtitleType = "text/vtt"; - String subtitleSubType = "vtt"; - SubtitleInfo subtitle = new SubtitleInfo.Builder("http://subtitleurl") - .setMimeType(subtitleType) - .setLabel("label") - .setLanguage("en") - .build(); - String mediaUrl = "http://mediaurl/"; - String mediaType = "audio/mp3"; - String title = "&\"title"; - String description = "description"; - String iconUrl = "http://iconurl/"; - - String expectedXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + - "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " + - "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + - "<s:Body>" + - "<u:" + method + " xmlns:u=\"" + serviceURN + "\">" + - "<CurrentURIMetaData>" + - "<DIDL-Lite " + - "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " + - "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " + - "xmlns:sec=\"http://www.sec.co.kr/\" " + - "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" + - "<item id=\"1000\" parentID=\"0\" restricted=\"0\">" + - "<dc:title>&amp;\"title</dc:title>" + - "<dc:description>description</dc:description>" + - "<res xmlns:pv=\"http://www.pv.com/pvns/\" " + - "protocolInfo=\"http-get:*:"+mediaType+":DLNA.ORG_OP=01\" " + - "pv:subtitleFileType=\""+subtitleSubType+"\" " + - "pv:subtitleFileUri=\""+subtitle.getUrl()+"\">"+mediaUrl+"</res>" + - "<upnp:albumArtURI>"+iconUrl+"</upnp:albumArtURI>" + - "<upnp:class>object.item.audioItem</upnp:class>" + - "<res protocolInfo=\"http-get:*:smi/caption\">"+subtitle.getUrl()+"</res>" + - "<res protocolInfo=\"http-get:*:"+subtitle.getMimeType()+":\">"+subtitle.getUrl()+"</res>" + - "<sec:CaptionInfoEx sec:type=\""+subtitleSubType+"\">"+subtitle.getUrl()+"</sec:CaptionInfoEx>" + - "<sec:CaptionInfo sec:type=\""+subtitleSubType+"\">"+subtitle.getUrl()+"</sec:CaptionInfo>" + - "</item></DIDL-Lite>" + - "</CurrentURIMetaData>" + - "</u:" + method + "></s:Body></s:Envelope>"; - - String metadata = service.getMetadata(mediaUrl, subtitle, mediaType, title, description, iconUrl); - Map<String, String> params = new LinkedHashMap<String, String>(); - params.put("CurrentURIMetaData", metadata); - - String actualXML = service.getMessageXml(serviceURN, method, null, params); - assertXMLEquals(expectedXML, actualXML); - } - - @Test - public void testGetMessageXmlWithMetadataWithSubtitleUrl() throws Exception { - String method = "SetAVTransportUri"; - String serviceURN = "http://serviceurn/"; - String subtitleType = "text/srt"; - String subtitleSubType = "srt"; - SubtitleInfo subtitle = new SubtitleInfo.Builder("http://subtitleurl") - .build(); - String mediaUrl = "http://mediaurl/"; - String mediaType = "audio/mp3"; - String title = "&\"title"; - String description = "description"; - String iconUrl = "http://iconurl/"; - - String expectedXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + - "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " + - "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + - "<s:Body>" + - "<u:" + method + " xmlns:u=\"" + serviceURN + "\">" + - "<CurrentURIMetaData>" + - "<DIDL-Lite " + - "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " + - "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " + - "xmlns:sec=\"http://www.sec.co.kr/\" " + - "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" + - "<item id=\"1000\" parentID=\"0\" restricted=\"0\">" + - "<dc:title>&amp;\"title</dc:title>" + - "<dc:description>description</dc:description>" + - "<res xmlns:pv=\"http://www.pv.com/pvns/\" " + - "protocolInfo=\"http-get:*:"+mediaType+":DLNA.ORG_OP=01\" " + - "pv:subtitleFileType=\""+subtitleSubType+"\" " + - "pv:subtitleFileUri=\""+subtitle.getUrl()+"\">"+mediaUrl+"</res>" + - "<upnp:albumArtURI>"+iconUrl+"</upnp:albumArtURI>" + - "<upnp:class>object.item.audioItem</upnp:class>" + - "<res protocolInfo=\"http-get:*:smi/caption\">"+subtitle.getUrl()+"</res>" + - "<res protocolInfo=\"http-get:*:"+subtitleType+":\">"+subtitle.getUrl()+"</res>" + - "<sec:CaptionInfoEx sec:type=\""+subtitleSubType+"\">"+subtitle.getUrl()+"</sec:CaptionInfoEx>" + - "<sec:CaptionInfo sec:type=\""+subtitleSubType+"\">"+subtitle.getUrl()+"</sec:CaptionInfo>" + - "</item></DIDL-Lite>" + - "</CurrentURIMetaData>" + - "</u:" + method + "></s:Body></s:Envelope>"; - - String metadata = service.getMetadata(mediaUrl, subtitle, mediaType, title, description, iconUrl); - Map<String, String> params = new LinkedHashMap<String, String>(); - params.put("CurrentURIMetaData", metadata); - - String actualXML = service.getMessageXml(serviceURN, method, null, params); - assertXMLEquals(expectedXML, actualXML); - } - - @Test - public void testGetMessageXmlWithMetadataWithRequiredParameters() throws Exception { - String method = "SetAVTransportUri"; - String serviceURN = "http://serviceurn/"; - - String expectedXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + - "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " + - "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + - "<s:Body>" + - "<u:" + method + " xmlns:u=\"" + serviceURN + "\">" + - "<CurrentURIMetaData>" + - "<DIDL-Lite " + - "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" " + - "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " + - "xmlns:sec=\"http://www.sec.co.kr/\" " + - "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" + - "<item id=\"1000\" parentID=\"0\" restricted=\"0\">" + - "<dc:title/>" + - "<dc:description/>" + - "<res protocolInfo=\"http-get:*:audio/mpeg:DLNA.ORG_OP=01\">http://url/t&amp;t</res>" + - "<upnp:albumArtURI/>" + - "<upnp:class>object.item.audioItem</upnp:class>" + - "</item></DIDL-Lite>" + - "</CurrentURIMetaData>" + - "</u:" + method + "></s:Body></s:Envelope>"; - - String metadata = service.getMetadata("http://url/t&t", null, "audio/mpeg", null, null, null); - Map<String, String> params = new LinkedHashMap<String, String>(); - params.put("CurrentURIMetaData", metadata); - - String actualXML = service.getMessageXml(serviceURN, method, null, params); - assertXMLEquals(expectedXML, actualXML); - } - - @Test - public void testUrlEncode() throws Exception { - String expected = "http://192.168.1.100:8000/ph&o't'o%20with%20symbols.jpg"; - String urlStr = "http://192.168.1.100:8000/ph&o't'o with symbols.jpg"; - Assert.assertEquals(expected, service.encodeURL(urlStr)); - } - - @Test - public void testUrlEncodeAlreadyEncoded() throws Exception { - String expected = "http://192.168.1.100:8000/ph&o't'o%20with%20symbols.jpg"; - String urlStr = "http://192.168.1.100:8000/ph&o't'o%20with%20symbols.jpg"; - Assert.assertEquals(expected, service.encodeURL(urlStr)); - } - - @Test - public void testNullUrlEncode() throws Exception { - Assert.assertEquals("", service.encodeURL(null)); - } - - - @Test - public void testEmptyUrlEncode() throws Exception { - Assert.assertEquals("", service.encodeURL("")); - } - - @Test - public void testServiceControlURL() { - DLNAService dlnaService = makeServiceWithControlURL("http://192.168.1.0/", "/controlURL"); - Assert.assertEquals("http://192.168.1.0/controlURL", dlnaService.avTransportURL); - } - - @Test - public void testServiceControlURLWithWrongBase() { - DLNAService dlnaService = makeServiceWithControlURL("http://192.168.1.0", "/controlURL"); - Assert.assertEquals("http://192.168.1.0/controlURL", dlnaService.avTransportURL); - } - - @Test - public void testServiceControlURLWithWrongControlURL() { - DLNAService dlnaService = makeServiceWithControlURL("http://192.168.1.0/", "controlURL"); - Assert.assertEquals("http://192.168.1.0/controlURL", dlnaService.avTransportURL); - } - - @Test - public void testServiceControlURLWithWrongBaseAndControlURL() { - DLNAService dlnaService = makeServiceWithControlURL("http://192.168.1.0", "controlURL"); - Assert.assertEquals("http://192.168.1.0/controlURL", dlnaService.avTransportURL); - } - - @Test - public void testInitialPairingType() { - Assert.assertEquals(DeviceService.PairingType.NONE, service.getPairingType()); - } - - @Test - public void testPairingTypeSetter() { - service.setPairingType(DeviceService.PairingType.PIN_CODE); - Assert.assertEquals(DeviceService.PairingType.NONE, service.getPairingType()); - } - - @Test - public void testTimeToLongNullValue() { - Assert.assertEquals(0L, service.convertStrTimeFormatToLong(null)); - } - - @Test - public void testTimeToLongWrongValue() { - Assert.assertEquals(0L, service.convertStrTimeFormatToLong("abc")); - } - - @Test - public void testTimeToLongZeroValue() { - Assert.assertEquals(0L, service.convertStrTimeFormatToLong("00:00:00")); - } - - @Test - public void testTimeToLong() { - Assert.assertEquals(10000L, service.convertStrTimeFormatToLong("00:00:10")); - } - - @Test - public void testTimeToLong12Hours() { - Assert.assertEquals(43200000L, service.convertStrTimeFormatToLong("12:00:00")); - } - - @Test - public void testTimeToLong20Hours() { - Assert.assertEquals(72000000L, service.convertStrTimeFormatToLong("20:00:00")); - } - - @Test - public void testTimeToLongBigValue() { - Assert.assertEquals(432000000L, service.convertStrTimeFormatToLong("120:00:00")); - } - - @Test - public void testStopDLNAServerOnDisconnect() { - service.disconnect(); - TestUtil.runUtilBackgroundTasks(); - Mockito.verify(dlnaServer).stop(); - } - - @Test - public void testTimeToLongWithMilliseconds() { - Assert.assertEquals(43200000L, service.convertStrTimeFormatToLong("12:00:00.777")); - } - - @Test - public void testTimeToLongWithInvalidArguments() { - try { - Assert.assertEquals(0L, service.convertStrTimeFormatToLong("01.210")); - Assert.assertEquals(0L, service.convertStrTimeFormatToLong("00:01.210")); - Assert.assertEquals(0L, service.convertStrTimeFormatToLong("Not a number")); - } catch (Exception e) { - Assert.fail("convertStrTimeFormatToLong must not throw an exception"); - } - } - - @Test - public void testMakeControlURL() { - Assert.assertEquals("base/path", service.makeControlURL("base/", "path")); - } - - @Test - public void testMakeControlURLWithNullBase() { - Assert.assertNull(service.makeControlURL(null, "path")); - } - - @Test - public void testMakeControlURLWithNullPath() { - Assert.assertNull(service.makeControlURL("base", null)); - } - - private DLNAService makeServiceWithControlURL(String base, String controlURL) { - List<Service> services = new ArrayList<Service>(); - Service service = new Service(); - service.baseURL = base; - service.controlURL = controlURL; - service.serviceType = DLNAService.AV_TRANSPORT; - services.add(service); - - ServiceDescription description = Mockito.mock(ServiceDescription.class); - Mockito.when(description.getServiceList()).thenReturn(services); - return new DLNAService(description, Mockito.mock(ServiceConfig.class), Robolectric.application, null); - } - - private void assertXMLEquals(String expectedXML, String actualXML) throws SAXException, IOException { - XMLUnit.setIgnoreWhitespace(true); - XMLUnit.setIgnoreAttributeOrder(true); - XMLUnit.setNormalize(true); - DetailedDiff diff = new DetailedDiff(XMLUnit.compareXML(expectedXML, actualXML)); - List<?> allDifferences = diff.getAllDifferences(); - Assert.assertEquals("XML differences found: " + diff.toString(), 0, allDifferences.size()); - } -} diff --git a/test/src/com/connectsdk/service/NetCastTVServiceTest.java b/test/src/com/connectsdk/service/NetCastTVServiceTest.java deleted file mode 100644 index c481a430..00000000 --- a/test/src/com/connectsdk/service/NetCastTVServiceTest.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.connectsdk.service; - -import com.connectsdk.discovery.DiscoveryManager; -import com.connectsdk.service.capability.CapabilityMethods; -import com.connectsdk.service.capability.MediaControl; -import com.connectsdk.service.capability.MediaPlayer; -import com.connectsdk.service.capability.listeners.ResponseListener; -import com.connectsdk.service.command.NotSupportedServiceCommandError; -import com.connectsdk.service.command.ServiceCommand; -import com.connectsdk.service.command.ServiceCommandError; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class NetCastTVServiceTest { - - private NetcastTVService service; - - private ServiceDescription serviceDescription; - - private ServiceConfig serviceConfig; - - @Before - public void setUp() { - serviceDescription = Mockito.mock(ServiceDescription.class); - Mockito.when(serviceDescription.getModelNumber()).thenReturn("4.0"); - serviceConfig = Mockito.mock(ServiceConfig.class); - service = new NetcastTVService(serviceDescription, serviceConfig); - } - - @Test - public void testDecToHex() { - Assert.assertEquals("0000000000000010", service.decToHex("16")); - } - - @Test - public void testDecToHexWithNullArgument() { - Assert.assertEquals(null, service.decToHex(null)); - } - - @Test - public void testDecToHexWithEmptyArgument() { - Assert.assertEquals(null, service.decToHex("")); - } - - @Test - public void testDecToHexWithWrongArgument() { - Assert.assertEquals(null, service.decToHex("Not a number")); - } - - @Test - public void testDecToHexWithWrongCharactersArgument() { - Assert.assertEquals("0000000000000010", service.decToHex(" 16\r\n")); - } - - @Test - public void testServiceShouldHasSubtitleCapabilityWhenPairingLevelOn() { - setPairingLevel(DiscoveryManager.PairingLevel.OFF); - Assert.assertTrue(service.hasCapability(MediaPlayer.Subtitle_SRT)); - } - - @Test - public void testServiceShouldHasSubtitleCapabilityWhenPairingLevelOff() { - setPairingLevel(DiscoveryManager.PairingLevel.ON); - Assert.assertTrue(service.hasCapability(MediaPlayer.Subtitle_SRT)); - } - - @Test - public void testShouldNotContainRewindCapabilityWhenPairingLevelOff() { - setPairingLevel(DiscoveryManager.PairingLevel.OFF); - Assert.assertFalse(service.hasCapability(MediaControl.Rewind)); - } - - @Test - public void testShouldNotContainRewindCapabilityWhenPairingLevelOn() { - setPairingLevel(DiscoveryManager.PairingLevel.ON); - Assert.assertFalse(service.hasCapability(MediaControl.Rewind)); - } - - @Test - public void testShouldNotContainFastForwardCapabilityWhenPairingLevelOff() { - setPairingLevel(DiscoveryManager.PairingLevel.OFF); - Assert.assertFalse(service.hasCapability(MediaControl.FastForward)); - } - - @Test - public void testShouldNotContainFastForwardCapabilityWhenPairingLevelOn() { - setPairingLevel(DiscoveryManager.PairingLevel.ON); - Assert.assertFalse(service.hasCapability(MediaControl.FastForward)); - } - - @Test - public void testRewindShouldSendNotSupportedError() { - ResponseListener<Object> listener = Mockito.mock(ResponseListener.class); - service.rewind(listener); - verifyNotImplemented(listener); - } - - @Test - public void testFastForwardShouldSendNotSupportedError() { - ResponseListener<Object> listener = Mockito.mock(ResponseListener.class); - service.fastForward(listener); - verifyNotImplemented(listener); - } - - @Test - public void testMediaPlayerPriorityShouldBeHigh() { - Assert.assertEquals(CapabilityMethods.CapabilityPriorityLevel.HIGH, - service.getMediaPlayerCapabilityLevel()); - } - - @Test - public void testMediaControlPriorityShouldBeHigh() { - Assert.assertEquals(CapabilityMethods.CapabilityPriorityLevel.HIGH, - service.getMediaControlCapabilityLevel()); - } - - private void verifyNotImplemented(ResponseListener<Object> listener) { - ArgumentCaptor<ServiceCommandError> argError - = ArgumentCaptor.forClass(ServiceCommandError.class); - Mockito.verify(listener).onError(argError.capture()); - Assert.assertTrue(argError.getValue() instanceof NotSupportedServiceCommandError); - } - - private void setPairingLevel(DiscoveryManager.PairingLevel level) { - DiscoveryManager.init(Robolectric.application); - DiscoveryManager.getInstance().setPairingLevel(level); - } - -} diff --git a/test/src/com/connectsdk/service/RokuServiceTest.java b/test/src/com/connectsdk/service/RokuServiceTest.java deleted file mode 100644 index c001ff21..00000000 --- a/test/src/com/connectsdk/service/RokuServiceTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * RokuServiceTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 16 Jul 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.connectsdk.service; - -import com.connectsdk.core.MediaInfo; -import com.connectsdk.core.TestUtil; -import com.connectsdk.service.capability.MediaPlayer; -import com.connectsdk.service.command.ServiceCommand; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class RokuServiceTest { - - private StubRokuService service; - private ServiceDescription serviceDescription; - - class StubRokuService extends RokuService { - - private Object response; - private ServiceCommand<?> mLatestCommand; - - public StubRokuService(ServiceDescription serviceDescription, ServiceConfig serviceConfig) { - super(serviceDescription, serviceConfig); - } - - public void setResponse(Object response) { - this.response = response; - } - - @Override - public void sendCommand(ServiceCommand<?> serviceCommand) { - mLatestCommand = serviceCommand; - serviceCommand.getResponseListener().onSuccess(response); - } - - } - - @Before - public void setUp() { - serviceDescription = Mockito.mock(ServiceDescription.class); - Mockito.when(serviceDescription.getIpAddress()).thenReturn("127.0.0.1"); - Mockito.when(serviceDescription.getPort()).thenReturn(13); - - ServiceConfig serviceConfig = Mockito.mock(ServiceConfig.class); - service = new StubRokuService(serviceDescription, serviceConfig); - - MediaPlayer.MediaLaunchObject response = Mockito.mock(MediaPlayer.MediaLaunchObject.class); - service.setResponse(response); - } - - @Test - public void testServiceNotNull() { - Assert.assertNotNull(service); - } - - @Test - public void testPlayVideoShouldSendHTTPRequestWithCorrectURL() { - playMedia("url", "video/mp4", "title", "description"); - - Assert.assertTrue( - TestUtil.compareUrls( - "http://127.0.0.1:13/input/15985?t=v&u=url&k=(null)&videoName=title&videoFormat=mp4" - , service.mLatestCommand.getTarget()) - ); - } - - @Test - public void testPlayAudioShouldSendHTTPRequestWithCorrectURL() { - playMedia("url", "audio/mp3", "title", "description"); - - Assert.assertTrue( - TestUtil.compareUrls( - "http://127.0.0.1:13/input/15985?t=a&u=url&k=(null)&songname=title" + - "&artistname=description&songformat=mp3&albumarturl=(null)", - service.mLatestCommand.getTarget())); - } - - @Test - public void testDisplayImageShouldSendHTTPRequestWithCorrectURL() { - MediaInfo mediaInfo = new MediaInfo("url", "image/jpeg", "title", "description"); - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - service.displayImage(mediaInfo, listener); - - Assert.assertTrue( - TestUtil.compareUrls("http://127.0.0.1:13/input/15985?t=p&u=url&tr=crossfade", - service.mLatestCommand.getTarget())); - } - - - private void playMedia(String url, String mimeType, String title, String description) { - MediaInfo mediaInfo = new MediaInfo(url, mimeType, title, description); - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - service.playMedia(mediaInfo, false, listener); - } - -} diff --git a/test/src/com/connectsdk/service/WebOSTVServiceTest.java b/test/src/com/connectsdk/service/WebOSTVServiceTest.java deleted file mode 100644 index 5ec94662..00000000 --- a/test/src/com/connectsdk/service/WebOSTVServiceTest.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * WebOSTVServiceTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 27 May 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.connectsdk.service; - -import com.connectsdk.core.ChannelInfo; -import com.connectsdk.core.MediaInfo; -import com.connectsdk.core.SubtitleInfo; -import com.connectsdk.device.ConnectableDevice; -import com.connectsdk.discovery.DiscoveryManager; -import com.connectsdk.service.capability.Launcher; -import com.connectsdk.service.capability.MediaPlayer; -import com.connectsdk.service.capability.ToastControl; -import com.connectsdk.service.capability.listeners.ResponseListener; -import com.connectsdk.service.command.NotSupportedServiceCommandError; -import com.connectsdk.service.command.ServiceCommand; -import com.connectsdk.service.command.ServiceCommandError; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; -import com.connectsdk.service.sessions.LaunchSession; -import com.connectsdk.service.sessions.WebOSWebAppSession; -import com.connectsdk.service.webos.WebOSTVServiceSocketClient; - -import junit.framework.Assert; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) -public class WebOSTVServiceTest { - - private WebOSTVService service; - - private ServiceDescription serviceDescription; - - private WebOSTVServiceSocketClient socket; - - @Before - public void setUp() { - serviceDescription = Mockito.mock(ServiceDescription.class); - Map<String, List<String>> headers = new HashMap<String, List<String>>(); - Mockito.when(serviceDescription.getVersion()).thenReturn("5.0.0"); - Mockito.when(serviceDescription.getResponseHeaders()).thenReturn(headers); - service = new WebOSTVService(serviceDescription, Mockito.mock(ServiceConfig.class)); - this.socket = Mockito.mock(WebOSTVServiceSocketClient.class); - service.socket = this.socket; - Mockito.when(socket.isConnected()).thenReturn(Boolean.TRUE); - } - - @After - public void tearDown() { - DiscoveryManager.getInstance().getAllDevices().clear(); - } - - @Test - public void testCapabilitiesShouldContainToastControlWhenPairingOn() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.ON); - service.updateCapabilities(); - - Assert.assertTrue(service.hasCapabilities(ToastControl.Capabilities)); - } - - @Test - public void testCapabilitiesShouldNotContainToastControlWhenPairingOff() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.OFF); - service.updateCapabilities(); - - Assert.assertFalse(service.hasCapabilities(ToastControl.Capabilities)); - } - - @Test - public void testCapabilitiesShouldContainSubtitlesForWebOsWithWebAppSupport() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.OFF); - setWebOSVersion("5.0.0"); - - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_SRT)); - Assert.assertTrue(service.hasCapabilities(MediaPlayer.Subtitle_WebVTT)); - } - - @Test - public void testCapabilitiesShouldContainOnlySrtSubtitlesForWebOsWithDLNA() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.OFF); - injectDLNAService(); - setWebOSVersion("4.0.0"); - - Assert.assertTrue(service.hasCapabilities(MediaPlayer.Subtitle_SRT)); - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_WebVTT)); - } - - @Test - public void testCapabilitiesShouldNotContainSubtitlesForWebOsV4() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.OFF); - setWebOSVersion("4.0.0"); - - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_SRT)); - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_WebVTT)); - } - - @Test - public void testCapabilitiesShouldContainSubtitlesForWebOsWithWebAppSupportAndPairingOn() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.ON); - setWebOSVersion("5.0.0"); - - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_SRT)); - Assert.assertTrue(service.hasCapabilities(MediaPlayer.Subtitle_WebVTT)); - } - - @Test - public void testCapabilitiesShouldContainOnlySrtSubtitlesForWebOsWithDLNAAndPairingOn() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.ON); - injectDLNAService(); - setWebOSVersion("4.0.0"); - - Assert.assertTrue(service.hasCapabilities(MediaPlayer.Subtitle_SRT)); - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_WebVTT)); - } - - @Test - public void testCapabilitiesShouldNotContainSubtitlesForWebOsV4AndPairingOn() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.ON); - setWebOSVersion("4.0.0"); - - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_SRT)); - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_WebVTT)); - } - - @Test - public void testCapabilitiesShouldContainSubtitlesForWebOsWithWebAppSupportAndDLNA() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.OFF); - injectDLNAService(); - setWebOSVersion("5.0.0"); - - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_SRT)); - Assert.assertTrue(service.hasCapabilities(MediaPlayer.Subtitle_WebVTT)); - } - - @Test - public void testCapabilitiesShouldContainSubtitlesForWebOsWithWebAppSupportAndDLNAPairingOn() { - DiscoveryManager.getInstance().setPairingLevel(DiscoveryManager.PairingLevel.ON); - injectDLNAService(); - setWebOSVersion("5.0.0"); - - Assert.assertFalse(service.hasCapabilities(MediaPlayer.Subtitle_SRT)); - Assert.assertTrue(service.hasCapabilities(MediaPlayer.Subtitle_WebVTT)); - } - - @Test - public void testJumpToTrack() { - ResponseListener<Object> listener = Mockito.mock(ResponseListener.class); - service.jumpToTrack(1, listener); - Mockito.verify(listener).onError(Mockito.isA(NotSupportedServiceCommandError.class)); - } - - @Test - public void testNext() { - ResponseListener<Object> listener = Mockito.mock(ResponseListener.class); - service.next(listener); - Mockito.verify(listener).onError(Mockito.isA(NotSupportedServiceCommandError.class)); - } - - @Test - public void testPrevious() { - ResponseListener<Object> listener = Mockito.mock(ResponseListener.class); - service.previous(listener); - Mockito.verify(listener).onError(Mockito.isA(NotSupportedServiceCommandError.class)); - } - - @Test - public void testLaunchInputPickerForOldTV() throws JSONException { - Launcher.AppLaunchListener listener = Mockito.mock(Launcher.AppLaunchListener.class); - service.launchInputPicker(listener); - - ArgumentCaptor<ServiceCommand> argCommand = ArgumentCaptor.forClass(ServiceCommand.class); - Mockito.verify(socket).sendCommand(argCommand.capture()); - ServiceCommand command = argCommand.getValue(); - command.getResponseListener().onSuccess(new JSONObject()); - - Mockito.verify(listener).onSuccess(Mockito.any(LaunchSession.class)); - JSONObject payload = (JSONObject)command.getPayload(); - Assert.assertEquals("com.webos.app.inputpicker", payload.getString("id")); - } - - @Test - public void testLaunchInputPickerForNewTV() throws JSONException { - Launcher.AppLaunchListener listener = Mockito.mock(Launcher.AppLaunchListener.class); - service.launchInputPicker(listener); - - ArgumentCaptor<ServiceCommand> argCommand = ArgumentCaptor.forClass(ServiceCommand.class); - Mockito.verify(socket).sendCommand(argCommand.capture()); - - ServiceCommand command = argCommand.getValue(); - command.getResponseListener().onError(new ServiceCommandError()); - - argCommand = ArgumentCaptor.forClass(ServiceCommand.class); - Mockito.verify(socket, Mockito.times(2)).sendCommand(argCommand.capture()); - command = argCommand.getValue(); - command.getResponseListener().onSuccess(new JSONObject()); - - Mockito.verify(listener).onSuccess(Mockito.any(LaunchSession.class)); - JSONObject payload = (JSONObject)command.getPayload(); - Assert.assertEquals("com.webos.app.inputmgr", payload.getString("id")); - } - - @Test - public void testLaunchInputPickerForNewTVFailure() throws JSONException { - Launcher.AppLaunchListener listener = Mockito.mock(Launcher.AppLaunchListener.class); - service.launchInputPicker(listener); - - ArgumentCaptor<ServiceCommand> argCommand = ArgumentCaptor.forClass(ServiceCommand.class); - Mockito.verify(socket).sendCommand(argCommand.capture()); - ServiceCommand command = argCommand.getValue(); - command.getResponseListener().onError(new ServiceCommandError()); - - argCommand = ArgumentCaptor.forClass(ServiceCommand.class); - Mockito.verify(socket, Mockito.times(2)).sendCommand(argCommand.capture()); - command = argCommand.getValue(); - command.getResponseListener().onError(new ServiceCommandError()); - - Mockito.verify(listener).onError(Mockito.any(ServiceCommandError.class)); - } - - @Test - public void testPlayMediaDeprecatedWithRequiredParametersOnTheLatestWebOS() { - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - WebOSWebAppSession webAppSession = Mockito.mock(WebOSWebAppSession.class); - service.mWebAppSessions.put("MediaPlayer", webAppSession); - - MediaInfo mediaInfo = new MediaInfo.Builder("url", "mimetype").build(); - boolean shouldLoop = true; - service.playMedia(mediaInfo.getUrl(), mediaInfo.getMimeType(), null, null, null, - shouldLoop, listener); - - verifyPlayMediaOnTheLatestWebOS(mediaInfo, shouldLoop, listener, webAppSession); - } - - @Test - public void testPlayMediaDeprecatedWithAllParametersOnTheLatestWebOS() { - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - WebOSWebAppSession webAppSession = Mockito.mock(WebOSWebAppSession.class); - service.mWebAppSessions.put("MediaPlayer", webAppSession); - - MediaInfo mediaInfo = new MediaInfo.Builder("url", "mimetype") - .setTitle("title") - .setDescription("description") - .setIcon("icon") - .build(); - boolean shouldLoop = true; - service.playMedia(mediaInfo.getUrl(), mediaInfo.getMimeType(), mediaInfo.getTitle(), - mediaInfo.getDescription(), mediaInfo.getImages().get(0).getUrl(), shouldLoop, - listener); - - verifyPlayMediaOnTheLatestWebOS(mediaInfo, shouldLoop, listener, webAppSession); - } - - @Test - public void testPlayMediaWithRequiredParametersOnTheLatestWebOS() { - MediaInfo mediaInfo = createBasicMediaInfo(); - callAndVerifyPlayMediaOnTheLatestWebOS(mediaInfo, false); - } - - @Test - public void testPlayMediaWithSubtitlesOnTheLatestWebOS() { - MediaInfo mediaInfo = createMediaInfoWithSubtitles(); - callAndVerifyPlayMediaOnTheLatestWebOS(mediaInfo, true); - } - - @Test - public void testPlayMediaWithRequiredParametersOnTheWebOSV4AndDlna() { - MediaInfo mediaInfo = createBasicMediaInfo(); - verifyPlayMediaOnTheWebOSV4(mediaInfo, false); - } - - @Test - public void testPlayMediaWithSubtitlesOnTheWebOSV4AndDlna() { - MediaInfo mediaInfo = createMediaInfoWithSubtitles(); - verifyPlayMediaOnTheWebOSV4(mediaInfo, false); - } - - @Test - public void testPlayMediaWithRequiredParametersOnTheWebOSV4WithoutDlna() throws JSONException { - MediaInfo mediaInfo = createMediaInfoWithSubtitles(); - verifyPlayMediaOnTheWebOSV4WithoutDlna(mediaInfo, false); - } - - @Test - public void testSetChannelWithIdArgument() throws JSONException { - ChannelInfo channelInfo = new ChannelInfo(); - channelInfo.setId("id"); - - JSONObject payload = verifySetChannel(channelInfo); - Assert.assertEquals("id", payload.getString("channelId")); - Assert.assertFalse(payload.has("channelNumber")); - } - - @Test - public void testSetChannelWithNumberArgument() throws JSONException { - ChannelInfo channelInfo = new ChannelInfo(); - channelInfo.setNumber("number"); - - JSONObject payload = verifySetChannel(channelInfo); - Assert.assertEquals("number", payload.getString("channelNumber")); - Assert.assertFalse(payload.has("channelId")); - } - - @Test - public void testSetChannelWithIdAndNumberArguments() throws JSONException { - ChannelInfo channelInfo = new ChannelInfo(); - channelInfo.setNumber("number"); - channelInfo.setId("id"); - - JSONObject payload = verifySetChannel(channelInfo); - Assert.assertEquals("number", payload.getString("channelNumber")); - Assert.assertEquals("id", payload.getString("channelId")); - } - - @Test - public void testSetChannelWithEmptyArguments() throws JSONException { - ChannelInfo channelInfo = new ChannelInfo(); - - JSONObject payload = verifySetChannel(channelInfo); - Assert.assertEquals(0, payload.length()); - } - - @Test(expected = NullPointerException.class) - public void testSetChannelWithNullChannelInfo() throws JSONException { - JSONObject payload = verifySetChannel(null); - Assert.assertEquals(0, payload.length()); - } - - private JSONObject verifySetChannel(ChannelInfo channelInfo) { - ResponseListener<Object> response = Mockito.mock(ResponseListener.class); - ArgumentCaptor<ServiceCommand> argCommand = ArgumentCaptor.forClass(ServiceCommand.class); - - service.setChannel(channelInfo, response); - Mockito.verify(socket).sendCommand(argCommand.capture()); - ServiceCommand command = argCommand.getValue(); - JSONObject payload = (JSONObject) command.getPayload(); - Assert.assertEquals("ssap://tv/openChannel", command.getTarget()); - return payload; - } - - - private MediaInfo createBasicMediaInfo() { - return new MediaInfo.Builder("http://media", "video/mp4").build(); - } - - private MediaInfo createMediaInfoWithSubtitles() { - SubtitleInfo subtitle = new SubtitleInfo.Builder("http://subtitle") - .build(); - - return new MediaInfo.Builder("http://media", "video/mp4") - .setTitle("title") - .setDescription("description") - .setIcon("icon") - .setSubtitleInfo(subtitle) - .build(); - } - - private void verifyPlayMediaOnTheWebOSV4WithoutDlna(MediaInfo mediaInfo, boolean shouldLoop) throws JSONException { - Mockito.when(serviceDescription.getVersion()).thenReturn("4.0.0"); - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - - service.playMedia(mediaInfo, shouldLoop, listener); - - ArgumentCaptor<ServiceCommand> argCommand = ArgumentCaptor.forClass(ServiceCommand.class); - Mockito.verify(socket).sendCommand(argCommand.capture()); - - ServiceCommand command = argCommand.getValue(); - JSONObject payload = (JSONObject) command.getPayload(); - - Assert.assertEquals("ssap://media.viewer/open", command.getTarget()); - Assert.assertEquals(mediaInfo.getUrl(), payload.getString("target")); - Assert.assertEquals(mediaInfo.getTitle(), payload.getString("title")); - Assert.assertEquals(mediaInfo.getDescription(), payload.getString("description")); - Assert.assertEquals(mediaInfo.getMimeType(), payload.getString("mimeType")); - Assert.assertEquals(shouldLoop, payload.getBoolean("loop")); - - Assert.assertEquals(mediaInfo.getImages().get(0).getUrl(), payload.getString("iconSrc")); - } - - private void verifyPlayMediaOnTheWebOSV4(MediaInfo mediaInfo, boolean shouldLoop) { - Mockito.when(serviceDescription.getVersion()).thenReturn("4.0.0"); - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - - DLNAService dlnaService = injectDLNAService(); - MediaPlayer mediaPlayer = Mockito.mock(MediaPlayer.class); - Mockito.when(dlnaService.getAPI(MediaPlayer.class)).thenReturn(mediaPlayer); - - service.playMedia(mediaInfo, shouldLoop, listener); - - ArgumentCaptor<MediaInfo> argMediaInfo = ArgumentCaptor.forClass(MediaInfo.class); - ArgumentCaptor<Boolean> argShouldLoop = ArgumentCaptor.forClass(Boolean.class); - Mockito.verify(mediaPlayer).playMedia(argMediaInfo.capture(), argShouldLoop.capture(), - Mockito.same(listener)); - - MediaInfo capturedMediaInfo = argMediaInfo.getValue(); - Assert.assertEquals(mediaInfo.getDescription(), capturedMediaInfo.getDescription()); - Assert.assertEquals(mediaInfo.getMimeType(), capturedMediaInfo.getMimeType()); - Assert.assertEquals(mediaInfo.getTitle(), capturedMediaInfo.getTitle()); - Assert.assertEquals(mediaInfo.getUrl(), capturedMediaInfo.getUrl()); - Assert.assertEquals(mediaInfo.getImages(), capturedMediaInfo.getImages()); - Assert.assertEquals(mediaInfo.getSubtitleInfo(), capturedMediaInfo.getSubtitleInfo()); - Assert.assertEquals(shouldLoop, argShouldLoop.getValue().booleanValue()); - } - - private void callAndVerifyPlayMediaOnTheLatestWebOS(final MediaInfo mediaInfo, boolean shouldLoop) { - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - WebOSWebAppSession webAppSession = Mockito.mock(WebOSWebAppSession.class); - service.mWebAppSessions.put("MediaPlayer", webAppSession); - - service.playMedia(mediaInfo, shouldLoop, listener); - verifyPlayMediaOnTheLatestWebOS(mediaInfo, shouldLoop, listener, webAppSession); - } - - private void verifyPlayMediaOnTheLatestWebOS(MediaInfo mediaInfo, boolean shouldLoop, MediaPlayer.LaunchListener listener, WebOSWebAppSession webAppSession) { - // should try to join to the web app - ArgumentCaptor<ResponseListener> argListener = ArgumentCaptor.forClass(ResponseListener - .class); - Mockito.verify(webAppSession).join(argListener.capture()); - - // run join success - ResponseListener webAppListener = argListener.getValue(); - webAppListener.onSuccess(null); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - - // should delegate playing media to the WebAppSession - ArgumentCaptor<MediaInfo> argMediaInfo = ArgumentCaptor.forClass(MediaInfo.class); - ArgumentCaptor<Boolean> argShouldLoop = ArgumentCaptor.forClass(Boolean.class); - Mockito.verify(webAppSession).playMedia(argMediaInfo.capture(), argShouldLoop.capture(), - Mockito.same(listener)); - - MediaInfo capturedMediaInfo = argMediaInfo.getValue(); - Assert.assertEquals(mediaInfo.getDescription(), capturedMediaInfo.getDescription()); - Assert.assertEquals(mediaInfo.getMimeType(), capturedMediaInfo.getMimeType()); - Assert.assertEquals(mediaInfo.getTitle(), capturedMediaInfo.getTitle()); - Assert.assertEquals(mediaInfo.getUrl(), capturedMediaInfo.getUrl()); - Assert.assertEquals(mediaInfo.getImages(), capturedMediaInfo.getImages()); - Assert.assertEquals(mediaInfo.getSubtitleInfo(), capturedMediaInfo.getSubtitleInfo()); - Assert.assertEquals(shouldLoop, argShouldLoop.getValue().booleanValue()); - } - - private DLNAService injectDLNAService() { - DLNAService dlnaService = Mockito.mock(DLNAService.class); - ConnectableDevice dlnaDevice = Mockito.mock(ConnectableDevice.class); - Mockito.when(dlnaDevice.getServiceByName(DLNAService.ID)).thenReturn(dlnaService); - String ipAddress = "127.0.0.1"; - DiscoveryManager.getInstance().getAllDevices().put(ipAddress, dlnaDevice); - Mockito.when(serviceDescription.getIpAddress()).thenReturn(ipAddress); - return dlnaService; - } - - private void setWebOSVersion(String version) { - Map<String, List<String>> headers = new HashMap<String, List<String>>(); - headers.put("Server", Arrays.asList("server/" + version + " server")); - ServiceDescription serviceDescription = new ServiceDescription(); - serviceDescription.setIpAddress("127.0.0.1"); - serviceDescription.setResponseHeaders(headers); - service.setServiceDescription(serviceDescription); - } -} diff --git a/test/src/com/connectsdk/service/airplay/PListParserTest.java b/test/src/com/connectsdk/service/airplay/PListParserTest.java deleted file mode 100644 index 91ff685e..00000000 --- a/test/src/com/connectsdk/service/airplay/PListParserTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * PListParserTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 19 Mar 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.connectsdk.service.airplay; - -import junit.framework.Assert; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; - - -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) -public class PListParserTest { - - @Test - public void testSimplePlistParsing() throws JSONException, XmlPullParserException, IOException { - String rawString = "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " + - "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" + - "<plist version=\"1.0\">\n" + - "<dict>\n" + - "\t<key>duration</key>\n" + - "\t<real>52.209000000000003</real>\n" + - "\t<key>loadedTimeRanges</key>\n" + - "\t<array>\n" + - "\t\t<dict>\n" + - "\t\t\t<key>duration</key>\n" + - "\t\t\t<real>52.209000000000003</real>\n" + - "\t\t\t<key>start</key>\n" + - "\t\t\t<real>0.0</real>\n" + - "\t\t</dict>\n" + - "\t</array>\n" + - "\t<key>playbackBufferEmpty</key>\n" + - "\t<true/>\n" + - "\t<key>playbackBufferFull</key>\n" + - "\t<false/>\n" + - "\t<key>playbackLikelyToKeepUp</key>\n" + - "\t<true/>\n" + - "\t<key>position</key>\n" + - "\t<real>4.6505421629999999</real>\n" + - "\t<key>rate</key>\n" + - "\t<real>1</real>\n" + - "\t<key>readyToPlay</key>\n" + - "\t<true/>\n" + - "\t<key>seekableTimeRanges</key>\n" + - "\t<array>\n" + - "\t\t<dict>\n" + - "\t\t\t<key>duration</key>\n" + - "\t\t\t<real>52.209000000000003</real>\n" + - "\t\t\t<key>start</key>\n" + - "\t\t\t<real>0.0</real>\n" + - "\t\t</dict>\n" + - "\t</array>\n" + - "\t<key>stallCount</key>\n" + - "\t<integer>0</integer>\n" + - "\t<key>uuid</key>\n" + - "\t<string>D6E86A89-82F0-41F5-B680-B27AB83656F6-25-0000000E81A3E1CF</string>\n" + - "</dict>\n" + - "</plist>\n"; - - JSONObject json = new PListParser().parse(rawString); - Assert.assertTrue(json.has("duration")); - Assert.assertTrue(json.has("loadedTimeRanges")); - Assert.assertTrue(json.has("playbackBufferEmpty")); - Assert.assertTrue(json.has("playbackBufferFull")); - Assert.assertTrue(json.has("playbackLikelyToKeepUp")); - Assert.assertTrue(json.has("position")); - Assert.assertTrue(json.has("rate")); - Assert.assertTrue(json.has("readyToPlay")); - Assert.assertTrue(json.has("seekableTimeRanges")); - Assert.assertTrue(json.has("uuid")); - Assert.assertTrue(json.has("rate")); - Assert.assertTrue(json.getJSONArray("seekableTimeRanges").getJSONObject(0).has("start")); - - Assert.assertEquals(1, json.getInt("rate")); - Assert.assertEquals("D6E86A89-82F0-41F5-B680-B27AB83656F6-25-0000000E81A3E1CF", - json.getString("uuid")); - } - - @Test - public void testHLSPlistParsing() throws JSONException, XmlPullParserException, IOException { - String rawString = "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " + - "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" + - " <plist version=\"1.0\">\n" + - " <dict>\n" + - " <key>duration</key>\n" + - " <real>0.0</real>\n" + - " <key>estimatedDate</key>\n" + - " <date>2015-07-14T17:55:59Z</date>\n" + - " <key>loadedTimeRanges</key>\n" + - " <array>\n" + - " <dict>\n" + - " <key>duration</key>\n" + - " <real>15.952108843537415</real>\n" + - " <key>start</key>\n" + - " <real>0.0</real>\n" + - " </dict>\n" + - " </array>\n" + - " <key>playbackBufferEmpty</key>\n" + - " <true/>\n" + - " <key>playbackBufferFull</key>\n" + - " <false/>\n" + - " <key>playbackLikelyToKeepUp</key>\n" + - " <true/>\n" + - " <key>position</key>\n" + - " <real>3.4013898230000001</real>\n" + - " <key>rate</key>\n" + - " <real>1</real>\n" + - " <key>readyToPlay</key>\n" + - " <true/>\n" + - " <key>seekableTimeRanges</key>\n" + - " <array>\n" + - " <dict>\n" + - " <key>duration</key>\n" + - " <real>0.0</real>\n" + - " <key>start</key>\n" + - " <real>0.0</real>\n" + - " </dict>\n" + - " </array>\n" + - " <key>stallCount</key>\n" + - " <integer>0</integer>\n" + - " <key>uuid</key>\n" + - " <string>792FE533-1CC6-474B-84BD-A0D3D9081626-40-00001A5906010248</string>\n" + - " </dict>\n" + - " </plist>"; - - JSONObject json = new PListParser().parse(rawString); - Assert.assertTrue(json.has("loadedTimeRanges")); - Assert.assertEquals(1, json.getInt("rate")); - Assert.assertTrue(json.getBoolean("readyToPlay")); - Assert.assertEquals("792FE533-1CC6-474B-84BD-A0D3D9081626-40-00001A5906010248", - json.getString("uuid")); - } -} diff --git a/test/src/com/connectsdk/service/capability/KeyCodeParameterizedTest.java b/test/src/com/connectsdk/service/capability/KeyCodeParameterizedTest.java deleted file mode 100644 index 124b4105..00000000 --- a/test/src/com/connectsdk/service/capability/KeyCodeParameterizedTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * KeyCodeParameterizedTest - * Connect SDK - * - * Copyright (c) 2014 LG Electronics. - * Created by Oleksii Frolov on 20 Aug 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.connectsdk.service.capability; - -import com.connectsdk.service.capability.KeyControl.KeyCode; - -import junit.framework.Assert; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.ParameterizedRobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.util.Arrays; -import java.util.Collection; - -@RunWith(ParameterizedRobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class KeyCodeParameterizedTest { - - private final int value; - private final KeyCode keyCode; - - public static Object[][] data = new Object[][] { - {0, KeyCode.NUM_0}, - {1, KeyCode.NUM_1}, - {2, KeyCode.NUM_2}, - {3, KeyCode.NUM_3}, - {4, KeyCode.NUM_4}, - {5, KeyCode.NUM_5}, - {6, KeyCode.NUM_6}, - {7, KeyCode.NUM_7}, - {8, KeyCode.NUM_8}, - {9, KeyCode.NUM_9}, - {10, KeyCode.DASH}, - {11, KeyCode.ENTER}, - {12, null}, - {-1, null}, - {999, null}, - }; - - @ParameterizedRobolectricTestRunner.Parameters - public static Collection<Object[]> data() { - return Arrays.asList( - new Object[][] { - {0}, - {1}, - {2}, - {3}, - {4}, - {5}, - {6}, - {7}, - {8}, - {9}, - {10}, - {11}, - {12}, - {13}, - {14}, - } - ); - } - - public KeyCodeParameterizedTest(int index) { - this.value = (Integer)data[index][0]; - this.keyCode = (KeyCode)data[index][1]; - } - - @Test - public void testGetKeyCodeFromInt() { - Assert.assertEquals(keyCode, KeyCode.createFromInteger(value)); - } - -} diff --git a/test/src/com/connectsdk/service/roku/RokuApplicationListParserTest.java b/test/src/com/connectsdk/service/roku/RokuApplicationListParserTest.java deleted file mode 100644 index 82f90106..00000000 --- a/test/src/com/connectsdk/service/roku/RokuApplicationListParserTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * RokuApplicationListParserTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 08 Sep 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.connectsdk.service.roku; - -import com.connectsdk.core.AppInfo; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.xml.sax.SAXException; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -public class RokuApplicationListParserTest { - - RokuApplicationListParser parser; - private SAXParser saxParser; - - @Before - public void setUp() throws ParserConfigurationException, SAXException { - SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); - saxParser = saxParserFactory.newSAXParser(); - parser = new RokuApplicationListParser(); - } - - @Test - public void testParseListWithEmptyInput() throws IOException, ParserConfigurationException, SAXException { - String msg = "<root></root>"; - InputStream stream = new ByteArrayInputStream(msg.getBytes("UTF-8")); - - saxParser.parse(stream, parser); - - List<AppInfo> appList = parser.getApplicationList(); - Assert.assertNotNull(appList); - Assert.assertTrue(appList.isEmpty()); - } - - @Test - public void testParseListWithOneItem() throws IOException, ParserConfigurationException, SAXException { - String msg = "<app id=\"youtube\">YouTube</app>"; - InputStream stream = new ByteArrayInputStream(msg.getBytes("UTF-8")); - - saxParser.parse(stream, parser); - - List<AppInfo> appList = parser.getApplicationList(); - Assert.assertEquals(1, appList.size()); - Assert.assertEquals("youtube", appList.get(0).getId()); - } - - @Test - public void testParseListWithSeveralItem() throws IOException, ParserConfigurationException, SAXException { - String msg = "<root><app id=\"youtube\">YouTube</app><app id=\"netflix\">Netflix</app></root>"; - InputStream stream = new ByteArrayInputStream(msg.getBytes("UTF-8")); - - saxParser.parse(stream, parser); - - List<AppInfo> appList = parser.getApplicationList(); - Assert.assertEquals(2, appList.size()); - Assert.assertEquals("youtube", appList.get(0).getId()); - Assert.assertEquals("YouTube", appList.get(0).getName()); - Assert.assertEquals("netflix", appList.get(1).getId()); - Assert.assertEquals("Netflix", appList.get(1).getName()); - } -} diff --git a/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java b/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java deleted file mode 100644 index 87e5046b..00000000 --- a/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * WebOSWebAppSessionTest - * Connect SDK - * - * Copyright (c) 2015 LG Electronics. - * Created by Oleksii Frolov on 27 May 2015 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.connectsdk.service.sessions; - -import com.connectsdk.core.MediaInfo; -import com.connectsdk.core.SubtitleInfo; -import com.connectsdk.service.DeviceService; -import com.connectsdk.service.WebOSTVService; -import com.connectsdk.service.capability.CapabilityMethods; -import com.connectsdk.service.capability.MediaPlayer; -import com.connectsdk.service.capability.listeners.ResponseListener; -import com.connectsdk.service.config.ServiceConfig; -import com.connectsdk.service.config.ServiceDescription; -import com.connectsdk.service.config.WebOSTVServiceConfig; -import com.connectsdk.service.webos.WebOSTVServiceSocketClient; - -import junit.framework.Assert; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import android.support.annotation.NonNull; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) -public class WebOSWebAppSessionTest { - - private WebOSWebAppSession session; - private LaunchSession launchSession; - private DeviceService service; - private WebOSTVServiceSocketClient socket; - - @Before - public void setUp() { - socket = Mockito.mock(WebOSTVServiceSocketClient.class); - Mockito.when(socket.isConnected()).thenReturn(Boolean.TRUE); - launchSession = Mockito.mock(LaunchSession.class); - service = Mockito.mock(WebOSTVService.class); - session = new WebOSWebAppSession(launchSession, service); - session.setConnected(Boolean.TRUE); - session.socket = socket; - session.mFullAppId = "com.webos.app.webapphost.MediaPlayer"; - } - - @Test - public void testPrevious() throws JSONException { - ResponseListener<Object> listener = Mockito.mock(ResponseListener.class); - session.previous(listener); - - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - ArgumentCaptor<JSONObject> argPacket = ArgumentCaptor.forClass(JSONObject.class); - ArgumentCaptor<JSONObject> argPayload = ArgumentCaptor.forClass(JSONObject.class); - Mockito.verify(socket).sendMessage(argPacket.capture(), argPayload.capture()); - Mockito.verify(listener).onSuccess(null); - - JSONObject packet = argPacket.getValue(); - JSONObject payload = argPayload.getValue(); - Assert.assertNull(payload); - Assert.assertTrue(packet.has("payload")); - Assert.assertEquals("playPrevious", packet.getJSONObject("payload") - .getJSONObject("mediaCommand").getString("type")); - Assert.assertEquals("connectsdk.mediaCommand", packet.getJSONObject("payload") - .getString ("contentType")); - } - - @Test - public void testNext() throws JSONException { - ResponseListener<Object> listener = Mockito.mock(ResponseListener.class); - session.next(listener); - - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - ArgumentCaptor<JSONObject> argPacket = ArgumentCaptor.forClass(JSONObject.class); - ArgumentCaptor<JSONObject> argPayload = ArgumentCaptor.forClass(JSONObject.class); - Mockito.verify(socket).sendMessage(argPacket.capture(), argPayload.capture()); - Mockito.verify(listener).onSuccess(null); - - JSONObject packet = argPacket.getValue(); - JSONObject payload = argPayload.getValue(); - Assert.assertNull(payload); - Assert.assertTrue(packet.has("payload")); - Assert.assertEquals("playNext", packet.getJSONObject("payload") - .getJSONObject("mediaCommand").getString("type")); - Assert.assertEquals("connectsdk.mediaCommand", packet.getJSONObject("payload") - .getString("contentType")); - } - - @Test - public void testJumpToTrack() throws JSONException { - ResponseListener<Object> listener = Mockito.mock(ResponseListener.class); - session.jumpToTrack(7, listener); - - Robolectric.runUiThreadTasksIncludingDelayedTasks(); - ArgumentCaptor<JSONObject> argPacket = ArgumentCaptor.forClass(JSONObject.class); - ArgumentCaptor<JSONObject> argPayload = ArgumentCaptor.forClass(JSONObject.class); - Mockito.verify(socket).sendMessage(argPacket.capture(), argPayload.capture()); - Mockito.verify(listener).onSuccess(null); - - JSONObject packet = argPacket.getValue(); - JSONObject payload = argPayload.getValue(); - Assert.assertNull(payload); - Assert.assertTrue(packet.has("payload")); - Assert.assertEquals("jumpToTrack", packet.getJSONObject("payload") - .getJSONObject("mediaCommand").getString("type")); - Assert.assertEquals(7, packet.getJSONObject("payload") - .getJSONObject("mediaCommand").getInt("index")); - Assert.assertEquals("connectsdk.mediaCommand", packet.getJSONObject("payload") - .getString("contentType")); - } - - @Test - public void testGetPlaylistControl() { - Assert.assertSame(session, session.getPlaylistControl()); - } - - @Test - public void testGetPlaylistControlCapability() { - Assert.assertEquals(CapabilityMethods.CapabilityPriorityLevel.HIGH, - session.getPlaylistControlCapabilityLevel()); - } - - @Test - public void testSendMessageWithEmptySocketShouldNotCrash() { - ServiceDescription description = Mockito.mock(ServiceDescription.class); - Mockito.when(description.getIpAddress()).thenReturn("127.0.0.1"); - Mockito.when(service.getServiceDescription()).thenReturn(description); - ServiceConfig config = Mockito.mock(WebOSTVServiceConfig.class); - Mockito.when(service.getServiceConfig()).thenReturn(config); - - session.socket = null; - session.setConnected(true); - ResponseListener<Object> listener = Mockito.mock(ResponseListener.class); - try { - session.sendMessage("message", listener); - } catch (RuntimeException e) { - Assert.fail("sendMessage should not throw an exception"); - } - } - - @Test - public void testPlayMediaDeprecatedWithRequiredParameters() throws JSONException { - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - final boolean shouldLoop = true; - final MediaInfo mediaInfo = new MediaInfo.Builder("url", "type").build(); - - session.playMedia(mediaInfo.getUrl(), mediaInfo.getMimeType(), null, null, null, shouldLoop, - listener); - - verifyPlayMedia(shouldLoop, null, mediaInfo); - } - - @Test(expected = NullPointerException.class) - public void testPlayMediaWithNullParametersShouldThrowException() throws JSONException { - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - final boolean shouldLoop = true; - - session.playMedia(null, shouldLoop, listener); - } - - @Test - public void testPlayMediaWithRequiredParameters() throws JSONException { - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - final boolean shouldLoop = true; - final MediaInfo mediaInfo = new MediaInfo.Builder("url", "type").build(); - - session.playMedia(mediaInfo, shouldLoop, listener); - - verifyPlayMedia(shouldLoop, null, mediaInfo); - } - - @Test - public void testPlayMediaWithSubtitles() throws JSONException { - MediaPlayer.LaunchListener listener = Mockito.mock(MediaPlayer.LaunchListener.class); - final boolean shouldLoop = true; - final SubtitleInfo subtitleInfo = new SubtitleInfo.Builder("subtitleurl") - .setLabel("label") - .setLanguage("en") - .setMimeType("subtitletype") - .build(); - final MediaInfo mediaInfo = new MediaInfo.Builder("url", "type") - .setIcon("icon") - .setTitle("title") - .setDescription("description") - .setSubtitleInfo(subtitleInfo) - .build(); - - session.playMedia(mediaInfo, shouldLoop, listener); - - verifyPlayMedia(shouldLoop, subtitleInfo, mediaInfo); - } - - private void verifyPlayMedia(boolean shouldLoop, SubtitleInfo subtitleInfo, MediaInfo - mediaInfo) throws JSONException { - ArgumentCaptor<JSONObject> argPacket = ArgumentCaptor.forClass(JSONObject.class); - Mockito.verify(socket).sendMessage(argPacket.capture(), Mockito.isNull(JSONObject.class)); - JSONObject capturedPacket = argPacket.getValue(); - JSONObject expectedPacket = getPlayMediaExpectedRequest(shouldLoop, subtitleInfo, mediaInfo); - - Assert.assertEquals(expectedPacket.toString(), capturedPacket.toString()); - } - - @NonNull - private JSONObject getPlayMediaExpectedRequest(final boolean shouldLoop, final SubtitleInfo - subtitleInfo, final MediaInfo mediaInfo) throws JSONException { - return new JSONObject() {{ - put("type", "p2p"); - put("to", "com.webos.app.webapphost.MediaPlayer"); - put("payload", new JSONObject() {{ - putOpt("contentType", "connectsdk.mediaCommand"); - putOpt("mediaCommand", new JSONObject() {{ - putOpt("type", "playMedia"); - putOpt("mediaURL", mediaInfo.getUrl()); - if (mediaInfo.getImages() != null) { - putOpt("iconURL", mediaInfo.getImages().get(0).getUrl()); - } - putOpt("title", mediaInfo.getTitle()); - putOpt("description", mediaInfo.getDescription()); - putOpt("mimeType", mediaInfo.getMimeType()); - putOpt("shouldLoop", shouldLoop); - put("requestId", "req1"); - if (subtitleInfo != null) { - putOpt("subtitles", new JSONObject() {{ - putOpt("default", "1"); - putOpt("enabled", "1"); - putOpt("tracks", new JSONArray() {{ - put(new JSONObject() {{ - putOpt("id", "1"); - putOpt("language", subtitleInfo.getLanguage()); - putOpt("source", subtitleInfo.getUrl()); - putOpt("label", subtitleInfo.getLabel()); - }}); - - }}); - - }}); - } - - }}); - - }}); - - }}; - } - - -} diff --git a/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java b/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java deleted file mode 100644 index 79048869..00000000 --- a/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.connectsdk.service.upnp; - -import com.connectsdk.service.command.URLServiceSubscription; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -/** - * Created by oleksii on 4/27/15. - */ -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) -public class DLNAHttpServerTest { - - DLNAHttpServer server; - - @Before - public void setUp() { - server = new DLNAHttpServer(); - } - - @Test - public void testUnsubscribeOnDisconnect() { - URLServiceSubscription<?> subscribtion = Mockito.mock(URLServiceSubscription.class); - server.getSubscriptions().add(subscribtion); - server.running = true; - - server.stop(); - Mockito.verify(subscribtion).unsubscribe(); - } - -} diff --git a/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java b/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java deleted file mode 100644 index 94fadf15..00000000 --- a/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.connectsdk.service.webos; - - -import com.connectsdk.service.WebOSTVService; -import com.connectsdk.service.capability.listeners.ResponseListener; -import com.connectsdk.service.command.ServiceCommand; -import com.connectsdk.service.command.ServiceCommandError; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.net.URI; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class WebOSTVServiceSocketClientTest { - - private WebOSTVServiceSocketClient socketClient; - - @Before - public void setUp() { - WebOSTVService service = Mockito.mock(WebOSTVService.class); - URI uri = URI.create("http://127.0.0.1/"); - socketClient = new WebOSTVServiceSocketClient(service, uri); - } - - @Test - public void test403ErrorShouldNotCloseSocket() { - ServiceCommand command = new ServiceCommand(null, null, (Object)null, null); - WebOSTVServiceSocketClient spySocketClient = Mockito.spy(socketClient); - - spySocketClient.requests.put(11, command); - spySocketClient.state = WebOSTVServiceSocketClient.State.REGISTERED; - spySocketClient.onMessage(" {\"type\":\"error\",\"id\":\"11\",\"error\":" + - "\"403 access denied\",\"payload\":{}}"); - - Assert.assertEquals(WebOSTVServiceSocketClient.State.REGISTERED, spySocketClient.getState()); - Mockito.verify(spySocketClient, Mockito.times(0)).close(); - } -} diff --git a/test/src/com/connectsdk/shadow/WifiInfoShadow.java b/test/src/com/connectsdk/shadow/WifiInfoShadow.java deleted file mode 100644 index c6f29539..00000000 --- a/test/src/com/connectsdk/shadow/WifiInfoShadow.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.connectsdk.shadow; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -import org.robolectric.annotation.Implements; -import org.robolectric.shadows.ShadowWifiInfo; - -import android.net.wifi.WifiInfo; - -@Implements(WifiInfo.class) -public class WifiInfoShadow extends ShadowWifiInfo { - - public int getIpAddress() { - try { - byte[] addr = InetAddress.getLocalHost().getAddress(); - return addr[0] + (addr[1] << 8) + (addr[2] << 16) + (addr[3] << 24); - } catch (UnknownHostException e) { - e.printStackTrace(); - } - return 0; - } -}