73 implements LibFreeRDP.UIEventListener, KeyboardView.OnKeyboardActionListener,
74 ScrollView2D.ScrollView2DListener, KeyboardMapper.KeyProcessingListener,
76 ClipboardManagerProxy.OnClipboardChangedListener
78 public static final String PARAM_CONNECTION_REFERENCE =
"conRef";
79 public static final String PARAM_INSTANCE =
"instance";
80 private static final float ZOOMING_STEP = 0.5f;
81 private static final int ZOOMCONTROLS_AUTOHIDE_TIMEOUT = 4000;
84 private static final int SCROLLING_TIMEOUT = 50;
85 private static final int SCROLLING_DISTANCE = 20;
86 private static final String TAG =
"FreeRDP.SessionActivity";
88 private static final int MAX_DISCARDED_MOVE_EVENTS = 3;
89 private static final int SEND_MOVE_EVENT_TIMEOUT = 150;
90 private Bitmap bitmap;
91 private SessionState session;
94 private ProgressDialog progressDialog;
95 private KeyboardView keyboardView;
96 private KeyboardView modifiersKeyboardView;
97 private ZoomControls zoomControls;
98 private KeyboardMapper keyboardMapper;
100 private Keyboard specialkeysKeyboard;
101 private Keyboard numpadKeyboard;
102 private Keyboard cursorKeyboard;
103 private Keyboard modifiersKeyboard;
105 private AlertDialog dlgVerifyCertificate;
106 private AlertDialog dlgUserCredentials;
107 private View userCredView;
109 private UIHandler uiHandler;
111 private int screen_width;
112 private int screen_height;
114 private boolean connectCancelledByUser =
false;
115 private boolean sessionRunning =
false;
116 private boolean toggleMouseButtons =
false;
118 private LibFreeRDPBroadcastReceiver libFreeRDPBroadcastReceiver;
121 private boolean sysKeyboardVisible =
false;
122 private boolean extKeyboardVisible =
false;
123 private int discardedMoveEvents = 0;
124 private ClipboardManagerProxy mClipboardManager;
125 private boolean callbackDialogResult;
128 private void createDialogs()
131 dlgVerifyCertificate =
132 new AlertDialog.Builder(
this)
133 .setTitle(R.string.dlg_title_verify_certificate)
134 .setPositiveButton(android.R.string.yes,
135 new DialogInterface.OnClickListener() {
137 public void onClick(DialogInterface dialog, int which)
139 callbackDialogResult = true;
140 synchronized (dialog)
146 .setNegativeButton(android.R.string.no,
147 new DialogInterface.OnClickListener() {
149 public void onClick(DialogInterface dialog, int which)
151 callbackDialogResult = false;
152 connectCancelledByUser = true;
153 synchronized (dialog)
159 .setCancelable(
false)
163 userCredView = getLayoutInflater().inflate(R.layout.credentials,
null,
true);
165 new AlertDialog.Builder(
this)
166 .setView(userCredView)
167 .setTitle(R.string.dlg_title_credentials)
168 .setPositiveButton(android.R.string.ok,
169 new DialogInterface.OnClickListener() {
171 public void onClick(DialogInterface dialog, int which)
173 callbackDialogResult = true;
174 synchronized (dialog)
180 .setNegativeButton(android.R.string.cancel,
181 new DialogInterface.OnClickListener() {
183 public void onClick(DialogInterface dialog, int which)
185 callbackDialogResult = false;
186 connectCancelledByUser = true;
187 synchronized (dialog)
193 .setCancelable(
false)
197 private boolean hasHardwareMenuButton()
199 if (Build.VERSION.SDK_INT <= 10)
202 if (Build.VERSION.SDK_INT >= 14)
205 final ViewConfiguration cfg = ViewConfiguration.get(
this);
207 return cfg.hasPermanentMenuKey();
213 @Override
public void onCreate(Bundle savedInstanceState)
215 super.onCreate(savedInstanceState);
218 if (ApplicationSettingsActivity.getHideStatusBar(
this))
220 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
221 WindowManager.LayoutParams.FLAG_FULLSCREEN);
224 this.setContentView(R.layout.session);
225 if (hasHardwareMenuButton() || ApplicationSettingsActivity.getHideActionBar(
this))
227 this.getSupportActionBar().hide();
230 this.getSupportActionBar().show();
232 Log.v(TAG,
"Session.onCreate");
241 final View activityRootView = findViewById(R.id.session_root_view);
242 activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
243 new OnGlobalLayoutListener() {
244 @Override
public void onGlobalLayout()
246 screen_width = activityRootView.getWidth();
247 screen_height = activityRootView.getHeight();
250 if (!sessionRunning && getIntent() !=
null)
252 processIntent(getIntent());
253 sessionRunning =
true;
258 sessionView = findViewById(R.id.sessionView);
259 sessionView.setScaleGestureDetector(
260 new ScaleGestureDetector(
this,
new PinchZoomListener()));
261 sessionView.setSessionViewListener(
this);
262 sessionView.requestFocus();
264 touchPointerView = findViewById(R.id.touchPointerView);
265 touchPointerView.setTouchPointerListener(
this);
267 keyboardMapper =
new KeyboardMapper();
268 keyboardMapper.init(
this);
269 keyboardMapper.reset(
this);
271 modifiersKeyboard =
new Keyboard(getApplicationContext(), R.xml.modifiers_keyboard);
272 specialkeysKeyboard =
new Keyboard(getApplicationContext(), R.xml.specialkeys_keyboard);
273 numpadKeyboard =
new Keyboard(getApplicationContext(), R.xml.numpad_keyboard);
274 cursorKeyboard =
new Keyboard(getApplicationContext(), R.xml.cursor_keyboard);
277 keyboardView = findViewById(R.id.extended_keyboard);
278 keyboardView.setKeyboard(specialkeysKeyboard);
279 keyboardView.setOnKeyboardActionListener(
this);
281 modifiersKeyboardView = findViewById(R.id.extended_keyboard_header);
282 modifiersKeyboardView.setKeyboard(modifiersKeyboard);
283 modifiersKeyboardView.setOnKeyboardActionListener(
this);
285 scrollView = findViewById(R.id.sessionScrollView);
286 scrollView.setScrollViewListener(
this);
287 uiHandler =
new UIHandler();
288 libFreeRDPBroadcastReceiver =
new LibFreeRDPBroadcastReceiver();
290 zoomControls = findViewById(R.id.zoomControls);
292 zoomControls.setOnZoomInClickListener(
new View.OnClickListener() {
293 @Override public void onClick(View v)
295 resetZoomControlsAutoHideTimeout();
296 zoomControls.setIsZoomInEnabled(sessionView.zoomIn(ZOOMING_STEP));
297 zoomControls.setIsZoomOutEnabled(true);
300 zoomControls.setOnZoomOutClickListener(
new View.OnClickListener() {
301 @Override public void onClick(View v)
303 resetZoomControlsAutoHideTimeout();
304 zoomControls.setIsZoomOutEnabled(sessionView.zoomOut(ZOOMING_STEP));
305 zoomControls.setIsZoomInEnabled(true);
309 toggleMouseButtons =
false;
314 IntentFilter filter =
new IntentFilter();
315 filter.addAction(GlobalApp.ACTION_EVENT_FREERDP);
316 registerReceiver(libFreeRDPBroadcastReceiver, filter, RECEIVER_EXPORTED);
318 mClipboardManager = ClipboardManagerProxy.getClipboardManager(
this);
319 mClipboardManager.addClipboardChangedListener(
this);
321 mDecor = getWindow().getDecorView();
322 mDecor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
323 View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
326 @Override
public void onWindowFocusChanged(
boolean hasFocus)
328 super.onWindowFocusChanged(hasFocus);
329 mClipboardManager.getPrimaryClipManually();
332 @Override
protected void onStart()
335 Log.v(TAG,
"Session.onStart");
338 @Override
protected void onRestart()
341 Log.v(TAG,
"Session.onRestart");
344 @Override
protected void onResume()
347 Log.v(TAG,
"Session.onResume");
350 @Override
protected void onPause()
353 Log.v(TAG,
"Session.onPause");
356 showKeyboard(
false,
false);
359 @Override
protected void onStop()
362 Log.v(TAG,
"Session.onStop");
365 @Override
protected void onDestroy()
367 if (connectThread !=
null)
369 connectThread.interrupt();
372 Log.v(TAG,
"Session.onDestroy");
375 GlobalApp.cancelDisconnectTimer();
378 Collection<SessionState> sessions = GlobalApp.getSessions();
379 for (SessionState session : sessions)
380 LibFreeRDP.disconnect(session.getInstance());
383 unregisterReceiver(libFreeRDPBroadcastReceiver);
386 mClipboardManager.removeClipboardboardChangedListener(
this);
389 GlobalApp.freeSession(session.getInstance());
394 @Override
public void onConfigurationChanged(Configuration newConfig)
396 super.onConfigurationChanged(newConfig);
399 modifiersKeyboard =
new Keyboard(getApplicationContext(), R.xml.modifiers_keyboard);
400 specialkeysKeyboard =
new Keyboard(getApplicationContext(), R.xml.specialkeys_keyboard);
401 numpadKeyboard =
new Keyboard(getApplicationContext(), R.xml.numpad_keyboard);
402 cursorKeyboard =
new Keyboard(getApplicationContext(), R.xml.cursor_keyboard);
405 keyboardView.setKeyboard(specialkeysKeyboard);
406 modifiersKeyboardView.setKeyboard(modifiersKeyboard);
408 mDecor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
409 View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
412 private void processIntent(Intent intent)
415 Bundle bundle = intent.getExtras();
416 Uri openUri = intent.getData();
423 else if (bundle.containsKey(PARAM_INSTANCE))
425 int inst = bundle.getInt(PARAM_INSTANCE);
426 session = GlobalApp.getSession(inst);
427 bitmap = session.getSurface().getBitmap();
430 else if (bundle.containsKey(PARAM_CONNECTION_REFERENCE))
432 BookmarkBase bookmark =
null;
433 String refStr = bundle.getString(PARAM_CONNECTION_REFERENCE);
434 if (ConnectionReference.isHostnameReference(refStr))
436 bookmark =
new ManualBookmark();
437 bookmark.<ManualBookmark>
get().setHostname(ConnectionReference.getHostname(refStr));
439 else if (ConnectionReference.isBookmarkReference(refStr))
441 if (ConnectionReference.isManualBookmarkReference(refStr))
442 bookmark = GlobalApp.getManualBookmarkGateway().findById(
443 ConnectionReference.getManualBookmarkId(refStr));
448 if (bookmark !=
null)
451 closeSessionActivity(RESULT_CANCELED);
456 closeSessionActivity(RESULT_CANCELED);
460 private void connect(BookmarkBase bookmark)
462 session = GlobalApp.createSession(bookmark, getApplicationContext());
464 BookmarkBase.ScreenSettings screenSettings =
465 session.getBookmark().getActiveScreenSettings();
466 Log.v(TAG,
"Screen Resolution: " + screenSettings.getResolutionString());
467 if (screenSettings.isAutomatic())
469 if ((getResources().getConfiguration().screenLayout &
470 Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE)
473 screenSettings.setHeight(screen_height);
474 screenSettings.setWidth(screen_width);
481 int screenMax = Math.max(screen_width, screen_height);
482 screenSettings.setHeight(screenMax);
483 screenSettings.setWidth((
int)((
float)screenMax * 1.6f));
486 if (screenSettings.isFitScreen())
488 screenSettings.setHeight(screen_height);
489 screenSettings.setWidth(screen_width);
492 connectWithTitle(bookmark.getLabel());
495 private void connect(Uri openUri)
497 session = GlobalApp.createSession(openUri, getApplicationContext());
499 connectWithTitle(openUri.getAuthority());
502 static class ConnectThread
extends Thread
504 private final SessionState runnableSession;
505 private final Context context;
507 public ConnectThread(@NonNull Context context, @NonNull SessionState session)
509 this.context = context;
510 runnableSession = session;
515 runnableSession.connect(context.getApplicationContext());
519 private ConnectThread connectThread =
null;
521 private void connectWithTitle(String title)
523 session.setUIEventListener(
this);
525 progressDialog =
new ProgressDialog(
this);
526 progressDialog.setTitle(title);
527 progressDialog.setMessage(getResources().getText(R.string.dlg_msg_connecting));
528 progressDialog.setButton(
529 ProgressDialog.BUTTON_NEGATIVE,
"Cancel",
new DialogInterface.OnClickListener() {
530 @Override public void onClick(DialogInterface dialog, int which)
532 connectCancelledByUser = true;
533 LibFreeRDP.cancelConnection(session.getInstance());
536 progressDialog.setCancelable(
false);
537 progressDialog.show();
539 connectThread =
new ConnectThread(getApplicationContext(), session);
540 connectThread.start();
545 private void bindSession()
547 Log.v(TAG,
"bindSession called");
548 session.setUIEventListener(
this);
549 sessionView.onSurfaceChange(session);
550 scrollView.requestLayout();
551 keyboardMapper.reset(
this);
552 mDecor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
553 View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
556 private void setSoftInputState(
boolean state)
558 InputMethodManager mgr = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
562 mgr.showSoftInput(sessionView, InputMethodManager.SHOW_FORCED);
566 mgr.hideSoftInputFromWindow(sessionView.getWindowToken(), 0);
571 private void showKeyboard(
final boolean showSystemKeyboard,
final boolean showExtendedKeyboard)
576 uiHandler.removeMessages(UIHandler.SHOW_ZOOMCONTROLS);
577 uiHandler.sendEmptyMessage(UIHandler.HIDE_ZOOMCONTROLS);
579 InputMethodManager mgr = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
581 if (showSystemKeyboard)
584 keyboardView.setVisibility(View.GONE);
586 setSoftInputState(
true);
589 modifiersKeyboardView.setVisibility(View.VISIBLE);
591 else if (showExtendedKeyboard)
594 setSoftInputState(
false);
597 keyboardView.setKeyboard(specialkeysKeyboard);
598 keyboardView.setVisibility(View.VISIBLE);
599 modifiersKeyboardView.setVisibility(View.VISIBLE);
604 setSoftInputState(
false);
605 keyboardView.setVisibility(View.GONE);
606 modifiersKeyboardView.setVisibility(View.GONE);
609 keyboardMapper.clearlAllModifiers();
612 sysKeyboardVisible = showSystemKeyboard;
613 extKeyboardVisible = showExtendedKeyboard;
616 private void closeSessionActivity(
int resultCode)
619 setResult(resultCode, getIntent());
624 private void updateModifierKeyStates()
628 List<Keyboard.Key> keys = modifiersKeyboard.getKeys();
629 for (Keyboard.Key curKey : keys)
634 switch (keyboardMapper.getModifierState(curKey.codes[0]))
636 case KeyboardMapper.KEYSTATE_ON:
638 curKey.pressed =
false;
641 case KeyboardMapper.KEYSTATE_OFF:
643 curKey.pressed =
false;
646 case KeyboardMapper.KEYSTATE_LOCKED:
648 curKey.pressed =
true;
655 modifiersKeyboardView.invalidateAllKeys();
658 private void sendDelayedMoveEvent(
int x,
int y)
660 if (uiHandler.hasMessages(UIHandler.SEND_MOVE_EVENT))
662 uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
663 discardedMoveEvents++;
666 discardedMoveEvents = 0;
668 if (discardedMoveEvents > MAX_DISCARDED_MOVE_EVENTS)
669 LibFreeRDP.sendCursorEvent(session.getInstance(), x, y, Mouse.getMoveEvent());
671 uiHandler.sendMessageDelayed(Message.obtain(
null, UIHandler.SEND_MOVE_EVENT, x, y),
672 SEND_MOVE_EVENT_TIMEOUT);
675 private void cancelDelayedMoveEvent()
677 uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
680 @Override
public boolean onCreateOptionsMenu(Menu menu)
682 getMenuInflater().inflate(R.menu.session_menu, menu);
686 @Override
public boolean onOptionsItemSelected(MenuItem item)
690 int itemId = item.getItemId();
692 if (itemId == R.id.session_touch_pointer)
695 if (touchPointerView.getVisibility() == View.VISIBLE)
697 touchPointerView.setVisibility(View.INVISIBLE);
698 sessionView.setTouchPointerPadding(0, 0);
702 touchPointerView.setVisibility(View.VISIBLE);
703 sessionView.setTouchPointerPadding(touchPointerView.getPointerWidth(),
704 touchPointerView.getPointerHeight());
707 else if (itemId == R.id.session_sys_keyboard)
709 showKeyboard(!sysKeyboardVisible,
false);
711 else if (itemId == R.id.session_ext_keyboard)
713 showKeyboard(
false, !extKeyboardVisible);
715 else if (itemId == R.id.session_disconnect)
717 showKeyboard(
false,
false);
718 LibFreeRDP.disconnect(session.getInstance());
724 @Override
public void onBackPressed()
727 if (sysKeyboardVisible || extKeyboardVisible)
728 showKeyboard(
false,
false);
729 else if (ApplicationSettingsActivity.getUseBackAsAltf4(
this))
731 keyboardMapper.sendAltF4();
735 @Override
public boolean onKeyLongPress(
int keyCode, KeyEvent event)
737 if (keyCode == KeyEvent.KEYCODE_BACK)
739 LibFreeRDP.disconnect(session.getInstance());
742 return super.onKeyLongPress(keyCode, event);
751 @Override
public boolean onKeyDown(
int keycode, KeyEvent event)
753 return keyboardMapper.processAndroidKeyEvent(event);
756 @Override
public boolean onKeyUp(
int keycode, KeyEvent event)
758 return keyboardMapper.processAndroidKeyEvent(event);
763 @Override
public boolean onKeyMultiple(
int keyCode,
int repeatCount, KeyEvent event)
765 return keyboardMapper.processAndroidKeyEvent(event);
770 @Override
public void onKey(
int primaryCode,
int[] keyCodes)
772 keyboardMapper.processCustomKeyEvent(primaryCode);
775 @Override
public void onText(CharSequence text)
779 @Override
public void swipeRight()
783 @Override
public void swipeLeft()
787 @Override
public void swipeDown()
791 @Override
public void swipeUp()
795 @Override
public void onPress(
int primaryCode)
799 @Override
public void onRelease(
int primaryCode)
805 @Override
public void processVirtualKey(
int virtualKeyCode,
boolean down)
807 LibFreeRDP.sendKeyEvent(session.getInstance(), virtualKeyCode, down);
810 @Override
public void processUnicodeKey(
int unicodeKey)
812 LibFreeRDP.sendUnicodeKeyEvent(session.getInstance(), unicodeKey,
true);
813 LibFreeRDP.sendUnicodeKeyEvent(session.getInstance(), unicodeKey,
false);
816 @Override
public void switchKeyboard(
int keyboardType)
818 switch (keyboardType)
820 case KeyboardMapper.KEYBOARD_TYPE_FUNCTIONKEYS:
821 keyboardView.setKeyboard(specialkeysKeyboard);
824 case KeyboardMapper.KEYBOARD_TYPE_NUMPAD:
825 keyboardView.setKeyboard(numpadKeyboard);
828 case KeyboardMapper.KEYBOARD_TYPE_CURSOR:
829 keyboardView.setKeyboard(cursorKeyboard);
837 @Override
public void modifiersChanged()
839 updateModifierKeyStates();
844 @Override
public void OnSettingsChanged(
int width,
int height,
int bpp)
848 bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
850 bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
852 session.setSurface(
new BitmapDrawable(getResources(), bitmap));
854 if (session.getBookmark() ==
null)
865 BookmarkBase.ScreenSettings settings = session.getBookmark().getActiveScreenSettings();
866 if ((settings.getWidth() != width && settings.getWidth() != width + 1) ||
867 settings.getHeight() != height || settings.getColors() != bpp)
868 uiHandler.sendMessage(
869 Message.obtain(
null, UIHandler.DISPLAY_TOAST,
870 getResources().getText(R.string.info_capabilities_changed)));
873 @Override
public void OnGraphicsUpdate(
int x,
int y,
int width,
int height)
875 LibFreeRDP.updateGraphics(session.getInstance(), bitmap, x, y, width, height);
877 sessionView.addInvalidRegion(
new Rect(x, y, x + width, y + height));
884 uiHandler.sendEmptyMessage(UIHandler.REFRESH_SESSIONVIEW);
887 @Override
public void OnGraphicsResize(
int width,
int height,
int bpp)
891 bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
893 bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
894 session.setSurface(
new BitmapDrawable(getResources(), bitmap));
900 uiHandler.sendEmptyMessage(UIHandler.GRAPHICS_CHANGED);
904 public boolean OnAuthenticate(StringBuilder username, StringBuilder domain,
905 StringBuilder password)
908 callbackDialogResult =
false;
911 ((EditText)userCredView.findViewById(R.id.editTextUsername)).setText(username);
912 ((EditText)userCredView.findViewById(R.id.editTextDomain)).setText(domain);
913 ((EditText)userCredView.findViewById(R.id.editTextPassword)).setText(password);
916 uiHandler.sendMessage(Message.obtain(
null, UIHandler.SHOW_DIALOG, dlgUserCredentials));
921 synchronized (dlgUserCredentials)
923 dlgUserCredentials.wait();
926 catch (InterruptedException e)
931 username.setLength(0);
933 password.setLength(0);
937 ((EditText)userCredView.findViewById(R.id.editTextUsername)).getText().toString());
939 ((EditText)userCredView.findViewById(R.id.editTextDomain)).getText().toString());
941 ((EditText)userCredView.findViewById(R.id.editTextPassword)).getText().toString());
943 return callbackDialogResult;
947 public boolean OnGatewayAuthenticate(StringBuilder username, StringBuilder domain,
948 StringBuilder password)
951 callbackDialogResult =
false;
954 ((EditText)userCredView.findViewById(R.id.editTextUsername)).setText(username);
955 ((EditText)userCredView.findViewById(R.id.editTextDomain)).setText(domain);
956 ((EditText)userCredView.findViewById(R.id.editTextPassword)).setText(password);
959 uiHandler.sendMessage(Message.obtain(
null, UIHandler.SHOW_DIALOG, dlgUserCredentials));
964 synchronized (dlgUserCredentials)
966 dlgUserCredentials.wait();
969 catch (InterruptedException e)
974 username.setLength(0);
976 password.setLength(0);
980 ((EditText)userCredView.findViewById(R.id.editTextUsername)).getText().toString());
982 ((EditText)userCredView.findViewById(R.id.editTextDomain)).getText().toString());
984 ((EditText)userCredView.findViewById(R.id.editTextPassword)).getText().toString());
986 return callbackDialogResult;
990 public int OnVerifiyCertificateEx(String host,
long port, String commonName, String subject,
991 String issuer, String fingerprint,
long flags)
994 if (ApplicationSettingsActivity.getAcceptAllCertificates(
this))
998 callbackDialogResult =
false;
1001 String msg = getResources().getString(R.string.dlg_msg_verify_certificate);
1002 String type =
"RDP-Server";
1003 if ((flags & LibFreeRDP.VERIFY_CERT_FLAG_GATEWAY) != 0)
1004 type =
"RDP-Gateway";
1005 if ((flags & LibFreeRDP.VERIFY_CERT_FLAG_REDIRECT) != 0)
1006 type =
"RDP-Redirect";
1007 msg +=
"\n\n" + type +
": " + host +
":" + port;
1009 msg +=
"\n\nSubject: " + subject +
"\nIssuer: " + issuer;
1011 if ((flags & LibFreeRDP.VERIFY_CERT_FLAG_FP_IS_PEM) != 0)
1012 msg +=
"\nCertificate: " + fingerprint;
1014 msg +=
"\nFingerprint: " + fingerprint;
1015 dlgVerifyCertificate.setMessage(msg);
1018 uiHandler.sendMessage(Message.obtain(
null, UIHandler.SHOW_DIALOG, dlgVerifyCertificate));
1023 synchronized (dlgVerifyCertificate)
1025 dlgVerifyCertificate.wait();
1028 catch (InterruptedException e)
1032 return callbackDialogResult ? 1 : 0;
1036 public int OnVerifyChangedCertificateEx(String host,
long port, String commonName,
1037 String subject, String issuer, String fingerprint,
1038 String oldSubject, String oldIssuer,
1039 String oldFingerprint,
long flags)
1042 if (ApplicationSettingsActivity.getAcceptAllCertificates(
this))
1046 callbackDialogResult =
false;
1049 String msg = getResources().getString(R.string.dlg_msg_verify_certificate);
1050 String type =
"RDP-Server";
1051 if ((flags & LibFreeRDP.VERIFY_CERT_FLAG_GATEWAY) != 0)
1052 type =
"RDP-Gateway";
1053 if ((flags & LibFreeRDP.VERIFY_CERT_FLAG_REDIRECT) != 0)
1054 type =
"RDP-Redirect";
1055 msg +=
"\n\n" + type +
": " + host +
":" + port;
1056 msg +=
"\n\nSubject: " + subject +
"\nIssuer: " + issuer;
1057 if ((flags & LibFreeRDP.VERIFY_CERT_FLAG_FP_IS_PEM) != 0)
1058 msg +=
"\nCertificate: " + fingerprint;
1060 msg +=
"\nFingerprint: " + fingerprint;
1061 dlgVerifyCertificate.setMessage(msg);
1064 uiHandler.sendMessage(Message.obtain(
null, UIHandler.SHOW_DIALOG, dlgVerifyCertificate));
1069 synchronized (dlgVerifyCertificate)
1071 dlgVerifyCertificate.wait();
1074 catch (InterruptedException e)
1078 return callbackDialogResult ? 1 : 0;
1081 @Override
public void OnRemoteClipboardChanged(String data)
1083 Log.v(TAG,
"OnRemoteClipboardChanged: " + data);
1084 mClipboardManager.setClipboardData(data);
1089 private void resetZoomControlsAutoHideTimeout()
1091 uiHandler.removeMessages(UIHandler.HIDE_ZOOMCONTROLS);
1092 uiHandler.sendEmptyMessageDelayed(UIHandler.HIDE_ZOOMCONTROLS,
1093 ZOOMCONTROLS_AUTOHIDE_TIMEOUT);
1096 @Override
public void onScrollChanged(ScrollView2D scrollView,
int x,
int y,
int oldx,
int oldy)
1098 zoomControls.setIsZoomInEnabled(!sessionView.isAtMaxZoom());
1099 zoomControls.setIsZoomOutEnabled(!sessionView.isAtMinZoom());
1101 if (sysKeyboardVisible || extKeyboardVisible)
1104 if (!ApplicationSettingsActivity.getHideZoomControls(
this))
1106 uiHandler.sendEmptyMessage(UIHandler.SHOW_ZOOMCONTROLS);
1107 resetZoomControlsAutoHideTimeout();
1113 @Override
public void onSessionViewBeginTouch()
1115 scrollView.setScrollEnabled(
false);
1118 @Override
public void onSessionViewEndTouch()
1120 scrollView.setScrollEnabled(
true);
1123 @Override
public void onSessionViewLeftTouch(
int x,
int y,
boolean down)
1126 cancelDelayedMoveEvent();
1128 LibFreeRDP.sendCursorEvent(session.getInstance(), x, y,
1129 toggleMouseButtons ? Mouse.getRightButtonEvent(
this, down)
1130 : Mouse.getLeftButtonEvent(this, down));
1133 toggleMouseButtons =
false;
1136 public void onSessionViewRightTouch(
int x,
int y,
boolean down)
1139 toggleMouseButtons = !toggleMouseButtons;
1142 @Override
public void onSessionViewMove(
int x,
int y)
1144 sendDelayedMoveEvent(x, y);
1147 @Override
public void onSessionViewScroll(
boolean down)
1149 LibFreeRDP.sendCursorEvent(session.getInstance(), 0, 0, Mouse.getScrollEvent(
this, down));
1154 @Override
public void onTouchPointerClose()
1156 touchPointerView.setVisibility(View.INVISIBLE);
1157 sessionView.setTouchPointerPadding(0, 0);
1160 private Point mapScreenCoordToSessionCoord(
int x,
int y)
1162 int mappedX = (int)((
float)(x + scrollView.getScrollX()) / sessionView.getZoom());
1163 int mappedY = (int)((
float)(y + scrollView.getScrollY()) / sessionView.getZoom());
1166 if (mappedX > bitmap.getWidth())
1167 mappedX = bitmap.getWidth();
1168 if (mappedY > bitmap.getHeight())
1169 mappedY = bitmap.getHeight();
1171 return new Point(mappedX, mappedY);
1174 @Override
public void onTouchPointerLeftClick(
int x,
int y,
boolean down)
1176 Point p = mapScreenCoordToSessionCoord(x, y);
1177 LibFreeRDP.sendCursorEvent(session.getInstance(), p.x, p.y,
1178 Mouse.getLeftButtonEvent(
this, down));
1181 @Override
public void onTouchPointerRightClick(
int x,
int y,
boolean down)
1183 Point p = mapScreenCoordToSessionCoord(x, y);
1184 LibFreeRDP.sendCursorEvent(session.getInstance(), p.x, p.y,
1185 Mouse.getRightButtonEvent(
this, down));
1188 @Override
public void onTouchPointerMove(
int x,
int y)
1190 Point p = mapScreenCoordToSessionCoord(x, y);
1191 LibFreeRDP.sendCursorEvent(session.getInstance(), p.x, p.y, Mouse.getMoveEvent());
1193 if (ApplicationSettingsActivity.getAutoScrollTouchPointer(
this) &&
1194 !uiHandler.hasMessages(UIHandler.SCROLLING_REQUESTED))
1196 Log.v(TAG,
"Starting auto-scroll");
1197 uiHandler.sendEmptyMessageDelayed(UIHandler.SCROLLING_REQUESTED, SCROLLING_TIMEOUT);
1201 @Override
public void onTouchPointerScroll(
boolean down)
1203 LibFreeRDP.sendCursorEvent(session.getInstance(), 0, 0, Mouse.getScrollEvent(
this, down));
1206 @Override
public void onTouchPointerToggleKeyboard()
1208 showKeyboard(!sysKeyboardVisible,
false);
1211 @Override
public void onTouchPointerToggleExtKeyboard()
1213 showKeyboard(
false, !extKeyboardVisible);
1216 @Override
public void onTouchPointerResetScrollZoom()
1218 sessionView.setZoom(1.0f);
1219 scrollView.scrollTo(0, 0);
1222 @Override
public boolean onGenericMotionEvent(MotionEvent e)
1224 super.onGenericMotionEvent(e);
1225 switch (e.getAction())
1227 case MotionEvent.ACTION_SCROLL:
1228 final float vScroll = e.getAxisValue(MotionEvent.AXIS_VSCROLL);
1231 LibFreeRDP.sendCursorEvent(session.getInstance(), 0, 0,
1232 Mouse.getScrollEvent(
this,
false));
1236 LibFreeRDP.sendCursorEvent(session.getInstance(), 0, 0,
1237 Mouse.getScrollEvent(
this,
true));
1246 @Override
public void onClipboardChanged(String data)
1248 Log.v(TAG,
"onClipboardChanged: " + data);
1249 LibFreeRDP.sendClipboardData(session.getInstance(), data);
1252 private class UIHandler
extends Handler
1255 public static final int REFRESH_SESSIONVIEW = 1;
1256 public static final int DISPLAY_TOAST = 2;
1257 public static final int HIDE_ZOOMCONTROLS = 3;
1258 public static final int SEND_MOVE_EVENT = 4;
1259 public static final int SHOW_DIALOG = 5;
1260 public static final int GRAPHICS_CHANGED = 6;
1261 public static final int SCROLLING_REQUESTED = 7;
1262 public static final int SHOW_ZOOMCONTROLS = 8;
1269 @Override
public void handleMessage(Message msg)
1273 case GRAPHICS_CHANGED:
1275 sessionView.onSurfaceChange(session);
1276 scrollView.requestLayout();
1279 case REFRESH_SESSIONVIEW:
1281 sessionView.invalidateRegion();
1286 Toast errorToast = Toast.makeText(getApplicationContext(), msg.obj.toString(),
1291 case HIDE_ZOOMCONTROLS:
1293 if (zoomControls.isShown())
1294 zoomControls.hide();
1297 case SHOW_ZOOMCONTROLS:
1299 if (!zoomControls.isShown())
1300 zoomControls.show();
1304 case SEND_MOVE_EVENT:
1306 LibFreeRDP.sendCursorEvent(session.getInstance(), msg.arg1, msg.arg2,
1307 Mouse.getMoveEvent());
1313 ((Dialog)msg.obj).show();
1316 case SCROLLING_REQUESTED:
1320 float[] pointerPos = touchPointerView.getPointerPosition();
1322 if (pointerPos[0] > (screen_width - touchPointerView.getPointerWidth()))
1323 scrollX = SCROLLING_DISTANCE;
1324 else if (pointerPos[0] < 0)
1325 scrollX = -SCROLLING_DISTANCE;
1327 if (pointerPos[1] > (screen_height - touchPointerView.getPointerHeight()))
1328 scrollY = SCROLLING_DISTANCE;
1329 else if (pointerPos[1] < 0)
1330 scrollY = -SCROLLING_DISTANCE;
1332 scrollView.scrollBy(scrollX, scrollY);
1335 if (scrollView.getScrollX() == 0 ||
1336 scrollView.getScrollX() == (sessionView.getWidth() - scrollView.getWidth()))
1338 if (scrollView.getScrollY() == 0 ||
1339 scrollView.getScrollY() ==
1340 (sessionView.getHeight() - scrollView.getHeight()))
1343 if (scrollX != 0 || scrollY != 0)
1344 uiHandler.sendEmptyMessageDelayed(SCROLLING_REQUESTED, SCROLLING_TIMEOUT);
1346 Log.v(TAG,
"Stopping auto-scroll");
1353 private class PinchZoomListener
extends ScaleGestureDetector.SimpleOnScaleGestureListener
1355 private float scaleFactor = 1.0f;
1357 @Override
public boolean onScaleBegin(ScaleGestureDetector detector)
1359 scrollView.setScrollEnabled(
false);
1363 @Override
public boolean onScale(ScaleGestureDetector detector)
1367 scaleFactor *= detector.getScaleFactor();
1368 scaleFactor = Math.max(SessionView.MIN_SCALE_FACTOR,
1369 Math.min(scaleFactor, SessionView.MAX_SCALE_FACTOR));
1370 sessionView.setZoom(scaleFactor);
1372 if (!sessionView.isAtMinZoom() && !sessionView.isAtMaxZoom())
1375 float transOriginX = scrollView.getScrollX() * detector.getScaleFactor();
1376 float transOriginY = scrollView.getScrollY() * detector.getScaleFactor();
1379 float transCenterX =
1380 (scrollView.getScrollX() + detector.getFocusX()) * detector.getScaleFactor();
1381 float transCenterY =
1382 (scrollView.getScrollY() + detector.getFocusY()) * detector.getScaleFactor();
1387 scrollView.scrollBy((
int)((transCenterX - transOriginX) - detector.getFocusX()),
1388 (
int)((transCenterY - transOriginY) - detector.getFocusY()));
1394 @Override
public void onScaleEnd(ScaleGestureDetector de)
1396 scrollView.setScrollEnabled(
true);
1400 private class LibFreeRDPBroadcastReceiver
extends BroadcastReceiver
1402 @Override
public void onReceive(Context context, Intent intent)
1405 if (session ==
null)
1409 if (session.getInstance() != intent.getExtras().getLong(GlobalApp.EVENT_PARAM, -1))
1412 switch (intent.getExtras().getInt(GlobalApp.EVENT_TYPE, -1))
1414 case GlobalApp.FREERDP_EVENT_CONNECTION_SUCCESS:
1415 OnConnectionSuccess(context);
1418 case GlobalApp.FREERDP_EVENT_CONNECTION_FAILURE:
1419 OnConnectionFailure(context);
1421 case GlobalApp.FREERDP_EVENT_DISCONNECTED:
1422 OnDisconnected(context);
1427 private void OnConnectionSuccess(Context context)
1429 Log.v(TAG,
"OnConnectionSuccess");
1434 if (progressDialog !=
null)
1436 progressDialog.dismiss();
1437 progressDialog =
null;
1440 if (session.getBookmark() ==
null)
1447 Bundle bundle = getIntent().getExtras();
1448 if (bundle !=
null && bundle.containsKey(PARAM_CONNECTION_REFERENCE))
1450 if (ConnectionReference.isHostnameReference(
1451 bundle.getString(PARAM_CONNECTION_REFERENCE)))
1453 assert session.getBookmark().getType() == BookmarkBase.TYPE_MANUAL;
1454 String item = session.getBookmark().<ManualBookmark>
get().getHostname();
1455 if (!GlobalApp.getQuickConnectHistoryGateway().historyItemExists(item))
1456 GlobalApp.getQuickConnectHistoryGateway().addHistoryItem(item);
1461 private void OnConnectionFailure(Context context)
1463 Log.v(TAG,
"OnConnectionFailure");
1466 uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
1468 if (progressDialog !=
null)
1470 progressDialog.dismiss();
1471 progressDialog =
null;
1475 if (!connectCancelledByUser)
1476 uiHandler.sendMessage(
1477 Message.obtain(
null, UIHandler.DISPLAY_TOAST,
1478 getResources().getText(R.string.error_connection_failure)));
1480 closeSessionActivity(RESULT_CANCELED);
1483 private void OnDisconnected(Context context)
1485 Log.v(TAG,
"OnDisconnected");
1488 uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
1490 if (progressDialog !=
null)
1492 progressDialog.dismiss();
1493 progressDialog =
null;
1496 session.setUIEventListener(
null);
1497 closeSessionActivity(RESULT_OK);