summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSho Amano <samano@xevo.com>2018-10-11 22:15:06 +0900
committerSho Amano <samano@xevo.com>2018-10-12 21:20:35 +0900
commitf362309c3c9532a46a972c64640dd366f2b6c6a3 (patch)
tree468ce672e420ea360319ba5dba4597efc6908437
parent44c3f2ab669e047101f212d5258983043299716f (diff)
downloadsdl_android-f362309c3c9532a46a972c64640dd366f2b6c6a3.tar.gz
Reflect review comments
- Check ACCESS_NETWORK_STATE permission to avoid crash - Create a normal Socket when Wi-Fi network isn't available or the permission isn't available - Add null checkings
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java64
1 files changed, 49 insertions, 15 deletions
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java b/sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java
index 31449cf57..b35070d89 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/transport/utl/WiFiSocketFactory.java
@@ -1,7 +1,9 @@
package com.smartdevicelink.transport.utl;
+import android.Manifest;
import android.annotation.TargetApi;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
@@ -10,53 +12,85 @@ import android.os.Build;
import java.io.IOException;
import java.net.Socket;
+import javax.net.SocketFactory;
+
import static com.smartdevicelink.util.NativeLogTool.logInfo;
public class WiFiSocketFactory {
/**
- * Creates a TCP socket which is bound to Wi-Fi network (for Android 5+)
+ * Try to create a TCP socket which is bound to Wi-Fi network (for Android 5+)
*
- * On Android 5 and later, this method returns a Socket which is always bound to a Wi-Fi
- * network. If the phone is not connected to a Wi-Fi network, this method throws an IOException.
- * Prior to Android 5, this method simply creates a Socket equivalent to "new Socket();".
+ * On Android 5 and later, this method tries to create a Socket instance which is bound to a
+ * Wi-Fi network. If the phone is not connected to a Wi-Fi network, or the app lacks
+ * required permission (ACCESS_NETWORK_STATE), then this method simply creates a Socket instance
+ * with "new Socket();".
*
- * @return a Socket instance bound to Wi-Fi network.
+ * @return a Socket instance, preferably bound to a Wi-Fi network
*/
- public static Socket createSocket(Context context) throws IOException {
+ public static Socket createSocket(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Socket socket = createWiFiSocket(context);
- if (socket == null) {
- logInfo("Cannot find Wi-Fi network, aborting socket creation.");
- throw new IOException("The phone is not connected to Wi-Fi network");
+ if (socket != null) {
+ logInfo("Created a Socket bound to Wi-Fi network");
+ return socket;
}
- return socket;
- } else {
- return new Socket();
}
+
+ return new Socket();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static Socket createWiFiSocket(Context context) {
+ PackageManager pm = context.getPackageManager();
+ if (pm == null) {
+ logInfo("PackageManager isn't available.");
+ return null;
+ }
+ // getAllNetworks() and getNetworkCapabilities() require ACCESS_NETWORK_STATE
+ if (pm.checkPermission(Manifest.permission.ACCESS_NETWORK_STATE, context.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
+ logInfo("Router service doesn't have ACCESS_NETWORK_STATE permission. It cannot bind a TCP transport to Wi-Fi network.");
+ return null;
+ }
+
ConnectivityManager connMan = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
- // requires ACCESS_NETWORK_STATE permission
+ if (connMan == null) {
+ logInfo("ConnectivityManager isn't available.");
+ return null;
+ }
+
Network[] allNetworks = connMan.getAllNetworks();
+ if (allNetworks == null) {
+ logInfo("Failed to acquire a list of networks.");
+ return null;
+ }
// Samsung Galaxy S9 (with Android 8.0.0) provides two `Network` instances which have
// TRANSPORT_WIFI capability. The first one throws an IOException upon creating a Socket,
// and the second one actually works. To support such case, here we iterate over all
// `Network` instances until we can create a Socket.
for (Network network : allNetworks) {
- // requires ACCESS_NETWORK_STATE permission
+ if (network == null) {
+ continue;
+ }
+
NetworkCapabilities capabilities = connMan.getNetworkCapabilities(network);
+ if (capabilities == null) {
+ continue;
+ }
+
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
try {
- return network.getSocketFactory().createSocket();
+ SocketFactory factory = network.getSocketFactory();
+ if (factory != null) {
+ return factory.createSocket();
+ }
} catch (IOException e) {
logInfo("IOException during socket creation (ignored): " + e.getMessage());
}
}
}
+ logInfo("Cannot find Wi-Fi network to bind a TCP transport.");
return null;
}
}