From 0f4e5a4585d048a5813f1b8cde061da887ba0c74 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 4 Jul 2014 14:51:57 -0700 Subject: [PATCH] Make remote discovery faster. Fix the bitrate slider. Change some toast text. --- libs/limelight-common.jar | Bin 408690 -> 408696 bytes src/com/limelight/AdvancedSettings.java | 31 ++- src/com/limelight/AppView.java | 4 + src/com/limelight/Game.java | 116 +--------- src/com/limelight/PcView.java | 13 +- .../computers/ComputerManagerService.java | 202 +++++++++++++++--- 6 files changed, 221 insertions(+), 145 deletions(-) diff --git a/libs/limelight-common.jar b/libs/limelight-common.jar index c77477999fb84e4724f96f77dacda0f27a4c8312..1e437dcc39f1ddaea10f0024b446b918beeae0fa 100644 GIT binary patch delta 1609 zcmezLL*mB|37!CNW)=|!4h{|mt%8j_`rnzA3Z87X`~Hgw#F&29hf!nlhp(*D3yj(L zr%M^L@oaAX)e4rI+_L~KC0ai>G`3tgROIgVc+bNQiqo9DuP(e|jl zG+p=nmeXH3c8U1Co5g>o@t&y-YT=CF^P2^Y6 zw&b;DTGrEcXTF>AcZq6u?&YnivQoSEOgby9)*lpd>UHK7uDYh+V-w5z^1nMh+|!o# zg=6;u#ikV->bIMGQBr%es4e+IOK-MCpYWkcQooqYRw~NySc?7Cq|!LtRGD-)-4Pm?~Z#J0Gi|L2dp^#-fEpH6H0uJ}Fg zTGq6~YBNmuj@#CRNEG`y)o3Udv6sEO`lQu*aYX8|jT+Y?)_yCTb#-yX@&%z~OF#G) ztz1}8mU1TF+;+Fx>weL`wZDahq~2{@9WG{E6%lM$dn$0c;Dy6$7XOHOc%|yXuU%jE z=^a#^tgk8@oOt8JKAWd|+R8W9A5csT*5cWBVS17IDqi#ayIWGVe(`_F_4*bVcdbyz zJlO1YX?OqKb%)NZ-sj45ZC}rVLuPiLUZ3duY{<0F`ttfuS6mM4Qu+7a&o2LWb>Y0t z*H8ZEn(4@AGILVlw~2?}D7)Wu=iAg@t5{T0+tXerlaM4XIbZ+ZyoXx8AxGXF5uQ_D z>vO45@!z)}$2iV?4Cj_H=(+yaApgPHg3tb6-YKLBpNwB%zL2}m#8AoN){zwtB7~Eh z+=SZ_7In5fa1j=6TB#P)6zuC`D?H(YDZk<6;xow->6JUqE#{T8b2U4BN++Skw(6j` zr2q$~E7xuxwVfZgaz3qdmtXm`KV5hIkwg(Dm-+azouo|hi}eB&37^$ z-a34){r9Q1KhZl*Jd)7yo%GtX=i~lAM&|`ps|t?oo0NIxv6X1XmtBt0?3V0m7nb}w zEM)hWx4V44!esAb)1!BsEdDBH*Rg)Wea~b0?8_#aU3PEGoU$SP7KcxAZd`QZ$qeJW zoIagqm+v0PF}W!Adh&rOS)YID82E1e;F^(@`21pBY|tC$2U7Vt(@JMNu9~<0aA}Uw zYbE1<(=6-#PxnV0I)7rz-CLJ8gaz6-F^XwlZe0IohwGF-UFC zO}}Ny#xvc|giVg=4jV{VVS1kln+elu$>|SG*;J;#Fk!P{dM^Xw$WM1QWwT>)Q-E-) z6&MAlTj{e2Oh0PMCdIgF`U6w8c*dUT4rXi#jLFj%nz1D^)#^ahDx0&}Fm9NhV9u7z z)NM6A(VWe2`ZsenL#EaCAdbQGNDDRtrc_T5M``+63pNX;Yd#>3_H=PyM!x9^mTX!~ zf_@=yZ8&HZ8`<)4iw>sz`y_iqcPg_ delta 1648 zcmezIL*mm937!CNW)=|!4h{~6C5an(^uJGDYap=M`}Siy(G}nG<3WGX&$%-*IoEE`(f|DR^W55R zZ{O5DdtYDoU-&?3MW74IrK3@%+0mhy(NDXkm%cN#37>T}=jiA9S2veNZN2wp$!;Cn z%bTPFOSpO7%=&(2O|I3`H)rR@Mt)(blA8C@vvK7i!=B!}70#QPtU|j)i;r*8eQ(`( zXJgNr@;OV_<{e*SG@;^Q<^<_^*_NqWujfRm9+Q7#YJ2)zUhdQBJB7DqyIwwbowcpW z*S+edjXn3$N!rr9t1{NDxn@(pvgFsRWl!^1B;zX+H)Mw_c`tg|@bo3w*xUB*)f-nu z@~q{aQ!=~H`KUCH-FX4mxCQ0sige!BHm-Ye!>l=e)zlQ8Scz+eY|c!7Sx-+~efCvf ziTPRC+x}6h8*_I}i)v5V9=`EK;v);!)QY`lt4{hC7*(#BoP4`hV8@EZ?0dbcg6rMo zlf0_Dk8{58+O_1dil1htk9)ns($XW$dpTv9E!Hks(-&@V;Zy< z)4DmiJZZ+UsT%hLExx`Hef{R!_T(9XyTe)8{=e>v{CaD1ukfwZ>g#*DN^Ua8>1L?S z^5~Pz-Kg=5^_<)?@!8X2C*|>6H&~O{`SXWu{RCr?&y9VrcN{!(rYhEI&#%rWfxF#f zTg}p^cJ49ycyZz6-=>xCJb78uWG-(wl~u|YcrIXT{AIz`Wr=eauHB?v+}7rMYSk>S zH1}hF%8Wl{XZ>AyptH2z$>|Z_?yA(plN_s8uQ+e{DvPDZpq@9LYfc=0)ct_H`5KS4 zmah->TXvwnHRa#Ylj5a&*iBV(yc!=qe`R#1H|nzPsn^qHbscoBogMgGBJN({lHDn@ zd)uBQZ`U^XyeVI>w^VQO3a%KtZ?8|>`)tUy&-$|d=PND;cP;t%-_tIiJ-u+^+zUtR zTVHYTnW!$jb;!MMYrjmEyyYdkZ|x@(zZuHCDxA`Jcgl~NkJa_lR_g=`R0r`FzGH0V zIQRMX>&bz8POX>Ic)%3*`RtxP^FxR21FfB6JeJlsUu;@fu%uP6b+K-bmd}<60W)$G zR~lS(@_Jao{g}&GH)WocpMiG3r59BVdgm{$be!&KHFt^0;jS~uNBDCz3gp<9E%Efy zlHX^V*kK>wel_3fFUzC!`jkukiebkj@5W1b{k*U~%qu53tG}qJXi;zZ_g&xk7FoRy zw>#JrlVlkb(_d`rsUKXY;`ZRN!lcY62B$envd&KI4tO?!#jx|>hMfL?2e#hk-x%O= zT>N&#viQZl{Ey{>_f73v&vNA~->b2I%t6(9#qDgysjoJC zjdbWO&!`m)m}$0;Yo%G)JNYZBhwm}JcR3t-P4W0wo%}?;*=M$$soDSh_Xp+ouf;d* zPulqSnq2GFO9k?(9${)t`8B&!L;iG?A5{AN_K!i%BIh*^^`t%@{?8QP&Can@e0O~S z3j>2)`vykF_6>|o?Hd@G+cz+>v~OT!-M)d5Em)ChN#b@^Wws>#=@0bSSf*ziv1LG5 z*NxZ`!7NU=Dbrnz*$SA}GESdp!6rHVf-##FlOhY4Gx@_;*6CU%Y#vP4*uVlHS@!8u zOxR4AmP$fI9!N6EPBUfGVtOe97hs$2ZOUfHY*|oj%{3 zO^d133Q72zIh#4tQhOwkC<``I#`x(IEZCx%F8IJD92vQ%2U@a4Gsz@?#3ZL5w`6l> znvezIoX%pDoNi~urp2f-J=2QKjPb?v1y*e4jJKxWuwpZ1ygZ%Hn$3~1cY1&|n;qk% z>HQ$yjp-My+58wIrYqR6nW(H#Vq?%t&n(GI&&w}L4e(}VV_;xl@L=#@$d+Va_^1Tp F0sv21%?AJg diff --git a/src/com/limelight/AdvancedSettings.java b/src/com/limelight/AdvancedSettings.java index 86bbacff..40941ed7 100644 --- a/src/com/limelight/AdvancedSettings.java +++ b/src/com/limelight/AdvancedSettings.java @@ -9,6 +9,7 @@ import android.os.Bundle; import android.widget.CompoundButton; import android.widget.RadioButton; import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import android.widget.CompoundButton.OnCheckedChangeListener; @@ -17,6 +18,9 @@ public class AdvancedSettings extends Activity { private RadioButton forceSoftDec, autoDec, forceHardDec; private SeekBar bitrateSlider; private TextView bitrateLabel; + + private static final int BITRATE_FLOOR = 1; + private static final int BITRATE_CEILING = 100; @Override public void onPause() { @@ -49,7 +53,7 @@ public class AdvancedSettings extends Activity { prefs = getSharedPreferences(Game.PREFS_FILE_NAME, Context.MODE_MULTI_PROCESS); - bitrateSlider.setMax(Game.BITRATE_CEILING); + bitrateSlider.setMax(BITRATE_CEILING); bitrateSlider.setProgress(prefs.getInt(Game.BITRATE_PREF_STRING, Game.DEFAULT_BITRATE)); updateBitrateLabel(); @@ -94,6 +98,31 @@ public class AdvancedSettings extends Activity { forceSoftDec.setOnCheckedChangeListener(occl); forceHardDec.setOnCheckedChangeListener(occl); autoDec.setOnCheckedChangeListener(occl); + + this.bitrateSlider.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, + boolean fromUser) { + + // Verify the user's selection + if (fromUser) { + if (progress < BITRATE_FLOOR) { + seekBar.setProgress(BITRATE_FLOOR); + return; + } + } + + updateBitrateLabel(); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); } private void updateBitrateLabel() { diff --git a/src/com/limelight/AppView.java b/src/com/limelight/AppView.java index bf6f5ac6..ef2787f8 100644 --- a/src/com/limelight/AppView.java +++ b/src/com/limelight/AppView.java @@ -35,6 +35,7 @@ public class AppView extends Activity { private ArrayAdapter appListAdapter; private InetAddress ipAddress; private String uniqueId; + private boolean remote; private final static int RESUME_ID = 1; private final static int QUIT_ID = 2; @@ -42,6 +43,7 @@ public class AppView extends Activity { public final static String ADDRESS_EXTRA = "Address"; public final static String UNIQUEID_EXTRA = "UniqueId"; public final static String NAME_EXTRA = "Name"; + public final static String REMOTE_EXTRA = "Remote"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -50,6 +52,7 @@ public class AppView extends Activity { byte[] address = getIntent().getByteArrayExtra(ADDRESS_EXTRA); uniqueId = getIntent().getStringExtra(UNIQUEID_EXTRA); + remote = getIntent().getBooleanExtra(REMOTE_EXTRA, false); if (address == null || uniqueId == null) { return; } @@ -195,6 +198,7 @@ public class AppView extends Activity { intent.putExtra(Game.EXTRA_HOST, ipAddress.getHostAddress()); intent.putExtra(Game.EXTRA_APP, app.getAppName()); intent.putExtra(Game.EXTRA_UNIQUEID, uniqueId); + intent.putExtra(Game.EXTRA_STREAMING_REMOTE, remote); startActivity(intent); } diff --git a/src/com/limelight/Game.java b/src/com/limelight/Game.java index c359069c..5c7e7cf4 100644 --- a/src/com/limelight/Game.java +++ b/src/com/limelight/Game.java @@ -1,11 +1,5 @@ package com.limelight; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Enumeration; import com.limelight.binding.PlatformBinding; import com.limelight.binding.input.ControllerHandler; @@ -26,7 +20,6 @@ import android.content.SharedPreferences; import android.graphics.Point; import android.media.AudioManager; import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; @@ -74,6 +67,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM public static final String EXTRA_HOST = "Host"; public static final String EXTRA_APP = "App"; public static final String EXTRA_UNIQUEID = "UniqueId"; + public static final String EXTRA_STREAMING_REMOTE = "Remote"; public static final String PREFS_FILE_NAME = "gameprefs"; @@ -83,18 +77,11 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM public static final String DECODER_PREF_STRING = "Decoder"; public static final String BITRATE_PREF_STRING = "Bitrate"; - public static final int BITRATE_FLOOR_720_30 = 2; - public static final int BITRATE_FLOOR_720_60 = 4; - public static final int BITRATE_FLOOR_1080_30 = 4; - public static final int BITRATE_FLOOR_1080_60 = 10; - public static final int BITRATE_DEFAULT_720_30 = 5; public static final int BITRATE_DEFAULT_720_60 = 10; public static final int BITRATE_DEFAULT_1080_30 = 10; public static final int BITRATE_DEFAULT_1080_60 = 30; - - public static final int BITRATE_CEILING = 50; - + public static final int DEFAULT_WIDTH = 1280; public static final int DEFAULT_HEIGHT = 720; public static final int DEFAULT_REFRESH_RATE = 60; @@ -179,21 +166,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM String host = Game.this.getIntent().getStringExtra(EXTRA_HOST); String app = Game.this.getIntent().getStringExtra(EXTRA_APP); String uniqueId = Game.this.getIntent().getStringExtra(EXTRA_UNIQUEID); - InetAddress addr; - boolean enableLargePackets; - try { - // If this does a DNS lookup, it could cause a NetworkOnMainThread exception - // Chances are if it has to do this, we're not on the same network anyways - addr = InetAddress.getByName(host); - - // Check if we can enable large packets if we get this far - enableLargePackets = shouldEnableLargePackets(addr); - } catch (Exception e) { - // We don't want to deal with any exceptions here. The user will be notified - // when the connection fails - enableLargePackets = false; - } - + boolean enableLargePackets = !Game.this.getIntent().getBooleanExtra(EXTRA_STREAMING_REMOTE, true); LimeLog.info("Using large packets? "+enableLargePackets); // Start the connection @@ -208,89 +181,6 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM sh.addCallback(this); } - private boolean shouldEnableLargePackets(InetAddress targetAddress) { - ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo(); - String matchingPrefix; - - if (activeNetworkInfo == null) { - return false; - } - - switch (activeNetworkInfo.getType()) - { - case ConnectivityManager.TYPE_ETHERNET: - matchingPrefix = "eth"; - break; - case ConnectivityManager.TYPE_WIFI: - matchingPrefix = "wlan"; - break; - - default: - // Must be on Ethernet or Wifi to consider that we can send large packets - return false; - } - - // Try to find the interface that corresponds to the active network - try { - Enumeration ifaceList = NetworkInterface.getNetworkInterfaces(); - while (ifaceList.hasMoreElements()) { - NetworkInterface iface = ifaceList.nextElement(); - - // Look for an interface that matches the prefix we expect - if (iface.isUp() && iface.getName().startsWith(matchingPrefix)) { - // Find the IPv4 address for the interface - for (InterfaceAddress addr : iface.getInterfaceAddresses()) { - if (!(addr.getAddress() instanceof Inet4Address)) { - // Skip non-IPv4 addresses - continue; - } - - // Found the right address on the right interface - return isOnSameSubnet(targetAddress, addr.getAddress(), addr.getNetworkPrefixLength()); - } - } - } - } catch (SocketException e) { - e.printStackTrace(); - } - - // We didn't find the interface or something else went wrong - return false; - } - - private boolean isOnSameSubnet(InetAddress targetAddress, InetAddress localAddress, short networkPrefixLength) { - byte[] targetBytes = targetAddress.getAddress(); - byte[] localBytes = localAddress.getAddress(); - - for (int byteIndex = 0; networkPrefixLength > 0; byteIndex++) { - byte target = targetBytes[byteIndex]; - byte local = localBytes[byteIndex]; - - if (networkPrefixLength >= 8) { - // Do a full byte comparison - if (target != local) { - return false; - } - - networkPrefixLength -= 8; - } - else { - target &= (byte)(0xFF << (8 - networkPrefixLength)); - local &= (byte)(0xFF << (8 - networkPrefixLength)); - - // Do a masked comparison - if (target != local) { - return false; - } - - networkPrefixLength = 0; - } - } - - return true; - } - private void checkDataConnection() { ConnectivityManager mgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); diff --git a/src/com/limelight/PcView.java b/src/com/limelight/PcView.java index be8096e0..d3ac3da1 100644 --- a/src/com/limelight/PcView.java +++ b/src/com/limelight/PcView.java @@ -223,6 +223,11 @@ public class PcView extends Activity { Toast.makeText(PcView.this, "Computer is offline", Toast.LENGTH_SHORT).show(); return; } + if (computer.runningGameId != 0) { + Toast.makeText(PcView.this, "Computer is currently in a game. " + + "You must close the game before pairing.", Toast.LENGTH_LONG).show(); + return; + } Toast.makeText(PcView.this, "Pairing...", Toast.LENGTH_SHORT).show(); new Thread(new Runnable() { @@ -305,7 +310,7 @@ public class PcView extends Activity { message = "It may take a few seconds for your PC to wake up. " + "If it doesn't, make sure it's configured properly for Wake-On-LAN."; } catch (IOException e) { - message = "Failed to send wake-on-lan packets"; + message = "Failed to send Wake-On-LAN packets"; } final String toastMessage = message; @@ -388,9 +393,11 @@ public class PcView extends Activity { if (computer.reachability == ComputerDetails.Reachability.LOCAL) { i.putExtra(AppView.ADDRESS_EXTRA, computer.localIp.getAddress()); + i.putExtra(AppView.REMOTE_EXTRA, false); } else { i.putExtra(AppView.ADDRESS_EXTRA, computer.remoteIp.getAddress()); + i.putExtra(AppView.REMOTE_EXTRA, true); } startActivity(i); } @@ -459,8 +466,8 @@ public class PcView extends Activity { } private void addListPlaceholder() { - pcListAdapter.add(new ComputerObject("No computers found yet. Make sure your computer is running GFE " + - "or add your PC manually on the settings page.", null)); + pcListAdapter.add(new ComputerObject("Discovery is running. No computers found yet. " + + "Make sure your computer is running GFE or add your PC manually on the settings page.", null)); } private void removeListView(ComputerDetails details) { diff --git a/src/com/limelight/computers/ComputerManagerService.java b/src/com/limelight/computers/ComputerManagerService.java index 9d49a646..b9c6702b 100644 --- a/src/com/limelight/computers/ComputerManagerService.java +++ b/src/com/limelight/computers/ComputerManagerService.java @@ -1,6 +1,11 @@ package com.limelight.computers; +import java.net.Inet4Address; import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; import java.util.List; import java.util.Timer; import java.util.TimerTask; @@ -18,8 +23,11 @@ import com.limelight.nvstream.mdns.MdnsDiscoveryListener; import android.app.Service; import android.content.ComponentName; +import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.os.Binder; import android.os.IBinder; @@ -180,41 +188,179 @@ public class ComputerManagerService extends Service { }; } + private int getActiveNetworkType() { + ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo(); + if (activeNetworkInfo == null) { + return -1; + } + + return activeNetworkInfo.getType(); + } + + private InterfaceAddress getActiveInterfaceAddress() { + String matchingPrefix; + + switch (getActiveNetworkType()) + { + case ConnectivityManager.TYPE_ETHERNET: + matchingPrefix = "eth"; + break; + case ConnectivityManager.TYPE_WIFI: + matchingPrefix = "wlan"; + break; + + default: + // Must be on Ethernet or Wifi to consider that we can send large packets + return null; + } + + // Try to find the interface that corresponds to the active network + try { + Enumeration ifaceList = NetworkInterface.getNetworkInterfaces(); + while (ifaceList.hasMoreElements()) { + NetworkInterface iface = ifaceList.nextElement(); + + // Look for an interface that matches the prefix we expect + if (iface.isUp() && iface.getName().startsWith(matchingPrefix)) { + // Find the IPv4 address for the interface + for (InterfaceAddress addr : iface.getInterfaceAddresses()) { + if (!(addr.getAddress() instanceof Inet4Address)) { + // Skip non-IPv4 addresses + continue; + } + + // Found the right address on the right interface + return addr; + } + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + + // We didn't find the interface or something else went wrong + return null; + } + + private boolean isOnSameSubnet(InetAddress targetAddress, InetAddress localAddress, short networkPrefixLength) { + byte[] targetBytes = targetAddress.getAddress(); + byte[] localBytes = localAddress.getAddress(); + + for (int byteIndex = 0; networkPrefixLength > 0; byteIndex++) { + byte target = targetBytes[byteIndex]; + byte local = localBytes[byteIndex]; + + if (networkPrefixLength >= 8) { + // Do a full byte comparison + if (target != local) { + return false; + } + + networkPrefixLength -= 8; + } + else { + target &= (byte)(0xFF << (8 - networkPrefixLength)); + local &= (byte)(0xFF << (8 - networkPrefixLength)); + + // Do a masked comparison + if (target != local) { + return false; + } + + networkPrefixLength = 0; + } + } + + return true; + } + + private ComputerDetails tryPollIp(InetAddress ipAddr) { + try { + NvHTTP http = new NvHTTP(ipAddr, idManager.getUniqueId(), + null, PlatformBinding.getCryptoProvider(ComputerManagerService.this)); + + return http.getComputerDetails(); + } catch (Exception e) { + return null; + } + } + + private boolean pollComputer(ComputerDetails details, boolean localFirst) { + ComputerDetails polledDetails; + + if (localFirst) { + polledDetails = tryPollIp(details.localIp); + } + else { + polledDetails = tryPollIp(details.remoteIp); + } + + if (polledDetails == null) { + // Failed, so let's try the fallback + if (!localFirst) { + polledDetails = tryPollIp(details.localIp); + } + else { + polledDetails = tryPollIp(details.remoteIp); + } + + // The fallback poll worked + if (polledDetails != null) { + polledDetails.reachability = !localFirst ? ComputerDetails.Reachability.LOCAL : + ComputerDetails.Reachability.REMOTE; + } + } else { + polledDetails.reachability = localFirst ? ComputerDetails.Reachability.LOCAL : + ComputerDetails.Reachability.REMOTE; + } + + // Machine was unreachable both tries + if (polledDetails == null) { + return false; + } + + // If we got here, it's reachable + details.update(polledDetails); + return true; + } + + private boolean doPollMachine(ComputerDetails details) { + // Get the network type + int networkType = getActiveNetworkType(); + switch (networkType) { + // We'll check local first on these if we find + // we're on the same subnet + case ConnectivityManager.TYPE_ETHERNET: + case ConnectivityManager.TYPE_WIFI: + InterfaceAddress ifaceAddr = getActiveInterfaceAddress(); + if (ifaceAddr != null) { + if (isOnSameSubnet(details.localIp, ifaceAddr.getAddress(), ifaceAddr.getNetworkPrefixLength())) { + // It's on the same subnet, so poll local first + LimeLog.info("Machine looks local; trying local IP first"); + return pollComputer(details, true); + } + } + // Fall through to remote first + default: + LimeLog.info("Machine looks remote; trying remote IP first"); + return pollComputer(details, false); + } + } + private Runnable getPollingRunnable(final ComputerDetails details) { return new Runnable() { @Override public void run() { - boolean newPc = details.name == null; + boolean newPc = (details.name == null); - try { - // Try the local IP first - NvHTTP http = new NvHTTP(details.localIp, idManager.getUniqueId(), - null, PlatformBinding.getCryptoProvider(ComputerManagerService.this)); - - ComputerDetails localDetails = http.getComputerDetails(); - - // If we got here, it's reachable - details.reachability = ComputerDetails.Reachability.LOCAL; - details.update(localDetails); - } catch (Exception e) { - // This isn't horrible yet; we'll try remote - try { - NvHTTP http = new NvHTTP(details.remoteIp, idManager.getUniqueId(), - null, PlatformBinding.getCryptoProvider(ComputerManagerService.this)); - - ComputerDetails remoteDetails = http.getComputerDetails(); - - // If we got here, it's reachable - details.reachability = ComputerDetails.Reachability.REMOTE; - details.update(remoteDetails); - } catch (Exception e1) { - // No good, it's offline - details.state = ComputerDetails.State.OFFLINE; - details.reachability = ComputerDetails.Reachability.OFFLINE; - } + // Poll the machine + if (!doPollMachine(details)) { + details.state = ComputerDetails.State.OFFLINE; + details.reachability = ComputerDetails.Reachability.OFFLINE; } - + // If it's online, update our persistent state if (details.state == ComputerDetails.State.ONLINE) { if (!newPc) {