Tuesday, August 14, 2012

Make use of a resized disc in a virtualized Ubuntu (LVM)

In Ubuntu 12.04 running as a guest in VirtualBox on a Windows host, I needed extended disk space.
Resiszing the disc was easy:

"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"  modifyhd Ubuntu.vdi --resize 16000

But how make the guest system effectively use the additional space, if the disc is used with LVM? It took me some time to understand that several steps are needed due to the layered architecture of LVM. Execute following steps as root
  1. Create a new logical partition with fdisk and give it type 8e (sda is the device name under which Ubuntu recognizes the disk)
    fdisk /dev/sda
    
  2. Create a physical volume from the new partition (sda6 is the device name for the new partition)
    pvcreate /dev/sda6
    
  3. Add the new physical volume to a volume group (ubuntu is its name, you can find it out with vgdisplay)
    vgextend ubuntu /dev/sda6
  4. Extend the logical volume with the space now available (/dev/mapper/ubuntu-root is the path of the logical volume)
    lvextend /dev/mapper/ubuntu-root /dev/sda6
  5. Make the file system aware of its new dimension
    sudo resize2fs /dev/mapper/ubuntu-root

Thursday, May 3, 2012

Linux on my laptop

Using Linux on the Desktop since 1999, I was quite excited about my first Linux laptop I bought last week. I have always been reluctant to deal with the different problems that normally arise when you replace a Windows system tuned by the manufacturer for the device through a Linux distribution of your choice. So buying a HP 635, with Suse Linux Enterprise Desktop ready to be installed, I thought being save of such problems. Effectively, once finished the installation, all system cyomponents worked as expected including wlan.
My satisfaction about what seems to me being a remarkable technical progress of Linux on laptops, and about the availability of devices sold with Linux instead of Windows, nevertheless got tainted by the very unclear terms under which this device is sold by HP. I have no problem with SLED being a commercial distribution, but neither on the distributor's website, nor in the documents accompanying the machine, I found any indication of what services I got entitled to by bying the product. Neither was there any manual or physical installation medium included. Registering the product at Novell's support center, you get confronted with a field for a licence key, which is not provided with the product either. Although you can leave the field blank, I found it nonetheless confusing. Only some googling revealed the information, that support and updates  would be provided for 90 days, and extension to this duration provided as HP Care packages. While this all makes sense to me for a system sold to enterprises, I imagine selling it to private users curious about Linux, but not proficient with it, and not familiar with the distinction between free software and free beer, must lead to confusion and frustration.

Finally I decided to replace SLED with Ubuntu 12.04 (Precise) which started the second part of the adventure. The wlan was no longer actionable through the wlan key (f12). "rfkill list" revealed that the "phy0" device stayed "hard blocked". For those reading this while confronted with the same issue: The solution that finally worked after some hours of mounting frustration consisted in booting the device from a 11.04 live CD, which allows to unblock phy0. After rebooting back into 12.04, wlan works flawlessly!

Sunday, April 22, 2012

DOM vs SAX on Android

It is well documented that when working with XML on an Android device, SAX is preferable over DOM. For MyExpenses, for importing categories from an XML file, I had ignored this advice, since originally it was planned to import a limited number of small files provided with the app. But later users got the possibility to provide their own file, and it was no longer possible to exclude the case of potentially large files being provided as input.
Having implemented the import based on the SAX parser now, using Androids infrastructure for unit testing, I could easily compare the two implementations through this UnitTest, and come up with a measurement of how they perform when confronted with large files. The table lists the time the test needs to run when parsing the files with SAX or DOM on a Google Nexus S:

FileSize SAX DOM
1M 0,755 4,934
2M 1,475 8,335
4M 3,019 19,347
6M 4,756 OutOfMemoryError

Monday, March 26, 2012

Experimenting with button bar on Android as an efficient data entry interface

As suggested by a user of My Expenses, I sought for an interface that would facilitate the entry of new data and still have a consistent display of all available commands. It should also be possible to use the standard menu provided by the Android platform and triggered by the hardware menu button.
Release 1.4.8. implements these requirements. There is a simple button bar class, where each button open up a menu on long clicks, and triggers a default action on short clicks. Upon press on the menu button, a dialog offers to switch back to the traditional Android menu. There is much room for improvement with respect to the design of the popup menus.



Not sure yet how this approach will be taken up by users. If you consider it worth a try, grab MyExpenses source code at Github.

Wednesday, March 14, 2012

Multilingual documentation for an Android project with Docbook

Two interesting challenges, while writing the multilingual tutorial for My Expenses:
  1. Use one single input file facilitating translation
  2. Reference interface messages from the project's resource files instead of repeating them literally, in order to assure consistency.
For the first one, I borrowed a stylesheet from DocBook.sml that allows to generate language-specific files from the multilingual document. These can then be further processed into html and pdf with the standard Docbook XSLT.

My solution to the second one, can be found in this customization of the chunking template. Have a look at how the inline.charseq template is overridden. This is the important part:

  <xsl:choose>
  <xsl:when test="normalize-space(.)">
   .....
  </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="document($resfile)/resources/string[@name = $id]">
    </xsl:value-of></xsl:otherwise>
  </xsl:choose>

When the element has no content, localized string is looked up in the resource file, based on the role attribute of the element, stored earlier in the variable id. Now elements like <guimenuitem role="select_account"/> are rendered with their translated message.

Tuesday, March 13, 2012

Automatic generation of screenshots for a tutorial on Android app

I invested some time in finding a way to generate screenshots for the tutorial on my Android app. With now 11 images in four languages, keep the screenshots up to date when the app evolves, has become too tedious to be done manually
Monkeyrunner seems the perfect tool, but I found it very hard to have it execute a given scenario reliabily. The two main problems I encountered were:
  • Entering data in a form
  • Triggering context menu in listviews
The solution I found, involves defining a key (e.g. KEYCODE_ENVELOPE) to a backdoor in the app, that changes the activity's state in the desired way.  Then in the Monkeyrunner script, I just need to send the key at the right moment with

device.press('KEYCODE_ENVELOPE', MonkeyDevice.DOWN)

The method handling the key in the activity class is onKeyDown.
You can find examples in the classes AccountEdit, ExpenseEdit, SelectAccount and SelectCategory from here (tag r25). In the editing activities, I populate the form with data, in the selection activities, I make sure that the listview has the focus, I found no other reliable method to have the context menu triggered from Monkeyrunner.

Sunday, March 11, 2012

TextWatcher and change of device orientation

I encountered an interesting problem with a TextWatcher listening for changes in an EditText. The afterTextChanged method was called, each time, the device orientation changed. An answer on Stackoverflow let me understand what was happening: Android recreates the activity, and the automatic restoration of the state of the input fields, is happening after onCreate had finished, where the TextWatcher was added as a TextChangedListener. The solution to the problem consisted in adding the TextWatcher in onPostCreate, which is called after restoration has taken place. You can find the source in this commit of project MyExpenses on Github.