Thursday, September 25, 2014

Introducing Messages for Android

We are pleased to announce our latest application, Messages for Android. Messages allow you to see consolidated view of all your messages (both emails and SMS, with more message types possibly added in the future release), which comes handy if you have multiple e-mail accounts and you are tired of the necessity to switch among them in the GMail client.

Why another e-mail client ?


The main reason for us to create Messages is the fact that e-mail database is currently not accessible for third parties on Android through any API, while Google never gave any official comment to this omission, my guess is that they would cite security reasons for this decision, clearly you don't want to give access to your emails to some rogue application on your Android device. It goes along the lines of a popular request of fine-grained access to Android permissions which seems never be treated seriously by Android team despite it is highly demanded by the community for multiple years.
To get around this limitation, we created Messages. You need to download it from the Google Play:

https://play.google.com/store/apps/details?id=actiwerks.messages

Current status : Please note that Messages Application is currently in beta, if you are interested to be a part of our tester community, please let us know.

install it on your device, sign into any of your e-mail accounts (using standard IMAP/POP3 protocols/credentials) and your e-mails are accessible through Messages application, both from the UI and through API available for third party applications.

We are very serious about the security of your data, and thus we designed a mechanism that protects your e-mails from being abused, yet is very simple to use by any application, as we don't want to limit the Messages to be used only in our own applications, such as Who's Calling?, it is open to anybody willing to implement the communication & security protocol.

Here you find the description to the Messages API and how to use it.

To access the messages provided by the Messages application, you need to use ContentProvider, which is standard way to access data from the remote application by the third party on Android. While Android provides a way to secure the access by third party as outlined here, it is bit to wide, can easily be overlooked when installing application (especially if such an application has a long list of permissions) and can't be revoked from within Messages. We came up with a different way to secure the access to the Messages ContentProvider.

In order to access the provider you need to specify the following base URI :

content://actiwerks.messages/

In fact, this URI won't return any content. You need to append it with your own secure hash first :

content://actiwerks.messages/your_secure_hash_here/

Where you can get the secure hash from ? It is easy, just ask Messages application for one. This is done by sending it a request connect Intent :

actiwerks.messages.action.GRANT_ACCESS

Here is an example of the code that creates and sends such an intent :

Intent intent = new Intent("actiwerks.messages.action.GRANT_ACCESS");
intent.putExtra("appId", getActivity().getPackageName());
startActivity(intent); 

The Messages application react to this request by displaying the dialog to the user, notifying that your application just asked for permission to access the data of the Messages application.



Since the application needs to provide its package info that is both verified by the PackageManager and used for the callback to your application, user knows which application is asking for access to data an can either grant or reject it. In case of granting the access privileges, they can be revoked at any time by accessing the dialog within the Messages application.

Once the user does either grants or reject the request for the access to the ContentProvider data, the Messages application sends back another Intent carrying the information about result, and in case of the successful approval by the user, the data of the security hash for the application :

actiwerks.messages.action.ACTION_ACCESS_RESULT

Your application should define a broadcast filter to be able to intercept and get the data from the reply Intent:

<receiver
     android:name=".receiver.MessagesAccessResultReceiver_"
     android:exported="true" >
            <intent-filter>
                <action android:name="actiwerks.messages.action.ACTION_ACCESS_RESULT" />
            </intent-filter>
</receiver>

If the request to get access to was successful, the Intent contains extra String data with a key "hash". To get this data, do the following call :

String returnedHash = intentFromMessages.getStringExtra("hash");

If the returned value is non null, your access has been granted and you can use this hash in constructing the content provider URI and you will be able to get the data from the ContentProvider.

Here is a diagram of the entire workflow :



The description of the intents involved in this process are also available in the popular intent registry OpenIntents :

http://www.openintents.org/en/node/953

Working with the content provider


Assuming you were able to get the correct hash to access messages data, here is the explanation of the commands you can get from the Messages content provider. Data are accessed using REST notation.

content://actiwerks.messages/your_secure_hash_here/command/command_details

The basic commands that can be used are :

accounts
mail/account_name
sms

First command will list the names of all available e-mail accounts that were added by the user to the Messages application. You can access any of the accounts by specifying that account name after the /mail part. Using /sms will provide the access to list of SMS as an e-mail pseudo-account.

For each account there might be more specific criteria included.

in
out
read
unread
count


Using these subcommands will give you access to in-coming messages, out-coming messages, already read messages, new (unread messages). If you specify /count as the part of the URI, instead of the list of messages, the content provider will return a number, representing the count of the messages matching your criteria.

If you add any other string except of these "reserved" commands it will try to search for user name containing this string (it can be in the recipient as well as "Carbon copy" a "Blind carbon copy" fields)

Returned value from the content provider is a standard Cursor object, you can inspect its column dynamically to get idea of the data provided in each specific scenario.

We will provide more information about dealing with the returned data from the Messages application in the followup post.

Conclusion


Hope you liked the outlined security framework over the standard Android Content Provider, we believe such revocable, "at the time of service usage" scenario, similar to what iOS users are familiar with offers significant advantages over the traditional Android permission based static system. Our solution is also a proof that there is no need for any special support from the Android OS to make a more granular, lifecycle controlled security solution happen, and we are definitely interested to hear your feedback.

Please note that Messages Application is currently in beta, if you are interested to be a part of our tester community, please let us know.