/**
* Copyright (C) 2012 Iordan Iordanov
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
package com.iiordanov.bVNC;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import com.iiordanov.bVNC.dialogs.ImportExportDialog;
import com.iiordanov.bVNC.dialogs.ImportTlsCaDialog;
import com.iiordanov.bVNC.*;
import com.iiordanov.freebVNC.*;
import com.iiordanov.aRDP.*;
import com.iiordanov.freeaRDP.*;
import com.iiordanov.aSPICE.*;
import com.iiordanov.freeaSPICE.*;
/**
* aSPICE is the Activity for setting up SPICE connections.
*/
public class aSPICE extends MainConfiguration {
private final static String TAG = "aSPICE";
private Spinner connectionType;
private int selectedConnType;
private TextView sshCaption;
private LinearLayout sshCredentials;
private LinearLayout layoutUseSshPubkey;
private LinearLayout sshServerEntry;
private LinearLayout layoutAdvancedSettings;
private EditText sshServer;
private EditText sshPort;
private EditText sshUser;
private EditText sshPassword;
private EditText sshPassphrase;
private EditText ipText;
private EditText portText;
private Button buttonImportCa;
private EditText tlsPort;
private EditText passwordText;
private Button goButton;
private ToggleButton toggleAdvancedSettings;
private Spinner spinnerGeometry;
private EditText textNickname;
private EditText resWidth;
private EditText resHeight;
private CheckBox checkboxKeepPassword;
private CheckBox checkboxUseDpadAsArrows;
private CheckBox checkboxRotateDpad;
private CheckBox checkboxLocalCursor;
private CheckBox checkboxUseSshPubkey;
private CheckBox checkboxEnableSound;
private Spinner layoutMapSpinner = null;
private List<String> spinnerArray = null;
@Override
public void onCreate(Bundle icicle) {
layoutID = R.layout.main_spice;
super.onCreate(icicle);
ipText = (EditText) findViewById(R.id.textIP);
sshServer = (EditText) findViewById(R.id.sshServer);
sshPort = (EditText) findViewById(R.id.sshPort);
sshUser = (EditText) findViewById(R.id.sshUser);
sshPassword = (EditText) findViewById(R.id.sshPassword);
sshPassphrase = (EditText) findViewById(R.id.sshPassphrase);
sshCredentials = (LinearLayout) findViewById(R.id.sshCredentials);
sshCaption = (TextView) findViewById(R.id.sshCaption);
layoutUseSshPubkey = (LinearLayout) findViewById(R.id.layoutUseSshPubkey);
sshServerEntry = (LinearLayout) findViewById(R.id.sshServerEntry);
portText = (EditText) findViewById(R.id.textPORT);
tlsPort = (EditText) findViewById(R.id.tlsPort);
passwordText = (EditText) findViewById(R.id.textPASSWORD);
textNickname = (EditText) findViewById(R.id.textNickname);
buttonImportCa = (Button) findViewById(R.id.buttonImportCa);
buttonImportCa.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
aSPICE.this.updateSelectedFromView();
showDialog(R.layout.import_tls_ca_dialog);
}
});
// Here we say what happens when the Pubkey Checkbox is
// checked/unchecked.
checkboxUseSshPubkey = (CheckBox) findViewById(R.id.checkboxUseSshPubkey);
// Define what happens when somebody selects different VNC connection
// types.
connectionType = (Spinner) findViewById(R.id.connectionType);
connectionType
.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> ad, View view,
int itemIndex, long id) {
selectedConnType = itemIndex;
if (selectedConnType == Constants.CONN_TYPE_PLAIN) {
setVisibilityOfSshWidgets(View.GONE);
} else if (selectedConnType == Constants.CONN_TYPE_SSH) {
setVisibilityOfSshWidgets(View.VISIBLE);
if (ipText.getText().toString().equals(""))
ipText.setText("localhost");
}
}
@Override
public void onNothingSelected(AdapterView<?> ad) {
}
});
checkboxKeepPassword = (CheckBox) findViewById(R.id.checkboxKeepPassword);
checkboxUseDpadAsArrows = (CheckBox) findViewById(R.id.checkboxUseDpadAsArrows);
checkboxRotateDpad = (CheckBox) findViewById(R.id.checkboxRotateDpad);
checkboxLocalCursor = (CheckBox) findViewById(R.id.checkboxUseLocalCursor);
checkboxEnableSound = (CheckBox) findViewById(R.id.checkboxEnableSound);
goButton = (Button) findViewById(R.id.buttonGO);
goButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (ipText.getText().length() != 0
&& (portText.getText().length() != 0 || tlsPort.getText().length() != 0))
canvasStart();
else
Toast.makeText(view.getContext(),
R.string.spice_server_empty, Toast.LENGTH_LONG)
.show();
}
});
// The advanced settings button.
toggleAdvancedSettings = (ToggleButton) findViewById(R.id.toggleAdvancedSettings);
layoutAdvancedSettings = (LinearLayout) findViewById(R.id.layoutAdvancedSettings);
toggleAdvancedSettings.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton arg0,
boolean checked) {
if (checked)
layoutAdvancedSettings.setVisibility(View.VISIBLE);
else
layoutAdvancedSettings.setVisibility(View.GONE);
}
});
// The geometry type and dimensions boxes.
spinnerGeometry = (Spinner) findViewById(R.id.spinnerRdpGeometry);
resWidth = (EditText) findViewById(R.id.rdpWidth);
resHeight = (EditText) findViewById(R.id.rdpHeight);
spinnerGeometry.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener () {
@Override
public void onItemSelected(AdapterView<?> arg0, View view, int itemIndex, long id) {
selected.setRdpResType(itemIndex);
setRemoteWidthAndHeight ();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
// Define what happens when the Import/Export button is pressed.
((Button) findViewById(R.id.buttonImportExport))
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
android.util.Log.e(TAG, "import/export!!");
showDialog(R.layout.importexport);
}
});
// Load list of items from asset folder and populate
try {
spinnerArray = listFiles("layouts");
} catch (IOException e) {
e.printStackTrace();
}
layoutMapSpinner = (Spinner) findViewById(R.id.layoutMaps);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, android.R.layout.simple_spinner_item, spinnerArray);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
layoutMapSpinner.setAdapter(adapter);
}
/**
* Makes the ssh-related widgets visible/invisible.
*/
private void setVisibilityOfSshWidgets(int visibility) {
sshCredentials.setVisibility(visibility);
sshCaption.setVisibility(visibility);
layoutUseSshPubkey.setVisibility(visibility);
sshServerEntry.setVisibility(visibility);
}
/**
* Enables and disables the EditText boxes for width and height of remote desktop.
*/
private void setRemoteWidthAndHeight () {
if (selected.getRdpResType() != Constants.RDP_GEOM_SELECT_CUSTOM) {
resWidth.setEnabled(false);
resHeight.setEnabled(false);
} else {
resWidth.setEnabled(true);
resHeight.setEnabled(true);
}
}
/*
* (non-Javadoc)
*
* @see android.app.Activity#onCreateDialog(int)
*/
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case R.layout.importexport:
return new ImportExportDialog(this);
case R.id.itemMainScreenHelp:
return createHelpDialog();
case R.layout.import_tls_ca_dialog:
return new ImportTlsCaDialog(this, database);
}
return null;
}
/**
* Creates the help dialog for this activity.
*/
private Dialog createHelpDialog() {
AlertDialog.Builder adb = new AlertDialog.Builder(this).setMessage(
R.string.spice_main_screen_help_text).setPositiveButton(
R.string.close, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// We don't have to do anything.
}
});
Dialog d = adb.setView(new ListView(this)).create();
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(d.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.FILL_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
d.show();
d.getWindow().setAttributes(lp);
return d;
}
public void updateViewFromSelected() {
if (selected == null)
return;
selectedConnType = selected.getConnectionType();
connectionType.setSelection(selectedConnType);
sshServer.setText(selected.getSshServer());
sshPort.setText(Integer.toString(selected.getSshPort()));
sshUser.setText(selected.getSshUser());
checkboxUseSshPubkey.setChecked(selected.getUseSshPubKey());
if (selectedConnType == Constants.CONN_TYPE_SSH
&& selected.getAddress().equals(""))
ipText.setText("localhost");
else
ipText.setText(selected.getAddress());
if (selected.getPort() < 0) {
portText.setText("");
} else {
portText.setText(Integer.toString(selected.getPort()));
}
if (selected.getTlsPort() < 0) {
tlsPort.setText("");
} else {
tlsPort.setText(Integer.toString(selected.getTlsPort()));
}
if (selected.getKeepPassword() || selected.getPassword().length() > 0) {
passwordText.setText(selected.getPassword());
}
checkboxKeepPassword.setChecked(selected.getKeepPassword());
checkboxUseDpadAsArrows.setChecked(selected.getUseDpadAsArrows());
checkboxRotateDpad.setChecked(selected.getRotateDpad());
checkboxLocalCursor.setChecked(selected.getUseLocalCursor());
checkboxEnableSound.setChecked(selected.getEnableSound());
textNickname.setText(selected.getNickname());
spinnerGeometry.setSelection(selected.getRdpResType());
resWidth.setText(Integer.toString(selected.getRdpWidth()));
resHeight.setText(Integer.toString(selected.getRdpHeight()));
setRemoteWidthAndHeight ();
// Write out CA to file if it doesn't exist.
String caCertData = selected.getCaCert();
try {
// If a cert has been set, write out a unique file containing the cert and save the path to that file to give to libspice.
String filename = getFilesDir() + "/ca" + Integer.toString(selected.getCaCert().hashCode()) + ".pem";
selected.setCaCertPath(filename);
File file = new File(filename);
if (!file.exists() && !caCertData.equals("")) {
android.util.Log.e(TAG, filename);
PrintWriter fout = new PrintWriter(filename);
fout.println(selected.getCaCert().toString());
fout.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int selection = spinnerArray.indexOf(selected.getLayoutMap());
if (selection < 0) {
selection = spinnerArray.indexOf(Constants.DEFAULT_LAYOUT_MAP);
}
layoutMapSpinner.setSelection(selection);
}
/**
* Returns the current ConnectionBean.
*/
public ConnectionBean getCurrentConnection() {
return selected;
}
protected void updateSelectedFromView() {
if (selected == null) {
return;
}
selected.setConnectionType(selectedConnType);
selected.setAddress(ipText.getText().toString());
String port = portText.getText().toString();
if (!port.equals("")) {
try {
selected.setPort(Integer.parseInt(portText.getText().toString()));
} catch (NumberFormatException nfe) { }
} else {
selected.setPort(-1);
}
String tlsport = tlsPort.getText().toString();
if (!tlsport.equals("")) {
try {
selected.setTlsPort(Integer.parseInt(tlsPort.getText().toString()));
} catch (NumberFormatException nfe) { }
} else {
selected.setTlsPort(-1);
}
try {
selected.setSshPort(Integer.parseInt(sshPort.getText().toString()));
} catch (NumberFormatException nfe) {
}
selected.setNickname(textNickname.getText().toString());
selected.setSshServer(sshServer.getText().toString());
selected.setSshUser(sshUser.getText().toString());
selected.setKeepSshPassword(false);
// If we are using an SSH key, then the ssh password box is used
// for the key pass-phrase instead.
selected.setUseSshPubKey(checkboxUseSshPubkey.isChecked());
selected.setSshPassPhrase(sshPassphrase.getText().toString());
selected.setSshPassword(sshPassword.getText().toString());
selected.setRdpResType(spinnerGeometry.getSelectedItemPosition());
try {
selected.setRdpWidth(Integer.parseInt(resWidth.getText().toString()));
selected.setRdpHeight(Integer.parseInt(resHeight.getText().toString()));
} catch (NumberFormatException nfe) {}
selected.setPassword(passwordText.getText().toString());
selected.setKeepPassword(checkboxKeepPassword.isChecked());
selected.setUseDpadAsArrows(checkboxUseDpadAsArrows.isChecked());
selected.setRotateDpad(checkboxRotateDpad.isChecked());
selected.setUseLocalCursor(checkboxLocalCursor.isChecked());
selected.setEnableSound(checkboxEnableSound.isChecked());
TextView selection = null;
if (layoutMapSpinner != null) {
selection = (TextView) layoutMapSpinner.getSelectedView();
}
if (selection != null) {
selected.setLayoutMap(selection.getText().toString());
}
}
private List<String> listFiles(String dirFrom) throws IOException {
Resources res = getResources();
AssetManager am = res.getAssets();
String fileList[] = am.list(dirFrom);
if (fileList != null)
{
for ( int i = 0;i<fileList.length;i++)
{
Log.d("",fileList[i]);
}
}
return (List<String>)Arrays.asList(fileList);
}
}