Android Open Source - valence Valence Activity






From Project

Back to project page valence.

License

The source code is released under:

Apache License

If you think the Android project valence listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2011 David Simmons/* www . j av  a2  s.  c o m*/
 * http://cafbit.com/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.cafbit.valence;

import java.io.IOException;
import java.net.UnknownHostException;

//import com.cafbit.motelib.R;
import com.cafbit.valence.RFBThread.RFBThreadHandler;
import com.cafbit.valence.TouchPadView.OnTouchPadEventListener;
import com.cafbit.valence.rfb.RFBKeyEvent;
import com.cafbit.valence.rfb.RFBPointerEvent;
import com.cafbit.valence.rfb.RFBSecurity;
import com.cafbit.valence.rfb.RFBSecurityARD;
import com.cafbit.valence.rfb.RFBSecurityVNC;
import com.cafbit.valence.rfb.RFBKeyEvent.SpecialKey;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ToggleButton;
import android.widget.ImageView.ScaleType;

public class ValenceActivity extends Activity implements OnTouchPadEventListener {
    private static final String TAG = "Valence";

    private ValenceHandler handler = new ValenceHandlerImpl();

    // TODO: consider marshaling the ValenceDevice object into the
    // activity using Parcels or some such, instead of (or in addition
    // to) using the URL approach.
    private String address;
    private int port;
    private String password;
    private boolean ard35Compatibility = false;
    private boolean macAuthentication = false;
    private String username;

    private RFBThread rfbThread;
    private boolean isRunning = false;
    private InputMethodManager inputMethodManager;
    private TouchPadView touchPadView = null;

    private ToggleButton modButton = null;
    private ToggleButton keyButton = null;
    private SpecialKey modifier = null;

    //////////////////////////////////////////////////////////////////////
    // Activity lifecycle
    //////////////////////////////////////////////////////////////////////

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        inputMethodManager = ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE));

        Intent intent = getIntent();
        Uri uri = intent.getData();
        if (uri == null) {
            finish();
        }
        this.address = uri.getHost();
        this.port = uri.getPort();
        this.password = uri.getQueryParameter("password");
        if ((uri.getQueryParameter("ard35Compatibility") != null) &&
            (uri.getQueryParameter("ard35Compatibility").equals("true"))) {
            this.ard35Compatibility = true;
        }
        if ((uri.getQueryParameter("macAuthentication") != null) &&
            (uri.getQueryParameter("macAuthentication").equals("true"))) {
            this.macAuthentication = true;
        }
        this.username = uri.getQueryParameter("username");

        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);

        //TouchPadView
        touchPadView = new TouchPadView(this);
        touchPadView.setOnTouchPadEvent(this);

        modButton = newModifierButton("mod");
        modButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                modButton.setChecked(false);
                if (modifier == null) {
                    view.showContextMenu();
                } else {
                    modifier = null;
                }
            }
        });
        registerForContextMenu(modButton);

        keyButton = new ToggleButton(this);
        keyButton.setText("keys");
        keyButton.setTextOn("keys");
        keyButton.setTextOff("keys");
        keyButton.setFocusable(false);
        keyButton.setFocusableInTouchMode(false);
        keyButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                keyButton.setChecked(false);
                view.showContextMenu();
            }
        });
        registerForContextMenu(keyButton);

        ImageButton keyboardButton = new ImageButton(this);
        Drawable keyboardDrawable = getResources().getDrawable(R.drawable.keyboard);
        keyboardButton.setImageDrawable(keyboardDrawable);
        keyboardButton.setScaleType(ScaleType.CENTER_INSIDE);
        keyboardButton.setFocusable(false);
        keyboardButton.setFocusableInTouchMode(false);
        keyboardButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                inputMethodManager.showSoftInput(touchPadView, 0);
            }
        });

        // assemble layout of buttons
        LinearLayout buttonLayout = new LinearLayout(this);
        LinearLayout rightLayout = new LinearLayout(this);
        buttonLayout.setOrientation(LinearLayout.HORIZONTAL);
        buttonLayout.addView(modButton);
        buttonLayout.addView(keyButton);
        rightLayout.addView(keyboardButton);
        rightLayout.setGravity(Gravity.RIGHT);
        buttonLayout.addView(rightLayout, LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);

        layout.addView(touchPadView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT, 1));
        layout.addView(buttonLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 0));

        setContentView(layout);

        touchPadView.setFocusable(true);
        touchPadView.setFocusableInTouchMode(true);
        touchPadView.requestFocus();

        RFBThread savedRfbThread = (RFBThread) getLastNonConfigurationInstance();
        if (savedRfbThread != null) {
            reattachThread(savedRfbThread);
        } else {
            startThread();
        }
    }

    /**
     * This is called when the user resumes using the activity
     * after using other programs (and at activity creation time).
     *
     * We don't keep the network thread running when the user is
     * not running this program in the foreground, so we use this
     * method to initialize the packet list and start the
     * network thread.
     */
    @Override
    protected void onResume() {
        super.onResume();

        isRunning = true;

        if (! rfbThread.isAlive()) {
            Log.w(TAG, "rfbThread is disconnected -- reconnect.");
            rfbThread = null;
            startThread();
        } else if (rfbThread != null) {
            RFBThreadHandler rfbHandler = rfbThread.getHandler();
            if (rfbHandler != null) {
                rfbHandler.onActivityResume();
            }
        }

    }

    /**
     * This is called when the user leaves the activity to run
     * another program.  We stop the network thread when this
     * happens.
     */
    @Override
    protected void onPause() {
        isRunning = false;
        super.onPause();

        if (rfbThread != null) {
            RFBThreadHandler rfbHandler = rfbThread.getHandler();
            if (rfbHandler != null) {
                rfbThread.getHandler().onActivityPause();
            }
        }

    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        detachThread();
        RFBThread persistentRfbThread = this.rfbThread;
        this.rfbThread = null;
        return persistentRfbThread;
    }

    @Override
    protected void onDestroy() {
        stopThread();
        super.onDestroy();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onRestart() {
        super.onRestart();
    }

    @Override
    public void onBackPressed() {
        finish();
    }

    //////////////////////////////////////////////////////////////////////
    // options menu
    //////////////////////////////////////////////////////////////////////

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return OptionsMenuHelper.onCreateOptionsMenu(this, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        boolean result = OptionsMenuHelper.onOptionsItemSelected(this, item);
        if (result) {
            return true;
        } else {
            return super.onOptionsItemSelected(item);
        }
    }

    //////////////////////////////////////////////////////////////////////
    // context menus
    //////////////////////////////////////////////////////////////////////

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        if (v.equals(modButton)) {
            menu.setHeaderTitle("Modifier keys");
            for (int i=0; i<RFBKeyEvent.MODIFIERS.length; i++) {
                SpecialKey key = RFBKeyEvent.MODIFIERS[i];
                menu.add(Menu.NONE, (1<<16) | i, Menu.NONE, key.name);
            }
        } else if (v.equals(keyButton)) {
            menu.setHeaderTitle("Special keys");
            for (int i=0; i<RFBKeyEvent.SPECIALS.length; i++) {
                SpecialKey key = RFBKeyEvent.SPECIALS[i];
                menu.add(Menu.NONE, (2<<16) | i, Menu.NONE, key.name);
            }

        }
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        int major = itemId >> 16;
        int minor = itemId & 0xFFFF;

        switch (major) {
        case 1:
            // mod menu
            if ((minor >= 0) && (minor < RFBKeyEvent.MODIFIERS.length)) {
                modifier = RFBKeyEvent.MODIFIERS[minor];
                modButton.setTextOn(modifier.shortName);
                modButton.setChecked(true);
            }
            break;
        case 2:
            // key menu
            if ((minor >= 0) && (minor < RFBKeyEvent.SPECIALS.length)) {
                SpecialKey key = RFBKeyEvent.SPECIALS[minor];
                sendKey(new RFBKeyEvent(key, modifier));
            }
            break;
        }

        return true;
    }

    private ToggleButton newModifierButton(String text) {
        ToggleButton button = new ToggleButton(this);
        button.setText(text);
        button.setTextOn(text);
        button.setTextOff(text);
        button.setFocusable(false);
        button.setFocusableInTouchMode(false);
        return button;
    }

    private void startThread() {
        if (rfbThread != null) {
            Log.e(TAG, "rfbThread should be null!");
        }

        // create the appropriate RFBSecurity object for this connection
        RFBSecurity security;
        if (macAuthentication) {
            security = new RFBSecurityARD(username, password);
        } else {
            security = new RFBSecurityVNC(password);
        }

        if (port != -1) {
            rfbThread = new RFBThread(handler, address, port, security);
        } else {
            rfbThread = new RFBThread(handler, address, security);
        }
        if (ard35Compatibility) {
            rfbThread.setArd35Compatibility(true);
        }
        rfbThread.start();
        startConnectDialog();
    }

    private void stopThread() {
        if (rfbThread != null) {
            RFBThread.RFBThreadHandler handler = rfbThread.getHandler();
            if (handler != null) {
                handler.quit();
            }
            rfbThread = null;
        }
    }

    private void detachThread() {
        if (rfbThread != null) {
            RFBThread.RFBThreadHandler handler = rfbThread.getHandler();
            if (handler != null) {
                // replace our activity's handler with a stub handler while
                // the thread is detached from a valid activity.
                rfbThread.setValenceHandler(new ValenceDetachedHandler());
                // notify the thread of its detachment.
                handler.onDetach();
            }
        }
    }

    private void reattachThread(RFBThread rfbThread) {
        rfbThread.setValenceHandler(handler);
        rfbThread.getHandler().onReattach();
        this.rfbThread = rfbThread;
    }

    private ProgressDialog connectDialog;
    private void startConnectDialog() {
        connectDialog = new ProgressDialog(this);
        connectDialog.setIndeterminate(true);
        connectDialog.setMessage("Connecting to "+address);
        connectDialog.show();
        connectDialog.setOnCancelListener(new OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialogInterface) {
                ValenceActivity.this.finish();
            }
        });
    }

    private void stopConnectDialog() {
        if (connectDialog != null) {
            connectDialog.dismiss();
        }
    }

    private final boolean isConnected() {
        if ((rfbThread != null) && (rfbThread.isConnected())) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
        if ((keyCode == KeyEvent.KEYCODE_MENU) || (keyCode == KeyEvent.KEYCODE_BACK)) {
            return super.onKeyDown(keyCode, keyEvent);
        }
        sendKey(new RFBKeyEvent(keyEvent, modifier));
        return true;
    }

    @Override
    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent keyEvent) {
        // handle the special case of a ACTION_MULTIPLE event with key code of KEYCODE_UNKNOWN,
        // which signals a raw string of characters associated with the event.
        if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
            String chars = keyEvent.getCharacters();
            if (chars != null) {
                for (char c : chars.toCharArray()) {
                    sendKey(new RFBKeyEvent(c, modifier));
                }
            }
            return true;
        } else {
            return super.onKeyMultiple(keyCode, repeatCount, keyEvent);
        }
    }

    /*
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent keyEvent) {
        System.out.println("********** onKeyUp() keyCode="+keyCode+" keyEvent="+keyEvent+" isCanceled="+keyEvent.isCanceled()+" isTracking="+keyEvent.isTracking());
        return super.onKeyUp(keyCode, keyEvent);
    }
    @Override
    public boolean onKeyLongPress(int keyCode, KeyEvent keyEvent) {
        System.out.println("********** onKeyLongPress() keyCode="+keyCode+" keyEvent="+keyEvent);
        return super.onKeyLongPress(keyCode, keyEvent);
    }
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        System.out.println("********** dispatchKeyEvent() keyEvent="+event);
        return super.dispatchKeyEvent(event);
    }
    @Override
    public void onUserInteraction() {
        System.out.println("********** onUserInteraction()");
        super.onUserInteraction();
    }
    */


    private void sendKey(RFBKeyEvent rfbKeyEvent) {
        if (isConnected()) {
            rfbThread.getHandler().onRFBEvent(rfbKeyEvent);
            if (modifier != null) {
                modifier = null;
                modButton.setChecked(false);
            }
        }
    }

    //
    // implement OnTouchPadEventListener
    //

    @Override
    public void onTouchPadEvent(TouchPadEvent tpe) {
        if (isConnected()) {
            // convert the TouchPadEvent to an RFBPointerEvent by
            // applying the following complex transformation to
            // overcome the fundamental TPE vs. RPE mismatch
            // inherent in the system.
            RFBPointerEvent rpe = new RFBPointerEvent();
            rpe.dt = tpe.dt;
            rpe.dx = tpe.dx;
            rpe.dy = tpe.dy;
            rpe.button1 = tpe.button1;
            rpe.button2 = tpe.button2;
            rpe.sy = tpe.sy;
            rpe.sx = tpe.sx;

            // send the RFBPointerEvent
//tpe.debug();
            rfbThread.getHandler().onRFBEvent(rpe);
        }
    }

    //

    private boolean finishOnAlert = false;
    private void alert(String title, String message) {
        stopConnectDialog();
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setPositiveButton("OK", null);
        AlertDialog alertDialog = builder.create();
        alertDialog.setTitle(title);
        alertDialog.setMessage(message);
        alertDialog.show();
        alertDialog.setOnDismissListener(new OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface arg0) {
                if (finishOnAlert) {
                    ValenceActivity.this.finish();
                }
            }
        });
        return;
    }

    public interface ValenceHandler {
        public void error(Throwable throwable);
        public void onConnect();
        public void onDisconnect();
        public void onAbnormalDisconnect();
    };

    public static class ValenceDetachedHandler implements ValenceHandler {
        @Override
        public void error(Throwable throwable) {}
        @Override
        public void onAbnormalDisconnect() {}
        @Override
        public void onConnect() {}
        @Override
        public void onDisconnect() {}
    };

    public class ValenceHandlerImpl extends Handler implements ValenceHandler {

        public static final int MSG_ERROR = 1;
        public static final int MSG_CONNECT = 2;
        public static final int MSG_DISCONNECT = 3;
        public static final int MSG_ABNORMAL_DISCONNECT = 4;

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            if (! isRunning) {
                return;
            }

            switch (msg.what) {
            case MSG_ERROR:
                finishOnAlert = true;
                String text;
                if (msg.obj instanceof IOException) {
                    msg.obj = new ValenceIOException((IOException)msg.obj);
                }
                if (msg.obj instanceof UnknownHostException) {
                    text = "unknown host: "+((Throwable)msg.obj).getMessage();
                } else {
                    text = ((Throwable)msg.obj).getMessage();
                }
                alert("Error", text);
                break;
            case MSG_CONNECT:
                stopConnectDialog();
                break;
            case MSG_DISCONNECT:
                finishOnAlert = true;
                alert("Disconnect", "The remote host closed the connection.");
                break;
            case MSG_ABNORMAL_DISCONNECT:
                finishOnAlert = true;
                alert("Disconnect", "The remote host closed the connection.");
                break;
            }
        }

        // helper methods

        public void error(Throwable throwable) {
            sendMessage(Message.obtain(this, MSG_ERROR, throwable));
        }

        public void onConnect() {
            sendMessage(Message.obtain(this, MSG_CONNECT));
        }

        public void onDisconnect() {
            sendMessage(Message.obtain(this, MSG_DISCONNECT));
        }

        public void onAbnormalDisconnect() {
            sendMessage(Message.obtain(this, MSG_ABNORMAL_DISCONNECT));
        }
    }


}




Java Source Code List

com.cafbit.valence.HelpActivity.java
com.cafbit.valence.MoteContextImpl.java
com.cafbit.valence.OptionsMenuHelper.java
com.cafbit.valence.RFBRecvThread.java
com.cafbit.valence.RFBThread.java
com.cafbit.valence.SelectionActivity.java
com.cafbit.valence.TouchPadEvent.java
com.cafbit.valence.TouchPadHandler.java
com.cafbit.valence.TouchPadView.java
com.cafbit.valence.ValenceActivity.java
com.cafbit.valence.ValenceApplication.java
com.cafbit.valence.ValenceIOException.java
com.cafbit.valence.device.ValenceDeviceClass.java
com.cafbit.valence.device.ValenceDeviceSetupView.java
com.cafbit.valence.device.ValenceDevice.java
com.cafbit.valence.device.ValenceMDNSDiscoveryHandler.java
com.cafbit.valence.rfb.DES.java
com.cafbit.valence.rfb.KeyTranslator.java
com.cafbit.valence.rfb.RFBConnection.java
com.cafbit.valence.rfb.RFBEvent.java
com.cafbit.valence.rfb.RFBException.java
com.cafbit.valence.rfb.RFBKeyEvent.java
com.cafbit.valence.rfb.RFBMessage.java
com.cafbit.valence.rfb.RFBPointerEvent.java
com.cafbit.valence.rfb.RFBSecurityARD.java
com.cafbit.valence.rfb.RFBSecurityNone.java
com.cafbit.valence.rfb.RFBSecurityVNC.java
com.cafbit.valence.rfb.RFBSecurity.java
com.cafbit.valence.rfb.RFBStream.java
com.cafbit.valence.rfb.Security.java
com.cafbit.valence.rfb.Util.java
com.cafbit.valence.rfb.Version.java