In this interview we talk to open source developer Philipp Crocoll about Keepass2Android. Besides its features as a password store, this project is a good case study for combining Java and C# in a single Android application.
InfoQ: Can you explain what problem Keepass2Android was created to solve?
Keepass 2 is a great password manager which I was using since quite a while. It has nice plugins, e.g. to integrate into Chrome or Firefox. I had Keepassdroid on my phone to access my passwords there as well. Unfortunately, it only provided read-only access to my database. (It was originally created for use with Keepass 1 which it can also write, but that didn't help me.) As I started to use my phone more and more, I wanted to create accounts and store the passwords from the phone as well.
So I started to think about adding that feature on my own. I decided to do this by porting the app to C# with Mono for Android to use the original Keepass 2 code for modifying the password databases.
InfoQ: What makes Keepass2Android different from other password managers?
When my app was nearly finished, Keepassdroid added write support (at least in beta mode) as well. I decided to publish it anyway because it already had a few more features - including full compatibility with Keepass 2, browser integration or QuickUnlock: QuickUnlock is a technique to keep the database in memory (i.e. the master password is never stored on SD card). To protect the database in case a user loses his phone, a short password must be entered to unlock the database. That's much better than entering the strong, long master password each time.
Since the initial release, I have added quite a bunch of further features: A custom keyboard can be used to enter credentials (because clipboard is unsafe in Android); for users of the PC version there is an option to synchronize the database through WebDAV, FTP, SFTP, Dropbox, OneDrive or GoogleDrive. There are some more "expert" features like use of One-Time-Passwords (entered via NFC with a Yubikey NEO, https://www.yubico.com/products/yubikey-hardware/yubikey-neo/) or support for Keepass 2's placeholder system (http://keepass.info/help/base/placeholders.html).
I try to make the app usable for people without a lot of experience, but want to provide options for security paranoid users as well.
InfoQ: What language did you choose to use C# for Keepass2Android instead of Java?
Writing an encrypted file must be done very carefully: If you write one wrong bit, the file might become useless and unreadable. Users must be sure that their password database remains intact! To make sure I wouldn't kill any database, I decided to rely on the original implementation in Keepass 2. As Keepass 2 is written in C#, I evaluated options to use this implementation on Android. This is when I first got in touch with Xamarin's Mono for Android. I had some C# experience from earlier work and at least a little experience with Android. Bringing these two together seemed very interesting. As I am eager to learn new technologies regularly, this seemed like a great choice. And indeed, Mono for Android turned out to be a nice platform: You have the power of the .net framework as well as the Java platform and the Android libraries.
Another nice thing is that it's possible to include Java libraries easily. And in fact, I wrote parts of the app (cloud storage, custom keyboard) in Java to use the better Android support in Eclipse.
InfoQ: What's involved in combining Java and C# code into the same application? Is it pretty straight forward or does it pose a significant challenge?
The Xamarin team has done a great job in mixing the two worlds: Java libraries can be linked by creating a so called binding library in the .net project. This generates some C# classes and interfaces which allow calling the Java code. This works pretty seamlessly and even automatically translates between the common naming conventions and patterns. A simple example is that "String getPackageName()" is transformed into string PackageName { get {...} }". But also event handling is translated: "setOnClickListener(...)" becomes "Click += ..." in C#.
For simple interfaces, I haven't experienced any issues. If you want to bind complex libraries, you usually have to do some manual work as described in http://docs.xamarin.com/guides/android/advanced_topics/java_integration_overview/binding_a_java_library_(.jar)/api_metadata_reference/.
With the Java classes bound and having the C# counterparts, it mostly feels like using a C# library. One of the rare cases where I actually see that I am dealing with Java is a line like
catch (Java.Lang.Exception e)
or when I have to derive a class from Java.Lang.Object. This is necessary when implementing an interface originally defined in Java when an object of that class should be passed back into Java code.
This is the only point where I realized in my code that objects live in two virtual machines, with Garbage Collection running in both worlds!
InfoQ. For future Android project would you consider using C# again?
I consider Mono for Android as a tool in my tool set. While it is a powerful tool, it is certainly not required or best-suited for every project:
The reason for using it in Keepass2Android is that it gives me the option to incorporate a powerful library (Keepass 2 code) into an Android application. And for everybody with some C# background, it's great to use all the nice C# features (LINQ, Lambdas, dynamic types ...) and the .net-framework.
Another reason to use Mono for Android can be portability: Your code can run on Android, iOS (both with Xamarin) and of course on Windows and Linux (with Mono). But unfortunately, there is a downside as well. The Mono libraries add several MB of app package size (depending on how much of the framework you use) and the build process is pretty slow compared to pure Java.
My app currently takes more than 2 minutes to launch from Visual Studio. To mitigate this problem, I added build options for development with less app features and faster build times and I try to develop new features in external projects.
Also, IDE support for some Android specific functions is not as good as in Eclipse or Android Studio, which can slow down development.
For these reasons, I would decide on a per-project basis if I want to use Mono for Android.
Keepass2Android is available on CodePlex under the GPLv3 license.