Add fallback for jrpc client connection when failing to connect. (#678)

diff --git a/mobly/controllers/android_device_lib/jsonrpc_client_base.py b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
index 2efef97..160ee83 100644
--- a/mobly/controllers/android_device_lib/jsonrpc_client_base.py
+++ b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
@@ -55,6 +55,7 @@
 
 import json
 import socket
+import sys
 import threading
 
 from mobly.controllers.android_device_lib import callback_handler
@@ -217,9 +218,24 @@
             socket.timeout: Raised when the socket waits to long for connection.
             ProtocolError: Raised when there is an error in the protocol.
         """
+        # socket.create_connection throws different exceptions in Python 2/3
+        # TODO: Use ConnectionRefusedError directly once PY2 is deprecated.
+        ExceptionAlias = socket.error
+        if sys.version_info >= (3, 0):
+          ExceptionAlias = ConnectionRefusedError
+
         self._counter = self._id_counter()
-        self._conn = socket.create_connection(('localhost', self.host_port),
-                                              _SOCKET_CONNECTION_TIMEOUT)
+        try:
+          self._conn = socket.create_connection(('localhost', self.host_port),
+                                                _SOCKET_CONNECTION_TIMEOUT)
+        except ExceptionAlias as err:
+          # Retry using '127.0.0.1' for IPv4 enabled machines that only resolve
+          # 'localhost' to '[::1]'.
+          self.log.debug('Failed to connect to localhost, trying 127.0.0.1: {}'
+                         .format(str(err)))
+          self._conn = socket.create_connection(('127.0.0.1', self.host_port),
+                                                _SOCKET_CONNECTION_TIMEOUT)
+
         self._conn.settimeout(_SOCKET_READ_TIMEOUT)
         self._client = self._conn.makefile(mode='brw')