Android: Add basic .RDP file support
authorblazee <blazee.dev@gmail.com>
Sun, 10 Mar 2013 11:51:36 +0000 (12:51 +0100)
committerblazee <blazee.dev@gmail.com>
Sun, 10 Mar 2013 12:08:47 +0000 (13:08 +0100)
client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/ConnectionReference.java
client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/BookmarkActivity.java
client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/presentation/HomeActivity.java
client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/RDPFileParser.java [new file with mode: 0644]
client/Android/aFreeRDP/AndroidManifest.xml.cmake

index 270139c..4e4442d 100644 (file)
@@ -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());
+       }
 }
index 078852f..4d938f4 100644 (file)
@@ -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.<ManualBookmark>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
index 8abd471..6330cb1 100644 (file)
@@ -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 (file)
index 0000000..a903ed2
--- /dev/null
@@ -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<String, Object> options;
+
+       private void init()
+       {
+               options = new HashMap<String, Object>(); 
+       }
+       
+       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;
+       }
+}
index e0d01c8..f63717d 100644 (file)
                                        <action android:name="android.intent.action.MAIN"/>
                                        <category android:name="android.intent.category.LAUNCHER"/>
                                </intent-filter>
+                               <intent-filter>
+                                       <action android:name="android.intent.action.VIEW" />
+                                       <category android:name="android.intent.category.DEFAULT" />
+                                       <data 
+                                               android:scheme="file"
+                                           android:mimeType="application/x-rdp" />
+                               </intent-filter>
+                               <intent-filter>
+                                       <action android:name="android.intent.action.VIEW" />
+                                       <category android:name="android.intent.category.DEFAULT" />
+                                       <data
+                                               android:scheme="file"
+                                               android:pathPattern=".*\\.rdp"
+                                               android:mimeType="*/*" />
+                               </intent-filter>
                        </activity>
 
                        <!-- Session request handler activity - used for search and internally to start sessions -->