Example #1
0
static void* jni_channels_thread(void* arg)
{     
	int status;
	HANDLE event;
	rdpChannels* channels;
	freerdp* instance = (freerdp*) arg;
	
	assert(NULL != instance);
											  
	DEBUG_ANDROID("Start.");

	channels = instance->context->channels;
	event = freerdp_channels_get_event_handle(instance);
																	    
	while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
	{
		status = freerdp_channels_process_pending_messages(instance);
		if (!status)
			break; 
		
		android_process_channel_event(channels, instance);
	}
	
	DEBUG_ANDROID("Quit.");

	ExitThread(0);
	return NULL;
} 
Example #2
0
static int android_freerdp_run(freerdp* instance)
{
	int i;
	int fds;
	int max_fds;
	int rcount;
	int wcount;
	int fd_input_event;
	HANDLE input_event = NULL;
	void* rfds[32];
	void* wfds[32];
	fd_set rfds_set;
	fd_set wfds_set;
	int select_status;
	struct timeval timeout;

	const rdpSettings* settings = instance->context->settings;

	HANDLE update_thread;
	HANDLE input_thread;
	HANDLE channels_thread;
	
	BOOL async_update = settings->AsyncUpdate;
	BOOL async_input = settings->AsyncInput;
	BOOL async_channels = settings->AsyncChannels;
	BOOL async_transport = settings->AsyncTransport;

	DEBUG_ANDROID("AsyncUpdate=%d", settings->AsyncUpdate);
	DEBUG_ANDROID("AsyncInput=%d", settings->AsyncInput);
	DEBUG_ANDROID("AsyncChannels=%d", settings->AsyncChannels);
	DEBUG_ANDROID("AsyncTransport=%d", settings->AsyncTransport);

	memset(rfds, 0, sizeof(rfds));
	memset(wfds, 0, sizeof(wfds));

	if (!freerdp_connect(instance))
	{
		freerdp_callback("OnConnectionFailure", "(I)V", instance);
		return 0;
	}

	if (async_update)
	{
		update_thread = CreateThread(NULL, 0,
				(LPTHREAD_START_ROUTINE) jni_update_thread, instance, 0, NULL);
	}
   
	if (async_input)
	{
		input_thread = CreateThread(NULL, 0,
				(LPTHREAD_START_ROUTINE) jni_input_thread, instance, 0, NULL);
	}
	      
	if (async_channels)
	{
		channels_thread = CreateThread(NULL, 0,
				(LPTHREAD_START_ROUTINE) jni_channels_thread, instance, 0, NULL);
	}

	((androidContext*)instance->context)->is_connected = TRUE;
	while (!freerdp_shall_disconnect(instance))
	{
		rcount = 0;
		wcount = 0;

		if (!async_transport)
		{
			if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
			{
				DEBUG_ANDROID("Failed to get FreeRDP file descriptor\n");
				break;
			}
		}

		if (!async_channels)
		{
			if (freerdp_channels_get_fds(instance->context->channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
			{
				DEBUG_ANDROID("Failed to get channel manager file descriptor\n");
				break;
			}
		}

		if (!async_input)
		{
			if (android_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
			{
				DEBUG_ANDROID("Failed to get android file descriptor\n");
				break;
			}
		}
		else
		{
			input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
			fd_input_event = GetEventFileDescriptor(input_event);
			rfds[rcount++] = (void*) (long) fd_input_event;
		}

		max_fds = 0;
		FD_ZERO(&rfds_set);
		FD_ZERO(&wfds_set);

		for (i = 0; i < rcount; i++)
		{
			fds = (int)(long)(rfds[i]);

			if (fds > max_fds)
				max_fds = fds;

			FD_SET(fds, &rfds_set);
		}

		if (max_fds == 0)
			break;

		timeout.tv_sec = 1;
		timeout.tv_usec = 0;

		select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout);

		if (select_status == 0)
			continue;
		else if (select_status == -1)
		{
			/* these are not really errors */
			if (!((errno == EAGAIN) ||
				(errno == EWOULDBLOCK) ||
				(errno == EINPROGRESS) ||
				(errno == EINTR))) /* signal occurred */
			{
				DEBUG_ANDROID("android_run: select failed\n");
				break;
			}
		}
		
		if (freerdp_shall_disconnect(instance))
			break;

		if (!async_transport)
		{
			if (freerdp_check_fds(instance) != TRUE)
			{
				DEBUG_ANDROID("Failed to check FreeRDP file descriptor\n");
				break;
			}
		}

		if (!async_input)
		{
			if (android_check_fds(instance) != TRUE)
			{
				DEBUG_ANDROID("Failed to check android file descriptor\n");
				break;
			}
		}
		else if (input_event)
		{
			if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0)
			{
				if (!freerdp_message_queue_process_pending_messages(instance,
							FREERDP_INPUT_MESSAGE_QUEUE))
				{
					DEBUG_ANDROID("User Disconnect");
					break;
				}
			}
		}

		if (!async_channels)
		{
			if (freerdp_channels_check_fds(instance->context->channels, instance) != TRUE)
			{
				DEBUG_ANDROID("Failed to check channel manager file descriptor\n");
				break;
			}
		
			android_process_channel_event(instance->context->channels, instance);
		}
	}

	DEBUG_ANDROID("Prepare shutdown...");

	// issue another OnDisconnecting here in case the disconnect was initiated by the sever and not our client
	freerdp_callback("OnDisconnecting", "(I)V", instance);
	
	DEBUG_ANDROID("Close channels...");
	freerdp_channels_close(instance->context->channels, instance);

	DEBUG_ANDROID("Cleanup threads...");

	if (async_channels)
	{
		WaitForSingleObject(channels_thread, INFINITE);
		CloseHandle(channels_thread);
	}

	if (async_update)
	{
		wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
		MessageQueue_PostQuit(update_queue, 0);
		WaitForSingleObject(update_thread, INFINITE);
		CloseHandle(update_thread);
	}
	 
	if (async_input)
	{
		wMessageQueue* input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
		MessageQueue_PostQuit(input_queue, 0);
		WaitForSingleObject(input_thread, INFINITE);
		CloseHandle(input_thread);
	}

	DEBUG_ANDROID("Disconnecting...");
	freerdp_disconnect(instance);
	freerdp_callback("OnDisconnected", "(I)V", instance);

	DEBUG_ANDROID("Quit.");

	return 0;
}
Example #3
0
int android_freerdp_run(freerdp* instance)
{
	int i;
	int fds;
	int max_fds;
	int rcount;
	int wcount;
	void* rfds[32];
	void* wfds[32];
	fd_set rfds_set;
	fd_set wfds_set;
	int select_status;
	struct timeval timeout;

	assert(instance);

	memset(rfds, 0, sizeof(rfds));
	memset(wfds, 0, sizeof(wfds));

	if (!freerdp_connect(instance))
	{
		freerdp_callback("OnConnectionFailure", "(I)V", instance);
		return 0;
	}
	
	((androidContext*)instance->context)->is_connected = TRUE;
	while (!freerdp_shall_disconnect(instance))
	{
		rcount = 0;
		wcount = 0;

		if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
		{
			DEBUG_ANDROID("Failed to get FreeRDP file descriptor\n");
			break;
		}
		if (freerdp_channels_get_fds(instance->context->channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
		{
			DEBUG_ANDROID("Failed to get channel manager file descriptor\n");
			break;
		}
		if (android_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
		{
			DEBUG_ANDROID("Failed to get android file descriptor\n");
			break;
		}

		max_fds = 0;
		FD_ZERO(&rfds_set);
		FD_ZERO(&wfds_set);

		for (i = 0; i < rcount; i++)
		{
			fds = (int)(long)(rfds[i]);

			if (fds > max_fds)
				max_fds = fds;

			FD_SET(fds, &rfds_set);
		}

		if (max_fds == 0)
			break;

		timeout.tv_sec = 1;
		timeout.tv_usec = 0;

		select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout);

		if (select_status == 0)
			continue;
		else if (select_status == -1)
		{
			/* these are not really errors */
			if (!((errno == EAGAIN) ||
				(errno == EWOULDBLOCK) ||
				(errno == EINPROGRESS) ||
				(errno == EINTR))) /* signal occurred */
			{
				DEBUG_ANDROID("android_run: select failed\n");
				break;
			}
		}
		
		if (freerdp_shall_disconnect(instance))
			break;

		if (freerdp_check_fds(instance) != TRUE)
		{
			DEBUG_ANDROID("Failed to check FreeRDP file descriptor\n");
			break;
		}
		if (android_check_fds(instance) != TRUE)
		{
			DEBUG_ANDROID("Failed to check android file descriptor\n");
			break;
		}
		if (freerdp_channels_check_fds(instance->context->channels, instance) != TRUE)
		{
			DEBUG_ANDROID("Failed to check channel manager file descriptor\n");
			break;
		}
		android_process_channel_event(instance->context->channels, instance);
	}

	// issue another OnDisconnecting here in case the disconnect was initiated by the sever and not our client
	freerdp_callback("OnDisconnecting", "(I)V", instance);
	freerdp_channels_close(instance->context->channels, instance);
	freerdp_disconnect(instance);
	gdi_free(instance);
	cache_free(instance->context->cache);
	android_cliprdr_uninit(instance);
	freerdp_callback("OnDisconnected", "(I)V", instance);

	return 0;
}