Wednesday, July 29, 2015

New MoVirt release - introduction of augmented reality

  I decided to date this post for MoVirt release and since release has been delayed this post is delayed too.

  But now 0.2 beta version of MoVirt is available to everyone, and I'm very happy about this because the main feature introduced in this version is my work on augmented reality! You can check how does it work in this video:

  Also you can download latest test build for Android from here if you are using oVirt or interested in virtualization. This is unsigned package, so you need to copy .apk file into your android device, enable "Unknown sources" in Settings and install .apk file.

  To prepare this release I've spent three weeks fixing various bugs, stability and usability issues along with refactoring and cleaning some parts of the code. And there were two "interesting" tasks which annoyed me a lot.

  The first task was about android synchronization. We noticed that automatic synchronization with oVirt server happens only once a day and this may be not very good behavior for monitoring software, because you can easily skip some important events if you are relying on notifications from moVirt. According to android SDK documentation:
When a network connection is available, the Android system sends out a message every few seconds to keep the device's TCP/IP connection open. This message also goes to the ContentResolver of each app. By calling setSyncAutomatically(), you can run the sync adapter whenever the ContentResolver receives the message.
"every few seconds", but this is not working in moVirt for some reason. People at stackoverflow.com says that android documentation misguiding in some topics especially about synchronization, and I found the only working solution is to enable periodic sync with fixed custom interval which is not recommended. There is one more solution (which is possibly the best) is to use push-notifications via GCM, but this is far-far future plans which requires modification also in oVirt server.

  The second task was about proper storing time in database. Since we have information at what time connection to server was lost and when was the last successful synchronization, we need to store this information in database to share between activities and sessions (detailed about necessity of using database in previous post). My first thought was to use java.sql.Timestamp class because it specially designed to store time and date in database. As I understand this class contains Unix Time which is UTC time and converts to properly formatted string to store in database.
public String toString()
Formats a timestamp in JDBC timestamp escape format. yyyy-mm-dd hh:mm:ss.fffffffff, where ffffffffff indicates nanoseconds.
Everything was looking fine until I realized that time in database stored in local time zone! And if you change time zone in your device it will show wrong time. Who in the world needs to store date and time in database in local time zone? And why does this Timestamp class do this conversion implicitly in toString() function with no obvious way to avoid this conversion? Ok, there are LOTS of other classes to work with time in java, and I decided to find some ready to use code snippets to store time as string in database in UTC... I've spent three days trying different solutions and all of them was wrong and shows the wrong time, because every class in Java performs implicit time zone conversion even if it is not needed and not obvious for this action. So I stopped to store time in database just as Unix Time and convert to string only while displaying and this seems to work.

Wednesday, July 8, 2015

More ways to help

  Hello again, it's time for a blog today!

  So it's my 7th week along with moVirt, as I said previously I have finished with my feature which was to implement  AR in moVirt. In past two weeks I've been focused on bug fixes, requests from users and other improvements which should make moVirt more stable and friendly to the users.

  The first task was to add notifications about Internet connection which came from user request. It's very important to keep user informed about connection state and how information is old while you work with remote data. So we decided just to put simple icon that warns if sync request was failed and Internet connection lost. "Looks like quite simple task with few lines of code" - what I was thinking. The first thing that I realized about android applications, that it's not that simple to keep application scope data if you have more that one activity and one of appropriate way to share some piece of information between all the activities is to put it into database. Well, ok, I'm familiar with SQL, and there is guides inside Android SDK documentation how to perform actions with SQLite. But if you are developing inside big enough project like moVirt then you find that it uses couple of frameworks and classes that hides low-level actions and I just can't connect to DB and insert a record into table. And I stepped into stupid situation where high-level concept confuses more then low-level. Hopefully my mentor guided me through part of the maze of classes and frameworks. And all this misadventures just to save a one variable available across all the activities. So the next step was to put an icon... into every activity in app. I thought: "Oh no, do I really need to copy&past code across all the activities?" I was about to start blaming Google for this Activity concept, but actually there are a couple of techniques to share logic and views between different activities: you can use fragments or overlays, but the best solution with minimal copy&pasting is to inherit activities! I'm quite experienced in OOP, but I haven't realized that we can inherit activities, before my mentor suggested this to me. Even though this trick requires significant refactoring, but it has lots of advantages. Following this solution and implemented parent activity as super class now we can add any code in one place in it would automatically work in every activity. After adding connection warning icon into parent activity I also grabbed sync action button to appear on every screen and now we can sync everywhere! And there could be even more things to appear in every activity.

  Yet another task was to extend moVirt's notification system. Since we now have connection state, information, we can inform user about failed synchronizations via android notifications. And since it was me who created NotificationHelper class (during initial contribution) adding new notifications is the easiest part.

  There were a couple of small fixes which I don't want to concentrate on. The last thing I want to write is about testing. My mentor insists that we need implement some unit tests for moVirt project, so that project may become more stable and bugless, and I agree with him, since I was interested in unit testing and this tasks now assigned to me. However my first attempts was failed. Android is not that simple to write unit tests, especially if you are not following TDD from beginning. But we'll see what I can do in the next two weeks.


Pic. 1. Foretasting of unit testing.