Skip to content

Commit

Permalink
release version 2.6
Browse files Browse the repository at this point in the history
- Applications running the SDK can now run on other network hosts, reachable by the TeamViewer Embedded Agent
- Qt6 support for Qt plugin and qt_simulate
- eglfs support for Qt based applications
- offical support screen recording access control
  • Loading branch information
Korbinian Kram committed Mar 22, 2024
1 parent 7f637cd commit 3f16cd0
Show file tree
Hide file tree
Showing 514 changed files with 47,714 additions and 1,635 deletions.
1 change: 1 addition & 0 deletions Bindings/Python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
cmake_minimum_required(VERSION 3.12)
project(bindings_Python)

# Stick to https://devguide.python.org/versions/
find_package (Python3 3.8 REQUIRED COMPONENTS Development)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
Expand Down
3 changes: 2 additions & 1 deletion Bindings/Python/PyAccessControlModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ PyTypeObject* GetPyTypeAccessControlModule_Feature()
"tvagentapi.AccessControlModule.Feature",
{{toCString(Feature::FileTransfer), static_cast<long>(Feature::FileTransfer)},
{toCString(Feature::RemoteView), static_cast<long>(Feature::RemoteView)},
{toCString(Feature::RemoteControl), static_cast<long>(Feature::RemoteControl)}});
{toCString(Feature::RemoteControl), static_cast<long>(Feature::RemoteControl)},
{toCString(Feature::ScreenRecording), static_cast<long>(Feature::ScreenRecording)}});

return result;
}();
Expand Down
95 changes: 93 additions & 2 deletions Bindings/Python/PyAgentConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ namespace
{

// Methods
PyObject* PyAgentConnection_setConnectionURLs(PyAgentConnection* self, PyObject* args)
{
const char* baseSdkURL{};
const char* agentAPIURL{};

if (!PyArg_ParseTuple(args, "ss", &baseSdkURL, &agentAPIURL))
{
return nullptr;
}

const auto result = self->m_connection->setConnectionURLs(baseSdkURL, agentAPIURL);

return PyEnumValue(GetPyTypeAgentConnection_SetConnectionURLsResult(), tvagentapi::toCString(result));
}

PyObject* PyAgentConnection_start(PyAgentConnection* self, PyObject* args)
{
(void)args;
Expand All @@ -61,6 +76,15 @@ PyObject* PyAgentConnection_stop(PyAgentConnection* self, PyObject* args)
Py_RETURN_NONE;
}

PyObject* PyAgentConnection_getStatus(PyAgentConnection* self, PyObject* args)
{
(void)args;

const auto result = self->m_connection->getStatus();

return PyEnumValue(GetPyTypeAgentConnection_Status(), tvagentapi::toCString(result));
}

PyObject* PyAgentConnection_processEvents(PyAgentConnection* self, PyObject* args, PyObject* kwargs)
{
int waitForMoreEvents = false;
Expand Down Expand Up @@ -170,7 +194,7 @@ PyObject* PyAgentConnection_setCallbacks(

auto statusChangedCallback = [](
tvagentapi::IAgentConnection::Status status,
void* userdata)
void* userdata) noexcept
{
auto pyStatusChangedPyCallback = static_cast<PyObject*>(userdata);

Expand Down Expand Up @@ -201,6 +225,30 @@ PyObject* PyAgentConnection_setCallbacks(
namespace DocStrings
{

PyDoc_STRVAR(setConnectionURLs,
R"__(setConnectionURLs($self, baseSdkUrl, agentApiUrl)
--
Sets a custom base URL where the plugin will host its server sockets
and agent URL which locates the IoT Agent API entry point.
If never called, by default :p baseSdkUrl is :c unix:///tmp or :c tcp+tv://127.0.0.1
and :p agentApiUrl is :c unix:///tmp/teamviewer-iot-agent-services/remoteScreen/registrationService or :c tcp+tv://127.0.0.1:9221
depending on which flags the SDK has been built with.
Check TV_COMM_ENABLE_GRPC and TV_COMM_ENABLE_PLAIN_SOCKET CMake options.
When compiled with both options enabled (standard), the gRPC method is preferred by default.
If you call this method, you should do so once early on after the plugin has been loaded,
before any [register*] methods.
Affects all subsequently initiated communication sessions.
This function checks whether any sockets located at the base URL exceed the length limit for socket names.
If the limit is exceeded, the function will return an error code and the SDK will not use the provided path.
In that case, please provide a shorter path to this function.
It also checks the consistency and validity of the provided URLs (e.g., both URLs must use the same scheme).
:param str baseSdkUrl: the new base URL
:param str agentApiUrl: path to agent API entry point
:return result of URLs' change as enum value, see :p SetConnectionURLsResult
)__");

PyDoc_STRVAR(start,
R"__(start($self)
--
Expand All @@ -217,6 +265,13 @@ R"__(stop($self)
Shuts down all communication with the TeamViewer IoT Agent and changes state afterwards to Disconnected.
)__");

PyDoc_STRVAR(getStatus,
R"__(getStatus($self)
--
Returns the current status of the connection.
)__");

PyDoc_STRVAR(processEvents,
R"__(processEvents($self, waitForMoreEvents, timeoutMs)
--
Expand Down Expand Up @@ -256,6 +311,12 @@ Sets callback to handle changes in connection status.

PyMethodDef PyAgentConnection_methods[] =
{
{
"setConnectionURLs",
PyCFunctionCast(PyAgentConnection_setConnectionURLs),
METH_VARARGS,
DocStrings::setConnectionURLs
},
{
"start",
PyCFunctionCast(PyAgentConnection_start),
Expand All @@ -268,6 +329,12 @@ PyMethodDef PyAgentConnection_methods[] =
METH_NOARGS,
DocStrings::stop
},
{
"getStatus",
PyCFunctionCast(PyAgentConnection_getStatus),
METH_NOARGS,
DocStrings::getStatus
},
{
"processEvents",
PyCFunctionCast(PyAgentConnection_processEvents),
Expand Down Expand Up @@ -296,7 +363,7 @@ namespace tvagentapipy
{

PyAgentConnection::PyAgentConnection(PyTVAgentAPI* pyAgentAPI, PyLogging* pyLogging)
: m_modules{std::make_unique<std::map<tvagentapi::IModule*, PyObject*>>()}
: m_modules{new std::map<tvagentapi::IModule*, PyObject*>()}
, m_pyAgentAPI{pyAgentAPI}
, m_pyLogging{pyLogging}
{
Expand Down Expand Up @@ -350,6 +417,10 @@ PyTypeObject* GetPyTypeAgentConnection()
result.tp_dict,
"Status",
reinterpret_cast<PyObject*>(GetPyTypeAgentConnection_Status()));
PyDict_SetItemString(
result.tp_dict,
"SetConnectionURLsResult",
reinterpret_cast<PyObject*>(GetPyTypeAgentConnection_SetConnectionURLsResult()));

if (PyType_Ready(&result) < 0)
{
Expand Down Expand Up @@ -382,4 +453,24 @@ PyTypeObject* GetPyTypeAgentConnection_Status()
return pyTypeAgentConnection_Status;
}

PyTypeObject* GetPyTypeAgentConnection_SetConnectionURLsResult()
{
static PyTypeObject* pyTypeAgentConnection_Status = []() -> PyTypeObject*
{
using Code = tvagentapi::IAgentConnection::SetConnectionURLsResult;
using tvagentapi::toCString;

PyTypeObject* result =
CreateEnumType(
"tvagentapi.AgentConnection.SetConnectionURLsResult",
{{toCString(Code::Success), static_cast<long>(Code::Success)},
{toCString(Code::CharacterLimitForPathExceeded), static_cast<long>(Code::CharacterLimitForPathExceeded)},
{toCString(Code::SchemaNotValid), static_cast<long>(Code::SchemaNotValid)},
{toCString(Code::ConnectionIsInUse), static_cast<long>(Code::ConnectionIsInUse)}});

return result;
}();
return pyTypeAgentConnection_Status;
}

} // namespace tvagentapipy
1 change: 1 addition & 0 deletions Bindings/Python/PyAgentConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ struct PyAgentConnection final

PyTypeObject* GetPyTypeAgentConnection();
PyTypeObject* GetPyTypeAgentConnection_Status();
PyTypeObject* GetPyTypeAgentConnection_SetConnectionURLsResult();

} // namespace tvagentapipy
33 changes: 31 additions & 2 deletions Bindings/Python/PyTVAgentAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ int PyTVAgentAPI_init(PyTVAgentAPI* self, PyObject* args, PyObject* kwargs)
}

// Methods
PyObject* PyTVAgentAPI_createAgentConnectionLocal(PyTVAgentAPI* self, PyObject* args)
PyObject* PyTVAgentAPI_createAgentConnection(PyTVAgentAPI* self, PyObject* args)
{
PyLogging* pyLogging = nullptr;

Expand Down Expand Up @@ -81,6 +81,12 @@ PyObject* PyTVAgentAPI_createAgentConnectionLocal(PyTVAgentAPI* self, PyObject*
return reinterpret_cast<PyObject*>(pyAgentConnection);
}

PyObject* PyTVAgentAPI_createAgentConnectionLocal(PyTVAgentAPI* self, PyObject* args)
{
PyErr_Warn(PyExc_DeprecationWarning, "use createAgentConnection");
return PyTVAgentAPI_createAgentConnection(self, args);
}

PyObject* PyTVAgentAPI_createFileLogging(PyTVAgentAPI* self, PyObject* arg)
{
if (!PyObject_IsInstance(arg, reinterpret_cast<PyObject*>(&PyUnicode_Type)))
Expand Down Expand Up @@ -111,6 +117,21 @@ FileLogging is thread safe and its methods can be safely called from user code.
:return file logging object.
)__");

PyDoc_STRVAR(createAgentConnection,
R"__(createAgentConnection($self, logger)
--
Creates an instance of a connection to the running TeamViewer IoT Agent instance.
By default the connection already has the parameters for connecting to the agent.
You can change them via :p setConnectionURLs method before starting the connection.
The returned connection is to be used in subsequent calls to create functionality modules
(e.g. Instant Support, TV Session Management, Access Control, etc.).
:param logger: used internally for logging; logger ownership remains on caller's side and is not transferred to the connection.
If no logger is passed no logging happens.
:return agent connection object.
)__");

PyDoc_STRVAR(createAgentConnectionLocal,
R"__(createAgentConnectionLocal($self, logger)
--
Expand All @@ -119,9 +140,10 @@ Creates an instance of a connection to the running TeamViewer IoT Agent instance
The returned connection is to be used in subsequent calls to create functionality modules
(e.g. Instant Support, TV Session Management, Access Control, etc.).
:param logger: would be used internaly for logging; logging ownership remains on caller side and is not transferred to the connection.
:param logger: would be used internally for logging; logging ownership remains on caller side and is not transferred to the connection.
If no logger is passed no logging happens.
:return agent connection object.
:deprecated use createAgentConnection.
)__");

} // namespace DocStrings
Expand All @@ -135,6 +157,13 @@ PyMethodDef PyTVAgentAPI_methods[] =
DocStrings::createFileLogging
},

{
"createAgentConnection",
PyCFunctionCast(PyTVAgentAPI_createAgentConnection),
METH_VARARGS,
DocStrings::createAgentConnection
},

{
"createAgentConnectionLocal",
PyCFunctionCast(PyTVAgentAPI_createAgentConnectionLocal),
Expand Down
5 changes: 5 additions & 0 deletions Bindings/Python/Typesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ namespace tvagentapipy

struct PyTypeMeta final
{
PyTypeMeta(PyTypeObject* pyTypeObject, const char* publicName)
: pyTypeObject{pyTypeObject}
, publicName{publicName}
{}

PyTypeObject* pyTypeObject = nullptr;
const char* publicName = nullptr;
};
Expand Down
6 changes: 3 additions & 3 deletions Bindings/Python/tests/test_access_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@

# Test cases
test_cases = {
'test_file_transfer_access_accept': lambda: test_file_transfer_access_request('accept'),
'test_file_transfer_access_reject': lambda: test_file_transfer_access_request('reject'),
'test_file_transfer_access_timeout': lambda: test_file_transfer_access_request('timeout'),
'test_file_transfer_access_accept': test_file_transfer_access_request('accept'),
'test_file_transfer_access_reject': test_file_transfer_access_request('reject'),
'test_file_transfer_access_timeout': test_file_transfer_access_request('timeout'),
}

if __name__ == "__main__":
Expand Down
10 changes: 5 additions & 5 deletions Bindings/Python/tests/test_agent_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@
# Test cases
test_cases = {
'test_agent_connection_while_agent_running': test_agent_connection,
'test_agent_connection_while_agent_running_processEvents_busy_loop': lambda: test_agent_connection(wait_for_more_events=False),
'test_agent_connection_while_agent_running_processEvents_wrong_argument_1': lambda: test_agent_connection(
'test_agent_connection_while_agent_running_processEvents_busy_loop': test_agent_connection(wait_for_more_events=False),
'test_agent_connection_while_agent_running_processEvents_wrong_argument_1': test_agent_connection(
wait_for_more_events=False,
more_events_timeout_ms=-10,
process_events_expect_error=True),
'test_agent_connection_while_agent_running_processEvents_wrong_argument_2': lambda: test_agent_connection(
'test_agent_connection_while_agent_running_processEvents_wrong_argument_2': test_agent_connection(
wait_for_more_events=False,
more_events_timeout_ms="wrong type",
process_events_expect_error=True),
'test_agent_connection_while_agent_running_processEvents_wrong_argument_3': lambda: test_agent_connection(
'test_agent_connection_while_agent_running_processEvents_wrong_argument_3': test_agent_connection(
wait_for_more_events="wrong type",
more_events_timeout_ms="wrong type",
process_events_expect_error=True),
'test_agent_connection_while_agent_running_processEvents_wrong_argument_4': lambda: test_agent_connection(
'test_agent_connection_while_agent_running_processEvents_wrong_argument_4': test_agent_connection(
wait_for_more_events=True,
more_events_timeout_ms=8000000000000,
process_events_expect_error=True)
Expand Down
10 changes: 5 additions & 5 deletions Bindings/Python/tests/test_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

# Test cases
test_cases = {
'test_send_receive': lambda: test_chat(
'test_send_receive': test_chat(
behavior=[
# receive and send first messages to create the chat
lambda connection: sub_test_chat_send_receive_messages(
Expand All @@ -54,27 +54,27 @@
)
]
),
'test_load_messages': lambda: test_chat(
'test_load_messages': test_chat(
behavior=[
lambda connection: sub_test_chat_send_receive_messages(connection, expect_chat_room_created=False, expected_message_pairs=[("Hello", "Hi 😀")]),
lambda connection: sub_test_chat_load_messages(connection, messages_to_load=2, expected_messages=["Hello", "Hi 😀"])
]
),
'test_delete_history': lambda: test_chat(
'test_delete_history': test_chat(
behavior=[
lambda connection: sub_test_chat_send_receive_messages(connection, expect_chat_room_created=False, expected_message_pairs=[("Hello", "Hi 😀")]),
lambda connection: sub_test_chat_load_messages(connection, messages_to_load=2, expected_messages=["Hello", "Hi 😀"]),
lambda connection: sub_test_chat_delete_history(connection),
lambda connection: sub_test_chat_load_messages(connection, messages_to_load=2, expected_messages=[])
]
),
'test_delete_chat': lambda: test_chat(
'test_delete_chat': test_chat(
behavior=[
lambda connection: sub_test_chat_send_receive_messages(connection, expect_chat_room_created=False, expected_message_pairs=[("Hello", None)]),
lambda connection: sub_test_chat_delete_chat(connection, number_of_rooms_to_delete=1)
]
),
'test_error_cases': lambda: test_chat(
'test_error_cases': test_chat(
behavior=[
lambda connection: sub_test_chat_send_receive_messages(connection, expect_chat_room_created=False, expected_message_pairs=[("Hello", None)]),
lambda connection: sub_test_chat_error_send_message(connection)
Expand Down
Loading

0 comments on commit 3f16cd0

Please sign in to comment.