From 81a95f8d7c9888c795db4b35bde2ea50cb33b0c0 Mon Sep 17 00:00:00 2001 From: David Mayboroda Date: Mon, 26 Oct 2015 17:43:52 +0200 Subject: [PATCH 01/41] out of memotu fix --- .../provider/SSDPDiscoveryProvider.java | 52 +++++++++++-------- .../provider/SSDPDiscoveryProviderTest.java | 2 +- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java index dfc14abe..bcf9a9ee 100644 --- a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java @@ -45,6 +45,9 @@ 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; @@ -70,7 +73,7 @@ public class SSDPDiscoveryProvider implements DiscoveryProvider { private Thread responseThread; private Thread notifyThread; - + private ScheduledExecutorService executorService; boolean isRunning = false; public SSDPDiscoveryProvider(Context context) { @@ -111,7 +114,11 @@ public void start() { isRunning = true; openSocket(); - + if (serviceFilters != null && !serviceFilters.isEmpty()) { + //three tasks for each service filter + int poolSize = serviceFilters.size() * 3; + executorService = Executors.newScheduledThreadPool(poolSize); + } scanTimer = new Timer(); scanTimer.schedule(new TimerTask() { @@ -177,6 +184,10 @@ public void stop() { ssdpClient.close(); ssdpClient = null; } + + if (executorService != null && !executorService.isShutdown()) { + executorService.shutdown(); + } } @Override @@ -194,26 +205,25 @@ 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 { + 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); + } } } diff --git a/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java b/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java index df497254..f650fefa 100755 --- a/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java +++ b/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java @@ -38,7 +38,7 @@ public class SSDPDiscoveryProviderTest{ SSDPDiscoveryProvider dp; private SSDPClient ssdpClient = Mockito.mock(SSDPClient.class); - class StubSSDPDiscoveryProvider extends SSDPDiscoveryProvider { + class StubSSDPDiscoveryProvider extends SSDPDiscoveryProvider { public StubSSDPDiscoveryProvider(Context context) { super(context); From 0cf0c6c861134156b55b8cb222c369d5e8052003 Mon Sep 17 00:00:00 2001 From: David Mayboroda Date: Sat, 31 Oct 2015 02:24:54 +0200 Subject: [PATCH 02/41] Switched to robolectric 3.0 --- test/src/com/connectsdk/core/MediaInfoTest.java | 5 +++-- test/src/com/connectsdk/core/SubtitleInfoTest.java | 4 ++-- test/src/com/connectsdk/device/ConnectableDeviceTest.java | 4 ++-- test/src/com/connectsdk/discovery/DiscoveryManagerTest.java | 4 ++-- .../discovery/provider/SSDPDiscoveryProviderTest.java | 4 ++-- .../discovery/provider/ZeroConfDiscoveryPrividerTest.java | 5 ++--- .../connectsdk/discovery/provider/ssdp/SSDPClientTest.java | 4 ++-- .../connectsdk/discovery/provider/ssdp/SSDPPacketTest.java | 4 ++-- test/src/com/connectsdk/service/AirPlayServiceTest.java | 4 ++-- .../com/connectsdk/service/DIALServiceSendCommandTest.java | 5 ++--- test/src/com/connectsdk/service/DIALServiceTest.java | 4 ++-- .../com/connectsdk/service/DLNAServiceSendCommandTest.java | 4 ++-- test/src/com/connectsdk/service/DLNAServiceTest.java | 4 ++-- test/src/com/connectsdk/service/NetCastTVServiceTest.java | 4 ++-- test/src/com/connectsdk/service/RokuServiceTest.java | 4 ++-- test/src/com/connectsdk/service/WebOSTVServiceTest.java | 4 ++-- test/src/com/connectsdk/service/airplay/PListParserTest.java | 4 ++-- .../connectsdk/service/sessions/WebOSWebAppSessionTest.java | 4 ++-- test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java | 4 ++-- .../service/webos/WebOSTVServiceSocketClientTest.java | 4 ++-- 20 files changed, 41 insertions(+), 42 deletions(-) diff --git a/test/src/com/connectsdk/core/MediaInfoTest.java b/test/src/com/connectsdk/core/MediaInfoTest.java index 39f45dcc..46b91262 100644 --- a/test/src/com/connectsdk/core/MediaInfoTest.java +++ b/test/src/com/connectsdk/core/MediaInfoTest.java @@ -26,8 +26,9 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) + +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class MediaInfoTest { @Test diff --git a/test/src/com/connectsdk/core/SubtitleInfoTest.java b/test/src/com/connectsdk/core/SubtitleInfoTest.java index 942d1b91..835e293d 100644 --- a/test/src/com/connectsdk/core/SubtitleInfoTest.java +++ b/test/src/com/connectsdk/core/SubtitleInfoTest.java @@ -27,8 +27,8 @@ import org.robolectric.annotation.Config; -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class SubtitleInfoTest { @Test diff --git a/test/src/com/connectsdk/device/ConnectableDeviceTest.java b/test/src/com/connectsdk/device/ConnectableDeviceTest.java index b46bc373..e816317c 100644 --- a/test/src/com/connectsdk/device/ConnectableDeviceTest.java +++ b/test/src/com/connectsdk/device/ConnectableDeviceTest.java @@ -27,8 +27,8 @@ import java.util.ArrayList; import java.util.List; -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class ConnectableDeviceTest { private ConnectableDevice device; diff --git a/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java b/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java index 9d01633e..67e90304 100644 --- a/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java +++ b/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java @@ -20,8 +20,8 @@ * Created by oleksii.frolov on 2/16/2015. */ -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class DiscoveryManagerTest { DiscoveryManager discovery; diff --git a/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java b/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java index f650fefa..8f9c6857 100755 --- a/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java +++ b/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java @@ -30,8 +30,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE,shadows={WifiInfoShadow.class}) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class, shadows={WifiInfoShadow.class}) public class SSDPDiscoveryProviderTest{ diff --git a/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java b/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java index b9173d5c..96ef3536 100644 --- a/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java +++ b/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java @@ -34,9 +34,8 @@ 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 }) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class, shadows = {WifiInfoShadow.class }) public class ZeroConfDiscoveryPrividerTest { private ZeroconfDiscoveryProvider dp; diff --git a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java index 5f638446..3fc3c70c 100644 --- a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java +++ b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java @@ -22,8 +22,8 @@ import java.net.NetworkInterface; import java.net.SocketAddress; -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE ,shadows = { WifiInfoShadow.class }) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class, shadows = { WifiInfoShadow.class }) public class SSDPClientTest { InetAddress localAddress; diff --git a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java index d9e4d23d..c9388f97 100644 --- a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java +++ b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java @@ -9,8 +9,8 @@ import java.net.DatagramPacket; -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class SSDPPacketTest { DatagramPacket mDatagramPacket; diff --git a/test/src/com/connectsdk/service/AirPlayServiceTest.java b/test/src/com/connectsdk/service/AirPlayServiceTest.java index 1f9f4a8c..fc583608 100644 --- a/test/src/com/connectsdk/service/AirPlayServiceTest.java +++ b/test/src/com/connectsdk/service/AirPlayServiceTest.java @@ -20,8 +20,8 @@ /** * Created by Oleksii Frolov on 3/19/2015. */ -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class AirPlayServiceTest { private StubAirPlayService service; diff --git a/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java b/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java index 0e6bc222..ab1b34de 100644 --- a/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java +++ b/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java @@ -41,9 +41,8 @@ import java.io.IOException; - -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class DIALServiceSendCommandTest { public static final String COMMAND_URL = "http://host:8080/path"; diff --git a/test/src/com/connectsdk/service/DIALServiceTest.java b/test/src/com/connectsdk/service/DIALServiceTest.java index 2c2956b4..bcb3cc29 100644 --- a/test/src/com/connectsdk/service/DIALServiceTest.java +++ b/test/src/com/connectsdk/service/DIALServiceTest.java @@ -35,8 +35,8 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class DIALServiceTest { private static final String APPLICATION_URL = "http://applicationurl"; diff --git a/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java b/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java index b715e1e9..132f6760 100644 --- a/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java +++ b/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java @@ -42,8 +42,8 @@ import java.io.IOException; -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class DLNAServiceSendCommandTest { public static final String COMMAND_URL = "http://host:8080/path"; diff --git a/test/src/com/connectsdk/service/DLNAServiceTest.java b/test/src/com/connectsdk/service/DLNAServiceTest.java index a5ee87c0..df7fcaf5 100644 --- a/test/src/com/connectsdk/service/DLNAServiceTest.java +++ b/test/src/com/connectsdk/service/DLNAServiceTest.java @@ -30,8 +30,8 @@ /** * Created by oleksii.frolov on 1/13/2015. */ -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class DLNAServiceTest { private DLNAService service; diff --git a/test/src/com/connectsdk/service/NetCastTVServiceTest.java b/test/src/com/connectsdk/service/NetCastTVServiceTest.java index c481a430..243f470d 100644 --- a/test/src/com/connectsdk/service/NetCastTVServiceTest.java +++ b/test/src/com/connectsdk/service/NetCastTVServiceTest.java @@ -22,8 +22,8 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class NetCastTVServiceTest { private NetcastTVService service; diff --git a/test/src/com/connectsdk/service/RokuServiceTest.java b/test/src/com/connectsdk/service/RokuServiceTest.java index c001ff21..60edf7aa 100644 --- a/test/src/com/connectsdk/service/RokuServiceTest.java +++ b/test/src/com/connectsdk/service/RokuServiceTest.java @@ -35,8 +35,8 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class RokuServiceTest { private StubRokuService service; diff --git a/test/src/com/connectsdk/service/WebOSTVServiceTest.java b/test/src/com/connectsdk/service/WebOSTVServiceTest.java index 5ec94662..bcc8b519 100644 --- a/test/src/com/connectsdk/service/WebOSTVServiceTest.java +++ b/test/src/com/connectsdk/service/WebOSTVServiceTest.java @@ -56,8 +56,8 @@ import java.util.List; import java.util.Map; -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class WebOSTVServiceTest { private WebOSTVService service; diff --git a/test/src/com/connectsdk/service/airplay/PListParserTest.java b/test/src/com/connectsdk/service/airplay/PListParserTest.java index 91ff685e..fe918a5c 100644 --- a/test/src/com/connectsdk/service/airplay/PListParserTest.java +++ b/test/src/com/connectsdk/service/airplay/PListParserTest.java @@ -32,8 +32,8 @@ import java.io.IOException; -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class PListParserTest { @Test diff --git a/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java b/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java index 87e5046b..9d3491e6 100644 --- a/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java +++ b/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java @@ -47,8 +47,8 @@ import android.support.annotation.NonNull; -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class WebOSWebAppSessionTest { private WebOSWebAppSession session; diff --git a/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java b/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java index 79048869..cf580ea1 100644 --- a/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java +++ b/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java @@ -12,8 +12,8 @@ /** * Created by oleksii on 4/27/15. */ -@RunWith(RobolectricTestRunner.class) -@Config(manifest=Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class DLNAHttpServerTest { DLNAHttpServer server; diff --git a/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java b/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java index 94fadf15..538f47ef 100644 --- a/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java +++ b/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java @@ -17,8 +17,8 @@ import java.net.URI; -@RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = BuildConfig.class) public class WebOSTVServiceSocketClientTest { private WebOSTVServiceSocketClient socketClient; From 426e051de9eec4f23557ca0b9c98ee054fa0f5a0 Mon Sep 17 00:00:00 2001 From: David Mayboroda Date: Mon, 16 Nov 2015 19:38:30 +0200 Subject: [PATCH 03/41] robolectric tests fixed --- src/com/connectsdk/service/DIALService.java | 15 ++++- .../com/connectsdk/core/MediaInfoTest.java | 6 +- .../com/connectsdk/core/SubtitleInfoTest.java | 6 +- .../device/ConnectableDeviceTest.java | 9 +-- .../discovery/DiscoveryManagerTest.java | 15 ++--- .../provider/SSDPDiscoveryProviderTest.java | 10 ++-- .../ZeroConfDiscoveryPrividerTest.java | 56 ++++++++++--------- .../provider/ssdp/SSDPClientTest.java | 9 +-- .../provider/ssdp/SSDPPacketTest.java | 6 +- .../service/AirPlayServiceTest.java | 5 +- .../service/DIALServiceSendCommandTest.java | 13 +++-- .../connectsdk/service/DIALServiceTest.java | 5 +- .../service/DLNAServiceSendCommandTest.java | 12 ++-- .../connectsdk/service/DLNAServiceTest.java | 11 ++-- .../service/NetCastTVServiceTest.java | 10 ++-- .../connectsdk/service/RokuServiceTest.java | 5 +- .../service/WebOSTVServiceTest.java | 9 +-- .../service/airplay/PListParserTest.java | 6 +- .../sessions/WebOSWebAppSessionTest.java | 17 +++--- .../service/upnp/DLNAHttpServerTest.java | 5 +- .../webos/WebOSTVServiceSocketClientTest.java | 7 +-- 21 files changed, 134 insertions(+), 103 deletions(-) diff --git a/src/com/connectsdk/service/DIALService.java b/src/com/connectsdk/service/DIALService.java index 475bcb93..3b550bea 100644 --- a/src/com/connectsdk/service/DIALService.java +++ b/src/com/connectsdk/service/DIALService.java @@ -54,6 +54,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(); @@ -206,9 +207,9 @@ public void launchYouTube(String contentId, AppLaunchListener listener) { @Override public void launchYouTube(String contentId, float startTime, AppLaunchListener 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 +220,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); } diff --git a/test/src/com/connectsdk/core/MediaInfoTest.java b/test/src/com/connectsdk/core/MediaInfoTest.java index 46b91262..b2636651 100644 --- a/test/src/com/connectsdk/core/MediaInfoTest.java +++ b/test/src/com/connectsdk/core/MediaInfoTest.java @@ -19,16 +19,18 @@ */ package com.connectsdk.core; +import com.connectsdk.BuildConfig; + import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class MediaInfoTest { @Test diff --git a/test/src/com/connectsdk/core/SubtitleInfoTest.java b/test/src/com/connectsdk/core/SubtitleInfoTest.java index 835e293d..5649d811 100644 --- a/test/src/com/connectsdk/core/SubtitleInfoTest.java +++ b/test/src/com/connectsdk/core/SubtitleInfoTest.java @@ -19,16 +19,18 @@ */ package com.connectsdk.core; +import com.connectsdk.BuildConfig; + import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class SubtitleInfoTest { @Test diff --git a/test/src/com/connectsdk/device/ConnectableDeviceTest.java b/test/src/com/connectsdk/device/ConnectableDeviceTest.java index e816317c..d809dee5 100644 --- a/test/src/com/connectsdk/device/ConnectableDeviceTest.java +++ b/test/src/com/connectsdk/device/ConnectableDeviceTest.java @@ -1,5 +1,6 @@ package com.connectsdk.device; +import com.connectsdk.BuildConfig; import com.connectsdk.discovery.DiscoveryManager; import com.connectsdk.service.AirPlayService; import com.connectsdk.service.DIALService; @@ -19,8 +20,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import java.io.IOException; @@ -28,14 +29,14 @@ import java.util.List; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class ConnectableDeviceTest { private ConnectableDevice device; @Before public void setUp() { - DiscoveryManager.init(Robolectric.application); + DiscoveryManager.init(RuntimeEnvironment.application); device = new ConnectableDevice(); } diff --git a/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java b/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java index 67e90304..01a4ef02 100644 --- a/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java +++ b/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java @@ -1,5 +1,6 @@ package com.connectsdk.discovery; +import com.connectsdk.BuildConfig; import com.connectsdk.discovery.provider.SSDPDiscoveryProvider; import com.connectsdk.discovery.provider.ZeroconfDiscoveryProvider; import com.connectsdk.service.DIALService; @@ -10,8 +11,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import java.util.Objects; @@ -21,14 +22,14 @@ */ @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class DiscoveryManagerTest { DiscoveryManager discovery; @Before public void setUp() { - discovery = new DiscoveryManager(Robolectric.application); + discovery = new DiscoveryManager(RuntimeEnvironment.application); } @Test @@ -48,7 +49,7 @@ public void testUnregisterDeviceServiceWithWrongArguments() { @Test public void testUnregisterDeviceServiceWithWrongProvider() { - discovery.discoveryProviders.add(new SSDPDiscoveryProvider(Robolectric.application)); + discovery.discoveryProviders.add(new SSDPDiscoveryProvider(RuntimeEnvironment.application)); discovery.deviceClasses.put(DIALService.ID, DIALService.class); Assert.assertEquals(1, discovery.discoveryProviders.size()); Assert.assertEquals(1, discovery.deviceClasses.size()); @@ -60,7 +61,7 @@ public void testUnregisterDeviceServiceWithWrongProvider() { @Test public void testUnregisterDeviceServiceWithWrongServiceID() { - discovery.discoveryProviders.add(new SSDPDiscoveryProvider(Robolectric.application)); + discovery.discoveryProviders.add(new SSDPDiscoveryProvider(RuntimeEnvironment.application)); discovery.deviceClasses.put(DLNAService.ID, DIALService.class); Assert.assertEquals(1, discovery.discoveryProviders.size()); Assert.assertEquals(1, discovery.deviceClasses.size()); @@ -72,7 +73,7 @@ public void testUnregisterDeviceServiceWithWrongServiceID() { @Test public void testUnregisterDeviceService() { - discovery.discoveryProviders.add(new SSDPDiscoveryProvider(Robolectric.application)); + discovery.discoveryProviders.add(new SSDPDiscoveryProvider(RuntimeEnvironment.application)); discovery.deviceClasses.put(DIALService.ID, DIALService.class); Assert.assertEquals(1, discovery.discoveryProviders.size()); Assert.assertEquals(1, discovery.deviceClasses.size()); diff --git a/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java b/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java index 8f9c6857..238b365e 100755 --- a/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java +++ b/test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java @@ -2,6 +2,7 @@ import android.content.Context; +import com.connectsdk.BuildConfig; import com.connectsdk.core.TestUtil; import com.connectsdk.discovery.DiscoveryFilter; import com.connectsdk.discovery.provider.ssdp.SSDPClient; @@ -14,10 +15,9 @@ 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.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import java.io.IOException; @@ -31,7 +31,7 @@ import static org.mockito.Mockito.when; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, shadows={WifiInfoShadow.class}) +@Config(constants = BuildConfig.class, shadows={WifiInfoShadow.class}, sdk = 21) public class SSDPDiscoveryProviderTest{ @@ -57,7 +57,7 @@ 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); + dp = new StubSSDPDiscoveryProvider(RuntimeEnvironment.application); assertNotNull(dp); } @After diff --git a/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java b/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java index 96ef3536..97061cdb 100644 --- a/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java +++ b/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java @@ -1,41 +1,43 @@ 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 android.content.Context; -import javax.jmdns.JmDNS; -import javax.jmdns.ServiceEvent; -import javax.jmdns.ServiceInfo; -import javax.jmdns.ServiceListener; -import javax.jmdns.impl.JmDNSImpl; +import com.connectsdk.BuildConfig; +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; 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.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLooper; -import android.content.Context; +import java.io.IOException; +import java.net.InetAddress; -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; +import javax.jmdns.JmDNS; +import javax.jmdns.ServiceEvent; +import javax.jmdns.ServiceInfo; +import javax.jmdns.ServiceListener; +import javax.jmdns.impl.JmDNSImpl; + +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; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, shadows = {WifiInfoShadow.class }) +@Config(constants = BuildConfig.class, shadows = {WifiInfoShadow.class }, sdk = 21) public class ZeroConfDiscoveryPrividerTest { private ZeroconfDiscoveryProvider dp; @@ -77,7 +79,7 @@ protected JmDNS createJmDNS() { @Before public void setUp() { - dp = new StubZeroConfDiscoveryProvider(Robolectric.application); + dp = new StubZeroConfDiscoveryProvider(RuntimeEnvironment.application); mDNS = mock(StubJmDNS.class); eventMock = mock(StubServiceEvent.class); @@ -296,7 +298,7 @@ public void testServiceRemoveEvent() throws Exception { // when dp.jmdnsListener.serviceRemoved(event); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); // then verify(listener).onServiceRemoved(any(DiscoveryProvider.class), any(ServiceDescription.class)); diff --git a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java index 3fc3c70c..8b4ab54c 100644 --- a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java +++ b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java @@ -1,5 +1,6 @@ package com.connectsdk.discovery.provider.ssdp; +import com.connectsdk.BuildConfig; import com.connectsdk.core.Util; import com.connectsdk.shadow.WifiInfoShadow; @@ -9,8 +10,8 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import java.io.IOException; @@ -23,7 +24,7 @@ import java.net.SocketAddress; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, shadows = { WifiInfoShadow.class }) +@Config(constants = BuildConfig.class, shadows = { WifiInfoShadow.class }, sdk = 21) public class SSDPClientTest { InetAddress localAddress; @@ -38,7 +39,7 @@ public SSDPClientTest() { @Before public void setUp() throws IOException { - localAddress = Util.getIpAddress(Robolectric.application); + localAddress = Util.getIpAddress(RuntimeEnvironment.application); ssdpClient = new SSDPClient(localAddress, mLocalSocket, wildSocket); } diff --git a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java index c9388f97..3d63dd4e 100644 --- a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java +++ b/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java @@ -1,16 +1,18 @@ package com.connectsdk.discovery.provider.ssdp; +import com.connectsdk.BuildConfig; + import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; import java.net.DatagramPacket; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class SSDPPacketTest { DatagramPacket mDatagramPacket; diff --git a/test/src/com/connectsdk/service/AirPlayServiceTest.java b/test/src/com/connectsdk/service/AirPlayServiceTest.java index fc583608..bde24111 100644 --- a/test/src/com/connectsdk/service/AirPlayServiceTest.java +++ b/test/src/com/connectsdk/service/AirPlayServiceTest.java @@ -1,5 +1,6 @@ package com.connectsdk.service; +import com.connectsdk.BuildConfig; import com.connectsdk.service.capability.MediaControl; import com.connectsdk.service.command.ServiceCommand; import com.connectsdk.service.command.ServiceCommandError; @@ -12,7 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; import java.io.IOException; @@ -21,7 +22,7 @@ * Created by Oleksii Frolov on 3/19/2015. */ @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class AirPlayServiceTest { private StubAirPlayService service; diff --git a/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java b/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java index ab1b34de..2cfb9042 100644 --- a/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java +++ b/test/src/com/connectsdk/service/DIALServiceSendCommandTest.java @@ -20,6 +20,7 @@ package com.connectsdk.service; +import com.connectsdk.BuildConfig; import com.connectsdk.core.TestUtil; import com.connectsdk.etc.helper.HttpConnection; import com.connectsdk.etc.helper.HttpMessage; @@ -35,14 +36,14 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLooper; import java.io.IOException; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class DIALServiceSendCommandTest { public static final String COMMAND_URL = "http://host:8080/path"; @@ -150,7 +151,7 @@ public void testSendCommand200ShouldInvokeSuccess() throws Exception { service.sendCommand(command); TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); Mockito.verify(listener).onSuccess(Mockito.eq(response)); } @@ -166,7 +167,7 @@ public void testSendCommand201ShouldInvokeSuccess() throws Exception { service.sendCommand(command); TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); Mockito.verify(listener).onSuccess(Mockito.eq(response)); } @@ -196,7 +197,7 @@ private void verifyFailedConnection(int code) throws IOException { service.sendCommand(command); TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.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 index bcb3cc29..2e073f3f 100644 --- a/test/src/com/connectsdk/service/DIALServiceTest.java +++ b/test/src/com/connectsdk/service/DIALServiceTest.java @@ -20,6 +20,7 @@ package com.connectsdk.service; +import com.connectsdk.BuildConfig; import com.connectsdk.service.capability.Launcher; import com.connectsdk.service.command.ServiceCommand; import com.connectsdk.service.config.ServiceConfig; @@ -32,11 +33,11 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class DIALServiceTest { private static final String APPLICATION_URL = "http://applicationurl"; diff --git a/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java b/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java index 132f6760..dfefb7d4 100644 --- a/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java +++ b/test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java @@ -20,9 +20,9 @@ package com.connectsdk.service; +import com.connectsdk.BuildConfig; 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; @@ -35,15 +35,15 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLooper; import java.io.IOException; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class DLNAServiceSendCommandTest { public static final String COMMAND_URL = "http://host:8080/path"; @@ -104,7 +104,7 @@ public void testSendPostCommandWithNullPayload() throws Exception { service.sendCommand(command); TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); Mockito.verify(httpConnection, Mockito.times(0)).execute(); Mockito.verify(listener).onError(Mockito.any(ServiceCommandError.class)); @@ -121,7 +121,7 @@ public void testSendPostCommandWithWrongPayload() throws Exception { service.sendCommand(command); TestUtil.runUtilBackgroundTasks(); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.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 index df7fcaf5..1f39324d 100644 --- a/test/src/com/connectsdk/service/DLNAServiceTest.java +++ b/test/src/com/connectsdk/service/DLNAServiceTest.java @@ -1,5 +1,6 @@ package com.connectsdk.service; +import com.connectsdk.BuildConfig; import com.connectsdk.core.SubtitleInfo; import com.connectsdk.core.TestUtil; import com.connectsdk.discovery.provider.ssdp.Service; @@ -15,8 +16,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.xml.sax.SAXException; @@ -31,7 +32,7 @@ * Created by oleksii.frolov on 1/13/2015. */ @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class DLNAServiceTest { private DLNAService service; @@ -42,7 +43,7 @@ public class DLNAServiceTest { public void setUp() { dlnaServer = Mockito.mock(DLNAHttpServer.class); service = new DLNAService(Mockito.mock(ServiceDescription.class), - Mockito.mock(ServiceConfig.class), Robolectric.application, dlnaServer); + Mockito.mock(ServiceConfig.class), RuntimeEnvironment.application, dlnaServer); } @Test @@ -446,7 +447,7 @@ private DLNAService makeServiceWithControlURL(String base, String controlURL) { ServiceDescription description = Mockito.mock(ServiceDescription.class); Mockito.when(description.getServiceList()).thenReturn(services); - return new DLNAService(description, Mockito.mock(ServiceConfig.class), Robolectric.application, null); + return new DLNAService(description, Mockito.mock(ServiceConfig.class), RuntimeEnvironment.application, null); } private void assertXMLEquals(String expectedXML, String actualXML) throws SAXException, IOException { diff --git a/test/src/com/connectsdk/service/NetCastTVServiceTest.java b/test/src/com/connectsdk/service/NetCastTVServiceTest.java index 243f470d..b876a6ea 100644 --- a/test/src/com/connectsdk/service/NetCastTVServiceTest.java +++ b/test/src/com/connectsdk/service/NetCastTVServiceTest.java @@ -1,12 +1,12 @@ package com.connectsdk.service; +import com.connectsdk.BuildConfig; 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; @@ -18,12 +18,12 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class NetCastTVServiceTest { private NetcastTVService service; @@ -135,7 +135,7 @@ private void verifyNotImplemented(ResponseListener listener) { } private void setPairingLevel(DiscoveryManager.PairingLevel level) { - DiscoveryManager.init(Robolectric.application); + DiscoveryManager.init(RuntimeEnvironment.application); DiscoveryManager.getInstance().setPairingLevel(level); } diff --git a/test/src/com/connectsdk/service/RokuServiceTest.java b/test/src/com/connectsdk/service/RokuServiceTest.java index 60edf7aa..8097241f 100644 --- a/test/src/com/connectsdk/service/RokuServiceTest.java +++ b/test/src/com/connectsdk/service/RokuServiceTest.java @@ -19,6 +19,7 @@ */ package com.connectsdk.service; +import com.connectsdk.BuildConfig; import com.connectsdk.core.MediaInfo; import com.connectsdk.core.TestUtil; import com.connectsdk.service.capability.MediaPlayer; @@ -32,11 +33,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class RokuServiceTest { private StubRokuService service; diff --git a/test/src/com/connectsdk/service/WebOSTVServiceTest.java b/test/src/com/connectsdk/service/WebOSTVServiceTest.java index bcc8b519..f25262a1 100644 --- a/test/src/com/connectsdk/service/WebOSTVServiceTest.java +++ b/test/src/com/connectsdk/service/WebOSTVServiceTest.java @@ -19,6 +19,7 @@ */ package com.connectsdk.service; +import com.connectsdk.BuildConfig; import com.connectsdk.core.ChannelInfo; import com.connectsdk.core.MediaInfo; import com.connectsdk.core.SubtitleInfo; @@ -47,9 +48,9 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLooper; import java.util.Arrays; import java.util.HashMap; @@ -57,7 +58,7 @@ import java.util.Map; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class WebOSTVServiceTest { private WebOSTVService service; @@ -452,7 +453,7 @@ private void verifyPlayMediaOnTheLatestWebOS(MediaInfo mediaInfo, boolean should // run join success ResponseListener webAppListener = argListener.getValue(); webAppListener.onSuccess(null); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); // should delegate playing media to the WebAppSession ArgumentCaptor argMediaInfo = ArgumentCaptor.forClass(MediaInfo.class); diff --git a/test/src/com/connectsdk/service/airplay/PListParserTest.java b/test/src/com/connectsdk/service/airplay/PListParserTest.java index fe918a5c..32da84af 100644 --- a/test/src/com/connectsdk/service/airplay/PListParserTest.java +++ b/test/src/com/connectsdk/service/airplay/PListParserTest.java @@ -19,13 +19,15 @@ */ package com.connectsdk.service.airplay; +import com.connectsdk.BuildConfig; + 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.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; import org.xmlpull.v1.XmlPullParserException; @@ -33,7 +35,7 @@ @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class PListParserTest { @Test diff --git a/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java b/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java index 9d3491e6..8e5be5c3 100644 --- a/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java +++ b/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java @@ -19,6 +19,9 @@ */ package com.connectsdk.service.sessions; +import android.support.annotation.NonNull; + +import com.connectsdk.BuildConfig; import com.connectsdk.core.MediaInfo; import com.connectsdk.core.SubtitleInfo; import com.connectsdk.service.DeviceService; @@ -41,14 +44,12 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; - -import android.support.annotation.NonNull; +import org.robolectric.shadows.ShadowLooper; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class WebOSWebAppSessionTest { private WebOSWebAppSession session; @@ -73,7 +74,7 @@ public void testPrevious() throws JSONException { ResponseListener listener = Mockito.mock(ResponseListener.class); session.previous(listener); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); ArgumentCaptor argPacket = ArgumentCaptor.forClass(JSONObject.class); ArgumentCaptor argPayload = ArgumentCaptor.forClass(JSONObject.class); Mockito.verify(socket).sendMessage(argPacket.capture(), argPayload.capture()); @@ -94,7 +95,7 @@ public void testNext() throws JSONException { ResponseListener listener = Mockito.mock(ResponseListener.class); session.next(listener); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); ArgumentCaptor argPacket = ArgumentCaptor.forClass(JSONObject.class); ArgumentCaptor argPayload = ArgumentCaptor.forClass(JSONObject.class); Mockito.verify(socket).sendMessage(argPacket.capture(), argPayload.capture()); @@ -115,7 +116,7 @@ public void testJumpToTrack() throws JSONException { ResponseListener listener = Mockito.mock(ResponseListener.class); session.jumpToTrack(7, listener); - Robolectric.runUiThreadTasksIncludingDelayedTasks(); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); ArgumentCaptor argPacket = ArgumentCaptor.forClass(JSONObject.class); ArgumentCaptor argPayload = ArgumentCaptor.forClass(JSONObject.class); Mockito.verify(socket).sendMessage(argPacket.capture(), argPayload.capture()); diff --git a/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java b/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java index cf580ea1..a024665d 100644 --- a/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java +++ b/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java @@ -1,19 +1,20 @@ package com.connectsdk.service.upnp; +import com.connectsdk.BuildConfig; 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.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; /** * Created by oleksii on 4/27/15. */ @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class DLNAHttpServerTest { DLNAHttpServer server; diff --git a/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java b/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java index 538f47ef..dce97ff5 100644 --- a/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java +++ b/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java @@ -1,10 +1,9 @@ package com.connectsdk.service.webos; +import com.connectsdk.BuildConfig; 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; @@ -12,13 +11,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.robolectric.RobolectricTestRunner; +import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; import java.net.URI; @RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class) +@Config(constants = BuildConfig.class, sdk = 21) public class WebOSTVServiceSocketClientTest { private WebOSTVServiceSocketClient socketClient; From 54bfc374c573f764645379565c6797d071d35018 Mon Sep 17 00:00:00 2001 From: David Mayboroda Date: Tue, 8 Dec 2015 02:53:28 +0200 Subject: [PATCH 04/41] fixed network on main thread exception --- .../discovery/provider/ssdp/SSDPClient.java | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java index 234e2528..402a2a64 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java +++ b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java @@ -20,6 +20,14 @@ package com.connectsdk.discovery.provider.ssdp; +import android.os.Handler; +import android.os.HandlerThread; +import android.text.TextUtils; +import android.util.Log; + +import com.connectsdk.BuildConfig; +import com.connectsdk.core.Util; + import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -66,6 +74,11 @@ public class SSDPClient { int timeout = 0; static int MX = 5; + private static HandlerThread HANDLER = new HandlerThread("join_thread"); + static { + HANDLER.start(); + } + public SSDPClient(InetAddress source) throws IOException { this(source, new MulticastSocket(PORT), new DatagramSocket(null)); } @@ -77,8 +90,27 @@ public SSDPClient(InetAddress source, MulticastSocket mcSocket, DatagramSocket d multicastGroup = new InetSocketAddress(MULTICAST_ADDRESS, PORT); networkInterface = NetworkInterface.getByInetAddress(localInAddress); - multicastSocket.joinGroup(multicastGroup, networkInterface); + joinGroup(); + bind(); + } + + private void joinGroup() { + Handler joinHandler = new Handler(HANDLER.getLooper()); + joinHandler.post(new Runnable() { + @Override + public void run() { + try { + multicastSocket.joinGroup(multicastGroup, networkInterface); + } catch (IOException e) { + if (BuildConfig.DEBUG && !TextUtils.isEmpty(e.getMessage())) { + Log.i(Util.T, e.getMessage()); + } + } + } + }); + } + private void bind() throws SocketException { datagramSocket.setReuseAddress(true); datagramSocket.bind(new InetSocketAddress(localInAddress, 0)); } From 48b90f7df7b01d184a70102b85f4c40efa6b4e5b Mon Sep 17 00:00:00 2001 From: David Mayboroda Date: Tue, 8 Dec 2015 20:47:12 +0200 Subject: [PATCH 05/41] ZeroConf filter nullpointer fix --- .../provider/ZeroconfDiscoveryProvider.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java index a72381fc..c5b7571d 100644 --- a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java @@ -20,6 +20,16 @@ package com.connectsdk.discovery.provider; +import android.content.Context; +import android.text.TextUtils; +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; + import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; @@ -35,15 +45,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"; @@ -216,7 +217,9 @@ public void stop() { if (jmdns != null) { for (DiscoveryFilter searchTarget : serviceFilters) { String filter = searchTarget.getServiceFilter(); - jmdns.removeServiceListener(filter, jmdnsListener); + if (!TextUtils.isEmpty(filter)) { + jmdns.removeServiceListener(filter, jmdnsListener); + } } } } @@ -245,7 +248,9 @@ public void rescan() { if (jmdns != null) { for (DiscoveryFilter searchTarget : serviceFilters) { String filter = searchTarget.getServiceFilter(); - jmdns.addServiceListener(filter, jmdnsListener); + if (!TextUtils.isEmpty(filter)) { + jmdns.addServiceListener(filter, jmdnsListener); + } } } } catch (IOException e) { From 98d375367391f2fd8f2d6dc0f680c1e3ed0b4652 Mon Sep 17 00:00:00 2001 From: David Mayboroda Date: Wed, 9 Dec 2015 04:48:44 +0200 Subject: [PATCH 06/41] Fix for RejectedExecutionException on SSDPDiscoveryProvider --- .../discovery/provider/SSDPDiscoveryProvider.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java index bcf9a9ee..02c17b6c 100644 --- a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java @@ -208,6 +208,12 @@ public void rescan() { if (executorService == null || executorService.isShutdown()) { Log.w(Util.T, "There are no filters added"); } else { + if (executorService.isTerminated() || executorService.isShutdown()) { + if (serviceFilters != null && !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 */ From edc686aaa0eed1cdac5e70b97c050ebb69c04d5f Mon Sep 17 00:00:00 2001 From: Sebastian Prehn Date: Mon, 14 Mar 2016 20:04:13 +0100 Subject: [PATCH 07/41] call to datagramSocket.disconnect() results in deadlock with receive on shutdown and is not necessary --- src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java index 234e2528..6088f536 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java +++ b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java @@ -132,7 +132,6 @@ public void close() { } if (datagramSocket != null) { - datagramSocket.disconnect(); datagramSocket.close(); } } From e2e7cb92a0a78346ba136506d9581e21a8ae103d Mon Sep 17 00:00:00 2001 From: Sebastian Prehn Date: Sat, 29 Oct 2016 20:51:30 +0200 Subject: [PATCH 08/41] synchronized all changes in openhab plugin to this repository --- src/com/connectsdk/core/Util.java | 71 ++--- src/com/connectsdk/device/DevicePicker.java | 103 ------ .../device/DevicePickerAdapter.java | 99 ------ .../device/DevicePickerListView.java | 112 ------- src/com/connectsdk/device/PairingDialog.java | 79 ----- .../connectsdk/device/SimpleDevicePicker.java | 296 ------------------ .../discovery/DiscoveryManager.java | 2 +- .../provider/SSDPDiscoveryProvider.java | 110 ++++--- .../provider/ZeroconfDiscoveryProvider.java | 5 +- .../discovery/provider/ssdp/SSDPClient.java | 40 +-- .../webos/WebOSTVServiceSocketClient.java | 34 +- 11 files changed, 117 insertions(+), 834 deletions(-) delete mode 100644 src/com/connectsdk/device/DevicePicker.java delete mode 100644 src/com/connectsdk/device/DevicePickerAdapter.java delete mode 100644 src/com/connectsdk/device/DevicePickerListView.java delete mode 100644 src/com/connectsdk/device/PairingDialog.java delete mode 100644 src/com/connectsdk/device/SimpleDevicePicker.java diff --git a/src/com/connectsdk/core/Util.java b/src/com/connectsdk/core/Util.java index 75378138..533416ef 100644 --- a/src/com/connectsdk/core/Util.java +++ b/src/com/connectsdk/core/Util.java @@ -24,61 +24,46 @@ 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; +import android.content.Context; + public final class Util { static public String T = "Connect SDK"; - static private Handler handler; - - static private final int NUM_OF_THREADS = 20; - - static private Executor executor; - - static { - createExecutor(); + static private ExecutorService executor; + static private InetAddress localIP; + + /** + * Configure Util on component start. + * + * @param e must not be null + * @param ip may be null + */ + public static void start(ExecutorService e, InetAddress ip) { + executor = e; + localIP = ip; } - 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 stop() { + executor = null; + localIP = 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) { @@ -90,7 +75,7 @@ public static Executor getExecutor() { } public static boolean isMain() { - return Looper.myLooper() == Looper.getMainLooper(); + return true; } public static void postSuccess(final ResponseListener listener, final T object) { @@ -140,16 +125,6 @@ public static boolean isIPv6Address(String 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); - } + return localIP; } } \ No newline at end of file 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/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/discovery/DiscoveryManager.java b/src/com/connectsdk/discovery/DiscoveryManager.java index 21b26d98..84af81df 100644 --- a/src/com/connectsdk/discovery/DiscoveryManager.java +++ b/src/com/connectsdk/discovery/DiscoveryManager.java @@ -366,7 +366,7 @@ public boolean deviceIsCompatible(ConnectableDevice device) { public void registerDefaultDeviceTypes() { final HashMap devicesList = DefaultPlatform.getDeviceServiceMap(); - for (HashMap.Entry entry : devicesList.entrySet()) { + for (Map.Entry entry : devicesList.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); try { diff --git a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java index 02c17b6c..69b8db75 100644 --- a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java @@ -20,20 +20,6 @@ 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; @@ -53,6 +39,20 @@ import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.SAXException; + +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 android.content.Context; +import android.util.Log; + public class SSDPDiscoveryProvider implements DiscoveryProvider { Context context; @@ -86,13 +86,15 @@ public SSDPDiscoveryProvider(Context context) { } private void openSocket() { - if (ssdpClient != null && ssdpClient.isConnected()) + if (ssdpClient != null && ssdpClient.isConnected()) { return; + } try { InetAddress source = Util.getIpAddress(context); - if (source == null) + if (source == null) { return; + } ssdpClient = createSocket(source); } catch (UnknownHostException e) { @@ -108,8 +110,9 @@ protected SSDPClient createSocket(InetAddress source) throws IOException { @Override public void start() { - if (isRunning) + if (isRunning) { return; + } isRunning = true; @@ -128,8 +131,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(); @@ -154,8 +157,9 @@ public void sendSearch() { notifyListenersOfLostService(service); } - if (foundServices.containsKey(key)) + if (foundServices.containsKey(key)) { foundServices.remove(key); + } } rescan(); @@ -266,6 +270,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) { @@ -283,6 +290,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) { @@ -295,37 +305,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(); @@ -340,8 +356,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); @@ -360,8 +377,9 @@ private void handleSSDPPacket(SSDPPacket ssdpPacket) { getLocationData(location, uuid, serviceFilter); } - if (foundService != null) + if (foundService != null) { foundService.setLastDetection(new Date().getTime()); + } } } @@ -475,8 +493,9 @@ public List serviceIdsForFilter(String filter) { if (ssdpFilter.equals(filter)) { String serviceId = serviceFilter.getServiceId(); - if (serviceId != null) + if (serviceId != null) { serviceIds.add(serviceId); + } } } @@ -487,20 +506,21 @@ 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) { -// } + // List servicesRequired = new ArrayList(); + // + // for (JSONObject serviceFilter : serviceFilters) { + // } - // TODO Implement this method. Not sure why needs to happen since there are now required services. + // TODO Implement this method. Not sure why needs to happen since there are now required services. return true; } diff --git a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java index c5b7571d..67d673a3 100644 --- a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java @@ -21,7 +21,6 @@ package com.connectsdk.discovery.provider; import android.content.Context; -import android.text.TextUtils; import android.util.Log; import com.connectsdk.core.Util; @@ -217,7 +216,7 @@ public void stop() { if (jmdns != null) { for (DiscoveryFilter searchTarget : serviceFilters) { String filter = searchTarget.getServiceFilter(); - if (!TextUtils.isEmpty(filter)) { + if (filter != null && !filter.isEmpty()) { jmdns.removeServiceListener(filter, jmdnsListener); } } @@ -248,7 +247,7 @@ public void rescan() { if (jmdns != null) { for (DiscoveryFilter searchTarget : serviceFilters) { String filter = searchTarget.getServiceFilter(); - if (!TextUtils.isEmpty(filter)) { + if (filter != null && !filter.isEmpty()) { jmdns.addServiceListener(filter, jmdnsListener); } } diff --git a/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java index 7d8811ce..971b0eb6 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 @@ -20,14 +20,6 @@ package com.connectsdk.discovery.provider.ssdp; -import android.os.Handler; -import android.os.HandlerThread; -import android.text.TextUtils; -import android.util.Log; - -import com.connectsdk.BuildConfig; -import com.connectsdk.core.Util; - import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -74,11 +66,6 @@ public class SSDPClient { int timeout = 0; static int MX = 5; - private static HandlerThread HANDLER = new HandlerThread("join_thread"); - static { - HANDLER.start(); - } - public SSDPClient(InetAddress source) throws IOException { this(source, new MulticastSocket(PORT), new DatagramSocket(null)); } @@ -90,27 +77,8 @@ public SSDPClient(InetAddress source, MulticastSocket mcSocket, DatagramSocket d multicastGroup = new InetSocketAddress(MULTICAST_ADDRESS, PORT); networkInterface = NetworkInterface.getByInetAddress(localInAddress); - joinGroup(); - bind(); - } - - private void joinGroup() { - Handler joinHandler = new Handler(HANDLER.getLooper()); - joinHandler.post(new Runnable() { - @Override - public void run() { - try { - multicastSocket.joinGroup(multicastGroup, networkInterface); - } catch (IOException e) { - if (BuildConfig.DEBUG && !TextUtils.isEmpty(e.getMessage())) { - Log.i(Util.T, e.getMessage()); - } - } - } - }); - } + multicastSocket.joinGroup(multicastGroup, networkInterface); - private void bind() throws SocketException { datagramSocket.setReuseAddress(true); datagramSocket.bind(new InetSocketAddress(localInAddress, 0)); } @@ -164,7 +132,7 @@ public void close() { } if (datagramSocket != null) { - datagramSocket.close(); + datagramSocket.close(); } } diff --git a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index 14e83f6e..ce1b2314 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; @@ -20,7 +21,8 @@ import javax.net.ssl.X509TrustManager; 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; @@ -36,8 +38,8 @@ import android.util.Base64; import android.util.Log; import android.util.SparseArray; -import android.view.Display; -import android.view.WindowManager; +//import android.view.Display; +//import android.view.WindowManager; import com.connectsdk.core.Util; import com.connectsdk.discovery.DiscoveryManager; @@ -372,16 +374,16 @@ private void helloTV() { String OSVersion = 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; @@ -393,7 +395,8 @@ private void helloTV() { String applicationName = (String) (applicationInfo != null ? packageManager.getApplicationLabel(applicationInfo) : "(unknown)"); // 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(); @@ -677,8 +680,15 @@ else if (payloadType.equals("hello")) { } } + // 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() { From db52d76dbad331354ec5d80df34f6b3ec1c1a222 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn Date: Sat, 29 Oct 2016 23:39:43 +0200 Subject: [PATCH 09/41] added fake antroid classes and converted project to maven --- .classpath | 23 +- .gitignore | 3 +- .project | 23 +- AndroidManifest.xml | 13 - README.md | 5 +- libs/java-websocket-patch.jar | Bin 108309 -> 0 bytes libs/javax.jmdns_3.4.1-patch2.jar | Bin 210945 -> 0 bytes pom.xml | 47 + project.properties | 16 - res/drawable-hdpi/ic_launcher.png | Bin 9397 -> 0 bytes res/drawable-mdpi/ic_launcher.png | Bin 5237 -> 0 bytes res/drawable-xhdpi/ic_launcher.png | Bin 14383 -> 0 bytes res/values-v11/styles.xml | 11 - res/values-v14/styles.xml | 12 - res/values/strings.xml | 5 - res/values/styles.xml | 20 - src/android/content/BroadcastReceiver.java | 38 + src/android/content/Context.java | 148 +++ src/android/content/Intent.java | 368 ++++++++ src/android/content/IntentFilter.java | 219 +++++ src/android/content/pm/ApplicationInfo.java | 65 ++ src/android/content/pm/PackageInfo.java | 33 + src/android/content/pm/PackageItemInfo.java | 27 + src/android/content/pm/PackageManager.java | 152 +++ src/android/graphics/Bitmap.java | 64 ++ src/android/graphics/BitmapFactory.java | 40 + src/android/graphics/PointF.java | 22 + .../graphics/drawable/BitmapDrawable.java | 46 + src/android/graphics/drawable/Drawable.java | 66 ++ src/android/net/ConnectivityManager.java | 38 + src/android/net/NetworkInfo.java | 46 + src/android/net/wifi/WifiManager.java | 172 ++++ src/android/os/Build.java | 61 ++ src/android/os/Environment.java | 49 + src/android/os/Parcelable.java | 18 + src/android/support/annotation/NonNull.java | 31 + src/android/text/Html.java | 17 + src/android/text/Spanned.java | 26 + src/android/text/TextUtils.java | 73 ++ src/android/util/AndroidException.java | 7 + src/android/util/Base64.java | 24 + src/android/util/ContainerHelpers.java | 51 + src/android/util/Log.java | 134 +++ src/android/util/SparseArray.java | 356 +++++++ src/android/util/Xml.java | 44 + src/android/view/Display.java | 20 + .../internal/util/GrowingArrayUtils.java | 170 ++++ .../discovery/DiscoveryManager.java | 374 +++++--- .../connectsdk/service/WebOSTVService.java | 885 +++++++++--------- .../webos/WebOSTVServiceSocketClient.java | 304 +++--- test/.project | 17 - test/README.md | 36 - .../com/connectsdk/core/MediaInfoTest.java | 93 -- .../com/connectsdk/core/SubtitleInfoTest.java | 65 -- test/src/com/connectsdk/core/TestUtil.java | 88 -- .../device/ConnectableDeviceTest.java | 166 ---- .../DiscoveryFilterParameterizedTest.java | 59 -- .../discovery/DiscoveryManagerTest.java | 114 --- .../provider/DiscoveryFilterTest.java | 25 - .../provider/SSDPDiscoveryProviderTest.java | 215 ----- .../ZeroConfDiscoveryPrividerTest.java | 317 ------- .../provider/ssdp/SSDPClientTest.java | 120 --- .../provider/ssdp/SSDPDeviceTest.java | 138 --- .../provider/ssdp/SSDPPacketTest.java | 96 -- .../service/AirPlayServiceTest.java | 179 ---- .../service/DIALServiceSendCommandTest.java | 205 ---- .../connectsdk/service/DIALServiceTest.java | 100 -- .../service/DLNAServiceSendCommandTest.java | 130 --- .../connectsdk/service/DLNAServiceTest.java | 461 --------- .../service/NetCastTVServiceTest.java | 142 --- .../connectsdk/service/RokuServiceTest.java | 125 --- .../service/WebOSTVServiceTest.java | 492 ---------- .../service/airplay/PListParserTest.java | 159 ---- .../capability/KeyCodeParameterizedTest.java | 92 -- .../roku/RokuApplicationListParserTest.java | 89 -- .../sessions/WebOSWebAppSessionTest.java | 272 ------ .../service/upnp/DLNAHttpServerTest.java | 37 - .../webos/WebOSTVServiceSocketClientTest.java | 45 - .../com/connectsdk/shadow/WifiInfoShadow.java | 23 - 79 files changed, 3559 insertions(+), 4907 deletions(-) delete mode 100644 AndroidManifest.xml delete mode 100644 libs/java-websocket-patch.jar delete mode 100644 libs/javax.jmdns_3.4.1-patch2.jar create mode 100644 pom.xml delete mode 100644 project.properties delete mode 100644 res/drawable-hdpi/ic_launcher.png delete mode 100644 res/drawable-mdpi/ic_launcher.png delete mode 100644 res/drawable-xhdpi/ic_launcher.png delete mode 100644 res/values-v11/styles.xml delete mode 100644 res/values-v14/styles.xml delete mode 100644 res/values/strings.xml delete mode 100644 res/values/styles.xml create mode 100644 src/android/content/BroadcastReceiver.java create mode 100644 src/android/content/Context.java create mode 100644 src/android/content/Intent.java create mode 100644 src/android/content/IntentFilter.java create mode 100644 src/android/content/pm/ApplicationInfo.java create mode 100644 src/android/content/pm/PackageInfo.java create mode 100644 src/android/content/pm/PackageItemInfo.java create mode 100644 src/android/content/pm/PackageManager.java create mode 100644 src/android/graphics/Bitmap.java create mode 100644 src/android/graphics/BitmapFactory.java create mode 100644 src/android/graphics/PointF.java create mode 100644 src/android/graphics/drawable/BitmapDrawable.java create mode 100644 src/android/graphics/drawable/Drawable.java create mode 100644 src/android/net/ConnectivityManager.java create mode 100644 src/android/net/NetworkInfo.java create mode 100644 src/android/net/wifi/WifiManager.java create mode 100644 src/android/os/Build.java create mode 100644 src/android/os/Environment.java create mode 100644 src/android/os/Parcelable.java create mode 100644 src/android/support/annotation/NonNull.java create mode 100644 src/android/text/Html.java create mode 100644 src/android/text/Spanned.java create mode 100644 src/android/text/TextUtils.java create mode 100644 src/android/util/AndroidException.java create mode 100644 src/android/util/Base64.java create mode 100644 src/android/util/ContainerHelpers.java create mode 100644 src/android/util/Log.java create mode 100644 src/android/util/SparseArray.java create mode 100644 src/android/util/Xml.java create mode 100644 src/android/view/Display.java create mode 100644 src/com/android/internal/util/GrowingArrayUtils.java delete mode 100644 test/.project delete mode 100644 test/README.md delete mode 100644 test/src/com/connectsdk/core/MediaInfoTest.java delete mode 100644 test/src/com/connectsdk/core/SubtitleInfoTest.java delete mode 100644 test/src/com/connectsdk/core/TestUtil.java delete mode 100644 test/src/com/connectsdk/device/ConnectableDeviceTest.java delete mode 100644 test/src/com/connectsdk/discovery/DiscoveryFilterParameterizedTest.java delete mode 100644 test/src/com/connectsdk/discovery/DiscoveryManagerTest.java delete mode 100644 test/src/com/connectsdk/discovery/provider/DiscoveryFilterTest.java delete mode 100755 test/src/com/connectsdk/discovery/provider/SSDPDiscoveryProviderTest.java delete mode 100644 test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java delete mode 100644 test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java delete mode 100644 test/src/com/connectsdk/discovery/provider/ssdp/SSDPDeviceTest.java delete mode 100644 test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java delete mode 100644 test/src/com/connectsdk/service/AirPlayServiceTest.java delete mode 100644 test/src/com/connectsdk/service/DIALServiceSendCommandTest.java delete mode 100644 test/src/com/connectsdk/service/DIALServiceTest.java delete mode 100644 test/src/com/connectsdk/service/DLNAServiceSendCommandTest.java delete mode 100644 test/src/com/connectsdk/service/DLNAServiceTest.java delete mode 100644 test/src/com/connectsdk/service/NetCastTVServiceTest.java delete mode 100644 test/src/com/connectsdk/service/RokuServiceTest.java delete mode 100644 test/src/com/connectsdk/service/WebOSTVServiceTest.java delete mode 100644 test/src/com/connectsdk/service/airplay/PListParserTest.java delete mode 100644 test/src/com/connectsdk/service/capability/KeyCodeParameterizedTest.java delete mode 100644 test/src/com/connectsdk/service/roku/RokuApplicationListParserTest.java delete mode 100644 test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java delete mode 100644 test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java delete mode 100644 test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java delete mode 100644 test/src/com/connectsdk/shadow/WifiInfoShadow.java diff --git a/.classpath b/.classpath index 51769745..7397c6ef 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..59ca793d 100644 --- a/.project +++ b/.project @@ -1,33 +1,28 @@ - Connect-SDK-Android-Core + Connect-SDK-Java-Core - com.android.ide.eclipse.adt.ResourceManagerBuilder + org.eclipse.m2e.core.maven2Builder - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.jdt.core.javabuilder.launch + - 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..54774782 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 diff --git a/libs/java-websocket-patch.jar b/libs/java-websocket-patch.jar deleted file mode 100644 index 22cda9f4a7fccad5f58370119e98c957c9e179ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108309 zcmbTd18`;0x-OcelTJFe(XnlJY};P3ZLc`#*tTukwr!(hygujbbL;K%_TBH@x2on^ zvucjN#+YOM-}iIKOML@}2KkRqi%zo0f8PA#>&M?;84+axS_xTEdij40g92&(J8VL2 zdfWEzi>P1jDW0!sECp>os8(c%*42~6fNB>oD?n9)WmeXBEtgn&Y=U1Hm6#|K|vl ze~hp&a52zxH8FIwHL^5u`ZogD|60Jv%G|`}|A(Bhg8{(F@!!mc|F7pWaWgWpb27KJ z`FFB7|5_H{U|?--^Y3;A?_Ud=8Q2&*ni*J{{G0XuZ}!L0#KFbH;orz%{_827oy@KN zmlV{0{=vos8%FfsKtRGFK|q-QwUmINqmzSyk&~K(ft{U+v7oz?iO}E0+n89<8Ce-P zIwr}W@Q{D=!)teN zfb?1aVG+TE=g9?g$O%!Jd9u@W>Lv63Yn!>-$M+3hA6AMn2vbzXlHaqWOGPjHCd1l7 zY-5z}z-m~L)pS`gLL^Ji>-whf+aiM-ArMNa5^5S<*@(YAmHQwKMF^t*7f11`8Oju{o2;3EWy>trg;ijU{EC-iON96hO1U>?_U9q>}H4HY_m~ zuR8s{&EXTjzXZdowgdaevZx5%MOg~N^NC>(_k>Nz<+8g1>5}W{M<#QDl0YjcXWnHm z&XA%Jy4pQ#B_FeJ&))48elq~5inTX>&7$k%G+$$MVr=%?AGNvdv{NDnr`hnt;N-Qq z7+P~ylQ%m4Yu8+e!!$=|6FGYFM?Y$;@wKq^W<~gU)ushS z{p{04>80fovOF05A67}tbb>iP$jzDq5I_9fUa1ovZcIt|=jejCUaNDpe}+L>Q07NN z{c@zlhBE^{C<`l*W=gl6u=)ugHet~jwThK)^YK`gHAPx;7Ju!Kk}KdR;y;Q%&t{k|lv;=%IxhqK6J+#he>4I+6k$wA}0G-(wMp|TZ{rQS*8{@yUPM^Htnl`S!dV7w^H1Hq@zd1R)R(RofNZz- z*8@b4$%X==ev0!(+-IMgIZyR{z;Q~t_6cBcuW1GYCd&>^$=K^Y_uT5*cnoNLA0B|% z|3H}vNg1P)uX#B55WVw8345ucv72Rp(OFkJibcekTDhK-Ki=bHZ4}r}2|RKiZyEsW z7k{Vdvr4#qFk)2-V+G0&Q97UrWX$H|h(HLX16`aD4RZl1;mC~Jzb>N5vC*i3I&=4Z zjTee#5T;mZ==Z5ssv;Of&}~?K?K+ua@d<=+MyCUs^zCYEw3c?Nc`Po+XmjNy z*yXs#E@qN3^iqc8w`_J|_vJTP0%#+zu$U=HFxU zc2FC8R!NB5%TBVs=t!M$K6o|)NYu?zREfmtlb6)5AT|S>iW7_L6D!n=$FK88M|n#| z59k`EZs@r9^RB;r-_EgqVK$U2dStl!gICBx7{C{)GzKAgMu^k!F^5A)9j+TWgGFvz zp@9B_1oVq7jIs=obj5t)C&=bB+ychML_SyTVM9my# zzjc1lf5t|G?=b`;1PF)(JP63Ie~S%a6M%uUm6MW^w3>;b(tmm#{{<7#zjn*k!TrAs z)u5`i5{?S04;^@uL{pNWlvLuK;@S~JTa!w;L}8)7#TsgZRA~bhUAmOIy377mQP1njdsr|-f71y$E&TkIu%j?RB1}Dgttm}4? zYZH6W?B5_VVViNpHZd#+;9kV~9BPQYY%C#rGoDc#hk{y3gnjHSqjnOn zW{Ev@teR%3JaRiSv9*GP&R4wk(z2hK?6kwsLs+jUQT=4c6n0azcbKv}1p#!x`;eh0 z6{q|VgPGm)w!;J~zV-|I{F3zX4)t1h`{CGK3nGo|bI@(PIYx#IRU|Qbp)16tN{OEi z+zK_gd^#Fh2U``jW{$wC088x0j9rbr)>kHE8ZEy5$-dcj5}c(vNk*W{Lxl7ca|3yt zBlLGHpldpX?Rtmt3W{!NohV}wo3t)G&2pFl$cIAQZU8jI@W4f0IE5kX@Sh$AH3CeN zQ4N8BT`S^X)B;RVO@%PRt}Cp=jk;Zq4M0gyon`c)1>kvZx$G1ev+4oAQN%0oetkb# zrc+c3iT_8OExV%rXbRBdDj4U&`ojwXTPQ~R*XK*>@<3~3Io0Lqxw3kE8{JOAU4l{` zHnX+_3-}hX!iikxBb^O}TgQN8az1${h{{14HjWokJQD5R|a3 zj#Y`ViL#zqQixZ&Ti~SbrVDpg>N%!RU?2KF=2n=VKg$%>WA((2_y!&yBG7i-rdg*ky$ zuGfSu8e5!D)dYkFz{0PB@H>y1ygena(VEXMEA>$W89O&|)1)g^p7`y?AP0k{z?8k6HZZ>-MutwS+VDw2p=dYJRROS$;&{VE-3u*pDR1?jAdf2MAGc@pf>|5ZPA(5*MKXbIf8p ze-KfqyF73_*#5;|kYzcB=!vNGvmKDuUo&?uV=}!a5Tgu}ETW?Z(qwY%-$!paL7_*a z&p3g@vSPY>m(pT-kWts~LDFi|2q*5r>-VQ!@D7+*n?sqEYAGI;6+3t z%Lgn9xP_}JBz*XJ3!$brjCXNv-=FOCEK&tP5sU+{r1#NlmBS8U`Epx`XeA%$3sBqI z7-j=hqMYkQ%}8|qygZz&u;E)ThA&YPR!KmY&QyvLMo%-)U)uBZDoOmky$!xVTQhwC z2#CH)g57@mHDq%|I1`2L7q0S?&OgblYRQVU!C40J!GX0ITm-o`x)AD`wBjR-F-+|C zpltEA`~p~hay;UTVS?Rmo;0|8Q<}(yxT9hEp!d&oOkfK4{raz~!UqKc!u$V)j{hAO zXR7}7Rs>K#fk|6tv^ikmV>;#$72)A6K_!UD4QE1V`|+tZA$2tuZ0$-Cz5!p~QQ*SJ zy3(HWBTb76p%7ll9uPc=Fy2(?5W$Y7%59!bD+Q3{1iL)JYDCWsL~QYXd7AnVBZ= z@28%AC=YPdCkew3`43+Ib-mv2Ebf8CKr*YK2|oq6 zs&>JVk@@1hiv(FD=7CFMhOW#(|I2ZTj+4CVUa5~c=OHfN2w zSyKeZsCO4<5&xA9xrZZo2j7=7v~;2(^S!Luj;He`nJr8kBVD6m{hjEes9m}bIH=P_ zF!!L_Uq*FMr37bQ7`NidS_<^Nkpo}M1pEwDL@X?vscCHt6%V&LNjP!nH8ow<`R9S7Z;35XLRHZ z47%}Jl{AFKVWyqOBc}nE^Gi=QZ!=l*Xp`qJma}QkqaZ`qBvc-}WL1C>%mi92l#~om z!tpJjv;~^%;2g`BGwMfW#0;~K@! zyby#1y((`_R83+nX)+mE)g&D0mw=36FSTVk;mvEtyx1kpcr5Tz=JqMfhP!YkI0lXB zn-!uT&z|-}2$o#9uz=4D-gFq%73En>b@|dGDcK_>dz}!Pg?wPsHu3{I+{Toj78}xHd|rTBm?AD-(f%xM7+zEL*47a6`L-1=0tx*VJ3}5=h zcct7R(U;j9B?wP1`R57~%Oq>8>T?)h;M%e;i1o6R#ZJ90@PxDM6hhe}O!TqQE^^); z+o#9VLa<)U184*>S1mGk;M%~)u_N(tDX=Lt%-4p|_qpXAq}u;b;>0iXB*RN*!B$67DVrC}_e``$MQ z4Ut>us~vQk`V%rfa)!|fv`|m9B8JK4F~+^ZbkL9Q|7>tl_cj9IK|w%n{$8U0M=<#x zu=%GbAWETKw*MDm1}h<%tlteHKL~_5M;IGiA5k2HA~Z(AiI*l8std~dgCFXW9v zXrqy$Fdc=gXFWHwXWHB6%R87|gc1h)F5S3MOH-Z(oaxd}&i{nivdQVFcf9UB9R0+}MwP=c?q-@}?xEzO&cT+d7G&i6V^> zm&@<6?NAwGb0qaK+Ku-|j0UOXY+2vq;U~RS?y^aHJ)apmDrliGg!(jy5q%i8WrNTF zY_FPwxs!>qnS+Ue@qa~K zg(~N=|B;s{f@o@pQ2uoT7TUO=m_USKD|HAF zmw1P;jI&^rCj?)gaj&kFjTwC-#yZh8 z>VwQKne#kiQo1(Mi-=t8mo(-?78b{#4GPetB|a$E4bSJ>co5LZK!qi6CQne{CltS?3JbCH z&2XWBBq*7!ZUK^?BO#B&b2ut-t5v!3Jkjt#nM<;*OQ&^$(?^tOynN$|bu~PN_WWx@xAxat1ytu)U zecu+6x!B*Jlj6%bc12nDgP$GpRJmF$$HVJzXhp0NcGC)D@bQ~!y5fDf$|1gmKLaH? zB=zx2hs1Qhe>;ZX=1P?FY^e_fUeL9FM-<>!+~Nukk(Lh-Bhh&E1MwCN<;zcBhVmAO z>@rN~GKlQ*9N-$?K{I45dWKSxzGRf5HG>U)LHM1f#$kh*@#GZj9J%?ggl9`)i*&WO(~)DPNdnGrl@D z#9WePNw<@-h1AU?rj`-kdew@gOskKOIIcw3*2+qm-D0s(bXD54m8N-_)(XyrG%`h0 zw}?nX84q4`t$f)@jHoxtAds@08{H6lHYZD@=1&~!A6DsA+F9|S(+OZaQuXx(v{B{K z98#okB*Q#-gfxYw^=5>c)?He%I&U61`o$TO=B3QO4jb)S62qLtxOX3_(Kv5#rJu1A4DIv|TCGF-2)6y!V!Bo>ePY4qSgb>r-nxS@Rm zd0tW&AMLK$Mh%;Jn0ztPB~Vlwq10o~x;IIfr76lhHXV4So|V>*Y3)NVLixsKk{ zG!)5kA)hoP$m^rXp(rOrgnaK` z8%}u+Qo3eVzFQ0pZN>s|B%5B&1`EceqKKv>QI3Q#7`YTo85i}#?Ppae%Q5miCs(G3 zX?VLJl97q)u_$rVQjmj!Py;EZE=FYV!CG5t%m;1yF5~$c_cU@@jp5Iu;);1QbVPn| z6iR$aDq=*>j96EE>_N9JdPxBB^Eqo%lOh-@99)B>RXsMK3Ir#&R69gDjHNBXd@5|SX2lG~B?RS4;Gp== z0!;_qH$H0F-qa%H}IG@Yz%t$({0}#znTGvxW zRbX9WD0Rh)iKvoR0hzM-3O;8AC887v@sOrhZfYfMvrssO$&0loNr-XfvN}$zOoGYI zlc*&rdvSj@AD5umNkYJ#i2?aKqQ<`jK+&}&;3~L$&T_4>twn0F3`=DRau5QL^cT@B z#E$e(hm2MNO7rqo6XTK9l7IB;_AfX(%vJylTT*`^hZN2y#FtmhlBbM?Sg?9I zeN$4=VF-Fv%nD6P-!sx`y{xF0Vn26+@&3+A zWV4#TGNh`B7G=}_%^8ECM9<_6sxnIDeEtyoU6i$@LIj;2OTDtmITcMRU#DbbYM^}f z*ngc+x@s0f{`@iKj$uAHJr!xaKH$EOMt0oC#fqt_DnnMzVjr@6Ws+p7WQa^_x zO3D>rWob+oFq-XK$l+{M`Y$S7{Gf57Sz-5ylW3g0uI#Hqwx}-9ROWUb{!OtbsX7lo z^9E*(!ZZ!HSuq5#WvmV3eIYJh8V%V9oUp`RS)r@TWlD*7zeqPCOeGJz8S{WMS{j}C z-s@(xaLWhlB768o;?OX4cB1^n*wj?~#nbUQB9@_JD z^Ur0^q=C&#<=Y?bNT1aDAtbxKx)!l-v~VM~>4A$KmwzShgyLJ>|9kzjWaX?>El zcq+vW>&N{8+&zc1ywMibqNP$2FLKM7C*gj|Wqyi$sfMKKC+iHhQ3GiV$t!qkmK}`J zrCe36RjV_^sAsSFxjLn;LD2wQI<%&sS``pBhMbhJgM=7 zi7RiTcK||08HUH%iVDma70E`qiMSjQop#8U(y>aXJ+hY|tfAGbMD|s(!OA)#3W>Yp048u<8cV)|?~gO79(i z#LT)mg?C`;Sap`PSHj7lC*PfpocA&)LgI$?l-Ys(?5rD_HsO)oXP%jFG2;hu{!^ZW zy-SzNmo*-XGGS+1W>?7lFdmRQvp_?}sdQZLMzmnVs%dA8Dx$qw>NFVd%%{bWXd;Y) zy|2$XDg%9=85pRBuVz;`r4kqXk^3y!Z>E!Pr#y6gqCI)smymZ6UXt+{_*LK6k1R?# z#iMhK#e;G>Ea_)H3F#c@lSM0^9xoYDDo9Zo(kZ)tKg$5e=3e;=?)`G?aK&HIu4z14 zzhLl}yRAr`Jqyn&o_HK)n=(4@@L)SRK*gw86l=_XOEhKKC&R$eNrm^feF{+IdY3FQ zos0Fc96`-!$;@lkuWCTLPLWNX$mNbHGg->(n5YX!iz`yLf0&~T@MmD(r)pn?tNJJc z)MEeaN}nUkeoM3Pm9VF0IEtc`*FK6~AUS^2O2L&Pk~ubJIe+yc+A3N!kN41iaAMlB z6pnwR;@+eKG;#nP3H)5SIdC&a3;h(E&^~xdEu5-LctJ7FR4M&oFg$UH_Dam8|0-5K zuNk~Q*D2cdftY)Brj=F&pazM8=TI$l{Ch9V6T=mUL#f{^-5Fl0@DUg#?wQv=+=Ht& z9#5B94FC`Q&bB#31;xHPnH9+TRQqs<@#+QxY|Xn=Wn5w7*p^ME1Kcvo1{d6hq!hK9 zZN<*juPv$f`KB%U-MO$Zb!75a+&iCDMA11#A;q{1Yeo)=c95c<^|ek66F@wwZ2LD7 zEW1PQt0ydyl84pnWSqD}j^=Z}e9z<`W$#PS$6H^bfK2UErZ0epY*C3H&OSq%gTtxIQrx@e0U!L986_!*u8MFH-(M|R>aYN%Z? zn8w*KwM7_wYCrScJ@XnB%ppJ^a;%d6%qw{V*{=enI08g(?qxi#w=w#s;T9OZKPlar1gW!eFqdq3})2G&h|-^F*uHtT*J!nk+I`s~+`@~O{6{rTbms}wq&jfHl*-DMnh?O(q1jknLB za_H!*!NxG-eow}XCT4R~Jmw4Y+b|m_V!b*j*x8&~nA`2-wm(Hl>4uw{Q!%!M6=Toa zb}%CqV<k<3#!>nHqkE3wUKsx#w(%h0SLziy65JlHpm1^C zws4$FT5N~RHTy(Zi~eZpxxOg_$%Pk?S{MKVYmW0kr+Y(i|Nox`12RWqifOHZu-otxV|o@+?_ z={orsGdWilyuE&aV@Fs?hvY94@b9QfMYm|=^{E$3{I3v7ude~Lv?vk3cayFb9uh=SIDj0Fo0mUX4{9-Qsl7G~3mA1*@1cJ+Y(uQGH z5b6^w@Ch`><7t5;r-vg_bk*XiKvq`Y&97K>^}2EMv9d z`7|&cza^?&AUbV{Pe)S(N|@|Jt$cF zJ4O!Wv%|OW7HDqqwkL7Q@xOhL0H~xQ12*T;U+7 z;pKa!Vl+O)+H=TLHk3aqiRqvDtf68i(!L?cb4W1mHpV0Y$j!%Jb*VDajcVy9CFWe* z9U`Zo^*0bp_5vSvt+)iag-5)Vk15;uB(nd;`RA<_vU4)gDxSHn>^gGnbCowS>NYSp z0u7*Q^ZMynJsY?y$6h(5=q>7Cmb$|ACHRk8vd&JNwE5I#a5^IA6rtPbOeKkIyX=zI zIkg-3h69utiE@c6<hgmwe`_1?X z$*A_|1=Vp{3lZ(;&;$@ShCZQdpCD;0K6i~XaeD~kQTi*7R-&5yS53F}&vAs=+oG{L zzE{h*&n{gnBnBl+e0!5s0T1qwxCdEg#Ty@w?TIFDX(~l{dsQV6u@T%b%twgFS_J<& zDN{CZO!UpJWg4M2Sao_k*pFmJ^T|ixbj(MaB)Warm1R9hN@rNfZwQet$l> zIMeOja2*ykfLM#6$f5u|gTs1)?wC~N@Je%pD3yf@q}$omXEI*Qz(xDp^+{nVHBA{J zBQIVjk$mETIl!*N|CA;c3ICQb-YZ~QX@4?9?8y-;=D5`Y_UD92#$Y`y0UrnfQcdA3 z%E~ROM@TUeXZNqmFVeCP=9}Z{nkxrz&mPy2X&E(@rT{zfL|N+&-xhKV0QsAzeCxi*5I>_-~J`ALqMU zLv@dtJhI12^&$roCw?#V*K?*@a)g}6Wy%oap#c}k@icgTy-1UgZceN z%0O2OSQZ*y*Xa8||M}$7g;@V~3e(|-Vd#=k=8m)+2f1OgX*fY;0&D~Q@w>$4m^6n- zyvq;TyYM=;${z1&-lG)zx9a{q-5f{tfzH@sOToe$U1qL*u<8T6IUM%14$!bpdVf{1 zK(}zY;`yySn-K$2PoUhr3 zNiyEb@N|mDE;W`g!j}TJQkB@NoE@iyECbex#F$kTlDYLx6d69f!2iWimNttjD&J~uQm82cL zJCzmAxJR0q@OCpD8x?I!U4FZct7J}e>vn4QYHJoVW^3L6vHU~`SWvg=9-Jp5HpS`~CNAM)- z9y%uIv85C>yc4xtsX%3m4_BndMBgtbgg~EgesTdcPI|5sKF39+kX0FDzr8o#c)!Cr z;lwCXUhls7Un%n&Z@GiG4vaS|+VI1FTLrUh!TySO60f*QVPEL1^Lc>fobsfCU3wHs zid@Iv7%CvBbieW=w^)H^Yetf}2&qe3H%d{~HP94b-lSUPW5&9gJSlKX$_IO)8ArS8 z@0eceMlFZ9)E&)vV}_=n&%rega*}qt1UoC#=F2JZm=%v03_fe#D8U~qXaiS12Nt|S z(JLzx9QH>8#FsEiw!&k;%c5_LBtCsaBl^nq`xaT^=v{6oYTQv*c%c3K38?U6?qg{1 zvms;);^ZW6f76M7f5c0S1HO*PfsYkQrhKsIe99#QGSYjWnXr3te(TZ|Gj)NVH`y_MCLD4teePE^-El(m$$1^y41wtYP0my#aNdeZ?J~6!oi+v>J}ct=*-^L z(@-{zb^m$DB7pJ>N$hKYjj<_|@hdI6QJf_pmn9c_BL3i*i8R9BRvQT>W!%azjW!j4 zBUB&R`>wUluBO>F+IaCLNEU%#kX8xr$^F)e8ljyoQe}OuJ-$VA%}EQupjvOoJP3q8 z=Yq`}sY~On-22;4QzBBKdnk-yxXc0Tz+}jTf;ITF`*@$uw4`lfq?2Ii1<6>b=qGy%-qACf&*EAKXnxIa=Bc@S zWiz~v`1ds=uFs$RW{{~^o9v)C?8H4b_TuboNj43KX4Foi{_}cYYO>9N^T$1>(FXQo zfR`*#{(3K1#r=2?zer}cqPf->a(FZw*Y*&cFBxY5%~#ndk$vf(=#mv4$^(Ku_H?jB z@Anu;YGyP6sd2d;1Aco%`lc|9d;Z#Jykf0SjIVV#QZ?hegX3SLO60#rxkHiYZf<>_ zbt0BXa7a%~9*rro(mlw5wAZ(9flaWY9MOlTv>!xMIke+U%^9}c?)Pr$A09j!RA7#7 zv0+ihn7qPxlE_g#cwsie$_?bLk|D(zy#+ox|@wdwJ_P6Jh<6ozy z|ItY={2vYVBtllUjwa&&-L9_eZfEjeIqFR1ZMnbI=1;oKrApz2t2Q2t#4zVNnV7Wm-oP3M=aYm;qB###Vp*2>OfRr55$pz51?2^1sj zNJ_=vC7?;aIT};&P_nhBM*j6Hh!Y3}ab2+_zPeTlF6o=w(aEWxLu-uz3mkmvJd8TR zNit9WWD1OvR0}&wtEbL`ved_%v&XP6OTBI*Q7jy9g574l1XQI|4UIfyMKcg7lpyoW zI;jZB9%s+h6)&A(xf&~G)JHHZSFZsF$_q_25PBXr6EI#!a)N=W4diUgm;6q zXa&a7mD`F{S*7(Q2T7cr3xk`EBZ%?ne;bC{FCSh49X9|Y+SUz<{D^S;Y8}1G30g(p zH>f;eao8{9+Sr?*0Zs+CanX+!bF2}bx>rS1zEe1Ol>iRfX2K$Zcr!H1@P7e?E-vMl{tlifF;KBd|ohR+yjrwiX>&D4AWg_Ccvl_ZD4pd^b`k&>J& zM8)DBh*u%9pRQ0p`tCG8pj9IfC`>VV2JJwuLco4Q_4M0;#KqbMCBOrtG)n@56kuF` zv&b^Orp7(&B6YIH^`J%#li)+DzRZx%(sGIkld7;X^SS_U$9teSb8reE+rr7?xEX!J zO*d~y&*XsQT$q)eN=z7y9S04iky-mM6UCORE4I*#X%W)wVn7-Pm5BNY&Z6$XP5feg zwwXFNv=PqN(NQw2&Fb2gxcC2|zqk3t_!@upx9_k1{;jV3=b@DUapdHm^!I9wq+dra`~& z;vS?-dYaD_!J^ZnAZk?9Zd`lns`vfTDjXkh7v8y#6OdJ-}@chIl6F# z+&qixTtyJ+Y_4qv%PkK#^Ll@Ou<+$N3Lpa**~}{vvbTl zp|=oiH)0=vRKl+~N|ca7bT&_siD<`5XWQDAoIs#o{Ina=SzIGeCh)9+pJ8K$#82|Z0H6oJg7?WFQ00#f1Lx1io zf~YVgRN?*)gL#I*8MjH~Ptk1(6;QY!pnIets1gh4d`i9=(SelFR&^q&iDG)1W(M!@ z1gnG}$O-vrR<)sOI9adUO+)r)wB+c68G=${jO1BeQu0_+LMqGzt#|w2P!&m#8Hny9 zr(y$e$~VKx+TCFQXBGfRO&b ztLlI8YNN&vFVtoCFWYZbe!nHJ3T9%z#kePq$S|_pIY;!(mD=hkAuh*nC z16TB|eQ`HE>b&;e{^H(#%If;K8b1d8o7lw;2WKy0@^%)B+8^3Q0m!kT;V@jbxec8( z);n`A2nEV9h#@VIMjGpFUS;J2CeRZa*|(fq8f!Zb?Mxr^BYx$PM7RjI=S5jhwQ%!P zH&)geLz7|q#iZ#5rbs}F!su|^>~ZD3Zd zvz7XjO9o*W7X4Eaynel+V3pCWVtB#{i&t{?u1R@9+zAIu%KP~HH@Ik3LR6#FXdHzi zw~YegAjLDYC#{60iE+VTS;fcE6jALk)QTy8Da}%@;AZoh=H&^i(nnmlTx=vb)&S@j zbG&i|sYT`^#z2mE@901I77Cfsjp|~(qC^6nR?xcYXqlQLv|KiW->a^ftwW^Zu{R5h zm~Hl5J!Vv4(~1B!B4UAHDAL7sNe+?N8%6scD|9#H6-MZs6Ya=-17~E79_=3Mx%m*4 zV4d3|SDk{@f$x`C7ibet-~ztJndW+2M);;9%)khvKrAw$V(WqLYf(;9rS%ES8#Q)1 zirzBGsGT+|Eu01dGf}SVp07<(MWGhTU`Rsu1^}c#!tu@@dYPEC8dV zLK^oHO6)&7ax1*pSDi$~o0OuBnT&C(;NGp{;zRWxLw>E}P4i&mIG-%Y&1(@wz8Ri6 zy0Y^*iJ{zV@QoRfspjOjECb-_JeVo&acyRIEwMFw?xHV?*k(_!=d{s<(S;}g|Gt+$ zV@TdyTs2y&>vQ%CKe|$4*$k6-Q3Y{-B-RWksO2qg3KW>Fk0D<5LOL1ubo?=$|ACgE zg1<s9qo;r!`eT16P&g$g_ATyU$2h73mD$r05 z8a+1v<#eX$uHwos^Y-n7UHE3NSnErBr6)EF07h8U*2PQ$UP--*1Ovydv?NL{g|QVE z#j=SXG`M3$yd0GQ=dnMt^kZ9_nUDvRz)DU$M29hMNtdc4Q)Mw3>leq2%~vP!Up>{0 z@8l`729sIeJ91n^Tg#}PuzJf*M=w=pd=-Z2OKG4{{GxSsV$gg)4JPP5c^LO2Q z;Y6hu3wUIVmUKv--4-KLJkc*G6Yr`vgRO_dc`C<577Jy7XH00gse}t(AvbgQ#Fm5D zc;Jx*=TH;$F*r@Ng|GUE7~pGNPI^Er^>DQtOYAPfl2kqvyz0GWjh>aA22B9bmNm(D zED-8W==p=(pSq@02f-yyFG(=t7dvkiHzw{7s`v#T<>J(){a!EESXD< z;N8L7OE;Uhn_K3#nRE%DRZs&gZ-jetm_fv!bn1`ke&5oh>V9AqUH|F-dY!Um#3ln3S7}*Y`*=CYUCcL_MNaf8${=GtN|D1ZcQs?-@u}wLgq(mxAkfnM$-<32m z;Vh3jASct|){IH2#tiImtGB=!FP$R`+yp-2PT%2YDwjfO9ubKN2VMfSfPzNoTk^!R ziT_3qw%IB`^pNzB>n+aFSK;KQMCfg)AvD;3`1OCK2xJK%o7e zAw{wb7O|ovts+-UGbyX);xh#%U8d7BtcTdmZ49$8Dx)2m9)sb#XJUNZlrEaXR!n=8 zuy`io#y7CZv}DY)TmcVUnbQ^O>lEPJ{*$x{ejhfOssGpwa<9y(^3qnk#2{ww3&{5Q zR-Q~lc3A2kr~Na%V_E&NXt!YY600;iniCcRU;6Yt^Rpd)AJtC>(&dnfwxi4$;UIH| z5dDt^8v&P^jbrK{{ig?#3H@?4v_{U@FIo)FxrP2p^mefW#7q7_n z^ZVVryU{1*fTPlc%wE}1TAem0+##eQm5S|1IF_<;nI|B5*{IHz8Yo1xnbPuaTJp&j z^C1`u)`-3e`1YN>sisIUorvaSfi6b`ak(rcJ_JZg3Oc z3%e55J%}swqk2(M<>x_)U6iIsv_cjN)8r50bk_PbJCD&u^*QM9QnHV&T{k?_dFyyc zRxHGd)K!U?q7H|i=EzKSMi2tYg>0~A)x1x{9#i$rL2hQkgu7P1ZLTqK{s=udud=VB zN!riPh!kGaw}=!iUB>Vidc)g$T>3u6&nX8twRk-^_llvn3@p3LD2R-3T;1F>B;}K9afOb8)A|A=OpzYGUYJ@>V&NgPE&L8i36sV2zRkdC4^|wteupHl z2t4UO(G`ChhG-W~Reh{`w5^08*bE5SQ1-1CnzHh>o~uE%UYfo|twfMP`bI?{ao0vn z|6D^n#Ca0rvmM4;@Iu$*^ng5UjL$KdrDYv-_6oD*1bK|&20m(d3ORAEfQt>dX~_KXhg`n&DCO4%l&p?A-Xlge!khQ`c(?rL0Yesk|1?_v;2XAJ zWB+q7IeoX}Ng?zrl+R1w*^dakLg!ze&*rztYdn$MwHdM%qU3*1;zoDDtlRss@rs+` z=OtbhSzir;Y)8)<3We?lHY^4*+%kCFV!qx$JnYlZcqQ&*NW4%XKf_0J;kX=fDo0nefq%ZO^cWk*q33Jhb3ea^bZmxbhAa;X7%lfzqn>xW84fe_%y#Ggxn4n?>zCU zy=!khf|3tH!Voo*C10IgPTyj*iqis>k%sh`?iaH)zp#D#!@8ZzhPOGleY3wlA$@$a zS;ZE!2zEkn?T5c+LDwZu%I3f=iORkEpNs2XpbrGyXZ#gU=MHkg9px9+yGwYS-MUkc zKdQrB6^fO#2w|poE5AAJ5kEh9=pCSSctcb7cinyA4*6apyb)pCK4Q}S*qDZX3hu>o z7YUc$J*ttbtU}xl1t-ENG?QitF;*9(+pTa^9C}$LW_k+H)T;s#8!^eLZ%^qENUmYy+o_R1r-CS^?`C2=$X`%sE#<3uKy?~Zr<_pC z{+&5Qr0n(Gzs7|Rm%}%RwS^B8UJPy@XqtJW&@`q0!)7&GN&xZ6G1x=<@vwS@7LDPD*`@=TF$h?Cq*!($iVwZ(I|Oqy#xd@zRJpKK{^#^C=*A6qP!-4?MEGhXR!a@+=C}-JnJ8YgCIH z&B$rS93rLfTpOMj<3!IE`;fJU|HA)w&1+Z53flM2vj6t4MZ@#|*Sz|S3?!0v#`d-j zHl{A7qW_8F_`gy(R!P==Q2@a=c?c3#F1ZzK)bs%Xlv~pr(|0ZyL)GC9i z&~%-I3b&zA>5XoKY))FJxSTn=ng+kZWdiSa>!bUk=NaN>=#CE?Z~Z9wFC~%6WAKn0 z8)WX!`yp@YM=go;gL#PED^Y-jtw6=oQ^cu&#?yYWqBy3y&(tAR;g&9T`xGm_s}32< zr{qX|xwtS}S2;J`iz^K^m8Qy$2)t)pURK6F z37zZ_{v_B{;iu@P7+HGNm8M$5&<3X;fQQE!48T{D%ckx)Cc6P))$S}0Qk^9E5&$h) zay3L^#A?b`(jDr1+&avfd;`L_xKe|6kn4KUeb>fEQLeu@E5|_gVlas&$(XbM|8 z(Bj=Oo6H9aa!HHOy@lV${JJd=b|@@Ami;khA>5%o)LjA)xLJnC+_Vj@X*XvZ!^GcfW8a*Q}nrrPtn-c)w2^j z3r3#8%9=5lt&mcX*Gly3<-G^PzDtLc&7ePyFGQ^4u==tBI>*v$pj#PDMA$FjJc2(Q zIul@X^`pmTC1&uW#Lzv6hxW!rvNLd=EQ5Us`r7~|lX_2Zky&e2%(%=WU{xuDu_Pyc79#$jg)&`d+7{_BtHw@X13S6G59|v1EZk&NhObAI+WXls)Z8by7q#g<1p& z$~g(fYZT)@$Vixu>%oNvZXqtJx6QUt&?x%TT&2z;$a| zuAHc5v!+II(f3cuDqCjBdCG7Cn_DXI$%ZRpO|2pIVOD6LLbFJ#nAD%Wh?&v^8Dwym z-ljyG&C%qVxoK98G6zFdLae}M^oMB_Kd5!cIcJ2qD5nv_VNXRkP_kLjO(ScIeL>V3 zu2Z^a%R&!{o(_Ukg6NQ=kb`3QT!<04u)CoA7QG80sl^dOF6vBj5_j!PuylihGfM)&+r5B(yG*i4s>W4`oa5lF zOV8%sYEG+i6>7@xV)MdwL9A7$i+zc?ND=(gFNjXOC%4-v!ueM=KYg42-2PS1&1HeC zY95l2<@)N%Qh}CGvy)m))mBGSNww96k;wgHolCSNk1Q7q#3z0|v z0R97rp*E+J77P?(blOgD;|f~DThl^y+UyS-n|jj~85AZ8+Wu3Cffq>i6h)EK#yTkJ zjM-337$Uq`pS5>5#bQAPWEL*AZ~qw^GZ5T)WaNgJzCcrK<^{m;JA*CPB(TehxR8xs zreHFqwwOMP1^IQ5w6%|-zb#MI4A*(F8(gL6vH))QEfIIx5cTUjUOe6_U=`f=^J2^)CrG!TIw7!P+MRE4y}1vWt{5HSr;jv4Ze( z1Rxf)By!Tk2zzjwEMLL*lxS(!53)3O@(>abZJfvug;xARne`jR^&5y}_Rj<6tCGdG zOfgqxtwo%e_iQh-U$(L>sb5nwwILW{&OMlqBSAF=l*uTz@WDa|0&71Oo0X5tZ?oKJ zykbzGp*XB3-1{0lmbTFVa*;f8n2);lCAeo~y)f~$;0@C>Y)8!95ddz4j+|* z{KfgkMSOek#6I%ein@QdHFuAFB-TxcRJF5x=4m|;LYJ)?LJ1DCPP{URP~wIMBc&P9 zp`ei9M&WI7VoAqZqVILk*(CA{UM`=|k`d)usn!Hia<%$kmAwLfQGYCCOlqFkK?0{q zDeLj}nmmCg4WSW){Ef1h5DuJNgh1&&h)p}s>z~+jcZ{>Pb_W*B{0rnBhIY^KIa20L zvXUQ@HwG_VKFAkiUaFsEvUWB*i9 z56!R{N9x(Iu910}1}Lk7gyOugkit1OXquPLzzHPY2v9;7Hmp(wV_g}sC+MPF&EJLv zA&FENRys)ELM(IE>id%dRH3xt^#t~aq3WqbZk$LIIo|LelN&*i8>>-m__+-?MN-~b zRRy;>5x4;JS<=1SLF9%XUX^Pgx=R$(1MM!egLic^CG|)EOgDaTmfjyR@u04#ai)u7 z^N3x9x@r%hi?KX%g2kuqHLKC~R!DgX964p;o8Nh4x~JAwRZ!JybXnP!%E+^LB*|Qw z{<}5O)M-*XY=X-v(5jJwP_~-E>3-qaWZ*QRMt-H<6Sy+&OrJGCQ8m>Zu^P?H*`K z>TViHS~!oMI6+B6L*Xc))1XdIMQQgyq@VX>T(lU5m+0g?h`%1ww-hVx1#?dPS6S}v zm3G4*0FpNGV8p%$wLts^F<)k8P3lyx|01ELV|NQhH3Gw^Hb-Efg4G`^Gl=FEp}_#L z1P1K0>Xb5f4m!`E#Fq9}XtGT1wZ!nv+ky?Jj8n)6CFKQO_#j?+bvB?DPMmCvBnb#Z zw8hHu%Jq>|uHxM?DJaZq@3C)a{7reUggOMM#aP25z{Q6XHLfNu)M}78_+`C^tM2-R z&(Zx{KsBRuR_&|C(Fx|z!M2NdyO04VZqFTGwyQf8%f-$x^8;J?D|aQXDu*assdvfY z5ls@Pz<^N?1Sd8-;T-VGVd9WMA8HcxizL?;xrhiAnlEYH&XwfR&q>%Ke^6`fF5mI` z`&c>!pt}~nGrc(^xcTX}gPCA)%;sOyipVz>glJT_p+G=o(`Ruf=LyaZLu#N& zgBI79AUo6>>`t7`_Fk-1_~)a0&T-yKYp&jU#sC1u;Hw_e(|r59DZ_S(+)&8w_`T2NIKi9+WB{NKRsfUJyhe1^%C zwp~qznSv~WVh*&wOJ4Ed+g$l>kvH96- z=nWvvN$>+$N4Gsb>Dhx|a9=+>VZc-$sO^-%An>d4&2-EF@ToY zPg;NYyW&-Xi%Ka_@piqb(x#I@tMjArSNn`bI(RN!Lci@p*~~#Tu-MJs?U_$XWyLQ& z9P&i+Zdei=`&-7EdqekBWCl?0Wyveraj*4VvJcLBYb)Y&oybn)koK|@VpO%hk ze8%QiKbPj6Z?N{8^~0TJaDH+)+xc#(_{k}(pWu!RMr`j{RvkONhHm~D?c%49CNvf4 z19;gt;CTp}l-@3dxv%j-Lp)1cxFXn8XK(xo%pSB1mG@L?8K(kyE{hhl189=8AHkn6 zLn4C6#Xiz&2zOuktjBdnH}JkNwgi23-4_5pyi{q*FH$(M*m^o@r0pzHxVO}P{S#}P zFKmN|4Fv`?NYJJOuooKUXCabBMn^`}&A6lU{N)*OFMiT9spv+Kzgc!_esvfy@ z!&}GEt*7Xp*BXKL)NgMS>R75A z@@Wy_#cV0Mi?PAu<-c$0%P*Ir*&r_aJ(Z(KptC~|S zu(On%_bJp=>#OKA{lnl|_#qR>sD!5zwVWgMeKoJ4mMjOr)2P4=qATn>%v4svihq1J zq;=a(W4#n}5+@{r<@{&iT#^n5gbO`j%bg9KpoQk8vX(GoSl)}Gt;2kpNu}^9^`$HAjJ;k$Fcxlqffpb zf|MT%amSADkDlk`7^k%K=8o{n9pbB6i&Ht)L}jN+5oln-N;|L}L|YQc4lGmR zqaej-_iL=kOpIqZr8u!_C2op=y3a=#vv~7{owh7~v1xJmPZdI4C%8dWFHk~*QA&^b z!@&r$AoG~-kK0_agUinrJF3VaTl8-5lJ^4BmXTV$%4kVV9(Db@lgpv+xZ(UKEkQlv zl*E>}`b8EktK^s?T&WfXdXuOGTBY6t1HVMRPE*7q(vHk(IHgpvu8Regnb~kkXDvaz z@e5u z=U@0PbR#h#yT?0ln~i@mT)yp`;w0U-f;j^0dmG|&61r2bh(0YJMu81+ORCEVT@Xz) z>W`+Q{zy-7W6B|V+Rky@L@83~)R0?3l&4-aN8Y)x>*B$qPf8cK7+t;A0;*7TllxD5N*e z7$VHPYK&Y9H+;>invI{39s8zZ{ z59b$9?J>TA$e~3O?Tc0uzF4sOyUtxjazdfj#q9~eYMTR3=jrd4#GZL_cS`gPyK`p? z^^HpwX{VmBy`pgvj(k37^Ef>blcqN{E|cDlC0Ra5JYB3b$H*yTW07t|o;F-0Nxd0h z!D1-+e5H)_!Za_KKOtok?uB5W?)P%#j#SOzvxa85lNz;9!c*jFt&Yx8itaVl%iW2% z{a%*kQXRBBh9I3b#rpyJg4f~g2@t5P1BcnCRb-!Q%rM^9%_Jvl=B=M^Zx(6!^| zKQBq${Tz5^y;6Q^6?YK198TiSn{Er5AbMdsCm-2V1leGrTI(Z37

PZFd4+LWi$C#xt&^}h!o1Pm5IdW^l_tX^ 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 z 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 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 be0fb34f9ee980673f5251839ec999bb0fcc94e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 210945 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
      $r>2QWRj0n5T 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�(4F!@(PTn7`@ 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 + 4.0.0 + Connect-SDK-Java-Core + Connect-SDK-Java-Core + 0.0.1-SNAPSHOT + + + + clojars.org + http://clojars.org/repo + + + + + + 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 + + + \ 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 96a442e5b8e9394ccf50bab9988cb2316026245d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9397 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 diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 71c6d760f05183ef8a47c614d8d13380c8528499..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14383 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 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/android/content/BroadcastReceiver.java b/src/android/content/BroadcastReceiver.java new file mode 100644 index 00000000..26a233c6 --- /dev/null +++ b/src/android/content/BroadcastReceiver.java @@ -0,0 +1,38 @@ +package android.content; +public abstract class BroadcastReceiver +{ +public static class PendingResult +{ +PendingResult() { throw new RuntimeException("Stub!"); } +public final void setResultCode(int code) { throw new RuntimeException("Stub!"); } +public final int getResultCode() { throw new RuntimeException("Stub!"); } +public final void setResultData(java.lang.String data) { throw new RuntimeException("Stub!"); } +public final java.lang.String getResultData() { throw new RuntimeException("Stub!"); } +//public final void setResultExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } +//public final android.os.Bundle getResultExtras(boolean makeMap) { throw new RuntimeException("Stub!"); } +//public final void setResult(int code, java.lang.String data, android.os.Bundle extras) { throw new RuntimeException("Stub!"); } +public final boolean getAbortBroadcast() { throw new RuntimeException("Stub!"); } +public final void abortBroadcast() { throw new RuntimeException("Stub!"); } +public final void clearAbortBroadcast() { throw new RuntimeException("Stub!"); } +public final void finish() { throw new RuntimeException("Stub!"); } +} +public BroadcastReceiver() { /*throw new RuntimeException("Stub!"); */} +public abstract void onReceive(android.content.Context context, android.content.Intent intent); +public final android.content.BroadcastReceiver.PendingResult goAsync() { throw new RuntimeException("Stub!"); } +//public android.os.IBinder peekService(android.content.Context myContext, android.content.Intent service) { throw new RuntimeException("Stub!"); } +public final void setResultCode(int code) { throw new RuntimeException("Stub!"); } +public final int getResultCode() { throw new RuntimeException("Stub!"); } +public final void setResultData(java.lang.String data) { throw new RuntimeException("Stub!"); } +public final java.lang.String getResultData() { throw new RuntimeException("Stub!"); } +//public final void setResultExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } +//public final android.os.Bundle getResultExtras(boolean makeMap) { throw new RuntimeException("Stub!"); } +//public final void setResult(int code, java.lang.String data, android.os.Bundle extras) { throw new RuntimeException("Stub!"); } +public final boolean getAbortBroadcast() { throw new RuntimeException("Stub!"); } +public final void abortBroadcast() { throw new RuntimeException("Stub!"); } +public final void clearAbortBroadcast() { throw new RuntimeException("Stub!"); } +public final boolean isOrderedBroadcast() { throw new RuntimeException("Stub!"); } +public final boolean isInitialStickyBroadcast() { throw new RuntimeException("Stub!"); } +public final void setOrderedHint(boolean isOrdered) { throw new RuntimeException("Stub!"); } +public final void setDebugUnregister(boolean debug) { throw new RuntimeException("Stub!"); } +public final boolean getDebugUnregister() { throw new RuntimeException("Stub!"); } +} diff --git a/src/android/content/Context.java b/src/android/content/Context.java new file mode 100644 index 00000000..3a7fc3c8 --- /dev/null +++ b/src/android/content/Context.java @@ -0,0 +1,148 @@ +package android.content; + +public abstract class Context +{ +public Context() { /*throw new RuntimeException("Stub!");*/ } +//public abstract android.content.res.AssetManager getAssets(); +//public abstract android.content.res.Resources getResources(); +public abstract android.content.pm.PackageManager getPackageManager(); +//public abstract android.content.ContentResolver getContentResolver(); +//public abstract android.os.Looper getMainLooper(); +public abstract android.content.Context getApplicationContext(); +//public void registerComponentCallbacks(android.content.ComponentCallbacks callback) { throw new RuntimeException("Stub!"); } +//public void unregisterComponentCallbacks(android.content.ComponentCallbacks callback) { throw new RuntimeException("Stub!"); } +public final java.lang.CharSequence getText(int resId) { throw new RuntimeException("Stub!"); } +public final java.lang.String getString(int resId) { throw new RuntimeException("Stub!"); } +public final java.lang.String getString(int resId, java.lang.Object... formatArgs) { throw new RuntimeException("Stub!"); } +public abstract void setTheme(int resid); +//public abstract android.content.res.Resources.Theme getTheme(); +//public final android.content.res.TypedArray obtainStyledAttributes(int[] attrs) { throw new RuntimeException("Stub!"); } +//public final android.content.res.TypedArray obtainStyledAttributes(int resid, int[] attrs) throws android.content.res.Resources.NotFoundException { throw new RuntimeException("Stub!"); } +//public final android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet set, int[] attrs) { throw new RuntimeException("Stub!"); } +//public final android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) { throw new RuntimeException("Stub!"); } +public abstract java.lang.ClassLoader getClassLoader(); +public abstract java.lang.String getPackageName(); +public abstract android.content.pm.ApplicationInfo getApplicationInfo(); +public abstract java.lang.String getPackageResourcePath(); +public abstract java.lang.String getPackageCodePath(); +//public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String name, int mode); +public abstract java.io.FileInputStream openFileInput(java.lang.String name) throws java.io.FileNotFoundException; +public abstract java.io.FileOutputStream openFileOutput(java.lang.String name, int mode) throws java.io.FileNotFoundException; +public abstract boolean deleteFile(java.lang.String name); +public abstract java.io.File getFileStreamPath(java.lang.String name); +public abstract java.io.File getFilesDir(); +public abstract java.io.File getExternalFilesDir(java.lang.String type); +public abstract java.io.File getObbDir(); +public abstract java.io.File getCacheDir(); +public abstract java.io.File getExternalCacheDir(); +public abstract java.lang.String[] fileList(); +public abstract java.io.File getDir(java.lang.String name, int mode); +//public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String name, int mode, android.database.sqlite.SQLiteDatabase.CursorFactory factory); +//public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String name, int mode, android.database.sqlite.SQLiteDatabase.CursorFactory factory, android.database.DatabaseErrorHandler errorHandler); +public abstract boolean deleteDatabase(java.lang.String name); +public abstract java.io.File getDatabasePath(java.lang.String name); +public abstract java.lang.String[] databaseList(); +//@java.lang.Deprecated() +//public abstract android.graphics.drawable.Drawable getWallpaper(); +//@java.lang.Deprecated() +///public abstract android.graphics.drawable.Drawable peekWallpaper(); +@java.lang.Deprecated() +public abstract int getWallpaperDesiredMinimumWidth(); +@java.lang.Deprecated() +public abstract int getWallpaperDesiredMinimumHeight(); +//@java.lang.Deprecated() +//public abstract void setWallpaper(android.graphics.Bitmap bitmap) throws java.io.IOException; +@java.lang.Deprecated() +public abstract void setWallpaper(java.io.InputStream data) throws java.io.IOException; +@java.lang.Deprecated() +public abstract void clearWallpaper() throws java.io.IOException; +//public abstract void startActivity(android.content.Intent intent); +//public abstract void startActivity(android.content.Intent intent, android.os.Bundle options); +//public abstract void startActivities(android.content.Intent[] intents); +//public abstract void startActivities(android.content.Intent[] intents, android.os.Bundle options); +//public abstract void startIntentSender(android.content.IntentSender intent, android.content.Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) throws android.content.IntentSender.SendIntentException; +//public abstract void startIntentSender(android.content.IntentSender intent, android.content.Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, android.os.Bundle options) throws android.content.IntentSender.SendIntentException; +//public abstract void sendBroadcast(android.content.Intent intent); +//public abstract void sendBroadcast(android.content.Intent intent, java.lang.String receiverPermission); +//public abstract void sendOrderedBroadcast(android.content.Intent intent, java.lang.String receiverPermission); +//public abstract void sendOrderedBroadcast(android.content.Intent intent, java.lang.String receiverPermission, android.content.BroadcastReceiver resultReceiver, android.os.Handler scheduler, int initialCode, java.lang.String initialData, android.os.Bundle initialExtras); +//public abstract void sendStickyBroadcast(android.content.Intent intent); +//public abstract void sendStickyOrderedBroadcast(android.content.Intent intent, android.content.BroadcastReceiver resultReceiver, android.os.Handler scheduler, int initialCode, java.lang.String initialData, android.os.Bundle initialExtras); +//public abstract void removeStickyBroadcast(android.content.Intent intent); +public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver receiver, android.content.IntentFilter filter); +//public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver receiver, android.content.IntentFilter filter, java.lang.String broadcastPermission, android.os.Handler scheduler); +public abstract void unregisterReceiver(android.content.BroadcastReceiver receiver); +//public abstract android.content.ComponentName startService(android.content.Intent service); +//public abstract boolean stopService(android.content.Intent service); +//public abstract boolean bindService(android.content.Intent service, android.content.ServiceConnection conn, int flags); +//public abstract void unbindService(android.content.ServiceConnection conn); +//public abstract boolean startInstrumentation(android.content.ComponentName className, java.lang.String profileFile, android.os.Bundle arguments); +public abstract java.lang.Object getSystemService(java.lang.String name); +public abstract int checkPermission(java.lang.String permission, int pid, int uid); +public abstract int checkCallingPermission(java.lang.String permission); +public abstract int checkCallingOrSelfPermission(java.lang.String permission); +public abstract void enforcePermission(java.lang.String permission, int pid, int uid, java.lang.String message); +public abstract void enforceCallingPermission(java.lang.String permission, java.lang.String message); +public abstract void enforceCallingOrSelfPermission(java.lang.String permission, java.lang.String message); +//public abstract void grantUriPermission(java.lang.String toPackage, android.net.Uri uri, int modeFlags); +//public abstract void revokeUriPermission(android.net.Uri uri, int modeFlags); +//public abstract int checkUriPermission(android.net.Uri uri, int pid, int uid, int modeFlags); +//public abstract int checkCallingUriPermission(android.net.Uri uri, int modeFlags); +//public abstract int checkCallingOrSelfUriPermission(android.net.Uri uri, int modeFlags); +//public abstract int checkUriPermission(android.net.Uri uri, java.lang.String readPermission, java.lang.String writePermission, int pid, int uid, int modeFlags); +//public abstract void enforceUriPermission(android.net.Uri uri, int pid, int uid, int modeFlags, java.lang.String message); +//public abstract void enforceCallingUriPermission(android.net.Uri uri, int modeFlags, java.lang.String message); +//public abstract void enforceCallingOrSelfUriPermission(android.net.Uri uri, int modeFlags, java.lang.String message); +//public abstract void enforceUriPermission(android.net.Uri uri, java.lang.String readPermission, java.lang.String writePermission, int pid, int uid, int modeFlags, java.lang.String message); +public abstract android.content.Context createPackageContext(java.lang.String packageName, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +public boolean isRestricted() { throw new RuntimeException("Stub!"); } +public static final int MODE_PRIVATE = 0; +public static final int MODE_WORLD_READABLE = 1; +public static final int MODE_WORLD_WRITEABLE = 2; +public static final int MODE_APPEND = 32768; +public static final int MODE_MULTI_PROCESS = 4; +public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; +public static final int BIND_AUTO_CREATE = 1; +public static final int BIND_DEBUG_UNBIND = 2; +public static final int BIND_NOT_FOREGROUND = 4; +public static final int BIND_ABOVE_CLIENT = 8; +public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; +public static final int BIND_WAIVE_PRIORITY = 32; +public static final int BIND_IMPORTANT = 64; +public static final int BIND_ADJUST_WITH_ACTIVITY = 128; +public static final java.lang.String POWER_SERVICE = "power"; +public static final java.lang.String WINDOW_SERVICE = "window"; +public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater"; +public static final java.lang.String ACCOUNT_SERVICE = "account"; +public static final java.lang.String ACTIVITY_SERVICE = "activity"; +public static final java.lang.String ALARM_SERVICE = "alarm"; +public static final java.lang.String NOTIFICATION_SERVICE = "notification"; +public static final java.lang.String ACCESSIBILITY_SERVICE = "accessibility"; +public static final java.lang.String KEYGUARD_SERVICE = "keyguard"; +public static final java.lang.String LOCATION_SERVICE = "location"; +public static final java.lang.String SEARCH_SERVICE = "search"; +public static final java.lang.String SENSOR_SERVICE = "sensor"; +public static final java.lang.String STORAGE_SERVICE = "storage"; +public static final java.lang.String WALLPAPER_SERVICE = "wallpaper"; +public static final java.lang.String VIBRATOR_SERVICE = "vibrator"; +public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity"; +public static final java.lang.String WIFI_SERVICE = "wifi"; +public static final java.lang.String WIFI_P2P_SERVICE = "wifip2p"; +public static final java.lang.String NSD_SERVICE = "servicediscovery"; +public static final java.lang.String AUDIO_SERVICE = "audio"; +public static final java.lang.String MEDIA_ROUTER_SERVICE = "media_router"; +public static final java.lang.String TELEPHONY_SERVICE = "phone"; +public static final java.lang.String CLIPBOARD_SERVICE = "clipboard"; +public static final java.lang.String INPUT_METHOD_SERVICE = "input_method"; +public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices"; +public static final java.lang.String DROPBOX_SERVICE = "dropbox"; +public static final java.lang.String DEVICE_POLICY_SERVICE = "device_policy"; +public static final java.lang.String UI_MODE_SERVICE = "uimode"; +public static final java.lang.String DOWNLOAD_SERVICE = "download"; +public static final java.lang.String NFC_SERVICE = "nfc"; +public static final java.lang.String USB_SERVICE = "usb"; +public static final java.lang.String INPUT_SERVICE = "input"; +public static final int CONTEXT_INCLUDE_CODE = 1; +public static final int CONTEXT_IGNORE_SECURITY = 2; +public static final int CONTEXT_RESTRICTED = 4; +} diff --git a/src/android/content/Intent.java b/src/android/content/Intent.java new file mode 100644 index 00000000..293d656f --- /dev/null +++ b/src/android/content/Intent.java @@ -0,0 +1,368 @@ +package android.content; +public class Intent + implements /*android.os.Parcelable,*/ java.lang.Cloneable +{ +public static class ShortcutIconResource +// implements android.os.Parcelable +{ +public ShortcutIconResource() { throw new RuntimeException("Stub!"); } +public static android.content.Intent.ShortcutIconResource fromContext(android.content.Context context, int resourceId) { throw new RuntimeException("Stub!"); } +public int describeContents() { throw new RuntimeException("Stub!"); } +//public void writeToParcel(android.os.Parcel dest, int flags) { throw new RuntimeException("Stub!"); } +public java.lang.String toString() { throw new RuntimeException("Stub!"); } +public java.lang.String packageName; +public java.lang.String resourceName; +//public static final android.os.Parcelable.Creator CREATOR; +//static { CREATOR = null; } +} +public static final class FilterComparison +{ +public FilterComparison(android.content.Intent intent) { throw new RuntimeException("Stub!"); } +public android.content.Intent getIntent() { throw new RuntimeException("Stub!"); } +public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); } +public int hashCode() { throw new RuntimeException("Stub!"); } +} +public Intent() { throw new RuntimeException("Stub!"); } +public Intent(android.content.Intent o) { throw new RuntimeException("Stub!"); } +public Intent(java.lang.String action) { throw new RuntimeException("Stub!"); } +//public Intent(java.lang.String action, android.net.Uri uri) { throw new RuntimeException("Stub!"); } +public Intent(android.content.Context packageContext, java.lang.Class cls) { throw new RuntimeException("Stub!"); } +//public Intent(java.lang.String action, android.net.Uri uri, android.content.Context packageContext, java.lang.Class cls) { throw new RuntimeException("Stub!"); } +public static android.content.Intent createChooser(android.content.Intent target, java.lang.CharSequence title) { throw new RuntimeException("Stub!"); } +public java.lang.Object clone() { throw new RuntimeException("Stub!"); } +public android.content.Intent cloneFilter() { throw new RuntimeException("Stub!"); } +//public static android.content.Intent makeMainActivity(android.content.ComponentName mainActivity) { throw new RuntimeException("Stub!"); } +public static android.content.Intent makeMainSelectorActivity(java.lang.String selectorAction, java.lang.String selectorCategory) { throw new RuntimeException("Stub!"); } +//public static android.content.Intent makeRestartActivityTask(android.content.ComponentName mainActivity) { throw new RuntimeException("Stub!"); } +@java.lang.Deprecated() +public static android.content.Intent getIntent(java.lang.String uri) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } +public static android.content.Intent parseUri(java.lang.String uri, int flags) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } +public static android.content.Intent getIntentOld(java.lang.String uri) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } +public java.lang.String getAction() { throw new RuntimeException("Stub!"); } +//public android.net.Uri getData() { throw new RuntimeException("Stub!"); } +public java.lang.String getDataString() { throw new RuntimeException("Stub!"); } +public java.lang.String getScheme() { throw new RuntimeException("Stub!"); } +public java.lang.String getType() { throw new RuntimeException("Stub!"); } +public java.lang.String resolveType(android.content.Context context) { throw new RuntimeException("Stub!"); } +//public java.lang.String resolveType(android.content.ContentResolver resolver) { throw new RuntimeException("Stub!"); } +//public java.lang.String resolveTypeIfNeeded(android.content.ContentResolver resolver) { throw new RuntimeException("Stub!"); } +public boolean hasCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } +public java.util.Set getCategories() { throw new RuntimeException("Stub!"); } +public android.content.Intent getSelector() { throw new RuntimeException("Stub!"); } +//public android.content.ClipData getClipData() { throw new RuntimeException("Stub!"); } +public void setExtrasClassLoader(java.lang.ClassLoader loader) { throw new RuntimeException("Stub!"); } +public boolean hasExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public boolean hasFileDescriptors() { throw new RuntimeException("Stub!"); } +public boolean getBooleanExtra(java.lang.String name, boolean defaultValue) { throw new RuntimeException("Stub!"); } +public byte getByteExtra(java.lang.String name, byte defaultValue) { throw new RuntimeException("Stub!"); } +public short getShortExtra(java.lang.String name, short defaultValue) { throw new RuntimeException("Stub!"); } +public char getCharExtra(java.lang.String name, char defaultValue) { throw new RuntimeException("Stub!"); } +public int getIntExtra(java.lang.String name, int defaultValue) { throw new RuntimeException("Stub!"); } +public long getLongExtra(java.lang.String name, long defaultValue) { throw new RuntimeException("Stub!"); } +public float getFloatExtra(java.lang.String name, float defaultValue) { throw new RuntimeException("Stub!"); } +public double getDoubleExtra(java.lang.String name, double defaultValue) { throw new RuntimeException("Stub!"); } +public java.lang.String getStringExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public java.lang.CharSequence getCharSequenceExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public T getParcelableExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public android.os.Parcelable[] getParcelableArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public java.util.ArrayList getParcelableArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public java.io.Serializable getSerializableExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public java.util.ArrayList getIntegerArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public java.util.ArrayList getStringArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public java.util.ArrayList getCharSequenceArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public boolean[] getBooleanArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public byte[] getByteArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public short[] getShortArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public char[] getCharArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public int[] getIntArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public long[] getLongArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public float[] getFloatArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public double[] getDoubleArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public java.lang.String[] getStringArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public java.lang.CharSequence[] getCharSequenceArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public android.os.Bundle getBundleExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public android.os.Bundle getExtras() { throw new RuntimeException("Stub!"); } +public int getFlags() { throw new RuntimeException("Stub!"); } +public java.lang.String getPackage() { throw new RuntimeException("Stub!"); } +//public android.content.ComponentName getComponent() { throw new RuntimeException("Stub!"); } +//public android.graphics.Rect getSourceBounds() { throw new RuntimeException("Stub!"); } +//public android.content.ComponentName resolveActivity(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +//public android.content.pm.ActivityInfo resolveActivityInfo(android.content.pm.PackageManager pm, int flags) { throw new RuntimeException("Stub!"); } +public android.content.Intent setAction(java.lang.String action) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setData(android.net.Uri data) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setDataAndNormalize(android.net.Uri data) { throw new RuntimeException("Stub!"); } +public android.content.Intent setType(java.lang.String type) { throw new RuntimeException("Stub!"); } +public android.content.Intent setTypeAndNormalize(java.lang.String type) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setDataAndType(android.net.Uri data, java.lang.String type) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setDataAndTypeAndNormalize(android.net.Uri data, java.lang.String type) { throw new RuntimeException("Stub!"); } +public android.content.Intent addCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } +public void removeCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } +public void setSelector(android.content.Intent selector) { throw new RuntimeException("Stub!"); } +//public void setClipData(android.content.ClipData clip) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, boolean value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, byte value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, char value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, short value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, int value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, long value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, float value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, double value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, java.lang.String value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, java.lang.CharSequence value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, android.os.Parcelable value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, android.os.Parcelable[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putParcelableArrayListExtra(java.lang.String name, java.util.ArrayList value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putIntegerArrayListExtra(java.lang.String name, java.util.ArrayList value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putStringArrayListExtra(java.lang.String name, java.util.ArrayList value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putCharSequenceArrayListExtra(java.lang.String name, java.util.ArrayList value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, java.io.Serializable value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, boolean[] value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, byte[] value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, short[] value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, char[] value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, int[] value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, long[] value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, float[] value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, double[] value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, java.lang.String[] value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtra(java.lang.String name, java.lang.CharSequence[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, android.os.Bundle value) { throw new RuntimeException("Stub!"); } +public android.content.Intent putExtras(android.content.Intent src) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } +public android.content.Intent replaceExtras(android.content.Intent src) { throw new RuntimeException("Stub!"); } +//public android.content.Intent replaceExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } +public void removeExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +public android.content.Intent setFlags(int flags) { throw new RuntimeException("Stub!"); } +public android.content.Intent addFlags(int flags) { throw new RuntimeException("Stub!"); } +public android.content.Intent setPackage(java.lang.String packageName) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setComponent(android.content.ComponentName component) { throw new RuntimeException("Stub!"); } +public android.content.Intent setClassName(android.content.Context packageContext, java.lang.String className) { throw new RuntimeException("Stub!"); } +public android.content.Intent setClassName(java.lang.String packageName, java.lang.String className) { throw new RuntimeException("Stub!"); } +public android.content.Intent setClass(android.content.Context packageContext, java.lang.Class cls) { throw new RuntimeException("Stub!"); } +//public void setSourceBounds(android.graphics.Rect r) { throw new RuntimeException("Stub!"); } +public int fillIn(android.content.Intent other, int flags) { throw new RuntimeException("Stub!"); } +public boolean filterEquals(android.content.Intent other) { throw new RuntimeException("Stub!"); } +public int filterHashCode() { throw new RuntimeException("Stub!"); } +public java.lang.String toString() { throw new RuntimeException("Stub!"); } +@java.lang.Deprecated() +public java.lang.String toURI() { throw new RuntimeException("Stub!"); } +public java.lang.String toUri(int flags) { throw new RuntimeException("Stub!"); } +public int describeContents() { throw new RuntimeException("Stub!"); } +//public void writeToParcel(android.os.Parcel out, int flags) { throw new RuntimeException("Stub!"); } +//public void readFromParcel(android.os.Parcel in) { throw new RuntimeException("Stub!"); } +//public static android.content.Intent parseIntent(android.content.res.Resources resources, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } +public static java.lang.String normalizeMimeType(java.lang.String type) { throw new RuntimeException("Stub!"); } +public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN"; +public static final java.lang.String ACTION_VIEW = "android.intent.action.VIEW"; +public static final java.lang.String ACTION_DEFAULT = "android.intent.action.VIEW"; +public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA"; +public static final java.lang.String ACTION_EDIT = "android.intent.action.EDIT"; +public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT"; +public static final java.lang.String ACTION_PICK = "android.intent.action.PICK"; +public static final java.lang.String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT"; +public static final java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT"; +public static final java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME"; +public static final java.lang.String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON"; +public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE"; +public static final java.lang.String ACTION_CHOOSER = "android.intent.action.CHOOSER"; +public static final java.lang.String ACTION_GET_CONTENT = "android.intent.action.GET_CONTENT"; +public static final java.lang.String ACTION_DIAL = "android.intent.action.DIAL"; +public static final java.lang.String ACTION_CALL = "android.intent.action.CALL"; +public static final java.lang.String ACTION_SENDTO = "android.intent.action.SENDTO"; +public static final java.lang.String ACTION_SEND = "android.intent.action.SEND"; +public static final java.lang.String ACTION_SEND_MULTIPLE = "android.intent.action.SEND_MULTIPLE"; +public static final java.lang.String ACTION_ANSWER = "android.intent.action.ANSWER"; +public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT"; +public static final java.lang.String ACTION_PASTE = "android.intent.action.PASTE"; +public static final java.lang.String ACTION_DELETE = "android.intent.action.DELETE"; +public static final java.lang.String ACTION_RUN = "android.intent.action.RUN"; +public static final java.lang.String ACTION_SYNC = "android.intent.action.SYNC"; +public static final java.lang.String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY"; +public static final java.lang.String ACTION_SEARCH = "android.intent.action.SEARCH"; +public static final java.lang.String ACTION_SYSTEM_TUTORIAL = "android.intent.action.SYSTEM_TUTORIAL"; +public static final java.lang.String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH"; +public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST"; +public static final java.lang.String ACTION_ALL_APPS = "android.intent.action.ALL_APPS"; +public static final java.lang.String ACTION_SET_WALLPAPER = "android.intent.action.SET_WALLPAPER"; +public static final java.lang.String ACTION_BUG_REPORT = "android.intent.action.BUG_REPORT"; +public static final java.lang.String ACTION_FACTORY_TEST = "android.intent.action.FACTORY_TEST"; +public static final java.lang.String ACTION_CALL_BUTTON = "android.intent.action.CALL_BUTTON"; +public static final java.lang.String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND"; +public static final java.lang.String ACTION_SEARCH_LONG_PRESS = "android.intent.action.SEARCH_LONG_PRESS"; +public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR"; +public static final java.lang.String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; +public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE"; +public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE"; +public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME"; +public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE"; +@java.lang.Deprecated() +public static final java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE"; +public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT"; +public static final java.lang.String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE"; +public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF"; +public static final java.lang.String ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON"; +public static final java.lang.String ACTION_USER_PRESENT = "android.intent.action.USER_PRESENT"; +public static final java.lang.String ACTION_TIME_TICK = "android.intent.action.TIME_TICK"; +public static final java.lang.String ACTION_TIME_CHANGED = "android.intent.action.TIME_SET"; +public static final java.lang.String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED"; +public static final java.lang.String ACTION_TIMEZONE_CHANGED = "android.intent.action.TIMEZONE_CHANGED"; +public static final java.lang.String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED"; +public static final java.lang.String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS"; +@java.lang.Deprecated() +public static final java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; +public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; +public static final java.lang.String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED"; +public static final java.lang.String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED"; +public static final java.lang.String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED"; +public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED"; +public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; +public static final java.lang.String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED"; +public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED"; +public static final java.lang.String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED"; +public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH"; +public static final java.lang.String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION"; +public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE"; +public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE"; +@java.lang.Deprecated() +public static final java.lang.String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED"; +public static final java.lang.String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED"; +public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED"; +public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED"; +public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW"; +public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY"; +public static final java.lang.String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED"; +public static final java.lang.String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED"; +public static final java.lang.String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN"; +public static final java.lang.String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW"; +public static final java.lang.String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK"; +public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE"; +@java.lang.Deprecated() +public static final java.lang.String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED"; +@java.lang.Deprecated() +public static final java.lang.String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED"; +public static final java.lang.String ACTION_MEDIA_REMOVED = "android.intent.action.MEDIA_REMOVED"; +public static final java.lang.String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED"; +public static final java.lang.String ACTION_MEDIA_CHECKING = "android.intent.action.MEDIA_CHECKING"; +public static final java.lang.String ACTION_MEDIA_NOFS = "android.intent.action.MEDIA_NOFS"; +public static final java.lang.String ACTION_MEDIA_MOUNTED = "android.intent.action.MEDIA_MOUNTED"; +public static final java.lang.String ACTION_MEDIA_SHARED = "android.intent.action.MEDIA_SHARED"; +public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL"; +public static final java.lang.String ACTION_MEDIA_UNMOUNTABLE = "android.intent.action.MEDIA_UNMOUNTABLE"; +public static final java.lang.String ACTION_MEDIA_EJECT = "android.intent.action.MEDIA_EJECT"; +public static final java.lang.String ACTION_MEDIA_SCANNER_STARTED = "android.intent.action.MEDIA_SCANNER_STARTED"; +public static final java.lang.String ACTION_MEDIA_SCANNER_FINISHED = "android.intent.action.MEDIA_SCANNER_FINISHED"; +public static final java.lang.String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE"; +public static final java.lang.String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON"; +public static final java.lang.String ACTION_CAMERA_BUTTON = "android.intent.action.CAMERA_BUTTON"; +public static final java.lang.String ACTION_GTALK_SERVICE_CONNECTED = "android.intent.action.GTALK_CONNECTED"; +public static final java.lang.String ACTION_GTALK_SERVICE_DISCONNECTED = "android.intent.action.GTALK_DISCONNECTED"; +public static final java.lang.String ACTION_INPUT_METHOD_CHANGED = "android.intent.action.INPUT_METHOD_CHANGED"; +public static final java.lang.String ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE"; +public static final java.lang.String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED"; +public static final java.lang.String ACTION_HEADSET_PLUG = "android.intent.action.HEADSET_PLUG"; +public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"; +public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT"; +public static final java.lang.String ACTION_DOCK_EVENT = "android.intent.action.DOCK_EVENT"; +public static final java.lang.String CATEGORY_DEFAULT = "android.intent.category.DEFAULT"; +public static final java.lang.String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE"; +public static final java.lang.String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE"; +public static final java.lang.String CATEGORY_SELECTED_ALTERNATIVE = "android.intent.category.SELECTED_ALTERNATIVE"; +public static final java.lang.String CATEGORY_TAB = "android.intent.category.TAB"; +public static final java.lang.String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER"; +public static final java.lang.String CATEGORY_INFO = "android.intent.category.INFO"; +public static final java.lang.String CATEGORY_HOME = "android.intent.category.HOME"; +public static final java.lang.String CATEGORY_PREFERENCE = "android.intent.category.PREFERENCE"; +public static final java.lang.String CATEGORY_DEVELOPMENT_PREFERENCE = "android.intent.category.DEVELOPMENT_PREFERENCE"; +public static final java.lang.String CATEGORY_EMBED = "android.intent.category.EMBED"; +public static final java.lang.String CATEGORY_APP_MARKET = "android.intent.category.APP_MARKET"; +public static final java.lang.String CATEGORY_MONKEY = "android.intent.category.MONKEY"; +public static final java.lang.String CATEGORY_TEST = "android.intent.category.TEST"; +public static final java.lang.String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST"; +public static final java.lang.String CATEGORY_SAMPLE_CODE = "android.intent.category.SAMPLE_CODE"; +public static final java.lang.String CATEGORY_OPENABLE = "android.intent.category.OPENABLE"; +public static final java.lang.String CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST = "android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"; +public static final java.lang.String CATEGORY_CAR_DOCK = "android.intent.category.CAR_DOCK"; +public static final java.lang.String CATEGORY_DESK_DOCK = "android.intent.category.DESK_DOCK"; +public static final java.lang.String CATEGORY_LE_DESK_DOCK = "android.intent.category.LE_DESK_DOCK"; +public static final java.lang.String CATEGORY_HE_DESK_DOCK = "android.intent.category.HE_DESK_DOCK"; +public static final java.lang.String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE"; +public static final java.lang.String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER"; +public static final java.lang.String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR"; +public static final java.lang.String CATEGORY_APP_CALENDAR = "android.intent.category.APP_CALENDAR"; +public static final java.lang.String CATEGORY_APP_CONTACTS = "android.intent.category.APP_CONTACTS"; +public static final java.lang.String CATEGORY_APP_EMAIL = "android.intent.category.APP_EMAIL"; +public static final java.lang.String CATEGORY_APP_GALLERY = "android.intent.category.APP_GALLERY"; +public static final java.lang.String CATEGORY_APP_MAPS = "android.intent.category.APP_MAPS"; +public static final java.lang.String CATEGORY_APP_MESSAGING = "android.intent.category.APP_MESSAGING"; +public static final java.lang.String CATEGORY_APP_MUSIC = "android.intent.category.APP_MUSIC"; +public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE"; +public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT"; +public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT"; +public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; +public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL"; +public static final java.lang.String EXTRA_CC = "android.intent.extra.CC"; +public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC"; +public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT"; +public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT"; +public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE"; +public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS"; +public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT"; +public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP"; +public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER"; +public static final java.lang.String EXTRA_UID = "android.intent.extra.UID"; +public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED"; +public static final java.lang.String EXTRA_REPLACING = "android.intent.extra.REPLACING"; +public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT"; +public static final java.lang.String EXTRA_DOCK_STATE = "android.intent.extra.DOCK_STATE"; +public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; +public static final int EXTRA_DOCK_STATE_DESK = 1; +public static final int EXTRA_DOCK_STATE_CAR = 2; +public static final int EXTRA_DOCK_STATE_LE_DESK = 3; +public static final int EXTRA_DOCK_STATE_HE_DESK = 4; +public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home"; +public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT"; +public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token"; +@java.lang.Deprecated() +public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME = "android.intent.extra.changed_component_name"; +public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list"; +public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list"; +public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list"; +public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY"; +public static final int FLAG_GRANT_READ_URI_PERMISSION = 1; +public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 2; +public static final int FLAG_FROM_BACKGROUND = 4; +public static final int FLAG_DEBUG_LOG_RESOLUTION = 8; +public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 16; +public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32; +public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824; +public static final int FLAG_ACTIVITY_SINGLE_TOP = 536870912; +public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; +public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; +public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; +public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; +public static final int FLAG_ACTIVITY_PREVIOUS_IS_TOP = 16777216; +public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; +public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 4194304; +public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 2097152; +public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; +public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; +public static final int FLAG_ACTIVITY_NO_USER_ACTION = 262144; +public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 131072; +public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536; +public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; +public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; +public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; +public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; +public static final int FLAG_RECEIVER_FOREGROUND = 268435456; +public static final int URI_INTENT_SCHEME = 1; +public static final int FILL_IN_ACTION = 1; +public static final int FILL_IN_DATA = 2; +public static final int FILL_IN_CATEGORIES = 4; +public static final int FILL_IN_COMPONENT = 8; +public static final int FILL_IN_PACKAGE = 16; +public static final int FILL_IN_SOURCE_BOUNDS = 32; +public static final int FILL_IN_SELECTOR = 64; +public static final int FILL_IN_CLIP_DATA = 128; +//public static final android.os.Parcelable.Creator CREATOR; +//static { CREATOR = null; } +} diff --git a/src/android/content/IntentFilter.java b/src/android/content/IntentFilter.java new file mode 100644 index 00000000..29e622dd --- /dev/null +++ b/src/android/content/IntentFilter.java @@ -0,0 +1,219 @@ +package android.content; + +public class IntentFilter +// implements android.os.Parcelable +{ + public static class MalformedMimeTypeException extends android.util.AndroidException { + public MalformedMimeTypeException() { + throw new RuntimeException("Stub!"); + } + + public MalformedMimeTypeException(java.lang.String name) { + throw new RuntimeException("Stub!"); + } + } + + public static final class AuthorityEntry { + public AuthorityEntry(java.lang.String host, java.lang.String port) { + throw new RuntimeException("Stub!"); + } + + public java.lang.String getHost() { + throw new RuntimeException("Stub!"); + } + + public int getPort() { + throw new RuntimeException("Stub!"); + } + // public int match(android.net.Uri data) { throw new RuntimeException("Stub!"); } + } + + public IntentFilter() { + /* throw new RuntimeException("Stub!"); */} + + public IntentFilter(java.lang.String action) { + throw new RuntimeException("Stub!"); + } + + public IntentFilter(java.lang.String action, java.lang.String dataType) + throws android.content.IntentFilter.MalformedMimeTypeException { + throw new RuntimeException("Stub!"); + } + + public IntentFilter(android.content.IntentFilter o) { + throw new RuntimeException("Stub!"); + } + + public static android.content.IntentFilter create(java.lang.String action, java.lang.String dataType) { + throw new RuntimeException("Stub!"); + } + + public final void setPriority(int priority) { + throw new RuntimeException("Stub!"); + } + + public final int getPriority() { + throw new RuntimeException("Stub!"); + } + + public final void addAction(java.lang.String action) { + /* throw new RuntimeException("Stub!"); */ } + + public final int countActions() { + throw new RuntimeException("Stub!"); + } + + public final java.lang.String getAction(int index) { + throw new RuntimeException("Stub!"); + } + + public final boolean hasAction(java.lang.String action) { + throw new RuntimeException("Stub!"); + } + + public final boolean matchAction(java.lang.String action) { + throw new RuntimeException("Stub!"); + } + + public final java.util.Iterator actionsIterator() { + throw new RuntimeException("Stub!"); + } + + public final void addDataType(java.lang.String type) + throws android.content.IntentFilter.MalformedMimeTypeException { + throw new RuntimeException("Stub!"); + } + + public final boolean hasDataType(java.lang.String type) { + throw new RuntimeException("Stub!"); + } + + public final int countDataTypes() { + throw new RuntimeException("Stub!"); + } + + public final java.lang.String getDataType(int index) { + throw new RuntimeException("Stub!"); + } + + public final java.util.Iterator typesIterator() { + throw new RuntimeException("Stub!"); + } + + public final void addDataScheme(java.lang.String scheme) { + throw new RuntimeException("Stub!"); + } + + public final int countDataSchemes() { + throw new RuntimeException("Stub!"); + } + + public final java.lang.String getDataScheme(int index) { + throw new RuntimeException("Stub!"); + } + + public final boolean hasDataScheme(java.lang.String scheme) { + throw new RuntimeException("Stub!"); + } + + public final java.util.Iterator schemesIterator() { + throw new RuntimeException("Stub!"); + } + + public final void addDataAuthority(java.lang.String host, java.lang.String port) { + throw new RuntimeException("Stub!"); + } + + public final int countDataAuthorities() { + throw new RuntimeException("Stub!"); + } + + public final android.content.IntentFilter.AuthorityEntry getDataAuthority(int index) { + throw new RuntimeException("Stub!"); + } + + // public final boolean hasDataAuthority(android.net.Uri data) { throw new RuntimeException("Stub!"); } + public final java.util.Iterator authoritiesIterator() { + throw new RuntimeException("Stub!"); + } + + public final void addDataPath(java.lang.String path, int type) { + throw new RuntimeException("Stub!"); + } + + public final int countDataPaths() { + throw new RuntimeException("Stub!"); + } + + // public final android.os.PatternMatcher getDataPath(int index) { throw new RuntimeException("Stub!"); } + public final boolean hasDataPath(java.lang.String data) { + throw new RuntimeException("Stub!"); + } + + // public final java.util.Iterator pathsIterator() { throw new RuntimeException("Stub!"); + // } + // public final int matchDataAuthority(android.net.Uri data) { throw new RuntimeException("Stub!"); } + // public final int matchData(java.lang.String type, java.lang.String scheme, android.net.Uri data) { throw new + // RuntimeException("Stub!"); } + public final void addCategory(java.lang.String category) { + throw new RuntimeException("Stub!"); + } + + public final int countCategories() { + throw new RuntimeException("Stub!"); + } + + public final java.lang.String getCategory(int index) { + throw new RuntimeException("Stub!"); + } + + public final boolean hasCategory(java.lang.String category) { + throw new RuntimeException("Stub!"); + } + + public final java.util.Iterator categoriesIterator() { + throw new RuntimeException("Stub!"); + } + + public final java.lang.String matchCategories(java.util.Set categories) { + throw new RuntimeException("Stub!"); + } + + // public final int match(android.content.ContentResolver resolver, android.content.Intent intent, boolean resolve, + // java.lang.String logTag) { throw new RuntimeException("Stub!"); } + // public final int match(java.lang.String action, java.lang.String type, java.lang.String scheme, android.net.Uri + // data, java.util.Set categories, java.lang.String logTag) { throw new RuntimeException("Stub!"); + // } + // public void writeToXml(org.xmlpull.v1.XmlSerializer serializer) throws java.io.IOException { + // throw new RuntimeException("Stub!"); + // } + + // public void readFromXml(org.xmlpull.v1.XmlPullParser parser) + // throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { + // throw new RuntimeException("Stub!"); + // } + + // public void dump(android.util.Printer du, java.lang.String prefix) { throw new RuntimeException("Stub!"); } + public final int describeContents() { + throw new RuntimeException("Stub!"); + } + + // public final void writeToParcel(android.os.Parcel dest, int flags) { throw new RuntimeException("Stub!"); } + public static final int SYSTEM_HIGH_PRIORITY = 1000; + public static final int SYSTEM_LOW_PRIORITY = -1000; + public static final int MATCH_CATEGORY_MASK = 268369920; + public static final int MATCH_ADJUSTMENT_MASK = 65535; + public static final int MATCH_ADJUSTMENT_NORMAL = 32768; + public static final int MATCH_CATEGORY_EMPTY = 1048576; + public static final int MATCH_CATEGORY_SCHEME = 2097152; + public static final int MATCH_CATEGORY_HOST = 3145728; + public static final int MATCH_CATEGORY_PORT = 4194304; + public static final int MATCH_CATEGORY_PATH = 5242880; + public static final int MATCH_CATEGORY_TYPE = 6291456; + public static final int NO_MATCH_TYPE = -1; + public static final int NO_MATCH_DATA = -2; + public static final int NO_MATCH_ACTION = -3; + public static final int NO_MATCH_CATEGORY = -4; + // public static final android.os.Parcelable.Creator CREATOR; + // static { CREATOR = null; } +} diff --git a/src/android/content/pm/ApplicationInfo.java b/src/android/content/pm/ApplicationInfo.java new file mode 100644 index 00000000..23ed2611 --- /dev/null +++ b/src/android/content/pm/ApplicationInfo.java @@ -0,0 +1,65 @@ +package android.content.pm; +public class ApplicationInfo + extends android.content.pm.PackageItemInfo +// implements android.os.Parcelable +{ +public static class DisplayNameComparator + implements java.util.Comparator +{ +public DisplayNameComparator(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +public final int compare(android.content.pm.ApplicationInfo aa, android.content.pm.ApplicationInfo ab) { throw new RuntimeException("Stub!"); } +} +public ApplicationInfo() { /*throw new RuntimeException("Stub!");*/ } +public ApplicationInfo(android.content.pm.ApplicationInfo orig) { throw new RuntimeException("Stub!"); } +//public void dump(android.util.Printer pw, java.lang.String prefix) { throw new RuntimeException("Stub!"); } +public java.lang.String toString() { throw new RuntimeException("Stub!"); } +public int describeContents() { throw new RuntimeException("Stub!"); } +//public void writeToParcel(android.os.Parcel dest, int parcelableFlags) { throw new RuntimeException("Stub!"); } +public java.lang.CharSequence loadDescription(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +public java.lang.String taskAffinity; +public java.lang.String permission; +public java.lang.String processName; +public java.lang.String className; +public int descriptionRes; +public int theme; +public java.lang.String manageSpaceActivityName; +public java.lang.String backupAgentName; +public int uiOptions; +public static final int FLAG_SYSTEM = 1; +public static final int FLAG_DEBUGGABLE = 2; +public static final int FLAG_HAS_CODE = 4; +public static final int FLAG_PERSISTENT = 8; +public static final int FLAG_FACTORY_TEST = 16; +public static final int FLAG_ALLOW_TASK_REPARENTING = 32; +public static final int FLAG_ALLOW_CLEAR_USER_DATA = 64; +public static final int FLAG_UPDATED_SYSTEM_APP = 128; +public static final int FLAG_TEST_ONLY = 256; +public static final int FLAG_SUPPORTS_SMALL_SCREENS = 512; +public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1024; +public static final int FLAG_SUPPORTS_LARGE_SCREENS = 2048; +public static final int FLAG_RESIZEABLE_FOR_SCREENS = 4096; +public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 8192; +public static final int FLAG_VM_SAFE_MODE = 16384; +public static final int FLAG_ALLOW_BACKUP = 32768; +public static final int FLAG_KILL_AFTER_RESTORE = 65536; +public static final int FLAG_RESTORE_ANY_VERSION = 131072; +public static final int FLAG_EXTERNAL_STORAGE = 262144; +public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 524288; +public static final int FLAG_LARGE_HEAP = 1048576; +public static final int FLAG_STOPPED = 2097152; +public int flags; +public int requiresSmallestWidthDp; +public int compatibleWidthLimitDp; +public int largestWidthLimitDp; +public java.lang.String sourceDir; +public java.lang.String publicSourceDir; +public java.lang.String[] sharedLibraryFiles = null; +public java.lang.String dataDir; +public java.lang.String nativeLibraryDir; +public int uid; +public int targetSdkVersion; +public boolean enabled; +//public static final android.os.Parcelable.Creator CREATOR; +//static { CREATOR = null; } +} + diff --git a/src/android/content/pm/PackageInfo.java b/src/android/content/pm/PackageInfo.java new file mode 100644 index 00000000..9c6d4802 --- /dev/null +++ b/src/android/content/pm/PackageInfo.java @@ -0,0 +1,33 @@ +package android.content.pm; +public class PackageInfo +// implements android.os.Parcelable +{ +public PackageInfo() { /*throw new RuntimeException("Stub!"); */} +public java.lang.String toString() { throw new RuntimeException("Stub!"); } +public int describeContents() { throw new RuntimeException("Stub!"); } +//public void writeToParcel(android.os.Parcel dest, int parcelableFlags) { throw new RuntimeException("Stub!"); } +public java.lang.String packageName; +public int versionCode; +public java.lang.String versionName; +public java.lang.String sharedUserId; +public int sharedUserLabel; +public android.content.pm.ApplicationInfo applicationInfo; +public long firstInstallTime; +public long lastUpdateTime; +public int[] gids = null; +//public android.content.pm.ActivityInfo[] activities = null; +//public android.content.pm.ActivityInfo[] receivers = null; +//public android.content.pm.ServiceInfo[] services = null; +//public android.content.pm.ProviderInfo[] providers = null; +//public android.content.pm.InstrumentationInfo[] instrumentation = null; +//public android.content.pm.PermissionInfo[] permissions = null; +public java.lang.String[] requestedPermissions = null; +public int[] requestedPermissionsFlags = null; +public static final int REQUESTED_PERMISSION_REQUIRED = 1; +public static final int REQUESTED_PERMISSION_GRANTED = 2; +//public android.content.pm.Signature[] signatures = null; +//public android.content.pm.ConfigurationInfo[] configPreferences = null; +//public android.content.pm.FeatureInfo[] reqFeatures = null; +//public static final android.os.Parcelable.Creator CREATOR; +//static { CREATOR = null; } +} diff --git a/src/android/content/pm/PackageItemInfo.java b/src/android/content/pm/PackageItemInfo.java new file mode 100644 index 00000000..2be5fa60 --- /dev/null +++ b/src/android/content/pm/PackageItemInfo.java @@ -0,0 +1,27 @@ +package android.content.pm; +public class PackageItemInfo +{ +public static class DisplayNameComparator + implements java.util.Comparator +{ +public DisplayNameComparator(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +public final int compare(android.content.pm.PackageItemInfo aa, android.content.pm.PackageItemInfo ab) { throw new RuntimeException("Stub!"); } +} +public PackageItemInfo() { /*throw new RuntimeException("Stub!");*/ } +public PackageItemInfo(android.content.pm.PackageItemInfo orig) { throw new RuntimeException("Stub!"); } +//protected PackageItemInfo(android.os.Parcel source) { throw new RuntimeException("Stub!"); } +public java.lang.CharSequence loadLabel(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +//public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +//public android.graphics.drawable.Drawable loadLogo(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +//public android.content.res.XmlResourceParser loadXmlMetaData(android.content.pm.PackageManager pm, java.lang.String name) { throw new RuntimeException("Stub!"); } +//protected void dumpFront(android.util.Printer pw, java.lang.String prefix) { throw new RuntimeException("Stub!"); } +//protected void dumpBack(android.util.Printer pw, java.lang.String prefix) { throw new RuntimeException("Stub!"); } +//public void writeToParcel(android.os.Parcel dest, int parcelableFlags) { throw new RuntimeException("Stub!"); } +public java.lang.String name; +public java.lang.String packageName; +public int labelRes; +public java.lang.CharSequence nonLocalizedLabel; +public int icon; +public int logo; +//public android.os.Bundle metaData; +} diff --git a/src/android/content/pm/PackageManager.java b/src/android/content/pm/PackageManager.java new file mode 100644 index 00000000..0c772682 --- /dev/null +++ b/src/android/content/pm/PackageManager.java @@ -0,0 +1,152 @@ +package android.content.pm; +public abstract class PackageManager +{ +public static class NameNotFoundException + extends android.util.AndroidException +{ +public NameNotFoundException() { } +public NameNotFoundException(java.lang.String name) { throw new RuntimeException("Stub!"); } +} +public PackageManager() { /*throw new RuntimeException("Stub!");*/ } +public abstract android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +public abstract java.lang.String[] currentToCanonicalPackageNames(java.lang.String[] names); +public abstract java.lang.String[] canonicalToCurrentPackageNames(java.lang.String[] names); +//public abstract android.content.Intent getLaunchIntentForPackage(java.lang.String packageName); +public abstract int[] getPackageGids(java.lang.String packageName) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.content.pm.PermissionInfo getPermissionInfo(java.lang.String name, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract java.util.List queryPermissionsByGroup(java.lang.String group, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(java.lang.String name, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract java.util.List getAllPermissionGroups(int flags); +public abstract android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String packageName, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.content.pm.ActivityInfo getReceiverInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.content.pm.ProviderInfo getProviderInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +public abstract java.util.List getInstalledPackages(int flags); +public abstract int checkPermission(java.lang.String permName, java.lang.String pkgName); +//public abstract boolean addPermission(android.content.pm.PermissionInfo info); +//public abstract boolean addPermissionAsync(android.content.pm.PermissionInfo info); +public abstract void removePermission(java.lang.String name); +public abstract int checkSignatures(java.lang.String pkg1, java.lang.String pkg2); +public abstract int checkSignatures(int uid1, int uid2); +public abstract java.lang.String[] getPackagesForUid(int uid); +public abstract java.lang.String getNameForUid(int uid); +public abstract java.util.List getInstalledApplications(int flags); +public abstract java.lang.String[] getSystemSharedLibraryNames(); +//public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures(); +public abstract boolean hasSystemFeature(java.lang.String name); +//public abstract android.content.pm.ResolveInfo resolveActivity(android.content.Intent intent, int flags); +//public abstract java.util.List queryIntentActivities(android.content.Intent intent, int flags); +//public abstract java.util.List queryIntentActivityOptions(android.content.ComponentName caller, android.content.Intent[] specifics, android.content.Intent intent, int flags); +//public abstract java.util.List queryBroadcastReceivers(android.content.Intent intent, int flags); +//public abstract android.content.pm.ResolveInfo resolveService(android.content.Intent intent, int flags); +//public abstract java.util.List queryIntentServices(android.content.Intent intent, int flags); +//public abstract android.content.pm.ProviderInfo resolveContentProvider(java.lang.String name, int flags); +//public abstract java.util.List queryContentProviders(java.lang.String processName, int uid, int flags); +//public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName className, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract java.util.List queryInstrumentation(java.lang.String targetPackage, int flags); +//public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String packageName, int resid, android.content.pm.ApplicationInfo appInfo); +//public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName activityName) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.Intent intent) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.graphics.drawable.Drawable getDefaultActivityIcon(); +//public abstract android.graphics.drawable.Drawable getApplicationIcon(android.content.pm.ApplicationInfo info); +public abstract android.graphics.drawable.Drawable getApplicationIcon(java.lang.String packageName) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName activityName) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.Intent intent) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo info); +//public abstract android.graphics.drawable.Drawable getApplicationLogo(java.lang.String packageName) throws android.content.pm.PackageManager.NameNotFoundException; +public abstract java.lang.CharSequence getText(java.lang.String packageName, int resid, android.content.pm.ApplicationInfo appInfo); +//public abstract android.content.res.XmlResourceParser getXml(java.lang.String packageName, int resid, android.content.pm.ApplicationInfo appInfo); +public abstract java.lang.CharSequence getApplicationLabel(android.content.pm.ApplicationInfo info); +//public abstract android.content.res.Resources getResourcesForActivity(android.content.ComponentName activityName) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo app) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract android.content.res.Resources getResourcesForApplication(java.lang.String appPackageName) throws android.content.pm.PackageManager.NameNotFoundException; +public android.content.pm.PackageInfo getPackageArchiveInfo(java.lang.String archiveFilePath, int flags) { throw new RuntimeException("Stub!"); } +public abstract void verifyPendingInstall(int id, int verificationCode); +public abstract void setInstallerPackageName(java.lang.String targetPackage, java.lang.String installerPackageName); +public abstract java.lang.String getInstallerPackageName(java.lang.String packageName); +@java.lang.Deprecated() +public abstract void addPackageToPreferred(java.lang.String packageName); +@java.lang.Deprecated() +public abstract void removePackageFromPreferred(java.lang.String packageName); +public abstract java.util.List getPreferredPackages(int flags); +@java.lang.Deprecated() +//public abstract void addPreferredActivity(android.content.IntentFilter filter, int match, android.content.ComponentName[] set, android.content.ComponentName activity); +public abstract void clearPackagePreferredActivities(java.lang.String packageName); +//public abstract int getPreferredActivities(java.util.List outFilters, java.util.List outActivities, java.lang.String packageName); +//public abstract void setComponentEnabledSetting(android.content.ComponentName componentName, int newState, int flags); +//public abstract int getComponentEnabledSetting(android.content.ComponentName componentName); +public abstract void setApplicationEnabledSetting(java.lang.String packageName, int newState, int flags); +public abstract int getApplicationEnabledSetting(java.lang.String packageName); +public abstract boolean isSafeMode(); +public static final int GET_ACTIVITIES = 1; +public static final int GET_RECEIVERS = 2; +public static final int GET_SERVICES = 4; +public static final int GET_PROVIDERS = 8; +public static final int GET_INSTRUMENTATION = 16; +public static final int GET_INTENT_FILTERS = 32; +public static final int GET_SIGNATURES = 64; +public static final int GET_RESOLVED_FILTER = 64; +public static final int GET_META_DATA = 128; +public static final int GET_GIDS = 256; +public static final int GET_DISABLED_COMPONENTS = 512; +public static final int GET_SHARED_LIBRARY_FILES = 1024; +public static final int GET_URI_PERMISSION_PATTERNS = 2048; +public static final int GET_PERMISSIONS = 4096; +public static final int GET_UNINSTALLED_PACKAGES = 8192; +public static final int GET_CONFIGURATIONS = 16384; +public static final int MATCH_DEFAULT_ONLY = 65536; +public static final int PERMISSION_GRANTED = 0; +public static final int PERMISSION_DENIED = -1; +public static final int SIGNATURE_MATCH = 0; +public static final int SIGNATURE_NEITHER_SIGNED = 1; +public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; +public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; +public static final int SIGNATURE_NO_MATCH = -3; +public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; +public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; +public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; +public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; +public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; +public static final int DONT_KILL_APP = 1; +public static final int VERIFICATION_ALLOW = 1; +public static final int VERIFICATION_REJECT = -1; +public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency"; +public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth"; +public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera"; +public static final java.lang.String FEATURE_CAMERA_AUTOFOCUS = "android.hardware.camera.autofocus"; +public static final java.lang.String FEATURE_CAMERA_FLASH = "android.hardware.camera.flash"; +public static final java.lang.String FEATURE_CAMERA_FRONT = "android.hardware.camera.front"; +public static final java.lang.String FEATURE_LOCATION = "android.hardware.location"; +public static final java.lang.String FEATURE_LOCATION_GPS = "android.hardware.location.gps"; +public static final java.lang.String FEATURE_LOCATION_NETWORK = "android.hardware.location.network"; +public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone"; +public static final java.lang.String FEATURE_NFC = "android.hardware.nfc"; +public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer"; +public static final java.lang.String FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer"; +public static final java.lang.String FEATURE_SENSOR_COMPASS = "android.hardware.sensor.compass"; +public static final java.lang.String FEATURE_SENSOR_GYROSCOPE = "android.hardware.sensor.gyroscope"; +public static final java.lang.String FEATURE_SENSOR_LIGHT = "android.hardware.sensor.light"; +public static final java.lang.String FEATURE_SENSOR_PROXIMITY = "android.hardware.sensor.proximity"; +public static final java.lang.String FEATURE_TELEPHONY = "android.hardware.telephony"; +public static final java.lang.String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma"; +public static final java.lang.String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm"; +public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host"; +public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory"; +public static final java.lang.String FEATURE_SIP = "android.software.sip"; +public static final java.lang.String FEATURE_SIP_VOIP = "android.software.sip.voip"; +public static final java.lang.String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen"; +public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch"; +public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct"; +public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = "android.hardware.touchscreen.multitouch.jazzhand"; +public static final java.lang.String FEATURE_FAKETOUCH = "android.hardware.faketouch"; +public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT = "android.hardware.faketouch.multitouch.distinct"; +public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand"; +public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait"; +public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape"; +public static final java.lang.String FEATURE_LIVE_WALLPAPER = "android.software.live_wallpaper"; +public static final java.lang.String FEATURE_WIFI = "android.hardware.wifi"; +public static final java.lang.String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct"; +public static final java.lang.String FEATURE_TELEVISION = "android.hardware.type.television"; +public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID"; +} diff --git a/src/android/graphics/Bitmap.java b/src/android/graphics/Bitmap.java new file mode 100644 index 00000000..3d640604 --- /dev/null +++ b/src/android/graphics/Bitmap.java @@ -0,0 +1,64 @@ +package android.graphics; +public final class Bitmap + implements android.os.Parcelable +{ +public static enum Config +{ +ALPHA_8(), +ARGB_4444(), +ARGB_8888(), +RGB_565(); +} +public static enum CompressFormat +{ +JPEG(), +PNG(), +WEBP(); +} +Bitmap() { throw new RuntimeException("Stub!"); } +public int getDensity() { throw new RuntimeException("Stub!"); } +public void setDensity(int density) { throw new RuntimeException("Stub!"); } +public void recycle() { throw new RuntimeException("Stub!"); } +public final boolean isRecycled() { throw new RuntimeException("Stub!"); } +public int getGenerationId() { throw new RuntimeException("Stub!"); } +public void copyPixelsToBuffer(java.nio.Buffer dst) { throw new RuntimeException("Stub!"); } +public void copyPixelsFromBuffer(java.nio.Buffer src) { throw new RuntimeException("Stub!"); } +public android.graphics.Bitmap copy(android.graphics.Bitmap.Config config, boolean isMutable) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap src, int dstWidth, int dstHeight, boolean filter) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap src) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap source, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap source, int x, int y, int width, int height, android.graphics.Matrix m, boolean filter) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap createBitmap(int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap createBitmap(int[] colors, int offset, int stride, int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap createBitmap(int[] colors, int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } +public byte[] getNinePatchChunk() { throw new RuntimeException("Stub!"); } +public boolean compress(android.graphics.Bitmap.CompressFormat format, int quality, java.io.OutputStream stream) { throw new RuntimeException("Stub!"); } +public final boolean isMutable() { throw new RuntimeException("Stub!"); } +public final int getWidth() { throw new RuntimeException("Stub!"); } +public final int getHeight() { throw new RuntimeException("Stub!"); } +//public int getScaledWidth(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } +//public int getScaledHeight(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } +//public int getScaledWidth(android.util.DisplayMetrics metrics) { throw new RuntimeException("Stub!"); } +//public int getScaledHeight(android.util.DisplayMetrics metrics) { throw new RuntimeException("Stub!"); } +public int getScaledWidth(int targetDensity) { throw new RuntimeException("Stub!"); } +public int getScaledHeight(int targetDensity) { throw new RuntimeException("Stub!"); } +public final int getRowBytes() { throw new RuntimeException("Stub!"); } +public final int getByteCount() { throw new RuntimeException("Stub!"); } +public final android.graphics.Bitmap.Config getConfig() { throw new RuntimeException("Stub!"); } +public final boolean hasAlpha() { throw new RuntimeException("Stub!"); } +public void setHasAlpha(boolean hasAlpha) { throw new RuntimeException("Stub!"); } +public void eraseColor(int c) { throw new RuntimeException("Stub!"); } +public int getPixel(int x, int y) { throw new RuntimeException("Stub!"); } +public void getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } +public void setPixel(int x, int y, int color) { throw new RuntimeException("Stub!"); } +public void setPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } +public int describeContents() { throw new RuntimeException("Stub!"); } +//public void writeToParcel(android.os.Parcel p, int flags) { throw new RuntimeException("Stub!"); } +public android.graphics.Bitmap extractAlpha() { throw new RuntimeException("Stub!"); } +//public android.graphics.Bitmap extractAlpha(android.graphics.Paint paint, int[] offsetXY) { throw new RuntimeException("Stub!"); } +public boolean sameAs(android.graphics.Bitmap other) { throw new RuntimeException("Stub!"); } +public void prepareToDraw() { throw new RuntimeException("Stub!"); } +public static final int DENSITY_NONE = 0; +public static final android.os.Parcelable.Creator CREATOR; +static { CREATOR = null; } +} diff --git a/src/android/graphics/BitmapFactory.java b/src/android/graphics/BitmapFactory.java new file mode 100644 index 00000000..460eb90a --- /dev/null +++ b/src/android/graphics/BitmapFactory.java @@ -0,0 +1,40 @@ +package android.graphics; +public class BitmapFactory +{ +public static class Options +{ +public Options() { throw new RuntimeException("Stub!"); } +public void requestCancelDecode() { throw new RuntimeException("Stub!"); } +public android.graphics.Bitmap inBitmap; +@java.lang.SuppressWarnings(value={"UnusedDeclaration"}) +public boolean inMutable; +public boolean inJustDecodeBounds; +public int inSampleSize; +public android.graphics.Bitmap.Config inPreferredConfig; +public boolean inDither; +public int inDensity; +public int inTargetDensity; +public int inScreenDensity; +public boolean inScaled; +public boolean inPurgeable; +public boolean inInputShareable; +public boolean inPreferQualityOverSpeed; +public int outWidth; +public int outHeight; +public java.lang.String outMimeType; +public byte[] inTempStorage = null; +public boolean mCancel; +} +public BitmapFactory() { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap decodeFile(java.lang.String pathName, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap decodeFile(java.lang.String pathName) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeResourceStream(android.content.res.Resources res, android.util.TypedValue value, java.io.InputStream is, android.graphics.Rect pad, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeResource(android.content.res.Resources res, int id, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeResource(android.content.res.Resources res, int id) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap decodeByteArray(byte[] data, int offset, int length, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap decodeByteArray(byte[] data, int offset, int length) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeStream(java.io.InputStream is, android.graphics.Rect outPadding, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap decodeStream(java.io.InputStream is) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeFileDescriptor(java.io.FileDescriptor fd, android.graphics.Rect outPadding, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } +public static android.graphics.Bitmap decodeFileDescriptor(java.io.FileDescriptor fd) { throw new RuntimeException("Stub!"); } +} diff --git a/src/android/graphics/PointF.java b/src/android/graphics/PointF.java new file mode 100644 index 00000000..f0ff4051 --- /dev/null +++ b/src/android/graphics/PointF.java @@ -0,0 +1,22 @@ +package android.graphics; +public class PointF + implements android.os.Parcelable +{ +public PointF() { throw new RuntimeException("Stub!"); } +public PointF(float x, float y) { throw new RuntimeException("Stub!"); } +//public PointF(android.graphics.Point p) { throw new RuntimeException("Stub!"); } +public final void set(float x, float y) { throw new RuntimeException("Stub!"); } +public final void set(android.graphics.PointF p) { throw new RuntimeException("Stub!"); } +public final void negate() { throw new RuntimeException("Stub!"); } +public final void offset(float dx, float dy) { throw new RuntimeException("Stub!"); } +public final boolean equals(float x, float y) { throw new RuntimeException("Stub!"); } +public final float length() { throw new RuntimeException("Stub!"); } +public static float length(float x, float y) { throw new RuntimeException("Stub!"); } +public int describeContents() { throw new RuntimeException("Stub!"); } +//public void writeToParcel(android.os.Parcel out, int flags) { throw new RuntimeException("Stub!"); } +//public void readFromParcel(android.os.Parcel in) { throw new RuntimeException("Stub!"); } +public float x; +public float y; +public static final android.os.Parcelable.Creator CREATOR; +static { CREATOR = null; } +} diff --git a/src/android/graphics/drawable/BitmapDrawable.java b/src/android/graphics/drawable/BitmapDrawable.java new file mode 100644 index 00000000..25c6a69c --- /dev/null +++ b/src/android/graphics/drawable/BitmapDrawable.java @@ -0,0 +1,46 @@ +package android.graphics.drawable; +public class BitmapDrawable + extends android.graphics.drawable.Drawable +{ +@java.lang.Deprecated() +public BitmapDrawable() { throw new RuntimeException("Stub!"); } +@java.lang.SuppressWarnings(value={"UnusedParameters"}) +//public BitmapDrawable(android.content.res.Resources res) { throw new RuntimeException("Stub!"); } +@java.lang.Deprecated() +public BitmapDrawable(android.graphics.Bitmap bitmap) { throw new RuntimeException("Stub!"); } +//public BitmapDrawable(android.content.res.Resources res, android.graphics.Bitmap bitmap) { throw new RuntimeException("Stub!"); } +@java.lang.Deprecated() +public BitmapDrawable(java.lang.String filepath) { throw new RuntimeException("Stub!"); } +@java.lang.SuppressWarnings(value={"UnusedParameters"}) +//public BitmapDrawable(android.content.res.Resources res, java.lang.String filepath) { throw new RuntimeException("Stub!"); } +@java.lang.Deprecated() +public BitmapDrawable(java.io.InputStream is) { throw new RuntimeException("Stub!"); } +@java.lang.SuppressWarnings(value={"UnusedParameters"}) +//public BitmapDrawable(android.content.res.Resources res, java.io.InputStream is) { throw new RuntimeException("Stub!"); } +//public final android.graphics.Paint getPaint() { throw new RuntimeException("Stub!"); } +public final android.graphics.Bitmap getBitmap() { throw new RuntimeException("Stub!"); } +//public void setTargetDensity(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } +//public void setTargetDensity(android.util.DisplayMetrics metrics) { throw new RuntimeException("Stub!"); } +public void setTargetDensity(int density) { throw new RuntimeException("Stub!"); } +public int getGravity() { throw new RuntimeException("Stub!"); } +public void setGravity(int gravity) { throw new RuntimeException("Stub!"); } +public void setAntiAlias(boolean aa) { throw new RuntimeException("Stub!"); } +public void setFilterBitmap(boolean filter) { throw new RuntimeException("Stub!"); } +public void setDither(boolean dither) { throw new RuntimeException("Stub!"); } +//public android.graphics.Shader.TileMode getTileModeX() { throw new RuntimeException("Stub!"); } +//public android.graphics.Shader.TileMode getTileModeY() { throw new RuntimeException("Stub!"); } +//public void setTileModeX(android.graphics.Shader.TileMode mode) { throw new RuntimeException("Stub!"); } +//public final void setTileModeY(android.graphics.Shader.TileMode mode) { throw new RuntimeException("Stub!"); } +//public void setTileModeXY(android.graphics.Shader.TileMode xmode, android.graphics.Shader.TileMode ymode) { throw new RuntimeException("Stub!"); } +public int getChangingConfigurations() { throw new RuntimeException("Stub!"); } +//protected void onBoundsChange(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } +//public void draw(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } +public void setAlpha(int alpha) { throw new RuntimeException("Stub!"); } +//public void setColorFilter(android.graphics.ColorFilter cf) { throw new RuntimeException("Stub!"); } +public android.graphics.drawable.Drawable mutate() { throw new RuntimeException("Stub!"); } +//public void inflate(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } +public int getIntrinsicWidth() { throw new RuntimeException("Stub!"); } +public int getIntrinsicHeight() { throw new RuntimeException("Stub!"); } +public int getOpacity() { throw new RuntimeException("Stub!"); } +public final android.graphics.drawable.Drawable.ConstantState getConstantState() { throw new RuntimeException("Stub!"); } +} diff --git a/src/android/graphics/drawable/Drawable.java b/src/android/graphics/drawable/Drawable.java new file mode 100644 index 00000000..2710ce2a --- /dev/null +++ b/src/android/graphics/drawable/Drawable.java @@ -0,0 +1,66 @@ +package android.graphics.drawable; +public abstract class Drawable +{ +public static interface Callback +{ +public abstract void invalidateDrawable(android.graphics.drawable.Drawable who); +public abstract void scheduleDrawable(android.graphics.drawable.Drawable who, java.lang.Runnable what, long when); +public abstract void unscheduleDrawable(android.graphics.drawable.Drawable who, java.lang.Runnable what); +} +public abstract static class ConstantState +{ +public ConstantState() { throw new RuntimeException("Stub!"); } +public abstract android.graphics.drawable.Drawable newDrawable(); +//public android.graphics.drawable.Drawable newDrawable(android.content.res.Resources res) { throw new RuntimeException("Stub!"); } +public abstract int getChangingConfigurations(); +} +public Drawable() { throw new RuntimeException("Stub!"); } +//public abstract void draw(android.graphics.Canvas canvas); +public void setBounds(int left, int top, int right, int bottom) { throw new RuntimeException("Stub!"); } +//public void setBounds(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } +//public final void copyBounds(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } +//public final android.graphics.Rect copyBounds() { throw new RuntimeException("Stub!"); } +//public final android.graphics.Rect getBounds() { throw new RuntimeException("Stub!"); } +public void setChangingConfigurations(int configs) { throw new RuntimeException("Stub!"); } +public int getChangingConfigurations() { throw new RuntimeException("Stub!"); } +public void setDither(boolean dither) { throw new RuntimeException("Stub!"); } +public void setFilterBitmap(boolean filter) { throw new RuntimeException("Stub!"); } +public final void setCallback(android.graphics.drawable.Drawable.Callback cb) { throw new RuntimeException("Stub!"); } +public android.graphics.drawable.Drawable.Callback getCallback() { throw new RuntimeException("Stub!"); } +public void invalidateSelf() { throw new RuntimeException("Stub!"); } +public void scheduleSelf(java.lang.Runnable what, long when) { throw new RuntimeException("Stub!"); } +public void unscheduleSelf(java.lang.Runnable what) { throw new RuntimeException("Stub!"); } +public abstract void setAlpha(int alpha); +//public abstract void setColorFilter(android.graphics.ColorFilter cf); +//public void setColorFilter(int color, android.graphics.PorterDuff.Mode mode) { throw new RuntimeException("Stub!"); } +public void clearColorFilter() { throw new RuntimeException("Stub!"); } +public boolean isStateful() { throw new RuntimeException("Stub!"); } +public boolean setState(int[] stateSet) { throw new RuntimeException("Stub!"); } +public int[] getState() { throw new RuntimeException("Stub!"); } +public void jumpToCurrentState() { throw new RuntimeException("Stub!"); } +public android.graphics.drawable.Drawable getCurrent() { throw new RuntimeException("Stub!"); } +public final boolean setLevel(int level) { throw new RuntimeException("Stub!"); } +public final int getLevel() { throw new RuntimeException("Stub!"); } +public boolean setVisible(boolean visible, boolean restart) { throw new RuntimeException("Stub!"); } +public final boolean isVisible() { throw new RuntimeException("Stub!"); } +public abstract int getOpacity(); +public static int resolveOpacity(int op1, int op2) { throw new RuntimeException("Stub!"); } +//public android.graphics.Region getTransparentRegion() { throw new RuntimeException("Stub!"); } +protected boolean onStateChange(int[] state) { throw new RuntimeException("Stub!"); } +protected boolean onLevelChange(int level) { throw new RuntimeException("Stub!"); } +//protected void onBoundsChange(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } +public int getIntrinsicWidth() { throw new RuntimeException("Stub!"); } +public int getIntrinsicHeight() { throw new RuntimeException("Stub!"); } +public int getMinimumWidth() { throw new RuntimeException("Stub!"); } +public int getMinimumHeight() { throw new RuntimeException("Stub!"); } +//public boolean getPadding(android.graphics.Rect padding) { throw new RuntimeException("Stub!"); } +public android.graphics.drawable.Drawable mutate() { throw new RuntimeException("Stub!"); } +public static android.graphics.drawable.Drawable createFromStream(java.io.InputStream is, java.lang.String srcName) { throw new RuntimeException("Stub!"); } +//public static android.graphics.drawable.Drawable createFromResourceStream(android.content.res.Resources res, android.util.TypedValue value, java.io.InputStream is, java.lang.String srcName) { throw new RuntimeException("Stub!"); } +//public static android.graphics.drawable.Drawable createFromResourceStream(android.content.res.Resources res, android.util.TypedValue value, java.io.InputStream is, java.lang.String srcName, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } +//public static android.graphics.drawable.Drawable createFromXml(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } +//public static android.graphics.drawable.Drawable createFromXmlInner(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } +//public static android.graphics.drawable.Drawable createFromPath(java.lang.String pathName) { throw new RuntimeException("Stub!"); } +//public void inflate(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } +public android.graphics.drawable.Drawable.ConstantState getConstantState() { throw new RuntimeException("Stub!"); } +} diff --git a/src/android/net/ConnectivityManager.java b/src/android/net/ConnectivityManager.java new file mode 100644 index 00000000..38cf8b2f --- /dev/null +++ b/src/android/net/ConnectivityManager.java @@ -0,0 +1,38 @@ +package android.net; +public class ConnectivityManager +{ +public ConnectivityManager() { /*throw new RuntimeException("Stub!");*/ } +public static boolean isNetworkTypeValid(int networkType) { throw new RuntimeException("Stub!"); } +public void setNetworkPreference(int preference) { throw new RuntimeException("Stub!"); } +public int getNetworkPreference() { throw new RuntimeException("Stub!"); } +public android.net.NetworkInfo getActiveNetworkInfo() { throw new RuntimeException("Stub!"); } +public android.net.NetworkInfo getNetworkInfo(int networkType) { return new NetworkInfo();/*throw new RuntimeException("Stub!");*/ } +public android.net.NetworkInfo[] getAllNetworkInfo() { throw new RuntimeException("Stub!"); } +public int startUsingNetworkFeature(int networkType, java.lang.String feature) { throw new RuntimeException("Stub!"); } +public int stopUsingNetworkFeature(int networkType, java.lang.String feature) { throw new RuntimeException("Stub!"); } +public boolean requestRouteToHost(int networkType, int hostAddress) { throw new RuntimeException("Stub!"); } +@java.lang.Deprecated() +public boolean getBackgroundDataSetting() { throw new RuntimeException("Stub!"); } +public boolean isActiveNetworkMetered() { throw new RuntimeException("Stub!"); } +public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; +@java.lang.Deprecated() +public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; +public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover"; +public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork"; +public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity"; +public static final java.lang.String EXTRA_REASON = "reason"; +public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo"; +@java.lang.Deprecated() +public static final java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; +public static final int TYPE_MOBILE = 0; +public static final int TYPE_WIFI = 1; +public static final int TYPE_MOBILE_MMS = 2; +public static final int TYPE_MOBILE_SUPL = 3; +public static final int TYPE_MOBILE_DUN = 4; +public static final int TYPE_MOBILE_HIPRI = 5; +public static final int TYPE_WIMAX = 6; +public static final int TYPE_BLUETOOTH = 7; +public static final int TYPE_DUMMY = 8; +public static final int TYPE_ETHERNET = 9; +public static final int DEFAULT_NETWORK_PREFERENCE = 1; +} diff --git a/src/android/net/NetworkInfo.java b/src/android/net/NetworkInfo.java new file mode 100644 index 00000000..50e0fbe8 --- /dev/null +++ b/src/android/net/NetworkInfo.java @@ -0,0 +1,46 @@ +package android.net; +public class NetworkInfo +// implements android.os.Parcelable +{ +public static enum State +{ +CONNECTED(), +CONNECTING(), +DISCONNECTED(), +DISCONNECTING(), +SUSPENDED(), +UNKNOWN(); +} +public static enum DetailedState +{ +AUTHENTICATING(), +BLOCKED(), +CONNECTED(), +CONNECTING(), +DISCONNECTED(), +DISCONNECTING(), +FAILED(), +IDLE(), +OBTAINING_IPADDR(), +SCANNING(), +SUSPENDED(), +VERIFYING_POOR_LINK(); +} +NetworkInfo() { /* throw new RuntimeException("Stub!"); */} +public int getType() { throw new RuntimeException("Stub!"); } +public int getSubtype() { throw new RuntimeException("Stub!"); } +public java.lang.String getTypeName() { throw new RuntimeException("Stub!"); } +public java.lang.String getSubtypeName() { throw new RuntimeException("Stub!"); } +public boolean isConnectedOrConnecting() { throw new RuntimeException("Stub!"); } +public boolean isConnected() { return true; /*throw new RuntimeException("Stub!");*/ } +public boolean isAvailable() { throw new RuntimeException("Stub!"); } +public boolean isFailover() { throw new RuntimeException("Stub!"); } +public boolean isRoaming() { throw new RuntimeException("Stub!"); } +public android.net.NetworkInfo.State getState() { throw new RuntimeException("Stub!"); } +public android.net.NetworkInfo.DetailedState getDetailedState() { throw new RuntimeException("Stub!"); } +public java.lang.String getReason() { throw new RuntimeException("Stub!"); } +public java.lang.String getExtraInfo() { throw new RuntimeException("Stub!"); } +public java.lang.String toString() { throw new RuntimeException("Stub!"); } +public int describeContents() { throw new RuntimeException("Stub!"); } +//public void writeToParcel(android.os.Parcel dest, int flags) { throw new RuntimeException("Stub!"); } +} diff --git a/src/android/net/wifi/WifiManager.java b/src/android/net/wifi/WifiManager.java new file mode 100644 index 00000000..f250f92d --- /dev/null +++ b/src/android/net/wifi/WifiManager.java @@ -0,0 +1,172 @@ +package android.net.wifi; + +public class WifiManager { + + public class WifiLock { + WifiLock() { + throw new RuntimeException("Stub!"); + } + + public void acquire() { + throw new RuntimeException("Stub!"); + } + + public void release() { + throw new RuntimeException("Stub!"); + } + + public void setReferenceCounted(boolean refCounted) { + throw new RuntimeException("Stub!"); + } + + public boolean isHeld() { + throw new RuntimeException("Stub!"); + } + + // public void setWorkSource(android.os.WorkSource ws) { throw new RuntimeException("Stub!"); } + @Override + public java.lang.String toString() { + throw new RuntimeException("Stub!"); + } + + @Override + protected void finalize() throws java.lang.Throwable { + throw new RuntimeException("Stub!"); + } + } + + public class MulticastLock { + MulticastLock() { + /* throw new RuntimeException("Stub!"); */ } + + public void acquire() { + /* throw new RuntimeException("Stub!"); */} + + public void release() { + /* throw new RuntimeException("Stub!"); */ } + + public void setReferenceCounted(boolean refCounted) { + /* throw new RuntimeException("Stub!"); */ } + + public boolean isHeld() { + return true; + /* throw new RuntimeException("Stub!"); */ } + + @Override + public java.lang.String toString() { + return super.toString(); + } + + @Override + protected void finalize() throws java.lang.Throwable { + } + } + + public WifiManager() { + } + + // public java.util.List getConfiguredNetworks() { throw new + // RuntimeException("Stub!"); } + // public int addNetwork(android.net.wifi.WifiConfiguration config) { throw new RuntimeException("Stub!"); } + // public int updateNetwork(android.net.wifi.WifiConfiguration config) { throw new RuntimeException("Stub!"); } + public boolean removeNetwork(int netId) { + throw new RuntimeException("Stub!"); + } + + public boolean enableNetwork(int netId, boolean disableOthers) { + throw new RuntimeException("Stub!"); + } + + public boolean disableNetwork(int netId) { + throw new RuntimeException("Stub!"); + } + + public boolean disconnect() { + throw new RuntimeException("Stub!"); + } + + public boolean reconnect() { + throw new RuntimeException("Stub!"); + } + + public boolean reassociate() { + throw new RuntimeException("Stub!"); + } + + public boolean pingSupplicant() { + throw new RuntimeException("Stub!"); + } + + public boolean startScan() { + throw new RuntimeException("Stub!"); + } + + // public android.net.wifi.WifiInfo getConnectionInfo() { + // throw new RuntimeException("Stub!"); + // } + + // public java.util.List getScanResults() { throw new RuntimeException("Stub!"); } + public boolean saveConfiguration() { + throw new RuntimeException("Stub!"); + } + + // public android.net.DhcpInfo getDhcpInfo() { throw new RuntimeException("Stub!"); } + public boolean setWifiEnabled(boolean enabled) { + throw new RuntimeException("Stub!"); + } + + public int getWifiState() { + throw new RuntimeException("Stub!"); + } + + public boolean isWifiEnabled() { + throw new RuntimeException("Stub!"); + } + + public static int calculateSignalLevel(int rssi, int numLevels) { + throw new RuntimeException("Stub!"); + } + + public static int compareSignalLevel(int rssiA, int rssiB) { + throw new RuntimeException("Stub!"); + } + + public android.net.wifi.WifiManager.WifiLock createWifiLock(int lockType, java.lang.String tag) { + throw new RuntimeException("Stub!"); + } + + public android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String tag) { + throw new RuntimeException("Stub!"); + } + + public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String tag) { + /* throw new RuntimeException("Stub!"); */ return new MulticastLock(); + } + + public static final int ERROR_AUTHENTICATING = 1; + public static final java.lang.String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED"; + public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state"; + public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state"; + public static final int WIFI_STATE_DISABLING = 0; + public static final int WIFI_STATE_DISABLED = 1; + public static final int WIFI_STATE_ENABLING = 2; + public static final int WIFI_STATE_ENABLED = 3; + public static final int WIFI_STATE_UNKNOWN = 4; + public static final java.lang.String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE"; + public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected"; + public static final java.lang.String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE"; + public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; + public static final java.lang.String EXTRA_BSSID = "bssid"; + public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo"; + public static final java.lang.String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE"; + public static final java.lang.String EXTRA_NEW_STATE = "newState"; + public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError"; + public static final java.lang.String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS"; + public static final java.lang.String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; + public static final java.lang.String EXTRA_NEW_RSSI = "newRssi"; + public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED"; + public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; + public static final int WIFI_MODE_FULL = 1; + public static final int WIFI_MODE_SCAN_ONLY = 2; + public static final int WIFI_MODE_FULL_HIGH_PERF = 3; +} diff --git a/src/android/os/Build.java b/src/android/os/Build.java new file mode 100644 index 00000000..bbef79fe --- /dev/null +++ b/src/android/os/Build.java @@ -0,0 +1,61 @@ +package android.os; +public class Build +{ +public static class VERSION +{ +public VERSION() { throw new RuntimeException("Stub!"); } +public static final java.lang.String INCREMENTAL; +public static final java.lang.String RELEASE; +@java.lang.Deprecated() +public static final java.lang.String SDK; +public static final int SDK_INT; +public static final java.lang.String CODENAME; +static { INCREMENTAL = null; RELEASE = null; SDK = null; SDK_INT = 0; CODENAME = null; } +} +public static class VERSION_CODES +{ +public VERSION_CODES() { throw new RuntimeException("Stub!"); } +public static final int CUR_DEVELOPMENT = 10000; +public static final int BASE = 1; +public static final int BASE_1_1 = 2; +public static final int CUPCAKE = 3; +public static final int DONUT = 4; +public static final int ECLAIR = 5; +public static final int ECLAIR_0_1 = 6; +public static final int ECLAIR_MR1 = 7; +public static final int FROYO = 8; +public static final int GINGERBREAD = 9; +public static final int GINGERBREAD_MR1 = 10; +public static final int HONEYCOMB = 11; +public static final int HONEYCOMB_MR1 = 12; +public static final int HONEYCOMB_MR2 = 13; +public static final int ICE_CREAM_SANDWICH = 14; +public static final int ICE_CREAM_SANDWICH_MR1 = 15; +public static final int JELLY_BEAN = 16; +} +public Build() { throw new RuntimeException("Stub!"); } +public static java.lang.String getRadioVersion() { throw new RuntimeException("Stub!"); } +public static final java.lang.String UNKNOWN = "unknown"; +public static final java.lang.String ID; +public static final java.lang.String DISPLAY; +public static final java.lang.String PRODUCT; +public static final java.lang.String DEVICE; +public static final java.lang.String BOARD; +public static final java.lang.String CPU_ABI; +public static final java.lang.String CPU_ABI2; +public static final java.lang.String MANUFACTURER; +public static final java.lang.String BRAND; +public static final java.lang.String MODEL; +public static final java.lang.String BOOTLOADER; +@java.lang.Deprecated() +public static final java.lang.String RADIO; +public static final java.lang.String HARDWARE; +public static final java.lang.String SERIAL; +public static final java.lang.String TYPE; +public static final java.lang.String TAGS; +public static final java.lang.String FINGERPRINT; +public static final long TIME; +public static final java.lang.String USER; +public static final java.lang.String HOST; +static { ID = null; DISPLAY = null; PRODUCT = null; DEVICE = null; BOARD = null; CPU_ABI = null; CPU_ABI2 = null; MANUFACTURER = null; BRAND = null; MODEL = null; BOOTLOADER = null; RADIO = null; HARDWARE = null; SERIAL = null; TYPE = null; TAGS = null; FINGERPRINT = null; TIME = 0; USER = null; HOST = null; } +} diff --git a/src/android/os/Environment.java b/src/android/os/Environment.java new file mode 100644 index 00000000..2848a0c5 --- /dev/null +++ b/src/android/os/Environment.java @@ -0,0 +1,49 @@ +package android.os; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class Environment +{ + final static File tempDir; + static { + File dir; + try { + dir = Files.createTempDirectory("connectsdk").toFile(); + } catch (IOException ex) { + Logger.getLogger(Environment.class.getName()).log(Level.SEVERE, null, ex); + dir = null; + } + tempDir = dir; + } +public Environment() { } +public static java.io.File getRootDirectory() { throw new RuntimeException("Stub!"); } +public static java.io.File getDataDirectory() { throw new RuntimeException("Stub!"); } +public static java.io.File getExternalStorageDirectory() { return tempDir; } +public static java.io.File getExternalStoragePublicDirectory(java.lang.String type) { throw new RuntimeException("Stub!"); } +public static java.io.File getDownloadCacheDirectory() { throw new RuntimeException("Stub!"); } +public static java.lang.String getExternalStorageState() { return Environment.MEDIA_MOUNTED; /*throw new RuntimeException("Stub!");*/ } +public static boolean isExternalStorageRemovable() { throw new RuntimeException("Stub!"); } +public static boolean isExternalStorageEmulated() { throw new RuntimeException("Stub!"); } +public static java.lang.String DIRECTORY_MUSIC; +public static java.lang.String DIRECTORY_PODCASTS; +public static java.lang.String DIRECTORY_RINGTONES; +public static java.lang.String DIRECTORY_ALARMS; +public static java.lang.String DIRECTORY_NOTIFICATIONS; +public static java.lang.String DIRECTORY_PICTURES; +public static java.lang.String DIRECTORY_MOVIES; +public static java.lang.String DIRECTORY_DOWNLOADS; +public static java.lang.String DIRECTORY_DCIM; +public static final java.lang.String MEDIA_REMOVED = "removed"; +public static final java.lang.String MEDIA_UNMOUNTED = "unmounted"; +public static final java.lang.String MEDIA_CHECKING = "checking"; +public static final java.lang.String MEDIA_NOFS = "nofs"; +public static final java.lang.String MEDIA_MOUNTED = "mounted"; +public static final java.lang.String MEDIA_MOUNTED_READ_ONLY = "mounted_ro"; +public static final java.lang.String MEDIA_SHARED = "shared"; +public static final java.lang.String MEDIA_BAD_REMOVAL = "bad_removal"; +public static final java.lang.String MEDIA_UNMOUNTABLE = "unmountable"; +} diff --git a/src/android/os/Parcelable.java b/src/android/os/Parcelable.java new file mode 100644 index 00000000..cdf8abee --- /dev/null +++ b/src/android/os/Parcelable.java @@ -0,0 +1,18 @@ +package android.os; +public interface Parcelable +{ +public static interface Creator +{ +//public abstract T createFromParcel(android.os.Parcel source); +public abstract T[] newArray(int size); +} +public static interface ClassLoaderCreator + extends android.os.Parcelable.Creator +{ +//public abstract T createFromParcel(android.os.Parcel source, java.lang.ClassLoader loader); +} +public abstract int describeContents(); +//public abstract void writeToParcel(android.os.Parcel dest, int flags); +public static final int PARCELABLE_WRITE_RETURN_VALUE = 1; +public static final int CONTENTS_FILE_DESCRIPTOR = 1; +} diff --git a/src/android/support/annotation/NonNull.java b/src/android/support/annotation/NonNull.java new file mode 100644 index 00000000..402c3c4b --- /dev/null +++ b/src/android/support/annotation/NonNull.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * 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 android.support.annotation; +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/android/text/Html.java b/src/android/text/Html.java new file mode 100644 index 00000000..4cf55f02 --- /dev/null +++ b/src/android/text/Html.java @@ -0,0 +1,17 @@ +package android.text; +public class Html +{ +public static interface ImageGetter +{ +//public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String source); +} +public static interface TagHandler +{ +//public abstract void handleTag(boolean opening, java.lang.String tag, android.text.Editable output, org.xml.sax.XMLReader xmlReader); +} +Html() { throw new RuntimeException("Stub!"); } +public static android.text.Spanned fromHtml(java.lang.String source) { throw new RuntimeException("Stub!"); } +public static android.text.Spanned fromHtml(java.lang.String source, android.text.Html.ImageGetter imageGetter, android.text.Html.TagHandler tagHandler) { throw new RuntimeException("Stub!"); } +public static java.lang.String toHtml(android.text.Spanned text) { throw new RuntimeException("Stub!"); } +public static java.lang.String escapeHtml(java.lang.CharSequence text) { throw new RuntimeException("Stub!"); } +} diff --git a/src/android/text/Spanned.java b/src/android/text/Spanned.java new file mode 100644 index 00000000..cdf76743 --- /dev/null +++ b/src/android/text/Spanned.java @@ -0,0 +1,26 @@ +package android.text; +public interface Spanned + extends java.lang.CharSequence +{ +public abstract T[] getSpans(int start, int end, java.lang.Class type); +public abstract int getSpanStart(java.lang.Object tag); +public abstract int getSpanEnd(java.lang.Object tag); +public abstract int getSpanFlags(java.lang.Object tag); +public abstract int nextSpanTransition(int start, int limit, java.lang.Class type); +public static final int SPAN_POINT_MARK_MASK = 51; +public static final int SPAN_MARK_MARK = 17; +public static final int SPAN_MARK_POINT = 18; +public static final int SPAN_POINT_MARK = 33; +public static final int SPAN_POINT_POINT = 34; +public static final int SPAN_PARAGRAPH = 51; +public static final int SPAN_INCLUSIVE_EXCLUSIVE = 17; +public static final int SPAN_INCLUSIVE_INCLUSIVE = 18; +public static final int SPAN_EXCLUSIVE_EXCLUSIVE = 33; +public static final int SPAN_EXCLUSIVE_INCLUSIVE = 34; +public static final int SPAN_COMPOSING = 256; +public static final int SPAN_INTERMEDIATE = 512; +public static final int SPAN_USER_SHIFT = 24; +public static final int SPAN_USER = -16777216; +public static final int SPAN_PRIORITY_SHIFT = 16; +public static final int SPAN_PRIORITY = 16711680; +} diff --git a/src/android/text/TextUtils.java b/src/android/text/TextUtils.java new file mode 100644 index 00000000..065e5243 --- /dev/null +++ b/src/android/text/TextUtils.java @@ -0,0 +1,73 @@ +package android.text; +public class TextUtils +{ +public static interface StringSplitter + extends java.lang.Iterable +{ +public abstract void setString(java.lang.String string); +} +public static class SimpleStringSplitter + implements android.text.TextUtils.StringSplitter, java.util.Iterator +{ +public SimpleStringSplitter(char delimiter) { throw new RuntimeException("Stub!"); } +public void setString(java.lang.String string) { throw new RuntimeException("Stub!"); } +public java.util.Iterator iterator() { throw new RuntimeException("Stub!"); } +public boolean hasNext() { throw new RuntimeException("Stub!"); } +public java.lang.String next() { throw new RuntimeException("Stub!"); } +public void remove() { throw new RuntimeException("Stub!"); } +} +public static enum TruncateAt +{ +END(), +MARQUEE(), +MIDDLE(), +START(); +} +public static interface EllipsizeCallback +{ +public abstract void ellipsized(int start, int end); +} +TextUtils() { throw new RuntimeException("Stub!"); } +public static void getChars(java.lang.CharSequence s, int start, int end, char[] dest, int destoff) { throw new RuntimeException("Stub!"); } +public static int indexOf(java.lang.CharSequence s, char ch) { throw new RuntimeException("Stub!"); } +public static int indexOf(java.lang.CharSequence s, char ch, int start) { throw new RuntimeException("Stub!"); } +public static int indexOf(java.lang.CharSequence s, char ch, int start, int end) { throw new RuntimeException("Stub!"); } +public static int lastIndexOf(java.lang.CharSequence s, char ch) { throw new RuntimeException("Stub!"); } +public static int lastIndexOf(java.lang.CharSequence s, char ch, int last) { throw new RuntimeException("Stub!"); } +public static int lastIndexOf(java.lang.CharSequence s, char ch, int start, int last) { throw new RuntimeException("Stub!"); } +public static int indexOf(java.lang.CharSequence s, java.lang.CharSequence needle) { throw new RuntimeException("Stub!"); } +public static int indexOf(java.lang.CharSequence s, java.lang.CharSequence needle, int start) { throw new RuntimeException("Stub!"); } +public static int indexOf(java.lang.CharSequence s, java.lang.CharSequence needle, int start, int end) { throw new RuntimeException("Stub!"); } +public static boolean regionMatches(java.lang.CharSequence one, int toffset, java.lang.CharSequence two, int ooffset, int len) { throw new RuntimeException("Stub!"); } +public static java.lang.String substring(java.lang.CharSequence source, int start, int end) { throw new RuntimeException("Stub!"); } +public static java.lang.String join(java.lang.CharSequence delimiter, java.lang.Object[] tokens) { throw new RuntimeException("Stub!"); } +public static java.lang.String join(java.lang.CharSequence delimiter, java.lang.Iterable tokens) { throw new RuntimeException("Stub!"); } +public static java.lang.String[] split(java.lang.String text, java.lang.String expression) { throw new RuntimeException("Stub!"); } +public static java.lang.String[] split(java.lang.String text, java.util.regex.Pattern pattern) { throw new RuntimeException("Stub!"); } +public static java.lang.CharSequence stringOrSpannedString(java.lang.CharSequence source) { throw new RuntimeException("Stub!"); } +public static boolean isEmpty(java.lang.CharSequence str) { throw new RuntimeException("Stub!"); } +public static int getTrimmedLength(java.lang.CharSequence s) { throw new RuntimeException("Stub!"); } +public static boolean equals(java.lang.CharSequence a, java.lang.CharSequence b) { throw new RuntimeException("Stub!"); } +public static java.lang.CharSequence getReverse(java.lang.CharSequence source, int start, int end) { throw new RuntimeException("Stub!"); } +//public static void writeToParcel(java.lang.CharSequence cs, android.os.Parcel p, int parcelableFlags) { throw new RuntimeException("Stub!"); } +//public static void dumpSpans(java.lang.CharSequence cs, android.util.Printer printer, java.lang.String prefix) { throw new RuntimeException("Stub!"); } +public static java.lang.CharSequence replace(java.lang.CharSequence template, java.lang.String[] sources, java.lang.CharSequence[] destinations) { throw new RuntimeException("Stub!"); } +public static java.lang.CharSequence expandTemplate(java.lang.CharSequence template, java.lang.CharSequence... values) { throw new RuntimeException("Stub!"); } +public static int getOffsetBefore(java.lang.CharSequence text, int offset) { throw new RuntimeException("Stub!"); } +public static int getOffsetAfter(java.lang.CharSequence text, int offset) { throw new RuntimeException("Stub!"); } +//public static void copySpansFrom(android.text.Spanned source, int start, int end, java.lang.Class kind, android.text.Spannable dest, int destoff) { throw new RuntimeException("Stub!"); } +//public static java.lang.CharSequence ellipsize(java.lang.CharSequence text, android.text.TextPaint p, float avail, android.text.TextUtils.TruncateAt where) { throw new RuntimeException("Stub!"); } +//public static java.lang.CharSequence ellipsize(java.lang.CharSequence text, android.text.TextPaint paint, float avail, android.text.TextUtils.TruncateAt where, boolean preserveLength, android.text.TextUtils.EllipsizeCallback callback) { throw new RuntimeException("Stub!"); } +//public static java.lang.CharSequence commaEllipsize(java.lang.CharSequence text, android.text.TextPaint p, float avail, java.lang.String oneMore, java.lang.String more) { throw new RuntimeException("Stub!"); } +public static java.lang.String htmlEncode(java.lang.String s) { throw new RuntimeException("Stub!"); } +public static java.lang.CharSequence concat(java.lang.CharSequence... text) { throw new RuntimeException("Stub!"); } +public static boolean isGraphic(java.lang.CharSequence str) { throw new RuntimeException("Stub!"); } +public static boolean isGraphic(char c) { throw new RuntimeException("Stub!"); } +public static boolean isDigitsOnly(java.lang.CharSequence str) { throw new RuntimeException("Stub!"); } +public static int getCapsMode(java.lang.CharSequence cs, int off, int reqModes) { throw new RuntimeException("Stub!"); } +public static final android.os.Parcelable.Creator CHAR_SEQUENCE_CREATOR; +public static final int CAP_MODE_CHARACTERS = 4096; +public static final int CAP_MODE_WORDS = 8192; +public static final int CAP_MODE_SENTENCES = 16384; +static { CHAR_SEQUENCE_CREATOR = null; } +} diff --git a/src/android/util/AndroidException.java b/src/android/util/AndroidException.java new file mode 100644 index 00000000..282bc2b6 --- /dev/null +++ b/src/android/util/AndroidException.java @@ -0,0 +1,7 @@ +package android.util; +public class AndroidException extends java.lang.Exception { +public AndroidException() { super (); } +public AndroidException(java.lang.String name) { super(name); } +public AndroidException(java.lang.String name, java.lang.Throwable cause) { super(name, cause); } +public AndroidException(java.lang.Exception cause) { super(cause); } +} diff --git a/src/android/util/Base64.java b/src/android/util/Base64.java new file mode 100644 index 00000000..4bc677a5 --- /dev/null +++ b/src/android/util/Base64.java @@ -0,0 +1,24 @@ +package android.util; + +import javax.xml.bind.DatatypeConverter; + +public class Base64 +{ +Base64() { throw new RuntimeException("Stub!"); } +public static byte[] decode(java.lang.String str, int flags) { throw new RuntimeException("Stub!"); } +public static byte[] decode(byte[] input, int flags) { throw new RuntimeException("Stub!"); } +public static byte[] decode(byte[] input, int offset, int len, int flags) { throw new RuntimeException("Stub!"); } +public static java.lang.String encodeToString(byte[] input, int flags) { + //return java.util.Base64.getEncoder().encodeToString(input); // only available in java 1.8 + return DatatypeConverter.printBase64Binary(input); +} +public static java.lang.String encodeToString(byte[] input, int offset, int len, int flags) { throw new RuntimeException("Stub!"); } +public static byte[] encode(byte[] input, int flags) { throw new RuntimeException("Stub!"); } +public static byte[] encode(byte[] input, int offset, int len, int flags) { throw new RuntimeException("Stub!"); } +public static final int DEFAULT = 0; +public static final int NO_PADDING = 1; +public static final int NO_WRAP = 2; +public static final int CRLF = 4; +public static final int URL_SAFE = 8; +public static final int NO_CLOSE = 16; +} diff --git a/src/android/util/ContainerHelpers.java b/src/android/util/ContainerHelpers.java new file mode 100644 index 00000000..de76e430 --- /dev/null +++ b/src/android/util/ContainerHelpers.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * 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 android.util; +class ContainerHelpers { + // This is Arrays.binarySearch(), but doesn't do any argument validation. + static int binarySearch(int[] array, int size, int value) { + int lo = 0; + int hi = size - 1; + while (lo <= hi) { + final int mid = (lo + hi) >>> 1; + final int midVal = array[mid]; + if (midVal < value) { + lo = mid + 1; + } else if (midVal > value) { + hi = mid - 1; + } else { + return mid; // value found + } + } + return ~lo; // value not present + } + static int binarySearch(long[] array, int size, long value) { + int lo = 0; + int hi = size - 1; + while (lo <= hi) { + final int mid = (lo + hi) >>> 1; + final long midVal = array[mid]; + if (midVal < value) { + lo = mid + 1; + } else if (midVal > value) { + hi = mid - 1; + } else { + return mid; // value found + } + } + return ~lo; // value not present + } +} \ No newline at end of file diff --git a/src/android/util/Log.java b/src/android/util/Log.java new file mode 100644 index 00000000..d4a058dd --- /dev/null +++ b/src/android/util/Log.java @@ -0,0 +1,134 @@ +package android.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class Log { + + private static final Logger l = LoggerFactory.getLogger("org.openhab.binding.connectsdk.Log"); + + public static int v(java.lang.String tag, java.lang.String msg) { + l.trace(String.format("%s - %s", tag, msg)); + return 0; // did not find in android documentation what return codes + // mean + } + + public static int v(java.lang.String tag, java.lang.String msg, + java.lang.Throwable tr) { + l.trace(String.format("%s - %s", tag, msg), tr); + return 0; + } + + 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 d(java.lang.String tag, java.lang.String msg, + java.lang.Throwable tr) { + l.debug(String.format("%s - %s",tag, msg),tr); + return 0; + } + + public static int i(java.lang.String tag, java.lang.String msg) { + l.info(String.format("%s - %s", tag, msg)); + return 0; + } + + public static int i(java.lang.String tag, java.lang.String msg, + java.lang.Throwable tr) { + l.info(String.format("%s - %s",tag, msg),tr); + 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 w(java.lang.String tag, java.lang.String msg, + java.lang.Throwable tr) { + l.warn(String.format("%s - %s",tag, msg), tr); + return 0; + } + + public static boolean isLoggable(java.lang.String tag, int level) { + switch (level) { + case VERBOSE: + return l.isTraceEnabled(); + case DEBUG: + return l.isDebugEnabled(); + case INFO: + return l.isInfoEnabled(); + case WARN: + return l.isWarnEnabled(); + case ERROR: + case ASSERT: + return l.isErrorEnabled(); + default: + return false; + } + } + + public static int w(java.lang.String tag, java.lang.Throwable tr) { + l.warn(tag, tr); + 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; + } + + public static int wtf(java.lang.String tag, java.lang.String msg) { + l.error(String.format("%s - %s",tag, msg)); + return 0; + + } + + public static int wtf(java.lang.String tag, java.lang.Throwable tr) { + l.error(tag, tr); + return 0; + } + + public static int wtf(java.lang.String tag, java.lang.String msg, + java.lang.Throwable tr) { + l.error(String.format("%s - %s",tag, msg), tr); + return 0; + } + + public static java.lang.String getStackTraceString(java.lang.Throwable tr) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public static int println(int priority, java.lang.String tag, + java.lang.String msg) { + switch (priority) { + case VERBOSE: + return v(tag,msg); + case DEBUG: + return d(tag,msg); + case INFO: + return i(tag,msg); + case WARN: + return w(tag,msg); + case ERROR: + case ASSERT: + return e(tag,msg); + default: + return -1; + } + } + + public static final int VERBOSE = 2; + public static final int DEBUG = 3; + public static final int INFO = 4; + public static final int WARN = 5; + public static final int ERROR = 6; + public static final int ASSERT = 7; +} diff --git a/src/android/util/SparseArray.java b/src/android/util/SparseArray.java new file mode 100644 index 00000000..e2853c0b --- /dev/null +++ b/src/android/util/SparseArray.java @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * 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 android.util; +//import com.android.internal.util.ArrayUtils; +import com.android.internal.util.GrowingArrayUtils; + +/** + * SparseArrays map integers to Objects. Unlike a normal array of Objects, + * there can be gaps in the indices. It is intended to be more memory efficient + * than using a HashMap to map Integers to Objects, both because it avoids + * auto-boxing keys and its data structure doesn't rely on an extra entry object + * for each mapping. + * + *

      Note that this container keeps its mappings in an array data structure, + * using a binary search to find keys. The implementation is not intended to be appropriate for + * data structures + * that may contain large numbers of items. It is generally slower than a traditional + * HashMap, since lookups require a binary search and adds and removes require inserting + * and deleting entries in the array. For containers holding up to hundreds of items, + * the performance difference is not significant, less than 50%.

      + * + *

      To help with performance, the container includes an optimization when removing + * keys: instead of compacting its array immediately, it leaves the removed entry marked + * as deleted. The entry can then be re-used for the same key, or compacted later in + * a single garbage collection step of all removed entries. This garbage collection will + * need to be performed at any time the array needs to be grown or the the map size or + * entry values are retrieved.

      + * + *

      It is possible to iterate over the items in this container using + * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using + * keyAt(int) with ascending values of the index will return the + * keys in ascending order, or the values corresponding to the keys in ascending + * order in the case of valueAt(int).

      + */ +public class SparseArray implements Cloneable { + private static final Object DELETED = new Object(); + private boolean mGarbage = false; + private int[] mKeys; + private Object[] mValues; + private int mSize; + /** + * Creates a new SparseArray containing no mappings. + */ + public SparseArray() { + this(10); + } + /** + * Creates a new SparseArray containing no mappings that will not + * require any additional memory allocation to store the specified + * number of mappings. If you supply an initial capacity of 0, the + * sparse array will be initialized with a light-weight representation + * not requiring any additional array allocations. + */ + public SparseArray(int initialCapacity) { + if (initialCapacity == 0) { + mKeys = new int[0]; + mValues = new Object[0]; + } else { + mValues = new Object[initialCapacity]; + mKeys = new int[mValues.length]; + } + mSize = 0; + } + @Override + @SuppressWarnings("unchecked") + public SparseArray clone() { + SparseArray clone = null; + try { + clone = (SparseArray) super.clone(); + clone.mKeys = mKeys.clone(); + clone.mValues = mValues.clone(); + } catch (CloneNotSupportedException cnse) { + /* ignore */ + } + return clone; + } + /** + * Gets the Object mapped from the specified key, or null + * if no such mapping has been made. + */ + public E get(int key) { + return get(key, null); + } + /** + * Gets the Object mapped from the specified key, or the specified Object + * if no such mapping has been made. + */ + @SuppressWarnings("unchecked") + public E get(int key, E valueIfKeyNotFound) { + int i = ContainerHelpers.binarySearch(mKeys, mSize, key); + if (i < 0 || mValues[i] == DELETED) { + return valueIfKeyNotFound; + } else { + return (E) mValues[i]; + } + } + /** + * Removes the mapping from the specified key, if there was any. + */ + public void delete(int key) { + int i = ContainerHelpers.binarySearch(mKeys, mSize, key); + if (i >= 0) { + if (mValues[i] != DELETED) { + mValues[i] = DELETED; + mGarbage = true; + } + } + } + /** + * @hide + * Removes the mapping from the specified key, if there was any, returning the old value. + */ + public E removeReturnOld(int key) { + int i = ContainerHelpers.binarySearch(mKeys, mSize, key); + if (i >= 0) { + if (mValues[i] != DELETED) { + final E old = (E) mValues[i]; + mValues[i] = DELETED; + mGarbage = true; + return old; + } + } + return null; + } + /** + * Alias for {@link #delete(int)}. + */ + public void remove(int key) { + delete(key); + } + /** + * Removes the mapping at the specified index. + */ + public void removeAt(int index) { + if (mValues[index] != DELETED) { + mValues[index] = DELETED; + mGarbage = true; + } + } + /** + * Remove a range of mappings as a batch. + * + * @param index Index to begin at + * @param size Number of mappings to remove + */ + public void removeAtRange(int index, int size) { + final int end = Math.min(mSize, index + size); + for (int i = index; i < end; i++) { + removeAt(i); + } + } + private void gc() { + // Log.e("SparseArray", "gc start with " + mSize); + int n = mSize; + int o = 0; + int[] keys = mKeys; + Object[] values = mValues; + for (int i = 0; i < n; i++) { + Object val = values[i]; + if (val != DELETED) { + if (i != o) { + keys[o] = keys[i]; + values[o] = val; + values[i] = null; + } + o++; + } + } + mGarbage = false; + mSize = o; + // Log.e("SparseArray", "gc end with " + mSize); + } + /** + * Adds a mapping from the specified key to the specified value, + * replacing the previous mapping from the specified key if there + * was one. + */ + public void put(int key, E value) { + int i = ContainerHelpers.binarySearch(mKeys, mSize, key); + if (i >= 0) { + mValues[i] = value; + } else { + i = ~i; + if (i < mSize && mValues[i] == DELETED) { + mKeys[i] = key; + mValues[i] = value; + return; + } + if (mGarbage && mSize >= mKeys.length) { + gc(); + // Search again because indices may have changed. + i = ContainerHelpers.binarySearch(mKeys, mSize, key); + } + mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key); + mValues = GrowingArrayUtils.insert(mValues, mSize, i, value); + mSize++; + } + } + /** + * Returns the number of key-value mappings that this SparseArray + * currently stores. + */ + public int size() { + if (mGarbage) { + gc(); + } + return mSize; + } + /** + * Given an index in the range 0...size()-1, returns + * the key from the indexth key-value mapping that this + * SparseArray stores. + * + *

      The keys corresponding to indices in ascending order are guaranteed to + * be in ascending order, e.g., keyAt(0) will return the + * smallest key and keyAt(size()-1) will return the largest + * key.

      + */ + public int keyAt(int index) { + if (mGarbage) { + gc(); + } + return mKeys[index]; + } + /** + * Given an index in the range 0...size()-1, returns + * the value from the indexth key-value mapping that this + * SparseArray stores. + * + *

      The values corresponding to indices in ascending order are guaranteed + * to be associated with keys in ascending order, e.g., + * valueAt(0) will return the value associated with the + * smallest key and valueAt(size()-1) will return the value + * associated with the largest key.

      + */ + @SuppressWarnings("unchecked") + public E valueAt(int index) { + if (mGarbage) { + gc(); + } + return (E) mValues[index]; + } + /** + * Given an index in the range 0...size()-1, sets a new + * value for the indexth key-value mapping that this + * SparseArray stores. + */ + public void setValueAt(int index, E value) { + if (mGarbage) { + gc(); + } + mValues[index] = value; + } + /** + * Returns the index for which {@link #keyAt} would return the + * specified key, or a negative number if the specified + * key is not mapped. + */ + public int indexOfKey(int key) { + if (mGarbage) { + gc(); + } + return ContainerHelpers.binarySearch(mKeys, mSize, key); + } + /** + * Returns an index for which {@link #valueAt} would return the + * specified key, or a negative number if no keys map to the + * specified value. + *

      Beware that this is a linear search, unlike lookups by key, + * and that multiple keys can map to the same value and this will + * find only one of them. + *

      Note also that unlike most collections' {@code indexOf} methods, + * this method compares values using {@code ==} rather than {@code equals}. + */ + public int indexOfValue(E value) { + if (mGarbage) { + gc(); + } + for (int i = 0; i < mSize; i++) + if (mValues[i] == value) + return i; + return -1; + } + /** + * Removes all key-value mappings from this SparseArray. + */ + public void clear() { + int n = mSize; + Object[] values = mValues; + for (int i = 0; i < n; i++) { + values[i] = null; + } + mSize = 0; + mGarbage = false; + } + /** + * Puts a key/value pair into the array, optimizing for the case where + * the key is greater than all existing keys in the array. + */ + public void append(int key, E value) { + if (mSize != 0 && key <= mKeys[mSize - 1]) { + put(key, value); + return; + } + if (mGarbage && mSize >= mKeys.length) { + gc(); + } + mKeys = GrowingArrayUtils.append(mKeys, mSize, key); + mValues = GrowingArrayUtils.append(mValues, mSize, value); + mSize++; + } + /** + * {@inheritDoc} + * + *

      This implementation composes a string by iterating over its mappings. If + * this map contains itself as a value, the string "(this Map)" + * will appear in its place. + */ + @Override + public String toString() { + if (size() <= 0) { + return "{}"; + } + StringBuilder buffer = new StringBuilder(mSize * 28); + buffer.append('{'); + for (int i=0; i 0) { + buffer.append(", "); + } + int key = keyAt(i); + buffer.append(key); + buffer.append('='); + Object value = valueAt(i); + if (value != this) { + buffer.append(value); + } else { + buffer.append("(this Map)"); + } + } + buffer.append('}'); + return buffer.toString(); + } +} \ No newline at end of file diff --git a/src/android/util/Xml.java b/src/android/util/Xml.java new file mode 100644 index 00000000..7c45145d --- /dev/null +++ b/src/android/util/Xml.java @@ -0,0 +1,44 @@ +package android.util; + +public class Xml { + public static enum Encoding { + ISO_8859_1(), + US_ASCII(), + UTF_16(), + UTF_8(); + } + + Xml() { + throw new RuntimeException("Stub!"); + } + + public static void parse(java.lang.String xml, org.xml.sax.ContentHandler contentHandler) + throws org.xml.sax.SAXException { + throw new RuntimeException("Stub!"); + } + + public static void parse(java.io.Reader in, org.xml.sax.ContentHandler contentHandler) + throws java.io.IOException, org.xml.sax.SAXException { + throw new RuntimeException("Stub!"); + } + + public static void parse(java.io.InputStream in, android.util.Xml.Encoding encoding, + org.xml.sax.ContentHandler contentHandler) throws java.io.IOException, org.xml.sax.SAXException { + throw new RuntimeException("Stub!"); + } + + public static org.xmlpull.v1.XmlPullParser newPullParser() { + throw new RuntimeException("Stub!"); + } + + // public static org.xmlpull.v1.XmlSerializer newSerializer() {throw new RuntimeException("Stub!"); } + + public static android.util.Xml.Encoding findEncodingByName(java.lang.String encodingName) + throws java.io.UnsupportedEncodingException { + throw new RuntimeException("Stub!"); + } + + // public static android.util.AttributeSet asAttributeSet(org.xmlpull.v1.XmlPullParser parser) { throw new + // RuntimeException("Stub!"); } + public static java.lang.String FEATURE_RELAXED; +} diff --git a/src/android/view/Display.java b/src/android/view/Display.java new file mode 100644 index 00000000..42510b44 --- /dev/null +++ b/src/android/view/Display.java @@ -0,0 +1,20 @@ +package android.view; +public class Display +{ +public Display() { } +public int getDisplayId() { throw new RuntimeException("Stub!"); } +//public void getSize(android.graphics.Point outSize) { throw new RuntimeException("Stub!"); } +//public void getRectSize(android.graphics.Rect outSize) { throw new RuntimeException("Stub!"); } +//public void getCurrentSizeRange(android.graphics.Point outSmallestSize, android.graphics.Point outLargestSize) { throw new RuntimeException("Stub!"); } +@java.lang.Deprecated() +public int getWidth() { return 0; /*throw new RuntimeException("Stub!"); */} +@java.lang.Deprecated() +public int getHeight() { return 0; /*throw new RuntimeException("Stub!"); */} +public int getRotation() { throw new RuntimeException("Stub!"); } +@java.lang.Deprecated() +public native int getOrientation(); +public int getPixelFormat() { throw new RuntimeException("Stub!"); } +public float getRefreshRate() { throw new RuntimeException("Stub!"); } +//public void getMetrics(android.util.DisplayMetrics outMetrics) { throw new RuntimeException("Stub!"); } +public static final int DEFAULT_DISPLAY = 0; +} diff --git a/src/com/android/internal/util/GrowingArrayUtils.java b/src/com/android/internal/util/GrowingArrayUtils.java new file mode 100644 index 00000000..d2b04f16 --- /dev/null +++ b/src/com/android/internal/util/GrowingArrayUtils.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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.android.internal.util; +/** + * A helper class that aims to provide comparable growth performance to ArrayList, but on primitive + * arrays. Common array operations are implemented for efficient use in dynamic containers. + * + * All methods in this class assume that the length of an array is equivalent to its capacity and + * NOT the number of elements in the array. The current size of the array is always passed in as a + * parameter. + * + * @hide + */ +public final class GrowingArrayUtils { + /** + * Appends an element to the end of the array, growing the array if there is no more room. + * @param array The array to which to append the element. This must NOT be null. + * @param currentSize The number of elements in the array. Must be less than or equal to + * array.length. + * @param element The element to append. + * @return the array to which the element was appended. This may be different than the given + * array. + */ + public static T[] append(T[] array, int currentSize, T element) { + assert currentSize <= array.length; + if (currentSize + 1 > array.length) { + @SuppressWarnings("unchecked") + T[] newArray = (T[]) new Object[growSize(currentSize)]; + System.arraycopy(array, 0, newArray, 0, currentSize); + array = newArray; + } + array[currentSize] = element; + return array; + } + /** + * Primitive int version of {@link #append(Object[], int, Object)}. + */ + public static int[] append(int[] array, int currentSize, int element) { + assert currentSize <= array.length; + if (currentSize + 1 > array.length) { + int[] newArray = new int[growSize(currentSize)]; + System.arraycopy(array, 0, newArray, 0, currentSize); + array = newArray; + } + array[currentSize] = element; + return array; + } + /** + * Primitive long version of {@link #append(Object[], int, Object)}. + */ + public static long[] append(long[] array, int currentSize, long element) { + assert currentSize <= array.length; + if (currentSize + 1 > array.length) { + long[] newArray = new long[growSize(currentSize)]; + System.arraycopy(array, 0, newArray, 0, currentSize); + array = newArray; + } + array[currentSize] = element; + return array; + } + /** + * Primitive boolean version of {@link #append(Object[], int, Object)}. + */ + public static boolean[] append(boolean[] array, int currentSize, boolean element) { + assert currentSize <= array.length; + if (currentSize + 1 > array.length) { + boolean[] newArray = new boolean[growSize(currentSize)]; + System.arraycopy(array, 0, newArray, 0, currentSize); + array = newArray; + } + array[currentSize] = element; + return array; + } + /** + * Inserts an element into the array at the specified index, growing the array if there is no + * more room. + * + * @param array The array to which to append the element. Must NOT be null. + * @param currentSize The number of elements in the array. Must be less than or equal to + * array.length. + * @param element The element to insert. + * @return the array to which the element was appended. This may be different than the given + * array. + */ + public static T[] insert(T[] array, int currentSize, int index, T element) { + assert currentSize <= array.length; + if (currentSize + 1 <= array.length) { + System.arraycopy(array, index, array, index + 1, currentSize - index); + array[index] = element; + return array; + } + @SuppressWarnings("unchecked") + T[] newArray = (T[]) new Object[growSize(currentSize)]; + System.arraycopy(array, 0, newArray, 0, index); + newArray[index] = element; + System.arraycopy(array, index, newArray, index + 1, array.length - index); + return newArray; + } + /** + * Primitive int version of {@link #insert(Object[], int, int, Object)}. + */ + public static int[] insert(int[] array, int currentSize, int index, int element) { + assert currentSize <= array.length; + if (currentSize + 1 <= array.length) { + System.arraycopy(array, index, array, index + 1, currentSize - index); + array[index] = element; + return array; + } + int[] newArray = new int[growSize(currentSize)]; + System.arraycopy(array, 0, newArray, 0, index); + newArray[index] = element; + System.arraycopy(array, index, newArray, index + 1, array.length - index); + return newArray; + } + /** + * Primitive long version of {@link #insert(Object[], int, int, Object)}. + */ + public static long[] insert(long[] array, int currentSize, int index, long element) { + assert currentSize <= array.length; + if (currentSize + 1 <= array.length) { + System.arraycopy(array, index, array, index + 1, currentSize - index); + array[index] = element; + return array; + } + long[] newArray = new long[growSize(currentSize)]; + System.arraycopy(array, 0, newArray, 0, index); + newArray[index] = element; + System.arraycopy(array, index, newArray, index + 1, array.length - index); + return newArray; + } + /** + * Primitive boolean version of {@link #insert(Object[], int, int, Object)}. + */ + public static boolean[] insert(boolean[] array, int currentSize, int index, boolean element) { + assert currentSize <= array.length; + if (currentSize + 1 <= array.length) { + System.arraycopy(array, index, array, index + 1, currentSize - index); + array[index] = element; + return array; + } + boolean[] newArray = new boolean [growSize(currentSize)]; + System.arraycopy(array, 0, newArray, 0, index); + newArray[index] = element; + System.arraycopy(array, index, newArray, index + 1, array.length - index); + return newArray; + } + /** + * Given the current size of an array, returns an ideal size to which the array should grow. + * This is typically double the given size, but should not be relied upon to do so in the + * future. + */ + public static int growSize(int currentSize) { + return currentSize <= 4 ? 8 : currentSize * 2; + } + // Uninstantiable + private GrowingArrayUtils() {} +} \ No newline at end of file diff --git a/src/com/connectsdk/discovery/DiscoveryManager.java b/src/com/connectsdk/discovery/DiscoveryManager.java index 84af81df..82b938b1 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,6 @@ 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.Util; import com.connectsdk.device.ConnectableDevice; import com.connectsdk.device.ConnectableDeviceListener; @@ -58,32 +47,51 @@ import com.connectsdk.service.config.ServiceConfig.ServiceConfigListener; import com.connectsdk.service.config.ServiceDescription; +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; + /** * ###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 + * @code + * DiscoveryManager.init(getApplicationContext()); + * DiscoveryManager discoveryManager = DiscoveryManager.getInstance(); + * discoveryManager.addListener(this); + * discoveryManager.start(); + * @endcode * - * [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 { @@ -138,11 +146,12 @@ public enum PairingLevel { // @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 + * @code + * DiscoveryManager.init(getApplicationContext()); + * @endcode */ public static synchronized void init(Context context) { instance = new DiscoveryManager(context); @@ -153,14 +162,15 @@ 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 + * @code + * MyConnectableDeviceStore myDeviceStore = new MyConnectableDeviceStore(); + * DiscoveryManager.init(getApplicationContext(), myDeviceStore); + * @endcode */ public static synchronized void init(Context context, ConnectableDeviceStore connectableDeviceStore) { instance = new DiscoveryManager(context, connectableDeviceStore); @@ -170,8 +180,9 @@ public static synchronized void init(Context context, ConnectableDeviceStore con * Get 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; } @@ -210,52 +221,52 @@ public DiscoveryManager(Context context, ConnectableDeviceStore connectableDevic capabilityFilters = new ArrayList(); pairingLevel = PairingLevel.OFF; - receiver = new BroadcastReceiver() { + receiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { + @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(); + case CONNECTED: + if (mSearching) { + for (DiscoveryProvider provider : discoveryProviders) { + provider.restart(); + } } - } - break; + break; - case DISCONNECTED: - Log.w(Util.T, "Network connection is disconnected"); + case DISCONNECTED: + Log.w(Util.T, "Network connection is disconnected"); - for (DiscoveryProvider provider : discoveryProviders) { - provider.reset(); - } + for (DiscoveryProvider provider : discoveryProviders) { + provider.reset(); + } - allDevices.clear(); + allDevices.clear(); - for (ConnectableDevice device: compatibleDevices.values()) { - handleDeviceLoss(device); - } - compatibleDevices.clear(); - - break; - - case CONNECTING: - break; - case DISCONNECTING: - break; - case SUSPENDED: - break; - case UNKNOWN: - break; + for (ConnectableDevice device : compatibleDevices.values()) { + handleDeviceLoss(device); + } + compatibleDevices.clear(); + + break; + + case CONNECTING: + break; + case DISCONNECTING: + break; + case SUSPENDED: + break; + case UNKNOWN: + break; } } - } + } }; registerBroadcastReceiver(); @@ -281,13 +292,17 @@ private void unregisterBroadcastReceiver() { } /** - * 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. + * 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. * - * 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. */ 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); @@ -300,20 +315,20 @@ 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); @@ -336,7 +351,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 +363,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(); + 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 +411,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 +454,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 +475,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 +493,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,8 +538,9 @@ 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; @@ -516,7 +557,8 @@ public void run() { registerDefaultDeviceTypes(); } - ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + ConnectivityManager connManager = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); if (mWifi.isConnected()) { @@ -530,8 +572,10 @@ public void run() { @Override public void run() { - for (DiscoveryManagerListener listener : discoveryListeners) - listener.onDiscoveryFailed(DiscoveryManager.this, new ServiceCommandError(0, "No wifi connection", null)); + for (DiscoveryManagerListener listener : discoveryListeners) { + listener.onDiscoveryFailed(DiscoveryManager.this, + new ServiceCommandError(0, "No wifi connection", null)); + } } }); } @@ -543,8 +587,9 @@ public void run() { * Stop scanning for devices. */ public void stop() { - if (!mSearching) + if (!mSearching) { return; + } mSearching = false; @@ -558,26 +603,34 @@ public void stop() { } /** - * 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 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);`. */ 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 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);`. */ public ConnectableDeviceStore getConnectableDeviceStore() { return connectableDeviceStore; @@ -585,12 +638,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 +652,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 +692,45 @@ public boolean isNetcast(ServiceDescription description) { // @endcond /** - * List of all devices discovered by DiscoveryManager. Each ConnectableDevice object is keyed against its current IP address. + * 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. + * 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. */ 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. */ public void setPairingLevel(PairingLevel pairingLevel) { this.pairingLevel = pairingLevel; @@ -705,14 +766,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 +813,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 +826,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 +845,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 +861,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 +915,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/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index 2e5c9e0b..4dc2a75a 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 @@ -33,17 +33,6 @@ 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; @@ -89,8 +78,19 @@ 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 { +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; + +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,13 +104,8 @@ 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 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, @@ -125,18 +120,10 @@ public enum Protected implements WebOSTVServicePermission { 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 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, @@ -145,48 +132,29 @@ 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 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[] 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[] 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 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 +201,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 +250,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 +268,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 +282,9 @@ public void connect() { this.socket.setListener(mSocketListener); } - if (!this.isConnected()) + if (!this.isConnected()) { this.socket.connect(); + } } @Override @@ -336,8 +295,9 @@ public void disconnect() { @Override public void run() { - if (listener != null) + if (listener != null) { listener.onDisconnect(WebOSTVService.this, null); + } } }); @@ -347,8 +307,9 @@ public void run() { socket = null; } - if (mAppToAppIdMappings != null) + if (mAppToAppIdMappings != null) { mAppToAppIdMappings.clear(); + } if (mWebAppSessions != null) { Enumeration iterator = mWebAppSessions.elements(); @@ -379,14 +340,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 +362,9 @@ public void onFailWithError(final ServiceCommandError error) { @Override public void run() { - if (listener != null) + if (listener != null) { listener.onConnectionFailure(WebOSTVService.this, error); + } } }); } @@ -419,8 +384,9 @@ public void onCloseWithError(final ServiceCommandError error) { @Override public void run() { - if (listener != null) + if (listener != null) { listener.onDisconnect(WebOSTVService.this, error); + } } }); } @@ -432,8 +398,9 @@ public void onBeforeRegister(final PairingType pairingType) { @Override public void run() { - if (listener != null) + if (listener != null) { listener.onPairingRequired(WebOSTVService.this, pairingType, null); + } } }); } @@ -491,11 +458,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,11 +490,11 @@ 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) { String uri = "ssap://system.launcher/open"; @@ -559,13 +528,14 @@ 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); + launchYouTube(contentId, (float) 0.0, listener); } @Override @@ -579,16 +549,19 @@ 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); } @@ -603,10 +576,12 @@ 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); } @@ -614,7 +589,8 @@ public void launchHulu(String contentId, Launcher.AppLaunchListener listener) { @Override public void launchNetflix(String contentId, Launcher.AppLaunchListener 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,10 +598,12 @@ 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); } @@ -664,7 +642,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 +662,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 +688,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 +700,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 +718,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 +739,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 +771,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 +788,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 +812,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 +830,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 +869,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,14 +894,13 @@ public void showClickableToastForURL(String message, String url, String iconData } private void sendToast(JSONObject payload, ResponseListener listener) { - if (!payload.has("iconData")) - { + if (!payload.has("iconData")) { Context context = DiscoveryManager.getInstance().getContext(); try { Drawable drawable = context.getPackageManager().getApplicationIcon(context.getPackageName()); - if(drawable != null) { + if (drawable != null) { BitmapDrawable bitDw = ((BitmapDrawable) drawable); Bitmap bitmap = bitDw.getBitmap(); @@ -922,7 +908,7 @@ private void sendToast(JSONObject payload, ResponseListener listener) { bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] bitmapByte = stream.toByteArray(); - bitmapByte = Base64.encode(bitmapByte,Base64.NO_WRAP); + bitmapByte = Base64.encode(bitmapByte, Base64.NO_WRAP); String bitmapData = new String(bitmapByte); payload.put("iconData", bitmapData); @@ -936,13 +922,13 @@ private void sendToast(JSONObject payload, ResponseListener listener) { } 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 +947,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 +960,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 +974,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 +982,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 +996,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 +1012,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 +1028,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 +1045,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 +1059,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 +1073,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 +1089,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 +1121,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 +1142,8 @@ public ServiceSubscription subscribeVolumeStatus(VolumeSta return (ServiceSubscription) getVolumeStatus(true, listener); } - /****************** - MEDIA PLAYER + * MEDIA PLAYER *****************/ @Override public MediaPlayer getMediaPlayer() { @@ -1166,8 +1161,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 +1188,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 +1211,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 +1281,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 +1297,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 +1325,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 +1348,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 +1357,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 +1412,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 +1421,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 +1430,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 +1439,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 +1448,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 +1480,7 @@ public void getPosition(PositionListener listener) { } /****************** - TV CONTROL + * TV CONTROL *****************/ @Override public TVControl getTVControl() { @@ -1499,7 +1500,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,12 +1513,14 @@ 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 * @throws NullPointerException if channelInfo is null @@ -1540,7 +1544,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 +1563,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 +1590,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 +1604,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 +1619,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 +1642,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 +1664,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 +1674,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 +1686,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 +1706,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 +1715,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 +1732,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 +1761,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 +1810,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 +1826,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() { @@ -1830,10 +1847,12 @@ public CapabilityPriorityLevel getExternalInputControlPriorityLevel() { @Override public void launchInputPicker(final AppLaunchListener listener) { - final AppInfo appInfo = new AppInfo() {{ - setId("com.webos.app.inputpicker"); - setName("InputPicker"); - }}; + final AppInfo appInfo = new AppInfo() { + { + setId("com.webos.app.inputpicker"); + setName("InputPicker"); + } + }; launchAppWithInfo(appInfo, null, new AppLaunchListener() { @Override @@ -1863,7 +1882,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 +1896,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 +1947,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 +1967,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 +1981,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 +1990,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 +2004,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 +2023,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 +2038,8 @@ public void scroll(PointF diff) { scroll(diff.x, diff.y); } - /************** - KEYBOARD CONTROL + * KEYBOARD CONTROL **************/ @Override public TextInputControl getTextInputControl() { @@ -2085,9 +2103,8 @@ public void sendDelete() { } } - /************** - POWER CONTROL + * POWER CONTROL **************/ @Override public PowerControl getPowerControl() { @@ -2115,7 +2132,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 +2143,8 @@ public void powerOn(ResponseListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); } - /************** - KEY CONTROL + * KEY CONTROL **************/ @Override public KeyControl getKeyControl() { @@ -2143,8 +2160,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 +2196,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 +2217,8 @@ public void home(ResponseListener listener) { sendSpecialKey("HOME", listener); } - /************** - Web App Launcher + * Web App Launcher **************/ @Override @@ -2227,7 +2241,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 +2258,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 +2274,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 +2296,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 +2321,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 +2355,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 +2418,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 +2434,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 +2458,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 +2478,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 +2497,7 @@ public void pinWebApp(String webAppId, final ResponseListener listener) } return; } - + String uri = "ssap://webapp/pinWebApp"; JSONObject payload = new JSONObject(); @@ -2480,8 +2514,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 +2525,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 +2555,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 +2566,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 +2609,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 +2626,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 +2689,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 +2726,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 +2747,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 +2800,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 +2846,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 +2874,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 +2902,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,14 +2932,16 @@ 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 @@ -2934,8 +2979,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); @@ -2972,8 +3016,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 +3054,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 +3077,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 +3115,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.valueOf(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 + } else { return 0; + } } private List externalnputInfoFromJSONArray(JSONArray inputList) { @@ -3109,15 +3158,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 +3192,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/webos/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index ce1b2314..bc91fe85 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -29,18 +29,6 @@ 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.Util; import com.connectsdk.discovery.DiscoveryManager; import com.connectsdk.service.DeviceService.PairingType; @@ -53,7 +41,17 @@ import com.connectsdk.service.command.URLServiceSubscription; import com.connectsdk.service.config.WebOSTVServiceConfig; -@SuppressLint("DefaultLocale") +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; + public class WebOSTVServiceSocketClient extends WebSocketClient implements ServiceCommandProcessor { static final String WEBOS_PAIRING_PROMPT = "PROMPT"; @@ -123,6 +121,7 @@ public State getState() { return state; } + @Override public void connect() { synchronized (this) { if (state != State.INITIAL) { @@ -147,8 +146,9 @@ public void disconnectWithError(ServiceCommandError error) { state = State.INITIAL; - if (mListener != null) + if (mListener != null) { mListener.onCloseWithError(error); + } } public void clearRequests() { @@ -163,10 +163,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(); } @@ -175,7 +175,7 @@ private void setDefaultManifest() { private JSONArray convertStringListToJSONArray(List list) { JSONArray jsonArray = new JSONArray(); - for(String str: list) { + for (String str : list) { jsonArray.put(str); } @@ -220,8 +220,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) { @@ -238,11 +239,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"); @@ -254,31 +257,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()); @@ -294,23 +297,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) { @@ -325,28 +331,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((String) 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); @@ -374,16 +381,16 @@ private void helloTV() { String OSVersion = 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", 0, 0); + String screenResolution = String.format("%dx%d", 0, 0); // app Name ApplicationInfo applicationInfo; @@ -392,10 +399,11 @@ private void helloTV() { } catch (final NameNotFoundException e) { applicationInfo = null; } - String applicationName = (String) (applicationInfo != null ? packageManager.getApplicationLabel(applicationInfo) : "(unknown)"); + String applicationName = (String) (applicationInfo != null ? packageManager.getApplicationLabel(applicationInfo) + : "(unknown)"); // app Region - //Locale current = context.getResources().getConfiguration().locale; + // Locale current = context.getResources().getConfiguration().locale; Locale current = Locale.getDefault(); String appRegion = current.getDisplayCountry(); @@ -423,7 +431,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); } @@ -433,27 +442,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(); @@ -467,8 +479,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(); @@ -520,37 +532,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); } @@ -558,7 +573,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()); @@ -567,29 +583,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(); } @@ -597,7 +615,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 { @@ -607,17 +625,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(); } @@ -627,81 +645,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 + // 2016-01-01: Moved from 1.3.0 to 1.3.1-snapshot private void setSSLContext(SSLContext sslContext) { - //setWebSocketFactory(new DefaultSSLWebSocketClientFactory(sslContext)); - try { - super.setSocket(sslContext.getSocketFactory().createSocket()); - } catch (IOException e) { - Log.e("SSL Setup", "failed to setup ssl socket",e); - } - + // 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) { } @@ -712,12 +722,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); @@ -732,8 +742,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); } @@ -743,17 +752,21 @@ 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)); + ServiceCommand> request = (ServiceCommand>) requests + .get(requests.keyAt(i)); - if (request != null) + if (request != null) { Util.postError(request.getResponseListener(), new ServiceCommandError(0, "connection lost", null)); + } } clearRequests(); @@ -764,7 +777,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) { @@ -772,7 +785,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() { @@ -780,7 +793,7 @@ public X509Certificate getServerCertificate() { mService.setServiceConfig(new WebOSTVServiceConfig(mService.getServiceConfig().getServiceUUID())); } - return ((WebOSTVServiceConfig)mService.getServiceConfig()).getServerCertificate(); + return ((WebOSTVServiceConfig) mService.getServiceConfig()).getServerCertificate(); } public String getServerCertificateInString() { @@ -788,7 +801,7 @@ 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) { @@ -806,7 +819,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; @@ -817,10 +830,10 @@ 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; @@ -834,13 +847,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 @@ -853,8 +865,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()); @@ -877,11 +889,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 b2636651..00000000 --- a/test/src/com/connectsdk/core/MediaInfoTest.java +++ /dev/null @@ -1,93 +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 com.connectsdk.BuildConfig; - -import junit.framework.Assert; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; - - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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 5649d811..00000000 --- a/test/src/com/connectsdk/core/SubtitleInfoTest.java +++ /dev/null @@ -1,65 +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 com.connectsdk.BuildConfig; - -import junit.framework.Assert; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; - - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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 d809dee5..00000000 --- a/test/src/com/connectsdk/device/ConnectableDeviceTest.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.connectsdk.device; - -import com.connectsdk.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -public class ConnectableDeviceTest { - - private ConnectableDevice device; - - @Before - public void setUp() { - DiscoveryManager.init(RuntimeEnvironment.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 01a4ef02..00000000 --- a/test/src/com/connectsdk/discovery/DiscoveryManagerTest.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.connectsdk.discovery; - -import com.connectsdk.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -import java.util.Objects; - -/** - * Created by oleksii.frolov on 2/16/2015. - */ - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -public class DiscoveryManagerTest { - - DiscoveryManager discovery; - - @Before - public void setUp() { - discovery = new DiscoveryManager(RuntimeEnvironment.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(RuntimeEnvironment.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(RuntimeEnvironment.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(RuntimeEnvironment.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 238b365e..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.BuildConfig; -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.Mockito; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -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(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, shadows={WifiInfoShadow.class}, sdk = 21) -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(RuntimeEnvironment.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 97061cdb..00000000 --- a/test/src/com/connectsdk/discovery/provider/ZeroConfDiscoveryPrividerTest.java +++ /dev/null @@ -1,317 +0,0 @@ -package com.connectsdk.discovery.provider; - -import android.content.Context; - -import com.connectsdk.BuildConfig; -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; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLooper; - -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 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; -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, shadows = {WifiInfoShadow.class }, sdk = 21) -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(RuntimeEnvironment.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); - ShadowLooper.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 8b4ab54c..00000000 --- a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPClientTest.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.connectsdk.discovery.provider.ssdp; - -import com.connectsdk.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -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(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, shadows = { WifiInfoShadow.class }, sdk = 21) -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(RuntimeEnvironment.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 3d63dd4e..00000000 --- a/test/src/com/connectsdk/discovery/provider/ssdp/SSDPPacketTest.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.connectsdk.discovery.provider.ssdp; - -import com.connectsdk.BuildConfig; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; - -import java.net.DatagramPacket; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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 bde24111..00000000 --- a/test/src/com/connectsdk/service/AirPlayServiceTest.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.connectsdk.service; - -import com.connectsdk.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; - -import java.io.IOException; - -/** - * Created by Oleksii Frolov on 3/19/2015. - */ -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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 2cfb9042..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.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLooper; - -import java.io.IOException; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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(); - ShadowLooper.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(); - ShadowLooper.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(); - ShadowLooper.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 2e073f3f..00000000 --- a/test/src/com/connectsdk/service/DIALServiceTest.java +++ /dev/null @@ -1,100 +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.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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 dfefb7d4..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.BuildConfig; -import com.connectsdk.core.TestUtil; -import com.connectsdk.etc.helper.HttpConnection; -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.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLooper; - -import java.io.IOException; - - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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(); - ShadowLooper.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(); - ShadowLooper.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 1f39324d..00000000 --- a/test/src/com/connectsdk/service/DLNAServiceTest.java +++ /dev/null @@ -1,461 +0,0 @@ -package com.connectsdk.service; - -import com.connectsdk.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -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(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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), RuntimeEnvironment.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), RuntimeEnvironment.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 b876a6ea..00000000 --- a/test/src/com/connectsdk/service/NetCastTVServiceTest.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.connectsdk.service; - -import com.connectsdk.BuildConfig; -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.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.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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(RuntimeEnvironment.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 8097241f..00000000 --- a/test/src/com/connectsdk/service/RokuServiceTest.java +++ /dev/null @@ -1,125 +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.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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 f25262a1..00000000 --- a/test/src/com/connectsdk/service/WebOSTVServiceTest.java +++ /dev/null @@ -1,492 +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.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLooper; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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); - ShadowLooper.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 32da84af..00000000 --- a/test/src/com/connectsdk/service/airplay/PListParserTest.java +++ /dev/null @@ -1,159 +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 com.connectsdk.BuildConfig; - -import junit.framework.Assert; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; - - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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 8e5be5c3..00000000 --- a/test/src/com/connectsdk/service/sessions/WebOSWebAppSessionTest.java +++ /dev/null @@ -1,272 +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 android.support.annotation.NonNull; - -import com.connectsdk.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLooper; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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); - - ShadowLooper.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); - - ShadowLooper.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); - - ShadowLooper.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 a024665d..00000000 --- a/test/src/com/connectsdk/service/upnp/DLNAHttpServerTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.connectsdk.service.upnp; - -import com.connectsdk.BuildConfig; -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.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; - -/** - * Created by oleksii on 4/27/15. - */ -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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 dce97ff5..00000000 --- a/test/src/com/connectsdk/service/webos/WebOSTVServiceSocketClientTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.connectsdk.service.webos; - - -import com.connectsdk.BuildConfig; -import com.connectsdk.service.WebOSTVService; -import com.connectsdk.service.command.ServiceCommand; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; - -import java.net.URI; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21) -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; - } -} From b9dee14727e5881ea00f09026fd11641baf738fb Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Sat, 29 Oct 2016 23:42:25 +0200 Subject: [PATCH 10/41] updated eclipse project according to mvn configuration --- .classpath | 7 +------ .project | 10 +++++----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/.classpath b/.classpath index 7397c6ef..c1948bf3 100644 --- a/.classpath +++ b/.classpath @@ -1,11 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="src" output="target/classes" path="src"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> + <classpathentry kind="src" path="src"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"> <attributes> <attribute name="maven.pomderived" value="true"/> diff --git a/.project b/.project index 59ca793d..bc9f949d 100644 --- a/.project +++ b/.project @@ -5,11 +5,6 @@ <projects> </projects> <buildSpec> - <buildCommand> - <name>org.eclipse.m2e.core.maven2Builder</name> - <arguments> - </arguments> - </buildCommand> <buildCommand> <name>org.eclipse.ui.externaltools.ExternalToolBuilder</name> <triggers>full,incremental,</triggers> @@ -20,6 +15,11 @@ </dictionary> </arguments> </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> </buildSpec> <natures> <nature>org.eclipse.m2e.core.maven2Nature</nature> From d7d04fea36f60769f7fdab416a412d1b4e6c93eb Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Sun, 30 Oct 2016 00:59:58 +0200 Subject: [PATCH 11/41] actually include src in build --- .classpath | 7 ++++++- pom.xml | 14 +++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.classpath b/.classpath index c1948bf3..7397c6ef 100644 --- a/.classpath +++ b/.classpath @@ -1,6 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="src" path="src"/> + <classpathentry kind="src" output="target/classes" path="src"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"> <attributes> <attribute name="maven.pomderived" value="true"/> diff --git a/pom.xml b/pom.xml index 0ba945af..52b0b0c9 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,19 @@ <url>http://clojars.org/repo</url> </repository> </repositories> - +<build> + <sourceDirectory>src</sourceDirectory> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.5.1</version> + <configuration> + <source/> + <target/> + </configuration> + </plugin> + </plugins> + </build> <dependencies> <dependency> <groupId>org.json</groupId> From 1ac150c8127e85412fb2d28a41276ed4157dc3bc Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Sun, 13 Nov 2016 21:29:12 +0100 Subject: [PATCH 12/41] further anrdroid cleanup --- .project | 7 +- src/android/content/BroadcastReceiver.java | 39 +- src/android/content/Context.java | 213 +++--- src/android/content/Intent.java | 648 +++++++++--------- src/android/content/IntentFilter.java | 350 +++++----- src/android/content/pm/ApplicationInfo.java | 110 ++- src/android/content/pm/PackageInfo.java | 28 +- src/android/content/pm/PackageItemInfo.java | 28 +- src/android/content/pm/PackageManager.java | 206 +++--- src/android/graphics/Bitmap.java | 92 +-- src/android/graphics/BitmapFactory.java | 60 +- src/android/graphics/PointF.java | 31 +- .../graphics/drawable/BitmapDrawable.java | 48 +- src/android/graphics/drawable/Drawable.java | 90 +-- src/android/net/ConnectivityManager.java | 62 +- src/android/net/NetworkInfo.java | 56 +- src/android/net/wifi/WifiManager.java | 250 ++++--- src/android/os/Build.java | 90 +-- src/android/os/Environment.java | 45 +- src/android/os/Parcelable.java | 22 +- src/android/text/Html.java | 20 +- src/android/text/Spanned.java | 42 +- src/android/text/TextUtils.java | 73 -- src/android/util/AndroidException.java | 7 - src/com/connectsdk/service/RokuService.java | 10 +- 25 files changed, 1222 insertions(+), 1405 deletions(-) delete mode 100644 src/android/text/TextUtils.java delete mode 100644 src/android/util/AndroidException.java diff --git a/.project b/.project index bc9f949d..30ba1f9b 100644 --- a/.project +++ b/.project @@ -6,13 +6,8 @@ </projects> <buildSpec> <buildCommand> - <name>org.eclipse.ui.externaltools.ExternalToolBuilder</name> - <triggers>full,incremental,</triggers> + <name>org.eclipse.jdt.core.javabuilder</name> <arguments> - <dictionary> - <key>LaunchConfigHandle</key> - <value><project>/.externalToolBuilders/org.eclipse.jdt.core.javabuilder.launch</value> - </dictionary> </arguments> </buildCommand> <buildCommand> diff --git a/src/android/content/BroadcastReceiver.java b/src/android/content/BroadcastReceiver.java index 26a233c6..64a940ea 100644 --- a/src/android/content/BroadcastReceiver.java +++ b/src/android/content/BroadcastReceiver.java @@ -1,38 +1,5 @@ package android.content; -public abstract class BroadcastReceiver -{ -public static class PendingResult -{ -PendingResult() { throw new RuntimeException("Stub!"); } -public final void setResultCode(int code) { throw new RuntimeException("Stub!"); } -public final int getResultCode() { throw new RuntimeException("Stub!"); } -public final void setResultData(java.lang.String data) { throw new RuntimeException("Stub!"); } -public final java.lang.String getResultData() { throw new RuntimeException("Stub!"); } -//public final void setResultExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } -//public final android.os.Bundle getResultExtras(boolean makeMap) { throw new RuntimeException("Stub!"); } -//public final void setResult(int code, java.lang.String data, android.os.Bundle extras) { throw new RuntimeException("Stub!"); } -public final boolean getAbortBroadcast() { throw new RuntimeException("Stub!"); } -public final void abortBroadcast() { throw new RuntimeException("Stub!"); } -public final void clearAbortBroadcast() { throw new RuntimeException("Stub!"); } -public final void finish() { throw new RuntimeException("Stub!"); } -} -public BroadcastReceiver() { /*throw new RuntimeException("Stub!"); */} -public abstract void onReceive(android.content.Context context, android.content.Intent intent); -public final android.content.BroadcastReceiver.PendingResult goAsync() { throw new RuntimeException("Stub!"); } -//public android.os.IBinder peekService(android.content.Context myContext, android.content.Intent service) { throw new RuntimeException("Stub!"); } -public final void setResultCode(int code) { throw new RuntimeException("Stub!"); } -public final int getResultCode() { throw new RuntimeException("Stub!"); } -public final void setResultData(java.lang.String data) { throw new RuntimeException("Stub!"); } -public final java.lang.String getResultData() { throw new RuntimeException("Stub!"); } -//public final void setResultExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } -//public final android.os.Bundle getResultExtras(boolean makeMap) { throw new RuntimeException("Stub!"); } -//public final void setResult(int code, java.lang.String data, android.os.Bundle extras) { throw new RuntimeException("Stub!"); } -public final boolean getAbortBroadcast() { throw new RuntimeException("Stub!"); } -public final void abortBroadcast() { throw new RuntimeException("Stub!"); } -public final void clearAbortBroadcast() { throw new RuntimeException("Stub!"); } -public final boolean isOrderedBroadcast() { throw new RuntimeException("Stub!"); } -public final boolean isInitialStickyBroadcast() { throw new RuntimeException("Stub!"); } -public final void setOrderedHint(boolean isOrdered) { throw new RuntimeException("Stub!"); } -public final void setDebugUnregister(boolean debug) { throw new RuntimeException("Stub!"); } -public final boolean getDebugUnregister() { throw new RuntimeException("Stub!"); } + +public abstract class BroadcastReceiver { + public abstract void onReceive(android.content.Context context, android.content.Intent intent); } diff --git a/src/android/content/Context.java b/src/android/content/Context.java index 3a7fc3c8..81f82881 100644 --- a/src/android/content/Context.java +++ b/src/android/content/Context.java @@ -2,147 +2,94 @@ public abstract class Context { -public Context() { /*throw new RuntimeException("Stub!");*/ } -//public abstract android.content.res.AssetManager getAssets(); -//public abstract android.content.res.Resources getResources(); public abstract android.content.pm.PackageManager getPackageManager(); -//public abstract android.content.ContentResolver getContentResolver(); -//public abstract android.os.Looper getMainLooper(); -public abstract android.content.Context getApplicationContext(); -//public void registerComponentCallbacks(android.content.ComponentCallbacks callback) { throw new RuntimeException("Stub!"); } -//public void unregisterComponentCallbacks(android.content.ComponentCallbacks callback) { throw new RuntimeException("Stub!"); } -public final java.lang.CharSequence getText(int resId) { throw new RuntimeException("Stub!"); } -public final java.lang.String getString(int resId) { throw new RuntimeException("Stub!"); } -public final java.lang.String getString(int resId, java.lang.Object... formatArgs) { throw new RuntimeException("Stub!"); } -public abstract void setTheme(int resid); -//public abstract android.content.res.Resources.Theme getTheme(); -//public final android.content.res.TypedArray obtainStyledAttributes(int[] attrs) { throw new RuntimeException("Stub!"); } -//public final android.content.res.TypedArray obtainStyledAttributes(int resid, int[] attrs) throws android.content.res.Resources.NotFoundException { throw new RuntimeException("Stub!"); } -//public final android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet set, int[] attrs) { throw new RuntimeException("Stub!"); } -//public final android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) { throw new RuntimeException("Stub!"); } -public abstract java.lang.ClassLoader getClassLoader(); +//public abstract android.content.Context getApplicationContext(); +//public abstract void setTheme(int resid); +//public abstract java.lang.ClassLoader getClassLoader(); public abstract java.lang.String getPackageName(); -public abstract android.content.pm.ApplicationInfo getApplicationInfo(); -public abstract java.lang.String getPackageResourcePath(); -public abstract java.lang.String getPackageCodePath(); -//public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String name, int mode); -public abstract java.io.FileInputStream openFileInput(java.lang.String name) throws java.io.FileNotFoundException; -public abstract java.io.FileOutputStream openFileOutput(java.lang.String name, int mode) throws java.io.FileNotFoundException; -public abstract boolean deleteFile(java.lang.String name); -public abstract java.io.File getFileStreamPath(java.lang.String name); -public abstract java.io.File getFilesDir(); -public abstract java.io.File getExternalFilesDir(java.lang.String type); -public abstract java.io.File getObbDir(); -public abstract java.io.File getCacheDir(); -public abstract java.io.File getExternalCacheDir(); -public abstract java.lang.String[] fileList(); -public abstract java.io.File getDir(java.lang.String name, int mode); -//public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String name, int mode, android.database.sqlite.SQLiteDatabase.CursorFactory factory); -//public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String name, int mode, android.database.sqlite.SQLiteDatabase.CursorFactory factory, android.database.DatabaseErrorHandler errorHandler); -public abstract boolean deleteDatabase(java.lang.String name); -public abstract java.io.File getDatabasePath(java.lang.String name); -public abstract java.lang.String[] databaseList(); +//public abstract android.content.pm.ApplicationInfo getApplicationInfo(); +//public abstract java.lang.String getPackageResourcePath(); +//public abstract java.lang.String getPackageCodePath(); +//public abstract java.io.FileInputStream openFileInput(java.lang.String name) throws java.io.FileNotFoundException; +//public abstract java.io.FileOutputStream openFileOutput(java.lang.String name, int mode) throws java.io.FileNotFoundException; +//public abstract boolean deleteFile(java.lang.String name); +//public abstract java.io.File getFileStreamPath(java.lang.String name); +//public abstract java.io.File getFilesDir(); +//public abstract java.io.File getExternalFilesDir(java.lang.String type); +//public abstract java.io.File getObbDir(); +//public abstract java.io.File getCacheDir(); +//public abstract java.io.File getExternalCacheDir(); +//public abstract java.lang.String[] fileList(); +//public abstract java.io.File getDir(java.lang.String name, int mode); +//public abstract boolean deleteDatabase(java.lang.String name); +//public abstract java.io.File getDatabasePath(java.lang.String name); +//public abstract java.lang.String[] databaseList(); //@java.lang.Deprecated() -//public abstract android.graphics.drawable.Drawable getWallpaper(); +//public abstract int getWallpaperDesiredMinimumWidth(); //@java.lang.Deprecated() -///public abstract android.graphics.drawable.Drawable peekWallpaper(); -@java.lang.Deprecated() -public abstract int getWallpaperDesiredMinimumWidth(); -@java.lang.Deprecated() -public abstract int getWallpaperDesiredMinimumHeight(); +//public abstract int getWallpaperDesiredMinimumHeight(); //@java.lang.Deprecated() -//public abstract void setWallpaper(android.graphics.Bitmap bitmap) throws java.io.IOException; -@java.lang.Deprecated() -public abstract void setWallpaper(java.io.InputStream data) throws java.io.IOException; -@java.lang.Deprecated() -public abstract void clearWallpaper() throws java.io.IOException; -//public abstract void startActivity(android.content.Intent intent); -//public abstract void startActivity(android.content.Intent intent, android.os.Bundle options); -//public abstract void startActivities(android.content.Intent[] intents); -//public abstract void startActivities(android.content.Intent[] intents, android.os.Bundle options); -//public abstract void startIntentSender(android.content.IntentSender intent, android.content.Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) throws android.content.IntentSender.SendIntentException; -//public abstract void startIntentSender(android.content.IntentSender intent, android.content.Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, android.os.Bundle options) throws android.content.IntentSender.SendIntentException; -//public abstract void sendBroadcast(android.content.Intent intent); -//public abstract void sendBroadcast(android.content.Intent intent, java.lang.String receiverPermission); -//public abstract void sendOrderedBroadcast(android.content.Intent intent, java.lang.String receiverPermission); -//public abstract void sendOrderedBroadcast(android.content.Intent intent, java.lang.String receiverPermission, android.content.BroadcastReceiver resultReceiver, android.os.Handler scheduler, int initialCode, java.lang.String initialData, android.os.Bundle initialExtras); -//public abstract void sendStickyBroadcast(android.content.Intent intent); -//public abstract void sendStickyOrderedBroadcast(android.content.Intent intent, android.content.BroadcastReceiver resultReceiver, android.os.Handler scheduler, int initialCode, java.lang.String initialData, android.os.Bundle initialExtras); -//public abstract void removeStickyBroadcast(android.content.Intent intent); +//public abstract void setWallpaper(java.io.InputStream data) throws java.io.IOException; +//@java.lang.Deprecated() +//public abstract void clearWallpaper() throws java.io.IOException; public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver receiver, android.content.IntentFilter filter); -//public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver receiver, android.content.IntentFilter filter, java.lang.String broadcastPermission, android.os.Handler scheduler); public abstract void unregisterReceiver(android.content.BroadcastReceiver receiver); -//public abstract android.content.ComponentName startService(android.content.Intent service); -//public abstract boolean stopService(android.content.Intent service); -//public abstract boolean bindService(android.content.Intent service, android.content.ServiceConnection conn, int flags); -//public abstract void unbindService(android.content.ServiceConnection conn); -//public abstract boolean startInstrumentation(android.content.ComponentName className, java.lang.String profileFile, android.os.Bundle arguments); public abstract java.lang.Object getSystemService(java.lang.String name); -public abstract int checkPermission(java.lang.String permission, int pid, int uid); -public abstract int checkCallingPermission(java.lang.String permission); -public abstract int checkCallingOrSelfPermission(java.lang.String permission); -public abstract void enforcePermission(java.lang.String permission, int pid, int uid, java.lang.String message); -public abstract void enforceCallingPermission(java.lang.String permission, java.lang.String message); -public abstract void enforceCallingOrSelfPermission(java.lang.String permission, java.lang.String message); -//public abstract void grantUriPermission(java.lang.String toPackage, android.net.Uri uri, int modeFlags); -//public abstract void revokeUriPermission(android.net.Uri uri, int modeFlags); -//public abstract int checkUriPermission(android.net.Uri uri, int pid, int uid, int modeFlags); -//public abstract int checkCallingUriPermission(android.net.Uri uri, int modeFlags); -//public abstract int checkCallingOrSelfUriPermission(android.net.Uri uri, int modeFlags); -//public abstract int checkUriPermission(android.net.Uri uri, java.lang.String readPermission, java.lang.String writePermission, int pid, int uid, int modeFlags); -//public abstract void enforceUriPermission(android.net.Uri uri, int pid, int uid, int modeFlags, java.lang.String message); -//public abstract void enforceCallingUriPermission(android.net.Uri uri, int modeFlags, java.lang.String message); -//public abstract void enforceCallingOrSelfUriPermission(android.net.Uri uri, int modeFlags, java.lang.String message); -//public abstract void enforceUriPermission(android.net.Uri uri, java.lang.String readPermission, java.lang.String writePermission, int pid, int uid, int modeFlags, java.lang.String message); -public abstract android.content.Context createPackageContext(java.lang.String packageName, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -public boolean isRestricted() { throw new RuntimeException("Stub!"); } -public static final int MODE_PRIVATE = 0; -public static final int MODE_WORLD_READABLE = 1; -public static final int MODE_WORLD_WRITEABLE = 2; -public static final int MODE_APPEND = 32768; -public static final int MODE_MULTI_PROCESS = 4; -public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; -public static final int BIND_AUTO_CREATE = 1; -public static final int BIND_DEBUG_UNBIND = 2; -public static final int BIND_NOT_FOREGROUND = 4; -public static final int BIND_ABOVE_CLIENT = 8; -public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; -public static final int BIND_WAIVE_PRIORITY = 32; -public static final int BIND_IMPORTANT = 64; -public static final int BIND_ADJUST_WITH_ACTIVITY = 128; -public static final java.lang.String POWER_SERVICE = "power"; -public static final java.lang.String WINDOW_SERVICE = "window"; -public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater"; -public static final java.lang.String ACCOUNT_SERVICE = "account"; -public static final java.lang.String ACTIVITY_SERVICE = "activity"; -public static final java.lang.String ALARM_SERVICE = "alarm"; -public static final java.lang.String NOTIFICATION_SERVICE = "notification"; -public static final java.lang.String ACCESSIBILITY_SERVICE = "accessibility"; -public static final java.lang.String KEYGUARD_SERVICE = "keyguard"; -public static final java.lang.String LOCATION_SERVICE = "location"; -public static final java.lang.String SEARCH_SERVICE = "search"; -public static final java.lang.String SENSOR_SERVICE = "sensor"; -public static final java.lang.String STORAGE_SERVICE = "storage"; -public static final java.lang.String WALLPAPER_SERVICE = "wallpaper"; -public static final java.lang.String VIBRATOR_SERVICE = "vibrator"; +//public abstract int checkPermission(java.lang.String permission, int pid, int uid); +//public abstract int checkCallingPermission(java.lang.String permission); +//public abstract int checkCallingOrSelfPermission(java.lang.String permission); +//public abstract void enforcePermission(java.lang.String permission, int pid, int uid, java.lang.String message); +//public abstract void enforceCallingPermission(java.lang.String permission, java.lang.String message); +//public abstract void enforceCallingOrSelfPermission(java.lang.String permission, java.lang.String message); +//public abstract android.content.Context createPackageContext(java.lang.String packageName, int flags) throws android.content.pm.PackageManager.NameNotFoundException; +//public boolean isRestricted() { throw new RuntimeException("Stub!"); } +//public static final int MODE_PRIVATE = 0; +//public static final int MODE_WORLD_READABLE = 1; +//public static final int MODE_WORLD_WRITEABLE = 2; +//public static final int MODE_APPEND = 32768; +//public static final int MODE_MULTI_PROCESS = 4; +//public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; +//public static final int BIND_AUTO_CREATE = 1; +//public static final int BIND_DEBUG_UNBIND = 2; +//public static final int BIND_NOT_FOREGROUND = 4; +//public static final int BIND_ABOVE_CLIENT = 8; +//public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; +//public static final int BIND_WAIVE_PRIORITY = 32; +//public static final int BIND_IMPORTANT = 64; +//public static final int BIND_ADJUST_WITH_ACTIVITY = 128; +//public static final java.lang.String POWER_SERVICE = "power"; +//public static final java.lang.String WINDOW_SERVICE = "window"; +//public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater"; +//public static final java.lang.String ACCOUNT_SERVICE = "account"; +//public static final java.lang.String ACTIVITY_SERVICE = "activity"; +//public static final java.lang.String ALARM_SERVICE = "alarm"; +//public static final java.lang.String NOTIFICATION_SERVICE = "notification"; +//public static final java.lang.String ACCESSIBILITY_SERVICE = "accessibility"; +//public static final java.lang.String KEYGUARD_SERVICE = "keyguard"; +//public static final java.lang.String LOCATION_SERVICE = "location"; +//public static final java.lang.String SEARCH_SERVICE = "search"; +//public static final java.lang.String SENSOR_SERVICE = "sensor"; +//public static final java.lang.String STORAGE_SERVICE = "storage"; +//public static final java.lang.String WALLPAPER_SERVICE = "wallpaper"; +//public static final java.lang.String VIBRATOR_SERVICE = "vibrator"; public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity"; public static final java.lang.String WIFI_SERVICE = "wifi"; -public static final java.lang.String WIFI_P2P_SERVICE = "wifip2p"; -public static final java.lang.String NSD_SERVICE = "servicediscovery"; -public static final java.lang.String AUDIO_SERVICE = "audio"; -public static final java.lang.String MEDIA_ROUTER_SERVICE = "media_router"; -public static final java.lang.String TELEPHONY_SERVICE = "phone"; -public static final java.lang.String CLIPBOARD_SERVICE = "clipboard"; -public static final java.lang.String INPUT_METHOD_SERVICE = "input_method"; -public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices"; -public static final java.lang.String DROPBOX_SERVICE = "dropbox"; -public static final java.lang.String DEVICE_POLICY_SERVICE = "device_policy"; -public static final java.lang.String UI_MODE_SERVICE = "uimode"; -public static final java.lang.String DOWNLOAD_SERVICE = "download"; -public static final java.lang.String NFC_SERVICE = "nfc"; -public static final java.lang.String USB_SERVICE = "usb"; -public static final java.lang.String INPUT_SERVICE = "input"; -public static final int CONTEXT_INCLUDE_CODE = 1; -public static final int CONTEXT_IGNORE_SECURITY = 2; -public static final int CONTEXT_RESTRICTED = 4; +//public static final java.lang.String WIFI_P2P_SERVICE = "wifip2p"; +//public static final java.lang.String NSD_SERVICE = "servicediscovery"; +//public static final java.lang.String AUDIO_SERVICE = "audio"; +//public static final java.lang.String MEDIA_ROUTER_SERVICE = "media_router"; +//public static final java.lang.String TELEPHONY_SERVICE = "phone"; +//public static final java.lang.String CLIPBOARD_SERVICE = "clipboard"; +//public static final java.lang.String INPUT_METHOD_SERVICE = "input_method"; +//public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices"; +//public static final java.lang.String DROPBOX_SERVICE = "dropbox"; +//public static final java.lang.String DEVICE_POLICY_SERVICE = "device_policy"; +//public static final java.lang.String UI_MODE_SERVICE = "uimode"; +//public static final java.lang.String DOWNLOAD_SERVICE = "download"; +//public static final java.lang.String NFC_SERVICE = "nfc"; +//public static final java.lang.String USB_SERVICE = "usb"; +//public static final java.lang.String INPUT_SERVICE = "input"; +//public static final int CONTEXT_INCLUDE_CODE = 1; +//public static final int CONTEXT_IGNORE_SECURITY = 2; +//public static final int CONTEXT_RESTRICTED = 4; } diff --git a/src/android/content/Intent.java b/src/android/content/Intent.java index 293d656f..d2a9dfdf 100644 --- a/src/android/content/Intent.java +++ b/src/android/content/Intent.java @@ -2,367 +2,367 @@ public class Intent implements /*android.os.Parcelable,*/ java.lang.Cloneable { -public static class ShortcutIconResource +//public static class ShortcutIconResource // implements android.os.Parcelable -{ -public ShortcutIconResource() { throw new RuntimeException("Stub!"); } -public static android.content.Intent.ShortcutIconResource fromContext(android.content.Context context, int resourceId) { throw new RuntimeException("Stub!"); } -public int describeContents() { throw new RuntimeException("Stub!"); } +//{ +//public ShortcutIconResource() { throw new RuntimeException("Stub!"); } +//public static android.content.Intent.ShortcutIconResource fromContext(android.content.Context context, int resourceId) { throw new RuntimeException("Stub!"); } +//public int describeContents() { throw new RuntimeException("Stub!"); } //public void writeToParcel(android.os.Parcel dest, int flags) { throw new RuntimeException("Stub!"); } -public java.lang.String toString() { throw new RuntimeException("Stub!"); } -public java.lang.String packageName; -public java.lang.String resourceName; +//public java.lang.String toString() { throw new RuntimeException("Stub!"); } +//public java.lang.String packageName; +//public java.lang.String resourceName; //public static final android.os.Parcelable.Creator<android.content.Intent.ShortcutIconResource> CREATOR; //static { CREATOR = null; } -} -public static final class FilterComparison -{ -public FilterComparison(android.content.Intent intent) { throw new RuntimeException("Stub!"); } -public android.content.Intent getIntent() { throw new RuntimeException("Stub!"); } -public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); } -public int hashCode() { throw new RuntimeException("Stub!"); } -} -public Intent() { throw new RuntimeException("Stub!"); } -public Intent(android.content.Intent o) { throw new RuntimeException("Stub!"); } -public Intent(java.lang.String action) { throw new RuntimeException("Stub!"); } +//} +//public static final class FilterComparison +//{ +//public FilterComparison(android.content.Intent intent) { throw new RuntimeException("Stub!"); } +//public android.content.Intent getIntent() { throw new RuntimeException("Stub!"); } +//public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); } +//public int hashCode() { throw new RuntimeException("Stub!"); } +//} +//public Intent() { throw new RuntimeException("Stub!"); } +//public Intent(android.content.Intent o) { throw new RuntimeException("Stub!"); } +//public Intent(java.lang.String action) { throw new RuntimeException("Stub!"); } //public Intent(java.lang.String action, android.net.Uri uri) { throw new RuntimeException("Stub!"); } -public Intent(android.content.Context packageContext, java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); } +//public Intent(android.content.Context packageContext, java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); } //public Intent(java.lang.String action, android.net.Uri uri, android.content.Context packageContext, java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); } -public static android.content.Intent createChooser(android.content.Intent target, java.lang.CharSequence title) { throw new RuntimeException("Stub!"); } -public java.lang.Object clone() { throw new RuntimeException("Stub!"); } -public android.content.Intent cloneFilter() { throw new RuntimeException("Stub!"); } +//public static android.content.Intent createChooser(android.content.Intent target, java.lang.CharSequence title) { throw new RuntimeException("Stub!"); } +//public java.lang.Object clone() { throw new RuntimeException("Stub!"); } +//public android.content.Intent cloneFilter() { throw new RuntimeException("Stub!"); } //public static android.content.Intent makeMainActivity(android.content.ComponentName mainActivity) { throw new RuntimeException("Stub!"); } -public static android.content.Intent makeMainSelectorActivity(java.lang.String selectorAction, java.lang.String selectorCategory) { throw new RuntimeException("Stub!"); } +//public static android.content.Intent makeMainSelectorActivity(java.lang.String selectorAction, java.lang.String selectorCategory) { throw new RuntimeException("Stub!"); } //public static android.content.Intent makeRestartActivityTask(android.content.ComponentName mainActivity) { throw new RuntimeException("Stub!"); } -@java.lang.Deprecated() -public static android.content.Intent getIntent(java.lang.String uri) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } -public static android.content.Intent parseUri(java.lang.String uri, int flags) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } -public static android.content.Intent getIntentOld(java.lang.String uri) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } +//@java.lang.Deprecated() +//public static android.content.Intent getIntent(java.lang.String uri) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } +//public static android.content.Intent parseUri(java.lang.String uri, int flags) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } +//public static android.content.Intent getIntentOld(java.lang.String uri) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } public java.lang.String getAction() { throw new RuntimeException("Stub!"); } //public android.net.Uri getData() { throw new RuntimeException("Stub!"); } -public java.lang.String getDataString() { throw new RuntimeException("Stub!"); } -public java.lang.String getScheme() { throw new RuntimeException("Stub!"); } -public java.lang.String getType() { throw new RuntimeException("Stub!"); } -public java.lang.String resolveType(android.content.Context context) { throw new RuntimeException("Stub!"); } +//public java.lang.String getDataString() { throw new RuntimeException("Stub!"); } +//public java.lang.String getScheme() { throw new RuntimeException("Stub!"); } +//public java.lang.String getType() { throw new RuntimeException("Stub!"); } +//public java.lang.String resolveType(android.content.Context context) { throw new RuntimeException("Stub!"); } //public java.lang.String resolveType(android.content.ContentResolver resolver) { throw new RuntimeException("Stub!"); } //public java.lang.String resolveTypeIfNeeded(android.content.ContentResolver resolver) { throw new RuntimeException("Stub!"); } -public boolean hasCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } -public java.util.Set<java.lang.String> getCategories() { throw new RuntimeException("Stub!"); } -public android.content.Intent getSelector() { throw new RuntimeException("Stub!"); } +//public boolean hasCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } +//public java.util.Set<java.lang.String> getCategories() { throw new RuntimeException("Stub!"); } +//public android.content.Intent getSelector() { throw new RuntimeException("Stub!"); } //public android.content.ClipData getClipData() { throw new RuntimeException("Stub!"); } -public void setExtrasClassLoader(java.lang.ClassLoader loader) { throw new RuntimeException("Stub!"); } -public boolean hasExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public boolean hasFileDescriptors() { throw new RuntimeException("Stub!"); } -public boolean getBooleanExtra(java.lang.String name, boolean defaultValue) { throw new RuntimeException("Stub!"); } -public byte getByteExtra(java.lang.String name, byte defaultValue) { throw new RuntimeException("Stub!"); } -public short getShortExtra(java.lang.String name, short defaultValue) { throw new RuntimeException("Stub!"); } -public char getCharExtra(java.lang.String name, char defaultValue) { throw new RuntimeException("Stub!"); } -public int getIntExtra(java.lang.String name, int defaultValue) { throw new RuntimeException("Stub!"); } -public long getLongExtra(java.lang.String name, long defaultValue) { throw new RuntimeException("Stub!"); } -public float getFloatExtra(java.lang.String name, float defaultValue) { throw new RuntimeException("Stub!"); } -public double getDoubleExtra(java.lang.String name, double defaultValue) { throw new RuntimeException("Stub!"); } -public java.lang.String getStringExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public java.lang.CharSequence getCharSequenceExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public void setExtrasClassLoader(java.lang.ClassLoader loader) { throw new RuntimeException("Stub!"); } +//public boolean hasExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public boolean hasFileDescriptors() { throw new RuntimeException("Stub!"); } +//public boolean getBooleanExtra(java.lang.String name, boolean defaultValue) { throw new RuntimeException("Stub!"); } +//public byte getByteExtra(java.lang.String name, byte defaultValue) { throw new RuntimeException("Stub!"); } +//public short getShortExtra(java.lang.String name, short defaultValue) { throw new RuntimeException("Stub!"); } +//public char getCharExtra(java.lang.String name, char defaultValue) { throw new RuntimeException("Stub!"); } +//public int getIntExtra(java.lang.String name, int defaultValue) { throw new RuntimeException("Stub!"); } +//public long getLongExtra(java.lang.String name, long defaultValue) { throw new RuntimeException("Stub!"); } +//public float getFloatExtra(java.lang.String name, float defaultValue) { throw new RuntimeException("Stub!"); } +//public double getDoubleExtra(java.lang.String name, double defaultValue) { throw new RuntimeException("Stub!"); } +//public java.lang.String getStringExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public java.lang.CharSequence getCharSequenceExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } public <T extends android.os.Parcelable> T getParcelableExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } //public android.os.Parcelable[] getParcelableArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } //public <T extends android.os.Parcelable> java.util.ArrayList<T> getParcelableArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public java.io.Serializable getSerializableExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public java.util.ArrayList<java.lang.Integer> getIntegerArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public java.util.ArrayList<java.lang.String> getStringArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public java.util.ArrayList<java.lang.CharSequence> getCharSequenceArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public boolean[] getBooleanArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public byte[] getByteArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public short[] getShortArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public char[] getCharArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public int[] getIntArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public long[] getLongArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public float[] getFloatArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public double[] getDoubleArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public java.lang.String[] getStringArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public java.lang.CharSequence[] getCharSequenceArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public java.io.Serializable getSerializableExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public java.util.ArrayList<java.lang.Integer> getIntegerArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public java.util.ArrayList<java.lang.String> getStringArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public java.util.ArrayList<java.lang.CharSequence> getCharSequenceArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public boolean[] getBooleanArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public byte[] getByteArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public short[] getShortArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public char[] getCharArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public int[] getIntArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public long[] getLongArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public float[] getFloatArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public double[] getDoubleArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public java.lang.String[] getStringArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public java.lang.CharSequence[] getCharSequenceArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } //public android.os.Bundle getBundleExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } //public android.os.Bundle getExtras() { throw new RuntimeException("Stub!"); } -public int getFlags() { throw new RuntimeException("Stub!"); } -public java.lang.String getPackage() { throw new RuntimeException("Stub!"); } +//public int getFlags() { throw new RuntimeException("Stub!"); } +//public java.lang.String getPackage() { throw new RuntimeException("Stub!"); } //public android.content.ComponentName getComponent() { throw new RuntimeException("Stub!"); } //public android.graphics.Rect getSourceBounds() { throw new RuntimeException("Stub!"); } //public android.content.ComponentName resolveActivity(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } //public android.content.pm.ActivityInfo resolveActivityInfo(android.content.pm.PackageManager pm, int flags) { throw new RuntimeException("Stub!"); } -public android.content.Intent setAction(java.lang.String action) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setAction(java.lang.String action) { throw new RuntimeException("Stub!"); } //public android.content.Intent setData(android.net.Uri data) { throw new RuntimeException("Stub!"); } //public android.content.Intent setDataAndNormalize(android.net.Uri data) { throw new RuntimeException("Stub!"); } -public android.content.Intent setType(java.lang.String type) { throw new RuntimeException("Stub!"); } -public android.content.Intent setTypeAndNormalize(java.lang.String type) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setType(java.lang.String type) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setTypeAndNormalize(java.lang.String type) { throw new RuntimeException("Stub!"); } //public android.content.Intent setDataAndType(android.net.Uri data, java.lang.String type) { throw new RuntimeException("Stub!"); } //public android.content.Intent setDataAndTypeAndNormalize(android.net.Uri data, java.lang.String type) { throw new RuntimeException("Stub!"); } -public android.content.Intent addCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } -public void removeCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } -public void setSelector(android.content.Intent selector) { throw new RuntimeException("Stub!"); } +//public android.content.Intent addCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } +//public void removeCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } +//public void setSelector(android.content.Intent selector) { throw new RuntimeException("Stub!"); } //public void setClipData(android.content.ClipData clip) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, boolean value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, byte value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, char value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, short value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, int value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, long value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, float value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, double value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, java.lang.String value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, java.lang.CharSequence value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, boolean value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, byte value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, char value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, short value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, int value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, long value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, float value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, double value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, java.lang.String value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, java.lang.CharSequence value) { throw new RuntimeException("Stub!"); } //public android.content.Intent putExtra(java.lang.String name, android.os.Parcelable value) { throw new RuntimeException("Stub!"); } //public android.content.Intent putExtra(java.lang.String name, android.os.Parcelable[] value) { throw new RuntimeException("Stub!"); } //public android.content.Intent putParcelableArrayListExtra(java.lang.String name, java.util.ArrayList<? extends android.os.Parcelable> value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putIntegerArrayListExtra(java.lang.String name, java.util.ArrayList<java.lang.Integer> value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putStringArrayListExtra(java.lang.String name, java.util.ArrayList<java.lang.String> value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putCharSequenceArrayListExtra(java.lang.String name, java.util.ArrayList<java.lang.CharSequence> value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, java.io.Serializable value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, boolean[] value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, byte[] value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, short[] value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, char[] value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, int[] value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, long[] value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, float[] value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, double[] value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, java.lang.String[] value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtra(java.lang.String name, java.lang.CharSequence[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putIntegerArrayListExtra(java.lang.String name, java.util.ArrayList<java.lang.Integer> value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putStringArrayListExtra(java.lang.String name, java.util.ArrayList<java.lang.String> value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putCharSequenceArrayListExtra(java.lang.String name, java.util.ArrayList<java.lang.CharSequence> value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, java.io.Serializable value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, boolean[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, byte[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, short[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, char[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, int[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, long[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, float[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, double[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, java.lang.String[] value) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtra(java.lang.String name, java.lang.CharSequence[] value) { throw new RuntimeException("Stub!"); } //public android.content.Intent putExtra(java.lang.String name, android.os.Bundle value) { throw new RuntimeException("Stub!"); } -public android.content.Intent putExtras(android.content.Intent src) { throw new RuntimeException("Stub!"); } +//public android.content.Intent putExtras(android.content.Intent src) { throw new RuntimeException("Stub!"); } //public android.content.Intent putExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } -public android.content.Intent replaceExtras(android.content.Intent src) { throw new RuntimeException("Stub!"); } +//public android.content.Intent replaceExtras(android.content.Intent src) { throw new RuntimeException("Stub!"); } //public android.content.Intent replaceExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } -public void removeExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public android.content.Intent setFlags(int flags) { throw new RuntimeException("Stub!"); } -public android.content.Intent addFlags(int flags) { throw new RuntimeException("Stub!"); } -public android.content.Intent setPackage(java.lang.String packageName) { throw new RuntimeException("Stub!"); } +//public void removeExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setFlags(int flags) { throw new RuntimeException("Stub!"); } +//public android.content.Intent addFlags(int flags) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setPackage(java.lang.String packageName) { throw new RuntimeException("Stub!"); } //public android.content.Intent setComponent(android.content.ComponentName component) { throw new RuntimeException("Stub!"); } -public android.content.Intent setClassName(android.content.Context packageContext, java.lang.String className) { throw new RuntimeException("Stub!"); } -public android.content.Intent setClassName(java.lang.String packageName, java.lang.String className) { throw new RuntimeException("Stub!"); } -public android.content.Intent setClass(android.content.Context packageContext, java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setClassName(android.content.Context packageContext, java.lang.String className) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setClassName(java.lang.String packageName, java.lang.String className) { throw new RuntimeException("Stub!"); } +//public android.content.Intent setClass(android.content.Context packageContext, java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); } //public void setSourceBounds(android.graphics.Rect r) { throw new RuntimeException("Stub!"); } -public int fillIn(android.content.Intent other, int flags) { throw new RuntimeException("Stub!"); } -public boolean filterEquals(android.content.Intent other) { throw new RuntimeException("Stub!"); } -public int filterHashCode() { throw new RuntimeException("Stub!"); } -public java.lang.String toString() { throw new RuntimeException("Stub!"); } -@java.lang.Deprecated() -public java.lang.String toURI() { throw new RuntimeException("Stub!"); } -public java.lang.String toUri(int flags) { throw new RuntimeException("Stub!"); } -public int describeContents() { throw new RuntimeException("Stub!"); } +//public int fillIn(android.content.Intent other, int flags) { throw new RuntimeException("Stub!"); } +//public boolean filterEquals(android.content.Intent other) { throw new RuntimeException("Stub!"); } +//public int filterHashCode() { throw new RuntimeException("Stub!"); } +//public java.lang.String toString() { throw new RuntimeException("Stub!"); } +//@java.lang.Deprecated() +//public java.lang.String toURI() { throw new RuntimeException("Stub!"); } +//public java.lang.String toUri(int flags) { throw new RuntimeException("Stub!"); } +//public int describeContents() { throw new RuntimeException("Stub!"); } //public void writeToParcel(android.os.Parcel out, int flags) { throw new RuntimeException("Stub!"); } //public void readFromParcel(android.os.Parcel in) { throw new RuntimeException("Stub!"); } //public static android.content.Intent parseIntent(android.content.res.Resources resources, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } -public static java.lang.String normalizeMimeType(java.lang.String type) { throw new RuntimeException("Stub!"); } -public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN"; -public static final java.lang.String ACTION_VIEW = "android.intent.action.VIEW"; -public static final java.lang.String ACTION_DEFAULT = "android.intent.action.VIEW"; -public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA"; -public static final java.lang.String ACTION_EDIT = "android.intent.action.EDIT"; -public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT"; -public static final java.lang.String ACTION_PICK = "android.intent.action.PICK"; -public static final java.lang.String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT"; -public static final java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT"; -public static final java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME"; -public static final java.lang.String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON"; -public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE"; -public static final java.lang.String ACTION_CHOOSER = "android.intent.action.CHOOSER"; -public static final java.lang.String ACTION_GET_CONTENT = "android.intent.action.GET_CONTENT"; -public static final java.lang.String ACTION_DIAL = "android.intent.action.DIAL"; -public static final java.lang.String ACTION_CALL = "android.intent.action.CALL"; -public static final java.lang.String ACTION_SENDTO = "android.intent.action.SENDTO"; -public static final java.lang.String ACTION_SEND = "android.intent.action.SEND"; -public static final java.lang.String ACTION_SEND_MULTIPLE = "android.intent.action.SEND_MULTIPLE"; -public static final java.lang.String ACTION_ANSWER = "android.intent.action.ANSWER"; -public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT"; -public static final java.lang.String ACTION_PASTE = "android.intent.action.PASTE"; -public static final java.lang.String ACTION_DELETE = "android.intent.action.DELETE"; -public static final java.lang.String ACTION_RUN = "android.intent.action.RUN"; -public static final java.lang.String ACTION_SYNC = "android.intent.action.SYNC"; -public static final java.lang.String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY"; -public static final java.lang.String ACTION_SEARCH = "android.intent.action.SEARCH"; -public static final java.lang.String ACTION_SYSTEM_TUTORIAL = "android.intent.action.SYSTEM_TUTORIAL"; -public static final java.lang.String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH"; -public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST"; -public static final java.lang.String ACTION_ALL_APPS = "android.intent.action.ALL_APPS"; -public static final java.lang.String ACTION_SET_WALLPAPER = "android.intent.action.SET_WALLPAPER"; -public static final java.lang.String ACTION_BUG_REPORT = "android.intent.action.BUG_REPORT"; -public static final java.lang.String ACTION_FACTORY_TEST = "android.intent.action.FACTORY_TEST"; -public static final java.lang.String ACTION_CALL_BUTTON = "android.intent.action.CALL_BUTTON"; -public static final java.lang.String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND"; -public static final java.lang.String ACTION_SEARCH_LONG_PRESS = "android.intent.action.SEARCH_LONG_PRESS"; -public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR"; -public static final java.lang.String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; -public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE"; -public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE"; -public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME"; -public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE"; -@java.lang.Deprecated() -public static final java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE"; -public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT"; -public static final java.lang.String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE"; -public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF"; -public static final java.lang.String ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON"; -public static final java.lang.String ACTION_USER_PRESENT = "android.intent.action.USER_PRESENT"; -public static final java.lang.String ACTION_TIME_TICK = "android.intent.action.TIME_TICK"; -public static final java.lang.String ACTION_TIME_CHANGED = "android.intent.action.TIME_SET"; -public static final java.lang.String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED"; -public static final java.lang.String ACTION_TIMEZONE_CHANGED = "android.intent.action.TIMEZONE_CHANGED"; -public static final java.lang.String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED"; -public static final java.lang.String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS"; -@java.lang.Deprecated() -public static final java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; -public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; -public static final java.lang.String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED"; -public static final java.lang.String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED"; -public static final java.lang.String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED"; -public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED"; -public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; -public static final java.lang.String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED"; -public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED"; -public static final java.lang.String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED"; -public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH"; -public static final java.lang.String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION"; -public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE"; -public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE"; -@java.lang.Deprecated() -public static final java.lang.String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED"; -public static final java.lang.String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED"; -public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED"; -public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED"; -public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW"; -public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY"; -public static final java.lang.String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED"; -public static final java.lang.String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED"; -public static final java.lang.String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN"; -public static final java.lang.String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW"; -public static final java.lang.String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK"; -public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE"; -@java.lang.Deprecated() -public static final java.lang.String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED"; -@java.lang.Deprecated() -public static final java.lang.String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED"; -public static final java.lang.String ACTION_MEDIA_REMOVED = "android.intent.action.MEDIA_REMOVED"; -public static final java.lang.String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED"; -public static final java.lang.String ACTION_MEDIA_CHECKING = "android.intent.action.MEDIA_CHECKING"; -public static final java.lang.String ACTION_MEDIA_NOFS = "android.intent.action.MEDIA_NOFS"; -public static final java.lang.String ACTION_MEDIA_MOUNTED = "android.intent.action.MEDIA_MOUNTED"; -public static final java.lang.String ACTION_MEDIA_SHARED = "android.intent.action.MEDIA_SHARED"; -public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL"; -public static final java.lang.String ACTION_MEDIA_UNMOUNTABLE = "android.intent.action.MEDIA_UNMOUNTABLE"; -public static final java.lang.String ACTION_MEDIA_EJECT = "android.intent.action.MEDIA_EJECT"; -public static final java.lang.String ACTION_MEDIA_SCANNER_STARTED = "android.intent.action.MEDIA_SCANNER_STARTED"; -public static final java.lang.String ACTION_MEDIA_SCANNER_FINISHED = "android.intent.action.MEDIA_SCANNER_FINISHED"; -public static final java.lang.String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE"; -public static final java.lang.String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON"; -public static final java.lang.String ACTION_CAMERA_BUTTON = "android.intent.action.CAMERA_BUTTON"; -public static final java.lang.String ACTION_GTALK_SERVICE_CONNECTED = "android.intent.action.GTALK_CONNECTED"; -public static final java.lang.String ACTION_GTALK_SERVICE_DISCONNECTED = "android.intent.action.GTALK_DISCONNECTED"; -public static final java.lang.String ACTION_INPUT_METHOD_CHANGED = "android.intent.action.INPUT_METHOD_CHANGED"; -public static final java.lang.String ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE"; -public static final java.lang.String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED"; -public static final java.lang.String ACTION_HEADSET_PLUG = "android.intent.action.HEADSET_PLUG"; -public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"; -public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT"; -public static final java.lang.String ACTION_DOCK_EVENT = "android.intent.action.DOCK_EVENT"; -public static final java.lang.String CATEGORY_DEFAULT = "android.intent.category.DEFAULT"; -public static final java.lang.String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE"; -public static final java.lang.String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE"; -public static final java.lang.String CATEGORY_SELECTED_ALTERNATIVE = "android.intent.category.SELECTED_ALTERNATIVE"; -public static final java.lang.String CATEGORY_TAB = "android.intent.category.TAB"; -public static final java.lang.String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER"; -public static final java.lang.String CATEGORY_INFO = "android.intent.category.INFO"; -public static final java.lang.String CATEGORY_HOME = "android.intent.category.HOME"; -public static final java.lang.String CATEGORY_PREFERENCE = "android.intent.category.PREFERENCE"; -public static final java.lang.String CATEGORY_DEVELOPMENT_PREFERENCE = "android.intent.category.DEVELOPMENT_PREFERENCE"; -public static final java.lang.String CATEGORY_EMBED = "android.intent.category.EMBED"; -public static final java.lang.String CATEGORY_APP_MARKET = "android.intent.category.APP_MARKET"; -public static final java.lang.String CATEGORY_MONKEY = "android.intent.category.MONKEY"; -public static final java.lang.String CATEGORY_TEST = "android.intent.category.TEST"; -public static final java.lang.String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST"; -public static final java.lang.String CATEGORY_SAMPLE_CODE = "android.intent.category.SAMPLE_CODE"; -public static final java.lang.String CATEGORY_OPENABLE = "android.intent.category.OPENABLE"; -public static final java.lang.String CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST = "android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"; -public static final java.lang.String CATEGORY_CAR_DOCK = "android.intent.category.CAR_DOCK"; -public static final java.lang.String CATEGORY_DESK_DOCK = "android.intent.category.DESK_DOCK"; -public static final java.lang.String CATEGORY_LE_DESK_DOCK = "android.intent.category.LE_DESK_DOCK"; -public static final java.lang.String CATEGORY_HE_DESK_DOCK = "android.intent.category.HE_DESK_DOCK"; -public static final java.lang.String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE"; -public static final java.lang.String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER"; -public static final java.lang.String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR"; -public static final java.lang.String CATEGORY_APP_CALENDAR = "android.intent.category.APP_CALENDAR"; -public static final java.lang.String CATEGORY_APP_CONTACTS = "android.intent.category.APP_CONTACTS"; -public static final java.lang.String CATEGORY_APP_EMAIL = "android.intent.category.APP_EMAIL"; -public static final java.lang.String CATEGORY_APP_GALLERY = "android.intent.category.APP_GALLERY"; -public static final java.lang.String CATEGORY_APP_MAPS = "android.intent.category.APP_MAPS"; -public static final java.lang.String CATEGORY_APP_MESSAGING = "android.intent.category.APP_MESSAGING"; -public static final java.lang.String CATEGORY_APP_MUSIC = "android.intent.category.APP_MUSIC"; -public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE"; -public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT"; -public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT"; -public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; -public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL"; -public static final java.lang.String EXTRA_CC = "android.intent.extra.CC"; -public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC"; -public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT"; -public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT"; -public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE"; -public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS"; -public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT"; -public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP"; -public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER"; -public static final java.lang.String EXTRA_UID = "android.intent.extra.UID"; -public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED"; -public static final java.lang.String EXTRA_REPLACING = "android.intent.extra.REPLACING"; -public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT"; -public static final java.lang.String EXTRA_DOCK_STATE = "android.intent.extra.DOCK_STATE"; -public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; -public static final int EXTRA_DOCK_STATE_DESK = 1; -public static final int EXTRA_DOCK_STATE_CAR = 2; -public static final int EXTRA_DOCK_STATE_LE_DESK = 3; -public static final int EXTRA_DOCK_STATE_HE_DESK = 4; -public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home"; -public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT"; -public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token"; -@java.lang.Deprecated() -public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME = "android.intent.extra.changed_component_name"; -public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list"; -public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list"; -public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list"; -public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY"; -public static final int FLAG_GRANT_READ_URI_PERMISSION = 1; -public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 2; -public static final int FLAG_FROM_BACKGROUND = 4; -public static final int FLAG_DEBUG_LOG_RESOLUTION = 8; -public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 16; -public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32; -public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824; -public static final int FLAG_ACTIVITY_SINGLE_TOP = 536870912; -public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; -public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; -public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; -public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; -public static final int FLAG_ACTIVITY_PREVIOUS_IS_TOP = 16777216; -public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; -public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 4194304; -public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 2097152; -public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; -public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; -public static final int FLAG_ACTIVITY_NO_USER_ACTION = 262144; -public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 131072; -public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536; -public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; -public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; -public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; -public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; -public static final int FLAG_RECEIVER_FOREGROUND = 268435456; -public static final int URI_INTENT_SCHEME = 1; -public static final int FILL_IN_ACTION = 1; -public static final int FILL_IN_DATA = 2; -public static final int FILL_IN_CATEGORIES = 4; -public static final int FILL_IN_COMPONENT = 8; -public static final int FILL_IN_PACKAGE = 16; -public static final int FILL_IN_SOURCE_BOUNDS = 32; -public static final int FILL_IN_SELECTOR = 64; -public static final int FILL_IN_CLIP_DATA = 128; +//public static java.lang.String normalizeMimeType(java.lang.String type) { throw new RuntimeException("Stub!"); } +//public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN"; +//public static final java.lang.String ACTION_VIEW = "android.intent.action.VIEW"; +//public static final java.lang.String ACTION_DEFAULT = "android.intent.action.VIEW"; +//public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA"; +//public static final java.lang.String ACTION_EDIT = "android.intent.action.EDIT"; +//public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT"; +//public static final java.lang.String ACTION_PICK = "android.intent.action.PICK"; +//public static final java.lang.String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT"; +//public static final java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT"; +//public static final java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME"; +//public static final java.lang.String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON"; +//public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE"; +//public static final java.lang.String ACTION_CHOOSER = "android.intent.action.CHOOSER"; +//public static final java.lang.String ACTION_GET_CONTENT = "android.intent.action.GET_CONTENT"; +//public static final java.lang.String ACTION_DIAL = "android.intent.action.DIAL"; +//public static final java.lang.String ACTION_CALL = "android.intent.action.CALL"; +//public static final java.lang.String ACTION_SENDTO = "android.intent.action.SENDTO"; +//public static final java.lang.String ACTION_SEND = "android.intent.action.SEND"; +//public static final java.lang.String ACTION_SEND_MULTIPLE = "android.intent.action.SEND_MULTIPLE"; +//public static final java.lang.String ACTION_ANSWER = "android.intent.action.ANSWER"; +//public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT"; +//public static final java.lang.String ACTION_PASTE = "android.intent.action.PASTE"; +//public static final java.lang.String ACTION_DELETE = "android.intent.action.DELETE"; +//public static final java.lang.String ACTION_RUN = "android.intent.action.RUN"; +//public static final java.lang.String ACTION_SYNC = "android.intent.action.SYNC"; +//public static final java.lang.String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY"; +//public static final java.lang.String ACTION_SEARCH = "android.intent.action.SEARCH"; +//public static final java.lang.String ACTION_SYSTEM_TUTORIAL = "android.intent.action.SYSTEM_TUTORIAL"; +//public static final java.lang.String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH"; +//public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST"; +//public static final java.lang.String ACTION_ALL_APPS = "android.intent.action.ALL_APPS"; +//public static final java.lang.String ACTION_SET_WALLPAPER = "android.intent.action.SET_WALLPAPER"; +//public static final java.lang.String ACTION_BUG_REPORT = "android.intent.action.BUG_REPORT"; +//public static final java.lang.String ACTION_FACTORY_TEST = "android.intent.action.FACTORY_TEST"; +//public static final java.lang.String ACTION_CALL_BUTTON = "android.intent.action.CALL_BUTTON"; +//public static final java.lang.String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND"; +//public static final java.lang.String ACTION_SEARCH_LONG_PRESS = "android.intent.action.SEARCH_LONG_PRESS"; +//public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR"; +//public static final java.lang.String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; +//public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE"; +//public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE"; +//public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME"; +//public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE"; +//@java.lang.Deprecated() +//public static final java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE"; +//public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT"; +//public static final java.lang.String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE"; +//public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF"; +//public static final java.lang.String ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON"; +//public static final java.lang.String ACTION_USER_PRESENT = "android.intent.action.USER_PRESENT"; +//public static final java.lang.String ACTION_TIME_TICK = "android.intent.action.TIME_TICK"; +//public static final java.lang.String ACTION_TIME_CHANGED = "android.intent.action.TIME_SET"; +//public static final java.lang.String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED"; +//public static final java.lang.String ACTION_TIMEZONE_CHANGED = "android.intent.action.TIMEZONE_CHANGED"; +//public static final java.lang.String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED"; +//public static final java.lang.String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS"; +//@java.lang.Deprecated() +//public static final java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; +//public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; +//public static final java.lang.String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED"; +//public static final java.lang.String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED"; +//public static final java.lang.String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED"; +//public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED"; +//public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; +//public static final java.lang.String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED"; +//public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED"; +//public static final java.lang.String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED"; +//public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH"; +//public static final java.lang.String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION"; +//public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE"; +//public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE"; +//@java.lang.Deprecated() +//public static final java.lang.String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED"; +//public static final java.lang.String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED"; +//public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED"; +//public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED"; +//public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW"; +//public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY"; +//public static final java.lang.String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED"; +//public static final java.lang.String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED"; +//public static final java.lang.String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN"; +//public static final java.lang.String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW"; +//public static final java.lang.String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK"; +//public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE"; +//@java.lang.Deprecated() +//public static final java.lang.String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED"; +//@java.lang.Deprecated() +//public static final java.lang.String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED"; +//public static final java.lang.String ACTION_MEDIA_REMOVED = "android.intent.action.MEDIA_REMOVED"; +//public static final java.lang.String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED"; +//public static final java.lang.String ACTION_MEDIA_CHECKING = "android.intent.action.MEDIA_CHECKING"; +//public static final java.lang.String ACTION_MEDIA_NOFS = "android.intent.action.MEDIA_NOFS"; +//public static final java.lang.String ACTION_MEDIA_MOUNTED = "android.intent.action.MEDIA_MOUNTED"; +//public static final java.lang.String ACTION_MEDIA_SHARED = "android.intent.action.MEDIA_SHARED"; +//public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL"; +//public static final java.lang.String ACTION_MEDIA_UNMOUNTABLE = "android.intent.action.MEDIA_UNMOUNTABLE"; +//public static final java.lang.String ACTION_MEDIA_EJECT = "android.intent.action.MEDIA_EJECT"; +//public static final java.lang.String ACTION_MEDIA_SCANNER_STARTED = "android.intent.action.MEDIA_SCANNER_STARTED"; +//public static final java.lang.String ACTION_MEDIA_SCANNER_FINISHED = "android.intent.action.MEDIA_SCANNER_FINISHED"; +//public static final java.lang.String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE"; +//public static final java.lang.String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON"; +//public static final java.lang.String ACTION_CAMERA_BUTTON = "android.intent.action.CAMERA_BUTTON"; +//public static final java.lang.String ACTION_GTALK_SERVICE_CONNECTED = "android.intent.action.GTALK_CONNECTED"; +//public static final java.lang.String ACTION_GTALK_SERVICE_DISCONNECTED = "android.intent.action.GTALK_DISCONNECTED"; +//public static final java.lang.String ACTION_INPUT_METHOD_CHANGED = "android.intent.action.INPUT_METHOD_CHANGED"; +//public static final java.lang.String ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE"; +//public static final java.lang.String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED"; +//public static final java.lang.String ACTION_HEADSET_PLUG = "android.intent.action.HEADSET_PLUG"; +//public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"; +//public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT"; +//public static final java.lang.String ACTION_DOCK_EVENT = "android.intent.action.DOCK_EVENT"; +//public static final java.lang.String CATEGORY_DEFAULT = "android.intent.category.DEFAULT"; +//public static final java.lang.String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE"; +//public static final java.lang.String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE"; +//public static final java.lang.String CATEGORY_SELECTED_ALTERNATIVE = "android.intent.category.SELECTED_ALTERNATIVE"; +//public static final java.lang.String CATEGORY_TAB = "android.intent.category.TAB"; +//public static final java.lang.String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER"; +//public static final java.lang.String CATEGORY_INFO = "android.intent.category.INFO"; +//public static final java.lang.String CATEGORY_HOME = "android.intent.category.HOME"; +//public static final java.lang.String CATEGORY_PREFERENCE = "android.intent.category.PREFERENCE"; +//public static final java.lang.String CATEGORY_DEVELOPMENT_PREFERENCE = "android.intent.category.DEVELOPMENT_PREFERENCE"; +//public static final java.lang.String CATEGORY_EMBED = "android.intent.category.EMBED"; +//public static final java.lang.String CATEGORY_APP_MARKET = "android.intent.category.APP_MARKET"; +//public static final java.lang.String CATEGORY_MONKEY = "android.intent.category.MONKEY"; +//public static final java.lang.String CATEGORY_TEST = "android.intent.category.TEST"; +//public static final java.lang.String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST"; +//public static final java.lang.String CATEGORY_SAMPLE_CODE = "android.intent.category.SAMPLE_CODE"; +//public static final java.lang.String CATEGORY_OPENABLE = "android.intent.category.OPENABLE"; +//public static final java.lang.String CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST = "android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"; +//public static final java.lang.String CATEGORY_CAR_DOCK = "android.intent.category.CAR_DOCK"; +//public static final java.lang.String CATEGORY_DESK_DOCK = "android.intent.category.DESK_DOCK"; +//public static final java.lang.String CATEGORY_LE_DESK_DOCK = "android.intent.category.LE_DESK_DOCK"; +//public static final java.lang.String CATEGORY_HE_DESK_DOCK = "android.intent.category.HE_DESK_DOCK"; +//public static final java.lang.String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE"; +//public static final java.lang.String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER"; +//public static final java.lang.String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR"; +//public static final java.lang.String CATEGORY_APP_CALENDAR = "android.intent.category.APP_CALENDAR"; +//public static final java.lang.String CATEGORY_APP_CONTACTS = "android.intent.category.APP_CONTACTS"; +//public static final java.lang.String CATEGORY_APP_EMAIL = "android.intent.category.APP_EMAIL"; +//public static final java.lang.String CATEGORY_APP_GALLERY = "android.intent.category.APP_GALLERY"; +//public static final java.lang.String CATEGORY_APP_MAPS = "android.intent.category.APP_MAPS"; +//public static final java.lang.String CATEGORY_APP_MESSAGING = "android.intent.category.APP_MESSAGING"; +//public static final java.lang.String CATEGORY_APP_MUSIC = "android.intent.category.APP_MUSIC"; +//public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE"; +//public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT"; +//public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT"; +//public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; +//public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL"; +//public static final java.lang.String EXTRA_CC = "android.intent.extra.CC"; +//public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC"; +//public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT"; +//public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT"; +//public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE"; +//public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS"; +//public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT"; +//public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP"; +//public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER"; +//public static final java.lang.String EXTRA_UID = "android.intent.extra.UID"; +//public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED"; +//public static final java.lang.String EXTRA_REPLACING = "android.intent.extra.REPLACING"; +//public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT"; +//public static final java.lang.String EXTRA_DOCK_STATE = "android.intent.extra.DOCK_STATE"; +//public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; +//public static final int EXTRA_DOCK_STATE_DESK = 1; +//public static final int EXTRA_DOCK_STATE_CAR = 2; +//public static final int EXTRA_DOCK_STATE_LE_DESK = 3; +//public static final int EXTRA_DOCK_STATE_HE_DESK = 4; +//public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home"; +//public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT"; +//public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token"; +//@java.lang.Deprecated() +//public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME = "android.intent.extra.changed_component_name"; +//public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list"; +//public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list"; +//public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list"; +//public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY"; +//public static final int FLAG_GRANT_READ_URI_PERMISSION = 1; +//public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 2; +//public static final int FLAG_FROM_BACKGROUND = 4; +//public static final int FLAG_DEBUG_LOG_RESOLUTION = 8; +//public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 16; +//public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32; +//public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824; +//public static final int FLAG_ACTIVITY_SINGLE_TOP = 536870912; +//public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; +//public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; +//public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; +//public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; +//public static final int FLAG_ACTIVITY_PREVIOUS_IS_TOP = 16777216; +//public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; +//public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 4194304; +//public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 2097152; +//public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; +//public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; +//public static final int FLAG_ACTIVITY_NO_USER_ACTION = 262144; +//public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 131072; +//public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536; +//public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; +//public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; +//public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; +//public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; +//public static final int FLAG_RECEIVER_FOREGROUND = 268435456; +//public static final int URI_INTENT_SCHEME = 1; +//public static final int FILL_IN_ACTION = 1; +//public static final int FILL_IN_DATA = 2; +//public static final int FILL_IN_CATEGORIES = 4; +//public static final int FILL_IN_COMPONENT = 8; +//public static final int FILL_IN_PACKAGE = 16; +//public static final int FILL_IN_SOURCE_BOUNDS = 32; +//public static final int FILL_IN_SELECTOR = 64; +//public static final int FILL_IN_CLIP_DATA = 128; //public static final android.os.Parcelable.Creator<android.content.Intent> CREATOR; -//static { CREATOR = null; } +// static { CREATOR = null; } } diff --git a/src/android/content/IntentFilter.java b/src/android/content/IntentFilter.java index 29e622dd..b5e56dfb 100644 --- a/src/android/content/IntentFilter.java +++ b/src/android/content/IntentFilter.java @@ -3,181 +3,181 @@ public class IntentFilter // implements android.os.Parcelable { - public static class MalformedMimeTypeException extends android.util.AndroidException { - public MalformedMimeTypeException() { - throw new RuntimeException("Stub!"); - } - - public MalformedMimeTypeException(java.lang.String name) { - throw new RuntimeException("Stub!"); - } - } - - public static final class AuthorityEntry { - public AuthorityEntry(java.lang.String host, java.lang.String port) { - throw new RuntimeException("Stub!"); - } - - public java.lang.String getHost() { - throw new RuntimeException("Stub!"); - } - - public int getPort() { - throw new RuntimeException("Stub!"); - } - // public int match(android.net.Uri data) { throw new RuntimeException("Stub!"); } - } +// public static class MalformedMimeTypeException extends android.util.AndroidException { +// public MalformedMimeTypeException() { +// throw new RuntimeException("Stub!"); +// } +// +// public MalformedMimeTypeException(java.lang.String name) { +// throw new RuntimeException("Stub!"); +// } +// } +// +// public static final class AuthorityEntry { +// public AuthorityEntry(java.lang.String host, java.lang.String port) { +// throw new RuntimeException("Stub!"); +// } +// +// public java.lang.String getHost() { +// throw new RuntimeException("Stub!"); +// } +// +// public int getPort() { +// throw new RuntimeException("Stub!"); +// } +// // public int match(android.net.Uri data) { throw new RuntimeException("Stub!"); } +// } public IntentFilter() { /* throw new RuntimeException("Stub!"); */} - public IntentFilter(java.lang.String action) { - throw new RuntimeException("Stub!"); - } - - public IntentFilter(java.lang.String action, java.lang.String dataType) - throws android.content.IntentFilter.MalformedMimeTypeException { - throw new RuntimeException("Stub!"); - } - - public IntentFilter(android.content.IntentFilter o) { - throw new RuntimeException("Stub!"); - } - - public static android.content.IntentFilter create(java.lang.String action, java.lang.String dataType) { - throw new RuntimeException("Stub!"); - } - - public final void setPriority(int priority) { - throw new RuntimeException("Stub!"); - } - - public final int getPriority() { - throw new RuntimeException("Stub!"); - } +// public IntentFilter(java.lang.String action) { +// throw new RuntimeException("Stub!"); +// } +// +// public IntentFilter(java.lang.String action, java.lang.String dataType) +// throws android.content.IntentFilter.MalformedMimeTypeException { +// throw new RuntimeException("Stub!"); +// } +// +// public IntentFilter(android.content.IntentFilter o) { +// throw new RuntimeException("Stub!"); +// } + +// public static android.content.IntentFilter create(java.lang.String action, java.lang.String dataType) { +// throw new RuntimeException("Stub!"); +// } +// +// public final void setPriority(int priority) { +// throw new RuntimeException("Stub!"); +// } +// +// public final int getPriority() { +// throw new RuntimeException("Stub!"); +// } public final void addAction(java.lang.String action) { /* throw new RuntimeException("Stub!"); */ } - public final int countActions() { - throw new RuntimeException("Stub!"); - } - - public final java.lang.String getAction(int index) { - throw new RuntimeException("Stub!"); - } - - public final boolean hasAction(java.lang.String action) { - throw new RuntimeException("Stub!"); - } - - public final boolean matchAction(java.lang.String action) { - throw new RuntimeException("Stub!"); - } - - public final java.util.Iterator<java.lang.String> actionsIterator() { - throw new RuntimeException("Stub!"); - } - - public final void addDataType(java.lang.String type) - throws android.content.IntentFilter.MalformedMimeTypeException { - throw new RuntimeException("Stub!"); - } - - public final boolean hasDataType(java.lang.String type) { - throw new RuntimeException("Stub!"); - } - - public final int countDataTypes() { - throw new RuntimeException("Stub!"); - } - - public final java.lang.String getDataType(int index) { - throw new RuntimeException("Stub!"); - } - - public final java.util.Iterator<java.lang.String> typesIterator() { - throw new RuntimeException("Stub!"); - } - - public final void addDataScheme(java.lang.String scheme) { - throw new RuntimeException("Stub!"); - } - - public final int countDataSchemes() { - throw new RuntimeException("Stub!"); - } - - public final java.lang.String getDataScheme(int index) { - throw new RuntimeException("Stub!"); - } - - public final boolean hasDataScheme(java.lang.String scheme) { - throw new RuntimeException("Stub!"); - } - - public final java.util.Iterator<java.lang.String> schemesIterator() { - throw new RuntimeException("Stub!"); - } - - public final void addDataAuthority(java.lang.String host, java.lang.String port) { - throw new RuntimeException("Stub!"); - } - - public final int countDataAuthorities() { - throw new RuntimeException("Stub!"); - } - - public final android.content.IntentFilter.AuthorityEntry getDataAuthority(int index) { - throw new RuntimeException("Stub!"); - } +// public final int countActions() { +// throw new RuntimeException("Stub!"); +// } +// +// public final java.lang.String getAction(int index) { +// throw new RuntimeException("Stub!"); +// } +// +// public final boolean hasAction(java.lang.String action) { +// throw new RuntimeException("Stub!"); +// } +// +// public final boolean matchAction(java.lang.String action) { +// throw new RuntimeException("Stub!"); +// } +// +// public final java.util.Iterator<java.lang.String> actionsIterator() { +// throw new RuntimeException("Stub!"); +// } +// +// public final void addDataType(java.lang.String type) +// throws android.content.IntentFilter.MalformedMimeTypeException { +// throw new RuntimeException("Stub!"); +// } +// +// public final boolean hasDataType(java.lang.String type) { +// throw new RuntimeException("Stub!"); +// } +// +// public final int countDataTypes() { +// throw new RuntimeException("Stub!"); +// } +// +// public final java.lang.String getDataType(int index) { +// throw new RuntimeException("Stub!"); +// } +// +// public final java.util.Iterator<java.lang.String> typesIterator() { +// throw new RuntimeException("Stub!"); +// } +// +// public final void addDataScheme(java.lang.String scheme) { +// throw new RuntimeException("Stub!"); +// } +// +// public final int countDataSchemes() { +// throw new RuntimeException("Stub!"); +// } +// +// public final java.lang.String getDataScheme(int index) { +// throw new RuntimeException("Stub!"); +// } +// +// public final boolean hasDataScheme(java.lang.String scheme) { +// throw new RuntimeException("Stub!"); +// } +// +// public final java.util.Iterator<java.lang.String> schemesIterator() { +// throw new RuntimeException("Stub!"); +// } +// +// public final void addDataAuthority(java.lang.String host, java.lang.String port) { +// throw new RuntimeException("Stub!"); +// } +// +// public final int countDataAuthorities() { +// throw new RuntimeException("Stub!"); +// } +// +// public final android.content.IntentFilter.AuthorityEntry getDataAuthority(int index) { +// throw new RuntimeException("Stub!"); +// } // public final boolean hasDataAuthority(android.net.Uri data) { throw new RuntimeException("Stub!"); } - public final java.util.Iterator<android.content.IntentFilter.AuthorityEntry> authoritiesIterator() { - throw new RuntimeException("Stub!"); - } - - public final void addDataPath(java.lang.String path, int type) { - throw new RuntimeException("Stub!"); - } - - public final int countDataPaths() { - throw new RuntimeException("Stub!"); - } +// public final java.util.Iterator<android.content.IntentFilter.AuthorityEntry> authoritiesIterator() { +// throw new RuntimeException("Stub!"); +// } +// +// public final void addDataPath(java.lang.String path, int type) { +// throw new RuntimeException("Stub!"); +// } +// +// public final int countDataPaths() { +// throw new RuntimeException("Stub!"); +// } // public final android.os.PatternMatcher getDataPath(int index) { throw new RuntimeException("Stub!"); } - public final boolean hasDataPath(java.lang.String data) { - throw new RuntimeException("Stub!"); - } +// public final boolean hasDataPath(java.lang.String data) { +// throw new RuntimeException("Stub!"); +// } // public final java.util.Iterator<android.os.PatternMatcher> pathsIterator() { throw new RuntimeException("Stub!"); // } // public final int matchDataAuthority(android.net.Uri data) { throw new RuntimeException("Stub!"); } // public final int matchData(java.lang.String type, java.lang.String scheme, android.net.Uri data) { throw new // RuntimeException("Stub!"); } - public final void addCategory(java.lang.String category) { - throw new RuntimeException("Stub!"); - } - - public final int countCategories() { - throw new RuntimeException("Stub!"); - } - - public final java.lang.String getCategory(int index) { - throw new RuntimeException("Stub!"); - } - - public final boolean hasCategory(java.lang.String category) { - throw new RuntimeException("Stub!"); - } - - public final java.util.Iterator<java.lang.String> categoriesIterator() { - throw new RuntimeException("Stub!"); - } - - public final java.lang.String matchCategories(java.util.Set<java.lang.String> categories) { - throw new RuntimeException("Stub!"); - } +// public final void addCategory(java.lang.String category) { +// throw new RuntimeException("Stub!"); +// } +// +// public final int countCategories() { +// throw new RuntimeException("Stub!"); +// } +// +// public final java.lang.String getCategory(int index) { +// throw new RuntimeException("Stub!"); +// } +// +// public final boolean hasCategory(java.lang.String category) { +// throw new RuntimeException("Stub!"); +// } +// +// public final java.util.Iterator<java.lang.String> categoriesIterator() { +// throw new RuntimeException("Stub!"); +// } +// +// public final java.lang.String matchCategories(java.util.Set<java.lang.String> categories) { +// throw new RuntimeException("Stub!"); +// } // public final int match(android.content.ContentResolver resolver, android.content.Intent intent, boolean resolve, // java.lang.String logTag) { throw new RuntimeException("Stub!"); } @@ -194,26 +194,26 @@ public final java.lang.String matchCategories(java.util.Set<java.lang.String> ca // } // public void dump(android.util.Printer du, java.lang.String prefix) { throw new RuntimeException("Stub!"); } - public final int describeContents() { - throw new RuntimeException("Stub!"); - } +// public final int describeContents() { +// throw new RuntimeException("Stub!"); +// } // public final void writeToParcel(android.os.Parcel dest, int flags) { throw new RuntimeException("Stub!"); } - public static final int SYSTEM_HIGH_PRIORITY = 1000; - public static final int SYSTEM_LOW_PRIORITY = -1000; - public static final int MATCH_CATEGORY_MASK = 268369920; - public static final int MATCH_ADJUSTMENT_MASK = 65535; - public static final int MATCH_ADJUSTMENT_NORMAL = 32768; - public static final int MATCH_CATEGORY_EMPTY = 1048576; - public static final int MATCH_CATEGORY_SCHEME = 2097152; - public static final int MATCH_CATEGORY_HOST = 3145728; - public static final int MATCH_CATEGORY_PORT = 4194304; - public static final int MATCH_CATEGORY_PATH = 5242880; - public static final int MATCH_CATEGORY_TYPE = 6291456; - public static final int NO_MATCH_TYPE = -1; - public static final int NO_MATCH_DATA = -2; - public static final int NO_MATCH_ACTION = -3; - public static final int NO_MATCH_CATEGORY = -4; +// public static final int SYSTEM_HIGH_PRIORITY = 1000; +// public static final int SYSTEM_LOW_PRIORITY = -1000; +// public static final int MATCH_CATEGORY_MASK = 268369920; +// public static final int MATCH_ADJUSTMENT_MASK = 65535; +// public static final int MATCH_ADJUSTMENT_NORMAL = 32768; +// public static final int MATCH_CATEGORY_EMPTY = 1048576; +// public static final int MATCH_CATEGORY_SCHEME = 2097152; +// public static final int MATCH_CATEGORY_HOST = 3145728; +// public static final int MATCH_CATEGORY_PORT = 4194304; +// public static final int MATCH_CATEGORY_PATH = 5242880; +// public static final int MATCH_CATEGORY_TYPE = 6291456; +// public static final int NO_MATCH_TYPE = -1; +// public static final int NO_MATCH_DATA = -2; +// public static final int NO_MATCH_ACTION = -3; +// public static final int NO_MATCH_CATEGORY = -4; // public static final android.os.Parcelable.Creator<android.content.IntentFilter> CREATOR; // static { CREATOR = null; } } diff --git a/src/android/content/pm/ApplicationInfo.java b/src/android/content/pm/ApplicationInfo.java index 23ed2611..94c1b43c 100644 --- a/src/android/content/pm/ApplicationInfo.java +++ b/src/android/content/pm/ApplicationInfo.java @@ -1,64 +1,62 @@ package android.content.pm; -public class ApplicationInfo - extends android.content.pm.PackageItemInfo -// implements android.os.Parcelable +public class ApplicationInfo extends android.content.pm.PackageItemInfo // implements android.os.Parcelable { -public static class DisplayNameComparator - implements java.util.Comparator<android.content.pm.ApplicationInfo> -{ -public DisplayNameComparator(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -public final int compare(android.content.pm.ApplicationInfo aa, android.content.pm.ApplicationInfo ab) { throw new RuntimeException("Stub!"); } -} -public ApplicationInfo() { /*throw new RuntimeException("Stub!");*/ } -public ApplicationInfo(android.content.pm.ApplicationInfo orig) { throw new RuntimeException("Stub!"); } +//public static class DisplayNameComparator +// implements java.util.Comparator<android.content.pm.ApplicationInfo> +//{ +//public DisplayNameComparator(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +//public final int compare(android.content.pm.ApplicationInfo aa, android.content.pm.ApplicationInfo ab) { throw new RuntimeException("Stub!"); } +//} +//public ApplicationInfo() { /*throw new RuntimeException("Stub!");*/ } +//public ApplicationInfo(android.content.pm.ApplicationInfo orig) { throw new RuntimeException("Stub!"); } //public void dump(android.util.Printer pw, java.lang.String prefix) { throw new RuntimeException("Stub!"); } -public java.lang.String toString() { throw new RuntimeException("Stub!"); } -public int describeContents() { throw new RuntimeException("Stub!"); } +//public java.lang.String toString() { throw new RuntimeException("Stub!"); } +//public int describeContents() { throw new RuntimeException("Stub!"); } //public void writeToParcel(android.os.Parcel dest, int parcelableFlags) { throw new RuntimeException("Stub!"); } -public java.lang.CharSequence loadDescription(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -public java.lang.String taskAffinity; -public java.lang.String permission; -public java.lang.String processName; -public java.lang.String className; -public int descriptionRes; -public int theme; -public java.lang.String manageSpaceActivityName; -public java.lang.String backupAgentName; -public int uiOptions; -public static final int FLAG_SYSTEM = 1; -public static final int FLAG_DEBUGGABLE = 2; -public static final int FLAG_HAS_CODE = 4; -public static final int FLAG_PERSISTENT = 8; -public static final int FLAG_FACTORY_TEST = 16; -public static final int FLAG_ALLOW_TASK_REPARENTING = 32; -public static final int FLAG_ALLOW_CLEAR_USER_DATA = 64; -public static final int FLAG_UPDATED_SYSTEM_APP = 128; -public static final int FLAG_TEST_ONLY = 256; -public static final int FLAG_SUPPORTS_SMALL_SCREENS = 512; -public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1024; -public static final int FLAG_SUPPORTS_LARGE_SCREENS = 2048; -public static final int FLAG_RESIZEABLE_FOR_SCREENS = 4096; -public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 8192; -public static final int FLAG_VM_SAFE_MODE = 16384; -public static final int FLAG_ALLOW_BACKUP = 32768; -public static final int FLAG_KILL_AFTER_RESTORE = 65536; -public static final int FLAG_RESTORE_ANY_VERSION = 131072; -public static final int FLAG_EXTERNAL_STORAGE = 262144; -public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 524288; -public static final int FLAG_LARGE_HEAP = 1048576; -public static final int FLAG_STOPPED = 2097152; -public int flags; -public int requiresSmallestWidthDp; -public int compatibleWidthLimitDp; -public int largestWidthLimitDp; -public java.lang.String sourceDir; -public java.lang.String publicSourceDir; -public java.lang.String[] sharedLibraryFiles = null; +//public java.lang.CharSequence loadDescription(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +//public java.lang.String taskAffinity; +//public java.lang.String permission; +//public java.lang.String processName; +//public java.lang.String className; +//public int descriptionRes; +//public int theme; +//public java.lang.String manageSpaceActivityName; +//public java.lang.String backupAgentName; +//public int uiOptions; +//public static final int FLAG_SYSTEM = 1; +//public static final int FLAG_DEBUGGABLE = 2; +//public static final int FLAG_HAS_CODE = 4; +//public static final int FLAG_PERSISTENT = 8; +//public static final int FLAG_FACTORY_TEST = 16; +//public static final int FLAG_ALLOW_TASK_REPARENTING = 32; +//public static final int FLAG_ALLOW_CLEAR_USER_DATA = 64; +//public static final int FLAG_UPDATED_SYSTEM_APP = 128; +//public static final int FLAG_TEST_ONLY = 256; +//public static final int FLAG_SUPPORTS_SMALL_SCREENS = 512; +//public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1024; +//public static final int FLAG_SUPPORTS_LARGE_SCREENS = 2048; +//public static final int FLAG_RESIZEABLE_FOR_SCREENS = 4096; +//public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 8192; +//public static final int FLAG_VM_SAFE_MODE = 16384; +//public static final int FLAG_ALLOW_BACKUP = 32768; +//public static final int FLAG_KILL_AFTER_RESTORE = 65536; +//public static final int FLAG_RESTORE_ANY_VERSION = 131072; +//public static final int FLAG_EXTERNAL_STORAGE = 262144; +//public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 524288; +//public static final int FLAG_LARGE_HEAP = 1048576; +//public static final int FLAG_STOPPED = 2097152; +//public int flags; +//public int requiresSmallestWidthDp; +//public int compatibleWidthLimitDp; +//public int largestWidthLimitDp; +//public java.lang.String sourceDir; +//public java.lang.String publicSourceDir; +//public java.lang.String[] sharedLibraryFiles = null; public java.lang.String dataDir; -public java.lang.String nativeLibraryDir; -public int uid; -public int targetSdkVersion; -public boolean enabled; +//public java.lang.String nativeLibraryDir; +//public int uid; +//public int targetSdkVersion; +//public boolean enabled; //public static final android.os.Parcelable.Creator<android.content.pm.ApplicationInfo> CREATOR; //static { CREATOR = null; } } diff --git a/src/android/content/pm/PackageInfo.java b/src/android/content/pm/PackageInfo.java index 9c6d4802..c2d2fc77 100644 --- a/src/android/content/pm/PackageInfo.java +++ b/src/android/content/pm/PackageInfo.java @@ -3,28 +3,28 @@ public class PackageInfo // implements android.os.Parcelable { public PackageInfo() { /*throw new RuntimeException("Stub!"); */} -public java.lang.String toString() { throw new RuntimeException("Stub!"); } -public int describeContents() { throw new RuntimeException("Stub!"); } +//public java.lang.String toString() { throw new RuntimeException("Stub!"); } +//public int describeContents() { throw new RuntimeException("Stub!"); } //public void writeToParcel(android.os.Parcel dest, int parcelableFlags) { throw new RuntimeException("Stub!"); } -public java.lang.String packageName; -public int versionCode; -public java.lang.String versionName; -public java.lang.String sharedUserId; -public int sharedUserLabel; +//public java.lang.String packageName; +//public int versionCode; +//public java.lang.String versionName; +//public java.lang.String sharedUserId; +//public int sharedUserLabel; public android.content.pm.ApplicationInfo applicationInfo; -public long firstInstallTime; -public long lastUpdateTime; -public int[] gids = null; +//public long firstInstallTime; +//public long lastUpdateTime; +//public int[] gids = null; //public android.content.pm.ActivityInfo[] activities = null; //public android.content.pm.ActivityInfo[] receivers = null; //public android.content.pm.ServiceInfo[] services = null; //public android.content.pm.ProviderInfo[] providers = null; //public android.content.pm.InstrumentationInfo[] instrumentation = null; //public android.content.pm.PermissionInfo[] permissions = null; -public java.lang.String[] requestedPermissions = null; -public int[] requestedPermissionsFlags = null; -public static final int REQUESTED_PERMISSION_REQUIRED = 1; -public static final int REQUESTED_PERMISSION_GRANTED = 2; +//public java.lang.String[] requestedPermissions = null; +//public int[] requestedPermissionsFlags = null; +//public static final int REQUESTED_PERMISSION_REQUIRED = 1; +//public static final int REQUESTED_PERMISSION_GRANTED = 2; //public android.content.pm.Signature[] signatures = null; //public android.content.pm.ConfigurationInfo[] configPreferences = null; //public android.content.pm.FeatureInfo[] reqFeatures = null; diff --git a/src/android/content/pm/PackageItemInfo.java b/src/android/content/pm/PackageItemInfo.java index 2be5fa60..ded58f99 100644 --- a/src/android/content/pm/PackageItemInfo.java +++ b/src/android/content/pm/PackageItemInfo.java @@ -1,27 +1,27 @@ package android.content.pm; public class PackageItemInfo { -public static class DisplayNameComparator - implements java.util.Comparator<android.content.pm.PackageItemInfo> -{ -public DisplayNameComparator(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -public final int compare(android.content.pm.PackageItemInfo aa, android.content.pm.PackageItemInfo ab) { throw new RuntimeException("Stub!"); } -} +//public static class DisplayNameComparator +// implements java.util.Comparator<android.content.pm.PackageItemInfo> +//{ +//public DisplayNameComparator(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +//public final int compare(android.content.pm.PackageItemInfo aa, android.content.pm.PackageItemInfo ab) { throw new RuntimeException("Stub!"); } +//} public PackageItemInfo() { /*throw new RuntimeException("Stub!");*/ } -public PackageItemInfo(android.content.pm.PackageItemInfo orig) { throw new RuntimeException("Stub!"); } +//public PackageItemInfo(android.content.pm.PackageItemInfo orig) { throw new RuntimeException("Stub!"); } //protected PackageItemInfo(android.os.Parcel source) { throw new RuntimeException("Stub!"); } -public java.lang.CharSequence loadLabel(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } +//public java.lang.CharSequence loadLabel(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } //public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } //public android.graphics.drawable.Drawable loadLogo(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } //public android.content.res.XmlResourceParser loadXmlMetaData(android.content.pm.PackageManager pm, java.lang.String name) { throw new RuntimeException("Stub!"); } //protected void dumpFront(android.util.Printer pw, java.lang.String prefix) { throw new RuntimeException("Stub!"); } //protected void dumpBack(android.util.Printer pw, java.lang.String prefix) { throw new RuntimeException("Stub!"); } //public void writeToParcel(android.os.Parcel dest, int parcelableFlags) { throw new RuntimeException("Stub!"); } -public java.lang.String name; -public java.lang.String packageName; -public int labelRes; -public java.lang.CharSequence nonLocalizedLabel; -public int icon; -public int logo; +//public java.lang.String name; +//public java.lang.String packageName; +//public int labelRes; +//public java.lang.CharSequence nonLocalizedLabel; +//public int icon; +//public int logo; //public android.os.Bundle metaData; } diff --git a/src/android/content/pm/PackageManager.java b/src/android/content/pm/PackageManager.java index 0c772682..e5cccbed 100644 --- a/src/android/content/pm/PackageManager.java +++ b/src/android/content/pm/PackageManager.java @@ -1,18 +1,16 @@ package android.content.pm; public abstract class PackageManager { -public static class NameNotFoundException - extends android.util.AndroidException -{ -public NameNotFoundException() { } -public NameNotFoundException(java.lang.String name) { throw new RuntimeException("Stub!"); } +public static class NameNotFoundException extends java.lang.Exception { +//public NameNotFoundException() { } +//public NameNotFoundException(java.lang.String name) { throw new RuntimeException("Stub!"); } } -public PackageManager() { /*throw new RuntimeException("Stub!");*/ } +//public PackageManager() { /*throw new RuntimeException("Stub!");*/ } public abstract android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -public abstract java.lang.String[] currentToCanonicalPackageNames(java.lang.String[] names); -public abstract java.lang.String[] canonicalToCurrentPackageNames(java.lang.String[] names); +//public abstract java.lang.String[] currentToCanonicalPackageNames(java.lang.String[] names); +//public abstract java.lang.String[] canonicalToCurrentPackageNames(java.lang.String[] names); //public abstract android.content.Intent getLaunchIntentForPackage(java.lang.String packageName); -public abstract int[] getPackageGids(java.lang.String packageName) throws android.content.pm.PackageManager.NameNotFoundException; +//public abstract int[] getPackageGids(java.lang.String packageName) throws android.content.pm.PackageManager.NameNotFoundException; //public abstract android.content.pm.PermissionInfo getPermissionInfo(java.lang.String name, int flags) throws android.content.pm.PackageManager.NameNotFoundException; //public abstract java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(java.lang.String group, int flags) throws android.content.pm.PackageManager.NameNotFoundException; //public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(java.lang.String name, int flags) throws android.content.pm.PackageManager.NameNotFoundException; @@ -22,19 +20,19 @@ public NameNotFoundException() { } //public abstract android.content.pm.ActivityInfo getReceiverInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; //public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; //public abstract android.content.pm.ProviderInfo getProviderInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int flags); -public abstract int checkPermission(java.lang.String permName, java.lang.String pkgName); +//public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int flags); +//public abstract int checkPermission(java.lang.String permName, java.lang.String pkgName); //public abstract boolean addPermission(android.content.pm.PermissionInfo info); //public abstract boolean addPermissionAsync(android.content.pm.PermissionInfo info); -public abstract void removePermission(java.lang.String name); -public abstract int checkSignatures(java.lang.String pkg1, java.lang.String pkg2); -public abstract int checkSignatures(int uid1, int uid2); -public abstract java.lang.String[] getPackagesForUid(int uid); -public abstract java.lang.String getNameForUid(int uid); -public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int flags); -public abstract java.lang.String[] getSystemSharedLibraryNames(); +//public abstract void removePermission(java.lang.String name); +//public abstract int checkSignatures(java.lang.String pkg1, java.lang.String pkg2); +//public abstract int checkSignatures(int uid1, int uid2); +//public abstract java.lang.String[] getPackagesForUid(int uid); +//public abstract java.lang.String getNameForUid(int uid); +//public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int flags); +//public abstract java.lang.String[] getSystemSharedLibraryNames(); //public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures(); -public abstract boolean hasSystemFeature(java.lang.String name); +//public abstract boolean hasSystemFeature(java.lang.String name); //public abstract android.content.pm.ResolveInfo resolveActivity(android.content.Intent intent, int flags); //public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivities(android.content.Intent intent, int flags); //public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivityOptions(android.content.ComponentName caller, android.content.Intent[] specifics, android.content.Intent intent, int flags); @@ -55,98 +53,98 @@ public NameNotFoundException() { } //public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.Intent intent) throws android.content.pm.PackageManager.NameNotFoundException; //public abstract android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo info); //public abstract android.graphics.drawable.Drawable getApplicationLogo(java.lang.String packageName) throws android.content.pm.PackageManager.NameNotFoundException; -public abstract java.lang.CharSequence getText(java.lang.String packageName, int resid, android.content.pm.ApplicationInfo appInfo); +//public abstract java.lang.CharSequence getText(java.lang.String packageName, int resid, android.content.pm.ApplicationInfo appInfo); //public abstract android.content.res.XmlResourceParser getXml(java.lang.String packageName, int resid, android.content.pm.ApplicationInfo appInfo); public abstract java.lang.CharSequence getApplicationLabel(android.content.pm.ApplicationInfo info); //public abstract android.content.res.Resources getResourcesForActivity(android.content.ComponentName activityName) throws android.content.pm.PackageManager.NameNotFoundException; //public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo app) throws android.content.pm.PackageManager.NameNotFoundException; //public abstract android.content.res.Resources getResourcesForApplication(java.lang.String appPackageName) throws android.content.pm.PackageManager.NameNotFoundException; -public android.content.pm.PackageInfo getPackageArchiveInfo(java.lang.String archiveFilePath, int flags) { throw new RuntimeException("Stub!"); } -public abstract void verifyPendingInstall(int id, int verificationCode); -public abstract void setInstallerPackageName(java.lang.String targetPackage, java.lang.String installerPackageName); -public abstract java.lang.String getInstallerPackageName(java.lang.String packageName); -@java.lang.Deprecated() -public abstract void addPackageToPreferred(java.lang.String packageName); -@java.lang.Deprecated() -public abstract void removePackageFromPreferred(java.lang.String packageName); -public abstract java.util.List<android.content.pm.PackageInfo> getPreferredPackages(int flags); -@java.lang.Deprecated() +//public android.content.pm.PackageInfo getPackageArchiveInfo(java.lang.String archiveFilePath, int flags) { throw new RuntimeException("Stub!"); } +//public abstract void verifyPendingInstall(int id, int verificationCode); +//public abstract void setInstallerPackageName(java.lang.String targetPackage, java.lang.String installerPackageName); +//public abstract java.lang.String getInstallerPackageName(java.lang.String packageName); +//@java.lang.Deprecated() +//public abstract void addPackageToPreferred(java.lang.String packageName); +//@java.lang.Deprecated() +//public abstract void removePackageFromPreferred(java.lang.String packageName); +//public abstract java.util.List<android.content.pm.PackageInfo> getPreferredPackages(int flags); +//@java.lang.Deprecated() //public abstract void addPreferredActivity(android.content.IntentFilter filter, int match, android.content.ComponentName[] set, android.content.ComponentName activity); -public abstract void clearPackagePreferredActivities(java.lang.String packageName); +//public abstract void clearPackagePreferredActivities(java.lang.String packageName); //public abstract int getPreferredActivities(java.util.List<android.content.IntentFilter> outFilters, java.util.List<android.content.ComponentName> outActivities, java.lang.String packageName); //public abstract void setComponentEnabledSetting(android.content.ComponentName componentName, int newState, int flags); //public abstract int getComponentEnabledSetting(android.content.ComponentName componentName); -public abstract void setApplicationEnabledSetting(java.lang.String packageName, int newState, int flags); -public abstract int getApplicationEnabledSetting(java.lang.String packageName); -public abstract boolean isSafeMode(); -public static final int GET_ACTIVITIES = 1; -public static final int GET_RECEIVERS = 2; -public static final int GET_SERVICES = 4; -public static final int GET_PROVIDERS = 8; -public static final int GET_INSTRUMENTATION = 16; -public static final int GET_INTENT_FILTERS = 32; -public static final int GET_SIGNATURES = 64; -public static final int GET_RESOLVED_FILTER = 64; -public static final int GET_META_DATA = 128; -public static final int GET_GIDS = 256; -public static final int GET_DISABLED_COMPONENTS = 512; -public static final int GET_SHARED_LIBRARY_FILES = 1024; -public static final int GET_URI_PERMISSION_PATTERNS = 2048; -public static final int GET_PERMISSIONS = 4096; -public static final int GET_UNINSTALLED_PACKAGES = 8192; -public static final int GET_CONFIGURATIONS = 16384; -public static final int MATCH_DEFAULT_ONLY = 65536; -public static final int PERMISSION_GRANTED = 0; -public static final int PERMISSION_DENIED = -1; -public static final int SIGNATURE_MATCH = 0; -public static final int SIGNATURE_NEITHER_SIGNED = 1; -public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; -public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; -public static final int SIGNATURE_NO_MATCH = -3; -public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; -public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; -public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; -public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; -public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; -public static final int DONT_KILL_APP = 1; -public static final int VERIFICATION_ALLOW = 1; -public static final int VERIFICATION_REJECT = -1; -public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency"; -public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth"; -public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera"; -public static final java.lang.String FEATURE_CAMERA_AUTOFOCUS = "android.hardware.camera.autofocus"; -public static final java.lang.String FEATURE_CAMERA_FLASH = "android.hardware.camera.flash"; -public static final java.lang.String FEATURE_CAMERA_FRONT = "android.hardware.camera.front"; -public static final java.lang.String FEATURE_LOCATION = "android.hardware.location"; -public static final java.lang.String FEATURE_LOCATION_GPS = "android.hardware.location.gps"; -public static final java.lang.String FEATURE_LOCATION_NETWORK = "android.hardware.location.network"; -public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone"; -public static final java.lang.String FEATURE_NFC = "android.hardware.nfc"; -public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer"; -public static final java.lang.String FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer"; -public static final java.lang.String FEATURE_SENSOR_COMPASS = "android.hardware.sensor.compass"; -public static final java.lang.String FEATURE_SENSOR_GYROSCOPE = "android.hardware.sensor.gyroscope"; -public static final java.lang.String FEATURE_SENSOR_LIGHT = "android.hardware.sensor.light"; -public static final java.lang.String FEATURE_SENSOR_PROXIMITY = "android.hardware.sensor.proximity"; -public static final java.lang.String FEATURE_TELEPHONY = "android.hardware.telephony"; -public static final java.lang.String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma"; -public static final java.lang.String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm"; -public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host"; -public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory"; -public static final java.lang.String FEATURE_SIP = "android.software.sip"; -public static final java.lang.String FEATURE_SIP_VOIP = "android.software.sip.voip"; -public static final java.lang.String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen"; -public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch"; -public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct"; -public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = "android.hardware.touchscreen.multitouch.jazzhand"; -public static final java.lang.String FEATURE_FAKETOUCH = "android.hardware.faketouch"; -public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT = "android.hardware.faketouch.multitouch.distinct"; -public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand"; -public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait"; -public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape"; -public static final java.lang.String FEATURE_LIVE_WALLPAPER = "android.software.live_wallpaper"; -public static final java.lang.String FEATURE_WIFI = "android.hardware.wifi"; -public static final java.lang.String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct"; -public static final java.lang.String FEATURE_TELEVISION = "android.hardware.type.television"; -public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID"; +//public abstract void setApplicationEnabledSetting(java.lang.String packageName, int newState, int flags); +//public abstract int getApplicationEnabledSetting(java.lang.String packageName); +//public abstract boolean isSafeMode(); +//public static final int GET_ACTIVITIES = 1; +//public static final int GET_RECEIVERS = 2; +//public static final int GET_SERVICES = 4; +//public static final int GET_PROVIDERS = 8; +//public static final int GET_INSTRUMENTATION = 16; +//public static final int GET_INTENT_FILTERS = 32; +//public static final int GET_SIGNATURES = 64; +//public static final int GET_RESOLVED_FILTER = 64; +//public static final int GET_META_DATA = 128; +//public static final int GET_GIDS = 256; +//public static final int GET_DISABLED_COMPONENTS = 512; +//public static final int GET_SHARED_LIBRARY_FILES = 1024; +//public static final int GET_URI_PERMISSION_PATTERNS = 2048; +//public static final int GET_PERMISSIONS = 4096; +//public static final int GET_UNINSTALLED_PACKAGES = 8192; +//public static final int GET_CONFIGURATIONS = 16384; +//public static final int MATCH_DEFAULT_ONLY = 65536; +//public static final int PERMISSION_GRANTED = 0; +//public static final int PERMISSION_DENIED = -1; +//public static final int SIGNATURE_MATCH = 0; +//public static final int SIGNATURE_NEITHER_SIGNED = 1; +//public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; +//public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; +//public static final int SIGNATURE_NO_MATCH = -3; +//public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; +//public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; +//public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; +//public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; +//public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; +//public static final int DONT_KILL_APP = 1; +//public static final int VERIFICATION_ALLOW = 1; +//public static final int VERIFICATION_REJECT = -1; +//public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency"; +//public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth"; +//public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera"; +//public static final java.lang.String FEATURE_CAMERA_AUTOFOCUS = "android.hardware.camera.autofocus"; +//public static final java.lang.String FEATURE_CAMERA_FLASH = "android.hardware.camera.flash"; +//public static final java.lang.String FEATURE_CAMERA_FRONT = "android.hardware.camera.front"; +//public static final java.lang.String FEATURE_LOCATION = "android.hardware.location"; +//public static final java.lang.String FEATURE_LOCATION_GPS = "android.hardware.location.gps"; +//public static final java.lang.String FEATURE_LOCATION_NETWORK = "android.hardware.location.network"; +//public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone"; +//public static final java.lang.String FEATURE_NFC = "android.hardware.nfc"; +//public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer"; +//public static final java.lang.String FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer"; +//public static final java.lang.String FEATURE_SENSOR_COMPASS = "android.hardware.sensor.compass"; +//public static final java.lang.String FEATURE_SENSOR_GYROSCOPE = "android.hardware.sensor.gyroscope"; +//public static final java.lang.String FEATURE_SENSOR_LIGHT = "android.hardware.sensor.light"; +//public static final java.lang.String FEATURE_SENSOR_PROXIMITY = "android.hardware.sensor.proximity"; +//public static final java.lang.String FEATURE_TELEPHONY = "android.hardware.telephony"; +//public static final java.lang.String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma"; +//public static final java.lang.String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm"; +//public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host"; +//public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory"; +//public static final java.lang.String FEATURE_SIP = "android.software.sip"; +//public static final java.lang.String FEATURE_SIP_VOIP = "android.software.sip.voip"; +//public static final java.lang.String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen"; +//public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch"; +//public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct"; +//public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = "android.hardware.touchscreen.multitouch.jazzhand"; +//public static final java.lang.String FEATURE_FAKETOUCH = "android.hardware.faketouch"; +//public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT = "android.hardware.faketouch.multitouch.distinct"; +//public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand"; +//public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait"; +//public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape"; +//public static final java.lang.String FEATURE_LIVE_WALLPAPER = "android.software.live_wallpaper"; +//public static final java.lang.String FEATURE_WIFI = "android.hardware.wifi"; +//public static final java.lang.String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct"; +//public static final java.lang.String FEATURE_TELEVISION = "android.hardware.type.television"; +//public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID"; } diff --git a/src/android/graphics/Bitmap.java b/src/android/graphics/Bitmap.java index 3d640604..d51c7a6d 100644 --- a/src/android/graphics/Bitmap.java +++ b/src/android/graphics/Bitmap.java @@ -1,64 +1,64 @@ package android.graphics; public final class Bitmap - implements android.os.Parcelable + // implements android.os.Parcelable { -public static enum Config -{ -ALPHA_8(), -ARGB_4444(), -ARGB_8888(), -RGB_565(); -} +//public static enum Config +//{ +//ALPHA_8(), +//ARGB_4444(), +//ARGB_8888(), +//RGB_565(); +//} public static enum CompressFormat { JPEG(), PNG(), WEBP(); } -Bitmap() { throw new RuntimeException("Stub!"); } -public int getDensity() { throw new RuntimeException("Stub!"); } -public void setDensity(int density) { throw new RuntimeException("Stub!"); } -public void recycle() { throw new RuntimeException("Stub!"); } -public final boolean isRecycled() { throw new RuntimeException("Stub!"); } -public int getGenerationId() { throw new RuntimeException("Stub!"); } -public void copyPixelsToBuffer(java.nio.Buffer dst) { throw new RuntimeException("Stub!"); } -public void copyPixelsFromBuffer(java.nio.Buffer src) { throw new RuntimeException("Stub!"); } -public android.graphics.Bitmap copy(android.graphics.Bitmap.Config config, boolean isMutable) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap src, int dstWidth, int dstHeight, boolean filter) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap src) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap source, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } +//Bitmap() { throw new RuntimeException("Stub!"); } +//public int getDensity() { throw new RuntimeException("Stub!"); } +//public void setDensity(int density) { throw new RuntimeException("Stub!"); } +//public void recycle() { throw new RuntimeException("Stub!"); } +//public final boolean isRecycled() { throw new RuntimeException("Stub!"); } +//public int getGenerationId() { throw new RuntimeException("Stub!"); } +//public void copyPixelsToBuffer(java.nio.Buffer dst) { throw new RuntimeException("Stub!"); } +//public void copyPixelsFromBuffer(java.nio.Buffer src) { throw new RuntimeException("Stub!"); } +//public android.graphics.Bitmap copy(android.graphics.Bitmap.Config config, boolean isMutable) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap src, int dstWidth, int dstHeight, boolean filter) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap src) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap source, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } //public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap source, int x, int y, int width, int height, android.graphics.Matrix m, boolean filter) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap createBitmap(int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap createBitmap(int[] colors, int offset, int stride, int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap createBitmap(int[] colors, int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } -public byte[] getNinePatchChunk() { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap createBitmap(int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap createBitmap(int[] colors, int offset, int stride, int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap createBitmap(int[] colors, int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } +//public byte[] getNinePatchChunk() { throw new RuntimeException("Stub!"); } public boolean compress(android.graphics.Bitmap.CompressFormat format, int quality, java.io.OutputStream stream) { throw new RuntimeException("Stub!"); } -public final boolean isMutable() { throw new RuntimeException("Stub!"); } -public final int getWidth() { throw new RuntimeException("Stub!"); } -public final int getHeight() { throw new RuntimeException("Stub!"); } +//public final boolean isMutable() { throw new RuntimeException("Stub!"); } +//public final int getWidth() { throw new RuntimeException("Stub!"); } +//public final int getHeight() { throw new RuntimeException("Stub!"); } //public int getScaledWidth(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } //public int getScaledHeight(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } //public int getScaledWidth(android.util.DisplayMetrics metrics) { throw new RuntimeException("Stub!"); } //public int getScaledHeight(android.util.DisplayMetrics metrics) { throw new RuntimeException("Stub!"); } -public int getScaledWidth(int targetDensity) { throw new RuntimeException("Stub!"); } -public int getScaledHeight(int targetDensity) { throw new RuntimeException("Stub!"); } -public final int getRowBytes() { throw new RuntimeException("Stub!"); } -public final int getByteCount() { throw new RuntimeException("Stub!"); } -public final android.graphics.Bitmap.Config getConfig() { throw new RuntimeException("Stub!"); } -public final boolean hasAlpha() { throw new RuntimeException("Stub!"); } -public void setHasAlpha(boolean hasAlpha) { throw new RuntimeException("Stub!"); } -public void eraseColor(int c) { throw new RuntimeException("Stub!"); } -public int getPixel(int x, int y) { throw new RuntimeException("Stub!"); } -public void getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } -public void setPixel(int x, int y, int color) { throw new RuntimeException("Stub!"); } -public void setPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } -public int describeContents() { throw new RuntimeException("Stub!"); } +//public int getScaledWidth(int targetDensity) { throw new RuntimeException("Stub!"); } +//public int getScaledHeight(int targetDensity) { throw new RuntimeException("Stub!"); } +//public final int getRowBytes() { throw new RuntimeException("Stub!"); } +//public final int getByteCount() { throw new RuntimeException("Stub!"); } +//public final android.graphics.Bitmap.Config getConfig() { throw new RuntimeException("Stub!"); } +//public final boolean hasAlpha() { throw new RuntimeException("Stub!"); } +//public void setHasAlpha(boolean hasAlpha) { throw new RuntimeException("Stub!"); } +//public void eraseColor(int c) { throw new RuntimeException("Stub!"); } +//public int getPixel(int x, int y) { throw new RuntimeException("Stub!"); } +//public void getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } +//public void setPixel(int x, int y, int color) { throw new RuntimeException("Stub!"); } +//public void setPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } +//public int describeContents() { throw new RuntimeException("Stub!"); } //public void writeToParcel(android.os.Parcel p, int flags) { throw new RuntimeException("Stub!"); } -public android.graphics.Bitmap extractAlpha() { throw new RuntimeException("Stub!"); } +//public android.graphics.Bitmap extractAlpha() { throw new RuntimeException("Stub!"); } //public android.graphics.Bitmap extractAlpha(android.graphics.Paint paint, int[] offsetXY) { throw new RuntimeException("Stub!"); } -public boolean sameAs(android.graphics.Bitmap other) { throw new RuntimeException("Stub!"); } -public void prepareToDraw() { throw new RuntimeException("Stub!"); } -public static final int DENSITY_NONE = 0; -public static final android.os.Parcelable.Creator<android.graphics.Bitmap> CREATOR; -static { CREATOR = null; } +//public boolean sameAs(android.graphics.Bitmap other) { throw new RuntimeException("Stub!"); } +//public void prepareToDraw() { throw new RuntimeException("Stub!"); } +//public static final int DENSITY_NONE = 0; +//public static final android.os.Parcelable.Creator<android.graphics.Bitmap> CREATOR; +//static { CREATOR = null; } } diff --git a/src/android/graphics/BitmapFactory.java b/src/android/graphics/BitmapFactory.java index 460eb90a..a3be8d59 100644 --- a/src/android/graphics/BitmapFactory.java +++ b/src/android/graphics/BitmapFactory.java @@ -1,40 +1,40 @@ package android.graphics; public class BitmapFactory { -public static class Options -{ -public Options() { throw new RuntimeException("Stub!"); } -public void requestCancelDecode() { throw new RuntimeException("Stub!"); } -public android.graphics.Bitmap inBitmap; -@java.lang.SuppressWarnings(value={"UnusedDeclaration"}) -public boolean inMutable; -public boolean inJustDecodeBounds; -public int inSampleSize; -public android.graphics.Bitmap.Config inPreferredConfig; -public boolean inDither; -public int inDensity; -public int inTargetDensity; -public int inScreenDensity; -public boolean inScaled; -public boolean inPurgeable; -public boolean inInputShareable; -public boolean inPreferQualityOverSpeed; -public int outWidth; -public int outHeight; -public java.lang.String outMimeType; -public byte[] inTempStorage = null; -public boolean mCancel; -} -public BitmapFactory() { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap decodeFile(java.lang.String pathName, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap decodeFile(java.lang.String pathName) { throw new RuntimeException("Stub!"); } +//public static class Options +//{ +//public Options() { throw new RuntimeException("Stub!"); } +//public void requestCancelDecode() { throw new RuntimeException("Stub!"); } +//public android.graphics.Bitmap inBitmap; +//@java.lang.SuppressWarnings(value={"UnusedDeclaration"}) +//public boolean inMutable; +//public boolean inJustDecodeBounds; +//public int inSampleSize; +//public android.graphics.Bitmap.Config inPreferredConfig; +//public boolean inDither; +//public int inDensity; +//public int inTargetDensity; +//public int inScreenDensity; +//public boolean inScaled; +//public boolean inPurgeable; +//public boolean inInputShareable; +//public boolean inPreferQualityOverSpeed; +//public int outWidth; +//public int outHeight; +//public java.lang.String outMimeType; +//public byte[] inTempStorage = null; +//public boolean mCancel; +//} +//public BitmapFactory() { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeFile(java.lang.String pathName, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeFile(java.lang.String pathName) { throw new RuntimeException("Stub!"); } //public static android.graphics.Bitmap decodeResourceStream(android.content.res.Resources res, android.util.TypedValue value, java.io.InputStream is, android.graphics.Rect pad, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } //public static android.graphics.Bitmap decodeResource(android.content.res.Resources res, int id, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } //public static android.graphics.Bitmap decodeResource(android.content.res.Resources res, int id) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap decodeByteArray(byte[] data, int offset, int length, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap decodeByteArray(byte[] data, int offset, int length) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeByteArray(byte[] data, int offset, int length, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeByteArray(byte[] data, int offset, int length) { throw new RuntimeException("Stub!"); } //public static android.graphics.Bitmap decodeStream(java.io.InputStream is, android.graphics.Rect outPadding, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } public static android.graphics.Bitmap decodeStream(java.io.InputStream is) { throw new RuntimeException("Stub!"); } //public static android.graphics.Bitmap decodeFileDescriptor(java.io.FileDescriptor fd, android.graphics.Rect outPadding, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap decodeFileDescriptor(java.io.FileDescriptor fd) { throw new RuntimeException("Stub!"); } +//public static android.graphics.Bitmap decodeFileDescriptor(java.io.FileDescriptor fd) { throw new RuntimeException("Stub!"); } } diff --git a/src/android/graphics/PointF.java b/src/android/graphics/PointF.java index f0ff4051..11a73de1 100644 --- a/src/android/graphics/PointF.java +++ b/src/android/graphics/PointF.java @@ -1,22 +1,25 @@ package android.graphics; public class PointF - implements android.os.Parcelable +// implements android.os.Parcelable { -public PointF() { throw new RuntimeException("Stub!"); } -public PointF(float x, float y) { throw new RuntimeException("Stub!"); } -//public PointF(android.graphics.Point p) { throw new RuntimeException("Stub!"); } -public final void set(float x, float y) { throw new RuntimeException("Stub!"); } -public final void set(android.graphics.PointF p) { throw new RuntimeException("Stub!"); } -public final void negate() { throw new RuntimeException("Stub!"); } -public final void offset(float dx, float dy) { throw new RuntimeException("Stub!"); } -public final boolean equals(float x, float y) { throw new RuntimeException("Stub!"); } -public final float length() { throw new RuntimeException("Stub!"); } -public static float length(float x, float y) { throw new RuntimeException("Stub!"); } -public int describeContents() { throw new RuntimeException("Stub!"); } +//public PointF() { throw new RuntimeException("Stub!"); } +public PointF(float x, float y) { + this.x = x; + this.y = y; +} +////public PointF(android.graphics.Point p) { throw new RuntimeException("Stub!"); } +//public final void set(float x, float y) { throw new RuntimeException("Stub!"); } +//public final void set(android.graphics.PointF p) { throw new RuntimeException("Stub!"); } +//public final void negate() { throw new RuntimeException("Stub!"); } +//public final void offset(float dx, float dy) { throw new RuntimeException("Stub!"); } +//public final boolean equals(float x, float y) { throw new RuntimeException("Stub!"); } +//public final float length() { throw new RuntimeException("Stub!"); } +//public static float length(float x, float y) { throw new RuntimeException("Stub!"); } +//public int describeContents() { throw new RuntimeException("Stub!"); } //public void writeToParcel(android.os.Parcel out, int flags) { throw new RuntimeException("Stub!"); } //public void readFromParcel(android.os.Parcel in) { throw new RuntimeException("Stub!"); } public float x; public float y; -public static final android.os.Parcelable.Creator<android.graphics.PointF> CREATOR; -static { CREATOR = null; } +//public static final android.os.Parcelable.Creator<android.graphics.PointF> CREATOR; +//static { CREATOR = null; } } diff --git a/src/android/graphics/drawable/BitmapDrawable.java b/src/android/graphics/drawable/BitmapDrawable.java index 25c6a69c..3d89963c 100644 --- a/src/android/graphics/drawable/BitmapDrawable.java +++ b/src/android/graphics/drawable/BitmapDrawable.java @@ -2,45 +2,45 @@ public class BitmapDrawable extends android.graphics.drawable.Drawable { -@java.lang.Deprecated() -public BitmapDrawable() { throw new RuntimeException("Stub!"); } -@java.lang.SuppressWarnings(value={"UnusedParameters"}) +//@java.lang.Deprecated() +//public BitmapDrawable() { throw new RuntimeException("Stub!"); } +//@java.lang.SuppressWarnings(value={"UnusedParameters"}) //public BitmapDrawable(android.content.res.Resources res) { throw new RuntimeException("Stub!"); } -@java.lang.Deprecated() -public BitmapDrawable(android.graphics.Bitmap bitmap) { throw new RuntimeException("Stub!"); } +//@java.lang.Deprecated() +//public BitmapDrawable(android.graphics.Bitmap bitmap) { throw new RuntimeException("Stub!"); } //public BitmapDrawable(android.content.res.Resources res, android.graphics.Bitmap bitmap) { throw new RuntimeException("Stub!"); } -@java.lang.Deprecated() -public BitmapDrawable(java.lang.String filepath) { throw new RuntimeException("Stub!"); } -@java.lang.SuppressWarnings(value={"UnusedParameters"}) +//@java.lang.Deprecated() +//public BitmapDrawable(java.lang.String filepath) { throw new RuntimeException("Stub!"); } +//@java.lang.SuppressWarnings(value={"UnusedParameters"}) //public BitmapDrawable(android.content.res.Resources res, java.lang.String filepath) { throw new RuntimeException("Stub!"); } -@java.lang.Deprecated() -public BitmapDrawable(java.io.InputStream is) { throw new RuntimeException("Stub!"); } -@java.lang.SuppressWarnings(value={"UnusedParameters"}) +//@java.lang.Deprecated() +//public BitmapDrawable(java.io.InputStream is) { throw new RuntimeException("Stub!"); } +//@java.lang.SuppressWarnings(value={"UnusedParameters"}) //public BitmapDrawable(android.content.res.Resources res, java.io.InputStream is) { throw new RuntimeException("Stub!"); } //public final android.graphics.Paint getPaint() { throw new RuntimeException("Stub!"); } public final android.graphics.Bitmap getBitmap() { throw new RuntimeException("Stub!"); } //public void setTargetDensity(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } //public void setTargetDensity(android.util.DisplayMetrics metrics) { throw new RuntimeException("Stub!"); } -public void setTargetDensity(int density) { throw new RuntimeException("Stub!"); } -public int getGravity() { throw new RuntimeException("Stub!"); } -public void setGravity(int gravity) { throw new RuntimeException("Stub!"); } -public void setAntiAlias(boolean aa) { throw new RuntimeException("Stub!"); } -public void setFilterBitmap(boolean filter) { throw new RuntimeException("Stub!"); } -public void setDither(boolean dither) { throw new RuntimeException("Stub!"); } +//public void setTargetDensity(int density) { throw new RuntimeException("Stub!"); } +//public int getGravity() { throw new RuntimeException("Stub!"); } +//public void setGravity(int gravity) { throw new RuntimeException("Stub!"); } +//public void setAntiAlias(boolean aa) { throw new RuntimeException("Stub!"); } +//public void setFilterBitmap(boolean filter) { throw new RuntimeException("Stub!"); } +//public void setDither(boolean dither) { throw new RuntimeException("Stub!"); } //public android.graphics.Shader.TileMode getTileModeX() { throw new RuntimeException("Stub!"); } //public android.graphics.Shader.TileMode getTileModeY() { throw new RuntimeException("Stub!"); } //public void setTileModeX(android.graphics.Shader.TileMode mode) { throw new RuntimeException("Stub!"); } //public final void setTileModeY(android.graphics.Shader.TileMode mode) { throw new RuntimeException("Stub!"); } //public void setTileModeXY(android.graphics.Shader.TileMode xmode, android.graphics.Shader.TileMode ymode) { throw new RuntimeException("Stub!"); } -public int getChangingConfigurations() { throw new RuntimeException("Stub!"); } +//public int getChangingConfigurations() { throw new RuntimeException("Stub!"); } //protected void onBoundsChange(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } //public void draw(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } -public void setAlpha(int alpha) { throw new RuntimeException("Stub!"); } +//public void setAlpha(int alpha) { throw new RuntimeException("Stub!"); } //public void setColorFilter(android.graphics.ColorFilter cf) { throw new RuntimeException("Stub!"); } -public android.graphics.drawable.Drawable mutate() { throw new RuntimeException("Stub!"); } +//public android.graphics.drawable.Drawable mutate() { throw new RuntimeException("Stub!"); } //public void inflate(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } -public int getIntrinsicWidth() { throw new RuntimeException("Stub!"); } -public int getIntrinsicHeight() { throw new RuntimeException("Stub!"); } -public int getOpacity() { throw new RuntimeException("Stub!"); } -public final android.graphics.drawable.Drawable.ConstantState getConstantState() { throw new RuntimeException("Stub!"); } +//public int getIntrinsicWidth() { throw new RuntimeException("Stub!"); } +//public int getIntrinsicHeight() { throw new RuntimeException("Stub!"); } +//public int getOpacity() { throw new RuntimeException("Stub!"); } +//public final android.graphics.drawable.Drawable.ConstantState getConstantState() { throw new RuntimeException("Stub!"); } } diff --git a/src/android/graphics/drawable/Drawable.java b/src/android/graphics/drawable/Drawable.java index 2710ce2a..be8d99a4 100644 --- a/src/android/graphics/drawable/Drawable.java +++ b/src/android/graphics/drawable/Drawable.java @@ -1,66 +1,66 @@ package android.graphics.drawable; public abstract class Drawable { -public static interface Callback -{ -public abstract void invalidateDrawable(android.graphics.drawable.Drawable who); -public abstract void scheduleDrawable(android.graphics.drawable.Drawable who, java.lang.Runnable what, long when); -public abstract void unscheduleDrawable(android.graphics.drawable.Drawable who, java.lang.Runnable what); -} -public abstract static class ConstantState -{ -public ConstantState() { throw new RuntimeException("Stub!"); } -public abstract android.graphics.drawable.Drawable newDrawable(); +//public static interface Callback +//{ +//public abstract void invalidateDrawable(android.graphics.drawable.Drawable who); +//public abstract void scheduleDrawable(android.graphics.drawable.Drawable who, java.lang.Runnable what, long when); +//public abstract void unscheduleDrawable(android.graphics.drawable.Drawable who, java.lang.Runnable what); +//} +//public abstract static class ConstantState +//{ +//public ConstantState() { throw new RuntimeException("Stub!"); } +//public abstract android.graphics.drawable.Drawable newDrawable(); //public android.graphics.drawable.Drawable newDrawable(android.content.res.Resources res) { throw new RuntimeException("Stub!"); } -public abstract int getChangingConfigurations(); -} -public Drawable() { throw new RuntimeException("Stub!"); } +//public abstract int getChangingConfigurations(); +//} +//public Drawable() { throw new RuntimeException("Stub!"); } //public abstract void draw(android.graphics.Canvas canvas); -public void setBounds(int left, int top, int right, int bottom) { throw new RuntimeException("Stub!"); } +//public void setBounds(int left, int top, int right, int bottom) { throw new RuntimeException("Stub!"); } //public void setBounds(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } //public final void copyBounds(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } //public final android.graphics.Rect copyBounds() { throw new RuntimeException("Stub!"); } //public final android.graphics.Rect getBounds() { throw new RuntimeException("Stub!"); } -public void setChangingConfigurations(int configs) { throw new RuntimeException("Stub!"); } -public int getChangingConfigurations() { throw new RuntimeException("Stub!"); } -public void setDither(boolean dither) { throw new RuntimeException("Stub!"); } -public void setFilterBitmap(boolean filter) { throw new RuntimeException("Stub!"); } -public final void setCallback(android.graphics.drawable.Drawable.Callback cb) { throw new RuntimeException("Stub!"); } -public android.graphics.drawable.Drawable.Callback getCallback() { throw new RuntimeException("Stub!"); } -public void invalidateSelf() { throw new RuntimeException("Stub!"); } -public void scheduleSelf(java.lang.Runnable what, long when) { throw new RuntimeException("Stub!"); } -public void unscheduleSelf(java.lang.Runnable what) { throw new RuntimeException("Stub!"); } -public abstract void setAlpha(int alpha); +//public void setChangingConfigurations(int configs) { throw new RuntimeException("Stub!"); } +//public int getChangingConfigurations() { throw new RuntimeException("Stub!"); } +//public void setDither(boolean dither) { throw new RuntimeException("Stub!"); } +//public void setFilterBitmap(boolean filter) { throw new RuntimeException("Stub!"); } +//public final void setCallback(android.graphics.drawable.Drawable.Callback cb) { throw new RuntimeException("Stub!"); } +//public android.graphics.drawable.Drawable.Callback getCallback() { throw new RuntimeException("Stub!"); } +//public void invalidateSelf() { throw new RuntimeException("Stub!"); } +//public void scheduleSelf(java.lang.Runnable what, long when) { throw new RuntimeException("Stub!"); } +//public void unscheduleSelf(java.lang.Runnable what) { throw new RuntimeException("Stub!"); } +//public abstract void setAlpha(int alpha); //public abstract void setColorFilter(android.graphics.ColorFilter cf); //public void setColorFilter(int color, android.graphics.PorterDuff.Mode mode) { throw new RuntimeException("Stub!"); } -public void clearColorFilter() { throw new RuntimeException("Stub!"); } -public boolean isStateful() { throw new RuntimeException("Stub!"); } -public boolean setState(int[] stateSet) { throw new RuntimeException("Stub!"); } -public int[] getState() { throw new RuntimeException("Stub!"); } -public void jumpToCurrentState() { throw new RuntimeException("Stub!"); } -public android.graphics.drawable.Drawable getCurrent() { throw new RuntimeException("Stub!"); } -public final boolean setLevel(int level) { throw new RuntimeException("Stub!"); } -public final int getLevel() { throw new RuntimeException("Stub!"); } -public boolean setVisible(boolean visible, boolean restart) { throw new RuntimeException("Stub!"); } -public final boolean isVisible() { throw new RuntimeException("Stub!"); } -public abstract int getOpacity(); -public static int resolveOpacity(int op1, int op2) { throw new RuntimeException("Stub!"); } +//public void clearColorFilter() { throw new RuntimeException("Stub!"); } +//public boolean isStateful() { throw new RuntimeException("Stub!"); } +//public boolean setState(int[] stateSet) { throw new RuntimeException("Stub!"); } +//public int[] getState() { throw new RuntimeException("Stub!"); } +//public void jumpToCurrentState() { throw new RuntimeException("Stub!"); } +//public android.graphics.drawable.Drawable getCurrent() { throw new RuntimeException("Stub!"); } +//public final boolean setLevel(int level) { throw new RuntimeException("Stub!"); } +//public final int getLevel() { throw new RuntimeException("Stub!"); } +//public boolean setVisible(boolean visible, boolean restart) { throw new RuntimeException("Stub!"); } +//public final boolean isVisible() { throw new RuntimeException("Stub!"); } +//public abstract int getOpacity(); +//public static int resolveOpacity(int op1, int op2) { throw new RuntimeException("Stub!"); } //public android.graphics.Region getTransparentRegion() { throw new RuntimeException("Stub!"); } -protected boolean onStateChange(int[] state) { throw new RuntimeException("Stub!"); } -protected boolean onLevelChange(int level) { throw new RuntimeException("Stub!"); } +//protected boolean onStateChange(int[] state) { throw new RuntimeException("Stub!"); } +//protected boolean onLevelChange(int level) { throw new RuntimeException("Stub!"); } //protected void onBoundsChange(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } -public int getIntrinsicWidth() { throw new RuntimeException("Stub!"); } -public int getIntrinsicHeight() { throw new RuntimeException("Stub!"); } -public int getMinimumWidth() { throw new RuntimeException("Stub!"); } -public int getMinimumHeight() { throw new RuntimeException("Stub!"); } +//public int getIntrinsicWidth() { throw new RuntimeException("Stub!"); } +//public int getIntrinsicHeight() { throw new RuntimeException("Stub!"); } +//public int getMinimumWidth() { throw new RuntimeException("Stub!"); } +//public int getMinimumHeight() { throw new RuntimeException("Stub!"); } //public boolean getPadding(android.graphics.Rect padding) { throw new RuntimeException("Stub!"); } -public android.graphics.drawable.Drawable mutate() { throw new RuntimeException("Stub!"); } -public static android.graphics.drawable.Drawable createFromStream(java.io.InputStream is, java.lang.String srcName) { throw new RuntimeException("Stub!"); } +//public android.graphics.drawable.Drawable mutate() { throw new RuntimeException("Stub!"); } +//public static android.graphics.drawable.Drawable createFromStream(java.io.InputStream is, java.lang.String srcName) { throw new RuntimeException("Stub!"); } //public static android.graphics.drawable.Drawable createFromResourceStream(android.content.res.Resources res, android.util.TypedValue value, java.io.InputStream is, java.lang.String srcName) { throw new RuntimeException("Stub!"); } //public static android.graphics.drawable.Drawable createFromResourceStream(android.content.res.Resources res, android.util.TypedValue value, java.io.InputStream is, java.lang.String srcName, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } //public static android.graphics.drawable.Drawable createFromXml(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } //public static android.graphics.drawable.Drawable createFromXmlInner(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } //public static android.graphics.drawable.Drawable createFromPath(java.lang.String pathName) { throw new RuntimeException("Stub!"); } //public void inflate(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } -public android.graphics.drawable.Drawable.ConstantState getConstantState() { throw new RuntimeException("Stub!"); } +//public android.graphics.drawable.Drawable.ConstantState getConstantState() { throw new RuntimeException("Stub!"); } } diff --git a/src/android/net/ConnectivityManager.java b/src/android/net/ConnectivityManager.java index 38cf8b2f..32d4d69b 100644 --- a/src/android/net/ConnectivityManager.java +++ b/src/android/net/ConnectivityManager.java @@ -2,37 +2,37 @@ public class ConnectivityManager { public ConnectivityManager() { /*throw new RuntimeException("Stub!");*/ } -public static boolean isNetworkTypeValid(int networkType) { throw new RuntimeException("Stub!"); } -public void setNetworkPreference(int preference) { throw new RuntimeException("Stub!"); } -public int getNetworkPreference() { throw new RuntimeException("Stub!"); } -public android.net.NetworkInfo getActiveNetworkInfo() { throw new RuntimeException("Stub!"); } +//public static boolean isNetworkTypeValid(int networkType) { throw new RuntimeException("Stub!"); } +//public void setNetworkPreference(int preference) { throw new RuntimeException("Stub!"); } +//public int getNetworkPreference() { throw new RuntimeException("Stub!"); } +//public android.net.NetworkInfo getActiveNetworkInfo() { throw new RuntimeException("Stub!"); } public android.net.NetworkInfo getNetworkInfo(int networkType) { return new NetworkInfo();/*throw new RuntimeException("Stub!");*/ } -public android.net.NetworkInfo[] getAllNetworkInfo() { throw new RuntimeException("Stub!"); } -public int startUsingNetworkFeature(int networkType, java.lang.String feature) { throw new RuntimeException("Stub!"); } -public int stopUsingNetworkFeature(int networkType, java.lang.String feature) { throw new RuntimeException("Stub!"); } -public boolean requestRouteToHost(int networkType, int hostAddress) { throw new RuntimeException("Stub!"); } -@java.lang.Deprecated() -public boolean getBackgroundDataSetting() { throw new RuntimeException("Stub!"); } -public boolean isActiveNetworkMetered() { throw new RuntimeException("Stub!"); } -public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; -@java.lang.Deprecated() -public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; -public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover"; -public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork"; -public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity"; -public static final java.lang.String EXTRA_REASON = "reason"; -public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo"; -@java.lang.Deprecated() -public static final java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; -public static final int TYPE_MOBILE = 0; +//public android.net.NetworkInfo[] getAllNetworkInfo() { throw new RuntimeException("Stub!"); } +//public int startUsingNetworkFeature(int networkType, java.lang.String feature) { throw new RuntimeException("Stub!"); } +//public int stopUsingNetworkFeature(int networkType, java.lang.String feature) { throw new RuntimeException("Stub!"); } +//public boolean requestRouteToHost(int networkType, int hostAddress) { throw new RuntimeException("Stub!"); } +//@java.lang.Deprecated() +//public boolean getBackgroundDataSetting() { throw new RuntimeException("Stub!"); } +//public boolean isActiveNetworkMetered() { throw new RuntimeException("Stub!"); } +//public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; +//@java.lang.Deprecated() +//public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; +//public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover"; +//public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork"; +//public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity"; +//public static final java.lang.String EXTRA_REASON = "reason"; +//public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo"; +//@java.lang.Deprecated() +//public static final java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; +//public static final int TYPE_MOBILE = 0; public static final int TYPE_WIFI = 1; -public static final int TYPE_MOBILE_MMS = 2; -public static final int TYPE_MOBILE_SUPL = 3; -public static final int TYPE_MOBILE_DUN = 4; -public static final int TYPE_MOBILE_HIPRI = 5; -public static final int TYPE_WIMAX = 6; -public static final int TYPE_BLUETOOTH = 7; -public static final int TYPE_DUMMY = 8; -public static final int TYPE_ETHERNET = 9; -public static final int DEFAULT_NETWORK_PREFERENCE = 1; +//public static final int TYPE_MOBILE_MMS = 2; +//public static final int TYPE_MOBILE_SUPL = 3; +//public static final int TYPE_MOBILE_DUN = 4; +//public static final int TYPE_MOBILE_HIPRI = 5; +//public static final int TYPE_WIMAX = 6; +//public static final int TYPE_BLUETOOTH = 7; +//public static final int TYPE_DUMMY = 8; +//public static final int TYPE_ETHERNET = 9; +//public static final int DEFAULT_NETWORK_PREFERENCE = 1; } diff --git a/src/android/net/NetworkInfo.java b/src/android/net/NetworkInfo.java index 50e0fbe8..990f3b84 100644 --- a/src/android/net/NetworkInfo.java +++ b/src/android/net/NetworkInfo.java @@ -11,36 +11,36 @@ public static enum State SUSPENDED(), UNKNOWN(); } -public static enum DetailedState -{ -AUTHENTICATING(), -BLOCKED(), -CONNECTED(), -CONNECTING(), -DISCONNECTED(), -DISCONNECTING(), -FAILED(), -IDLE(), -OBTAINING_IPADDR(), -SCANNING(), -SUSPENDED(), -VERIFYING_POOR_LINK(); -} +//public static enum DetailedState +//{ +//AUTHENTICATING(), +//BLOCKED(), +//CONNECTED(), +//CONNECTING(), +//DISCONNECTED(), +//DISCONNECTING(), +//FAILED(), +//IDLE(), +//OBTAINING_IPADDR(), +//SCANNING(), +//SUSPENDED(), +//VERIFYING_POOR_LINK(); +//} NetworkInfo() { /* throw new RuntimeException("Stub!"); */} -public int getType() { throw new RuntimeException("Stub!"); } -public int getSubtype() { throw new RuntimeException("Stub!"); } -public java.lang.String getTypeName() { throw new RuntimeException("Stub!"); } -public java.lang.String getSubtypeName() { throw new RuntimeException("Stub!"); } -public boolean isConnectedOrConnecting() { throw new RuntimeException("Stub!"); } +//public int getType() { throw new RuntimeException("Stub!"); } +//public int getSubtype() { throw new RuntimeException("Stub!"); } +//public java.lang.String getTypeName() { throw new RuntimeException("Stub!"); } +//public java.lang.String getSubtypeName() { throw new RuntimeException("Stub!"); } +//public boolean isConnectedOrConnecting() { throw new RuntimeException("Stub!"); } public boolean isConnected() { return true; /*throw new RuntimeException("Stub!");*/ } -public boolean isAvailable() { throw new RuntimeException("Stub!"); } -public boolean isFailover() { throw new RuntimeException("Stub!"); } -public boolean isRoaming() { throw new RuntimeException("Stub!"); } +//public boolean isAvailable() { throw new RuntimeException("Stub!"); } +//public boolean isFailover() { throw new RuntimeException("Stub!"); } +//public boolean isRoaming() { throw new RuntimeException("Stub!"); } public android.net.NetworkInfo.State getState() { throw new RuntimeException("Stub!"); } -public android.net.NetworkInfo.DetailedState getDetailedState() { throw new RuntimeException("Stub!"); } -public java.lang.String getReason() { throw new RuntimeException("Stub!"); } -public java.lang.String getExtraInfo() { throw new RuntimeException("Stub!"); } -public java.lang.String toString() { throw new RuntimeException("Stub!"); } -public int describeContents() { throw new RuntimeException("Stub!"); } +//public android.net.NetworkInfo.DetailedState getDetailedState() { throw new RuntimeException("Stub!"); } +//public java.lang.String getReason() { throw new RuntimeException("Stub!"); } +//public java.lang.String getExtraInfo() { throw new RuntimeException("Stub!"); } +//public java.lang.String toString() { throw new RuntimeException("Stub!"); } +//public int describeContents() { throw new RuntimeException("Stub!"); } //public void writeToParcel(android.os.Parcel dest, int flags) { throw new RuntimeException("Stub!"); } } diff --git a/src/android/net/wifi/WifiManager.java b/src/android/net/wifi/WifiManager.java index f250f92d..b7e1b275 100644 --- a/src/android/net/wifi/WifiManager.java +++ b/src/android/net/wifi/WifiManager.java @@ -2,40 +2,40 @@ public class WifiManager { - public class WifiLock { - WifiLock() { - throw new RuntimeException("Stub!"); - } - - public void acquire() { - throw new RuntimeException("Stub!"); - } - - public void release() { - throw new RuntimeException("Stub!"); - } - - public void setReferenceCounted(boolean refCounted) { - throw new RuntimeException("Stub!"); - } - - public boolean isHeld() { - throw new RuntimeException("Stub!"); - } - - // public void setWorkSource(android.os.WorkSource ws) { throw new RuntimeException("Stub!"); } - @Override - public java.lang.String toString() { - throw new RuntimeException("Stub!"); - } - - @Override - protected void finalize() throws java.lang.Throwable { - throw new RuntimeException("Stub!"); - } - } - - public class MulticastLock { +// public class WifiLock { +// WifiLock() { +// throw new RuntimeException("Stub!"); +// } +// +// public void acquire() { +// throw new RuntimeException("Stub!"); +// } +// +// public void release() { +// throw new RuntimeException("Stub!"); +// } +// +// public void setReferenceCounted(boolean refCounted) { +// throw new RuntimeException("Stub!"); +// } +// +// public boolean isHeld() { +// throw new RuntimeException("Stub!"); +// } +// +// // public void setWorkSource(android.os.WorkSource ws) { throw new RuntimeException("Stub!"); } +// @Override +// public java.lang.String toString() { +// throw new RuntimeException("Stub!"); +// } +// +// @Override +// protected void finalize() throws java.lang.Throwable { +// throw new RuntimeException("Stub!"); +// } +// } + + public class MulticastLock { // multicast lock is used on android to save power. not required on a server MulticastLock() { /* throw new RuntimeException("Stub!"); */ } @@ -50,15 +50,6 @@ public void setReferenceCounted(boolean refCounted) { public boolean isHeld() { return true; - /* throw new RuntimeException("Stub!"); */ } - - @Override - public java.lang.String toString() { - return super.toString(); - } - - @Override - protected void finalize() throws java.lang.Throwable { } } @@ -69,36 +60,35 @@ public WifiManager() { // RuntimeException("Stub!"); } // public int addNetwork(android.net.wifi.WifiConfiguration config) { throw new RuntimeException("Stub!"); } // public int updateNetwork(android.net.wifi.WifiConfiguration config) { throw new RuntimeException("Stub!"); } - public boolean removeNetwork(int netId) { - throw new RuntimeException("Stub!"); - } - - public boolean enableNetwork(int netId, boolean disableOthers) { - throw new RuntimeException("Stub!"); - } - - public boolean disableNetwork(int netId) { - throw new RuntimeException("Stub!"); - } - - public boolean disconnect() { - throw new RuntimeException("Stub!"); - } - - public boolean reconnect() { - throw new RuntimeException("Stub!"); - } - - public boolean reassociate() { - throw new RuntimeException("Stub!"); - } - - public boolean pingSupplicant() { - throw new RuntimeException("Stub!"); - } - - public boolean startScan() { - throw new RuntimeException("Stub!"); +// public boolean removeNetwork(int netId) { +// throw new RuntimeException("Stub!"); +// } + +// public boolean enableNetwork(int netId, boolean disableOthers) { +// throw new RuntimeException("Stub!"); +// } +// +// public boolean disableNetwork(int netId) { +// throw new RuntimeException("Stub!"); +// } +// +// public boolean disconnect() { +// throw new RuntimeException("Stub!"); +// } +// +// public boolean reconnect() { +// throw new RuntimeException("Stub!"); +// } +// +// public boolean reassociate() { +// throw new RuntimeException("Stub!"); +// } +// +// public boolean pingSupplicant() { +// throw new RuntimeException("Stub!"); +// } + + public boolean startScan() { return true; } // public android.net.wifi.WifiInfo getConnectionInfo() { @@ -106,67 +96,67 @@ public boolean startScan() { // } // public java.util.List<android.net.wifi.ScanResult> getScanResults() { throw new RuntimeException("Stub!"); } - public boolean saveConfiguration() { - throw new RuntimeException("Stub!"); - } +// public boolean saveConfiguration() { +// throw new RuntimeException("Stub!"); +// } // public android.net.DhcpInfo getDhcpInfo() { throw new RuntimeException("Stub!"); } - public boolean setWifiEnabled(boolean enabled) { - throw new RuntimeException("Stub!"); - } - - public int getWifiState() { - throw new RuntimeException("Stub!"); - } - - public boolean isWifiEnabled() { - throw new RuntimeException("Stub!"); - } - - public static int calculateSignalLevel(int rssi, int numLevels) { - throw new RuntimeException("Stub!"); - } - - public static int compareSignalLevel(int rssiA, int rssiB) { - throw new RuntimeException("Stub!"); - } - - public android.net.wifi.WifiManager.WifiLock createWifiLock(int lockType, java.lang.String tag) { - throw new RuntimeException("Stub!"); - } - - public android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String tag) { - throw new RuntimeException("Stub!"); - } +// public boolean setWifiEnabled(boolean enabled) { +// throw new RuntimeException("Stub!"); +// } +// +// public int getWifiState() { +// throw new RuntimeException("Stub!"); +// } +// +// public boolean isWifiEnabled() { +// throw new RuntimeException("Stub!"); +// } +// +// public static int calculateSignalLevel(int rssi, int numLevels) { +// throw new RuntimeException("Stub!"); +// } +// +// public static int compareSignalLevel(int rssiA, int rssiB) { +// throw new RuntimeException("Stub!"); +// } + +// public android.net.wifi.WifiManager.WifiLock createWifiLock(int lockType, java.lang.String tag) { +// throw new RuntimeException("Stub!"); +// } +// +// public android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String tag) { +// throw new RuntimeException("Stub!"); +// } public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String tag) { - /* throw new RuntimeException("Stub!"); */ return new MulticastLock(); - } - - public static final int ERROR_AUTHENTICATING = 1; - public static final java.lang.String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED"; - public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state"; - public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state"; - public static final int WIFI_STATE_DISABLING = 0; - public static final int WIFI_STATE_DISABLED = 1; - public static final int WIFI_STATE_ENABLING = 2; - public static final int WIFI_STATE_ENABLED = 3; - public static final int WIFI_STATE_UNKNOWN = 4; - public static final java.lang.String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE"; - public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected"; + return new MulticastLock(); + } + +// public static final int ERROR_AUTHENTICATING = 1; +// public static final java.lang.String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED"; +// public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state"; +// public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state"; +// public static final int WIFI_STATE_DISABLING = 0; +// public static final int WIFI_STATE_DISABLED = 1; +// public static final int WIFI_STATE_ENABLING = 2; +// public static final int WIFI_STATE_ENABLED = 3; +// public static final int WIFI_STATE_UNKNOWN = 4; +// public static final java.lang.String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE"; +// public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected"; public static final java.lang.String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE"; public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; - public static final java.lang.String EXTRA_BSSID = "bssid"; - public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo"; - public static final java.lang.String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE"; - public static final java.lang.String EXTRA_NEW_STATE = "newState"; - public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError"; - public static final java.lang.String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS"; - public static final java.lang.String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; - public static final java.lang.String EXTRA_NEW_RSSI = "newRssi"; - public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED"; - public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; - public static final int WIFI_MODE_FULL = 1; - public static final int WIFI_MODE_SCAN_ONLY = 2; - public static final int WIFI_MODE_FULL_HIGH_PERF = 3; +// public static final java.lang.String EXTRA_BSSID = "bssid"; +// public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo"; +// public static final java.lang.String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE"; +// public static final java.lang.String EXTRA_NEW_STATE = "newState"; +// public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError"; +// public static final java.lang.String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS"; +// public static final java.lang.String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; +// public static final java.lang.String EXTRA_NEW_RSSI = "newRssi"; +// public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED"; +// public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; +// public static final int WIFI_MODE_FULL = 1; +// public static final int WIFI_MODE_SCAN_ONLY = 2; +// public static final int WIFI_MODE_FULL_HIGH_PERF = 3; } diff --git a/src/android/os/Build.java b/src/android/os/Build.java index bbef79fe..2b2bba6f 100644 --- a/src/android/os/Build.java +++ b/src/android/os/Build.java @@ -12,50 +12,50 @@ public static class VERSION public static final java.lang.String CODENAME; static { INCREMENTAL = null; RELEASE = null; SDK = null; SDK_INT = 0; CODENAME = null; } } -public static class VERSION_CODES -{ -public VERSION_CODES() { throw new RuntimeException("Stub!"); } -public static final int CUR_DEVELOPMENT = 10000; -public static final int BASE = 1; -public static final int BASE_1_1 = 2; -public static final int CUPCAKE = 3; -public static final int DONUT = 4; -public static final int ECLAIR = 5; -public static final int ECLAIR_0_1 = 6; -public static final int ECLAIR_MR1 = 7; -public static final int FROYO = 8; -public static final int GINGERBREAD = 9; -public static final int GINGERBREAD_MR1 = 10; -public static final int HONEYCOMB = 11; -public static final int HONEYCOMB_MR1 = 12; -public static final int HONEYCOMB_MR2 = 13; -public static final int ICE_CREAM_SANDWICH = 14; -public static final int ICE_CREAM_SANDWICH_MR1 = 15; -public static final int JELLY_BEAN = 16; -} +//public static class VERSION_CODES +//{ +//public VERSION_CODES() { throw new RuntimeException("Stub!"); } +//public static final int CUR_DEVELOPMENT = 10000; +//public static final int BASE = 1; +//public static final int BASE_1_1 = 2; +//public static final int CUPCAKE = 3; +//public static final int DONUT = 4; +//public static final int ECLAIR = 5; +//public static final int ECLAIR_0_1 = 6; +//public static final int ECLAIR_MR1 = 7; +//public static final int FROYO = 8; +//public static final int GINGERBREAD = 9; +//public static final int GINGERBREAD_MR1 = 10; +//public static final int HONEYCOMB = 11; +//public static final int HONEYCOMB_MR1 = 12; +//public static final int HONEYCOMB_MR2 = 13; +//public static final int ICE_CREAM_SANDWICH = 14; +//public static final int ICE_CREAM_SANDWICH_MR1 = 15; +//public static final int JELLY_BEAN = 16; +//} public Build() { throw new RuntimeException("Stub!"); } -public static java.lang.String getRadioVersion() { throw new RuntimeException("Stub!"); } -public static final java.lang.String UNKNOWN = "unknown"; -public static final java.lang.String ID; -public static final java.lang.String DISPLAY; -public static final java.lang.String PRODUCT; -public static final java.lang.String DEVICE; -public static final java.lang.String BOARD; -public static final java.lang.String CPU_ABI; -public static final java.lang.String CPU_ABI2; -public static final java.lang.String MANUFACTURER; -public static final java.lang.String BRAND; -public static final java.lang.String MODEL; -public static final java.lang.String BOOTLOADER; -@java.lang.Deprecated() -public static final java.lang.String RADIO; -public static final java.lang.String HARDWARE; -public static final java.lang.String SERIAL; -public static final java.lang.String TYPE; -public static final java.lang.String TAGS; -public static final java.lang.String FINGERPRINT; -public static final long TIME; -public static final java.lang.String USER; -public static final java.lang.String HOST; -static { ID = null; DISPLAY = null; PRODUCT = null; DEVICE = null; BOARD = null; CPU_ABI = null; CPU_ABI2 = null; MANUFACTURER = null; BRAND = null; MODEL = null; BOOTLOADER = null; RADIO = null; HARDWARE = null; SERIAL = null; TYPE = null; TAGS = null; FINGERPRINT = null; TIME = 0; USER = null; HOST = null; } +//public static java.lang.String getRadioVersion() { throw new RuntimeException("Stub!"); } +//public static final java.lang.String UNKNOWN = "unknown"; +//public static final java.lang.String ID; +//public static final java.lang.String DISPLAY; +//public static final java.lang.String PRODUCT; +//public static final java.lang.String DEVICE; +//public static final java.lang.String BOARD; +//public static final java.lang.String CPU_ABI; +//public static final java.lang.String CPU_ABI2; +//public static final java.lang.String MANUFACTURER; +//public static final java.lang.String BRAND; +public static final java.lang.String MODEL =null; +//public static final java.lang.String BOOTLOADER; +//@java.lang.Deprecated() +//public static final java.lang.String RADIO; +//public static final java.lang.String HARDWARE; +//public static final java.lang.String SERIAL; +//public static final java.lang.String TYPE; +//public static final java.lang.String TAGS; +//public static final java.lang.String FINGERPRINT; +//public static final long TIME; +//public static final java.lang.String USER; +//public static final java.lang.String HOST; +//static { ID = null; DISPLAY = null; PRODUCT = null; DEVICE = null; BOARD = null; CPU_ABI = null; CPU_ABI2 = null; MANUFACTURER = null; BRAND = null; MODEL = null; BOOTLOADER = null; RADIO = null; HARDWARE = null; SERIAL = null; TYPE = null; TAGS = null; FINGERPRINT = null; TIME = 0; USER = null; HOST = null; } } diff --git a/src/android/os/Environment.java b/src/android/os/Environment.java index 2848a0c5..faf2fd8a 100644 --- a/src/android/os/Environment.java +++ b/src/android/os/Environment.java @@ -19,31 +19,30 @@ public class Environment } tempDir = dir; } -public Environment() { } -public static java.io.File getRootDirectory() { throw new RuntimeException("Stub!"); } -public static java.io.File getDataDirectory() { throw new RuntimeException("Stub!"); } +//public static java.io.File getRootDirectory() { throw new RuntimeException("Stub!"); } +//public static java.io.File getDataDirectory() { throw new RuntimeException("Stub!"); } public static java.io.File getExternalStorageDirectory() { return tempDir; } -public static java.io.File getExternalStoragePublicDirectory(java.lang.String type) { throw new RuntimeException("Stub!"); } -public static java.io.File getDownloadCacheDirectory() { throw new RuntimeException("Stub!"); } +//public static java.io.File getExternalStoragePublicDirectory(java.lang.String type) { throw new RuntimeException("Stub!"); } +//public static java.io.File getDownloadCacheDirectory() { throw new RuntimeException("Stub!"); } public static java.lang.String getExternalStorageState() { return Environment.MEDIA_MOUNTED; /*throw new RuntimeException("Stub!");*/ } -public static boolean isExternalStorageRemovable() { throw new RuntimeException("Stub!"); } -public static boolean isExternalStorageEmulated() { throw new RuntimeException("Stub!"); } -public static java.lang.String DIRECTORY_MUSIC; -public static java.lang.String DIRECTORY_PODCASTS; -public static java.lang.String DIRECTORY_RINGTONES; -public static java.lang.String DIRECTORY_ALARMS; -public static java.lang.String DIRECTORY_NOTIFICATIONS; -public static java.lang.String DIRECTORY_PICTURES; -public static java.lang.String DIRECTORY_MOVIES; -public static java.lang.String DIRECTORY_DOWNLOADS; -public static java.lang.String DIRECTORY_DCIM; -public static final java.lang.String MEDIA_REMOVED = "removed"; +//public static boolean isExternalStorageRemovable() { throw new RuntimeException("Stub!"); } +//public static boolean isExternalStorageEmulated() { throw new RuntimeException("Stub!"); } +//public static java.lang.String DIRECTORY_MUSIC; +//public static java.lang.String DIRECTORY_PODCASTS; +//public static java.lang.String DIRECTORY_RINGTONES; +//public static java.lang.String DIRECTORY_ALARMS; +//public static java.lang.String DIRECTORY_NOTIFICATIONS; +//public static java.lang.String DIRECTORY_PICTURES; +//public static java.lang.String DIRECTORY_MOVIES; +//public static java.lang.String DIRECTORY_DOWNLOADS; +//public static java.lang.String DIRECTORY_DCIM; +//public static final java.lang.String MEDIA_REMOVED = "removed"; public static final java.lang.String MEDIA_UNMOUNTED = "unmounted"; -public static final java.lang.String MEDIA_CHECKING = "checking"; -public static final java.lang.String MEDIA_NOFS = "nofs"; +//public static final java.lang.String MEDIA_CHECKING = "checking"; +//public static final java.lang.String MEDIA_NOFS = "nofs"; public static final java.lang.String MEDIA_MOUNTED = "mounted"; -public static final java.lang.String MEDIA_MOUNTED_READ_ONLY = "mounted_ro"; -public static final java.lang.String MEDIA_SHARED = "shared"; -public static final java.lang.String MEDIA_BAD_REMOVAL = "bad_removal"; -public static final java.lang.String MEDIA_UNMOUNTABLE = "unmountable"; +//public static final java.lang.String MEDIA_MOUNTED_READ_ONLY = "mounted_ro"; +//public static final java.lang.String MEDIA_SHARED = "shared"; +//public static final java.lang.String MEDIA_BAD_REMOVAL = "bad_removal"; +//public static final java.lang.String MEDIA_UNMOUNTABLE = "unmountable"; } diff --git a/src/android/os/Parcelable.java b/src/android/os/Parcelable.java index cdf8abee..715300f2 100644 --- a/src/android/os/Parcelable.java +++ b/src/android/os/Parcelable.java @@ -1,18 +1,18 @@ package android.os; public interface Parcelable { -public static interface Creator<T> -{ +//public static interface Creator<T> +//{ //public abstract T createFromParcel(android.os.Parcel source); -public abstract T[] newArray(int size); -} -public static interface ClassLoaderCreator<T> - extends android.os.Parcelable.Creator<T> -{ +//public abstract T[] newArray(int size); +//} +//public static interface ClassLoaderCreator<T> +// extends android.os.Parcelable.Creator<T> +//{ //public abstract T createFromParcel(android.os.Parcel source, java.lang.ClassLoader loader); -} -public abstract int describeContents(); +//} +//public abstract int describeContents(); //public abstract void writeToParcel(android.os.Parcel dest, int flags); -public static final int PARCELABLE_WRITE_RETURN_VALUE = 1; -public static final int CONTENTS_FILE_DESCRIPTOR = 1; +//public static final int PARCELABLE_WRITE_RETURN_VALUE = 1; +//public static final int CONTENTS_FILE_DESCRIPTOR = 1; } diff --git a/src/android/text/Html.java b/src/android/text/Html.java index 4cf55f02..51109b7d 100644 --- a/src/android/text/Html.java +++ b/src/android/text/Html.java @@ -1,17 +1,17 @@ package android.text; public class Html { -public static interface ImageGetter -{ +//public static interface ImageGetter +//{ //public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String source); -} -public static interface TagHandler -{ +//} +//public static interface TagHandler +//{ //public abstract void handleTag(boolean opening, java.lang.String tag, android.text.Editable output, org.xml.sax.XMLReader xmlReader); -} -Html() { throw new RuntimeException("Stub!"); } +//} +//Html() { throw new RuntimeException("Stub!"); } public static android.text.Spanned fromHtml(java.lang.String source) { throw new RuntimeException("Stub!"); } -public static android.text.Spanned fromHtml(java.lang.String source, android.text.Html.ImageGetter imageGetter, android.text.Html.TagHandler tagHandler) { throw new RuntimeException("Stub!"); } -public static java.lang.String toHtml(android.text.Spanned text) { throw new RuntimeException("Stub!"); } -public static java.lang.String escapeHtml(java.lang.CharSequence text) { throw new RuntimeException("Stub!"); } +//public static android.text.Spanned fromHtml(java.lang.String source, android.text.Html.ImageGetter imageGetter, android.text.Html.TagHandler tagHandler) { throw new RuntimeException("Stub!"); } +//public static java.lang.String toHtml(android.text.Spanned text) { throw new RuntimeException("Stub!"); } +//public static java.lang.String escapeHtml(java.lang.CharSequence text) { throw new RuntimeException("Stub!"); } } diff --git a/src/android/text/Spanned.java b/src/android/text/Spanned.java index cdf76743..1e036422 100644 --- a/src/android/text/Spanned.java +++ b/src/android/text/Spanned.java @@ -2,25 +2,25 @@ public interface Spanned extends java.lang.CharSequence { -public abstract <T> T[] getSpans(int start, int end, java.lang.Class<T> type); -public abstract int getSpanStart(java.lang.Object tag); -public abstract int getSpanEnd(java.lang.Object tag); -public abstract int getSpanFlags(java.lang.Object tag); -public abstract int nextSpanTransition(int start, int limit, java.lang.Class type); -public static final int SPAN_POINT_MARK_MASK = 51; -public static final int SPAN_MARK_MARK = 17; -public static final int SPAN_MARK_POINT = 18; -public static final int SPAN_POINT_MARK = 33; -public static final int SPAN_POINT_POINT = 34; -public static final int SPAN_PARAGRAPH = 51; -public static final int SPAN_INCLUSIVE_EXCLUSIVE = 17; -public static final int SPAN_INCLUSIVE_INCLUSIVE = 18; -public static final int SPAN_EXCLUSIVE_EXCLUSIVE = 33; -public static final int SPAN_EXCLUSIVE_INCLUSIVE = 34; -public static final int SPAN_COMPOSING = 256; -public static final int SPAN_INTERMEDIATE = 512; -public static final int SPAN_USER_SHIFT = 24; -public static final int SPAN_USER = -16777216; -public static final int SPAN_PRIORITY_SHIFT = 16; -public static final int SPAN_PRIORITY = 16711680; +//public abstract <T> T[] getSpans(int start, int end, java.lang.Class<T> type); +//public abstract int getSpanStart(java.lang.Object tag); +//public abstract int getSpanEnd(java.lang.Object tag); +//public abstract int getSpanFlags(java.lang.Object tag); +//public abstract int nextSpanTransition(int start, int limit, java.lang.Class type); +//public static final int SPAN_POINT_MARK_MASK = 51; +//public static final int SPAN_MARK_MARK = 17; +//public static final int SPAN_MARK_POINT = 18; +//public static final int SPAN_POINT_MARK = 33; +//public static final int SPAN_POINT_POINT = 34; +//public static final int SPAN_PARAGRAPH = 51; +//public static final int SPAN_INCLUSIVE_EXCLUSIVE = 17; +//public static final int SPAN_INCLUSIVE_INCLUSIVE = 18; +//public static final int SPAN_EXCLUSIVE_EXCLUSIVE = 33; +//public static final int SPAN_EXCLUSIVE_INCLUSIVE = 34; +//public static final int SPAN_COMPOSING = 256; +//public static final int SPAN_INTERMEDIATE = 512; +//public static final int SPAN_USER_SHIFT = 24; +//public static final int SPAN_USER = -16777216; +//public static final int SPAN_PRIORITY_SHIFT = 16; +//public static final int SPAN_PRIORITY = 16711680; } diff --git a/src/android/text/TextUtils.java b/src/android/text/TextUtils.java deleted file mode 100644 index 065e5243..00000000 --- a/src/android/text/TextUtils.java +++ /dev/null @@ -1,73 +0,0 @@ -package android.text; -public class TextUtils -{ -public static interface StringSplitter - extends java.lang.Iterable<java.lang.String> -{ -public abstract void setString(java.lang.String string); -} -public static class SimpleStringSplitter - implements android.text.TextUtils.StringSplitter, java.util.Iterator<java.lang.String> -{ -public SimpleStringSplitter(char delimiter) { throw new RuntimeException("Stub!"); } -public void setString(java.lang.String string) { throw new RuntimeException("Stub!"); } -public java.util.Iterator<java.lang.String> iterator() { throw new RuntimeException("Stub!"); } -public boolean hasNext() { throw new RuntimeException("Stub!"); } -public java.lang.String next() { throw new RuntimeException("Stub!"); } -public void remove() { throw new RuntimeException("Stub!"); } -} -public static enum TruncateAt -{ -END(), -MARQUEE(), -MIDDLE(), -START(); -} -public static interface EllipsizeCallback -{ -public abstract void ellipsized(int start, int end); -} -TextUtils() { throw new RuntimeException("Stub!"); } -public static void getChars(java.lang.CharSequence s, int start, int end, char[] dest, int destoff) { throw new RuntimeException("Stub!"); } -public static int indexOf(java.lang.CharSequence s, char ch) { throw new RuntimeException("Stub!"); } -public static int indexOf(java.lang.CharSequence s, char ch, int start) { throw new RuntimeException("Stub!"); } -public static int indexOf(java.lang.CharSequence s, char ch, int start, int end) { throw new RuntimeException("Stub!"); } -public static int lastIndexOf(java.lang.CharSequence s, char ch) { throw new RuntimeException("Stub!"); } -public static int lastIndexOf(java.lang.CharSequence s, char ch, int last) { throw new RuntimeException("Stub!"); } -public static int lastIndexOf(java.lang.CharSequence s, char ch, int start, int last) { throw new RuntimeException("Stub!"); } -public static int indexOf(java.lang.CharSequence s, java.lang.CharSequence needle) { throw new RuntimeException("Stub!"); } -public static int indexOf(java.lang.CharSequence s, java.lang.CharSequence needle, int start) { throw new RuntimeException("Stub!"); } -public static int indexOf(java.lang.CharSequence s, java.lang.CharSequence needle, int start, int end) { throw new RuntimeException("Stub!"); } -public static boolean regionMatches(java.lang.CharSequence one, int toffset, java.lang.CharSequence two, int ooffset, int len) { throw new RuntimeException("Stub!"); } -public static java.lang.String substring(java.lang.CharSequence source, int start, int end) { throw new RuntimeException("Stub!"); } -public static java.lang.String join(java.lang.CharSequence delimiter, java.lang.Object[] tokens) { throw new RuntimeException("Stub!"); } -public static java.lang.String join(java.lang.CharSequence delimiter, java.lang.Iterable tokens) { throw new RuntimeException("Stub!"); } -public static java.lang.String[] split(java.lang.String text, java.lang.String expression) { throw new RuntimeException("Stub!"); } -public static java.lang.String[] split(java.lang.String text, java.util.regex.Pattern pattern) { throw new RuntimeException("Stub!"); } -public static java.lang.CharSequence stringOrSpannedString(java.lang.CharSequence source) { throw new RuntimeException("Stub!"); } -public static boolean isEmpty(java.lang.CharSequence str) { throw new RuntimeException("Stub!"); } -public static int getTrimmedLength(java.lang.CharSequence s) { throw new RuntimeException("Stub!"); } -public static boolean equals(java.lang.CharSequence a, java.lang.CharSequence b) { throw new RuntimeException("Stub!"); } -public static java.lang.CharSequence getReverse(java.lang.CharSequence source, int start, int end) { throw new RuntimeException("Stub!"); } -//public static void writeToParcel(java.lang.CharSequence cs, android.os.Parcel p, int parcelableFlags) { throw new RuntimeException("Stub!"); } -//public static void dumpSpans(java.lang.CharSequence cs, android.util.Printer printer, java.lang.String prefix) { throw new RuntimeException("Stub!"); } -public static java.lang.CharSequence replace(java.lang.CharSequence template, java.lang.String[] sources, java.lang.CharSequence[] destinations) { throw new RuntimeException("Stub!"); } -public static java.lang.CharSequence expandTemplate(java.lang.CharSequence template, java.lang.CharSequence... values) { throw new RuntimeException("Stub!"); } -public static int getOffsetBefore(java.lang.CharSequence text, int offset) { throw new RuntimeException("Stub!"); } -public static int getOffsetAfter(java.lang.CharSequence text, int offset) { throw new RuntimeException("Stub!"); } -//public static void copySpansFrom(android.text.Spanned source, int start, int end, java.lang.Class kind, android.text.Spannable dest, int destoff) { throw new RuntimeException("Stub!"); } -//public static java.lang.CharSequence ellipsize(java.lang.CharSequence text, android.text.TextPaint p, float avail, android.text.TextUtils.TruncateAt where) { throw new RuntimeException("Stub!"); } -//public static java.lang.CharSequence ellipsize(java.lang.CharSequence text, android.text.TextPaint paint, float avail, android.text.TextUtils.TruncateAt where, boolean preserveLength, android.text.TextUtils.EllipsizeCallback callback) { throw new RuntimeException("Stub!"); } -//public static java.lang.CharSequence commaEllipsize(java.lang.CharSequence text, android.text.TextPaint p, float avail, java.lang.String oneMore, java.lang.String more) { throw new RuntimeException("Stub!"); } -public static java.lang.String htmlEncode(java.lang.String s) { throw new RuntimeException("Stub!"); } -public static java.lang.CharSequence concat(java.lang.CharSequence... text) { throw new RuntimeException("Stub!"); } -public static boolean isGraphic(java.lang.CharSequence str) { throw new RuntimeException("Stub!"); } -public static boolean isGraphic(char c) { throw new RuntimeException("Stub!"); } -public static boolean isDigitsOnly(java.lang.CharSequence str) { throw new RuntimeException("Stub!"); } -public static int getCapsMode(java.lang.CharSequence cs, int off, int reqModes) { throw new RuntimeException("Stub!"); } -public static final android.os.Parcelable.Creator<java.lang.CharSequence> CHAR_SEQUENCE_CREATOR; -public static final int CAP_MODE_CHARACTERS = 4096; -public static final int CAP_MODE_WORDS = 8192; -public static final int CAP_MODE_SENTENCES = 16384; -static { CHAR_SEQUENCE_CREATOR = null; } -} diff --git a/src/android/util/AndroidException.java b/src/android/util/AndroidException.java deleted file mode 100644 index 282bc2b6..00000000 --- a/src/android/util/AndroidException.java +++ /dev/null @@ -1,7 +0,0 @@ -package android.util; -public class AndroidException extends java.lang.Exception { -public AndroidException() { super (); } -public AndroidException(java.lang.String name) { super(name); } -public AndroidException(java.lang.String name, java.lang.Throwable cause) { super(name, cause); } -public AndroidException(java.lang.Exception cause) { super(cause); } -} diff --git a/src/com/connectsdk/service/RokuService.java b/src/com/connectsdk/service/RokuService.java index 8853a17a..aa807c31 100644 --- a/src/com/connectsdk/service/RokuService.java +++ b/src/com/connectsdk/service/RokuService.java @@ -20,7 +20,7 @@ package com.connectsdk.service; -import android.text.TextUtils; + import android.util.Log; import com.connectsdk.core.AppInfo; @@ -677,16 +677,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); From 49085795284c424e3db7da2db42063e32d74f21d Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Wed, 16 Nov 2016 22:16:46 +0100 Subject: [PATCH 13/41] removed more android dependencies --- .classpath | 2 +- pom.xml | 4 +- src/android/content/BroadcastReceiver.java | 5 - src/android/content/Context.java | 12 +- src/android/content/Intent.java | 368 ------------------ src/android/content/IntentFilter.java | 219 ----------- src/android/net/ConnectivityManager.java | 38 -- src/android/net/NetworkInfo.java | 46 --- src/android/net/wifi/WifiManager.java | 162 -------- src/android/os/Build.java | 61 --- src/android/os/Parcelable.java | 18 - src/com/connectsdk/core/MediaInfo.java | 1 - .../discovery/DiscoveryManager.java | 204 +++++----- .../service/netcast/NetcastHttpServer.java | 4 +- .../webos/WebOSTVServiceSocketClient.java | 6 +- 15 files changed, 117 insertions(+), 1033 deletions(-) delete mode 100644 src/android/content/BroadcastReceiver.java delete mode 100644 src/android/content/Intent.java delete mode 100644 src/android/content/IntentFilter.java delete mode 100644 src/android/net/ConnectivityManager.java delete mode 100644 src/android/net/NetworkInfo.java delete mode 100644 src/android/net/wifi/WifiManager.java delete mode 100644 src/android/os/Build.java delete mode 100644 src/android/os/Parcelable.java diff --git a/.classpath b/.classpath index 7397c6ef..149cb3c9 100644 --- a/.classpath +++ b/.classpath @@ -6,7 +6,7 @@ <attribute name="maven.pomderived" value="true"/> </attributes> </classpathentry> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> <attributes> <attribute name="maven.pomderived" value="true"/> </attributes> diff --git a/pom.xml b/pom.xml index 52b0b0c9..d81c4017 100644 --- a/pom.xml +++ b/pom.xml @@ -18,8 +18,8 @@ <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> - <source/> - <target/> + <source>1.8</source> + <target>1.8</target> </configuration> </plugin> </plugins> diff --git a/src/android/content/BroadcastReceiver.java b/src/android/content/BroadcastReceiver.java deleted file mode 100644 index 64a940ea..00000000 --- a/src/android/content/BroadcastReceiver.java +++ /dev/null @@ -1,5 +0,0 @@ -package android.content; - -public abstract class BroadcastReceiver { - public abstract void onReceive(android.content.Context context, android.content.Intent intent); -} diff --git a/src/android/content/Context.java b/src/android/content/Context.java index 81f82881..7190d547 100644 --- a/src/android/content/Context.java +++ b/src/android/content/Context.java @@ -1,5 +1,7 @@ package android.content; + +/** Context that must be implemented for the library to interface with surrounding systems. */ public abstract class Context { public abstract android.content.pm.PackageManager getPackageManager(); @@ -32,9 +34,9 @@ public abstract class Context //public abstract void setWallpaper(java.io.InputStream data) throws java.io.IOException; //@java.lang.Deprecated() //public abstract void clearWallpaper() throws java.io.IOException; -public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver receiver, android.content.IntentFilter filter); -public abstract void unregisterReceiver(android.content.BroadcastReceiver receiver); -public abstract java.lang.Object getSystemService(java.lang.String name); +//public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver receiver, android.content.IntentFilter filter); +//public abstract void unregisterReceiver(android.content.BroadcastReceiver receiver); +//public abstract java.lang.Object getSystemService(java.lang.String name); //public abstract int checkPermission(java.lang.String permission, int pid, int uid); //public abstract int checkCallingPermission(java.lang.String permission); //public abstract int checkCallingOrSelfPermission(java.lang.String permission); @@ -72,8 +74,8 @@ public abstract class Context //public static final java.lang.String STORAGE_SERVICE = "storage"; //public static final java.lang.String WALLPAPER_SERVICE = "wallpaper"; //public static final java.lang.String VIBRATOR_SERVICE = "vibrator"; -public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity"; -public static final java.lang.String WIFI_SERVICE = "wifi"; +//public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity"; +//public static final java.lang.String WIFI_SERVICE = "wifi"; //public static final java.lang.String WIFI_P2P_SERVICE = "wifip2p"; //public static final java.lang.String NSD_SERVICE = "servicediscovery"; //public static final java.lang.String AUDIO_SERVICE = "audio"; diff --git a/src/android/content/Intent.java b/src/android/content/Intent.java deleted file mode 100644 index d2a9dfdf..00000000 --- a/src/android/content/Intent.java +++ /dev/null @@ -1,368 +0,0 @@ -package android.content; -public class Intent - implements /*android.os.Parcelable,*/ java.lang.Cloneable -{ -//public static class ShortcutIconResource -// implements android.os.Parcelable -//{ -//public ShortcutIconResource() { throw new RuntimeException("Stub!"); } -//public static android.content.Intent.ShortcutIconResource fromContext(android.content.Context context, int resourceId) { throw new RuntimeException("Stub!"); } -//public int describeContents() { throw new RuntimeException("Stub!"); } -//public void writeToParcel(android.os.Parcel dest, int flags) { throw new RuntimeException("Stub!"); } -//public java.lang.String toString() { throw new RuntimeException("Stub!"); } -//public java.lang.String packageName; -//public java.lang.String resourceName; -//public static final android.os.Parcelable.Creator<android.content.Intent.ShortcutIconResource> CREATOR; -//static { CREATOR = null; } -//} -//public static final class FilterComparison -//{ -//public FilterComparison(android.content.Intent intent) { throw new RuntimeException("Stub!"); } -//public android.content.Intent getIntent() { throw new RuntimeException("Stub!"); } -//public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); } -//public int hashCode() { throw new RuntimeException("Stub!"); } -//} -//public Intent() { throw new RuntimeException("Stub!"); } -//public Intent(android.content.Intent o) { throw new RuntimeException("Stub!"); } -//public Intent(java.lang.String action) { throw new RuntimeException("Stub!"); } -//public Intent(java.lang.String action, android.net.Uri uri) { throw new RuntimeException("Stub!"); } -//public Intent(android.content.Context packageContext, java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); } -//public Intent(java.lang.String action, android.net.Uri uri, android.content.Context packageContext, java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); } -//public static android.content.Intent createChooser(android.content.Intent target, java.lang.CharSequence title) { throw new RuntimeException("Stub!"); } -//public java.lang.Object clone() { throw new RuntimeException("Stub!"); } -//public android.content.Intent cloneFilter() { throw new RuntimeException("Stub!"); } -//public static android.content.Intent makeMainActivity(android.content.ComponentName mainActivity) { throw new RuntimeException("Stub!"); } -//public static android.content.Intent makeMainSelectorActivity(java.lang.String selectorAction, java.lang.String selectorCategory) { throw new RuntimeException("Stub!"); } -//public static android.content.Intent makeRestartActivityTask(android.content.ComponentName mainActivity) { throw new RuntimeException("Stub!"); } -//@java.lang.Deprecated() -//public static android.content.Intent getIntent(java.lang.String uri) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } -//public static android.content.Intent parseUri(java.lang.String uri, int flags) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } -//public static android.content.Intent getIntentOld(java.lang.String uri) throws java.net.URISyntaxException { throw new RuntimeException("Stub!"); } -public java.lang.String getAction() { throw new RuntimeException("Stub!"); } -//public android.net.Uri getData() { throw new RuntimeException("Stub!"); } -//public java.lang.String getDataString() { throw new RuntimeException("Stub!"); } -//public java.lang.String getScheme() { throw new RuntimeException("Stub!"); } -//public java.lang.String getType() { throw new RuntimeException("Stub!"); } -//public java.lang.String resolveType(android.content.Context context) { throw new RuntimeException("Stub!"); } -//public java.lang.String resolveType(android.content.ContentResolver resolver) { throw new RuntimeException("Stub!"); } -//public java.lang.String resolveTypeIfNeeded(android.content.ContentResolver resolver) { throw new RuntimeException("Stub!"); } -//public boolean hasCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } -//public java.util.Set<java.lang.String> getCategories() { throw new RuntimeException("Stub!"); } -//public android.content.Intent getSelector() { throw new RuntimeException("Stub!"); } -//public android.content.ClipData getClipData() { throw new RuntimeException("Stub!"); } -//public void setExtrasClassLoader(java.lang.ClassLoader loader) { throw new RuntimeException("Stub!"); } -//public boolean hasExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public boolean hasFileDescriptors() { throw new RuntimeException("Stub!"); } -//public boolean getBooleanExtra(java.lang.String name, boolean defaultValue) { throw new RuntimeException("Stub!"); } -//public byte getByteExtra(java.lang.String name, byte defaultValue) { throw new RuntimeException("Stub!"); } -//public short getShortExtra(java.lang.String name, short defaultValue) { throw new RuntimeException("Stub!"); } -//public char getCharExtra(java.lang.String name, char defaultValue) { throw new RuntimeException("Stub!"); } -//public int getIntExtra(java.lang.String name, int defaultValue) { throw new RuntimeException("Stub!"); } -//public long getLongExtra(java.lang.String name, long defaultValue) { throw new RuntimeException("Stub!"); } -//public float getFloatExtra(java.lang.String name, float defaultValue) { throw new RuntimeException("Stub!"); } -//public double getDoubleExtra(java.lang.String name, double defaultValue) { throw new RuntimeException("Stub!"); } -//public java.lang.String getStringExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public java.lang.CharSequence getCharSequenceExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -public <T extends android.os.Parcelable> T getParcelableExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public android.os.Parcelable[] getParcelableArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public <T extends android.os.Parcelable> java.util.ArrayList<T> getParcelableArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public java.io.Serializable getSerializableExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public java.util.ArrayList<java.lang.Integer> getIntegerArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public java.util.ArrayList<java.lang.String> getStringArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public java.util.ArrayList<java.lang.CharSequence> getCharSequenceArrayListExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public boolean[] getBooleanArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public byte[] getByteArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public short[] getShortArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public char[] getCharArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public int[] getIntArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public long[] getLongArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public float[] getFloatArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public double[] getDoubleArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public java.lang.String[] getStringArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public java.lang.CharSequence[] getCharSequenceArrayExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public android.os.Bundle getBundleExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public android.os.Bundle getExtras() { throw new RuntimeException("Stub!"); } -//public int getFlags() { throw new RuntimeException("Stub!"); } -//public java.lang.String getPackage() { throw new RuntimeException("Stub!"); } -//public android.content.ComponentName getComponent() { throw new RuntimeException("Stub!"); } -//public android.graphics.Rect getSourceBounds() { throw new RuntimeException("Stub!"); } -//public android.content.ComponentName resolveActivity(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -//public android.content.pm.ActivityInfo resolveActivityInfo(android.content.pm.PackageManager pm, int flags) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setAction(java.lang.String action) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setData(android.net.Uri data) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setDataAndNormalize(android.net.Uri data) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setType(java.lang.String type) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setTypeAndNormalize(java.lang.String type) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setDataAndType(android.net.Uri data, java.lang.String type) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setDataAndTypeAndNormalize(android.net.Uri data, java.lang.String type) { throw new RuntimeException("Stub!"); } -//public android.content.Intent addCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } -//public void removeCategory(java.lang.String category) { throw new RuntimeException("Stub!"); } -//public void setSelector(android.content.Intent selector) { throw new RuntimeException("Stub!"); } -//public void setClipData(android.content.ClipData clip) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, boolean value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, byte value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, char value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, short value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, int value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, long value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, float value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, double value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, java.lang.String value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, java.lang.CharSequence value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, android.os.Parcelable value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, android.os.Parcelable[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putParcelableArrayListExtra(java.lang.String name, java.util.ArrayList<? extends android.os.Parcelable> value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putIntegerArrayListExtra(java.lang.String name, java.util.ArrayList<java.lang.Integer> value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putStringArrayListExtra(java.lang.String name, java.util.ArrayList<java.lang.String> value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putCharSequenceArrayListExtra(java.lang.String name, java.util.ArrayList<java.lang.CharSequence> value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, java.io.Serializable value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, boolean[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, byte[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, short[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, char[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, int[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, long[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, float[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, double[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, java.lang.String[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, java.lang.CharSequence[] value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtra(java.lang.String name, android.os.Bundle value) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtras(android.content.Intent src) { throw new RuntimeException("Stub!"); } -//public android.content.Intent putExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } -//public android.content.Intent replaceExtras(android.content.Intent src) { throw new RuntimeException("Stub!"); } -//public android.content.Intent replaceExtras(android.os.Bundle extras) { throw new RuntimeException("Stub!"); } -//public void removeExtra(java.lang.String name) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setFlags(int flags) { throw new RuntimeException("Stub!"); } -//public android.content.Intent addFlags(int flags) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setPackage(java.lang.String packageName) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setComponent(android.content.ComponentName component) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setClassName(android.content.Context packageContext, java.lang.String className) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setClassName(java.lang.String packageName, java.lang.String className) { throw new RuntimeException("Stub!"); } -//public android.content.Intent setClass(android.content.Context packageContext, java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); } -//public void setSourceBounds(android.graphics.Rect r) { throw new RuntimeException("Stub!"); } -//public int fillIn(android.content.Intent other, int flags) { throw new RuntimeException("Stub!"); } -//public boolean filterEquals(android.content.Intent other) { throw new RuntimeException("Stub!"); } -//public int filterHashCode() { throw new RuntimeException("Stub!"); } -//public java.lang.String toString() { throw new RuntimeException("Stub!"); } -//@java.lang.Deprecated() -//public java.lang.String toURI() { throw new RuntimeException("Stub!"); } -//public java.lang.String toUri(int flags) { throw new RuntimeException("Stub!"); } -//public int describeContents() { throw new RuntimeException("Stub!"); } -//public void writeToParcel(android.os.Parcel out, int flags) { throw new RuntimeException("Stub!"); } -//public void readFromParcel(android.os.Parcel in) { throw new RuntimeException("Stub!"); } -//public static android.content.Intent parseIntent(android.content.res.Resources resources, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } -//public static java.lang.String normalizeMimeType(java.lang.String type) { throw new RuntimeException("Stub!"); } -//public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN"; -//public static final java.lang.String ACTION_VIEW = "android.intent.action.VIEW"; -//public static final java.lang.String ACTION_DEFAULT = "android.intent.action.VIEW"; -//public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA"; -//public static final java.lang.String ACTION_EDIT = "android.intent.action.EDIT"; -//public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT"; -//public static final java.lang.String ACTION_PICK = "android.intent.action.PICK"; -//public static final java.lang.String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT"; -//public static final java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT"; -//public static final java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME"; -//public static final java.lang.String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON"; -//public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE"; -//public static final java.lang.String ACTION_CHOOSER = "android.intent.action.CHOOSER"; -//public static final java.lang.String ACTION_GET_CONTENT = "android.intent.action.GET_CONTENT"; -//public static final java.lang.String ACTION_DIAL = "android.intent.action.DIAL"; -//public static final java.lang.String ACTION_CALL = "android.intent.action.CALL"; -//public static final java.lang.String ACTION_SENDTO = "android.intent.action.SENDTO"; -//public static final java.lang.String ACTION_SEND = "android.intent.action.SEND"; -//public static final java.lang.String ACTION_SEND_MULTIPLE = "android.intent.action.SEND_MULTIPLE"; -//public static final java.lang.String ACTION_ANSWER = "android.intent.action.ANSWER"; -//public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT"; -//public static final java.lang.String ACTION_PASTE = "android.intent.action.PASTE"; -//public static final java.lang.String ACTION_DELETE = "android.intent.action.DELETE"; -//public static final java.lang.String ACTION_RUN = "android.intent.action.RUN"; -//public static final java.lang.String ACTION_SYNC = "android.intent.action.SYNC"; -//public static final java.lang.String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY"; -//public static final java.lang.String ACTION_SEARCH = "android.intent.action.SEARCH"; -//public static final java.lang.String ACTION_SYSTEM_TUTORIAL = "android.intent.action.SYSTEM_TUTORIAL"; -//public static final java.lang.String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH"; -//public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST"; -//public static final java.lang.String ACTION_ALL_APPS = "android.intent.action.ALL_APPS"; -//public static final java.lang.String ACTION_SET_WALLPAPER = "android.intent.action.SET_WALLPAPER"; -//public static final java.lang.String ACTION_BUG_REPORT = "android.intent.action.BUG_REPORT"; -//public static final java.lang.String ACTION_FACTORY_TEST = "android.intent.action.FACTORY_TEST"; -//public static final java.lang.String ACTION_CALL_BUTTON = "android.intent.action.CALL_BUTTON"; -//public static final java.lang.String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND"; -//public static final java.lang.String ACTION_SEARCH_LONG_PRESS = "android.intent.action.SEARCH_LONG_PRESS"; -//public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR"; -//public static final java.lang.String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; -//public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE"; -//public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE"; -//public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME"; -//public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE"; -//@java.lang.Deprecated() -//public static final java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE"; -//public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT"; -//public static final java.lang.String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE"; -//public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF"; -//public static final java.lang.String ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON"; -//public static final java.lang.String ACTION_USER_PRESENT = "android.intent.action.USER_PRESENT"; -//public static final java.lang.String ACTION_TIME_TICK = "android.intent.action.TIME_TICK"; -//public static final java.lang.String ACTION_TIME_CHANGED = "android.intent.action.TIME_SET"; -//public static final java.lang.String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED"; -//public static final java.lang.String ACTION_TIMEZONE_CHANGED = "android.intent.action.TIMEZONE_CHANGED"; -//public static final java.lang.String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED"; -//public static final java.lang.String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS"; -//@java.lang.Deprecated() -//public static final java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; -//public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; -//public static final java.lang.String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED"; -//public static final java.lang.String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED"; -//public static final java.lang.String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED"; -//public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED"; -//public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; -//public static final java.lang.String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED"; -//public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED"; -//public static final java.lang.String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED"; -//public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH"; -//public static final java.lang.String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION"; -//public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE"; -//public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE"; -//@java.lang.Deprecated() -//public static final java.lang.String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED"; -//public static final java.lang.String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED"; -//public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED"; -//public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED"; -//public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW"; -//public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY"; -//public static final java.lang.String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED"; -//public static final java.lang.String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED"; -//public static final java.lang.String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN"; -//public static final java.lang.String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW"; -//public static final java.lang.String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK"; -//public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE"; -//@java.lang.Deprecated() -//public static final java.lang.String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED"; -//@java.lang.Deprecated() -//public static final java.lang.String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED"; -//public static final java.lang.String ACTION_MEDIA_REMOVED = "android.intent.action.MEDIA_REMOVED"; -//public static final java.lang.String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED"; -//public static final java.lang.String ACTION_MEDIA_CHECKING = "android.intent.action.MEDIA_CHECKING"; -//public static final java.lang.String ACTION_MEDIA_NOFS = "android.intent.action.MEDIA_NOFS"; -//public static final java.lang.String ACTION_MEDIA_MOUNTED = "android.intent.action.MEDIA_MOUNTED"; -//public static final java.lang.String ACTION_MEDIA_SHARED = "android.intent.action.MEDIA_SHARED"; -//public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL"; -//public static final java.lang.String ACTION_MEDIA_UNMOUNTABLE = "android.intent.action.MEDIA_UNMOUNTABLE"; -//public static final java.lang.String ACTION_MEDIA_EJECT = "android.intent.action.MEDIA_EJECT"; -//public static final java.lang.String ACTION_MEDIA_SCANNER_STARTED = "android.intent.action.MEDIA_SCANNER_STARTED"; -//public static final java.lang.String ACTION_MEDIA_SCANNER_FINISHED = "android.intent.action.MEDIA_SCANNER_FINISHED"; -//public static final java.lang.String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE"; -//public static final java.lang.String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON"; -//public static final java.lang.String ACTION_CAMERA_BUTTON = "android.intent.action.CAMERA_BUTTON"; -//public static final java.lang.String ACTION_GTALK_SERVICE_CONNECTED = "android.intent.action.GTALK_CONNECTED"; -//public static final java.lang.String ACTION_GTALK_SERVICE_DISCONNECTED = "android.intent.action.GTALK_DISCONNECTED"; -//public static final java.lang.String ACTION_INPUT_METHOD_CHANGED = "android.intent.action.INPUT_METHOD_CHANGED"; -//public static final java.lang.String ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE"; -//public static final java.lang.String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED"; -//public static final java.lang.String ACTION_HEADSET_PLUG = "android.intent.action.HEADSET_PLUG"; -//public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"; -//public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT"; -//public static final java.lang.String ACTION_DOCK_EVENT = "android.intent.action.DOCK_EVENT"; -//public static final java.lang.String CATEGORY_DEFAULT = "android.intent.category.DEFAULT"; -//public static final java.lang.String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE"; -//public static final java.lang.String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE"; -//public static final java.lang.String CATEGORY_SELECTED_ALTERNATIVE = "android.intent.category.SELECTED_ALTERNATIVE"; -//public static final java.lang.String CATEGORY_TAB = "android.intent.category.TAB"; -//public static final java.lang.String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER"; -//public static final java.lang.String CATEGORY_INFO = "android.intent.category.INFO"; -//public static final java.lang.String CATEGORY_HOME = "android.intent.category.HOME"; -//public static final java.lang.String CATEGORY_PREFERENCE = "android.intent.category.PREFERENCE"; -//public static final java.lang.String CATEGORY_DEVELOPMENT_PREFERENCE = "android.intent.category.DEVELOPMENT_PREFERENCE"; -//public static final java.lang.String CATEGORY_EMBED = "android.intent.category.EMBED"; -//public static final java.lang.String CATEGORY_APP_MARKET = "android.intent.category.APP_MARKET"; -//public static final java.lang.String CATEGORY_MONKEY = "android.intent.category.MONKEY"; -//public static final java.lang.String CATEGORY_TEST = "android.intent.category.TEST"; -//public static final java.lang.String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST"; -//public static final java.lang.String CATEGORY_SAMPLE_CODE = "android.intent.category.SAMPLE_CODE"; -//public static final java.lang.String CATEGORY_OPENABLE = "android.intent.category.OPENABLE"; -//public static final java.lang.String CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST = "android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"; -//public static final java.lang.String CATEGORY_CAR_DOCK = "android.intent.category.CAR_DOCK"; -//public static final java.lang.String CATEGORY_DESK_DOCK = "android.intent.category.DESK_DOCK"; -//public static final java.lang.String CATEGORY_LE_DESK_DOCK = "android.intent.category.LE_DESK_DOCK"; -//public static final java.lang.String CATEGORY_HE_DESK_DOCK = "android.intent.category.HE_DESK_DOCK"; -//public static final java.lang.String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE"; -//public static final java.lang.String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER"; -//public static final java.lang.String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR"; -//public static final java.lang.String CATEGORY_APP_CALENDAR = "android.intent.category.APP_CALENDAR"; -//public static final java.lang.String CATEGORY_APP_CONTACTS = "android.intent.category.APP_CONTACTS"; -//public static final java.lang.String CATEGORY_APP_EMAIL = "android.intent.category.APP_EMAIL"; -//public static final java.lang.String CATEGORY_APP_GALLERY = "android.intent.category.APP_GALLERY"; -//public static final java.lang.String CATEGORY_APP_MAPS = "android.intent.category.APP_MAPS"; -//public static final java.lang.String CATEGORY_APP_MESSAGING = "android.intent.category.APP_MESSAGING"; -//public static final java.lang.String CATEGORY_APP_MUSIC = "android.intent.category.APP_MUSIC"; -//public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE"; -//public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT"; -//public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT"; -//public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; -//public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL"; -//public static final java.lang.String EXTRA_CC = "android.intent.extra.CC"; -//public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC"; -//public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT"; -//public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT"; -//public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE"; -//public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS"; -//public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT"; -//public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP"; -//public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER"; -//public static final java.lang.String EXTRA_UID = "android.intent.extra.UID"; -//public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED"; -//public static final java.lang.String EXTRA_REPLACING = "android.intent.extra.REPLACING"; -//public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT"; -//public static final java.lang.String EXTRA_DOCK_STATE = "android.intent.extra.DOCK_STATE"; -//public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; -//public static final int EXTRA_DOCK_STATE_DESK = 1; -//public static final int EXTRA_DOCK_STATE_CAR = 2; -//public static final int EXTRA_DOCK_STATE_LE_DESK = 3; -//public static final int EXTRA_DOCK_STATE_HE_DESK = 4; -//public static final java.lang.String METADATA_DOCK_HOME = "android.dock_home"; -//public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT"; -//public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token"; -//@java.lang.Deprecated() -//public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME = "android.intent.extra.changed_component_name"; -//public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list"; -//public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list"; -//public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list"; -//public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY"; -//public static final int FLAG_GRANT_READ_URI_PERMISSION = 1; -//public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 2; -//public static final int FLAG_FROM_BACKGROUND = 4; -//public static final int FLAG_DEBUG_LOG_RESOLUTION = 8; -//public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 16; -//public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32; -//public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824; -//public static final int FLAG_ACTIVITY_SINGLE_TOP = 536870912; -//public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; -//public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; -//public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; -//public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; -//public static final int FLAG_ACTIVITY_PREVIOUS_IS_TOP = 16777216; -//public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; -//public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 4194304; -//public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 2097152; -//public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; -//public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; -//public static final int FLAG_ACTIVITY_NO_USER_ACTION = 262144; -//public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 131072; -//public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536; -//public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; -//public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; -//public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; -//public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; -//public static final int FLAG_RECEIVER_FOREGROUND = 268435456; -//public static final int URI_INTENT_SCHEME = 1; -//public static final int FILL_IN_ACTION = 1; -//public static final int FILL_IN_DATA = 2; -//public static final int FILL_IN_CATEGORIES = 4; -//public static final int FILL_IN_COMPONENT = 8; -//public static final int FILL_IN_PACKAGE = 16; -//public static final int FILL_IN_SOURCE_BOUNDS = 32; -//public static final int FILL_IN_SELECTOR = 64; -//public static final int FILL_IN_CLIP_DATA = 128; -//public static final android.os.Parcelable.Creator<android.content.Intent> CREATOR; -// static { CREATOR = null; } -} diff --git a/src/android/content/IntentFilter.java b/src/android/content/IntentFilter.java deleted file mode 100644 index b5e56dfb..00000000 --- a/src/android/content/IntentFilter.java +++ /dev/null @@ -1,219 +0,0 @@ -package android.content; - -public class IntentFilter -// implements android.os.Parcelable -{ -// public static class MalformedMimeTypeException extends android.util.AndroidException { -// public MalformedMimeTypeException() { -// throw new RuntimeException("Stub!"); -// } -// -// public MalformedMimeTypeException(java.lang.String name) { -// throw new RuntimeException("Stub!"); -// } -// } -// -// public static final class AuthorityEntry { -// public AuthorityEntry(java.lang.String host, java.lang.String port) { -// throw new RuntimeException("Stub!"); -// } -// -// public java.lang.String getHost() { -// throw new RuntimeException("Stub!"); -// } -// -// public int getPort() { -// throw new RuntimeException("Stub!"); -// } -// // public int match(android.net.Uri data) { throw new RuntimeException("Stub!"); } -// } - - public IntentFilter() { - /* throw new RuntimeException("Stub!"); */} - -// public IntentFilter(java.lang.String action) { -// throw new RuntimeException("Stub!"); -// } -// -// public IntentFilter(java.lang.String action, java.lang.String dataType) -// throws android.content.IntentFilter.MalformedMimeTypeException { -// throw new RuntimeException("Stub!"); -// } -// -// public IntentFilter(android.content.IntentFilter o) { -// throw new RuntimeException("Stub!"); -// } - -// public static android.content.IntentFilter create(java.lang.String action, java.lang.String dataType) { -// throw new RuntimeException("Stub!"); -// } -// -// public final void setPriority(int priority) { -// throw new RuntimeException("Stub!"); -// } -// -// public final int getPriority() { -// throw new RuntimeException("Stub!"); -// } - - public final void addAction(java.lang.String action) { - /* throw new RuntimeException("Stub!"); */ } - -// public final int countActions() { -// throw new RuntimeException("Stub!"); -// } -// -// public final java.lang.String getAction(int index) { -// throw new RuntimeException("Stub!"); -// } -// -// public final boolean hasAction(java.lang.String action) { -// throw new RuntimeException("Stub!"); -// } -// -// public final boolean matchAction(java.lang.String action) { -// throw new RuntimeException("Stub!"); -// } -// -// public final java.util.Iterator<java.lang.String> actionsIterator() { -// throw new RuntimeException("Stub!"); -// } -// -// public final void addDataType(java.lang.String type) -// throws android.content.IntentFilter.MalformedMimeTypeException { -// throw new RuntimeException("Stub!"); -// } -// -// public final boolean hasDataType(java.lang.String type) { -// throw new RuntimeException("Stub!"); -// } -// -// public final int countDataTypes() { -// throw new RuntimeException("Stub!"); -// } -// -// public final java.lang.String getDataType(int index) { -// throw new RuntimeException("Stub!"); -// } -// -// public final java.util.Iterator<java.lang.String> typesIterator() { -// throw new RuntimeException("Stub!"); -// } -// -// public final void addDataScheme(java.lang.String scheme) { -// throw new RuntimeException("Stub!"); -// } -// -// public final int countDataSchemes() { -// throw new RuntimeException("Stub!"); -// } -// -// public final java.lang.String getDataScheme(int index) { -// throw new RuntimeException("Stub!"); -// } -// -// public final boolean hasDataScheme(java.lang.String scheme) { -// throw new RuntimeException("Stub!"); -// } -// -// public final java.util.Iterator<java.lang.String> schemesIterator() { -// throw new RuntimeException("Stub!"); -// } -// -// public final void addDataAuthority(java.lang.String host, java.lang.String port) { -// throw new RuntimeException("Stub!"); -// } -// -// public final int countDataAuthorities() { -// throw new RuntimeException("Stub!"); -// } -// -// public final android.content.IntentFilter.AuthorityEntry getDataAuthority(int index) { -// throw new RuntimeException("Stub!"); -// } - - // public final boolean hasDataAuthority(android.net.Uri data) { throw new RuntimeException("Stub!"); } -// public final java.util.Iterator<android.content.IntentFilter.AuthorityEntry> authoritiesIterator() { -// throw new RuntimeException("Stub!"); -// } -// -// public final void addDataPath(java.lang.String path, int type) { -// throw new RuntimeException("Stub!"); -// } -// -// public final int countDataPaths() { -// throw new RuntimeException("Stub!"); -// } - - // public final android.os.PatternMatcher getDataPath(int index) { throw new RuntimeException("Stub!"); } -// public final boolean hasDataPath(java.lang.String data) { -// throw new RuntimeException("Stub!"); -// } - - // public final java.util.Iterator<android.os.PatternMatcher> pathsIterator() { throw new RuntimeException("Stub!"); - // } - // public final int matchDataAuthority(android.net.Uri data) { throw new RuntimeException("Stub!"); } - // public final int matchData(java.lang.String type, java.lang.String scheme, android.net.Uri data) { throw new - // RuntimeException("Stub!"); } -// public final void addCategory(java.lang.String category) { -// throw new RuntimeException("Stub!"); -// } -// -// public final int countCategories() { -// throw new RuntimeException("Stub!"); -// } -// -// public final java.lang.String getCategory(int index) { -// throw new RuntimeException("Stub!"); -// } -// -// public final boolean hasCategory(java.lang.String category) { -// throw new RuntimeException("Stub!"); -// } -// -// public final java.util.Iterator<java.lang.String> categoriesIterator() { -// throw new RuntimeException("Stub!"); -// } -// -// public final java.lang.String matchCategories(java.util.Set<java.lang.String> categories) { -// throw new RuntimeException("Stub!"); -// } - - // public final int match(android.content.ContentResolver resolver, android.content.Intent intent, boolean resolve, - // java.lang.String logTag) { throw new RuntimeException("Stub!"); } - // public final int match(java.lang.String action, java.lang.String type, java.lang.String scheme, android.net.Uri - // data, java.util.Set<java.lang.String> categories, java.lang.String logTag) { throw new RuntimeException("Stub!"); - // } - // public void writeToXml(org.xmlpull.v1.XmlSerializer serializer) throws java.io.IOException { - // throw new RuntimeException("Stub!"); - // } - - // public void readFromXml(org.xmlpull.v1.XmlPullParser parser) - // throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { - // throw new RuntimeException("Stub!"); - // } - - // public void dump(android.util.Printer du, java.lang.String prefix) { throw new RuntimeException("Stub!"); } -// public final int describeContents() { -// throw new RuntimeException("Stub!"); -// } - - // public final void writeToParcel(android.os.Parcel dest, int flags) { throw new RuntimeException("Stub!"); } -// public static final int SYSTEM_HIGH_PRIORITY = 1000; -// public static final int SYSTEM_LOW_PRIORITY = -1000; -// public static final int MATCH_CATEGORY_MASK = 268369920; -// public static final int MATCH_ADJUSTMENT_MASK = 65535; -// public static final int MATCH_ADJUSTMENT_NORMAL = 32768; -// public static final int MATCH_CATEGORY_EMPTY = 1048576; -// public static final int MATCH_CATEGORY_SCHEME = 2097152; -// public static final int MATCH_CATEGORY_HOST = 3145728; -// public static final int MATCH_CATEGORY_PORT = 4194304; -// public static final int MATCH_CATEGORY_PATH = 5242880; -// public static final int MATCH_CATEGORY_TYPE = 6291456; -// public static final int NO_MATCH_TYPE = -1; -// public static final int NO_MATCH_DATA = -2; -// public static final int NO_MATCH_ACTION = -3; -// public static final int NO_MATCH_CATEGORY = -4; - // public static final android.os.Parcelable.Creator<android.content.IntentFilter> CREATOR; - // static { CREATOR = null; } -} diff --git a/src/android/net/ConnectivityManager.java b/src/android/net/ConnectivityManager.java deleted file mode 100644 index 32d4d69b..00000000 --- a/src/android/net/ConnectivityManager.java +++ /dev/null @@ -1,38 +0,0 @@ -package android.net; -public class ConnectivityManager -{ -public ConnectivityManager() { /*throw new RuntimeException("Stub!");*/ } -//public static boolean isNetworkTypeValid(int networkType) { throw new RuntimeException("Stub!"); } -//public void setNetworkPreference(int preference) { throw new RuntimeException("Stub!"); } -//public int getNetworkPreference() { throw new RuntimeException("Stub!"); } -//public android.net.NetworkInfo getActiveNetworkInfo() { throw new RuntimeException("Stub!"); } -public android.net.NetworkInfo getNetworkInfo(int networkType) { return new NetworkInfo();/*throw new RuntimeException("Stub!");*/ } -//public android.net.NetworkInfo[] getAllNetworkInfo() { throw new RuntimeException("Stub!"); } -//public int startUsingNetworkFeature(int networkType, java.lang.String feature) { throw new RuntimeException("Stub!"); } -//public int stopUsingNetworkFeature(int networkType, java.lang.String feature) { throw new RuntimeException("Stub!"); } -//public boolean requestRouteToHost(int networkType, int hostAddress) { throw new RuntimeException("Stub!"); } -//@java.lang.Deprecated() -//public boolean getBackgroundDataSetting() { throw new RuntimeException("Stub!"); } -//public boolean isActiveNetworkMetered() { throw new RuntimeException("Stub!"); } -//public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; -//@java.lang.Deprecated() -//public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; -//public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover"; -//public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork"; -//public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity"; -//public static final java.lang.String EXTRA_REASON = "reason"; -//public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo"; -//@java.lang.Deprecated() -//public static final java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; -//public static final int TYPE_MOBILE = 0; -public static final int TYPE_WIFI = 1; -//public static final int TYPE_MOBILE_MMS = 2; -//public static final int TYPE_MOBILE_SUPL = 3; -//public static final int TYPE_MOBILE_DUN = 4; -//public static final int TYPE_MOBILE_HIPRI = 5; -//public static final int TYPE_WIMAX = 6; -//public static final int TYPE_BLUETOOTH = 7; -//public static final int TYPE_DUMMY = 8; -//public static final int TYPE_ETHERNET = 9; -//public static final int DEFAULT_NETWORK_PREFERENCE = 1; -} diff --git a/src/android/net/NetworkInfo.java b/src/android/net/NetworkInfo.java deleted file mode 100644 index 990f3b84..00000000 --- a/src/android/net/NetworkInfo.java +++ /dev/null @@ -1,46 +0,0 @@ -package android.net; -public class NetworkInfo -// implements android.os.Parcelable -{ -public static enum State -{ -CONNECTED(), -CONNECTING(), -DISCONNECTED(), -DISCONNECTING(), -SUSPENDED(), -UNKNOWN(); -} -//public static enum DetailedState -//{ -//AUTHENTICATING(), -//BLOCKED(), -//CONNECTED(), -//CONNECTING(), -//DISCONNECTED(), -//DISCONNECTING(), -//FAILED(), -//IDLE(), -//OBTAINING_IPADDR(), -//SCANNING(), -//SUSPENDED(), -//VERIFYING_POOR_LINK(); -//} -NetworkInfo() { /* throw new RuntimeException("Stub!"); */} -//public int getType() { throw new RuntimeException("Stub!"); } -//public int getSubtype() { throw new RuntimeException("Stub!"); } -//public java.lang.String getTypeName() { throw new RuntimeException("Stub!"); } -//public java.lang.String getSubtypeName() { throw new RuntimeException("Stub!"); } -//public boolean isConnectedOrConnecting() { throw new RuntimeException("Stub!"); } -public boolean isConnected() { return true; /*throw new RuntimeException("Stub!");*/ } -//public boolean isAvailable() { throw new RuntimeException("Stub!"); } -//public boolean isFailover() { throw new RuntimeException("Stub!"); } -//public boolean isRoaming() { throw new RuntimeException("Stub!"); } -public android.net.NetworkInfo.State getState() { throw new RuntimeException("Stub!"); } -//public android.net.NetworkInfo.DetailedState getDetailedState() { throw new RuntimeException("Stub!"); } -//public java.lang.String getReason() { throw new RuntimeException("Stub!"); } -//public java.lang.String getExtraInfo() { throw new RuntimeException("Stub!"); } -//public java.lang.String toString() { throw new RuntimeException("Stub!"); } -//public int describeContents() { throw new RuntimeException("Stub!"); } -//public void writeToParcel(android.os.Parcel dest, int flags) { throw new RuntimeException("Stub!"); } -} diff --git a/src/android/net/wifi/WifiManager.java b/src/android/net/wifi/WifiManager.java deleted file mode 100644 index b7e1b275..00000000 --- a/src/android/net/wifi/WifiManager.java +++ /dev/null @@ -1,162 +0,0 @@ -package android.net.wifi; - -public class WifiManager { - -// public class WifiLock { -// WifiLock() { -// throw new RuntimeException("Stub!"); -// } -// -// public void acquire() { -// throw new RuntimeException("Stub!"); -// } -// -// public void release() { -// throw new RuntimeException("Stub!"); -// } -// -// public void setReferenceCounted(boolean refCounted) { -// throw new RuntimeException("Stub!"); -// } -// -// public boolean isHeld() { -// throw new RuntimeException("Stub!"); -// } -// -// // public void setWorkSource(android.os.WorkSource ws) { throw new RuntimeException("Stub!"); } -// @Override -// public java.lang.String toString() { -// throw new RuntimeException("Stub!"); -// } -// -// @Override -// protected void finalize() throws java.lang.Throwable { -// throw new RuntimeException("Stub!"); -// } -// } - - public class MulticastLock { // multicast lock is used on android to save power. not required on a server - MulticastLock() { - /* throw new RuntimeException("Stub!"); */ } - - public void acquire() { - /* throw new RuntimeException("Stub!"); */} - - public void release() { - /* throw new RuntimeException("Stub!"); */ } - - public void setReferenceCounted(boolean refCounted) { - /* throw new RuntimeException("Stub!"); */ } - - public boolean isHeld() { - return true; - } - } - - public WifiManager() { - } - - // public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks() { throw new - // RuntimeException("Stub!"); } - // public int addNetwork(android.net.wifi.WifiConfiguration config) { throw new RuntimeException("Stub!"); } - // public int updateNetwork(android.net.wifi.WifiConfiguration config) { throw new RuntimeException("Stub!"); } -// public boolean removeNetwork(int netId) { -// throw new RuntimeException("Stub!"); -// } - -// public boolean enableNetwork(int netId, boolean disableOthers) { -// throw new RuntimeException("Stub!"); -// } -// -// public boolean disableNetwork(int netId) { -// throw new RuntimeException("Stub!"); -// } -// -// public boolean disconnect() { -// throw new RuntimeException("Stub!"); -// } -// -// public boolean reconnect() { -// throw new RuntimeException("Stub!"); -// } -// -// public boolean reassociate() { -// throw new RuntimeException("Stub!"); -// } -// -// public boolean pingSupplicant() { -// throw new RuntimeException("Stub!"); -// } - - public boolean startScan() { return true; - } - - // public android.net.wifi.WifiInfo getConnectionInfo() { - // throw new RuntimeException("Stub!"); - // } - - // public java.util.List<android.net.wifi.ScanResult> getScanResults() { throw new RuntimeException("Stub!"); } -// public boolean saveConfiguration() { -// throw new RuntimeException("Stub!"); -// } - - // public android.net.DhcpInfo getDhcpInfo() { throw new RuntimeException("Stub!"); } -// public boolean setWifiEnabled(boolean enabled) { -// throw new RuntimeException("Stub!"); -// } -// -// public int getWifiState() { -// throw new RuntimeException("Stub!"); -// } -// -// public boolean isWifiEnabled() { -// throw new RuntimeException("Stub!"); -// } -// -// public static int calculateSignalLevel(int rssi, int numLevels) { -// throw new RuntimeException("Stub!"); -// } -// -// public static int compareSignalLevel(int rssiA, int rssiB) { -// throw new RuntimeException("Stub!"); -// } - -// public android.net.wifi.WifiManager.WifiLock createWifiLock(int lockType, java.lang.String tag) { -// throw new RuntimeException("Stub!"); -// } -// -// public android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String tag) { -// throw new RuntimeException("Stub!"); -// } - - public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String tag) { - return new MulticastLock(); - } - -// public static final int ERROR_AUTHENTICATING = 1; -// public static final java.lang.String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED"; -// public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state"; -// public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state"; -// public static final int WIFI_STATE_DISABLING = 0; -// public static final int WIFI_STATE_DISABLED = 1; -// public static final int WIFI_STATE_ENABLING = 2; -// public static final int WIFI_STATE_ENABLED = 3; -// public static final int WIFI_STATE_UNKNOWN = 4; -// public static final java.lang.String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE"; -// public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected"; - public static final java.lang.String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE"; - public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; -// public static final java.lang.String EXTRA_BSSID = "bssid"; -// public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo"; -// public static final java.lang.String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE"; -// public static final java.lang.String EXTRA_NEW_STATE = "newState"; -// public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError"; -// public static final java.lang.String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS"; -// public static final java.lang.String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; -// public static final java.lang.String EXTRA_NEW_RSSI = "newRssi"; -// public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED"; -// public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; -// public static final int WIFI_MODE_FULL = 1; -// public static final int WIFI_MODE_SCAN_ONLY = 2; -// public static final int WIFI_MODE_FULL_HIGH_PERF = 3; -} diff --git a/src/android/os/Build.java b/src/android/os/Build.java deleted file mode 100644 index 2b2bba6f..00000000 --- a/src/android/os/Build.java +++ /dev/null @@ -1,61 +0,0 @@ -package android.os; -public class Build -{ -public static class VERSION -{ -public VERSION() { throw new RuntimeException("Stub!"); } -public static final java.lang.String INCREMENTAL; -public static final java.lang.String RELEASE; -@java.lang.Deprecated() -public static final java.lang.String SDK; -public static final int SDK_INT; -public static final java.lang.String CODENAME; -static { INCREMENTAL = null; RELEASE = null; SDK = null; SDK_INT = 0; CODENAME = null; } -} -//public static class VERSION_CODES -//{ -//public VERSION_CODES() { throw new RuntimeException("Stub!"); } -//public static final int CUR_DEVELOPMENT = 10000; -//public static final int BASE = 1; -//public static final int BASE_1_1 = 2; -//public static final int CUPCAKE = 3; -//public static final int DONUT = 4; -//public static final int ECLAIR = 5; -//public static final int ECLAIR_0_1 = 6; -//public static final int ECLAIR_MR1 = 7; -//public static final int FROYO = 8; -//public static final int GINGERBREAD = 9; -//public static final int GINGERBREAD_MR1 = 10; -//public static final int HONEYCOMB = 11; -//public static final int HONEYCOMB_MR1 = 12; -//public static final int HONEYCOMB_MR2 = 13; -//public static final int ICE_CREAM_SANDWICH = 14; -//public static final int ICE_CREAM_SANDWICH_MR1 = 15; -//public static final int JELLY_BEAN = 16; -//} -public Build() { throw new RuntimeException("Stub!"); } -//public static java.lang.String getRadioVersion() { throw new RuntimeException("Stub!"); } -//public static final java.lang.String UNKNOWN = "unknown"; -//public static final java.lang.String ID; -//public static final java.lang.String DISPLAY; -//public static final java.lang.String PRODUCT; -//public static final java.lang.String DEVICE; -//public static final java.lang.String BOARD; -//public static final java.lang.String CPU_ABI; -//public static final java.lang.String CPU_ABI2; -//public static final java.lang.String MANUFACTURER; -//public static final java.lang.String BRAND; -public static final java.lang.String MODEL =null; -//public static final java.lang.String BOOTLOADER; -//@java.lang.Deprecated() -//public static final java.lang.String RADIO; -//public static final java.lang.String HARDWARE; -//public static final java.lang.String SERIAL; -//public static final java.lang.String TYPE; -//public static final java.lang.String TAGS; -//public static final java.lang.String FINGERPRINT; -//public static final long TIME; -//public static final java.lang.String USER; -//public static final java.lang.String HOST; -//static { ID = null; DISPLAY = null; PRODUCT = null; DEVICE = null; BOARD = null; CPU_ABI = null; CPU_ABI2 = null; MANUFACTURER = null; BRAND = null; MODEL = null; BOOTLOADER = null; RADIO = null; HARDWARE = null; SERIAL = null; TYPE = null; TAGS = null; FINGERPRINT = null; TIME = 0; USER = null; HOST = null; } -} diff --git a/src/android/os/Parcelable.java b/src/android/os/Parcelable.java deleted file mode 100644 index 715300f2..00000000 --- a/src/android/os/Parcelable.java +++ /dev/null @@ -1,18 +0,0 @@ -package android.os; -public interface Parcelable -{ -//public static interface Creator<T> -//{ -//public abstract T createFromParcel(android.os.Parcel source); -//public abstract T[] newArray(int size); -//} -//public static interface ClassLoaderCreator<T> -// extends android.os.Parcelable.Creator<T> -//{ -//public abstract T createFromParcel(android.os.Parcel source, java.lang.ClassLoader loader); -//} -//public abstract int describeContents(); -//public abstract void writeToParcel(android.os.Parcel dest, int flags); -//public static final int PARCELABLE_WRITE_RETURN_VALUE = 1; -//public static final int CONTENTS_FILE_DESCRIPTOR = 1; -} diff --git a/src/com/connectsdk/core/MediaInfo.java b/src/com/connectsdk/core/MediaInfo.java index b05c2cbf..9d2f9f6d 100644 --- a/src/com/connectsdk/core/MediaInfo.java +++ b/src/com/connectsdk/core/MediaInfo.java @@ -21,7 +21,6 @@ package com.connectsdk.core; import android.support.annotation.NonNull; - import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/src/com/connectsdk/discovery/DiscoveryManager.java b/src/com/connectsdk/discovery/DiscoveryManager.java index 82b938b1..c8ffabb2 100644 --- a/src/com/connectsdk/discovery/DiscoveryManager.java +++ b/src/com/connectsdk/discovery/DiscoveryManager.java @@ -47,14 +47,14 @@ import com.connectsdk.service.config.ServiceConfig.ServiceConfigListener; import com.connectsdk.service.config.ServiceDescription; -import android.content.BroadcastReceiver; +//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.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; /** @@ -133,8 +133,8 @@ public enum PairingLevel { private CopyOnWriteArrayList<DiscoveryManagerListener> discoveryListeners; List<CapabilityFilter> capabilityFilters; - MulticastLock multicastLock; - BroadcastReceiver receiver; + //MulticastLock multicastLock; + //BroadcastReceiver receiver; boolean isBroadcastReceiverRegistered = false; Timer rescanTimer; @@ -214,82 +214,82 @@ public DiscoveryManager(Context context, ConnectableDeviceStore connectableDevic discoveryListeners = new CopyOnWriteArrayList<DiscoveryManagerListener>(); - 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<CapabilityFilter>(); 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 @@ -547,7 +547,7 @@ public void start() { } mSearching = true; - multicastLock.acquire(); +// multicastLock.acquire(); Util.runOnUI(new Runnable() { @@ -557,28 +557,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)); +// } +// } +// }); +// } } }); } @@ -597,9 +597,9 @@ public void stop() { provider.stop(); } - if (multicastLock.isHeld()) { - multicastLock.release(); - } +// if (multicastLock.isHeld()) { +// multicastLock.release(); +// } } /** @@ -742,7 +742,7 @@ public Context getContext() { } public void onDestroy() { - unregisterBroadcastReceiver(); + //unregisterBroadcastReceiver(); } public List<DiscoveryProvider> getDiscoveryProviders() { diff --git a/src/com/connectsdk/service/netcast/NetcastHttpServer.java b/src/com/connectsdk/service/netcast/NetcastHttpServer.java index 5b2e7f6d..be50be9b 100644 --- a/src/com/connectsdk/service/netcast/NetcastHttpServer.java +++ b/src/com/connectsdk/service/netcast/NetcastHttpServer.java @@ -136,7 +136,7 @@ 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; @@ -144,7 +144,7 @@ public void start() { outToClient = new DataOutputStream(connectionSocket.getOutputStream()); out = new PrintWriter(outToClient); 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"); diff --git a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index bc91fe85..3a66e840 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -45,7 +45,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Build; +//import android.os.Build; import android.util.Base64; import android.util.Log; import android.util.SparseArray; @@ -375,10 +375,10 @@ 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); From 4a7b9a34f9cd06666f6d5abebddbe684033b8458 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 21:28:07 +0100 Subject: [PATCH 14/41] removed applicationinfo packageinfo and packagemanager --- src/android/content/Context.java | 98 +----------- src/android/content/pm/ApplicationInfo.java | 63 -------- src/android/content/pm/PackageInfo.java | 33 ---- src/android/content/pm/PackageItemInfo.java | 27 ---- src/android/content/pm/PackageManager.java | 150 ------------------ .../device/DefaultConnectableDeviceStore.java | 10 +- .../connectsdk/service/WebOSTVService.java | 5 +- .../webos/WebOSTVServiceSocketClient.java | 16 +- 8 files changed, 12 insertions(+), 390 deletions(-) delete mode 100644 src/android/content/pm/ApplicationInfo.java delete mode 100644 src/android/content/pm/PackageInfo.java delete mode 100644 src/android/content/pm/PackageItemInfo.java delete mode 100644 src/android/content/pm/PackageManager.java diff --git a/src/android/content/Context.java b/src/android/content/Context.java index 7190d547..7f93dd34 100644 --- a/src/android/content/Context.java +++ b/src/android/content/Context.java @@ -1,97 +1,9 @@ package android.content; - /** Context that must be implemented for the library to interface with surrounding systems. */ -public abstract class Context -{ -public abstract android.content.pm.PackageManager getPackageManager(); -//public abstract android.content.Context getApplicationContext(); -//public abstract void setTheme(int resid); -//public abstract java.lang.ClassLoader getClassLoader(); -public abstract java.lang.String getPackageName(); -//public abstract android.content.pm.ApplicationInfo getApplicationInfo(); -//public abstract java.lang.String getPackageResourcePath(); -//public abstract java.lang.String getPackageCodePath(); -//public abstract java.io.FileInputStream openFileInput(java.lang.String name) throws java.io.FileNotFoundException; -//public abstract java.io.FileOutputStream openFileOutput(java.lang.String name, int mode) throws java.io.FileNotFoundException; -//public abstract boolean deleteFile(java.lang.String name); -//public abstract java.io.File getFileStreamPath(java.lang.String name); -//public abstract java.io.File getFilesDir(); -//public abstract java.io.File getExternalFilesDir(java.lang.String type); -//public abstract java.io.File getObbDir(); -//public abstract java.io.File getCacheDir(); -//public abstract java.io.File getExternalCacheDir(); -//public abstract java.lang.String[] fileList(); -//public abstract java.io.File getDir(java.lang.String name, int mode); -//public abstract boolean deleteDatabase(java.lang.String name); -//public abstract java.io.File getDatabasePath(java.lang.String name); -//public abstract java.lang.String[] databaseList(); -//@java.lang.Deprecated() -//public abstract int getWallpaperDesiredMinimumWidth(); -//@java.lang.Deprecated() -//public abstract int getWallpaperDesiredMinimumHeight(); -//@java.lang.Deprecated() -//public abstract void setWallpaper(java.io.InputStream data) throws java.io.IOException; -//@java.lang.Deprecated() -//public abstract void clearWallpaper() throws java.io.IOException; -//public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver receiver, android.content.IntentFilter filter); -//public abstract void unregisterReceiver(android.content.BroadcastReceiver receiver); -//public abstract java.lang.Object getSystemService(java.lang.String name); -//public abstract int checkPermission(java.lang.String permission, int pid, int uid); -//public abstract int checkCallingPermission(java.lang.String permission); -//public abstract int checkCallingOrSelfPermission(java.lang.String permission); -//public abstract void enforcePermission(java.lang.String permission, int pid, int uid, java.lang.String message); -//public abstract void enforceCallingPermission(java.lang.String permission, java.lang.String message); -//public abstract void enforceCallingOrSelfPermission(java.lang.String permission, java.lang.String message); -//public abstract android.content.Context createPackageContext(java.lang.String packageName, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public boolean isRestricted() { throw new RuntimeException("Stub!"); } -//public static final int MODE_PRIVATE = 0; -//public static final int MODE_WORLD_READABLE = 1; -//public static final int MODE_WORLD_WRITEABLE = 2; -//public static final int MODE_APPEND = 32768; -//public static final int MODE_MULTI_PROCESS = 4; -//public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; -//public static final int BIND_AUTO_CREATE = 1; -//public static final int BIND_DEBUG_UNBIND = 2; -//public static final int BIND_NOT_FOREGROUND = 4; -//public static final int BIND_ABOVE_CLIENT = 8; -//public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; -//public static final int BIND_WAIVE_PRIORITY = 32; -//public static final int BIND_IMPORTANT = 64; -//public static final int BIND_ADJUST_WITH_ACTIVITY = 128; -//public static final java.lang.String POWER_SERVICE = "power"; -//public static final java.lang.String WINDOW_SERVICE = "window"; -//public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater"; -//public static final java.lang.String ACCOUNT_SERVICE = "account"; -//public static final java.lang.String ACTIVITY_SERVICE = "activity"; -//public static final java.lang.String ALARM_SERVICE = "alarm"; -//public static final java.lang.String NOTIFICATION_SERVICE = "notification"; -//public static final java.lang.String ACCESSIBILITY_SERVICE = "accessibility"; -//public static final java.lang.String KEYGUARD_SERVICE = "keyguard"; -//public static final java.lang.String LOCATION_SERVICE = "location"; -//public static final java.lang.String SEARCH_SERVICE = "search"; -//public static final java.lang.String SENSOR_SERVICE = "sensor"; -//public static final java.lang.String STORAGE_SERVICE = "storage"; -//public static final java.lang.String WALLPAPER_SERVICE = "wallpaper"; -//public static final java.lang.String VIBRATOR_SERVICE = "vibrator"; -//public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity"; -//public static final java.lang.String WIFI_SERVICE = "wifi"; -//public static final java.lang.String WIFI_P2P_SERVICE = "wifip2p"; -//public static final java.lang.String NSD_SERVICE = "servicediscovery"; -//public static final java.lang.String AUDIO_SERVICE = "audio"; -//public static final java.lang.String MEDIA_ROUTER_SERVICE = "media_router"; -//public static final java.lang.String TELEPHONY_SERVICE = "phone"; -//public static final java.lang.String CLIPBOARD_SERVICE = "clipboard"; -//public static final java.lang.String INPUT_METHOD_SERVICE = "input_method"; -//public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices"; -//public static final java.lang.String DROPBOX_SERVICE = "dropbox"; -//public static final java.lang.String DEVICE_POLICY_SERVICE = "device_policy"; -//public static final java.lang.String UI_MODE_SERVICE = "uimode"; -//public static final java.lang.String DOWNLOAD_SERVICE = "download"; -//public static final java.lang.String NFC_SERVICE = "nfc"; -//public static final java.lang.String USB_SERVICE = "usb"; -//public static final java.lang.String INPUT_SERVICE = "input"; -//public static final int CONTEXT_INCLUDE_CODE = 1; -//public static final int CONTEXT_IGNORE_SECURITY = 2; -//public static final int CONTEXT_RESTRICTED = 4; +public abstract class Context { + public abstract String getPackageName(); + public abstract String getDataDir(); + public abstract android.graphics.drawable.Drawable getIcon(); + public abstract String getApplicationName(); } diff --git a/src/android/content/pm/ApplicationInfo.java b/src/android/content/pm/ApplicationInfo.java deleted file mode 100644 index 94c1b43c..00000000 --- a/src/android/content/pm/ApplicationInfo.java +++ /dev/null @@ -1,63 +0,0 @@ -package android.content.pm; -public class ApplicationInfo extends android.content.pm.PackageItemInfo // implements android.os.Parcelable -{ -//public static class DisplayNameComparator -// implements java.util.Comparator<android.content.pm.ApplicationInfo> -//{ -//public DisplayNameComparator(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -//public final int compare(android.content.pm.ApplicationInfo aa, android.content.pm.ApplicationInfo ab) { throw new RuntimeException("Stub!"); } -//} -//public ApplicationInfo() { /*throw new RuntimeException("Stub!");*/ } -//public ApplicationInfo(android.content.pm.ApplicationInfo orig) { throw new RuntimeException("Stub!"); } -//public void dump(android.util.Printer pw, java.lang.String prefix) { throw new RuntimeException("Stub!"); } -//public java.lang.String toString() { throw new RuntimeException("Stub!"); } -//public int describeContents() { throw new RuntimeException("Stub!"); } -//public void writeToParcel(android.os.Parcel dest, int parcelableFlags) { throw new RuntimeException("Stub!"); } -//public java.lang.CharSequence loadDescription(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -//public java.lang.String taskAffinity; -//public java.lang.String permission; -//public java.lang.String processName; -//public java.lang.String className; -//public int descriptionRes; -//public int theme; -//public java.lang.String manageSpaceActivityName; -//public java.lang.String backupAgentName; -//public int uiOptions; -//public static final int FLAG_SYSTEM = 1; -//public static final int FLAG_DEBUGGABLE = 2; -//public static final int FLAG_HAS_CODE = 4; -//public static final int FLAG_PERSISTENT = 8; -//public static final int FLAG_FACTORY_TEST = 16; -//public static final int FLAG_ALLOW_TASK_REPARENTING = 32; -//public static final int FLAG_ALLOW_CLEAR_USER_DATA = 64; -//public static final int FLAG_UPDATED_SYSTEM_APP = 128; -//public static final int FLAG_TEST_ONLY = 256; -//public static final int FLAG_SUPPORTS_SMALL_SCREENS = 512; -//public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1024; -//public static final int FLAG_SUPPORTS_LARGE_SCREENS = 2048; -//public static final int FLAG_RESIZEABLE_FOR_SCREENS = 4096; -//public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 8192; -//public static final int FLAG_VM_SAFE_MODE = 16384; -//public static final int FLAG_ALLOW_BACKUP = 32768; -//public static final int FLAG_KILL_AFTER_RESTORE = 65536; -//public static final int FLAG_RESTORE_ANY_VERSION = 131072; -//public static final int FLAG_EXTERNAL_STORAGE = 262144; -//public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 524288; -//public static final int FLAG_LARGE_HEAP = 1048576; -//public static final int FLAG_STOPPED = 2097152; -//public int flags; -//public int requiresSmallestWidthDp; -//public int compatibleWidthLimitDp; -//public int largestWidthLimitDp; -//public java.lang.String sourceDir; -//public java.lang.String publicSourceDir; -//public java.lang.String[] sharedLibraryFiles = null; -public java.lang.String dataDir; -//public java.lang.String nativeLibraryDir; -//public int uid; -//public int targetSdkVersion; -//public boolean enabled; -//public static final android.os.Parcelable.Creator<android.content.pm.ApplicationInfo> CREATOR; -//static { CREATOR = null; } -} - diff --git a/src/android/content/pm/PackageInfo.java b/src/android/content/pm/PackageInfo.java deleted file mode 100644 index c2d2fc77..00000000 --- a/src/android/content/pm/PackageInfo.java +++ /dev/null @@ -1,33 +0,0 @@ -package android.content.pm; -public class PackageInfo -// implements android.os.Parcelable -{ -public PackageInfo() { /*throw new RuntimeException("Stub!"); */} -//public java.lang.String toString() { throw new RuntimeException("Stub!"); } -//public int describeContents() { throw new RuntimeException("Stub!"); } -//public void writeToParcel(android.os.Parcel dest, int parcelableFlags) { throw new RuntimeException("Stub!"); } -//public java.lang.String packageName; -//public int versionCode; -//public java.lang.String versionName; -//public java.lang.String sharedUserId; -//public int sharedUserLabel; -public android.content.pm.ApplicationInfo applicationInfo; -//public long firstInstallTime; -//public long lastUpdateTime; -//public int[] gids = null; -//public android.content.pm.ActivityInfo[] activities = null; -//public android.content.pm.ActivityInfo[] receivers = null; -//public android.content.pm.ServiceInfo[] services = null; -//public android.content.pm.ProviderInfo[] providers = null; -//public android.content.pm.InstrumentationInfo[] instrumentation = null; -//public android.content.pm.PermissionInfo[] permissions = null; -//public java.lang.String[] requestedPermissions = null; -//public int[] requestedPermissionsFlags = null; -//public static final int REQUESTED_PERMISSION_REQUIRED = 1; -//public static final int REQUESTED_PERMISSION_GRANTED = 2; -//public android.content.pm.Signature[] signatures = null; -//public android.content.pm.ConfigurationInfo[] configPreferences = null; -//public android.content.pm.FeatureInfo[] reqFeatures = null; -//public static final android.os.Parcelable.Creator<android.content.pm.PackageInfo> CREATOR; -//static { CREATOR = null; } -} diff --git a/src/android/content/pm/PackageItemInfo.java b/src/android/content/pm/PackageItemInfo.java deleted file mode 100644 index ded58f99..00000000 --- a/src/android/content/pm/PackageItemInfo.java +++ /dev/null @@ -1,27 +0,0 @@ -package android.content.pm; -public class PackageItemInfo -{ -//public static class DisplayNameComparator -// implements java.util.Comparator<android.content.pm.PackageItemInfo> -//{ -//public DisplayNameComparator(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -//public final int compare(android.content.pm.PackageItemInfo aa, android.content.pm.PackageItemInfo ab) { throw new RuntimeException("Stub!"); } -//} -public PackageItemInfo() { /*throw new RuntimeException("Stub!");*/ } -//public PackageItemInfo(android.content.pm.PackageItemInfo orig) { throw new RuntimeException("Stub!"); } -//protected PackageItemInfo(android.os.Parcel source) { throw new RuntimeException("Stub!"); } -//public java.lang.CharSequence loadLabel(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -//public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -//public android.graphics.drawable.Drawable loadLogo(android.content.pm.PackageManager pm) { throw new RuntimeException("Stub!"); } -//public android.content.res.XmlResourceParser loadXmlMetaData(android.content.pm.PackageManager pm, java.lang.String name) { throw new RuntimeException("Stub!"); } -//protected void dumpFront(android.util.Printer pw, java.lang.String prefix) { throw new RuntimeException("Stub!"); } -//protected void dumpBack(android.util.Printer pw, java.lang.String prefix) { throw new RuntimeException("Stub!"); } -//public void writeToParcel(android.os.Parcel dest, int parcelableFlags) { throw new RuntimeException("Stub!"); } -//public java.lang.String name; -//public java.lang.String packageName; -//public int labelRes; -//public java.lang.CharSequence nonLocalizedLabel; -//public int icon; -//public int logo; -//public android.os.Bundle metaData; -} diff --git a/src/android/content/pm/PackageManager.java b/src/android/content/pm/PackageManager.java deleted file mode 100644 index e5cccbed..00000000 --- a/src/android/content/pm/PackageManager.java +++ /dev/null @@ -1,150 +0,0 @@ -package android.content.pm; -public abstract class PackageManager -{ -public static class NameNotFoundException extends java.lang.Exception { -//public NameNotFoundException() { } -//public NameNotFoundException(java.lang.String name) { throw new RuntimeException("Stub!"); } -} -//public PackageManager() { /*throw new RuntimeException("Stub!");*/ } -public abstract android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract java.lang.String[] currentToCanonicalPackageNames(java.lang.String[] names); -//public abstract java.lang.String[] canonicalToCurrentPackageNames(java.lang.String[] names); -//public abstract android.content.Intent getLaunchIntentForPackage(java.lang.String packageName); -//public abstract int[] getPackageGids(java.lang.String packageName) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.content.pm.PermissionInfo getPermissionInfo(java.lang.String name, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(java.lang.String group, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(java.lang.String name, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int flags); -public abstract android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String packageName, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.content.pm.ActivityInfo getReceiverInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.content.pm.ProviderInfo getProviderInfo(android.content.ComponentName component, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int flags); -//public abstract int checkPermission(java.lang.String permName, java.lang.String pkgName); -//public abstract boolean addPermission(android.content.pm.PermissionInfo info); -//public abstract boolean addPermissionAsync(android.content.pm.PermissionInfo info); -//public abstract void removePermission(java.lang.String name); -//public abstract int checkSignatures(java.lang.String pkg1, java.lang.String pkg2); -//public abstract int checkSignatures(int uid1, int uid2); -//public abstract java.lang.String[] getPackagesForUid(int uid); -//public abstract java.lang.String getNameForUid(int uid); -//public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int flags); -//public abstract java.lang.String[] getSystemSharedLibraryNames(); -//public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures(); -//public abstract boolean hasSystemFeature(java.lang.String name); -//public abstract android.content.pm.ResolveInfo resolveActivity(android.content.Intent intent, int flags); -//public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivities(android.content.Intent intent, int flags); -//public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivityOptions(android.content.ComponentName caller, android.content.Intent[] specifics, android.content.Intent intent, int flags); -//public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent intent, int flags); -//public abstract android.content.pm.ResolveInfo resolveService(android.content.Intent intent, int flags); -//public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentServices(android.content.Intent intent, int flags); -//public abstract android.content.pm.ProviderInfo resolveContentProvider(java.lang.String name, int flags); -//public abstract java.util.List<android.content.pm.ProviderInfo> queryContentProviders(java.lang.String processName, int uid, int flags); -//public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName className, int flags) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract java.util.List<android.content.pm.InstrumentationInfo> queryInstrumentation(java.lang.String targetPackage, int flags); -//public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String packageName, int resid, android.content.pm.ApplicationInfo appInfo); -//public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName activityName) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.Intent intent) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.graphics.drawable.Drawable getDefaultActivityIcon(); -//public abstract android.graphics.drawable.Drawable getApplicationIcon(android.content.pm.ApplicationInfo info); -public abstract android.graphics.drawable.Drawable getApplicationIcon(java.lang.String packageName) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName activityName) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.Intent intent) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo info); -//public abstract android.graphics.drawable.Drawable getApplicationLogo(java.lang.String packageName) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract java.lang.CharSequence getText(java.lang.String packageName, int resid, android.content.pm.ApplicationInfo appInfo); -//public abstract android.content.res.XmlResourceParser getXml(java.lang.String packageName, int resid, android.content.pm.ApplicationInfo appInfo); -public abstract java.lang.CharSequence getApplicationLabel(android.content.pm.ApplicationInfo info); -//public abstract android.content.res.Resources getResourcesForActivity(android.content.ComponentName activityName) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo app) throws android.content.pm.PackageManager.NameNotFoundException; -//public abstract android.content.res.Resources getResourcesForApplication(java.lang.String appPackageName) throws android.content.pm.PackageManager.NameNotFoundException; -//public android.content.pm.PackageInfo getPackageArchiveInfo(java.lang.String archiveFilePath, int flags) { throw new RuntimeException("Stub!"); } -//public abstract void verifyPendingInstall(int id, int verificationCode); -//public abstract void setInstallerPackageName(java.lang.String targetPackage, java.lang.String installerPackageName); -//public abstract java.lang.String getInstallerPackageName(java.lang.String packageName); -//@java.lang.Deprecated() -//public abstract void addPackageToPreferred(java.lang.String packageName); -//@java.lang.Deprecated() -//public abstract void removePackageFromPreferred(java.lang.String packageName); -//public abstract java.util.List<android.content.pm.PackageInfo> getPreferredPackages(int flags); -//@java.lang.Deprecated() -//public abstract void addPreferredActivity(android.content.IntentFilter filter, int match, android.content.ComponentName[] set, android.content.ComponentName activity); -//public abstract void clearPackagePreferredActivities(java.lang.String packageName); -//public abstract int getPreferredActivities(java.util.List<android.content.IntentFilter> outFilters, java.util.List<android.content.ComponentName> outActivities, java.lang.String packageName); -//public abstract void setComponentEnabledSetting(android.content.ComponentName componentName, int newState, int flags); -//public abstract int getComponentEnabledSetting(android.content.ComponentName componentName); -//public abstract void setApplicationEnabledSetting(java.lang.String packageName, int newState, int flags); -//public abstract int getApplicationEnabledSetting(java.lang.String packageName); -//public abstract boolean isSafeMode(); -//public static final int GET_ACTIVITIES = 1; -//public static final int GET_RECEIVERS = 2; -//public static final int GET_SERVICES = 4; -//public static final int GET_PROVIDERS = 8; -//public static final int GET_INSTRUMENTATION = 16; -//public static final int GET_INTENT_FILTERS = 32; -//public static final int GET_SIGNATURES = 64; -//public static final int GET_RESOLVED_FILTER = 64; -//public static final int GET_META_DATA = 128; -//public static final int GET_GIDS = 256; -//public static final int GET_DISABLED_COMPONENTS = 512; -//public static final int GET_SHARED_LIBRARY_FILES = 1024; -//public static final int GET_URI_PERMISSION_PATTERNS = 2048; -//public static final int GET_PERMISSIONS = 4096; -//public static final int GET_UNINSTALLED_PACKAGES = 8192; -//public static final int GET_CONFIGURATIONS = 16384; -//public static final int MATCH_DEFAULT_ONLY = 65536; -//public static final int PERMISSION_GRANTED = 0; -//public static final int PERMISSION_DENIED = -1; -//public static final int SIGNATURE_MATCH = 0; -//public static final int SIGNATURE_NEITHER_SIGNED = 1; -//public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; -//public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; -//public static final int SIGNATURE_NO_MATCH = -3; -//public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; -//public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; -//public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; -//public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; -//public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; -//public static final int DONT_KILL_APP = 1; -//public static final int VERIFICATION_ALLOW = 1; -//public static final int VERIFICATION_REJECT = -1; -//public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency"; -//public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth"; -//public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera"; -//public static final java.lang.String FEATURE_CAMERA_AUTOFOCUS = "android.hardware.camera.autofocus"; -//public static final java.lang.String FEATURE_CAMERA_FLASH = "android.hardware.camera.flash"; -//public static final java.lang.String FEATURE_CAMERA_FRONT = "android.hardware.camera.front"; -//public static final java.lang.String FEATURE_LOCATION = "android.hardware.location"; -//public static final java.lang.String FEATURE_LOCATION_GPS = "android.hardware.location.gps"; -//public static final java.lang.String FEATURE_LOCATION_NETWORK = "android.hardware.location.network"; -//public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone"; -//public static final java.lang.String FEATURE_NFC = "android.hardware.nfc"; -//public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer"; -//public static final java.lang.String FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer"; -//public static final java.lang.String FEATURE_SENSOR_COMPASS = "android.hardware.sensor.compass"; -//public static final java.lang.String FEATURE_SENSOR_GYROSCOPE = "android.hardware.sensor.gyroscope"; -//public static final java.lang.String FEATURE_SENSOR_LIGHT = "android.hardware.sensor.light"; -//public static final java.lang.String FEATURE_SENSOR_PROXIMITY = "android.hardware.sensor.proximity"; -//public static final java.lang.String FEATURE_TELEPHONY = "android.hardware.telephony"; -//public static final java.lang.String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma"; -//public static final java.lang.String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm"; -//public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host"; -//public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory"; -//public static final java.lang.String FEATURE_SIP = "android.software.sip"; -//public static final java.lang.String FEATURE_SIP_VOIP = "android.software.sip.voip"; -//public static final java.lang.String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen"; -//public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch"; -//public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct"; -//public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = "android.hardware.touchscreen.multitouch.jazzhand"; -//public static final java.lang.String FEATURE_FAKETOUCH = "android.hardware.faketouch"; -//public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT = "android.hardware.faketouch.multitouch.distinct"; -//public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand"; -//public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait"; -//public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape"; -//public static final java.lang.String FEATURE_LIVE_WALLPAPER = "android.software.live_wallpaper"; -//public static final java.lang.String FEATURE_WIFI = "android.hardware.wifi"; -//public static final java.lang.String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct"; -//public static final java.lang.String FEATURE_TELEVISION = "android.hardware.type.television"; -//public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID"; -} diff --git a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java index 6ff0b0f4..b68e1c92 100644 --- a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java +++ b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java @@ -34,7 +34,6 @@ import org.json.JSONObject; import android.content.Context; -import android.content.pm.PackageManager.NameNotFoundException; import android.os.Environment; import com.connectsdk.core.Util; @@ -111,12 +110,9 @@ public DefaultConnectableDeviceStore(Context context) { } 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 diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index 4dc2a75a..e50db0a5 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -79,7 +79,6 @@ import com.connectsdk.service.webos.WebOSTVServiceSocketClient.WebOSTVServiceSocketClientListener; import android.content.Context; -import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.Bitmap; import android.graphics.PointF; import android.graphics.drawable.BitmapDrawable; @@ -898,7 +897,7 @@ private void sendToast(JSONObject payload, ResponseListener<Object> listener) { Context context = DiscoveryManager.getInstance().getContext(); try { - Drawable drawable = context.getPackageManager().getApplicationIcon(context.getPackageName()); + Drawable drawable = context.getIcon(); if (drawable != null) { BitmapDrawable bitDw = ((BitmapDrawable) drawable); @@ -914,8 +913,6 @@ private void sendToast(JSONObject payload, ResponseListener<Object> listener) { payload.put("iconData", bitmapData); payload.put("iconExtension", "png"); } - } catch (NameNotFoundException e) { - e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } diff --git a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index 3a66e840..d3e482fb 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -42,9 +42,6 @@ import com.connectsdk.service.config.WebOSTVServiceConfig; 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; @@ -366,8 +363,7 @@ protected void handleMessage(JSONObject message) { private void helloTV() { Context context = DiscoveryManager.getInstance().getContext(); - PackageManager packageManager = context.getPackageManager(); - + // app Id String packageName = context.getPackageName(); @@ -393,14 +389,8 @@ private void helloTV() { 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; From 6ae3beaf3060d9b9d84b9d39cddd187f48bc9dcd Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 21:39:16 +0100 Subject: [PATCH 15/41] removed base64 dependency --- src/android/util/Base64.java | 24 ----------------- .../connectsdk/service/WebOSTVService.java | 26 ------------------- .../service/config/WebOSTVServiceConfig.java | 6 +++-- .../webos/WebOSTVServiceSocketClient.java | 5 ++-- 4 files changed, 7 insertions(+), 54 deletions(-) delete mode 100644 src/android/util/Base64.java diff --git a/src/android/util/Base64.java b/src/android/util/Base64.java deleted file mode 100644 index 4bc677a5..00000000 --- a/src/android/util/Base64.java +++ /dev/null @@ -1,24 +0,0 @@ -package android.util; - -import javax.xml.bind.DatatypeConverter; - -public class Base64 -{ -Base64() { throw new RuntimeException("Stub!"); } -public static byte[] decode(java.lang.String str, int flags) { throw new RuntimeException("Stub!"); } -public static byte[] decode(byte[] input, int flags) { throw new RuntimeException("Stub!"); } -public static byte[] decode(byte[] input, int offset, int len, int flags) { throw new RuntimeException("Stub!"); } -public static java.lang.String encodeToString(byte[] input, int flags) { - //return java.util.Base64.getEncoder().encodeToString(input); // only available in java 1.8 - return DatatypeConverter.printBase64Binary(input); -} -public static java.lang.String encodeToString(byte[] input, int offset, int len, int flags) { throw new RuntimeException("Stub!"); } -public static byte[] encode(byte[] input, int flags) { throw new RuntimeException("Stub!"); } -public static byte[] encode(byte[] input, int offset, int len, int flags) { throw new RuntimeException("Stub!"); } -public static final int DEFAULT = 0; -public static final int NO_PADDING = 1; -public static final int NO_WRAP = 2; -public static final int CRLF = 4; -public static final int URL_SAFE = 8; -public static final int NO_CLOSE = 16; -} diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index e50db0a5..e4e5bc2c 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -84,7 +84,6 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.support.annotation.NonNull; -import android.util.Base64; import android.util.Log; public class WebOSTVService extends DeviceService @@ -893,31 +892,6 @@ public void showClickableToastForURL(String message, String url, String iconData } private void sendToast(JSONObject payload, ResponseListener<Object> listener) { - if (!payload.has("iconData")) { - Context context = DiscoveryManager.getInstance().getContext(); - - try { - Drawable drawable = context.getIcon(); - - 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 (JSONException e) { - e.printStackTrace(); - } - } - String uri = "palm://system.notifications/createToast"; ServiceCommand<ResponseListener<Object>> request = new ServiceCommand<ResponseListener<Object>>(this, uri, payload, true, listener); 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/webos/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index d3e482fb..f2a13f79 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -19,6 +19,7 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; +import javax.xml.bind.DatatypeConverter; import org.java_websocket.WebSocket; //2016-01-01: Moved from 1.3.0 to 1.3.1-snapshot @@ -43,7 +44,6 @@ import android.content.Context; //import android.os.Build; -import android.util.Base64; import android.util.Log; import android.util.SparseArray; //import android.view.Display; @@ -796,7 +796,8 @@ public String getServerCertificateInString() { 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; From dd7f2cb80edaaa779b7a09d4cfa26497ed529476 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 21:54:20 +0100 Subject: [PATCH 16/41] removed environment dependency --- src/android/os/Environment.java | 48 ------------------- .../device/DefaultConnectableDeviceStore.java | 10 ---- .../connectsdk/service/WebOSTVService.java | 4 -- 3 files changed, 62 deletions(-) delete mode 100644 src/android/os/Environment.java diff --git a/src/android/os/Environment.java b/src/android/os/Environment.java deleted file mode 100644 index faf2fd8a..00000000 --- a/src/android/os/Environment.java +++ /dev/null @@ -1,48 +0,0 @@ -package android.os; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class Environment -{ - final static File tempDir; - static { - File dir; - try { - dir = Files.createTempDirectory("connectsdk").toFile(); - } catch (IOException ex) { - Logger.getLogger(Environment.class.getName()).log(Level.SEVERE, null, ex); - dir = null; - } - tempDir = dir; - } -//public static java.io.File getRootDirectory() { throw new RuntimeException("Stub!"); } -//public static java.io.File getDataDirectory() { throw new RuntimeException("Stub!"); } -public static java.io.File getExternalStorageDirectory() { return tempDir; } -//public static java.io.File getExternalStoragePublicDirectory(java.lang.String type) { throw new RuntimeException("Stub!"); } -//public static java.io.File getDownloadCacheDirectory() { throw new RuntimeException("Stub!"); } -public static java.lang.String getExternalStorageState() { return Environment.MEDIA_MOUNTED; /*throw new RuntimeException("Stub!");*/ } -//public static boolean isExternalStorageRemovable() { throw new RuntimeException("Stub!"); } -//public static boolean isExternalStorageEmulated() { throw new RuntimeException("Stub!"); } -//public static java.lang.String DIRECTORY_MUSIC; -//public static java.lang.String DIRECTORY_PODCASTS; -//public static java.lang.String DIRECTORY_RINGTONES; -//public static java.lang.String DIRECTORY_ALARMS; -//public static java.lang.String DIRECTORY_NOTIFICATIONS; -//public static java.lang.String DIRECTORY_PICTURES; -//public static java.lang.String DIRECTORY_MOVIES; -//public static java.lang.String DIRECTORY_DOWNLOADS; -//public static java.lang.String DIRECTORY_DCIM; -//public static final java.lang.String MEDIA_REMOVED = "removed"; -public static final java.lang.String MEDIA_UNMOUNTED = "unmounted"; -//public static final java.lang.String MEDIA_CHECKING = "checking"; -//public static final java.lang.String MEDIA_NOFS = "nofs"; -public static final java.lang.String MEDIA_MOUNTED = "mounted"; -//public static final java.lang.String MEDIA_MOUNTED_READ_ONLY = "mounted_ro"; -//public static final java.lang.String MEDIA_SHARED = "shared"; -//public static final java.lang.String MEDIA_BAD_REMOVAL = "bad_removal"; -//public static final java.lang.String MEDIA_UNMOUNTABLE = "unmountable"; -} diff --git a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java index b68e1c92..728324e9 100644 --- a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java +++ b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java @@ -101,16 +101,6 @@ public class DefaultConnectableDeviceStore implements ConnectableDeviceStore { 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; - - fileFullPath = context.getDataDir() + "/" + FILENAME; load(); diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index e4e5bc2c..cf1d5de4 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -78,11 +78,7 @@ import com.connectsdk.service.webos.WebOSTVServiceSocketClient; import com.connectsdk.service.webos.WebOSTVServiceSocketClient.WebOSTVServiceSocketClientListener; -import android.content.Context; -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.Log; From e71f66db043e5b4c85745be256ed273e455606df Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 22:00:01 +0100 Subject: [PATCH 17/41] removed drawable dependency --- .../graphics/drawable/BitmapDrawable.java | 46 ------------- src/android/graphics/drawable/Drawable.java | 66 ------------------- 2 files changed, 112 deletions(-) delete mode 100644 src/android/graphics/drawable/BitmapDrawable.java delete mode 100644 src/android/graphics/drawable/Drawable.java diff --git a/src/android/graphics/drawable/BitmapDrawable.java b/src/android/graphics/drawable/BitmapDrawable.java deleted file mode 100644 index 3d89963c..00000000 --- a/src/android/graphics/drawable/BitmapDrawable.java +++ /dev/null @@ -1,46 +0,0 @@ -package android.graphics.drawable; -public class BitmapDrawable - extends android.graphics.drawable.Drawable -{ -//@java.lang.Deprecated() -//public BitmapDrawable() { throw new RuntimeException("Stub!"); } -//@java.lang.SuppressWarnings(value={"UnusedParameters"}) -//public BitmapDrawable(android.content.res.Resources res) { throw new RuntimeException("Stub!"); } -//@java.lang.Deprecated() -//public BitmapDrawable(android.graphics.Bitmap bitmap) { throw new RuntimeException("Stub!"); } -//public BitmapDrawable(android.content.res.Resources res, android.graphics.Bitmap bitmap) { throw new RuntimeException("Stub!"); } -//@java.lang.Deprecated() -//public BitmapDrawable(java.lang.String filepath) { throw new RuntimeException("Stub!"); } -//@java.lang.SuppressWarnings(value={"UnusedParameters"}) -//public BitmapDrawable(android.content.res.Resources res, java.lang.String filepath) { throw new RuntimeException("Stub!"); } -//@java.lang.Deprecated() -//public BitmapDrawable(java.io.InputStream is) { throw new RuntimeException("Stub!"); } -//@java.lang.SuppressWarnings(value={"UnusedParameters"}) -//public BitmapDrawable(android.content.res.Resources res, java.io.InputStream is) { throw new RuntimeException("Stub!"); } -//public final android.graphics.Paint getPaint() { throw new RuntimeException("Stub!"); } -public final android.graphics.Bitmap getBitmap() { throw new RuntimeException("Stub!"); } -//public void setTargetDensity(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } -//public void setTargetDensity(android.util.DisplayMetrics metrics) { throw new RuntimeException("Stub!"); } -//public void setTargetDensity(int density) { throw new RuntimeException("Stub!"); } -//public int getGravity() { throw new RuntimeException("Stub!"); } -//public void setGravity(int gravity) { throw new RuntimeException("Stub!"); } -//public void setAntiAlias(boolean aa) { throw new RuntimeException("Stub!"); } -//public void setFilterBitmap(boolean filter) { throw new RuntimeException("Stub!"); } -//public void setDither(boolean dither) { throw new RuntimeException("Stub!"); } -//public android.graphics.Shader.TileMode getTileModeX() { throw new RuntimeException("Stub!"); } -//public android.graphics.Shader.TileMode getTileModeY() { throw new RuntimeException("Stub!"); } -//public void setTileModeX(android.graphics.Shader.TileMode mode) { throw new RuntimeException("Stub!"); } -//public final void setTileModeY(android.graphics.Shader.TileMode mode) { throw new RuntimeException("Stub!"); } -//public void setTileModeXY(android.graphics.Shader.TileMode xmode, android.graphics.Shader.TileMode ymode) { throw new RuntimeException("Stub!"); } -//public int getChangingConfigurations() { throw new RuntimeException("Stub!"); } -//protected void onBoundsChange(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } -//public void draw(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } -//public void setAlpha(int alpha) { throw new RuntimeException("Stub!"); } -//public void setColorFilter(android.graphics.ColorFilter cf) { throw new RuntimeException("Stub!"); } -//public android.graphics.drawable.Drawable mutate() { throw new RuntimeException("Stub!"); } -//public void inflate(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } -//public int getIntrinsicWidth() { throw new RuntimeException("Stub!"); } -//public int getIntrinsicHeight() { throw new RuntimeException("Stub!"); } -//public int getOpacity() { throw new RuntimeException("Stub!"); } -//public final android.graphics.drawable.Drawable.ConstantState getConstantState() { throw new RuntimeException("Stub!"); } -} diff --git a/src/android/graphics/drawable/Drawable.java b/src/android/graphics/drawable/Drawable.java deleted file mode 100644 index be8d99a4..00000000 --- a/src/android/graphics/drawable/Drawable.java +++ /dev/null @@ -1,66 +0,0 @@ -package android.graphics.drawable; -public abstract class Drawable -{ -//public static interface Callback -//{ -//public abstract void invalidateDrawable(android.graphics.drawable.Drawable who); -//public abstract void scheduleDrawable(android.graphics.drawable.Drawable who, java.lang.Runnable what, long when); -//public abstract void unscheduleDrawable(android.graphics.drawable.Drawable who, java.lang.Runnable what); -//} -//public abstract static class ConstantState -//{ -//public ConstantState() { throw new RuntimeException("Stub!"); } -//public abstract android.graphics.drawable.Drawable newDrawable(); -//public android.graphics.drawable.Drawable newDrawable(android.content.res.Resources res) { throw new RuntimeException("Stub!"); } -//public abstract int getChangingConfigurations(); -//} -//public Drawable() { throw new RuntimeException("Stub!"); } -//public abstract void draw(android.graphics.Canvas canvas); -//public void setBounds(int left, int top, int right, int bottom) { throw new RuntimeException("Stub!"); } -//public void setBounds(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } -//public final void copyBounds(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } -//public final android.graphics.Rect copyBounds() { throw new RuntimeException("Stub!"); } -//public final android.graphics.Rect getBounds() { throw new RuntimeException("Stub!"); } -//public void setChangingConfigurations(int configs) { throw new RuntimeException("Stub!"); } -//public int getChangingConfigurations() { throw new RuntimeException("Stub!"); } -//public void setDither(boolean dither) { throw new RuntimeException("Stub!"); } -//public void setFilterBitmap(boolean filter) { throw new RuntimeException("Stub!"); } -//public final void setCallback(android.graphics.drawable.Drawable.Callback cb) { throw new RuntimeException("Stub!"); } -//public android.graphics.drawable.Drawable.Callback getCallback() { throw new RuntimeException("Stub!"); } -//public void invalidateSelf() { throw new RuntimeException("Stub!"); } -//public void scheduleSelf(java.lang.Runnable what, long when) { throw new RuntimeException("Stub!"); } -//public void unscheduleSelf(java.lang.Runnable what) { throw new RuntimeException("Stub!"); } -//public abstract void setAlpha(int alpha); -//public abstract void setColorFilter(android.graphics.ColorFilter cf); -//public void setColorFilter(int color, android.graphics.PorterDuff.Mode mode) { throw new RuntimeException("Stub!"); } -//public void clearColorFilter() { throw new RuntimeException("Stub!"); } -//public boolean isStateful() { throw new RuntimeException("Stub!"); } -//public boolean setState(int[] stateSet) { throw new RuntimeException("Stub!"); } -//public int[] getState() { throw new RuntimeException("Stub!"); } -//public void jumpToCurrentState() { throw new RuntimeException("Stub!"); } -//public android.graphics.drawable.Drawable getCurrent() { throw new RuntimeException("Stub!"); } -//public final boolean setLevel(int level) { throw new RuntimeException("Stub!"); } -//public final int getLevel() { throw new RuntimeException("Stub!"); } -//public boolean setVisible(boolean visible, boolean restart) { throw new RuntimeException("Stub!"); } -//public final boolean isVisible() { throw new RuntimeException("Stub!"); } -//public abstract int getOpacity(); -//public static int resolveOpacity(int op1, int op2) { throw new RuntimeException("Stub!"); } -//public android.graphics.Region getTransparentRegion() { throw new RuntimeException("Stub!"); } -//protected boolean onStateChange(int[] state) { throw new RuntimeException("Stub!"); } -//protected boolean onLevelChange(int level) { throw new RuntimeException("Stub!"); } -//protected void onBoundsChange(android.graphics.Rect bounds) { throw new RuntimeException("Stub!"); } -//public int getIntrinsicWidth() { throw new RuntimeException("Stub!"); } -//public int getIntrinsicHeight() { throw new RuntimeException("Stub!"); } -//public int getMinimumWidth() { throw new RuntimeException("Stub!"); } -//public int getMinimumHeight() { throw new RuntimeException("Stub!"); } -//public boolean getPadding(android.graphics.Rect padding) { throw new RuntimeException("Stub!"); } -//public android.graphics.drawable.Drawable mutate() { throw new RuntimeException("Stub!"); } -//public static android.graphics.drawable.Drawable createFromStream(java.io.InputStream is, java.lang.String srcName) { throw new RuntimeException("Stub!"); } -//public static android.graphics.drawable.Drawable createFromResourceStream(android.content.res.Resources res, android.util.TypedValue value, java.io.InputStream is, java.lang.String srcName) { throw new RuntimeException("Stub!"); } -//public static android.graphics.drawable.Drawable createFromResourceStream(android.content.res.Resources res, android.util.TypedValue value, java.io.InputStream is, java.lang.String srcName, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -//public static android.graphics.drawable.Drawable createFromXml(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } -//public static android.graphics.drawable.Drawable createFromXmlInner(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } -//public static android.graphics.drawable.Drawable createFromPath(java.lang.String pathName) { throw new RuntimeException("Stub!"); } -//public void inflate(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs) throws org.xmlpull.v1.XmlPullParserException, java.io.IOException { throw new RuntimeException("Stub!"); } -//public android.graphics.drawable.Drawable.ConstantState getConstantState() { throw new RuntimeException("Stub!"); } -} From 128a0f297b7ecc088429b00eecf0a331cf9ca56b Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 22:00:34 +0100 Subject: [PATCH 18/41] removed drawable dependency --- src/android/content/Context.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/android/content/Context.java b/src/android/content/Context.java index 7f93dd34..303c460f 100644 --- a/src/android/content/Context.java +++ b/src/android/content/Context.java @@ -4,6 +4,5 @@ public abstract class Context { public abstract String getPackageName(); public abstract String getDataDir(); - public abstract android.graphics.drawable.Drawable getIcon(); public abstract String getApplicationName(); } From 56dee1f3b5ada67706eceb71dc5c09dfa64317ac Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 22:01:02 +0100 Subject: [PATCH 19/41] removed comments --- src/android/graphics/PointF.java | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/src/android/graphics/PointF.java b/src/android/graphics/PointF.java index 11a73de1..9e4d00af 100644 --- a/src/android/graphics/PointF.java +++ b/src/android/graphics/PointF.java @@ -1,25 +1,11 @@ package android.graphics; -public class PointF -// implements android.os.Parcelable -{ -//public PointF() { throw new RuntimeException("Stub!"); } -public PointF(float x, float y) { - this.x = x; - this.y = y; -} -////public PointF(android.graphics.Point p) { throw new RuntimeException("Stub!"); } -//public final void set(float x, float y) { throw new RuntimeException("Stub!"); } -//public final void set(android.graphics.PointF p) { throw new RuntimeException("Stub!"); } -//public final void negate() { throw new RuntimeException("Stub!"); } -//public final void offset(float dx, float dy) { throw new RuntimeException("Stub!"); } -//public final boolean equals(float x, float y) { throw new RuntimeException("Stub!"); } -//public final float length() { throw new RuntimeException("Stub!"); } -//public static float length(float x, float y) { throw new RuntimeException("Stub!"); } -//public int describeContents() { throw new RuntimeException("Stub!"); } -//public void writeToParcel(android.os.Parcel out, int flags) { throw new RuntimeException("Stub!"); } -//public void readFromParcel(android.os.Parcel in) { throw new RuntimeException("Stub!"); } -public float x; -public float y; -//public static final android.os.Parcelable.Creator<android.graphics.PointF> CREATOR; -//static { CREATOR = null; } +// maybe replace with point2d in awt +public class PointF { + public PointF(float x, float y) { + this.x = x; + this.y = y; + } + + public float x; + public float y; } From 18ff5aa37d7f29498e1f0b3a5d09ee7c5e964c9e Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 22:01:35 +0100 Subject: [PATCH 20/41] removed dependency to environment --- src/com/connectsdk/device/DefaultConnectableDeviceStore.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java index 728324e9..f7f089e1 100644 --- a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java +++ b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java @@ -34,7 +34,6 @@ import org.json.JSONObject; import android.content.Context; -import android.os.Environment; import com.connectsdk.core.Util; import com.connectsdk.service.DeviceService; From 562fc29cc1240f45c5de207bf901197f9e993443 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 22:04:24 +0100 Subject: [PATCH 21/41] removed display dependency --- src/android/view/Display.java | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/android/view/Display.java diff --git a/src/android/view/Display.java b/src/android/view/Display.java deleted file mode 100644 index 42510b44..00000000 --- a/src/android/view/Display.java +++ /dev/null @@ -1,20 +0,0 @@ -package android.view; -public class Display -{ -public Display() { } -public int getDisplayId() { throw new RuntimeException("Stub!"); } -//public void getSize(android.graphics.Point outSize) { throw new RuntimeException("Stub!"); } -//public void getRectSize(android.graphics.Rect outSize) { throw new RuntimeException("Stub!"); } -//public void getCurrentSizeRange(android.graphics.Point outSmallestSize, android.graphics.Point outLargestSize) { throw new RuntimeException("Stub!"); } -@java.lang.Deprecated() -public int getWidth() { return 0; /*throw new RuntimeException("Stub!"); */} -@java.lang.Deprecated() -public int getHeight() { return 0; /*throw new RuntimeException("Stub!"); */} -public int getRotation() { throw new RuntimeException("Stub!"); } -@java.lang.Deprecated() -public native int getOrientation(); -public int getPixelFormat() { throw new RuntimeException("Stub!"); } -public float getRefreshRate() { throw new RuntimeException("Stub!"); } -//public void getMetrics(android.util.DisplayMetrics outMetrics) { throw new RuntimeException("Stub!"); } -public static final int DEFAULT_DISPLAY = 0; -} From db472803ffeaee550b98fc28218701947b4ae94c Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 22:32:38 +0100 Subject: [PATCH 22/41] removed sparsearray dependency --- src/android/util/SparseArray.java | 356 ------------------ .../internal/util/GrowingArrayUtils.java | 170 --------- src/com/connectsdk/service/DeviceService.java | 4 +- .../webos/WebOSTVServiceSocketClient.java | 11 +- 4 files changed, 5 insertions(+), 536 deletions(-) delete mode 100644 src/android/util/SparseArray.java delete mode 100644 src/com/android/internal/util/GrowingArrayUtils.java diff --git a/src/android/util/SparseArray.java b/src/android/util/SparseArray.java deleted file mode 100644 index e2853c0b..00000000 --- a/src/android/util/SparseArray.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * 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 android.util; -//import com.android.internal.util.ArrayUtils; -import com.android.internal.util.GrowingArrayUtils; - -/** - * SparseArrays map integers to Objects. Unlike a normal array of Objects, - * there can be gaps in the indices. It is intended to be more memory efficient - * than using a HashMap to map Integers to Objects, both because it avoids - * auto-boxing keys and its data structure doesn't rely on an extra entry object - * for each mapping. - * - * <p>Note that this container keeps its mappings in an array data structure, - * using a binary search to find keys. The implementation is not intended to be appropriate for - * data structures - * that may contain large numbers of items. It is generally slower than a traditional - * HashMap, since lookups require a binary search and adds and removes require inserting - * and deleting entries in the array. For containers holding up to hundreds of items, - * the performance difference is not significant, less than 50%.</p> - * - * <p>To help with performance, the container includes an optimization when removing - * keys: instead of compacting its array immediately, it leaves the removed entry marked - * as deleted. The entry can then be re-used for the same key, or compacted later in - * a single garbage collection step of all removed entries. This garbage collection will - * need to be performed at any time the array needs to be grown or the the map size or - * entry values are retrieved.</p> - * - * <p>It is possible to iterate over the items in this container using - * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using - * <code>keyAt(int)</code> with ascending values of the index will return the - * keys in ascending order, or the values corresponding to the keys in ascending - * order in the case of <code>valueAt(int)</code>.</p> - */ -public class SparseArray<E> implements Cloneable { - private static final Object DELETED = new Object(); - private boolean mGarbage = false; - private int[] mKeys; - private Object[] mValues; - private int mSize; - /** - * Creates a new SparseArray containing no mappings. - */ - public SparseArray() { - this(10); - } - /** - * Creates a new SparseArray containing no mappings that will not - * require any additional memory allocation to store the specified - * number of mappings. If you supply an initial capacity of 0, the - * sparse array will be initialized with a light-weight representation - * not requiring any additional array allocations. - */ - public SparseArray(int initialCapacity) { - if (initialCapacity == 0) { - mKeys = new int[0]; - mValues = new Object[0]; - } else { - mValues = new Object[initialCapacity]; - mKeys = new int[mValues.length]; - } - mSize = 0; - } - @Override - @SuppressWarnings("unchecked") - public SparseArray<E> clone() { - SparseArray<E> clone = null; - try { - clone = (SparseArray<E>) super.clone(); - clone.mKeys = mKeys.clone(); - clone.mValues = mValues.clone(); - } catch (CloneNotSupportedException cnse) { - /* ignore */ - } - return clone; - } - /** - * Gets the Object mapped from the specified key, or <code>null</code> - * if no such mapping has been made. - */ - public E get(int key) { - return get(key, null); - } - /** - * Gets the Object mapped from the specified key, or the specified Object - * if no such mapping has been made. - */ - @SuppressWarnings("unchecked") - public E get(int key, E valueIfKeyNotFound) { - int i = ContainerHelpers.binarySearch(mKeys, mSize, key); - if (i < 0 || mValues[i] == DELETED) { - return valueIfKeyNotFound; - } else { - return (E) mValues[i]; - } - } - /** - * Removes the mapping from the specified key, if there was any. - */ - public void delete(int key) { - int i = ContainerHelpers.binarySearch(mKeys, mSize, key); - if (i >= 0) { - if (mValues[i] != DELETED) { - mValues[i] = DELETED; - mGarbage = true; - } - } - } - /** - * @hide - * Removes the mapping from the specified key, if there was any, returning the old value. - */ - public E removeReturnOld(int key) { - int i = ContainerHelpers.binarySearch(mKeys, mSize, key); - if (i >= 0) { - if (mValues[i] != DELETED) { - final E old = (E) mValues[i]; - mValues[i] = DELETED; - mGarbage = true; - return old; - } - } - return null; - } - /** - * Alias for {@link #delete(int)}. - */ - public void remove(int key) { - delete(key); - } - /** - * Removes the mapping at the specified index. - */ - public void removeAt(int index) { - if (mValues[index] != DELETED) { - mValues[index] = DELETED; - mGarbage = true; - } - } - /** - * Remove a range of mappings as a batch. - * - * @param index Index to begin at - * @param size Number of mappings to remove - */ - public void removeAtRange(int index, int size) { - final int end = Math.min(mSize, index + size); - for (int i = index; i < end; i++) { - removeAt(i); - } - } - private void gc() { - // Log.e("SparseArray", "gc start with " + mSize); - int n = mSize; - int o = 0; - int[] keys = mKeys; - Object[] values = mValues; - for (int i = 0; i < n; i++) { - Object val = values[i]; - if (val != DELETED) { - if (i != o) { - keys[o] = keys[i]; - values[o] = val; - values[i] = null; - } - o++; - } - } - mGarbage = false; - mSize = o; - // Log.e("SparseArray", "gc end with " + mSize); - } - /** - * Adds a mapping from the specified key to the specified value, - * replacing the previous mapping from the specified key if there - * was one. - */ - public void put(int key, E value) { - int i = ContainerHelpers.binarySearch(mKeys, mSize, key); - if (i >= 0) { - mValues[i] = value; - } else { - i = ~i; - if (i < mSize && mValues[i] == DELETED) { - mKeys[i] = key; - mValues[i] = value; - return; - } - if (mGarbage && mSize >= mKeys.length) { - gc(); - // Search again because indices may have changed. - i = ContainerHelpers.binarySearch(mKeys, mSize, key); - } - mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key); - mValues = GrowingArrayUtils.insert(mValues, mSize, i, value); - mSize++; - } - } - /** - * Returns the number of key-value mappings that this SparseArray - * currently stores. - */ - public int size() { - if (mGarbage) { - gc(); - } - return mSize; - } - /** - * Given an index in the range <code>0...size()-1</code>, returns - * the key from the <code>index</code>th key-value mapping that this - * SparseArray stores. - * - * <p>The keys corresponding to indices in ascending order are guaranteed to - * be in ascending order, e.g., <code>keyAt(0)</code> will return the - * smallest key and <code>keyAt(size()-1)</code> will return the largest - * key.</p> - */ - public int keyAt(int index) { - if (mGarbage) { - gc(); - } - return mKeys[index]; - } - /** - * Given an index in the range <code>0...size()-1</code>, returns - * the value from the <code>index</code>th key-value mapping that this - * SparseArray stores. - * - * <p>The values corresponding to indices in ascending order are guaranteed - * to be associated with keys in ascending order, e.g., - * <code>valueAt(0)</code> will return the value associated with the - * smallest key and <code>valueAt(size()-1)</code> will return the value - * associated with the largest key.</p> - */ - @SuppressWarnings("unchecked") - public E valueAt(int index) { - if (mGarbage) { - gc(); - } - return (E) mValues[index]; - } - /** - * Given an index in the range <code>0...size()-1</code>, sets a new - * value for the <code>index</code>th key-value mapping that this - * SparseArray stores. - */ - public void setValueAt(int index, E value) { - if (mGarbage) { - gc(); - } - mValues[index] = value; - } - /** - * Returns the index for which {@link #keyAt} would return the - * specified key, or a negative number if the specified - * key is not mapped. - */ - public int indexOfKey(int key) { - if (mGarbage) { - gc(); - } - return ContainerHelpers.binarySearch(mKeys, mSize, key); - } - /** - * Returns an index for which {@link #valueAt} would return the - * specified key, or a negative number if no keys map to the - * specified value. - * <p>Beware that this is a linear search, unlike lookups by key, - * and that multiple keys can map to the same value and this will - * find only one of them. - * <p>Note also that unlike most collections' {@code indexOf} methods, - * this method compares values using {@code ==} rather than {@code equals}. - */ - public int indexOfValue(E value) { - if (mGarbage) { - gc(); - } - for (int i = 0; i < mSize; i++) - if (mValues[i] == value) - return i; - return -1; - } - /** - * Removes all key-value mappings from this SparseArray. - */ - public void clear() { - int n = mSize; - Object[] values = mValues; - for (int i = 0; i < n; i++) { - values[i] = null; - } - mSize = 0; - mGarbage = false; - } - /** - * Puts a key/value pair into the array, optimizing for the case where - * the key is greater than all existing keys in the array. - */ - public void append(int key, E value) { - if (mSize != 0 && key <= mKeys[mSize - 1]) { - put(key, value); - return; - } - if (mGarbage && mSize >= mKeys.length) { - gc(); - } - mKeys = GrowingArrayUtils.append(mKeys, mSize, key); - mValues = GrowingArrayUtils.append(mValues, mSize, value); - mSize++; - } - /** - * {@inheritDoc} - * - * <p>This implementation composes a string by iterating over its mappings. If - * this map contains itself as a value, the string "(this Map)" - * will appear in its place. - */ - @Override - public String toString() { - if (size() <= 0) { - return "{}"; - } - StringBuilder buffer = new StringBuilder(mSize * 28); - buffer.append('{'); - for (int i=0; i<mSize; i++) { - if (i > 0) { - buffer.append(", "); - } - int key = keyAt(i); - buffer.append(key); - buffer.append('='); - Object value = valueAt(i); - if (value != this) { - buffer.append(value); - } else { - buffer.append("(this Map)"); - } - } - buffer.append('}'); - return buffer.toString(); - } -} \ No newline at end of file diff --git a/src/com/android/internal/util/GrowingArrayUtils.java b/src/com/android/internal/util/GrowingArrayUtils.java deleted file mode 100644 index d2b04f16..00000000 --- a/src/com/android/internal/util/GrowingArrayUtils.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * 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.android.internal.util; -/** - * A helper class that aims to provide comparable growth performance to ArrayList, but on primitive - * arrays. Common array operations are implemented for efficient use in dynamic containers. - * - * All methods in this class assume that the length of an array is equivalent to its capacity and - * NOT the number of elements in the array. The current size of the array is always passed in as a - * parameter. - * - * @hide - */ -public final class GrowingArrayUtils { - /** - * Appends an element to the end of the array, growing the array if there is no more room. - * @param array The array to which to append the element. This must NOT be null. - * @param currentSize The number of elements in the array. Must be less than or equal to - * array.length. - * @param element The element to append. - * @return the array to which the element was appended. This may be different than the given - * array. - */ - public static <T> T[] append(T[] array, int currentSize, T element) { - assert currentSize <= array.length; - if (currentSize + 1 > array.length) { - @SuppressWarnings("unchecked") - T[] newArray = (T[]) new Object[growSize(currentSize)]; - System.arraycopy(array, 0, newArray, 0, currentSize); - array = newArray; - } - array[currentSize] = element; - return array; - } - /** - * Primitive int version of {@link #append(Object[], int, Object)}. - */ - public static int[] append(int[] array, int currentSize, int element) { - assert currentSize <= array.length; - if (currentSize + 1 > array.length) { - int[] newArray = new int[growSize(currentSize)]; - System.arraycopy(array, 0, newArray, 0, currentSize); - array = newArray; - } - array[currentSize] = element; - return array; - } - /** - * Primitive long version of {@link #append(Object[], int, Object)}. - */ - public static long[] append(long[] array, int currentSize, long element) { - assert currentSize <= array.length; - if (currentSize + 1 > array.length) { - long[] newArray = new long[growSize(currentSize)]; - System.arraycopy(array, 0, newArray, 0, currentSize); - array = newArray; - } - array[currentSize] = element; - return array; - } - /** - * Primitive boolean version of {@link #append(Object[], int, Object)}. - */ - public static boolean[] append(boolean[] array, int currentSize, boolean element) { - assert currentSize <= array.length; - if (currentSize + 1 > array.length) { - boolean[] newArray = new boolean[growSize(currentSize)]; - System.arraycopy(array, 0, newArray, 0, currentSize); - array = newArray; - } - array[currentSize] = element; - return array; - } - /** - * Inserts an element into the array at the specified index, growing the array if there is no - * more room. - * - * @param array The array to which to append the element. Must NOT be null. - * @param currentSize The number of elements in the array. Must be less than or equal to - * array.length. - * @param element The element to insert. - * @return the array to which the element was appended. This may be different than the given - * array. - */ - public static <T> T[] insert(T[] array, int currentSize, int index, T element) { - assert currentSize <= array.length; - if (currentSize + 1 <= array.length) { - System.arraycopy(array, index, array, index + 1, currentSize - index); - array[index] = element; - return array; - } - @SuppressWarnings("unchecked") - T[] newArray = (T[]) new Object[growSize(currentSize)]; - System.arraycopy(array, 0, newArray, 0, index); - newArray[index] = element; - System.arraycopy(array, index, newArray, index + 1, array.length - index); - return newArray; - } - /** - * Primitive int version of {@link #insert(Object[], int, int, Object)}. - */ - public static int[] insert(int[] array, int currentSize, int index, int element) { - assert currentSize <= array.length; - if (currentSize + 1 <= array.length) { - System.arraycopy(array, index, array, index + 1, currentSize - index); - array[index] = element; - return array; - } - int[] newArray = new int[growSize(currentSize)]; - System.arraycopy(array, 0, newArray, 0, index); - newArray[index] = element; - System.arraycopy(array, index, newArray, index + 1, array.length - index); - return newArray; - } - /** - * Primitive long version of {@link #insert(Object[], int, int, Object)}. - */ - public static long[] insert(long[] array, int currentSize, int index, long element) { - assert currentSize <= array.length; - if (currentSize + 1 <= array.length) { - System.arraycopy(array, index, array, index + 1, currentSize - index); - array[index] = element; - return array; - } - long[] newArray = new long[growSize(currentSize)]; - System.arraycopy(array, 0, newArray, 0, index); - newArray[index] = element; - System.arraycopy(array, index, newArray, index + 1, array.length - index); - return newArray; - } - /** - * Primitive boolean version of {@link #insert(Object[], int, int, Object)}. - */ - public static boolean[] insert(boolean[] array, int currentSize, int index, boolean element) { - assert currentSize <= array.length; - if (currentSize + 1 <= array.length) { - System.arraycopy(array, index, array, index + 1, currentSize - index); - array[index] = element; - return array; - } - boolean[] newArray = new boolean [growSize(currentSize)]; - System.arraycopy(array, 0, newArray, 0, index); - newArray[index] = element; - System.arraycopy(array, index, newArray, index + 1, array.length - index); - return newArray; - } - /** - * Given the current size of an array, returns an ideal size to which the array should grow. - * This is typically double the given size, but should not be relied upon to do so in the - * future. - */ - public static int growSize(int currentSize) { - return currentSize <= 4 ? 8 : currentSize * 2; - } - // Uninstantiable - private GrowingArrayUtils() {} -} \ No newline at end of file diff --git a/src/com/connectsdk/service/DeviceService.java b/src/com/connectsdk/service/DeviceService.java index 90afe919..60b4c121 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; @@ -128,7 +126,7 @@ public enum PairingType { // @cond INTERNAL protected DeviceServiceListener listener; - public SparseArray<ServiceCommand<? extends Object>> requests = new SparseArray<ServiceCommand<? extends Object>>(); + //public SparseArray<ServiceCommand<? extends Object>> requests = new SparseArray<ServiceCommand<? extends Object>>(); public DeviceService(ServiceDescription serviceDescription, ServiceConfig serviceConfig) { this.serviceDescription = serviceDescription; diff --git a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index f2a13f79..4fb27d8b 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -12,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; @@ -45,7 +46,6 @@ import android.content.Context; //import android.os.Build; import android.util.Log; -import android.util.SparseArray; //import android.view.Display; //import android.view.WindowManager; @@ -79,8 +79,8 @@ public enum State { // Queue of commands that should be sent once register is complete LinkedHashSet<ServiceCommand<ResponseListener<Object>>> commandQueue = new LinkedHashSet<ServiceCommand<ResponseListener<Object>>>(); - public SparseArray<ServiceCommand<? extends Object>> requests = new SparseArray<ServiceCommand<? extends Object>>(); - + private HashMap<Integer, ServiceCommand<? extends Object>> requests = new HashMap<Integer,ServiceCommand<? extends Object>>(); + boolean mConnectSucceeded = false; Boolean mConnected; @@ -750,10 +750,7 @@ private void handleConnectionLost(boolean cleanDisconnect, Exception ex) { mListener.onCloseWithError(error); } - for (int i = 0; i < requests.size(); i++) { - ServiceCommand<ResponseListener<Object>> request = (ServiceCommand<ResponseListener<Object>>) requests - .get(requests.keyAt(i)); - + for(ServiceCommand<? extends Object> request : requests.values()){ if (request != null) { Util.postError(request.getResponseListener(), new ServiceCommandError(0, "connection lost", null)); } From 09f410cc345f403c0b0511c212e233cc1533dbbe Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 22:34:08 +0100 Subject: [PATCH 23/41] removed sparsearray dependency --- src/android/util/ContainerHelpers.java | 51 -------------------------- 1 file changed, 51 deletions(-) delete mode 100644 src/android/util/ContainerHelpers.java diff --git a/src/android/util/ContainerHelpers.java b/src/android/util/ContainerHelpers.java deleted file mode 100644 index de76e430..00000000 --- a/src/android/util/ContainerHelpers.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * 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 android.util; -class ContainerHelpers { - // This is Arrays.binarySearch(), but doesn't do any argument validation. - static int binarySearch(int[] array, int size, int value) { - int lo = 0; - int hi = size - 1; - while (lo <= hi) { - final int mid = (lo + hi) >>> 1; - final int midVal = array[mid]; - if (midVal < value) { - lo = mid + 1; - } else if (midVal > value) { - hi = mid - 1; - } else { - return mid; // value found - } - } - return ~lo; // value not present - } - static int binarySearch(long[] array, int size, long value) { - int lo = 0; - int hi = size - 1; - while (lo <= hi) { - final int mid = (lo + hi) >>> 1; - final long midVal = array[mid]; - if (midVal < value) { - lo = mid + 1; - } else if (midVal > value) { - hi = mid - 1; - } else { - return mid; // value found - } - } - return ~lo; // value not present - } -} \ No newline at end of file From 56bbb40bf46ffb160001b11f5a1c0cbbf72a6385 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 23:37:09 +0100 Subject: [PATCH 24/41] removed dependencies to context bitmap bitmapfactory xml. context now a simple interface in core that users need to implement to provide info about environment --- src/android/content/Context.java | 8 --- src/android/graphics/Bitmap.java | 64 ------------------- src/android/graphics/BitmapFactory.java | 40 ------------ src/android/util/Xml.java | 44 ------------- src/com/connectsdk/core/Context.java | 11 ++++ src/com/connectsdk/core/Util.java | 40 +++--------- .../device/DefaultConnectableDeviceStore.java | 3 +- .../discovery/DiscoveryManager.java | 3 +- .../provider/SSDPDiscoveryProvider.java | 8 +-- .../provider/ZeroconfDiscoveryProvider.java | 10 ++- .../connectsdk/service/AirPlayService.java | 32 ++-------- src/com/connectsdk/service/DLNAService.java | 17 +++-- .../service/airplay/PListParser.java | 6 +- .../service/upnp/DLNAEventParser.java | 5 +- .../service/upnp/DLNAMediaInfoParser.java | 6 +- .../service/upnp/DLNANotifyParser.java | 5 +- .../webos/WebOSTVServiceSocketClient.java | 2 +- 17 files changed, 52 insertions(+), 252 deletions(-) delete mode 100644 src/android/content/Context.java delete mode 100644 src/android/graphics/Bitmap.java delete mode 100644 src/android/graphics/BitmapFactory.java delete mode 100644 src/android/util/Xml.java create mode 100644 src/com/connectsdk/core/Context.java diff --git a/src/android/content/Context.java b/src/android/content/Context.java deleted file mode 100644 index 303c460f..00000000 --- a/src/android/content/Context.java +++ /dev/null @@ -1,8 +0,0 @@ -package android.content; - -/** Context that must be implemented for the library to interface with surrounding systems. */ -public abstract class Context { - public abstract String getPackageName(); - public abstract String getDataDir(); - public abstract String getApplicationName(); -} diff --git a/src/android/graphics/Bitmap.java b/src/android/graphics/Bitmap.java deleted file mode 100644 index d51c7a6d..00000000 --- a/src/android/graphics/Bitmap.java +++ /dev/null @@ -1,64 +0,0 @@ -package android.graphics; -public final class Bitmap - // implements android.os.Parcelable -{ -//public static enum Config -//{ -//ALPHA_8(), -//ARGB_4444(), -//ARGB_8888(), -//RGB_565(); -//} -public static enum CompressFormat -{ -JPEG(), -PNG(), -WEBP(); -} -//Bitmap() { throw new RuntimeException("Stub!"); } -//public int getDensity() { throw new RuntimeException("Stub!"); } -//public void setDensity(int density) { throw new RuntimeException("Stub!"); } -//public void recycle() { throw new RuntimeException("Stub!"); } -//public final boolean isRecycled() { throw new RuntimeException("Stub!"); } -//public int getGenerationId() { throw new RuntimeException("Stub!"); } -//public void copyPixelsToBuffer(java.nio.Buffer dst) { throw new RuntimeException("Stub!"); } -//public void copyPixelsFromBuffer(java.nio.Buffer src) { throw new RuntimeException("Stub!"); } -//public android.graphics.Bitmap copy(android.graphics.Bitmap.Config config, boolean isMutable) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap src, int dstWidth, int dstHeight, boolean filter) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap src) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap source, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap source, int x, int y, int width, int height, android.graphics.Matrix m, boolean filter) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap createBitmap(int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap createBitmap(int[] colors, int offset, int stride, int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap createBitmap(int[] colors, int width, int height, android.graphics.Bitmap.Config config) { throw new RuntimeException("Stub!"); } -//public byte[] getNinePatchChunk() { throw new RuntimeException("Stub!"); } -public boolean compress(android.graphics.Bitmap.CompressFormat format, int quality, java.io.OutputStream stream) { throw new RuntimeException("Stub!"); } -//public final boolean isMutable() { throw new RuntimeException("Stub!"); } -//public final int getWidth() { throw new RuntimeException("Stub!"); } -//public final int getHeight() { throw new RuntimeException("Stub!"); } -//public int getScaledWidth(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } -//public int getScaledHeight(android.graphics.Canvas canvas) { throw new RuntimeException("Stub!"); } -//public int getScaledWidth(android.util.DisplayMetrics metrics) { throw new RuntimeException("Stub!"); } -//public int getScaledHeight(android.util.DisplayMetrics metrics) { throw new RuntimeException("Stub!"); } -//public int getScaledWidth(int targetDensity) { throw new RuntimeException("Stub!"); } -//public int getScaledHeight(int targetDensity) { throw new RuntimeException("Stub!"); } -//public final int getRowBytes() { throw new RuntimeException("Stub!"); } -//public final int getByteCount() { throw new RuntimeException("Stub!"); } -//public final android.graphics.Bitmap.Config getConfig() { throw new RuntimeException("Stub!"); } -//public final boolean hasAlpha() { throw new RuntimeException("Stub!"); } -//public void setHasAlpha(boolean hasAlpha) { throw new RuntimeException("Stub!"); } -//public void eraseColor(int c) { throw new RuntimeException("Stub!"); } -//public int getPixel(int x, int y) { throw new RuntimeException("Stub!"); } -//public void getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } -//public void setPixel(int x, int y, int color) { throw new RuntimeException("Stub!"); } -//public void setPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) { throw new RuntimeException("Stub!"); } -//public int describeContents() { throw new RuntimeException("Stub!"); } -//public void writeToParcel(android.os.Parcel p, int flags) { throw new RuntimeException("Stub!"); } -//public android.graphics.Bitmap extractAlpha() { throw new RuntimeException("Stub!"); } -//public android.graphics.Bitmap extractAlpha(android.graphics.Paint paint, int[] offsetXY) { throw new RuntimeException("Stub!"); } -//public boolean sameAs(android.graphics.Bitmap other) { throw new RuntimeException("Stub!"); } -//public void prepareToDraw() { throw new RuntimeException("Stub!"); } -//public static final int DENSITY_NONE = 0; -//public static final android.os.Parcelable.Creator<android.graphics.Bitmap> CREATOR; -//static { CREATOR = null; } -} diff --git a/src/android/graphics/BitmapFactory.java b/src/android/graphics/BitmapFactory.java deleted file mode 100644 index a3be8d59..00000000 --- a/src/android/graphics/BitmapFactory.java +++ /dev/null @@ -1,40 +0,0 @@ -package android.graphics; -public class BitmapFactory -{ -//public static class Options -//{ -//public Options() { throw new RuntimeException("Stub!"); } -//public void requestCancelDecode() { throw new RuntimeException("Stub!"); } -//public android.graphics.Bitmap inBitmap; -//@java.lang.SuppressWarnings(value={"UnusedDeclaration"}) -//public boolean inMutable; -//public boolean inJustDecodeBounds; -//public int inSampleSize; -//public android.graphics.Bitmap.Config inPreferredConfig; -//public boolean inDither; -//public int inDensity; -//public int inTargetDensity; -//public int inScreenDensity; -//public boolean inScaled; -//public boolean inPurgeable; -//public boolean inInputShareable; -//public boolean inPreferQualityOverSpeed; -//public int outWidth; -//public int outHeight; -//public java.lang.String outMimeType; -//public byte[] inTempStorage = null; -//public boolean mCancel; -//} -//public BitmapFactory() { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeFile(java.lang.String pathName, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeFile(java.lang.String pathName) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeResourceStream(android.content.res.Resources res, android.util.TypedValue value, java.io.InputStream is, android.graphics.Rect pad, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeResource(android.content.res.Resources res, int id, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeResource(android.content.res.Resources res, int id) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeByteArray(byte[] data, int offset, int length, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeByteArray(byte[] data, int offset, int length) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeStream(java.io.InputStream is, android.graphics.Rect outPadding, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -public static android.graphics.Bitmap decodeStream(java.io.InputStream is) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeFileDescriptor(java.io.FileDescriptor fd, android.graphics.Rect outPadding, android.graphics.BitmapFactory.Options opts) { throw new RuntimeException("Stub!"); } -//public static android.graphics.Bitmap decodeFileDescriptor(java.io.FileDescriptor fd) { throw new RuntimeException("Stub!"); } -} diff --git a/src/android/util/Xml.java b/src/android/util/Xml.java deleted file mode 100644 index 7c45145d..00000000 --- a/src/android/util/Xml.java +++ /dev/null @@ -1,44 +0,0 @@ -package android.util; - -public class Xml { - public static enum Encoding { - ISO_8859_1(), - US_ASCII(), - UTF_16(), - UTF_8(); - } - - Xml() { - throw new RuntimeException("Stub!"); - } - - public static void parse(java.lang.String xml, org.xml.sax.ContentHandler contentHandler) - throws org.xml.sax.SAXException { - throw new RuntimeException("Stub!"); - } - - public static void parse(java.io.Reader in, org.xml.sax.ContentHandler contentHandler) - throws java.io.IOException, org.xml.sax.SAXException { - throw new RuntimeException("Stub!"); - } - - public static void parse(java.io.InputStream in, android.util.Xml.Encoding encoding, - org.xml.sax.ContentHandler contentHandler) throws java.io.IOException, org.xml.sax.SAXException { - throw new RuntimeException("Stub!"); - } - - public static org.xmlpull.v1.XmlPullParser newPullParser() { - throw new RuntimeException("Stub!"); - } - - // public static org.xmlpull.v1.XmlSerializer newSerializer() {throw new RuntimeException("Stub!"); } - - public static android.util.Xml.Encoding findEncodingByName(java.lang.String encodingName) - throws java.io.UnsupportedEncodingException { - throw new RuntimeException("Stub!"); - } - - // public static android.util.AttributeSet asAttributeSet(org.xmlpull.v1.XmlPullParser parser) { throw new - // RuntimeException("Stub!"); } - public static java.lang.String FEATURE_RELAXED; -} 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/Util.java b/src/com/connectsdk/core/Util.java index 533416ef..12485c84 100644 --- a/src/com/connectsdk/core/Util.java +++ b/src/com/connectsdk/core/Util.java @@ -20,10 +20,9 @@ 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.ExecutorService; import java.util.concurrent.TimeUnit; @@ -33,13 +32,12 @@ import com.connectsdk.service.capability.listeners.ResponseListener; import com.connectsdk.service.command.ServiceCommandError; -import android.content.Context; + public final class Util { static public String T = "Connect SDK"; static private ExecutorService executor; - static private InetAddress localIP; /** * Configure Util on component start. @@ -47,14 +45,12 @@ public final class Util { * @param e must not be <code>null</null> * @param ip may be <code>null</code> */ - public static void start(ExecutorService e, InetAddress ip) { + public static void init(ExecutorService e) { executor = e; - localIP = ip; } - public static void stop() { + public static void uninit() { executor = null; - localIP = null; } public static void runOnUI(Runnable runnable) { @@ -70,13 +66,7 @@ public static void runInBackground(Runnable runnable) { runInBackground(runnable, false); } - public static Executor getExecutor() { - return executor; - } - - public static boolean isMain() { - return true; - } + public static <T> void postSuccess(final ResponseListener<T> listener, final T object) { if (listener == null) @@ -102,15 +92,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()); @@ -120,11 +102,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 { - return localIP; - } + } \ No newline at end of file diff --git a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java index f7f089e1..3a90d5d3 100644 --- a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java +++ b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java @@ -33,8 +33,7 @@ import org.json.JSONException; import org.json.JSONObject; -import android.content.Context; - +import com.connectsdk.core.Context; import com.connectsdk.core.Util; import com.connectsdk.service.DeviceService; import com.connectsdk.service.config.ServiceConfig; diff --git a/src/com/connectsdk/discovery/DiscoveryManager.java b/src/com/connectsdk/discovery/DiscoveryManager.java index c8ffabb2..ea49da1b 100644 --- a/src/com/connectsdk/discovery/DiscoveryManager.java +++ b/src/com/connectsdk/discovery/DiscoveryManager.java @@ -33,6 +33,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import com.connectsdk.core.Context; import com.connectsdk.core.Util; import com.connectsdk.device.ConnectableDevice; import com.connectsdk.device.ConnectableDeviceListener; @@ -47,8 +48,6 @@ import com.connectsdk.service.config.ServiceConfig.ServiceConfigListener; import com.connectsdk.service.config.ServiceDescription; -//import android.content.BroadcastReceiver; -import android.content.Context; //import android.content.Intent; //import android.content.IntentFilter; //import android.net.ConnectivityManager; diff --git a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java index 69b8db75..740783ac 100644 --- a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java @@ -41,6 +41,7 @@ import org.xml.sax.SAXException; +import com.connectsdk.core.Context; import com.connectsdk.core.Util; import com.connectsdk.discovery.DiscoveryFilter; import com.connectsdk.discovery.DiscoveryProvider; @@ -50,7 +51,6 @@ import com.connectsdk.discovery.provider.ssdp.SSDPPacket; import com.connectsdk.service.config.ServiceDescription; -import android.content.Context; import android.util.Log; public class SSDPDiscoveryProvider implements DiscoveryProvider { @@ -91,15 +91,13 @@ private void openSocket() { } try { - InetAddress source = Util.getIpAddress(context); + InetAddress source = context.getIpAddress(); if (source == null) { return; } ssdpClient = createSocket(source); - } catch (UnknownHostException e) { - e.printStackTrace(); - } catch (IOException e) { + } catch (IOException e) { e.printStackTrace(); } } diff --git a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java index 67d673a3..14ce2d9b 100644 --- a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java @@ -20,9 +20,9 @@ package com.connectsdk.discovery.provider; -import android.content.Context; import android.util.Log; +import com.connectsdk.core.Context; import com.connectsdk.core.Util; import com.connectsdk.discovery.DiscoveryFilter; import com.connectsdk.discovery.DiscoveryProvider; @@ -141,11 +141,9 @@ public ZeroconfDiscoveryProvider(Context context) { serviceListeners = new CopyOnWriteArrayList<DiscoveryProviderListener>(); serviceFilters = new CopyOnWriteArrayList<DiscoveryFilter>(); - try { - srcAddress = Util.getIpAddress(context); - } catch (UnknownHostException e) { - e.printStackTrace(); - } + + srcAddress = context.getIpAddress(); + } @Override diff --git a/src/com/connectsdk/service/AirPlayService.java b/src/com/connectsdk/service/AirPlayService.java index 46eb038e..f0ef892b 100644 --- a/src/com/connectsdk/service/AirPlayService.java +++ b/src/com/connectsdk/service/AirPlayService.java @@ -20,8 +20,6 @@ package com.connectsdk.service; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.util.Log; import com.connectsdk.core.ImageInfo; @@ -48,6 +46,7 @@ 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; @@ -66,6 +65,8 @@ 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"; @@ -381,33 +382,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) { diff --git a/src/com/connectsdk/service/DLNAService.java b/src/com/connectsdk/service/DLNAService.java index 5911571e..2acc107c 100644 --- a/src/com/connectsdk/service/DLNAService.java +++ b/src/com/connectsdk/service/DLNAService.java @@ -20,11 +20,11 @@ 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.MediaInfo; import com.connectsdk.core.SubtitleInfo; @@ -57,6 +57,7 @@ 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; @@ -912,8 +913,9 @@ String parseData(String response, String key) { if (isXmlEncoded(response)) { response = Html.fromHtml(response).toString(); } - XmlPullParser parser = Xml.newPullParser(); try { + XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); + parser.setInput(new StringReader(response)); int event; boolean isFound = false; @@ -1123,12 +1125,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<Service> serviceList = serviceDescription.getServiceList(); if (serviceList != null) { diff --git a/src/com/connectsdk/service/airplay/PListParser.java b/src/com/connectsdk/service/airplay/PListParser.java index f4764a48..c9e8b229 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(); 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/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..877ac042 100644 --- a/src/com/connectsdk/service/upnp/DLNANotifyParser.java +++ b/src/com/connectsdk/service/upnp/DLNANotifyParser.java @@ -10,15 +10,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 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(); diff --git a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index 4fb27d8b..eecff15a 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -31,6 +31,7 @@ import org.json.JSONException; import org.json.JSONObject; +import com.connectsdk.core.Context; import com.connectsdk.core.Util; import com.connectsdk.discovery.DiscoveryManager; import com.connectsdk.service.DeviceService.PairingType; @@ -43,7 +44,6 @@ import com.connectsdk.service.command.URLServiceSubscription; import com.connectsdk.service.config.WebOSTVServiceConfig; -import android.content.Context; //import android.os.Build; import android.util.Log; //import android.view.Display; From 60d5c75e3d62ac7c74c39338a3259c02cdda214b Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 23:45:21 +0100 Subject: [PATCH 25/41] removed dependency to html and spanned --- src/android/text/Html.java | 17 -------------- src/android/text/Spanned.java | 26 --------------------- src/com/connectsdk/service/DLNAService.java | 12 ++++++---- 3 files changed, 7 insertions(+), 48 deletions(-) delete mode 100644 src/android/text/Html.java delete mode 100644 src/android/text/Spanned.java diff --git a/src/android/text/Html.java b/src/android/text/Html.java deleted file mode 100644 index 51109b7d..00000000 --- a/src/android/text/Html.java +++ /dev/null @@ -1,17 +0,0 @@ -package android.text; -public class Html -{ -//public static interface ImageGetter -//{ -//public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String source); -//} -//public static interface TagHandler -//{ -//public abstract void handleTag(boolean opening, java.lang.String tag, android.text.Editable output, org.xml.sax.XMLReader xmlReader); -//} -//Html() { throw new RuntimeException("Stub!"); } -public static android.text.Spanned fromHtml(java.lang.String source) { throw new RuntimeException("Stub!"); } -//public static android.text.Spanned fromHtml(java.lang.String source, android.text.Html.ImageGetter imageGetter, android.text.Html.TagHandler tagHandler) { throw new RuntimeException("Stub!"); } -//public static java.lang.String toHtml(android.text.Spanned text) { throw new RuntimeException("Stub!"); } -//public static java.lang.String escapeHtml(java.lang.CharSequence text) { throw new RuntimeException("Stub!"); } -} diff --git a/src/android/text/Spanned.java b/src/android/text/Spanned.java deleted file mode 100644 index 1e036422..00000000 --- a/src/android/text/Spanned.java +++ /dev/null @@ -1,26 +0,0 @@ -package android.text; -public interface Spanned - extends java.lang.CharSequence -{ -//public abstract <T> T[] getSpans(int start, int end, java.lang.Class<T> type); -//public abstract int getSpanStart(java.lang.Object tag); -//public abstract int getSpanEnd(java.lang.Object tag); -//public abstract int getSpanFlags(java.lang.Object tag); -//public abstract int nextSpanTransition(int start, int limit, java.lang.Class type); -//public static final int SPAN_POINT_MARK_MASK = 51; -//public static final int SPAN_MARK_MARK = 17; -//public static final int SPAN_MARK_POINT = 18; -//public static final int SPAN_POINT_MARK = 33; -//public static final int SPAN_POINT_POINT = 34; -//public static final int SPAN_PARAGRAPH = 51; -//public static final int SPAN_INCLUSIVE_EXCLUSIVE = 17; -//public static final int SPAN_INCLUSIVE_INCLUSIVE = 18; -//public static final int SPAN_EXCLUSIVE_EXCLUSIVE = 33; -//public static final int SPAN_EXCLUSIVE_INCLUSIVE = 34; -//public static final int SPAN_COMPOSING = 256; -//public static final int SPAN_INTERMEDIATE = 512; -//public static final int SPAN_USER_SHIFT = 24; -//public static final int SPAN_USER = -16777216; -//public static final int SPAN_PRIORITY_SHIFT = 16; -//public static final int SPAN_PRIORITY = 16711680; -} diff --git a/src/com/connectsdk/service/DLNAService.java b/src/com/connectsdk/service/DLNAService.java index 2acc107c..c3ea972d 100644 --- a/src/com/connectsdk/service/DLNAService.java +++ b/src/com/connectsdk/service/DLNAService.java @@ -902,17 +902,19 @@ 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(); - } + + // 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(); From 5178173f5fabdd50a71b5aa1cb0118d1b153f465 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 23:45:36 +0100 Subject: [PATCH 26/41] removed dependency to html and spanned --- src/com/connectsdk/service/DLNAService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/com/connectsdk/service/DLNAService.java b/src/com/connectsdk/service/DLNAService.java index c3ea972d..788f8d5d 100644 --- a/src/com/connectsdk/service/DLNAService.java +++ b/src/com/connectsdk/service/DLNAService.java @@ -20,7 +20,6 @@ package com.connectsdk.service; -import android.text.Html; import android.util.Log; From c4f7e811855293b5b72ee3717d40304bc549cdf3 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 23:51:12 +0100 Subject: [PATCH 27/41] moved log to core --- src/android/util/Log.java | 134 ------------------ src/com/connectsdk/core/ChannelInfo.java | 2 - src/com/connectsdk/core/Log.java | 31 ++++ .../connectsdk/device/ConnectableDevice.java | 3 +- .../discovery/DiscoveryManager.java | 9 +- .../provider/SSDPDiscoveryProvider.java | 3 +- .../provider/ZeroconfDiscoveryProvider.java | 3 +- .../connectsdk/service/AirPlayService.java | 3 +- src/com/connectsdk/service/DIALService.java | 3 +- src/com/connectsdk/service/DLNAService.java | 4 +- .../connectsdk/service/NetcastTVService.java | 2 +- src/com/connectsdk/service/RokuService.java | 3 +- .../connectsdk/service/WebOSTVService.java | 2 +- .../service/netcast/NetcastHttpServer.java | 3 +- .../service/sessions/WebOSWebAppSession.java | 2 +- .../webos/WebOSTVMouseSocketConnection.java | 2 +- .../webos/WebOSTVServiceSocketClient.java | 6 +- 17 files changed, 45 insertions(+), 170 deletions(-) delete mode 100644 src/android/util/Log.java create mode 100644 src/com/connectsdk/core/Log.java diff --git a/src/android/util/Log.java b/src/android/util/Log.java deleted file mode 100644 index d4a058dd..00000000 --- a/src/android/util/Log.java +++ /dev/null @@ -1,134 +0,0 @@ -package android.util; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class Log { - - private static final Logger l = LoggerFactory.getLogger("org.openhab.binding.connectsdk.Log"); - - public static int v(java.lang.String tag, java.lang.String msg) { - l.trace(String.format("%s - %s", tag, msg)); - return 0; // did not find in android documentation what return codes - // mean - } - - public static int v(java.lang.String tag, java.lang.String msg, - java.lang.Throwable tr) { - l.trace(String.format("%s - %s", tag, msg), tr); - return 0; - } - - 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 d(java.lang.String tag, java.lang.String msg, - java.lang.Throwable tr) { - l.debug(String.format("%s - %s",tag, msg),tr); - return 0; - } - - public static int i(java.lang.String tag, java.lang.String msg) { - l.info(String.format("%s - %s", tag, msg)); - return 0; - } - - public static int i(java.lang.String tag, java.lang.String msg, - java.lang.Throwable tr) { - l.info(String.format("%s - %s",tag, msg),tr); - 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 w(java.lang.String tag, java.lang.String msg, - java.lang.Throwable tr) { - l.warn(String.format("%s - %s",tag, msg), tr); - return 0; - } - - public static boolean isLoggable(java.lang.String tag, int level) { - switch (level) { - case VERBOSE: - return l.isTraceEnabled(); - case DEBUG: - return l.isDebugEnabled(); - case INFO: - return l.isInfoEnabled(); - case WARN: - return l.isWarnEnabled(); - case ERROR: - case ASSERT: - return l.isErrorEnabled(); - default: - return false; - } - } - - public static int w(java.lang.String tag, java.lang.Throwable tr) { - l.warn(tag, tr); - 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; - } - - public static int wtf(java.lang.String tag, java.lang.String msg) { - l.error(String.format("%s - %s",tag, msg)); - return 0; - - } - - public static int wtf(java.lang.String tag, java.lang.Throwable tr) { - l.error(tag, tr); - return 0; - } - - public static int wtf(java.lang.String tag, java.lang.String msg, - java.lang.Throwable tr) { - l.error(String.format("%s - %s",tag, msg), tr); - return 0; - } - - public static java.lang.String getStackTraceString(java.lang.Throwable tr) { - throw new UnsupportedOperationException("Not supported yet."); - } - - public static int println(int priority, java.lang.String tag, - java.lang.String msg) { - switch (priority) { - case VERBOSE: - return v(tag,msg); - case DEBUG: - return d(tag,msg); - case INFO: - return i(tag,msg); - case WARN: - return w(tag,msg); - case ERROR: - case ASSERT: - return e(tag,msg); - default: - return -1; - } - } - - public static final int VERBOSE = 2; - public static final int DEBUG = 3; - public static final int INFO = 4; - public static final int WARN = 5; - public static final int ERROR = 6; - public static final int ASSERT = 7; -} diff --git a/src/com/connectsdk/core/ChannelInfo.java b/src/com/connectsdk/core/ChannelInfo.java index 0211b580..21193ad6 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. */ 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/device/ConnectableDevice.java b/src/com/connectsdk/device/ConnectableDevice.java index d63230e5..143f24df 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; diff --git a/src/com/connectsdk/discovery/DiscoveryManager.java b/src/com/connectsdk/discovery/DiscoveryManager.java index ea49da1b..f8ec673f 100644 --- a/src/com/connectsdk/discovery/DiscoveryManager.java +++ b/src/com/connectsdk/discovery/DiscoveryManager.java @@ -34,6 +34,7 @@ import java.util.concurrent.CopyOnWriteArrayList; 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; @@ -48,14 +49,6 @@ import com.connectsdk.service.config.ServiceConfig.ServiceConfigListener; import com.connectsdk.service.config.ServiceDescription; -//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; - /** * ###Overview * diff --git a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java index 740783ac..b4523959 100644 --- a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java @@ -42,6 +42,7 @@ 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; @@ -51,8 +52,6 @@ import com.connectsdk.discovery.provider.ssdp.SSDPPacket; import com.connectsdk.service.config.ServiceDescription; -import android.util.Log; - public class SSDPDiscoveryProvider implements DiscoveryProvider { Context context; diff --git a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java index 14ce2d9b..b7715304 100644 --- a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java @@ -20,9 +20,8 @@ package com.connectsdk.discovery.provider; -import android.util.Log; - 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; diff --git a/src/com/connectsdk/service/AirPlayService.java b/src/com/connectsdk/service/AirPlayService.java index f0ef892b..51100d14 100644 --- a/src/com/connectsdk/service/AirPlayService.java +++ b/src/com/connectsdk/service/AirPlayService.java @@ -20,9 +20,8 @@ package com.connectsdk.service; -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; diff --git a/src/com/connectsdk/service/DIALService.java b/src/com/connectsdk/service/DIALService.java index 3b550bea..25b5a5ab 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; diff --git a/src/com/connectsdk/service/DLNAService.java b/src/com/connectsdk/service/DLNAService.java index 788f8d5d..73daa4ed 100644 --- a/src/com/connectsdk/service/DLNAService.java +++ b/src/com/connectsdk/service/DLNAService.java @@ -20,11 +20,9 @@ package com.connectsdk.service; -import android.util.Log; - - 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; diff --git a/src/com/connectsdk/service/NetcastTVService.java b/src/com/connectsdk/service/NetcastTVService.java index 90471146..dcc51c6d 100644 --- a/src/com/connectsdk/service/NetcastTVService.java +++ b/src/com/connectsdk/service/NetcastTVService.java @@ -21,12 +21,12 @@ 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.Util; import com.connectsdk.device.ConnectableDevice; diff --git a/src/com/connectsdk/service/RokuService.java b/src/com/connectsdk/service/RokuService.java index aa807c31..ee0fd314 100644 --- a/src/com/connectsdk/service/RokuService.java +++ b/src/com/connectsdk/service/RokuService.java @@ -21,10 +21,9 @@ package com.connectsdk.service; -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; diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index cf1d5de4..32fbaa7f 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -37,6 +37,7 @@ 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.ProgramInfo; import com.connectsdk.core.ProgramList; @@ -80,7 +81,6 @@ import android.graphics.PointF; import android.support.annotation.NonNull; -import android.util.Log; public class WebOSTVService extends DeviceService implements Launcher, MediaControl, MediaPlayer, VolumeControl, TVControl, ToastControl, ExternalInputControl, diff --git a/src/com/connectsdk/service/netcast/NetcastHttpServer.java b/src/com/connectsdk/service/netcast/NetcastHttpServer.java index be50be9b..d78b3d2f 100644 --- a/src/com/connectsdk/service/netcast/NetcastHttpServer.java +++ b/src/com/connectsdk/service/netcast/NetcastHttpServer.java @@ -44,9 +44,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; diff --git a/src/com/connectsdk/service/sessions/WebOSWebAppSession.java b/src/com/connectsdk/service/sessions/WebOSWebAppSession.java index 23960992..64570f82 100644 --- a/src/com/connectsdk/service/sessions/WebOSWebAppSession.java +++ b/src/com/connectsdk/service/sessions/WebOSWebAppSession.java @@ -21,7 +21,6 @@ package com.connectsdk.service.sessions; import android.support.annotation.NonNull; -import android.util.Log; import java.util.Enumeration; import java.util.List; @@ -33,6 +32,7 @@ import org.json.JSONObject; 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; 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 eecff15a..5c1d6d88 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -32,6 +32,7 @@ import org.json.JSONObject; 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; @@ -44,11 +45,6 @@ import com.connectsdk.service.command.URLServiceSubscription; import com.connectsdk.service.config.WebOSTVServiceConfig; -//import android.os.Build; -import android.util.Log; -//import android.view.Display; -//import android.view.WindowManager; - public class WebOSTVServiceSocketClient extends WebSocketClient implements ServiceCommandProcessor { static final String WEBOS_PAIRING_PROMPT = "PROMPT"; From 2f2eb5151e06e72f54c5531e28c182765d74abd8 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 23:53:15 +0100 Subject: [PATCH 28/41] moved nonull to core --- src/android/support/annotation/NonNull.java | 31 ------------------- src/com/connectsdk/core/MediaInfo.java | 1 - src/com/connectsdk/core/NonNull.java | 16 ++++++++++ src/com/connectsdk/core/SubtitleInfo.java | 2 -- .../connectsdk/service/WebOSTVService.java | 2 +- .../service/sessions/WebOSWebAppSession.java | 3 +- 6 files changed, 18 insertions(+), 37 deletions(-) delete mode 100644 src/android/support/annotation/NonNull.java create mode 100644 src/com/connectsdk/core/NonNull.java diff --git a/src/android/support/annotation/NonNull.java b/src/android/support/annotation/NonNull.java deleted file mode 100644 index 402c3c4b..00000000 --- a/src/android/support/annotation/NonNull.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * 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 android.support.annotation; -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. - * <p> - * 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/MediaInfo.java b/src/com/connectsdk/core/MediaInfo.java index 9d2f9f6d..0e8a0a4d 100644 --- a/src/com/connectsdk/core/MediaInfo.java +++ b/src/com/connectsdk/core/MediaInfo.java @@ -20,7 +20,6 @@ package com.connectsdk.core; -import android.support.annotation.NonNull; import java.util.ArrayList; import java.util.Collections; import java.util.List; 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. + * <p> + * 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/SubtitleInfo.java b/src/com/connectsdk/core/SubtitleInfo.java index d14bfa7f..7fc925fe 100644 --- a/src/com/connectsdk/core/SubtitleInfo.java +++ b/src/com/connectsdk/core/SubtitleInfo.java @@ -19,8 +19,6 @@ */ 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 diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index 32fbaa7f..41bfa2e6 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -39,6 +39,7 @@ import com.connectsdk.core.ImageInfo; import com.connectsdk.core.Log; import com.connectsdk.core.MediaInfo; +import com.connectsdk.core.NonNull; import com.connectsdk.core.ProgramInfo; import com.connectsdk.core.ProgramList; import com.connectsdk.core.Util; @@ -80,7 +81,6 @@ import com.connectsdk.service.webos.WebOSTVServiceSocketClient.WebOSTVServiceSocketClientListener; import android.graphics.PointF; -import android.support.annotation.NonNull; public class WebOSTVService extends DeviceService implements Launcher, MediaControl, MediaPlayer, VolumeControl, TVControl, ToastControl, ExternalInputControl, diff --git a/src/com/connectsdk/service/sessions/WebOSWebAppSession.java b/src/com/connectsdk/service/sessions/WebOSWebAppSession.java index 64570f82..f1b7c046 100644 --- a/src/com/connectsdk/service/sessions/WebOSWebAppSession.java +++ b/src/com/connectsdk/service/sessions/WebOSWebAppSession.java @@ -20,8 +20,6 @@ package com.connectsdk.service.sessions; -import android.support.annotation.NonNull; - import java.util.Enumeration; import java.util.List; import java.util.Locale; @@ -34,6 +32,7 @@ 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; From f2c64d3a799b6552176550d84fffc9418e0f4b5a Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 8 Dec 2016 23:54:27 +0100 Subject: [PATCH 29/41] moved PointF to core --- src/{android/graphics => com/connectsdk/core}/PointF.java | 4 ++-- src/com/connectsdk/service/NetcastTVService.java | 3 +-- src/com/connectsdk/service/WebOSTVService.java | 3 +-- src/com/connectsdk/service/capability/MouseControl.java | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) rename src/{android/graphics => com/connectsdk/core}/PointF.java (70%) diff --git a/src/android/graphics/PointF.java b/src/com/connectsdk/core/PointF.java similarity index 70% rename from src/android/graphics/PointF.java rename to src/com/connectsdk/core/PointF.java index 9e4d00af..8112afc6 100644 --- a/src/android/graphics/PointF.java +++ b/src/com/connectsdk/core/PointF.java @@ -1,5 +1,5 @@ -package android.graphics; -// maybe replace with point2d in awt +package com.connectsdk.core; + public class PointF { public PointF(float x, float y) { this.x = x; diff --git a/src/com/connectsdk/service/NetcastTVService.java b/src/com/connectsdk/service/NetcastTVService.java index dcc51c6d..a275b55f 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 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; diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index 41bfa2e6..57aa1d89 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -40,6 +40,7 @@ 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; @@ -80,8 +81,6 @@ import com.connectsdk.service.webos.WebOSTVServiceSocketClient; import com.connectsdk.service.webos.WebOSTVServiceSocketClient.WebOSTVServiceSocketClientListener; -import android.graphics.PointF; - public class WebOSTVService extends DeviceService implements Launcher, MediaControl, MediaPlayer, VolumeControl, TVControl, ToastControl, ExternalInputControl, MouseControl, TextInputControl, PowerControl, KeyControl, WebAppLauncher, PlaylistControl { diff --git a/src/com/connectsdk/service/capability/MouseControl.java b/src/com/connectsdk/service/capability/MouseControl.java index b34e632a..1218af56 100644 --- a/src/com/connectsdk/service/capability/MouseControl.java +++ b/src/com/connectsdk/service/capability/MouseControl.java @@ -20,7 +20,7 @@ package com.connectsdk.service.capability; -import android.graphics.PointF; +import com.connectsdk.core.PointF; public interface MouseControl extends CapabilityMethods { From 19cd60ae5e046ad5869f9d23e72dc881d2a987a1 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Wed, 22 Feb 2017 22:45:50 +0100 Subject: [PATCH 30/41] fixed javadoc --- pom.xml | 35 ++-- src/com/connectsdk/core/AppInfo.java | 8 +- src/com/connectsdk/core/ChannelInfo.java | 28 +-- .../connectsdk/core/ExternalInputInfo.java | 24 +-- src/com/connectsdk/core/ImageInfo.java | 54 +----- src/com/connectsdk/core/MediaInfo.java | 46 +---- src/com/connectsdk/core/ProgramInfo.java | 20 +-- src/com/connectsdk/core/SubtitleInfo.java | 18 +- .../connectsdk/core/TextInputStatusInfo.java | 10 +- src/com/connectsdk/core/Util.java | 3 +- .../connectsdk/device/ConnectableDevice.java | 169 +++--------------- .../device/ConnectableDeviceListener.java | 6 +- .../device/ConnectableDeviceStore.java | 2 +- .../device/DevicePickerListener.java | 4 +- .../device/SimpleDevicePickerListener.java | 6 +- .../discovery/CapabilityFilter.java | 48 +++-- .../discovery/DiscoveryManager.java | 54 ++++-- .../discovery/DiscoveryProvider.java | 8 +- .../discovery/DiscoveryProviderListener.java | 4 +- .../discovery/provider/ssdp/SSDPClient.java | 14 +- .../connectsdk/service/AirPlayService.java | 2 +- src/com/connectsdk/service/DeviceService.java | 13 +- .../connectsdk/service/WebOSTVService.java | 6 +- .../service/capability/CapabilityMethods.java | 2 +- .../service/capability/MediaControl.java | 19 +- .../service/capability/MediaPlayer.java | 13 ++ .../service/capability/PlaylistControl.java | 2 +- .../service/capability/TextInputControl.java | 2 +- .../capability/listeners/ErrorListener.java | 3 +- .../listeners/ResponseListener.java | 9 +- .../service/sessions/LaunchSession.java | 15 +- .../service/sessions/WebAppSession.java | 37 ++-- 32 files changed, 271 insertions(+), 413 deletions(-) diff --git a/pom.xml b/pom.xml index d81c4017..0c359b7e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,6 +4,10 @@ <groupId>Connect-SDK-Java-Core</groupId> <artifactId>Connect-SDK-Java-Core</artifactId> <version>0.0.1-SNAPSHOT</version> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> <repositories> <repository> <!-- required for java-websocket 1.3.1 --> @@ -11,19 +15,20 @@ <url>http://clojars.org/repo</url> </repository> </repositories> -<build> - <sourceDirectory>src</sourceDirectory> - <plugins> - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <version>3.5.1</version> - <configuration> - <source>1.8</source> - <target>1.8</target> - </configuration> - </plugin> - </plugins> - </build> + + <build> + <sourceDirectory>src</sourceDirectory> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.5.1</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> <dependencies> <dependency> <groupId>org.json</groupId> @@ -56,4 +61,8 @@ <version>4.5.2</version> </dependency> </dependencies> + <scm> + <url>https://github.com/sprehn/Connect-SDK-Android-Core</url> + <connection>scm:git:https://github.com/sprehn/Connect-SDK-Android-Core.git</connection> + </scm> </project> \ No newline at end of file diff --git a/src/com/connectsdk/core/AppInfo.java b/src/com/connectsdk/core/AppInfo.java index de157657..417beb1b 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; } diff --git a/src/com/connectsdk/core/ChannelInfo.java b/src/com/connectsdk/core/ChannelInfo.java index 21193ad6..2ad50143 100644 --- a/src/com/connectsdk/core/ChannelInfo.java +++ b/src/com/connectsdk/core/ChannelInfo.java @@ -43,62 +43,62 @@ 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; } @@ -106,9 +106,9 @@ public void setMajorNumber(int majorNumber) { /** * Compares two ChannelInfo objects. * - * @param channelInfo ChannelInfo object to compare. + * @param o ChannelInfo object to compare. * - * @return YES if both ChannelInfo number & name values are equal + * @return true if both ChannelInfo number & name values are equal */ @Override public boolean equals(Object o) { diff --git a/src/com/connectsdk/core/ExternalInputInfo.java b/src/com/connectsdk/core/ExternalInputInfo.java index f093a5ef..45739340 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; } @@ -108,9 +108,9 @@ public JSONObject toJSONObject() throws JSONException { /** * Compares two ExternalInputInfo objects. * - * @param externalInputInfo ExternalInputInfo object to compare. + * @param o ExternalInputInfo object to compare. * - * @return YES if both ExternalInputInfo id & name values are equal + * @return true if both ExternalInputInfo id & name values are equal */ @Override public boolean equals(Object o) { 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/MediaInfo.java b/src/com/connectsdk/core/MediaInfo.java index 0e8a0a4d..32796de8 100644 --- a/src/com/connectsdk/core/MediaInfo.java +++ b/src/com/connectsdk/core/MediaInfo.java @@ -152,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<ImageInfo> getImages() { @@ -214,40 +191,26 @@ public List<ImageInfo> 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<ImageInfo> 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; @@ -257,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/ProgramInfo.java b/src/com/connectsdk/core/ProgramInfo.java index 57e42312..9686bfe4 100644 --- a/src/com/connectsdk/core/ProgramInfo.java +++ b/src/com/connectsdk/core/ProgramInfo.java @@ -31,42 +31,42 @@ 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; } @@ -74,9 +74,9 @@ public void setRawData(Object rawData) { /** * Compares two ProgramInfo objects. * - * @param programInfo ProgramInfo object to compare. + * @param o ProgramInfo object to compare. * - * @return true if both ProgramInfo id & name values are equal + * @return true if both ProgramInfo id & name values are equal */ @Override public boolean equals(Object o) { diff --git a/src/com/connectsdk/core/SubtitleInfo.java b/src/com/connectsdk/core/SubtitleInfo.java index 7fc925fe..3ea33818 100644 --- a/src/com/connectsdk/core/SubtitleInfo.java +++ b/src/com/connectsdk/core/SubtitleInfo.java @@ -25,14 +25,16 @@ * 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. + * <ul> + * <li> `DLNAService` supports only SRT subtitles. Since there is no official specification for them, + * subtitles may not work on all DLNA-compatible devices</li> + * <li> `NetcastTVService` supports only SRT subtitles and has the same restrictions as `DLNAService`</li> + * <li> `CastService` supports only WebVTT subtitles and it has additional + * <a href="https://developers.google.com/cast/docs/android_sender#cors-requirements">requirements</a></li> + * <li> `FireTVService` supports only WebVTT subtitles</li> + * <li> `WebOSTVService` supports WebVTT subtitles. Server providing subtitles should + * support CORS headers, similarly to Cast service's requirements.</li> + * </ul> * */ 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 12485c84..14109ea5 100644 --- a/src/com/connectsdk/core/Util.java +++ b/src/com/connectsdk/core/Util.java @@ -42,8 +42,7 @@ public final class Util { /** * Configure Util on component start. * - * @param e must not be <code>null</null> - * @param ip may be <code>null</code> + * @param e must not be <code>null</code> */ public static void init(ExecutorService e) { executor = e; diff --git a/src/com/connectsdk/device/ConnectableDevice.java b/src/com/connectsdk/device/ConnectableDevice.java index 143f24df..95dceffc 100644 --- a/src/com/connectsdk/device/ConnectableDevice.java +++ b/src/com/connectsdk/device/ConnectableDevice.java @@ -151,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<DeviceService> services = getServices(); @@ -231,7 +231,7 @@ private synchronized List<String> getMismatchCapabilities(List<String> 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<DeviceService> getServices() { return services.values(); } @@ -262,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()) { @@ -369,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()) { @@ -398,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<String> getCapabilities() { List<String> caps = new ArrayList<String>(); @@ -421,6 +422,7 @@ public synchronized List<String> 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; @@ -441,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()) { @@ -457,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<String> capabilities) { String[] arr = new String[capabilities.size()]; @@ -470,6 +474,7 @@ public synchronized boolean hasCapabilities(List<String> 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; @@ -484,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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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 <T> a capability methods class * @return capability implementation */ public <T extends CapabilityMethods> T getCapability(Class<T> controllerClass) { @@ -658,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; } @@ -672,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; } @@ -680,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; } @@ -694,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; } @@ -714,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; } @@ -728,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; } @@ -742,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; } @@ -756,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; } @@ -770,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<String> of capabilities that are new to the ConnectableDevice - * @param removed List<String> 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<String> added, List<String> 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/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/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<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); -@endcode + * <code> + * 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); + * </code> * * Filter for all devices that support (video playback AND any media controls AND volume up/down) OR (image display). + * <code> + * 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); + * </code> */ public class CapabilityFilter { diff --git a/src/com/connectsdk/discovery/DiscoveryManager.java b/src/com/connectsdk/discovery/DiscoveryManager.java index f8ec673f..b89722fd 100644 --- a/src/com/connectsdk/discovery/DiscoveryManager.java +++ b/src/com/connectsdk/discovery/DiscoveryManager.java @@ -74,14 +74,12 @@ * * Example: * - * @capability kMediaControlPlay - * - * @code + * <code> * DiscoveryManager.init(getApplicationContext()); * DiscoveryManager discoveryManager = DiscoveryManager.getInstance(); * discoveryManager.addListener(this); * discoveryManager.start(); - * @endcode + * </code> * * [0]: http://tools.ietf.org/html/draft-cai-ssdp-v1-03 */ @@ -141,9 +139,11 @@ public enum PairingLevel { * 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 + * <code> * DiscoveryManager.init(getApplicationContext()); - * @endcode + * </code> + * + * @param context a valid context */ public static synchronized void init(Context context) { instance = new DiscoveryManager(context); @@ -159,17 +159,20 @@ public static synchronized void destroy() { * * This accepts a ConnectableDeviceStore to use instead of the default device store. * - * @code + * <code> * MyConnectableDeviceStore myDeviceStore = new MyConnectableDeviceStore(); * DiscoveryManager.init(getApplicationContext(), myDeviceStore); - * @endcode + * </code> + * + * @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) { @@ -184,6 +187,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)); @@ -193,6 +197,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; @@ -284,13 +291,15 @@ public DiscoveryManager(Context context, ConnectableDeviceStore connectableDevic // } /** - * Listener which should receive discovery updates. It is not necessary to set this listener property unless you are + * 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. + * + * @param listener Listener which should receive discovery updates */ public void addListener(DiscoveryManagerListener listener) { // notify listener of all devices so far @@ -302,6 +311,8 @@ 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); @@ -330,7 +341,7 @@ public void setCapabilityFilters(List<CapabilityFilter> capabilityFilters) { } /** - * Returns the list of capability filters. + * @return the list of capability filters. */ public List<CapabilityFilter> getCapabilityFilters() { return capabilityFilters; @@ -595,9 +606,6 @@ public void stop() { } /** - * 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. * @@ -606,15 +614,16 @@ public void stop() { * * 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. + * */ 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. * @@ -623,6 +632,9 @@ public void setConnectableDeviceStore(ConnectableDeviceStore connectableDeviceSt * * 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; @@ -684,7 +696,7 @@ public boolean isNetcast(ServiceDescription description) { // @endcond /** - * List of all devices discovered by DiscoveryManager. Each ConnectableDevice object is keyed against its current IP + * @return List of all devices discovered by DiscoveryManager. Each ConnectableDevice object is keyed against its current IP * address. */ public Map<String, ConnectableDevice> getAllDevices() { @@ -692,7 +704,7 @@ public Map<String, ConnectableDevice> getAllDevices() { } /** - * Filtered list of discovered ConnectableDevices, limited to devices that match at least one of the + * @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. */ @@ -709,6 +721,8 @@ public Map<String, ConnectableDevice> getCompatibleDevices() { * * 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; @@ -723,6 +737,8 @@ public PairingLevel getPairingLevel() { * * 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; diff --git a/src/com/connectsdk/discovery/DiscoveryProvider.java b/src/com/connectsdk/discovery/DiscoveryProvider.java index 99aa4fc0..471b84f8 100644 --- a/src/com/connectsdk/discovery/DiscoveryProvider.java +++ b/src/com/connectsdk/discovery/DiscoveryProvider.java @@ -64,10 +64,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); /** @@ -92,7 +94,7 @@ public interface DiscoveryProvider { public void setFilters(List<DiscoveryFilter> 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/ssdp/SSDPClient.java b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java index 971b0eb6..9c6fa628 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java +++ b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java @@ -83,7 +83,9 @@ 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); @@ -91,7 +93,9 @@ public void send(String data) throws IOException { } - /** 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 { diff --git a/src/com/connectsdk/service/AirPlayService.java b/src/com/connectsdk/service/AirPlayService.java index 51100d14..d509c5ea 100644 --- a/src/com/connectsdk/service/AirPlayService.java +++ b/src/com/connectsdk/service/AirPlayService.java @@ -214,7 +214,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) { diff --git a/src/com/connectsdk/service/DeviceService.java b/src/com/connectsdk/service/DeviceService.java index 60b4c121..4d8b8f64 100644 --- a/src/com/connectsdk/service/DeviceService.java +++ b/src/com/connectsdk/service/DeviceService.java @@ -60,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 @@ -279,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; } @@ -383,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); @@ -407,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) { @@ -423,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<String> capabilities) { String[] arr = new String[capabilities.size()]; @@ -436,6 +439,7 @@ public boolean hasCapabilities(List<String> 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; @@ -484,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/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index 57aa1d89..a5c01618 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -1488,7 +1488,7 @@ public void channelDown(ResponseListener<Object> listener) { * Sets current channel * * @param channelInfo must not be null - * @param listener + * @param listener the response listener * @throws NullPointerException if channelInfo is null */ @Override @@ -2734,9 +2734,9 @@ public void sendMessage(JSONObject message, LaunchSession launchSession, Respons } } - /************** + /* ************* * SYSTEM CONTROL - **************/ + ************* */ public void getServiceInfo(final ServiceInfoListener listener) { String uri = "ssap://api/getServiceList"; 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/MediaControl.java b/src/com/connectsdk/service/capability/MediaControl.java index a7fb7a60..f99ffbc5 100644 --- a/src/com/connectsdk/service/capability/MediaControl.java +++ b/src/com/connectsdk/service/capability/MediaControl.java @@ -193,44 +193,49 @@ else if (transportState.equals("NO_MEDIA_PRESENT")) { /** * This method is deprecated. - * Use `PlaylistControl#previous(ResponseListener<Object> listener)` instead. + * Use `PlaylistControl#previous(ResponseListener<Object> listener)` instead. + * @param listener the listener */ @Deprecated public void previous(ResponseListener<Object> listener); /** * This method is deprecated. - * Use `PlaylistControl#next(ResponseListener<Object> listener)` instead. + * Use `PlaylistControl#next(ResponseListener<Object> listener)` instead. + * @param listener the listener */ @Deprecated public void next(ResponseListener<Object> 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<Object> 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<PlayStateListener> + * @return ServiceSubscription<PlayStateListener> */ public ServiceSubscription<PlayStateListener> subscribePlayState(PlayStateListener listener); diff --git a/src/com/connectsdk/service/capability/MediaPlayer.java b/src/com/connectsdk/service/capability/MediaPlayer.java index a45715c0..8fd08c6e 100644 --- a/src/com/connectsdk/service/capability/MediaPlayer.java +++ b/src/com/connectsdk/service/capability/MediaPlayer.java @@ -87,6 +87,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 +101,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/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<Object> listener); diff --git a/src/com/connectsdk/service/capability/TextInputControl.java b/src/com/connectsdk/service/capability/TextInputControl.java index aae0802c..f11cf5ce 100644 --- a/src/com/connectsdk/service/capability/TextInputControl.java +++ b/src/com/connectsdk/service/capability/TextInputControl.java @@ -51,7 +51,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<TextInputStatusInfo> { } } 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<T> 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 <code>null</code> 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 <code>null</code> */ - abstract public void onSuccess(T object); + abstract public void onSuccess(T responseObject); } diff --git a/src/com/connectsdk/service/sessions/LaunchSession.java b/src/com/connectsdk/service/sessions/LaunchSession.java index 63070820..5db9727d 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<Object> listener) { service.closeLaunchSession(this, listener); 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<Boolean> { } /** * 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<MessageListener> subscribeWebAppStatus( MessageListener listener) { @@ -122,8 +120,7 @@ public ServiceSubscription<MessageListener> 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<Object> connectionListener) { Util.postError(connectionListener, ServiceCommandError.notSupported()); @@ -132,7 +129,7 @@ public void connect(ResponseListener<Object> 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<Object> 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<Object> listener) { Util.postError(listener, ServiceCommandError.notSupported()); @@ -155,6 +154,7 @@ public void pinWebApp(String webAppId, ResponseListener<Object> 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<Object> listener) { Util.postError(listener, ServiceCommandError.notSupported()); @@ -162,6 +162,8 @@ public void unPinWebApp(String webAppId, ResponseListener<Object> 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<WebAppPinStatusListener> subscribeIsWebAppPinned(String webAppId, WebAppPinStatusListener listener) { Util.postError(listener, ServiceCommandError.notSupported()); @@ -178,8 +183,7 @@ public ServiceSubscription<WebAppPinStatusListener> 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<Object> listener) { if (listener != null) @@ -190,6 +194,7 @@ public void close(ResponseListener<Object> 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<Object> 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<Object> 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 From 77b5180d80568a34ef956a9e5aa0be4140e46e73 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Wed, 22 Feb 2017 23:31:52 +0100 Subject: [PATCH 31/41] site deployment to github added --- pom.xml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/pom.xml b/pom.xml index 0c359b7e..a4bb73e7 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,35 @@ <target>1.8</target> </configuration> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>3.3</version> + <configuration> + <skipDeploy>true</skipDeploy> + </configuration> + </plugin> + <plugin> + <!-- Deploy the web site --> + <groupId>com.github.github</groupId> + <artifactId>site-maven-plugin</artifactId> + <version>0.12</version> + <executions> + <execution> + <goals> + <goal>site</goal> + </goals> + <phase>site-deploy</phase> + <configuration> + <server>github</server> + <message>site built</message> + <path>${project.version}</path> + <merge>true</merge> + </configuration> + </execution> + </executions> + </plugin> + </plugins> </build> <dependencies> From c3fd53992e80d5fbd8b18228bdee957dabf67c81 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Wed, 22 Feb 2017 23:39:19 +0100 Subject: [PATCH 32/41] repo renamed --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a4bb73e7..eb5b9fdc 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ <configuration> <server>github</server> <message>site built</message> - <path>${project.version}</path> + <path>${site.path}</path> <merge>true</merge> </configuration> </execution> @@ -91,7 +91,7 @@ </dependency> </dependencies> <scm> - <url>https://github.com/sprehn/Connect-SDK-Android-Core</url> - <connection>scm:git:https://github.com/sprehn/Connect-SDK-Android-Core.git</connection> + <url>https://github.com/sprehn/Connect-SDK-Java-Core</url> + <connection>scm:git:https://github.com/sprehn/Connect-SDK-Java-Core.git</connection> </scm> </project> \ No newline at end of file From 7f46f7268c6a1d37ca082b0caa4b2242558479fc Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Wed, 22 Feb 2017 23:55:18 +0100 Subject: [PATCH 33/41] link to project page added, setup instructions removed --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 54774782..fdff72db 100644 --- a/README.md +++ b/README.md @@ -13,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. From e6a9ab0c5147bcf5bbf3e41a7cc92cbd948079a0 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Thu, 23 Feb 2017 00:36:30 +0100 Subject: [PATCH 34/41] site reporting section --- pom.xml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eb5b9fdc..e8466c7e 100644 --- a/pom.xml +++ b/pom.xml @@ -55,9 +55,22 @@ </execution> </executions> </plugin> - </plugins> </build> + <reporting> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.10.4</version> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>findbugs-maven-plugin</artifactId> + <version>3.0.4</version> + </plugin> + </plugins> + </reporting> <dependencies> <dependency> <groupId>org.json</groupId> From 53e931a868af448a13be8c7965bc35f87b4b2b7f Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Fri, 24 Feb 2017 00:52:42 +0100 Subject: [PATCH 35/41] findbugs analyis - many high and medium findings removed --- pom.xml | 5 + src/com/connectsdk/core/AppInfo.java | 37 ++++--- src/com/connectsdk/core/ChannelInfo.java | 84 +++++++++------- .../connectsdk/core/ExternalInputInfo.java | 44 ++++++--- src/com/connectsdk/core/ProgramInfo.java | 44 ++++++--- src/com/connectsdk/core/Util.java | 2 +- .../connectsdk/device/ConnectableDevice.java | 2 +- .../device/DefaultConnectableDeviceStore.java | 96 ++++++------------- .../discovery/DiscoveryManager.java | 23 ++--- .../discovery/DiscoveryProvider.java | 7 -- .../provider/SSDPDiscoveryProvider.java | 90 +++++++---------- .../provider/ZeroconfDiscoveryProvider.java | 25 ++--- .../discovery/provider/ssdp/Action.java | 36 ------- .../discovery/provider/ssdp/Argument.java | 38 -------- .../discovery/provider/ssdp/Icon.java | 20 ++-- .../discovery/provider/ssdp/SSDPClient.java | 6 +- .../discovery/provider/ssdp/SSDPDevice.java | 20 ++-- .../discovery/provider/ssdp/Service.java | 6 +- .../provider/ssdp/StateVariable.java | 44 --------- .../connectsdk/service/AirPlayService.java | 1 + src/com/connectsdk/service/DLNAService.java | 14 ++- .../connectsdk/service/NetcastTVService.java | 4 +- .../connectsdk/service/WebOSTVService.java | 19 +--- .../service/airplay/PListParser.java | 2 +- .../service/capability/VolumeControl.java | 10 +- .../service/netcast/NetcastHttpServer.java | 19 +--- .../service/sessions/LaunchSession.java | 13 +-- .../webos/WebOSTVServiceSocketClient.java | 5 +- 28 files changed, 270 insertions(+), 446 deletions(-) delete mode 100644 src/com/connectsdk/discovery/provider/ssdp/Action.java delete mode 100644 src/com/connectsdk/discovery/provider/ssdp/Argument.java delete mode 100644 src/com/connectsdk/discovery/provider/ssdp/StateVariable.java diff --git a/pom.xml b/pom.xml index e8466c7e..cf26f820 100644 --- a/pom.xml +++ b/pom.xml @@ -68,6 +68,11 @@ <groupId>org.codehaus.mojo</groupId> <artifactId>findbugs-maven-plugin</artifactId> <version>3.0.4</version> + <configuration> + <effort>Max</effort> + <threshold>High</threshold> + + </configuration> </plugin> </plugins> </reporting> diff --git a/src/com/connectsdk/core/AppInfo.java b/src/com/connectsdk/core/AppInfo.java index 417beb1b..9d4543e8 100644 --- a/src/com/connectsdk/core/AppInfo.java +++ b/src/com/connectsdk/core/AppInfo.java @@ -114,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 2ad50143..4145fc3f 100644 --- a/src/com/connectsdk/core/ChannelInfo.java +++ b/src/com/connectsdk/core/ChannelInfo.java @@ -48,7 +48,10 @@ public JSONObject getRawData() { return rawData; } - /** @param rawData 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; } @@ -103,38 +106,6 @@ public void setMajorNumber(int majorNumber) { this.majorNumber = majorNumber; } - /** - * Compares two ChannelInfo objects. - * - * @param o ChannelInfo object to compare. - * - * @return true 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 { @@ -150,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/ExternalInputInfo.java b/src/com/connectsdk/core/ExternalInputInfo.java index 45739340..8db1599b 100644 --- a/src/com/connectsdk/core/ExternalInputInfo.java +++ b/src/com/connectsdk/core/ExternalInputInfo.java @@ -105,20 +105,36 @@ public JSONObject toJSONObject() throws JSONException { } // @endcond - /** - * Compares two ExternalInputInfo objects. - * - * @param o ExternalInputInfo object to compare. - * - * @return true 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/ProgramInfo.java b/src/com/connectsdk/core/ProgramInfo.java index 9686bfe4..31f778bf 100644 --- a/src/com/connectsdk/core/ProgramInfo.java +++ b/src/com/connectsdk/core/ProgramInfo.java @@ -71,20 +71,36 @@ public void setRawData(Object rawData) { this.rawData = rawData; } - /** - * Compares two ProgramInfo objects. - * - * @param o 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/Util.java b/src/com/connectsdk/core/Util.java index 14109ea5..d43a0497 100644 --- a/src/com/connectsdk/core/Util.java +++ b/src/com/connectsdk/core/Util.java @@ -35,7 +35,7 @@ public final class Util { - static public String T = "Connect SDK"; + static public final String T = "Connect SDK"; static private ExecutorService executor; diff --git a/src/com/connectsdk/device/ConnectableDevice.java b/src/com/connectsdk/device/ConnectableDevice.java index 95dceffc..a12e8fa4 100644 --- a/src/com/connectsdk/device/ConnectableDevice.java +++ b/src/com/connectsdk/device/ConnectableDevice.java @@ -96,7 +96,7 @@ public class ConnectableDevice implements DeviceServiceListener { Map<String, DeviceService> services; - public boolean featuresReady = false; + //public boolean featuresReady = false; public ConnectableDevice() { services = new ConcurrentHashMap<String, DeviceService>(); diff --git a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java index 3a90d5d3..fe665cf5 100644 --- a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java +++ b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java @@ -21,10 +21,17 @@ 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.io.FileOutputStream; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -34,6 +41,7 @@ import org.json.JSONObject; 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; @@ -85,10 +93,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; @@ -96,8 +100,6 @@ public class DefaultConnectableDeviceStore implements ConnectableDeviceStore { private Map<String, JSONObject> storedDevices = new ConcurrentHashMap<String, JSONObject>(); private Map<String, ConnectableDevice> activeDevices = new ConcurrentHashMap<String, ConnectableDevice>(); - private boolean waitToWrite = false; - public DefaultConnectableDeviceStore(Context context) { fileFullPath = context.getDataDir() + "/" + FILENAME; @@ -273,29 +275,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), "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) { @@ -308,32 +302,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); @@ -341,42 +325,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),"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/discovery/DiscoveryManager.java b/src/com/connectsdk/discovery/DiscoveryManager.java index b89722fd..815aa723 100644 --- a/src/com/connectsdk/discovery/DiscoveryManager.java +++ b/src/com/connectsdk/discovery/DiscoveryManager.java @@ -105,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<String, ConnectableDevice> allDevices; private ConcurrentHashMap<String, ConnectableDevice> compatibleDevices; @@ -123,13 +121,8 @@ public enum PairingLevel { private CopyOnWriteArrayList<DiscoveryManagerListener> discoveryListeners; List<CapabilityFilter> capabilityFilters; - //MulticastLock multicastLock; - //BroadcastReceiver receiver; - boolean isBroadcastReceiverRegistered = false; - - Timer rescanTimer; - - PairingLevel pairingLevel; + + private PairingLevel pairingLevel; private boolean mSearching = false; @@ -386,12 +379,12 @@ public void registerDefaultDeviceTypes() { final HashMap<String, String> devicesList = new HashMap<String, String>(); 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", + //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", diff --git a/src/com/connectsdk/discovery/DiscoveryProvider.java b/src/com/connectsdk/discovery/DiscoveryProvider.java index 471b84f8..38f793b8 100644 --- a/src/com/connectsdk/discovery/DiscoveryProvider.java +++ b/src/com/connectsdk/discovery/DiscoveryProvider.java @@ -86,13 +86,6 @@ 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<DiscoveryFilter> filters); - /** * @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. */ diff --git a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java index b4523959..0cac0bff 100644 --- a/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/SSDPDiscoveryProvider.java @@ -23,7 +23,6 @@ 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; @@ -53,35 +52,28 @@ import com.connectsdk.service.config.ServiceDescription; public class SSDPDiscoveryProvider implements DiscoveryProvider { - Context context; + private Context context; - boolean needToStartSearch = false; + private CopyOnWriteArrayList<DiscoveryProviderListener> serviceListeners = new CopyOnWriteArrayList<DiscoveryProviderListener>(); - private CopyOnWriteArrayList<DiscoveryProviderListener> serviceListeners; + private ConcurrentHashMap<String, ServiceDescription> foundServices = new ConcurrentHashMap<String, ServiceDescription>(); + private ConcurrentHashMap<String, ServiceDescription> discoveredServices = new ConcurrentHashMap<String, ServiceDescription>(); - ConcurrentHashMap<String, ServiceDescription> foundServices = new ConcurrentHashMap<String, ServiceDescription>(); - ConcurrentHashMap<String, ServiceDescription> discoveredServices = new ConcurrentHashMap<String, ServiceDescription>(); - - List<DiscoveryFilter> serviceFilters; + private List<DiscoveryFilter> serviceFilters = new CopyOnWriteArrayList<DiscoveryFilter>(); private SSDPClient ssdpClient; private Timer scanTimer; - private Pattern uuidReg; + private Pattern uuidReg = Pattern.compile("(?<=uuid:)(.+?)(?=(::)|$)"); private Thread responseThread; private Thread notifyThread; private ScheduledExecutorService executorService; - boolean isRunning = false; + private boolean isRunning = false; public SSDPDiscoveryProvider(Context context) { this.context = context; - - uuidReg = Pattern.compile("(?<=uuid:)(.+?)(?=(::)|$)"); - - serviceListeners = new CopyOnWriteArrayList<DiscoveryProviderListener>(); - serviceFilters = new CopyOnWriteArrayList<DiscoveryFilter>(); } private void openSocket() { @@ -96,7 +88,7 @@ private void openSocket() { } ssdpClient = createSocket(source); - } catch (IOException e) { + } catch (IOException e) { e.printStackTrace(); } } @@ -114,8 +106,8 @@ public void start() { isRunning = true; openSocket(); - if (serviceFilters != null && !serviceFilters.isEmpty()) { - //three tasks for each service filter + if (!serviceFilters.isEmpty()) { + // three tasks for each service filter int poolSize = serviceFilters.size() * 3; executorService = Executors.newScheduledThreadPool(poolSize); } @@ -210,7 +202,7 @@ public void rescan() { Log.w(Util.T, "There are no filters added"); } else { if (executorService.isTerminated() || executorService.isShutdown()) { - if (serviceFilters != null && !serviceFilters.isEmpty()) { + if (!serviceFilters.isEmpty()) { int poolSize = serviceFilters.size() * 3; executorService = Executors.newScheduledThreadPool(poolSize); } @@ -250,11 +242,6 @@ public void removeDeviceFilter(DiscoveryFilter filter) { serviceFilters.remove(filter); } - @Override - public void setFilters(List<DiscoveryFilter> filters) { - serviceFilters = filters; - } - @Override public boolean isEmpty() { return serviceFilters.size() == 0; @@ -406,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); @@ -511,17 +496,6 @@ public boolean isSearchingForFilter(String filter) { return false; } - public boolean containsServicesWithFilter(SSDPDevice device, String filter) { - // List<String> servicesRequired = new ArrayList<String>(); - // - // 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 b7715304..9c287408 100644 --- a/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java +++ b/src/com/connectsdk/discovery/provider/ZeroconfDiscoveryProvider.java @@ -30,7 +30,6 @@ import java.io.IOException; import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -51,10 +50,11 @@ public class ZeroconfDiscoveryProvider implements DiscoveryProvider { private Timer scanTimer; - List<DiscoveryFilter> serviceFilters; + private List<DiscoveryFilter> serviceFilters = new CopyOnWriteArrayList<DiscoveryFilter>(); - ConcurrentHashMap<String, ServiceDescription> foundServices; - CopyOnWriteArrayList<DiscoveryProviderListener> serviceListeners; + private ConcurrentHashMap<String, ServiceDescription> foundServices = new ConcurrentHashMap<String, ServiceDescription>(8, 0.75f, 2); + private CopyOnWriteArrayList<DiscoveryProviderListener> serviceListeners = new CopyOnWriteArrayList<DiscoveryProviderListener>(); + boolean isRunning = false; @@ -74,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()); @@ -87,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; @@ -135,14 +133,7 @@ public void serviceAdded(ServiceEvent event) { }; public ZeroconfDiscoveryProvider(Context context) { - foundServices = new ConcurrentHashMap<String, ServiceDescription>(8, 0.75f, 2); - - serviceListeners = new CopyOnWriteArrayList<DiscoveryProviderListener>(); - serviceFilters = new CopyOnWriteArrayList<DiscoveryFilter>(); - - srcAddress = context.getIpAddress(); - } @Override @@ -278,10 +269,6 @@ public void removeDeviceFilter(DiscoveryFilter filter) { serviceFilters.remove(filter); } - @Override - public void setFilters(List<DiscoveryFilter> 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<Argument> 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 9c6fa628..7de3b022 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java +++ b/src/com/connectsdk/discovery/provider/ssdp/SSDPClient.java @@ -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; @@ -87,8 +87,8 @@ public SSDPClient(InetAddress source, MulticastSocket mcSocket, DatagramSocket d * @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); } diff --git a/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java b/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java index ddccba81..88644689 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java +++ b/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java @@ -21,7 +21,6 @@ package com.connectsdk.discovery.provider.ssdp; import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -66,7 +65,7 @@ public class SSDPDevice { /* Optional. */ public List<Service> serviceList = new ArrayList<Service>(); - public String ST; +// public String ST; public String applicationURL; public String serviceURI; @@ -99,7 +98,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 +109,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(locationXML, 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<Action> actionList; - public List<StateVariable> serviceStateTable; + + //public List<StateVariable> 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/service/AirPlayService.java b/src/com/connectsdk/service/AirPlayService.java index d509c5ea..75433a9b 100644 --- a/src/com/connectsdk/service/AirPlayService.java +++ b/src/com/connectsdk/service/AirPlayService.java @@ -42,6 +42,7 @@ 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; diff --git a/src/com/connectsdk/service/DLNAService.java b/src/com/connectsdk/service/DLNAService.java index 73daa4ed..b418f126 100644 --- a/src/com/connectsdk/service/DLNAService.java +++ b/src/com/connectsdk/service/DLNAService.java @@ -50,6 +50,7 @@ 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; @@ -80,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; @@ -744,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 { diff --git a/src/com/connectsdk/service/NetcastTVService.java b/src/com/connectsdk/service/NetcastTVService.java index a275b55f..aa7c004f 100644 --- a/src/com/connectsdk/service/NetcastTVService.java +++ b/src/com/connectsdk/service/NetcastTVService.java @@ -1072,8 +1072,8 @@ public void onSuccess(List<ChannelInfo> 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); diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index a5c01618..cdef9586 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -20,7 +20,7 @@ package com.connectsdk.service; -import java.io.ByteArrayOutputStream; + import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; @@ -97,9 +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, @@ -112,12 +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, @@ -125,9 +117,6 @@ 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", @@ -3081,7 +3070,7 @@ private ChannelInfo parseRawChannelData(JSONObject channelRawData) { private int parseMinorNumber(String channelNumber) { if (channelNumber != null) { String tokens[] = channelNumber.split("-"); - return Integer.valueOf(tokens[tokens.length - 1]); + return Integer.parseInt(tokens[tokens.length - 1]); } else { return 0; } @@ -3090,7 +3079,7 @@ private int parseMinorNumber(String channelNumber) { private int parseMajorNumber(String channelNumber) { if (channelNumber != null) { String tokens[] = channelNumber.split("-"); - return Integer.valueOf(tokens[0]); + return Integer.parseInt(tokens[0]); } else { return 0; } diff --git a/src/com/connectsdk/service/airplay/PListParser.java b/src/com/connectsdk/service/airplay/PListParser.java index c9e8b229..50d40674 100644 --- a/src/com/connectsdk/service/airplay/PListParser.java +++ b/src/com/connectsdk/service/airplay/PListParser.java @@ -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/VolumeControl.java b/src/com/connectsdk/service/capability/VolumeControl.java index 7aec7bb8..7bfc63e8 100644 --- a/src/com/connectsdk/service/capability/VolumeControl.java +++ b/src/com/connectsdk/service/capability/VolumeControl.java @@ -20,6 +20,10 @@ package com.connectsdk.service.capability; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + import com.connectsdk.service.capability.listeners.ResponseListener; import com.connectsdk.service.command.ServiceSubscription; @@ -33,7 +37,7 @@ 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 = { Volume_Get, Volume_Set, @@ -43,6 +47,10 @@ public interface VolumeControl extends CapabilityMethods { Mute_Set, Mute_Subscribe }; + + public static List<String> getCapabilities() { + return Collections.unmodifiableList(Arrays.asList(Capabilities)); + } public VolumeControl getVolumeControl(); public CapabilityPriorityLevel getVolumeControlCapabilityLevel(); diff --git a/src/com/connectsdk/service/netcast/NetcastHttpServer.java b/src/com/connectsdk/service/netcast/NetcastHttpServer.java index d78b3d2f..8d3256b0 100644 --- a/src/com/connectsdk/service/netcast/NetcastHttpServer.java +++ b/src/com/connectsdk/service/netcast/NetcastHttpServer.java @@ -92,7 +92,7 @@ public void start() { Socket connectionSocket = null; BufferedReader inFromClient = null; - DataOutputStream outToClient = null; + try { connectionSocket = welcomeSocket.accept(); @@ -137,11 +137,7 @@ public void start() { String date = dateFormat.format(calendar.getTime()); //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 DataOutputStream(connectionSocket.getOutputStream()))) { out.println("HTTP/1.1 200 OK"); //out.println("Server: Android/" + androidOSVersion + " UDAP/2.0 ConnectSDK/1.2.1"); out.println("Cache-Control: no-store, no-cache, must-revalidate"); @@ -152,16 +148,7 @@ 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; diff --git a/src/com/connectsdk/service/sessions/LaunchSession.java b/src/com/connectsdk/service/sessions/LaunchSession.java index 5db9727d..1f772899 100644 --- a/src/com/connectsdk/service/sessions/LaunchSession.java +++ b/src/com/connectsdk/service/sessions/LaunchSession.java @@ -226,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/webos/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index 5c1d6d88..57663cbe 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -78,8 +78,7 @@ public enum State { private HashMap<Integer, ServiceCommand<? extends Object>> requests = new HashMap<Integer,ServiceCommand<? extends Object>>(); boolean mConnectSucceeded = false; - Boolean mConnected; - + public WebOSTVServiceSocketClient(WebOSTVService service, URI uri) { super(uri); @@ -339,7 +338,7 @@ protected void handleMessage(JSONObject message) { 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()).setServerCertificate((X509Certificate) null); mService.getServiceConfig().setServiceUUID(null); mService.getServiceDescription().setIpAddress(null); mService.getServiceDescription().setUUID(null); From 47956d20a6b0f11317a7efadb6b9910992b75b0f Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Fri, 24 Feb 2017 22:05:42 +0100 Subject: [PATCH 36/41] removed all high findings --- pom.xml | 3 +- .../device/DefaultConnectableDeviceStore.java | 5 +- .../discovery/DiscoveryProvider.java | 2 - .../connectsdk/etc/helper/HttpConnection.java | 9 +- .../connectsdk/service/AirPlayService.java | 5 +- src/com/connectsdk/service/DIALService.java | 2 +- .../connectsdk/service/NetcastTVService.java | 53 +++------ src/com/connectsdk/service/RokuService.java | 13 +-- .../connectsdk/service/WebOSTVService.java | 20 ++-- .../capability/ExternalInputControl.java | 8 +- .../service/capability/KeyControl.java | 10 +- .../service/capability/Launcher.java | 8 +- .../service/capability/MediaControl.java | 11 +- .../service/capability/MediaPlayer.java | 9 +- .../service/capability/MouseControl.java | 9 +- .../service/capability/PowerControl.java | 9 +- .../service/capability/TVControl.java | 8 +- .../service/capability/TextInputControl.java | 9 +- .../service/capability/ToastControl.java | 9 +- .../service/capability/VolumeControl.java | 13 +-- .../service/capability/WebAppLauncher.java | 9 +- .../service/netcast/NetcastHttpServer.java | 17 +-- .../netcast/NetcastPOSTRequestParser.java | 44 +++---- .../service/upnp/DLNAHttpServer.java | 109 +++++++----------- .../service/upnp/DLNANotifyParser.java | 9 +- .../service/webos/WebOSTVKeyboardInput.java | 2 - .../webos/WebOSTVServiceSocketClient.java | 10 +- 27 files changed, 201 insertions(+), 214 deletions(-) diff --git a/pom.xml b/pom.xml index cf26f820..5d3fa31f 100644 --- a/pom.xml +++ b/pom.xml @@ -70,8 +70,7 @@ <version>3.0.4</version> <configuration> <effort>Max</effort> - <threshold>High</threshold> - + <!--threshold>Low</threshold--> </configuration> </plugin> </plugins> diff --git a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java index fe665cf5..c0899774 100644 --- a/src/com/connectsdk/device/DefaultConnectableDeviceStore.java +++ b/src/com/connectsdk/device/DefaultConnectableDeviceStore.java @@ -31,6 +31,7 @@ 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; @@ -282,7 +283,7 @@ private void load() { created = Util.getTime(); updated = Util.getTime(); } else { - try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))){ + try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))){ StringBuilder sb = new StringBuilder(); @@ -327,7 +328,7 @@ private synchronized void store() { deviceStore.put(KEY_DEVICES, deviceArray); - try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output),"UTF-8"))) { + try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output), StandardCharsets.UTF_8))) { out.write(deviceStore.toString()); } } catch (JSONException|IOException e) { diff --git a/src/com/connectsdk/discovery/DiscoveryProvider.java b/src/com/connectsdk/discovery/DiscoveryProvider.java index 38f793b8..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 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 75433a9b..768f379b 100644 --- a/src/com/connectsdk/service/AirPlayService.java +++ b/src/com/connectsdk/service/AirPlayService.java @@ -54,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; @@ -72,7 +73,7 @@ public class AirPlayService extends DeviceService implements MediaPlayer, MediaC 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; @@ -610,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 25b5a5ab..d0a85d27 100644 --- a/src/com/connectsdk/service/DIALService.java +++ b/src/com/connectsdk/service/DIALService.java @@ -208,7 +208,7 @@ public void launchYouTube(String contentId, float startTime, AppLaunchListener l String params = null; AppInfo appInfo = new AppInfo(APP_YOUTUBE); appInfo.setName(appInfo.getId()); - JSONObject jsonParams = null; + //JSONObject jsonParams = null; if (contentId != null && contentId.length() > 0) { if (startTime < 0.0) { if (listener != null) { diff --git a/src/com/connectsdk/service/NetcastTVService.java b/src/com/connectsdk/service/NetcastTVService.java index aa7c004f..def13424 100644 --- a/src/com/connectsdk/service/NetcastTVService.java +++ b/src/com/connectsdk/service/NetcastTVService.java @@ -73,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; @@ -996,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(); @@ -1018,13 +1019,9 @@ public void onSuccess(Object response) { } Util.postSuccess(listener, channelList); - } catch (ParserConfigurationException e) { + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + } } @Override @@ -1112,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(); @@ -1127,15 +1124,9 @@ public void onSuccess(Object response) { Util.postSuccess(listener, channel); } - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { + } catch (ParserConfigurationException | SAXException | JSONException | IOException e) { e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (JSONException e) { - e.printStackTrace(); - } + } } @Override @@ -2059,60 +2050,48 @@ public void powerOn(ResponseListener<Object> 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) { + } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - } catch (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) { - e.printStackTrace(); - } catch (IOException e) { + } catch (ParserConfigurationException | SAXException | 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; } diff --git a/src/com/connectsdk/service/RokuService.java b/src/com/connectsdk/service/RokuService.java index ee0fd314..9e793b74 100644 --- a/src/com/connectsdk/service/RokuService.java +++ b/src/com/connectsdk/service/RokuService.java @@ -59,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; @@ -264,7 +265,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(); @@ -273,15 +274,9 @@ public void onSuccess(Object response) { List<AppInfo> 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 diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index cdef9586..2d80e20e 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -2903,18 +2903,18 @@ public void unsubscribe(URLServiceSubscription<?> subscription) { protected void updateCapabilities() { List<String> capabilities = new ArrayList<String>(); - 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); diff --git a/src/com/connectsdk/service/capability/ExternalInputControl.java b/src/com/connectsdk/service/capability/ExternalInputControl.java index 381476b6..066e61bb 100644 --- a/src/com/connectsdk/service/capability/ExternalInputControl.java +++ b/src/com/connectsdk/service/capability/ExternalInputControl.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.ExternalInputInfo; @@ -35,12 +38,13 @@ 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<String> Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Picker_Launch, Picker_Close, List, Set - }; + )); public ExternalInputControl getExternalInput(); public CapabilityPriorityLevel getExternalInputControlPriorityLevel(); 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<String> 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..ff003faf 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<String> Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Application, Application_Params, Application_Close, @@ -68,7 +72,7 @@ public interface Launcher extends CapabilityMethods { AppState_Subscribe, RunningApp, RunningApp_Subscribe - }; + )); public Launcher getLauncher(); public CapabilityPriorityLevel getLauncherCapabilityLevel(); diff --git a/src/com/connectsdk/service/capability/MediaControl.java b/src/com/connectsdk/service/capability/MediaControl.java index f99ffbc5..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<String> 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 diff --git a/src/com/connectsdk/service/capability/MediaPlayer.java b/src/com/connectsdk/service/capability/MediaPlayer.java index 8fd08c6e..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<String> 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(); diff --git a/src/com/connectsdk/service/capability/MouseControl.java b/src/com/connectsdk/service/capability/MouseControl.java index 1218af56..1c60d0f0 100644 --- a/src/com/connectsdk/service/capability/MouseControl.java +++ b/src/com/connectsdk/service/capability/MouseControl.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.PointF; @@ -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<String> Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Connect, Disconnect, Click, Move, Scroll - }; + )); public MouseControl getMouseControl(); public CapabilityPriorityLevel getMouseControlCapabilityLevel(); 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<String> 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<String> 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 f11cf5ce..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<String> Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Send, Send_Enter, Send_Delete, Subscribe - }; + )); public TextInputControl getTextInputControl(); public CapabilityPriorityLevel getTextInputControlCapabilityLevel(); 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<String> 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 7bfc63e8..f41f3717 100644 --- a/src/com/connectsdk/service/capability/VolumeControl.java +++ b/src/com/connectsdk/service/capability/VolumeControl.java @@ -21,8 +21,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.service.capability.listeners.ResponseListener; import com.connectsdk.service.command.ServiceSubscription; @@ -38,7 +39,8 @@ public interface VolumeControl extends CapabilityMethods { 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<String> Capabilities = + Collections.unmodifiableCollection(Arrays.asList( Volume_Get, Volume_Set, Volume_Up_Down, @@ -46,11 +48,8 @@ public interface VolumeControl extends CapabilityMethods { Mute_Get, Mute_Set, Mute_Subscribe - }; - - public static List<String> getCapabilities() { - return Collections.unmodifiableList(Arrays.asList(Capabilities)); - } + )); + 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<String> 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/netcast/NetcastHttpServer.java b/src/com/connectsdk/service/netcast/NetcastHttpServer.java index 8d3256b0..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; @@ -91,8 +93,7 @@ public void start() { } Socket connectionSocket = null; - BufferedReader inFromClient = null; - + try { connectionSocket = welcomeSocket.accept(); @@ -107,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; @@ -137,7 +136,7 @@ public void start() { String date = dateFormat.format(calendar.getTime()); //String androidOSVersion = android.os.Build.VERSION.RELEASE; - try(PrintWriter out = new PrintWriter(new DataOutputStream(connectionSocket.getOutputStream()))) { + 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("Cache-Control: no-store, no-cache, must-revalidate"); @@ -153,11 +152,7 @@ public void start() { 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/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("</e:propertyset>")) - 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("</e:propertyset>")) + 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/DLNANotifyParser.java b/src/com/connectsdk/service/upnp/DLNANotifyParser.java index 877ac042..ed56b7cd 100644 --- a/src/com/connectsdk/service/upnp/DLNANotifyParser.java +++ b/src/com/connectsdk/service/upnp/DLNANotifyParser.java @@ -4,6 +4,7 @@ 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; @@ -61,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/WebOSTVServiceSocketClient.java b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java index 57663cbe..003dcb8e 100644 --- a/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java +++ b/src/com/connectsdk/service/webos/WebOSTVServiceSocketClient.java @@ -366,10 +366,10 @@ private void helloTV() { String sdkVersion = DiscoveryManager.CONNECT_SDK_VERSION; // Device Model - String deviceModel = null; //Build.MODEL; + //String deviceModel = null; //Build.MODEL; // OS Version - String OSVersion = null; //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); @@ -395,8 +395,8 @@ private void helloTV() { 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); @@ -822,7 +822,7 @@ public static boolean isInteger(String s) { return true; } - class TrustManager implements X509TrustManager { + private static class TrustManager implements X509TrustManager { X509Certificate expectedCert; X509Certificate lastCheckedCert; From fa83ae04c010af4e9d08f2848d80e0a6a942be68 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Fri, 24 Feb 2017 22:10:00 +0100 Subject: [PATCH 37/41] removed all high findings --- src/com/connectsdk/service/NetcastTVService.java | 10 +++++----- src/com/connectsdk/service/WebOSTVService.java | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/com/connectsdk/service/NetcastTVService.java b/src/com/connectsdk/service/NetcastTVService.java index def13424..80468904 100644 --- a/src/com/connectsdk/service/NetcastTVService.java +++ b/src/com/connectsdk/service/NetcastTVService.java @@ -2327,10 +2327,10 @@ protected void updateCapabilities() { List<String> capabilities = new ArrayList<String>(); 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); @@ -2373,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/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index 2d80e20e..23745d4c 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -2953,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); From e8d60f56b9526aaf7686c7e21e9e204cb1bdbc69 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Sat, 25 Feb 2017 01:49:30 +0100 Subject: [PATCH 38/41] fixed bug in ssdp parsing --- src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java b/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java index 88644689..1cd3afa5 100644 --- a/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java +++ b/src/com/connectsdk/discovery/provider/ssdp/SSDPDevice.java @@ -21,10 +21,12 @@ package com.connectsdk.discovery.provider.ssdp; import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; import java.io.IOException; 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; @@ -115,7 +117,7 @@ public void parse(URL url) throws IOException, ParserConfigurationException, SAX locationXML = s.hasNext() ? s.next() : ""; SAXParser saxParser = factory.newSAXParser(); - saxParser.parse(locationXML, parser); + saxParser.parse(new ByteArrayInputStream(locationXML.getBytes(StandardCharsets.UTF_8)), parser); } headers = urlConnection.getHeaderFields(); From f368b63b3763d32224adb0d65b1dbacc7a50c4c2 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Sat, 25 Feb 2017 22:39:50 +0100 Subject: [PATCH 39/41] small simplifications --- .../discovery/DiscoveryManager.java | 8 +++--- src/com/connectsdk/service/DIALService.java | 20 +++++++------- .../connectsdk/service/NetcastTVService.java | 24 ++++++++--------- src/com/connectsdk/service/RokuService.java | 22 +++++++--------- .../connectsdk/service/WebOSTVService.java | 22 ++++++++-------- .../capability/ExternalInputControl.java | 3 +-- .../service/capability/Launcher.java | 26 +++++++------------ 7 files changed, 57 insertions(+), 68 deletions(-) diff --git a/src/com/connectsdk/discovery/DiscoveryManager.java b/src/com/connectsdk/discovery/DiscoveryManager.java index 815aa723..7dc29d1d 100644 --- a/src/com/connectsdk/discovery/DiscoveryManager.java +++ b/src/com/connectsdk/discovery/DiscoveryManager.java @@ -381,10 +381,10 @@ public void registerDefaultDeviceTypes() { "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.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", diff --git a/src/com/connectsdk/service/DIALService.java b/src/com/connectsdk/service/DIALService.java index d0a85d27..e010a8d7 100644 --- a/src/com/connectsdk/service/DIALService.java +++ b/src/com/connectsdk/service/DIALService.java @@ -115,11 +115,11 @@ public CapabilityPriorityLevel getLauncherCapabilityLevel() { } @Override - public void launchApp(String appId, AppLaunchListener listener) { + public void launchApp(String appId, ResponseListener<LaunchSession> listener) { launchApp(appId, null, listener); } - private void launchApp(String appId, JSONObject params, AppLaunchListener listener) { + private void launchApp(String appId, JSONObject params, ResponseListener<LaunchSession> 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<LaunchSession> 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<LaunchSession> listener) { ServiceCommand<ResponseListener<Object>> command = new ServiceCommand<ResponseListener<Object>>(getCommandProcessor(), requestURL(appInfo.getName()), params, new ResponseListener<Object>() { @@ -163,7 +163,7 @@ public void onSuccess(Object object) { } @Override - public void launchBrowser(String url, AppLaunchListener listener) { + public void launchBrowser(String url, ResponseListener<LaunchSession> listener) { Util.postError(listener, ServiceCommandError.notSupported()); } @@ -199,12 +199,12 @@ public void onError(ServiceCommandError error) { } @Override - public void launchYouTube(String contentId, AppLaunchListener listener) { + public void launchYouTube(String contentId, ResponseListener<LaunchSession> 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<LaunchSession> listener) { String params = null; AppInfo appInfo = new AppInfo(APP_YOUTUBE); appInfo.setName(appInfo.getId()); @@ -236,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<LaunchSession> listener) { Util.postError(listener, ServiceCommandError.notSupported()); } @Override - public void launchNetflix(final String contentId, AppLaunchListener listener) { + public void launchNetflix(final String contentId, ResponseListener<LaunchSession> listener) { JSONObject params = null; if (contentId != null && contentId.length() > 0) { @@ -261,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<LaunchSession> listener) { Util.postError(listener, ServiceCommandError.notSupported()); } diff --git a/src/com/connectsdk/service/NetcastTVService.java b/src/com/connectsdk/service/NetcastTVService.java index 80468904..6702f0af 100644 --- a/src/com/connectsdk/service/NetcastTVService.java +++ b/src/com/connectsdk/service/NetcastTVService.java @@ -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<LaunchSession> listener) { getAppInfoForId(appId, new AppInfoListener() { @Override @@ -525,7 +525,7 @@ public void onSuccess(List<AppInfo> 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<LaunchSession> 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<LaunchSession> listener) { launchAppWithInfo(appInfo, null, listener); } @Override - public void launchAppWithInfo(AppInfo appInfo, Object params, Launcher.AppLaunchListener listener) { + public void launchAppWithInfo(AppInfo appInfo, Object params, ResponseListener<LaunchSession> 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<LaunchSession> 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<LaunchSession> 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<LaunchSession> 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<LaunchSession> 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<LaunchSession> 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<LaunchSession> listener) { if (!serviceDescription.getModelNumber().equals("4.0")) { launchApp("LG Smart World", listener); // TODO: this will not work in Korea, use Korean name instead return; @@ -1392,7 +1392,7 @@ public CapabilityPriorityLevel getExternalInputControlPriorityLevel() { } @Override - public void launchInputPicker(final AppLaunchListener listener) { + public void launchInputPicker(final ResponseListener<LaunchSession> listener) { final String appName = "Input List"; final String encodedStr = HttpMessage.encode(appName); @@ -1400,7 +1400,7 @@ public void launchInputPicker(final AppLaunchListener listener) { @Override public void onSuccess(final AppInfo appInfo) { - Launcher.AppLaunchListener launchListener = new Launcher.AppLaunchListener() { + ResponseListener<LaunchSession> launchListener = new ResponseListener<LaunchSession>() { @Override public void onSuccess(LaunchSession session) { diff --git a/src/com/connectsdk/service/RokuService.java b/src/com/connectsdk/service/RokuService.java index 9e793b74..aa1e3d5d 100644 --- a/src/com/connectsdk/service/RokuService.java +++ b/src/com/connectsdk/service/RokuService.java @@ -145,7 +145,7 @@ public void close(ResponseListener<Object> responseListener) { } @Override - public void launchApp(String appId, AppLaunchListener listener) { + public void launchApp(String appId, ResponseListener<LaunchSession> 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<LaunchSession> listener) { launchAppWithInfo(appInfo, null, listener); } @Override public void launchAppWithInfo(final AppInfo appInfo, Object params, - final Launcher.AppLaunchListener listener) { + final ResponseListener<LaunchSession> listener) { if (appInfo == null || appInfo.getId() == null) { Util.postError(listener, new ServiceCommandError(-1, "Cannot launch app without valid AppInfo object", @@ -324,19 +323,17 @@ public ServiceSubscription<AppStateListener> subscribeAppState( } @Override - public void launchBrowser(String url, Launcher.AppLaunchListener listener) { + public void launchBrowser(String url, ResponseListener<LaunchSession> listener) { Util.postError(listener, ServiceCommandError.notSupported()); } @Override - public void launchYouTube(String contentId, - Launcher.AppLaunchListener listener) { + public void launchYouTube(String contentId, ResponseListener<LaunchSession> 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<LaunchSession> listener) { if (getDIALService() != null) { getDIALService().getLauncher().launchYouTube(contentId, startTime, listener); @@ -349,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<LaunchSession> listener) { getAppList(new AppListListener() { @Override @@ -381,7 +377,7 @@ public void onError(ServiceCommandError error) { @Override public void launchHulu(final String contentId, - final Launcher.AppLaunchListener listener) { + final ResponseListener<LaunchSession> listener) { getAppList(new AppListListener() { @Override @@ -408,7 +404,7 @@ public void onError(ServiceCommandError error) { } @Override - public void launchAppStore(final String appId, AppLaunchListener listener) { + public void launchAppStore(final String appId, ResponseListener<LaunchSession> listener) { AppInfo appInfo = new AppInfo("11"); appInfo.setName("Channel Store"); diff --git a/src/com/connectsdk/service/WebOSTVService.java b/src/com/connectsdk/service/WebOSTVService.java index 23745d4c..7e9563e8 100644 --- a/src/com/connectsdk/service/WebOSTVService.java +++ b/src/com/connectsdk/service/WebOSTVService.java @@ -408,7 +408,7 @@ public CapabilityPriorityLevel getLauncherCapabilityLevel() { } @Override - public void launchApp(String appId, AppLaunchListener listener) { + public void launchApp(String appId, ResponseListener<LaunchSession> listener) { AppInfo appInfo = new AppInfo(); appInfo.setId(appId); @@ -416,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<LaunchSession> 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<LaunchSession> listener) { String uri = "ssap://system.launcher/launch"; JSONObject payload = new JSONObject(); @@ -478,7 +478,7 @@ public void onError(ServiceCommandError error) { } @Override - public void launchBrowser(String url, final Launcher.AppLaunchListener listener) { + public void launchBrowser(String url, final ResponseListener<LaunchSession> listener) { String uri = "ssap://system.launcher/open"; JSONObject payload = new JSONObject(); @@ -516,12 +516,12 @@ public void onError(ServiceCommandError error) { } @Override - public void launchYouTube(String contentId, Launcher.AppLaunchListener listener) { + public void launchYouTube(String contentId, ResponseListener<LaunchSession> 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<LaunchSession> listener) { JSONObject params = new JSONObject(); if (contentId != null && contentId.length() > 0) { @@ -549,7 +549,7 @@ public void launchYouTube(final String contentId, float startTime, final AppLaun } @Override - public void launchHulu(String contentId, Launcher.AppLaunchListener listener) { + public void launchHulu(String contentId, ResponseListener<LaunchSession> listener) { JSONObject params = new JSONObject(); try { @@ -569,7 +569,7 @@ public void launchHulu(String contentId, Launcher.AppLaunchListener listener) { } @Override - public void launchNetflix(String contentId, Launcher.AppLaunchListener listener) { + public void launchNetflix(String contentId, ResponseListener<LaunchSession> listener) { JSONObject params = new JSONObject(); String netflixContentId = "m=http%3A%2F%2Fapi.netflix.com%2Fcatalog%2Ftitles%2Fmovies%2F" + contentId + "&source_type=4"; @@ -591,7 +591,7 @@ public void launchNetflix(String contentId, Launcher.AppLaunchListener listener) } @Override - public void launchAppStore(String appId, AppLaunchListener listener) { + public void launchAppStore(String appId, ResponseListener<LaunchSession> listener) { AppInfo appInfo = new AppInfo("com.webos.app.discovery"); appInfo.setName("LG Store"); @@ -1801,7 +1801,7 @@ public CapabilityPriorityLevel getExternalInputControlPriorityLevel() { } @Override - public void launchInputPicker(final AppLaunchListener listener) { + public void launchInputPicker(final ResponseListener<LaunchSession> listener) { final AppInfo appInfo = new AppInfo() { { setId("com.webos.app.inputpicker"); @@ -1809,7 +1809,7 @@ public void launchInputPicker(final AppLaunchListener listener) { } }; - launchAppWithInfo(appInfo, null, new AppLaunchListener() { + launchAppWithInfo(appInfo, null, new ResponseListener<LaunchSession>() { @Override public void onSuccess(LaunchSession object) { listener.onSuccess(object); diff --git a/src/com/connectsdk/service/capability/ExternalInputControl.java b/src/com/connectsdk/service/capability/ExternalInputControl.java index 066e61bb..ccc87c4d 100644 --- a/src/com/connectsdk/service/capability/ExternalInputControl.java +++ b/src/com/connectsdk/service/capability/ExternalInputControl.java @@ -26,7 +26,6 @@ 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; @@ -49,7 +48,7 @@ public interface ExternalInputControl extends CapabilityMethods { public ExternalInputControl getExternalInput(); public CapabilityPriorityLevel getExternalInputControlPriorityLevel(); - public void launchInputPicker(AppLaunchListener listener); + public void launchInputPicker(ResponseListener<LaunchSession> listener); public void closeInputPicker(LaunchSession launchSessionm, ResponseListener<Object> listener); public void getExternalInputList(ExternalInputListListener listener); diff --git a/src/com/connectsdk/service/capability/Launcher.java b/src/com/connectsdk/service/capability/Launcher.java index ff003faf..d76cca67 100644 --- a/src/com/connectsdk/service/capability/Launcher.java +++ b/src/com/connectsdk/service/capability/Launcher.java @@ -77,9 +77,9 @@ public interface Launcher extends CapabilityMethods { 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<LaunchSession> listener); + public void launchAppWithInfo(AppInfo appInfo, Object params, ResponseListener<LaunchSession> listener); + public void launchApp(String appId, ResponseListener<LaunchSession> listener); public void closeApp(LaunchSession launchSession, ResponseListener<Object> listener); @@ -91,20 +91,14 @@ public interface Launcher extends CapabilityMethods { public void getAppState(LaunchSession launchSession, AppStateListener listener); public ServiceSubscription<AppStateListener> 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<LaunchSession> { } + public void launchBrowser(String url, ResponseListener<LaunchSession> listener); + public void launchYouTube(String contentId, ResponseListener<LaunchSession> listener); + public void launchYouTube(String contentId, float startTime, ResponseListener<LaunchSession> listener); + public void launchNetflix(String contentId, ResponseListener<LaunchSession> listener); + public void launchHulu(String contentId, ResponseListener<LaunchSession> listener); + public void launchAppStore(String appId, ResponseListener<LaunchSession> listener); + /** * Success listener that is called upon requesting info about the current running app. * From 58823f610e1efe182aaeb3a28a32394d9f789c77 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Wed, 12 Apr 2017 21:52:14 +0200 Subject: [PATCH 40/41] 1.0 release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5d3fa31f..ead5e27e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>Connect-SDK-Java-Core</groupId> <artifactId>Connect-SDK-Java-Core</artifactId> - <version>0.0.1-SNAPSHOT</version> + <version>1.0</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> From 370fd0dc85d6f4bcf748281889d8f4e52d9bad94 Mon Sep 17 00:00:00 2001 From: Sebastian Prehn <sebastian.prehn@gmx.de> Date: Wed, 12 Apr 2017 22:17:57 +0200 Subject: [PATCH 41/41] next snapshot for 1.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ead5e27e..e60a4216 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>Connect-SDK-Java-Core</groupId> <artifactId>Connect-SDK-Java-Core</artifactId> - <version>1.0</version> + <version>1.1-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>