From bcbb80fc19108a7034910d440aa5a111c8430df1 Mon Sep 17 00:00:00 2001 From: blazee Date: Sun, 10 Mar 2013 12:51:36 +0100 Subject: [PATCH] Android: Add basic .RDP file support --- .../domain/ConnectionReference.java | 13 +++ .../presentation/BookmarkActivity.java | 75 +++++++++++++ .../presentation/HomeActivity.java | 24 ++++- .../freerdpcore/utils/RDPFileParser.java | 101 ++++++++++++++++++ .../aFreeRDP/AndroidManifest.xml.cmake | 15 +++ 5 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/RDPFileParser.java diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/ConnectionReference.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/ConnectionReference.java index 270139c51..4e4442dd7 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/ConnectionReference.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/ConnectionReference.java @@ -14,6 +14,7 @@ public class ConnectionReference public static final String PATH_MANUAL_BOOKMARK_ID = "MBMID/"; public static final String PATH_HOSTNAME = "HOST/"; public static final String PATH_PLACEHOLDER = "PLCHLD/"; + public static final String PATH_FILE = "FILE/"; public static String getManualBookmarkReference(long bookmarkId) { return (PATH_MANUAL_BOOKMARK_ID + bookmarkId); @@ -27,6 +28,10 @@ public class ConnectionReference return (PATH_PLACEHOLDER + name); } + public static String getFileReference(String uri) { + return (PATH_FILE + uri); + } + public static boolean isBookmarkReference(String refStr) { return refStr.startsWith(PATH_MANUAL_BOOKMARK_ID); } @@ -43,6 +48,10 @@ public class ConnectionReference return refStr.startsWith(PATH_PLACEHOLDER); } + public static boolean isFileReference(String refStr) { + return refStr.startsWith(PATH_FILE); + } + public static long getManualBookmarkId(String refStr) { return Integer.parseInt(refStr.substring(PATH_MANUAL_BOOKMARK_ID.length())); } @@ -54,4 +63,8 @@ public class ConnectionReference public static String getPlaceholder(String refStr) { return refStr.substring(PATH_PLACEHOLDER.length()); } + + public static String getFile(String refStr) { + return refStr.substring(PATH_FILE.length()); + } } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java index 078852f3b..4d938f419 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java @@ -9,12 +9,16 @@ package com.freerdp.freerdpcore.presentation; +import java.io.File; +import java.io.IOException; + import com.freerdp.freerdpcore.R; import com.freerdp.freerdpcore.application.GlobalApp; import com.freerdp.freerdpcore.domain.BookmarkBase; import com.freerdp.freerdpcore.domain.ConnectionReference; import com.freerdp.freerdpcore.domain.ManualBookmark; import com.freerdp.freerdpcore.services.BookmarkBaseGateway; +import com.freerdp.freerdpcore.utils.RDPFileParser; import android.app.AlertDialog; import android.content.ComponentName; @@ -25,11 +29,14 @@ import android.os.Bundle; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; +import android.util.Log; public class BookmarkActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { public static final String PARAM_CONNECTION_REFERENCE = "conRef"; + private static final String TAG = "BookmarkActivity"; + private int current_preferences; private static final int PREFERENCES_BOOKMARK = 1; private static final int PREFERENCES_CREDENTIALS = 2; @@ -78,6 +85,26 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref bookmark.get().setHostname(ConnectionReference.getHostname(refStr)); new_bookmark = true; } + else if (ConnectionReference.isFileReference(refStr)) + { + String file = ConnectionReference.getFile(refStr); + + bookmark = new ManualBookmark(); + bookmark.setLabel(file); + + try + { + RDPFileParser rdpFile = new RDPFileParser(file); + updateBookmarkFromFile((ManualBookmark)bookmark, rdpFile); + + bookmark.setLabel(new File(file).getName()); + new_bookmark = true; + } + catch (IOException e) + { + Log.e(TAG, "Failed reading RDP file", e); + } + } } } @@ -144,6 +171,54 @@ public class BookmarkActivity extends PreferenceActivity implements OnSharedPref setIntentComponentNames(); } + private void updateBookmarkFromFile(ManualBookmark bookmark, RDPFileParser rdpFile) + { + String s; + Integer i; + + s = rdpFile.getString("full address"); + if (s != null) + { + // this gets complicated as it can include port + if (s.lastIndexOf(":") > s.lastIndexOf("]")) + { + try + { + String port = s.substring(s.lastIndexOf(":") + 1); + bookmark.setPort(Integer.parseInt(port)); + } + catch (NumberFormatException e) + { + Log.e(TAG, "Malformed address"); + } + + s = s.substring(0, s.lastIndexOf(":")); + } + + // or even be an ipv6 address + if (s.startsWith("[") && s.endsWith("]")) + s = s.substring(1, s.length() - 1); + + bookmark.setHostname(s); + } + + i = rdpFile.getInteger("server port"); + if (i != null) + bookmark.setPort(i); + + s = rdpFile.getString("username"); + if (s != null) + bookmark.setUsername(s); + + s = rdpFile.getString("domain"); + if (s != null) + bookmark.setDomain(s); + + i = rdpFile.getInteger("connect to console"); + if (i != null) + bookmark.getAdvancedSettings().setConsoleMode(i == 1); + } + private void setIntentComponentNames() { // we set the component name for our sub-activity calls here because we don't know the package diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/HomeActivity.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/HomeActivity.java index 8abd471c9..6330cb18e 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/HomeActivity.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/HomeActivity.java @@ -26,26 +26,27 @@ import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; +import android.net.Uri; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.view.ContextMenu; import android.view.View.OnClickListener; -import android.view.ContextMenu.ContextMenuInfo; import android.view.View.OnCreateContextMenuListener; import android.webkit.WebView; import android.webkit.WebViewClient; +import android.widget.AdapterView; +import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ListView; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; public class HomeActivity extends Activity { @@ -87,6 +88,21 @@ public class HomeActivity extends Activity addBookmarkPlaceholder.setName(ADD_BOOKMARK_PLACEHOLDER); addBookmarkPlaceholder.setLabel(getResources().getString(R.string.list_placeholder_add_bookmark)); + // check for passed .rdp file and open it in a new bookmark + Intent caller = getIntent(); + Uri callParameter = caller.getData(); + + if (Intent.ACTION_VIEW.equals(caller.getAction()) && callParameter != null) + { + String refStr = ConnectionReference.getFileReference(callParameter.getPath()); + Bundle bundle = new Bundle(); + bundle.putString(BookmarkActivity.PARAM_CONNECTION_REFERENCE, refStr); + + Intent bookmarkIntent = new Intent(this.getApplicationContext(), BookmarkActivity.class); + bookmarkIntent.putExtras(bundle); + startActivity(bookmarkIntent); + } + // load views clearTextButton = (Button) findViewById(R.id.clear_search_btn); superBarEditText = (EditText) findViewById(R.id.superBarEditText); diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/RDPFileParser.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/RDPFileParser.java new file mode 100644 index 000000000..a903ed2eb --- /dev/null +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/RDPFileParser.java @@ -0,0 +1,101 @@ +/* + Simple .RDP file parser + + Copyright 2013 Blaz Bacnik + + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +package com.freerdp.freerdpcore.utils; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Locale; + +public class RDPFileParser { + + private static final int MAX_ERRORS = 20; + private static final int MAX_LINES = 500; + + private HashMap options; + + private void init() + { + options = new HashMap(); + } + + public RDPFileParser() + { + init(); + } + + public RDPFileParser(String filename) throws IOException + { + init(); + parse(filename); + } + + public void parse(String filename) throws IOException + { + BufferedReader br = new BufferedReader(new FileReader(filename)); + String line = null; + + int errors = 0; + int lines = 0; + boolean ok; + + while ((line = br.readLine()) != null) + { + lines++; ok = false; + + if (errors > MAX_ERRORS || lines > MAX_LINES) + throw new IOException("Parsing limits exceeded"); + + String[] fields = line.split(":", 3); + + if (fields.length == 3) + { + if (fields[1].equals("s")) + { + options.put(fields[0].toLowerCase(Locale.ENGLISH), fields[2]); + ok = true; + } + else if (fields[1].equals("i")) + { + try + { + Integer i = Integer.parseInt(fields[2]); + options.put(fields[0].toLowerCase(Locale.ENGLISH), i); + ok = true; + } + catch (NumberFormatException e) { } + } + else if (fields[1].equals("b")) + { + ok = true; + } + } + + if (!ok) errors++; + } + } + + public String getString(String optionName) + { + if (options.get(optionName) instanceof String) + return (String) options.get(optionName); + else + return null; + } + + public Integer getInteger(String optionName) + { + if (options.get(optionName) instanceof Integer) + return (Integer) options.get(optionName); + else + return null; + } +} diff --git a/client/Android/aFreeRDP/AndroidManifest.xml.cmake b/client/Android/aFreeRDP/AndroidManifest.xml.cmake index e0d01c824..f63717dd8 100644 --- a/client/Android/aFreeRDP/AndroidManifest.xml.cmake +++ b/client/Android/aFreeRDP/AndroidManifest.xml.cmake @@ -23,6 +23,21 @@ + + + + + + + + + +