IP/Top: Add Android network interface
This commit is contained in:
parent
26302c2257
commit
20ebed51bb
Source
Android
app/src/main
jni/AndroidCommon
Core/Core/IOS/Network/IP
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
<uses-feature android:glEsVersion="0x00030000"/>
|
<uses-feature android:glEsVersion="0x00030000"/>
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
package org.dolphinemu.dolphinemu.utils;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.LinkAddress;
|
||||||
|
import android.net.LinkProperties;
|
||||||
|
import android.net.Network;
|
||||||
|
import android.net.RouteInfo;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.annotation.Keep;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.DolphinApplication;
|
||||||
|
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NetworkHelper
|
||||||
|
{
|
||||||
|
private static ConnectivityManager GetConnectivityManager()
|
||||||
|
{
|
||||||
|
Context context = DolphinApplication.getAppContext();
|
||||||
|
ConnectivityManager manager =
|
||||||
|
(ConnectivityManager) context.getSystemService(Service.CONNECTIVITY_SERVICE);
|
||||||
|
if (manager == null)
|
||||||
|
Log.warning("Cannot get Network link as ConnectivityManager is null.");
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||||
|
private static LinkAddress GetIPv4Link()
|
||||||
|
{
|
||||||
|
ConnectivityManager manager = GetConnectivityManager();
|
||||||
|
if (manager == null)
|
||||||
|
return null;
|
||||||
|
Network active_network = manager.getActiveNetwork();
|
||||||
|
if (active_network == null)
|
||||||
|
{
|
||||||
|
Log.warning("Active network is null.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
LinkProperties properties = manager.getLinkProperties(active_network);
|
||||||
|
if (properties == null)
|
||||||
|
{
|
||||||
|
Log.warning("Link properties is null.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (LinkAddress link : properties.getLinkAddresses())
|
||||||
|
{
|
||||||
|
InetAddress address = link.getAddress();
|
||||||
|
if (address instanceof Inet4Address)
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
Log.warning("No IPv4 link found.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int InetAddressToInt(InetAddress address)
|
||||||
|
{
|
||||||
|
byte[] net_addr = address.getAddress();
|
||||||
|
int result = 0;
|
||||||
|
// Convert address to little endian
|
||||||
|
for (int i = 0; i < net_addr.length; i++)
|
||||||
|
{
|
||||||
|
result |= (net_addr[i] & 0xFF) << (8 * i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
public static int GetNetworkIpAddress()
|
||||||
|
{
|
||||||
|
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M)
|
||||||
|
return 0;
|
||||||
|
LinkAddress link = GetIPv4Link();
|
||||||
|
if (link == null)
|
||||||
|
return 0;
|
||||||
|
return InetAddressToInt(link.getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
public static int GetNetworkPrefixLength()
|
||||||
|
{
|
||||||
|
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M)
|
||||||
|
return 0;
|
||||||
|
LinkAddress link = GetIPv4Link();
|
||||||
|
if (link == null)
|
||||||
|
return 0;
|
||||||
|
return link.getPrefixLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
public static int GetNetworkGateway()
|
||||||
|
{
|
||||||
|
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M)
|
||||||
|
return 0;
|
||||||
|
ConnectivityManager manager = GetConnectivityManager();
|
||||||
|
if (manager == null)
|
||||||
|
return 0;
|
||||||
|
Network active_network = manager.getActiveNetwork();
|
||||||
|
if (active_network == null)
|
||||||
|
return 0;
|
||||||
|
LinkProperties properties = manager.getLinkProperties(active_network);
|
||||||
|
if (properties == null)
|
||||||
|
return 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InetAddress addr_out = InetAddress.getByName("8.8.8.8");
|
||||||
|
for (RouteInfo route : properties.getRoutes())
|
||||||
|
{
|
||||||
|
if (!route.matches(addr_out))
|
||||||
|
continue;
|
||||||
|
return InetAddressToInt(route.getGateway());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (UnknownHostException ignore)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
Log.warning("No valid gateway found.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,3 +65,24 @@ bool DeleteAndroidContent(const std::string& uri)
|
||||||
return env->CallStaticBooleanMethod(IDCache::GetContentHandlerClass(),
|
return env->CallStaticBooleanMethod(IDCache::GetContentHandlerClass(),
|
||||||
IDCache::GetContentHandlerDelete(), ToJString(env, uri));
|
IDCache::GetContentHandlerDelete(), ToJString(env, uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetNetworkIpAddress()
|
||||||
|
{
|
||||||
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
|
return env->CallStaticIntMethod(IDCache::GetNetworkHelperClass(),
|
||||||
|
IDCache::GetNetworkHelperGetNetworkIpAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetNetworkPrefixLength()
|
||||||
|
{
|
||||||
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
|
return env->CallStaticIntMethod(IDCache::GetNetworkHelperClass(),
|
||||||
|
IDCache::GetNetworkHelperGetNetworkPrefixLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetNetworkGateway()
|
||||||
|
{
|
||||||
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
|
return env->CallStaticIntMethod(IDCache::GetNetworkHelperClass(),
|
||||||
|
IDCache::GetNetworkHelperGetNetworkGateway());
|
||||||
|
}
|
||||||
|
|
|
@ -14,3 +14,6 @@ std::vector<std::string> JStringArrayToVector(JNIEnv* env, jobjectArray array);
|
||||||
|
|
||||||
int OpenAndroidContent(const std::string& uri, const std::string& mode);
|
int OpenAndroidContent(const std::string& uri, const std::string& mode);
|
||||||
bool DeleteAndroidContent(const std::string& uri);
|
bool DeleteAndroidContent(const std::string& uri);
|
||||||
|
int GetNetworkIpAddress();
|
||||||
|
int GetNetworkPrefixLength();
|
||||||
|
int GetNetworkGateway();
|
||||||
|
|
|
@ -45,6 +45,11 @@ static jclass s_content_handler_class;
|
||||||
static jmethodID s_content_handler_open_fd;
|
static jmethodID s_content_handler_open_fd;
|
||||||
static jmethodID s_content_handler_delete;
|
static jmethodID s_content_handler_delete;
|
||||||
|
|
||||||
|
static jclass s_network_helper_class;
|
||||||
|
static jmethodID s_network_helper_get_network_ip_address;
|
||||||
|
static jmethodID s_network_helper_get_network_prefix_length;
|
||||||
|
static jmethodID s_network_helper_get_network_gateway;
|
||||||
|
|
||||||
namespace IDCache
|
namespace IDCache
|
||||||
{
|
{
|
||||||
JNIEnv* GetEnvForThread()
|
JNIEnv* GetEnvForThread()
|
||||||
|
@ -205,6 +210,25 @@ jmethodID GetContentHandlerDelete()
|
||||||
return s_content_handler_delete;
|
return s_content_handler_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jclass GetNetworkHelperClass()
|
||||||
|
{
|
||||||
|
return s_network_helper_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID GetNetworkHelperGetNetworkIpAddress()
|
||||||
|
{
|
||||||
|
return s_network_helper_get_network_ip_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID GetNetworkHelperGetNetworkPrefixLength()
|
||||||
|
{
|
||||||
|
return s_network_helper_get_network_prefix_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmethodID GetNetworkHelperGetNetworkGateway()
|
||||||
|
{
|
||||||
|
return s_network_helper_get_network_gateway;
|
||||||
|
}
|
||||||
} // namespace IDCache
|
} // namespace IDCache
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -283,6 +307,16 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||||
s_content_handler_delete =
|
s_content_handler_delete =
|
||||||
env->GetStaticMethodID(s_content_handler_class, "delete", "(Ljava/lang/String;)Z");
|
env->GetStaticMethodID(s_content_handler_class, "delete", "(Ljava/lang/String;)Z");
|
||||||
|
|
||||||
|
const jclass network_helper_class =
|
||||||
|
env->FindClass("org/dolphinemu/dolphinemu/utils/NetworkHelper");
|
||||||
|
s_network_helper_class = reinterpret_cast<jclass>(env->NewGlobalRef(network_helper_class));
|
||||||
|
s_network_helper_get_network_ip_address =
|
||||||
|
env->GetStaticMethodID(s_network_helper_class, "GetNetworkIpAddress", "()I");
|
||||||
|
s_network_helper_get_network_prefix_length =
|
||||||
|
env->GetStaticMethodID(s_network_helper_class, "GetNetworkPrefixLength", "()I");
|
||||||
|
s_network_helper_get_network_gateway =
|
||||||
|
env->GetStaticMethodID(s_network_helper_class, "GetNetworkGateway", "()I");
|
||||||
|
|
||||||
return JNI_VERSION;
|
return JNI_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,6 +335,7 @@ void JNI_OnUnload(JavaVM* vm, void* reserved)
|
||||||
env->DeleteGlobalRef(s_ini_file_section_class);
|
env->DeleteGlobalRef(s_ini_file_section_class);
|
||||||
env->DeleteGlobalRef(s_compress_cb_class);
|
env->DeleteGlobalRef(s_compress_cb_class);
|
||||||
env->DeleteGlobalRef(s_content_handler_class);
|
env->DeleteGlobalRef(s_content_handler_class);
|
||||||
|
env->DeleteGlobalRef(s_network_helper_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -45,4 +45,9 @@ jclass GetContentHandlerClass();
|
||||||
jmethodID GetContentHandlerOpenFd();
|
jmethodID GetContentHandlerOpenFd();
|
||||||
jmethodID GetContentHandlerDelete();
|
jmethodID GetContentHandlerDelete();
|
||||||
|
|
||||||
|
jclass GetNetworkHelperClass();
|
||||||
|
jmethodID GetNetworkHelperGetNetworkIpAddress();
|
||||||
|
jmethodID GetNetworkHelperGetNetworkPrefixLength();
|
||||||
|
jmethodID GetNetworkHelperGetNetworkGateway();
|
||||||
|
|
||||||
} // namespace IDCache
|
} // namespace IDCache
|
||||||
|
|
|
@ -50,6 +50,10 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include "jni/AndroidCommon/AndroidCommon.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace IOS::HLE::Device
|
namespace IOS::HLE::Device
|
||||||
{
|
{
|
||||||
enum SOResultCode : s32
|
enum SOResultCode : s32
|
||||||
|
@ -217,7 +221,14 @@ static std::optional<DefaultInterface> GetSystemDefaultInterface()
|
||||||
return DefaultInterface{entry.dwAddr, entry.dwMask, entry.dwBCastAddr};
|
return DefaultInterface{entry.dwAddr, entry.dwMask, entry.dwBCastAddr};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif !defined(__ANDROID__)
|
#elif defined(__ANDROID__)
|
||||||
|
const u32 addr = GetNetworkIpAddress();
|
||||||
|
const u32 prefix_length = GetNetworkPrefixLength();
|
||||||
|
const u32 netmask = (1 << prefix_length) - 1;
|
||||||
|
const u32 gateway = GetNetworkGateway();
|
||||||
|
if (addr || netmask || gateway)
|
||||||
|
return DefaultInterface{addr, netmask, gateway};
|
||||||
|
#else
|
||||||
// Assume that the address that is used to access the Internet corresponds
|
// Assume that the address that is used to access the Internet corresponds
|
||||||
// to the default interface.
|
// to the default interface.
|
||||||
auto get_default_address = []() -> std::optional<in_addr> {
|
auto get_default_address = []() -> std::optional<in_addr> {
|
||||||
|
@ -261,7 +272,7 @@ static std::optional<DefaultInterface> GetSystemDefaultInterface()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return {};
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DefaultInterface GetSystemDefaultInterfaceOrFallback()
|
static DefaultInterface GetSystemDefaultInterfaceOrFallback()
|
||||||
|
|
Loading…
Reference in New Issue