FreeRDP
Loading...
Searching...
No Matches
LibFreeRDP.java
1/*
2 Android FreeRDP JNI Wrapper
3
4 Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
5
6 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
7 If a copy of the MPL was not distributed with this file, You can obtain one at
8 http://mozilla.org/MPL/2.0/.
9*/
10
11package com.freerdp.freerdpcore.services;
12
13import android.content.Context;
14import android.graphics.Bitmap;
15import android.net.Uri;
16import android.util.Log;
17
18import androidx.collection.LongSparseArray;
19
20import com.freerdp.freerdpcore.application.GlobalApp;
21import com.freerdp.freerdpcore.application.SessionState;
22import com.freerdp.freerdpcore.domain.BookmarkBase;
23import com.freerdp.freerdpcore.presentation.ApplicationSettingsActivity;
24
25import java.util.ArrayList;
26import java.util.List;
27import java.util.Objects;
28import java.util.regex.Matcher;
29import java.util.regex.Pattern;
30
31public class LibFreeRDP
32{
33 private static final String TAG = "LibFreeRDP";
34 private static EventListener listener;
35 private static boolean mHasH264 = false;
36 private static boolean mHasCameraRedirection = false;
37
38 private static final LongSparseArray<Boolean> mInstanceState = new LongSparseArray<>();
39
40 public static final long VERIFY_CERT_FLAG_NONE = 0x00;
41 public static final long VERIFY_CERT_FLAG_LEGACY = 0x02;
42 public static final long VERIFY_CERT_FLAG_REDIRECT = 0x10;
43 public static final long VERIFY_CERT_FLAG_GATEWAY = 0x20;
44 public static final long VERIFY_CERT_FLAG_CHANGED = 0x40;
45 public static final long VERIFY_CERT_FLAG_MISMATCH = 0x80;
46 public static final long VERIFY_CERT_FLAG_MATCH_LEGACY_SHA1 = 0x100;
47 public static final long VERIFY_CERT_FLAG_FP_IS_PEM = 0x200;
48
49 // Keep in sync with android_freerdp.c.
50 public static final int EXPERIMENTAL_REMOTEAPP = 0;
51 public static final int EXPERIMENTAL_CAMERA = 1;
52
53 private static boolean tryLoad(String[] libraries)
54 {
55 boolean success = false;
56 final String LD_PATH = System.getProperty("java.library.path");
57 for (String lib : libraries)
58 {
59 try
60 {
61 Log.v(TAG, "Trying to load library " + lib + " from LD_PATH: " + LD_PATH);
62 System.loadLibrary(lib);
63 success = true;
64 }
65 catch (UnsatisfiedLinkError e)
66 {
67 Log.e(TAG, "Failed to load library " + lib + ": " + e);
68 success = false;
69 break;
70 }
71 }
72
73 return success;
74 }
75
76 private static boolean tryLoad(String library)
77 {
78 return tryLoad(new String[] { library });
79 }
80
81 static
82 {
83 try
84 {
85 System.loadLibrary("freerdp-android");
86
87 /* Load dependent libraries too to trigger JNI_OnLoad calls */
88 String version = freerdp_get_jni_version();
89 String[] versions = version.split("[\\.-]");
90 if (versions.length > 0)
91 {
92 System.loadLibrary("freerdp-client" + versions[0]);
93 System.loadLibrary("freerdp" + versions[0]);
94 System.loadLibrary("winpr" + versions[0]);
95 }
96 Pattern pattern = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+).*");
97 Matcher matcher = pattern.matcher(version);
98 if (!matcher.matches() || (matcher.groupCount() < 3))
99 throw new RuntimeException("APK broken: native library version " + version +
100 " does not meet requirements!");
101 int major = Integer.parseInt(Objects.requireNonNull(matcher.group(1)));
102 int minor = Integer.parseInt(Objects.requireNonNull(matcher.group(2)));
103 int patch = Integer.parseInt(Objects.requireNonNull(matcher.group(3)));
104
105 if (major > 2)
106 mHasH264 = freerdp_has_h264();
107 else if (minor > 5)
108 mHasH264 = freerdp_has_h264();
109 else if ((minor == 5) && (patch >= 1))
110 mHasH264 = freerdp_has_h264();
111 else
112 throw new RuntimeException("APK broken: native library version " + version +
113 " does not meet requirements!");
114 mHasCameraRedirection = freerdp_has_camera_redirection();
115 Log.i(TAG, "Successfully loaded native library. H264 is " +
116 (mHasH264 ? "supported" : "not available") + ", camera redirection is " +
117 (mHasCameraRedirection ? "supported" : "not available"));
118 }
119 catch (UnsatisfiedLinkError e)
120 {
121 Log.e(TAG, "Failed to load library: " + e);
122 throw e;
123 }
124 }
125
126 public static boolean hasH264Support()
127 {
128 return mHasH264;
129 }
130
131 public static boolean hasCameraRedirectionSupport()
132 {
133 return mHasCameraRedirection;
134 }
135
136 private static native boolean freerdp_has_h264();
137
138 private static native boolean freerdp_has_camera_redirection();
139
140 private static native String freerdp_get_jni_version();
141
142 private static native String freerdp_get_version();
143
144 private static native String freerdp_get_build_revision();
145
146 private static native String freerdp_get_build_config();
147
148 private static native long freerdp_new(Context context);
149
150 private static native void freerdp_free(long inst);
151
152 private static native boolean freerdp_parse_arguments(long inst, String[] args);
153
154 private static native boolean freerdp_connect(long inst);
155
156 private static native boolean freerdp_disconnect(long inst);
157
158 private static native boolean freerdp_update_graphics(long inst, Bitmap bitmap, int x, int y,
159 int width, int height);
160
161 private static native boolean freerdp_send_cursor_event(long inst, int x, int y, int flags);
162
163 private static native boolean freerdp_send_key_event(long inst, int keycode, boolean down);
164
165 private static native boolean freerdp_send_unicodekey_event(long inst, int keycode,
166 boolean down);
167
168 private static native boolean freerdp_is_unicode_input_supported(long inst);
169
170 private static native boolean freerdp_send_clipboard_data(long inst, String data);
171
172 private static native boolean freerdp_send_clipboard_image_data(long inst, byte[] data,
173 String mimeType);
174
175 private static native boolean freerdp_send_monitor_layout(long inst, int width, int height);
176
177 private static native String freerdp_get_last_error_string(long inst);
178
179 public static void setEventListener(EventListener l)
180 {
181 listener = l;
182 }
183
184 public static long newInstance(Context context)
185 {
186 return freerdp_new(context);
187 }
188
189 public static void freeInstance(long inst)
190 {
191 synchronized (mInstanceState)
192 {
193 if (mInstanceState.get(inst, false))
194 {
195 freerdp_disconnect(inst);
196 }
197 while (mInstanceState.get(inst, false))
198 {
199 try
200 {
201 mInstanceState.wait();
202 }
203 catch (InterruptedException e)
204 {
205 throw new RuntimeException();
206 }
207 }
208 }
209 freerdp_free(inst);
210 }
211
212 public static boolean connect(long inst)
213 {
214 synchronized (mInstanceState)
215 {
216 if (mInstanceState.get(inst, false))
217 {
218 throw new RuntimeException("instance already connected");
219 }
220 }
221 return freerdp_connect(inst);
222 }
223
224 public static boolean disconnect(long inst)
225 {
226 synchronized (mInstanceState)
227 {
228 if (mInstanceState.get(inst, false))
229 {
230 return freerdp_disconnect(inst);
231 }
232 return true;
233 }
234 }
235
236 public static boolean cancelConnection(long inst)
237 {
238 return freerdp_disconnect(inst);
239 }
240
241 private static String addFlag(String name, boolean enabled)
242 {
243 if (enabled)
244 {
245 return "+" + name;
246 }
247 return "-" + name;
248 }
249
250 public static boolean setConnectionInfo(Context context, long inst, BookmarkBase bookmark)
251 {
252 BookmarkBase.ScreenSettings screenSettings = bookmark.getActiveScreenSettings();
253 BookmarkBase.AdvancedSettings advanced = bookmark.getAdvancedSettings();
254 BookmarkBase.DebugSettings debug = bookmark.getDebugSettings();
255
256 String arg;
257 ArrayList<String> args = new ArrayList<>();
258
259 args.add(TAG);
260 args.add("/gdi:sw");
261
262 final String clientName = ApplicationSettingsActivity.getClientName(context);
263 if (!clientName.isEmpty())
264 {
265 args.add("/client-hostname:" + clientName);
266 }
267 String certName = "";
268 if (bookmark.getType() != BookmarkBase.TYPE_MANUAL)
269 {
270 return false;
271 }
272
273 int port = bookmark.getPort();
274 String hostname = bookmark.getHostname();
275
276 args.add("/v:" + hostname);
277 args.add("/port:" + port);
278
279 final int level = advanced.getTlsSecLevel();
280 List<String> tls = new ArrayList<>();
281
282 if (level >= 0)
283 {
284 tls.add("seclevel:" + level);
285 }
286
287 final int tlsMinLevel = advanced.getTlsMinLevel();
288 if (tlsMinLevel >= 0)
289 {
290 tls.add("enforce:" + tlsMinLevel);
291 }
292
293 if (!tls.isEmpty())
294 {
295 StringBuilder sb = new StringBuilder();
296 for (String s : tls)
297 {
298 if (sb.length() > 0)
299 {
300 sb.append(',');
301 }
302 sb.append(s);
303 }
304 args.add("/tls:" + sb);
305 }
306
307 arg = bookmark.getUsername();
308 if (!arg.isEmpty())
309 {
310 args.add("/u:" + arg);
311 }
312 arg = bookmark.getDomain();
313 if (!arg.isEmpty())
314 {
315 args.add("/d:" + arg);
316 }
317 arg = bookmark.getPassword();
318 if (!arg.isEmpty())
319 {
320 args.add("/p:" + arg);
321 }
322
323 args.add(String.format(java.util.Locale.US, "/size:%dx%d", screenSettings.getWidth(),
324 screenSettings.getHeight()));
325 args.add("/bpp:" + screenSettings.getColors());
326
327 if (screenSettings.isCustomScale())
328 {
329 args.add("/scale-desktop:" + screenSettings.getScaleDesktop());
330 args.add("/scale-device:" + screenSettings.getScaleDevice());
331 }
332 else
333 {
334 args.add("/scale:" + screenSettings.getScalePreset());
335 }
336
337 if (advanced.getConsoleMode())
338 {
339 args.add("/admin");
340 }
341
342 if (advanced.getVmConnectMode())
343 {
344 String guid = advanced.getVmConnectGuid();
345 if (!guid.isEmpty())
346 args.add("/vmconnect:" + guid);
347 else
348 args.add("/vmconnect");
349 }
350
351 switch (advanced.getSecurity())
352 {
353 case 3: // NLA
354 args.add("/sec:nla");
355 break;
356 case 2: // TLS
357 args.add("/sec:tls");
358 break;
359 case 1: // RDP
360 args.add("/sec:rdp");
361 break;
362 default:
363 break;
364 }
365
366 if (!certName.isEmpty())
367 {
368 args.add("/cert-name:" + certName);
369 }
370
371 BookmarkBase.PerformanceFlags flags = bookmark.getActivePerformanceFlags();
372 if (flags.getRemoteFX())
373 {
374 args.add("/rfx");
375 args.add("/network:auto");
376 }
377
378 if (flags.getGfx())
379 {
380 args.add("/gfx");
381 args.add("/network:auto");
382 }
383
384 if (flags.getH264() && mHasH264)
385 {
386 args.add("/gfx:AVC444");
387 args.add("/network:auto");
388 }
389
390 args.add(addFlag("wallpaper", flags.getWallpaper()));
391 args.add(addFlag("window-drag", flags.getFullWindowDrag()));
392 args.add(addFlag("menu-anims", flags.getMenuAnimations()));
393 args.add(addFlag("themes", flags.getTheming()));
394 args.add(addFlag("fonts", flags.getFontSmoothing()));
395 args.add(addFlag("aero", flags.getDesktopComposition()));
396
397 if (!advanced.getRemoteProgram().isEmpty())
398 {
399 args.add("/app:program:" + advanced.getRemoteProgram());
400 if (!advanced.getWorkDir().isEmpty())
401 args.add("/app:workdir:" + advanced.getWorkDir());
402 }
403 else
404 {
405 if (!advanced.getAlternateShell().isEmpty())
406 args.add("/shell:" + advanced.getAlternateShell());
407 if (!advanced.getWorkDir().isEmpty())
408 args.add("/shell-dir:" + advanced.getWorkDir());
409 }
410
411 args.add(addFlag("async-channels", debug.getAsyncChannel()));
412 args.add(addFlag("async-update", debug.getAsyncUpdate()));
413
414 if (advanced.getRedirectSDCard())
415 {
416 String path = android.os.Environment.getExternalStorageDirectory().getPath();
417 args.add("/drive:sdcard," + path);
418 }
419
420 String info = advanced.getLoadBalanceInfo();
421 if (!info.isEmpty())
422 {
423 args.add("/load-balance-info:" + info);
424 }
425 args.add("/clipboard");
426 args.add("/disp");
427
428 if (advanced.getRedirectPrinter())
429 args.add("/printer:aFreeRDP Print,Microsoft Print to PDF,default");
430
431 // Gateway enabled?
432 if (bookmark.getType() == BookmarkBase.TYPE_MANUAL && bookmark.getEnableGatewaySettings())
433 {
434 BookmarkBase.GatewaySettings gateway = bookmark.getGatewaySettings();
435
436 StringBuilder carg = new StringBuilder();
437 carg.append(String.format(java.util.Locale.US, "/gateway:g:%s:%d",
438 gateway.getHostname(), gateway.getPort()));
439
440 arg = gateway.getUsername();
441 if (!arg.isEmpty())
442 {
443 carg.append(",u:" + arg);
444 }
445 arg = gateway.getDomain();
446 if (!arg.isEmpty())
447 {
448 carg.append(",d:" + arg);
449 }
450 arg = gateway.getPassword();
451 if (!arg.isEmpty())
452 {
453 carg.append(",p:" + arg);
454 }
455 args.add(carg.toString());
456 }
457
458 /* 0 ... local
459 1 ... remote
460 2 ... disable */
461 args.add("/audio-mode:" + advanced.getRedirectSound());
462 if (advanced.getRedirectSound() == 0)
463 {
464 args.add("/sound");
465 }
466
467 if (advanced.getRedirectMicrophone())
468 {
469 args.add("/microphone");
470 }
471
472 if (advanced.getRedirectCamera() && mHasCameraRedirection)
473 {
474 args.add("/dvc:rdpecam");
475 }
476
477 args.add("/kbd:unicode:on");
478 args.add("/cert:ignore");
479 args.add("/log-level:" + debug.getDebugLevel());
480 String[] arrayArgs = args.toArray(new String[0]);
481 return freerdp_parse_arguments(inst, arrayArgs);
482 }
483
484 public static boolean setConnectionInfo(Context context, long inst, Uri openUri)
485 {
486 ArrayList<String> args = new ArrayList<>();
487
488 // Parse URI from query string. Same key overwrite previous one
489 // freerdp://user@ip:port/connect?sound=&rfx=&p=password&clipboard=%2b&themes=-
490
491 // Now we only support Software GDI
492 args.add(TAG);
493 args.add("/gdi:sw");
494
495 final String clientName = ApplicationSettingsActivity.getClientName(context);
496 if (!clientName.isEmpty())
497 {
498 args.add("/client-hostname:" + clientName);
499 }
500
501 // Parse hostname and port. Set to 'v' argument
502 String hostname = openUri.getHost();
503 int port = openUri.getPort();
504 if (hostname != null)
505 {
506 hostname = hostname + ((port == -1) ? "" : (":" + port));
507 args.add("/v:" + hostname);
508 }
509
510 String user = openUri.getUserInfo();
511 if (user != null)
512 {
513 args.add("/u:" + user);
514 }
515
516 for (String key : openUri.getQueryParameterNames())
517 {
518 String value = openUri.getQueryParameter(key);
519
520 if (value.isEmpty())
521 {
522 // Query: key=
523 // To freerdp argument: /key
524 args.add("/" + key);
525 }
526 else if (value.equals("-") || value.equals("+"))
527 {
528 // Query: key=- or key=+
529 // To freerdp argument: -key or +key
530 args.add(value + key);
531 }
532 else
533 {
534 // Query: key=value
535 // To freerdp argument: /key:value
536 if (key.equals("drive") && value.equals("sdcard"))
537 {
538 // Special for sdcard redirect
539 String path = android.os.Environment.getExternalStorageDirectory().getPath();
540 value = "sdcard," + path;
541 }
542
543 args.add("/" + key + ":" + value);
544 }
545 }
546
547 String[] arrayArgs = args.toArray(new String[0]);
548 return freerdp_parse_arguments(inst, arrayArgs);
549 }
550
551 public static boolean updateGraphics(long inst, Bitmap bitmap, int x, int y, int width,
552 int height)
553 {
554 return freerdp_update_graphics(inst, bitmap, x, y, width, height);
555 }
556
557 public static boolean sendCursorEvent(long inst, int x, int y, int flags)
558 {
559 return freerdp_send_cursor_event(inst, x, y, flags);
560 }
561
562 public static boolean sendKeyEvent(long inst, int keycode, boolean down)
563 {
564 return freerdp_send_key_event(inst, keycode, down);
565 }
566
567 public static boolean sendUnicodeKeyEvent(long inst, int keycode, boolean down)
568 {
569 return freerdp_send_unicodekey_event(inst, keycode, down);
570 }
571
572 public static boolean isUnicodeInputSupported(long inst)
573 {
574 return freerdp_is_unicode_input_supported(inst);
575 }
576
577 public static boolean sendClipboardData(long inst, String data)
578 {
579 return freerdp_send_clipboard_data(inst, data);
580 }
581
582 public static boolean sendClipboardImageData(long inst, byte[] data, String mimeType)
583 {
584 return freerdp_send_clipboard_image_data(inst, data, mimeType);
585 }
586
587 public static boolean sendMonitorLayout(long inst, int width, int height)
588 {
589 return freerdp_send_monitor_layout(inst, width, height);
590 }
591
592 private static void OnConnectionSuccess(long inst)
593 {
594 if (listener != null)
595 listener.OnConnectionSuccess(inst);
596 synchronized (mInstanceState)
597 {
598 mInstanceState.append(inst, true);
599 mInstanceState.notifyAll();
600 }
601 }
602
603 private static void OnConnectionFailure(long inst)
604 {
605 if (listener != null)
606 listener.OnConnectionFailure(inst);
607 synchronized (mInstanceState)
608 {
609 mInstanceState.remove(inst);
610 mInstanceState.notifyAll();
611 }
612 }
613
614 private static void OnPreConnect(long inst)
615 {
616 if (listener != null)
617 listener.OnPreConnect(inst);
618 }
619
620 private static void OnDisconnecting(long inst)
621 {
622 if (listener != null)
623 listener.OnDisconnecting(inst);
624 }
625
626 private static void OnDisconnected(long inst)
627 {
628 if (listener != null)
629 listener.OnDisconnected(inst);
630 synchronized (mInstanceState)
631 {
632 mInstanceState.remove(inst);
633 mInstanceState.notifyAll();
634 }
635 }
636
637 private static void OnSettingsChanged(long inst, int width, int height, int bpp)
638 {
639 SessionState s = GlobalApp.getSession(inst);
640 if (s == null)
641 return;
642 UIEventListener uiEventListener = s.getUIEventListener();
643 if (uiEventListener != null)
644 uiEventListener.OnSettingsChanged(width, height, bpp);
645 }
646
647 private static boolean OnAuthenticate(long inst, StringBuilder username, StringBuilder domain,
648 StringBuilder password)
649 {
650 SessionState s = GlobalApp.getSession(inst);
651 if (s == null)
652 return false;
653 UIEventListener uiEventListener = s.getUIEventListener();
654 if (uiEventListener != null)
655 return uiEventListener.OnAuthenticate(username, domain, password);
656 return false;
657 }
658
659 private static boolean OnGatewayAuthenticate(long inst, StringBuilder username,
660 StringBuilder domain, StringBuilder password)
661 {
662 SessionState s = GlobalApp.getSession(inst);
663 if (s == null)
664 return false;
665 UIEventListener uiEventListener = s.getUIEventListener();
666 if (uiEventListener != null)
667 return uiEventListener.OnGatewayAuthenticate(username, domain, password);
668 return false;
669 }
670
671 private static int OnVerifyCertificateEx(long inst, String host, long port, String commonName,
672 String subject, String issuer, String fingerprint,
673 long flags)
674 {
675 SessionState s = GlobalApp.getSession(inst);
676 if (s == null)
677 return 0;
678 UIEventListener uiEventListener = s.getUIEventListener();
679 if (uiEventListener != null)
680 return uiEventListener.OnVerifiyCertificateEx(host, port, commonName, subject, issuer,
681 fingerprint, flags);
682 return 0;
683 }
684
685 private static int OnVerifyChangedCertificateEx(long inst, String host, long port,
686 String commonName, String subject,
687 String issuer, String fingerprint,
688 String oldSubject, String oldIssuer,
689 String oldFingerprint, long flags)
690 {
691 SessionState s = GlobalApp.getSession(inst);
692 if (s == null)
693 return 0;
694 UIEventListener uiEventListener = s.getUIEventListener();
695 if (uiEventListener != null)
696 return uiEventListener.OnVerifyChangedCertificateEx(host, port, commonName, subject,
697 issuer, fingerprint, oldSubject,
698 oldIssuer, oldFingerprint, flags);
699 return 0;
700 }
701
702 private static boolean OnExperimentalFeature(long inst, int feature)
703 {
704 SessionState s = GlobalApp.getSession(inst);
705 if (s == null)
706 return true;
707 UIEventListener uiEventListener = s.getUIEventListener();
708 if (uiEventListener == null)
709 return true;
710 return uiEventListener.OnExperimentalFeature(feature);
711 }
712
713 private static void OnGraphicsUpdate(long inst, int x, int y, int width, int height)
714 {
715 SessionState s = GlobalApp.getSession(inst);
716 if (s == null)
717 return;
718 UIEventListener uiEventListener = s.getUIEventListener();
719 if (uiEventListener != null)
720 uiEventListener.OnGraphicsUpdate(x, y, width, height);
721 }
722
723 private static void OnGraphicsResize(long inst, int width, int height, int bpp)
724 {
725 SessionState s = GlobalApp.getSession(inst);
726 if (s == null)
727 return;
728 UIEventListener uiEventListener = s.getUIEventListener();
729 if (uiEventListener != null)
730 uiEventListener.OnGraphicsResize(width, height, bpp);
731 }
732
733 private static void OnRemoteClipboardChanged(long inst, String data)
734 {
735 SessionState s = GlobalApp.getSession(inst);
736 if (s == null)
737 return;
738 UIEventListener uiEventListener = s.getUIEventListener();
739 if (uiEventListener != null)
740 uiEventListener.OnRemoteClipboardChanged(data);
741 }
742
743 private static void OnRemoteClipboardImageChanged(long inst, byte[] data)
744 {
745 SessionState s = GlobalApp.getSession(inst);
746 if (s == null)
747 return;
748 UIEventListener uiEventListener = s.getUIEventListener();
749 if (uiEventListener != null)
750 uiEventListener.OnRemoteClipboardImageChanged(data);
751 }
752
753 private static void OnPointerSet(long inst, int[] pixels, int width, int height, int hotX,
754 int hotY)
755 {
756 SessionState s = GlobalApp.getSession(inst);
757 if (s == null)
758 return;
759 UIEventListener uiEventListener = s.getUIEventListener();
760 if (uiEventListener != null)
761 uiEventListener.OnPointerSet(pixels, width, height, hotX, hotY);
762 }
763
764 private static void OnPointerSetNull(long inst)
765 {
766 SessionState s = GlobalApp.getSession(inst);
767 if (s == null)
768 return;
769 UIEventListener uiEventListener = s.getUIEventListener();
770 if (uiEventListener != null)
771 uiEventListener.OnPointerSetNull();
772 }
773
774 private static void OnPointerSetDefault(long inst)
775 {
776 SessionState s = GlobalApp.getSession(inst);
777 if (s == null)
778 return;
779 UIEventListener uiEventListener = s.getUIEventListener();
780 if (uiEventListener != null)
781 uiEventListener.OnPointerSetDefault();
782 }
783
784 private static void OnRailWindowUpdate(long inst, long windowId, int width, int height,
785 int[] pixels)
786 {
787 SessionState s = GlobalApp.getSession(inst);
788 if (s == null)
789 return;
790 UIEventListener uiEventListener = s.getUIEventListener();
791 if (uiEventListener != null)
792 uiEventListener.OnRailWindowUpdate(windowId, width, height, pixels);
793 }
794
795 private static void OnRailWindowMove(long inst, long windowId, int x, int y, int w, int h)
796 {
797 SessionState s = GlobalApp.getSession(inst);
798 if (s == null)
799 return;
800 UIEventListener uiEventListener = s.getUIEventListener();
801 if (uiEventListener != null)
802 uiEventListener.OnRailWindowMove(windowId, x, y, w, h);
803 }
804
805 private static void OnRailWindowHide(long inst, long windowId)
806 {
807 SessionState s = GlobalApp.getSession(inst);
808 if (s == null)
809 return;
810 UIEventListener uiEventListener = s.getUIEventListener();
811 if (uiEventListener != null)
812 uiEventListener.OnRailWindowHide(windowId);
813 }
814
815 private static void OnRailWindowDestroy(long inst, long windowId)
816 {
817 SessionState s = GlobalApp.getSession(inst);
818 if (s == null)
819 return;
820 UIEventListener uiEventListener = s.getUIEventListener();
821 if (uiEventListener != null)
822 uiEventListener.OnRailWindowDestroy(windowId);
823 }
824
825 private static void OnRailSessionEnd(long inst)
826 {
827 SessionState s = GlobalApp.getSession(inst);
828 if (s == null)
829 return;
830 UIEventListener uiEventListener = s.getUIEventListener();
831 if (uiEventListener != null)
832 uiEventListener.OnRailSessionEnd();
833 }
834
835 private static void OnRailMonitoredDesktop(long inst, long[] windowIds, long activeWindowId)
836 {
837 SessionState s = GlobalApp.getSession(inst);
838 if (s == null)
839 return;
840 UIEventListener uiEventListener = s.getUIEventListener();
841 if (uiEventListener != null)
842 uiEventListener.OnRailMonitoredDesktop(windowIds, activeWindowId);
843 }
844
845 public static String getVersion()
846 {
847 return freerdp_get_version();
848 }
849
850 public interface EventListener
851 {
852 void OnPreConnect(long instance);
853
854 void OnConnectionSuccess(long instance);
855
856 void OnConnectionFailure(long instance);
857
858 void OnDisconnecting(long instance);
859
860 void OnDisconnected(long instance);
861 }
862
863 public interface UIEventListener
864 {
865 void OnSettingsChanged(int width, int height, int bpp);
866
867 boolean OnAuthenticate(StringBuilder username, StringBuilder domain,
868 StringBuilder password);
869
870 boolean OnGatewayAuthenticate(StringBuilder username, StringBuilder domain,
871 StringBuilder password);
872
873 int OnVerifiyCertificateEx(String host, long port, String commonName, String subject, String issuer,
874 String fingerprint, long flags);
875
876 int OnVerifyChangedCertificateEx(String host, long port, String commonName, String subject, String issuer,
877 String fingerprint, String oldSubject, String oldIssuer,
878 String oldFingerprint, long flags);
879
880 boolean OnExperimentalFeature(int feature);
881
882 void OnGraphicsUpdate(int x, int y, int width, int height);
883
884 void OnGraphicsResize(int width, int height, int bpp);
885
886 void OnRemoteClipboardChanged(String data);
887
888 void OnRemoteClipboardImageChanged(byte[] data);
889
890 void OnPointerSet(int[] pixels, int width, int height, int hotX, int hotY);
891
892 void OnPointerSetNull();
893
894 void OnPointerSetDefault();
895
896 void OnRailWindowUpdate(long windowId, int width, int height, int[] pixels);
897
898 void OnRailWindowMove(long windowId, int x, int y, int w, int h);
899
900 void OnRailWindowHide(long windowId);
901
902 void OnRailWindowDestroy(long windowId);
903
904 void OnRailSessionEnd();
905
906 void OnRailMonitoredDesktop(long[] windowIds, long activeWindowId);
907 }
908}