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);