Merge pull request #33910 from Faless/net/android_mlock
Acquire MulticastLock on Android when using broadcast/multicast
This commit is contained in:
commit
d3a07d3550
@ -69,7 +69,7 @@ public:
|
||||
virtual bool is_open() const = 0;
|
||||
virtual int get_available_bytes() const = 0;
|
||||
|
||||
virtual void set_broadcasting_enabled(bool p_enabled) = 0;
|
||||
virtual Error set_broadcasting_enabled(bool p_enabled) = 0; // Returns OK if the socket option has been set successfully.
|
||||
virtual void set_blocking_enabled(bool p_enabled) = 0;
|
||||
virtual void set_ipv6_only_enabled(bool p_enabled) = 0;
|
||||
virtual void set_tcp_no_delay_enabled(bool p_enabled) = 0;
|
||||
|
@ -37,6 +37,12 @@ void PacketPeerUDP::set_blocking_mode(bool p_enable) {
|
||||
blocking = p_enable;
|
||||
}
|
||||
|
||||
void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) {
|
||||
broadcast = p_enabled;
|
||||
if (_sock.is_valid() && _sock->is_open())
|
||||
_sock->set_broadcasting_enabled(p_enabled);
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_if_name) {
|
||||
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
@ -47,6 +53,7 @@ Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_i
|
||||
Error err = _sock->open(NetSocket::TYPE_UDP, ip_type);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
_sock->set_blocking_enabled(false);
|
||||
_sock->set_broadcasting_enabled(broadcast);
|
||||
}
|
||||
return _sock->join_multicast_group(p_multi_address, p_if_name);
|
||||
}
|
||||
@ -122,6 +129,7 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
|
||||
err = _sock->open(NetSocket::TYPE_UDP, ip_type);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
_sock->set_blocking_enabled(false);
|
||||
_sock->set_broadcasting_enabled(broadcast);
|
||||
}
|
||||
|
||||
do {
|
||||
@ -165,6 +173,7 @@ Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_
|
||||
|
||||
_sock->set_blocking_enabled(false);
|
||||
_sock->set_reuse_address_enabled(true);
|
||||
_sock->set_broadcasting_enabled(broadcast);
|
||||
err = _sock->bind(p_bind_address, p_port);
|
||||
|
||||
if (err != OK) {
|
||||
@ -258,6 +267,7 @@ void PacketPeerUDP::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_packet_ip"), &PacketPeerUDP::_get_packet_ip);
|
||||
ClassDB::bind_method(D_METHOD("get_packet_port"), &PacketPeerUDP::get_packet_port);
|
||||
ClassDB::bind_method(D_METHOD("set_dest_address", "host", "port"), &PacketPeerUDP::_set_dest_address);
|
||||
ClassDB::bind_method(D_METHOD("set_broadcast_enabled", "enabled"), &PacketPeerUDP::set_broadcast_enabled);
|
||||
ClassDB::bind_method(D_METHOD("join_multicast_group", "multicast_address", "interface_name"), &PacketPeerUDP::join_multicast_group);
|
||||
ClassDB::bind_method(D_METHOD("leave_multicast_group", "multicast_address", "interface_name"), &PacketPeerUDP::leave_multicast_group);
|
||||
}
|
||||
@ -267,6 +277,7 @@ PacketPeerUDP::PacketPeerUDP() :
|
||||
queue_count(0),
|
||||
peer_port(0),
|
||||
blocking(true),
|
||||
broadcast(false),
|
||||
_sock(Ref<NetSocket>(NetSocket::create())) {
|
||||
rb.resize(16);
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ protected:
|
||||
IP_Address peer_addr;
|
||||
int peer_port;
|
||||
bool blocking;
|
||||
bool broadcast;
|
||||
Ref<NetSocket> _sock;
|
||||
|
||||
static void _bind_methods();
|
||||
@ -77,6 +78,7 @@ public:
|
||||
Error get_packet(const uint8_t **r_buffer, int &r_buffer_size);
|
||||
int get_available_packet_count() const;
|
||||
int get_max_packet_size() const;
|
||||
void set_broadcast_enabled(bool p_enabled);
|
||||
Error join_multicast_group(IP_Address p_multi_address, String p_if_name);
|
||||
Error leave_multicast_group(IP_Address p_multi_address, String p_if_name);
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
<description>
|
||||
Joins the multicast group specified by [code]multicast_address[/code] using the interface identified by [code]interface_name[/code].
|
||||
You can join the same multicast group with multiple interfaces. Use [method IP.get_local_interfaces] to know which are available.
|
||||
Note: Some Android devices might require the [code]CHANGE_WIFI_MULTICAST_STATE[/code] permission for multicast to work.
|
||||
</description>
|
||||
</method>
|
||||
<method name="leave_multicast_group">
|
||||
@ -76,6 +77,16 @@
|
||||
If [code]bind_address[/code] is set to any valid address (e.g. [code]"192.168.1.101"[/code], [code]"::1"[/code], etc), the peer will only listen on the interface with that addresses (or fail if no interface with the given address exists).
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_broadcast_enabled">
|
||||
<return type="void">
|
||||
</return>
|
||||
<argument index="0" name="enabled" type="bool">
|
||||
</argument>
|
||||
<description>
|
||||
Enable or disable sending of broadcast packets (e.g. [code]set_dest_address("255.255.255.255", 4343)[/code]. This option is disabled by default.
|
||||
Note: Some Android devices might require the [code]CHANGE_WIFI_MULTICAST_STATE[/code] permission and this option to be enabled to receive broadcast packets too.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_dest_address">
|
||||
<return type="int" enum="Error">
|
||||
</return>
|
||||
@ -85,6 +96,7 @@
|
||||
</argument>
|
||||
<description>
|
||||
Sets the destination address and port for sending packets and variables. A hostname will be resolved using DNS if needed.
|
||||
Note: [method set_broadcast_enabled] must be enabled before sending packets to a broadcast address (e.g. [code]255.255.255.255[/code]).
|
||||
</description>
|
||||
</method>
|
||||
<method name="wait">
|
||||
|
@ -333,9 +333,10 @@ Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) {
|
||||
set_ipv6_only_enabled(ip_type != IP::TYPE_ANY);
|
||||
}
|
||||
|
||||
if (protocol == IPPROTO_UDP && ip_type != IP::TYPE_IPV6) {
|
||||
// Enable broadcasting for UDP sockets if it's not IPv6 only (IPv6 has no broadcast option).
|
||||
set_broadcasting_enabled(true);
|
||||
if (protocol == IPPROTO_UDP) {
|
||||
// Make sure to disable broadcasting for UDP sockets.
|
||||
// Depending on the OS, this option might or might not be enabled by default. Let's normalize it.
|
||||
set_broadcasting_enabled(false);
|
||||
}
|
||||
|
||||
_is_stream = p_sock_type == TYPE_TCP;
|
||||
@ -603,15 +604,18 @@ Error NetSocketPosix::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP
|
||||
return OK;
|
||||
}
|
||||
|
||||
void NetSocketPosix::set_broadcasting_enabled(bool p_enabled) {
|
||||
ERR_FAIL_COND(!is_open());
|
||||
Error NetSocketPosix::set_broadcasting_enabled(bool p_enabled) {
|
||||
ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);
|
||||
// IPv6 has no broadcast support.
|
||||
ERR_FAIL_COND(_ip_type == IP::TYPE_IPV6);
|
||||
if (_ip_type == IP::TYPE_IPV6)
|
||||
return ERR_UNAVAILABLE;
|
||||
|
||||
int par = p_enabled ? 1 : 0;
|
||||
if (setsockopt(_sock, SOL_SOCKET, SO_BROADCAST, SOCK_CBUF(&par), sizeof(int)) != 0) {
|
||||
WARN_PRINT("Unable to change broadcast setting");
|
||||
return FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
void NetSocketPosix::set_blocking_enabled(bool p_enabled) {
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
virtual bool is_open() const;
|
||||
virtual int get_available_bytes() const;
|
||||
|
||||
virtual void set_broadcasting_enabled(bool p_enabled);
|
||||
virtual Error set_broadcasting_enabled(bool p_enabled);
|
||||
virtual void set_blocking_enabled(bool p_enabled);
|
||||
virtual void set_ipv6_only_enabled(bool p_enabled);
|
||||
virtual void set_tcp_no_delay_enabled(bool p_enabled);
|
||||
|
@ -12,6 +12,7 @@ android_files = [
|
||||
'file_access_jandroid.cpp',
|
||||
'dir_access_jandroid.cpp',
|
||||
'thread_jandroid.cpp',
|
||||
'net_socket_android.cpp',
|
||||
'audio_driver_jandroid.cpp',
|
||||
'java_godot_lib_jni.cpp',
|
||||
'java_class_wrapper.cpp',
|
||||
|
@ -96,6 +96,7 @@ import java.util.Locale;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import org.godotengine.godot.input.GodotEditText;
|
||||
import org.godotengine.godot.payments.PaymentsManager;
|
||||
import org.godotengine.godot.utils.GodotNetUtils;
|
||||
import org.godotengine.godot.utils.PermissionsUtil;
|
||||
import org.godotengine.godot.xr.XRMode;
|
||||
|
||||
@ -243,6 +244,7 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo
|
||||
private Sensor mGyroscope;
|
||||
|
||||
public static GodotIO io;
|
||||
public static GodotNetUtils netUtils;
|
||||
|
||||
static SingletonBase[] singletons = new SingletonBase[MAX_SINGLETONS];
|
||||
static int singleton_count = 0;
|
||||
@ -502,6 +504,7 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo
|
||||
io = new GodotIO(this);
|
||||
io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
|
||||
GodotLib.io = io;
|
||||
netUtils = new GodotNetUtils(this);
|
||||
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
|
||||
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
|
||||
|
@ -0,0 +1,84 @@
|
||||
/*************************************************************************/
|
||||
/* GodotNetUtils.java */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
package org.godotengine.godot.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.godotengine.godot.Godot;
|
||||
|
||||
/**
|
||||
* This class handles Android-specific networking functions.
|
||||
* For now, it only provides access to WifiManager.MulticastLock, which is needed on some devices
|
||||
* to receive broadcast and multicast packets.
|
||||
*/
|
||||
public class GodotNetUtils {
|
||||
|
||||
/* A single, reference counted, multicast lock, or null if permission CHANGE_WIFI_MULTICAST_STATE is missing */
|
||||
private WifiManager.MulticastLock multicastLock;
|
||||
|
||||
public GodotNetUtils(Godot p_activity) {
|
||||
if (PermissionsUtil.hasManifestPermission(p_activity, "android.permission.CHANGE_WIFI_MULTICAST_STATE")) {
|
||||
WifiManager wifi = (WifiManager)p_activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
||||
multicastLock = wifi.createMulticastLock("GodotMulticastLock");
|
||||
multicastLock.setReferenceCounted(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire the multicast lock. This is required on some devices to receive broadcast/multicast packets.
|
||||
* This is done automatically by Godot when enabling broadcast or joining a multicast group on a socket.
|
||||
*/
|
||||
public void multicastLockAcquire() {
|
||||
if (multicastLock == null)
|
||||
return;
|
||||
try {
|
||||
multicastLock.acquire();
|
||||
} catch (RuntimeException e) {
|
||||
Log.e("Godot", "Exception during multicast lock acquire: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the multicast lock.
|
||||
* This is done automatically by Godot when the lock is no longer needed by a socket.
|
||||
*/
|
||||
public void multicastLockRelease() {
|
||||
if (multicastLock == null)
|
||||
return;
|
||||
try {
|
||||
multicastLock.release();
|
||||
} catch (RuntimeException e) {
|
||||
Log.e("Godot", "Exception during multicast lock release: " + e);
|
||||
}
|
||||
}
|
||||
}
|
@ -161,6 +161,24 @@ public final class PermissionsUtil {
|
||||
return dangerousPermissions.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given permission is in the AndroidManifest.xml file.
|
||||
* @param activity the caller activity for this method.
|
||||
* @param permission the permession to look for in the manifest file.
|
||||
* @return "true" if the permission is in the manifest file of the activity, "false" otherwise.
|
||||
*/
|
||||
public static boolean hasManifestPermission(Godot activity, String permission) {
|
||||
try {
|
||||
for (String p : getManifestPermissions(activity)) {
|
||||
if (permission.equals(p))
|
||||
return true;
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the permissions defined in the AndroidManifest.xml file.
|
||||
* @param activity the caller activity for this method.
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "java_class_wrapper.h"
|
||||
#include "main/input_default.h"
|
||||
#include "main/main.h"
|
||||
#include "net_socket_android.h"
|
||||
#include "os_android.h"
|
||||
#include "string_android.h"
|
||||
#include "thread_jandroid.h"
|
||||
@ -635,6 +636,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
|
||||
|
||||
DirAccessJAndroid::setup(godot_io_java->get_instance());
|
||||
AudioDriverAndroid::setup(godot_io_java->get_instance());
|
||||
NetSocketAndroid::setup(godot_java->get_member_object("netUtils", "Lorg/godotengine/godot/utils/GodotNetUtils;", env));
|
||||
|
||||
os_android = new OS_Android(godot_java, godot_io_java, p_use_apk_expansion);
|
||||
|
||||
|
136
platform/android/net_socket_android.cpp
Normal file
136
platform/android/net_socket_android.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/*************************************************************************/
|
||||
/* net_socket_android.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "net_socket_android.h"
|
||||
|
||||
#include "thread_jandroid.h"
|
||||
|
||||
jobject NetSocketAndroid::net_utils = 0;
|
||||
jclass NetSocketAndroid::cls = 0;
|
||||
jmethodID NetSocketAndroid::_multicast_lock_acquire = 0;
|
||||
jmethodID NetSocketAndroid::_multicast_lock_release = 0;
|
||||
|
||||
void NetSocketAndroid::setup(jobject p_net_utils) {
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
|
||||
net_utils = env->NewGlobalRef(p_net_utils);
|
||||
|
||||
jclass c = env->GetObjectClass(net_utils);
|
||||
cls = (jclass)env->NewGlobalRef(c);
|
||||
|
||||
_multicast_lock_acquire = env->GetMethodID(cls, "multicastLockAcquire", "()V");
|
||||
_multicast_lock_release = env->GetMethodID(cls, "multicastLockRelease", "()V");
|
||||
}
|
||||
|
||||
void NetSocketAndroid::multicast_lock_acquire() {
|
||||
if (_multicast_lock_acquire) {
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
env->CallVoidMethod(net_utils, _multicast_lock_acquire);
|
||||
}
|
||||
}
|
||||
|
||||
void NetSocketAndroid::multicast_lock_release() {
|
||||
if (_multicast_lock_release) {
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
env->CallVoidMethod(net_utils, _multicast_lock_release);
|
||||
}
|
||||
}
|
||||
|
||||
NetSocket *NetSocketAndroid::_create_func() {
|
||||
return memnew(NetSocketAndroid);
|
||||
}
|
||||
|
||||
void NetSocketAndroid::make_default() {
|
||||
_create = _create_func;
|
||||
}
|
||||
|
||||
NetSocketAndroid::NetSocketAndroid() :
|
||||
wants_broadcast(false),
|
||||
multicast_groups(0) {
|
||||
}
|
||||
|
||||
NetSocketAndroid::~NetSocketAndroid() {
|
||||
close();
|
||||
}
|
||||
|
||||
void NetSocketAndroid::close() {
|
||||
NetSocketPosix::close();
|
||||
if (wants_broadcast)
|
||||
multicast_lock_release();
|
||||
if (multicast_groups)
|
||||
multicast_lock_release();
|
||||
wants_broadcast = false;
|
||||
multicast_groups = 0;
|
||||
}
|
||||
|
||||
Error NetSocketAndroid::set_broadcasting_enabled(bool p_enabled) {
|
||||
Error err = NetSocketPosix::set_broadcasting_enabled(p_enabled);
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
if (p_enabled != wants_broadcast) {
|
||||
if (p_enabled) {
|
||||
multicast_lock_acquire();
|
||||
} else {
|
||||
multicast_lock_release();
|
||||
}
|
||||
|
||||
wants_broadcast = p_enabled;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error NetSocketAndroid::join_multicast_group(const IP_Address &p_multi_address, String p_if_name) {
|
||||
Error err = NetSocketPosix::join_multicast_group(p_multi_address, p_if_name);
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
if (!multicast_groups)
|
||||
multicast_lock_acquire();
|
||||
multicast_groups++;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error NetSocketAndroid::leave_multicast_group(const IP_Address &p_multi_address, String p_if_name) {
|
||||
Error err = NetSocketPosix::leave_multicast_group(p_multi_address, p_if_name);
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
ERR_FAIL_COND_V(multicast_groups == 0, ERR_BUG);
|
||||
|
||||
multicast_groups--;
|
||||
if (!multicast_groups)
|
||||
multicast_lock_release();
|
||||
|
||||
return OK;
|
||||
}
|
78
platform/android/net_socket_android.h
Normal file
78
platform/android/net_socket_android.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*************************************************************************/
|
||||
/* net_socket_android.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef NET_SOCKET_ANDROID_H
|
||||
#define NET_SOCKET_ANDROID_H
|
||||
|
||||
#include "drivers/unix/net_socket_posix.h"
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
/**
|
||||
* Specialized NetSocket implementation for Android.
|
||||
*
|
||||
* Some devices requires Android-specific code to acquire a MulticastLock
|
||||
* before sockets are allowed to receive broadcast and multicast packets.
|
||||
* This implementation calls into Java code and automatically acquire/release
|
||||
* the lock when broadcasting is enabled/disabled on a socket, or that socket
|
||||
* joins/leaves a multicast group.
|
||||
*/
|
||||
class NetSocketAndroid : public NetSocketPosix {
|
||||
|
||||
private:
|
||||
static jobject net_utils;
|
||||
static jclass cls;
|
||||
static jmethodID _multicast_lock_acquire;
|
||||
static jmethodID _multicast_lock_release;
|
||||
|
||||
bool wants_broadcast;
|
||||
int multicast_groups;
|
||||
|
||||
static void multicast_lock_acquire();
|
||||
static void multicast_lock_release();
|
||||
|
||||
protected:
|
||||
static NetSocket *_create_func();
|
||||
|
||||
public:
|
||||
static void make_default();
|
||||
static void setup(jobject p_net_utils);
|
||||
|
||||
virtual void close();
|
||||
|
||||
virtual Error set_broadcasting_enabled(bool p_enabled);
|
||||
virtual Error join_multicast_group(const IP_Address &p_multi_address, String p_if_name);
|
||||
virtual Error leave_multicast_group(const IP_Address &p_multi_address, String p_if_name);
|
||||
|
||||
NetSocketAndroid();
|
||||
~NetSocketAndroid();
|
||||
};
|
||||
|
||||
#endif
|
@ -43,6 +43,7 @@
|
||||
|
||||
#include "dir_access_jandroid.h"
|
||||
#include "file_access_jandroid.h"
|
||||
#include "net_socket_android.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
@ -106,6 +107,8 @@ void OS_Android::initialize_core() {
|
||||
DirAccess::make_default<DirAccessJAndroid>(DirAccess::ACCESS_RESOURCES);
|
||||
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_USERDATA);
|
||||
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_FILESYSTEM);
|
||||
|
||||
NetSocketAndroid::make_default();
|
||||
}
|
||||
|
||||
void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
|
||||
|
Loading…
Reference in New Issue
Block a user