From 4ae29b00753550a266ca315f8daabc0349fbb42e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 11:52:08 -0800 Subject: [PATCH 01/14] Improve performance of the CPU decoder and add some details about changing decoders --- .../video/AndroidCpuDecoderRenderer.java | 53 +++++++++++++------ app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/preferences.xml | 1 + 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java b/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java index 26b11076..acbda3c8 100644 --- a/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java +++ b/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java @@ -21,14 +21,14 @@ import com.limelight.nvstream.av.video.cpu.AvcDecoder; @SuppressWarnings("EmptyCatchBlock") public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { - private Thread rendererThread; + private Thread rendererThread, decoderThread; private int targetFps; private static final int DECODER_BUFFER_SIZE = 92*1024; private ByteBuffer decoderBuffer; // Only sleep if the difference is above this value - private static final int WAIT_CEILING_MS = 8; + private static final int WAIT_CEILING_MS = 5; private static final int LOW_PERF = 1; private static final int MED_PERF = 2; @@ -108,9 +108,7 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { case LOW_PERF: // Disable the loop filter for performance reasons - avcFlags = AvcDecoder.DISABLE_LOOP_FILTER | - AvcDecoder.FAST_BILINEAR_FILTERING | - AvcDecoder.FAST_DECODE; + avcFlags = AvcDecoder.FAST_BILINEAR_FILTERING; // Use plenty of threads to try to utilize the CPU as best we can threadCount = cpuCount - 1; @@ -118,8 +116,7 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { default: case MED_PERF: - avcFlags = AvcDecoder.BILINEAR_FILTERING | - AvcDecoder.FAST_DECODE; + avcFlags = AvcDecoder.BILINEAR_FILTERING; // Only use 2 threads to minimize frame processing latency threadCount = 2; @@ -156,6 +153,26 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { @Override public boolean start(final VideoDepacketizer depacketizer) { + decoderThread = new Thread() { + @Override + public void run() { + DecodeUnit du; + while (!isInterrupted()) { + try { + du = depacketizer.takeNextDecodeUnit(); + } catch (InterruptedException e) { + break; + } + + submitDecodeUnit(du); + depacketizer.freeDecodeUnit(du); + } + } + }; + decoderThread.setName("Video - Decoder (CPU)"); + decoderThread.setPriority(Thread.MAX_PRIORITY - 1); + decoderThread.start(); + rendererThread = new Thread() { @Override public void run() { @@ -163,17 +180,15 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { DecodeUnit du; while (!isInterrupted()) { - du = depacketizer.pollNextDecodeUnit(); - if (du != null) { - submitDecodeUnit(du); - depacketizer.freeDecodeUnit(du); - } - long diff = nextFrameTime - System.currentTimeMillis(); if (diff > WAIT_CEILING_MS) { - LockSupport.parkNanos(1); - continue; + try { + Thread.sleep(diff - WAIT_CEILING_MS); + } catch (InterruptedException e) { + return; + } + continue; } nextFrameTime = computePresentationTimeMs(targetFps); @@ -194,10 +209,14 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer { @Override public void stop() { rendererThread.interrupt(); + decoderThread.interrupt(); try { - rendererThread.join(); - } catch (InterruptedException e) { } + rendererThread.join(); + } catch (InterruptedException e) { } + try { + decoderThread.join(); + } catch (InterruptedException e) { } } @Override diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 503be448..8ba430e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -106,4 +106,5 @@ Advanced Settings Change decoder + Software decoding may improve video latency at lower streaming settings diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 5a158cdd..c7780c06 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -52,6 +52,7 @@ android:title="@string/title_decoder_list" android:entries="@array/decoder_names" android:entryValues="@array/decoder_values" + android:summary="@string/summary_decoder_list" android:defaultValue="auto" /> From d5b61309368546c825999c906deadf9e263ced4c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 12:09:32 -0800 Subject: [PATCH 02/14] Use 40% larger packets (1450 bytes) on local networks --- app/libs/limelight-common.jar | Bin 725184 -> 725347 bytes app/src/main/java/com/limelight/Game.java | 2 ++ 2 files changed, 2 insertions(+) diff --git a/app/libs/limelight-common.jar b/app/libs/limelight-common.jar index 34955aaa531d4da096832a62a97a824d07b7232f..a4d81de01e78372c5b44fa7f4ee1a4826557e6bf 100644 GIT binary patch delta 10455 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 H{KWb{4^ZtE delta 10166 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 Date: Sun, 16 Nov 2014 14:23:58 -0800 Subject: [PATCH 03/14] Fix comment typo --- app/src/main/res/values-v21/styles.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml index 64631b04..aca590d2 100644 --- a/app/src/main/res/values-v21/styles.xml +++ b/app/src/main/res/values-v21/styles.xml @@ -3,7 +3,7 @@ + + + From afbe64f3ff1dd1ac71c4670fe847953cc261ad2b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 17:19:07 -0800 Subject: [PATCH 09/14] Remove an unused import --- .../com/limelight/binding/video/AndroidCpuDecoderRenderer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java b/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java index acbda3c8..ed5c501f 100644 --- a/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java +++ b/app/src/main/java/com/limelight/binding/video/AndroidCpuDecoderRenderer.java @@ -5,7 +5,6 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.concurrent.locks.LockSupport; import android.graphics.PixelFormat; import android.os.Build; From 99e3b5f33b5aa84e8b417f7341192b5202dbf62e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 17:20:04 -0800 Subject: [PATCH 10/14] Rewrite a large portion of the computer manager service to fix some thread leaks and improve performance --- .../computers/ComputerManagerService.java | 109 +++++++++++------- 1 file changed, 70 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/limelight/computers/ComputerManagerService.java b/app/src/main/java/com/limelight/computers/ComputerManagerService.java index 227a9f67..20662c00 100644 --- a/app/src/main/java/com/limelight/computers/ComputerManagerService.java +++ b/app/src/main/java/com/limelight/computers/ComputerManagerService.java @@ -1,8 +1,7 @@ package com.limelight.computers; import java.net.InetAddress; -import java.util.HashMap; -import java.util.List; +import java.util.LinkedList; import java.util.concurrent.atomic.AtomicInteger; import com.limelight.LimeLog; @@ -30,7 +29,7 @@ public class ComputerManagerService extends Service { private AtomicInteger dbRefCount = new AtomicInteger(0); private IdentityManager idManager; - private final HashMap pollingThreads = new HashMap(); + private final LinkedList pollingTuples = new LinkedList(); private ComputerManagerListener listener = null; private AtomicInteger activePolls = new AtomicInteger(0); @@ -102,20 +101,8 @@ public class ComputerManagerService extends Service { @Override public void run() { while (!isInterrupted()) { - ComputerDetails originalDetails = new ComputerDetails(); - originalDetails.update(details); - // Check if this poll has modified the details - if (runPoll(details) && !originalDetails.equals(details)) { - // Replace our thread entry with the new one - synchronized (pollingThreads) { - if (pollingThreads.remove(originalDetails) != null) { - // This could have gone away in the meantime, so don't - // add it back if it has - pollingThreads.put(details, this); - } - } - } + runPoll(details); // Wait until the next polling interval try { @@ -137,24 +124,16 @@ public class ComputerManagerService extends Service { // Start mDNS autodiscovery too discoveryBinder.startDiscovery(MDNS_QUERY_PERIOD_MS); - - // Start polling known machines - if (!getLocalDatabaseReference()) { - return; - } - List computerList = dbManager.getAllComputers(); - releaseLocalDatabaseReference(); - synchronized (pollingThreads) { - for (ComputerDetails computer : computerList) { + synchronized (pollingTuples) { + for (PollingTuple tuple : pollingTuples) { // This polling thread might already be there - if (!pollingThreads.containsKey(computer)) { + if (tuple.thread == null) { // Report this computer initially - listener.notifyComputerUpdated(computer); + listener.notifyComputerUpdated(tuple.computer); - Thread t = createPollingThread(computer); - pollingThreads.put(computer, t); - t.start(); + tuple.thread = createPollingThread(tuple.computer); + tuple.thread.start(); } } } @@ -208,11 +187,14 @@ public class ComputerManagerService extends Service { discoveryBinder.stopDiscovery(); // Stop polling - synchronized (pollingThreads) { - for (Thread t : pollingThreads.values()) { - t.interrupt(); + synchronized (pollingTuples) { + for (PollingTuple tuple : pollingTuples) { + if (tuple.thread != null) { + // Interrupt and remove the thread + tuple.thread.interrupt(); + tuple.thread = null; + } } - pollingThreads.clear(); } // Remove the listener @@ -249,13 +231,26 @@ public class ComputerManagerService extends Service { fakeDetails.remoteIp = addr; // Spawn a thread for this computer - synchronized (pollingThreads) { + synchronized (pollingTuples) { // This polling thread might already be there - if (!pollingThreads.containsKey(fakeDetails)) { - Thread t = createPollingThread(fakeDetails); - pollingThreads.put(fakeDetails, t); - t.start(); + for (PollingTuple tuple : pollingTuples) { + if (tuple.computer.localIp.equals(addr) || + tuple.computer.remoteIp.equals(addr)) { + // This is the same computer + if (tuple.thread == null) { + tuple.thread = createPollingThread(fakeDetails); + tuple.thread.start(); + } + + // Found an entry so we're done + return; + } } + + // If we got here, we didn't find an entry + PollingTuple tuple = new PollingTuple(fakeDetails, createPollingThread(fakeDetails)); + pollingTuples.add(tuple); + tuple.thread.start(); } } @@ -279,6 +274,20 @@ public class ComputerManagerService extends Service { // Remove it from the database dbManager.deleteComputer(name); + + synchronized (pollingTuples) { + // Remove the computer from the computer list + for (PollingTuple tuple : pollingTuples) { + if (tuple.computer.name.equals(name)) { + if (tuple.thread != null) { + // Interrupt the thread on this entry + tuple.thread.interrupt(); + } + pollingTuples.remove(tuple); + break; + } + } + } releaseLocalDatabaseReference(); } @@ -376,6 +385,18 @@ public class ComputerManagerService extends Service { // Initialize the DB dbManager = new ComputerDatabaseManager(this); dbRefCount.set(1); + + // Grab known machines into our computer list + if (!getLocalDatabaseReference()) { + return; + } + + for (ComputerDetails computer : dbManager.getAllComputers()) { + // Add this computer without a thread + pollingTuples.add(new PollingTuple(computer, null)); + } + + releaseLocalDatabaseReference(); } @Override @@ -396,3 +417,13 @@ public class ComputerManagerService extends Service { return binder; } } + +class PollingTuple { + public Thread thread; + public ComputerDetails computer; + + public PollingTuple(ComputerDetails computer, Thread thread) { + this.computer = computer; + this.thread = thread; + } +} \ No newline at end of file From 79e8bef289627339657e42934b9ab0d9f0b2afac Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 17:20:11 -0800 Subject: [PATCH 11/14] Update common --- app/libs/limelight-common.jar | Bin 725347 -> 725230 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/app/libs/limelight-common.jar b/app/libs/limelight-common.jar index a4d81de01e78372c5b44fa7f4ee1a4826557e6bf..bb57e5a1fa9ae06f5f9c9fd3bc9212236442cb08 100644 GIT binary patch delta 1719 zcmYk6do+}39LMMNHe=>}XP7ajLP+7bWL+|*(r89axs{4z#kwq6q zo|H&R7jlVqL^efgWHOzoP)WLI%_dT9<+5*bvVVNfd48Yo?{~hx^E~G~eWw<@EnGle z>kZG)#}SD{oMU_<`7#+2Xu)>zJLQX(TFDzUcraTV)dc|rl&<(w3o6ypvWu4wiLHNF zib6aj|30x@{$qk6JrN-Fqx1FI_M;xDwh=3w(<}t)!$dBpiDO6PDcnzvmX6h%2MKCB zH@O&vcMYls)%)OXLt$6$KHReG`!OQEM`(-wM5pA_Uy`xA9 zXPI=(`~2BUnNfuIq=0+(69;N&yz(1Q7Ak@pwIf~^vru2uwp*rSb=tYQupVYPQg7}@ z{01d6l8ot1L58PNt%Y`h2LsOmk&meHQRP@w=9XxwL7By1XhlbN)uYtjsyuexqGN7; z*VO@e?J3NRxp#CPmRL+si_UELMcmV&POK648Q$g62lG?j_v;V-l~UFqIcY|Fv3grg zLi+Q)r+f8k&oj#PQr8r^vW4r@*0ov(FE-iduh3+@X?9HCL`F})EC_J3$mCHD4JGFt z*xDhql4kafcs`aFAdYA8&;1g`drF;-KJ&BLC@41Rb1bzIx)ccA7>(iP{wKHG3^{Ax zXFhKE;h%!vyh4tAiju`_8y`(h3~wJDejIO;ha>G(rgI49jJHct${9bE;eXG}QhJbT zG%tcWl_I1*a%{wIFhZPqXtBG#%zb!SjHjr6y;PL`>Xb#8#;y1`?fiW9lU+Wdr!HHW z@}D~%jK@Y@{(QCQUvB90y>FAPT9Dj{5T&HQV&<5C2x=d@&P+QuKWpf{-AheSTBjoW zQgofW_s|y?+N*UpsxOX++urS#MK75*lHi@ouQ~SF_@QBc(VOTE?^r4GYgFM$JWf{I zz^FiK-xEDol{zy!jA$?cgG@^3tU!ap179mT;m3>J2S!-!tE%_izG?2k=EkL(|9a5m zgEed%Hf|X9cdo{Jgyh@B)nmAJHJp1?Noa0bRlHjQE~5Jg3OAjI0Lzw`+xsV)rG|Rl*O;YrmNNa>40jN$v95@`)RoD!#Zn zdv&YnGdcN+DaUugy`H<42sfg_y4o;#W#m)YgCw=U@4-syu?QpzU#Kirzvf0MUpDddA5S;uNA$mmJ`rgZ*5|0<7QKn891DZ zD1T-(M?SdPX!3IrX`{ybV<-?NEle<`8JO^x2$-}n5iyYzF%%^Im6l`tpCbrK@7vb} z$OJTU@*pOlVLBM$O=p090vZjUB}4LEZN>l#Sp^w`Yuczke3%M>Av$CNI5cP$IDnv3 z5JW@`;Sl;HXM&4F)CS(onCc25VGTqQ>IC=BnMNGg#b&ZH1J_8XD=f5|@{ACa1IIc~ zRq+Vs8L_4+ED#UWEQkvJL9hs`CI9Da6kQ7c&YnV8DgxMU5FIE`thJmA0j@h_4{m=% zs9-)BTUWJW5}APn9yAjuVQkC&-}ox;X|4;}$*3c|aNRW00W1pY06*kUBNE7_po?I7 zASADJo(<{)A%h$pEOdC|caXOUyQko9B!2sMVi^S)fLe?|yTD5w)EANgrY_2Y55+;i zOaw7NvM%O%f^uDSCA1rS)I~XvC16oeH^>&mQBf{7S3|`ztKK1iH-yXs3>r4zj6Dfz MOxXJ#!QpWK0azB%-2eap delta 1803 zcmY+Edpy)xAIJUXX3Uv!i6laDo0$wU80$LH@VKse<(5lCAv}#sHtpJZMr|&W>%>V` zJ9%i+WQ$^!G>LsRqP9@9o7@VytlQ|7TY9GK%kw;cykD>Ld7pD$pYQqS%v>>fQ(;2% z^+aRTqAyX&Nw|9OPTw{g6qhecfBK1o zHRookoW&G1CQ%Yf4cjaLi;*zvA1Zm~IZ-j?-_4PZ9;h1A{5@lM@~U61fHm|uPb~bI z_S&@a#EDsruL1=1las&bu?@dPMW31Ke%JIbkK&O1gVwa3bh3H+F5@`whQ$|0rVLTp zN0pp^xtkZe?QLkyv9avI`@+Vn#RL71P3DY_6el+oSL0JwVZ-oM`r6|$Y2N;t1FXdJ z2mY|CWTL zUy*vOUzedG5>D}k#yivWbIea4{Lw|kjPAXYTYMA(>Y^Bn z)_3kX9;XuOJqA44UUr3}bN+T1)9W#;vbUzySxio0zZUgRmE!)RTeW=+88=4Md^}C7 zD|*IV{eJuI-klt}&F;p;tv3a{^p4ettf!}Zdkm9(I(5n=Q*9qAe$A=I4{Wjd7=PO@ zc;?4(5Hpl`f5v~0{FUO_*O)GD2aK&8=*mEW* ztnnxZ#o6wy<>&}iOcZ`}qFxr3`VX)x0{7)-e7M-eu<1#pJh~qEkiZiJP|rO{+x{YN z)j@|kmloO-SZwNObENUGc>EAGFgme)>w>`7VP?q6M)yLW^?8Zz=BY zTj}cWY@Szjs@&m|@9L|1@w?IhN`@JB%csF2vtcgHG|9Vdt)~6t=nP*qN$SvX?*myh z!1;H7T7D|-LhwvipgD)%2Q7+oG}Rf^jCZdCL{)%BU==HzaH?#&g&n~{0BYz?blg-DlkQmhq%j6XU|0&)A#DYy&pJM+iMJ?;9ZEmVW3cTST-SXp8iskeOZ$SwF$GbF7q6IU9`9}% z=iM>tl8DJ&1}o3EaP zmpO>9r##;EC40#!N8499x zB7rxCstOnJqy&X6aA=KyffunLW@ClHfru|F!v7Q{oRZ3abJI@*o^}4iP+vK+kMNU?B}5!#O;_K|UT>p#8P~tE|yN>X)Pg-4uW$dV=;P zS;A%oKt)el{=Ik05>bI`O9W*|CIC%T0poLr0Ssm!${RZCvo5#Y(Cq|Zk6v>4yTuFu z2eiRngkNi^0ZAmF01E)HLGNX4nk_KT6T!h%0QR7pJ^x>m;LA_4+EgOYM6SU?qU=dt zftyD>&{;tn;TZ{Fp?46X26-gefFmM+h%#`N-EdKs4NRUVz-M!WT~MG5s7N*JR0i6(1t~#J GPVPSfOc6x@ From a267cf59c7e8a0dc603a411bf65ec0fa26958ee0 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 17:20:27 -0800 Subject: [PATCH 12/14] Increment version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c1d02b1b..72c5e489 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { minSdkVersion 16 targetSdkVersion 21 - versionName "3.0-beta1.01" - versionCode = 41 + versionName "3.0-beta2" + versionCode = 43 } productFlavors { From 94ba7f8e45b631d7b9cacd0dde36e1938fefe294 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 18:09:31 -0800 Subject: [PATCH 13/14] Fix a bunch of bugs in the new (and old) computer manager service --- .../computers/ComputerManagerService.java | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/limelight/computers/ComputerManagerService.java b/app/src/main/java/com/limelight/computers/ComputerManagerService.java index 20662c00..dac2fe78 100644 --- a/app/src/main/java/com/limelight/computers/ComputerManagerService.java +++ b/app/src/main/java/com/limelight/computers/ComputerManagerService.java @@ -32,6 +32,7 @@ public class ComputerManagerService extends Service { private final LinkedList pollingTuples = new LinkedList(); private ComputerManagerListener listener = null; private AtomicInteger activePolls = new AtomicInteger(0); + private boolean pollingActive = false; private DiscoveryService.DiscoveryBinder discoveryBinder; private final ServiceConnection discoveryServiceConnection = new ServiceConnection() { @@ -100,7 +101,7 @@ public class ComputerManagerService extends Service { Thread t = new Thread() { @Override public void run() { - while (!isInterrupted()) { + while (!isInterrupted() && pollingActive) { // Check if this poll has modified the details runPoll(details); @@ -119,6 +120,9 @@ public class ComputerManagerService extends Service { public class ComputerManagerBinder extends Binder { public void startPolling(ComputerManagerListener listener) { + // Polling is active + pollingActive = true; + // Set the listener ComputerManagerService.this.listener = listener; @@ -187,6 +191,7 @@ public class ComputerManagerService extends Service { discoveryBinder.stopDiscovery(); // Stop polling + pollingActive = false; synchronized (pollingTuples) { for (PollingTuple tuple : pollingTuples) { if (tuple.thread != null) { @@ -230,15 +235,21 @@ public class ComputerManagerService extends Service { fakeDetails.localIp = addr; fakeDetails.remoteIp = addr; - // Spawn a thread for this computer + addTuple(fakeDetails); + } + + private void addTuple(ComputerDetails details) { synchronized (pollingTuples) { - // This polling thread might already be there for (PollingTuple tuple : pollingTuples) { - if (tuple.computer.localIp.equals(addr) || - tuple.computer.remoteIp.equals(addr)) { - // This is the same computer - if (tuple.thread == null) { - tuple.thread = createPollingThread(fakeDetails); + // Check if this is the same computer + if (tuple.computer == details || + tuple.computer.localIp.equals(details.localIp) || + tuple.computer.remoteIp.equals(details.remoteIp) || + tuple.computer.name.equals(details.name)) { + + // Start a polling thread if polling is active + if (pollingActive && tuple.thread == null) { + tuple.thread = createPollingThread(details); tuple.thread.start(); } @@ -248,11 +259,13 @@ public class ComputerManagerService extends Service { } // If we got here, we didn't find an entry - PollingTuple tuple = new PollingTuple(fakeDetails, createPollingThread(fakeDetails)); + PollingTuple tuple = new PollingTuple(details, pollingActive ? createPollingThread(details) : null); pollingTuples.add(tuple); - tuple.thread.start(); + if (tuple.thread != null) { + tuple.thread.start(); + } } - } + } public boolean addComputerBlocking(InetAddress addr) { // Setup a placeholder @@ -264,7 +277,14 @@ public class ComputerManagerService extends Service { runPoll(fakeDetails); // If the machine is reachable, it was successful - return fakeDetails.state == ComputerDetails.State.ONLINE; + if (fakeDetails.state == ComputerDetails.State.ONLINE) { + // Start a polling thread for this machine + addTuple(fakeDetails); + return true; + } + else { + return false; + } } public void removeComputer(String name) { From b2ba216cd1fee0fe101606ca4117d0bdde31a2d3 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Nov 2014 18:14:50 -0800 Subject: [PATCH 14/14] Poll every 3 seconds instead of every 5 seconds --- .../java/com/limelight/computers/ComputerManagerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/limelight/computers/ComputerManagerService.java b/app/src/main/java/com/limelight/computers/ComputerManagerService.java index dac2fe78..4b73d1f8 100644 --- a/app/src/main/java/com/limelight/computers/ComputerManagerService.java +++ b/app/src/main/java/com/limelight/computers/ComputerManagerService.java @@ -20,7 +20,7 @@ import android.os.Binder; import android.os.IBinder; public class ComputerManagerService extends Service { - private static final int POLLING_PERIOD_MS = 5000; + private static final int POLLING_PERIOD_MS = 3000; private static final int MDNS_QUERY_PERIOD_MS = 1000; private ComputerManagerBinder binder = new ComputerManagerBinder();