Showing posts with label Ubuntu Touch. Show all posts
Showing posts with label Ubuntu Touch. Show all posts

Sunday, November 23, 2014

Your Shot Ubuntu Touch Scope

You might have heard about Ubuntu Touch, and one of unique feature of Ubuntu Touch is Scope. Recently they also announced Ubuntu Touch Scope competition. This got me interested, I wanted to learn about Scope development, so I thought to take part as well in the competition.

You can get more information about competition here.

Recently I discovered Your Shot photo community, I like pictures uploaded there and I visit site every day to checkout newly updated photos, so I thought it is good candidate for Scope development and I decided to write score for Your Shot photo community.

Your Shot has nice Jason based web API and I was able to create scope quite easily using Ubuntu Touch socpe's Jason template. In fact I was able to get decent working scope in few hours using template. Documentation is also quite good and rich with API Reference, Guide and Tutorials.

Here is demo for the same running on my desktop.


And Few snapshot.





It looks like now I am ready to write more complex Scope but may be later.

Saturday, September 28, 2013

Dealing with device for Ubuntu Touch development

Lately I am working on Ubuntu Touch Calendar application. Recently I also got device and now I wanted to run and test application on real device.

So it seems there are two type of Ubuntu Touch image,
one cdimage-touch, which is read-write image but it does not support over the air update and
other ubuntu-system, which is read only, but which can be updated over the air

For development purpose its better to use cdimage-touch, as you can transfer file from computer to device and test it as its read-write. Its not possible with ubuntu-system image. But if you just want to see how Ubuntu Touch looks and test applications then ubuntu-system image is good.

You can follow steps mentioned here, to install appropriate image on device.

Now we have proper image on device, then following are some command which can be used to install the application and transfer file form computer to device.

adb push can be used to tranfer file from computer to device, just like copy
adb push tests/autopilot/calendar_app/tests/test_calendar.py /usr/lib/python2.7/dist-packages/calendar_app/tests/
BTW, " /usr/lib/python2.7/dist-packages/" is the path where test case are installed by default on device. And above command is coping updated test case file to device.

If you want to run test on device then you can use following command on your desktop terminal.
phablet-test-run calendar_app
Same way we can transfer QML files as well. Like below.
adb push YearView.qml /usr/share/calendar-app/YearView.qml
It seems "/usr/share/" is path where applications are installed.

If you want to install complete application built from source code, then you can run following command to build application from source. You need to run this command from directory where debian folder is residing.
debuild -uc -us -b
This will generate .deb file in parent folder. You can copy this file to device via adb push. Then you can goto device's shell by adb shell command.
adb push DEB_FILENAME.deb /tmp
adb shell
And finally install .deb by running following command on device's shell.
cd /tmp
dpkg -i DEB_FILENAME.deb
Now you should be able to run latest installed app.

Sunday, September 22, 2013

Un-boxing Nexus 4

I recently received Nexus 4. Here are few snaps.


Box contains USB cable, power adapter in which you can plug in USB cord to charge the device and user manual.


Device is quite nice looking, but I am going to use it for testing Ubuntu Touch.


After firing some command from here, I was able to boot Ubuntu Touch on it.


Friday, August 30, 2013

Ubuntu Touch Calendar prototype for new design


Lately I am working on Ubuntu Touch's Calendar core app. Recently I tried to create a prototype for calendar to show how new design looks for the app.

Here if demo on youtube.



And following are few snaps from prototype.






Sunday, April 14, 2013

Audiobook Reader for Ubuntu-Touch

I have been exploring and working on Ubuntu-Touch for some time now. I have wrote some QML code for official Ubuntu-Touch calendar app and mean time I was also working on porting my Audiobook Reader application. This porting exercise helped me to understand how mature SDK is and also helped me to learn the SDK.

There were some minor issue with Ubuntu-Touch SDK, but nothing serious that can affect the work. As per Ubuntu-Touch development guideline, they prefer QML/Javascript and suggest to avoid C++ code as much as possible. This will help to make sure most of application is compatible for most Ubuntu platform. I tried to follow guideline and tried to not use C++ till now for app. I found myself missing C++ now and then, sometimes there are plugins that we can use instead and sometime there is no alternative. Mostly I missed the File IO, surely SDK team will come up with something, but till now there is no solution.

Anyway, I did not faced any major issue and was able to create initial version of Audiobook Reader quite easily without much problem. Following is demo.


Emitting signal from Javascript in QML application

While I was working on Ubuntu-Touch core app calendar, I wanted to emit signal from java script to QML code.

As such there is no official way provided by Qt framework, but we can try some workaround for this. Initially I used observer pattern to notify QML code from javascript. but I needed to wrote quite handful of code, and I did not liked the solution, I asked my team mates in calendar team and Frank suggested quite neat solution for this.

His suggestion was to create a temporary QtObject in javascript and use it for notification. Following is code for the same.

In following code, I created a QtObject in javascript with dataChanged signal defined in it.

eventsNotifier = Qt.createQmlObject('import QtQuick 2.0; QtObject { signal dataChanged }', Qt.application, 'EventsNotifier');
Now, we can use this object to emit signal to QML code, like this.

function someFunc() {
 ...
 ...
 eventsNotifier.dataChanged();
}
In QML code, we need to attach slot to dataChanged signal,like below.

    import "test.js" as TestJS

    function reload() {
        ...
        ...
    }
    Component.onCompleted: {
        TestJS.eventsNotifier.dataChanged.connect(reload);
    }
This is all, simple and neat.

Thursday, April 4, 2013

Accessing Amazon AWS service from QML/Javascript

Sometime back I published a post that shows how to access Amazon Web Service using Qt. You can find original post here. Now that trend is to code everything from QML and Javascript ( at-least Ubuntu Touch is following that path to make it as device independent as possible), I tired to access AWS service from using pure QML and Javascript.

I required to use external Crypto library for HMACSHA1 algorithm but everything else can easily be done with pure QML/Javascript.

Following is code i used for downloading Book cover image from Amazon AWS.

First all to communicate with AWS you required to have AWS access key id and Secret Access key. You can get it from here. I am also importing the Crypto library, for using HmacSHA1 implementation. I am using crypto-js Library. You can download required the same from here.

.import "JSLib/rollups/hmac-sha1.js" as Crypto

//key and password, required to sign the request using HMACSHA1
var AWS_KEY = "KEY";
var AWS_PASS = "PASSWORD";
var END_POINT = "http://ecs.amazonaws.com/onca/xml";
var AWS_TAG = "TAG"

Now we have required information, we can are ready to create request. In following code, I am putting all required parameter in a map and then using it to create signature and URL. We also need to encode parameter, I am using encodeURIComponent for encoding required parameter.
function downloadCover( author,bookName,callback) {

    var queryItems = {};
    queryItems["AWSAccessKeyId"] = AWS_KEY;
    queryItems["AssociateTag"] = AWS_TAG;
    queryItems["Author"] = encodeURIComponent(author);
    queryItems["Keywords"] = encodeURIComponent(bookName);
    queryItems["Operation"] = "ItemSearch";
    queryItems["ResponseGroup"] = "Images";       
    queryItems["SearchIndex"] = "Books";
    queryItems["Service"] = "AWSECommerceService";
    queryItems["SignatureMethod"] = "HmacSHA1";
    queryItems["Timestamp"] = encodeURIComponent( new Date().toISOString());
    queryItems["Signature"] = createSignature(queryItems);


    var downloadUrl = createUrl(queryItems);
    sendNetworkRequest(downloadUrl,callback);
}
Following is code for creating signature. Creating signature is the only tricky part to make code works as expected. I am using HmacSHA1 from Crypto-JS lib. This function return WordArray object, which can be converted to HEX string, binary string or base64. Once we have HmacSHA1 hash of request, we need to convert it to Base64. I was not able to use base64 function from Crypto-JS library due to some error. I decided to copy base64 function from library directly to my js file and use it. Then finally we need to encode this base64 output, which we can be used as signature while sending request.
function createSignature(queryItems) {
    var strToSign = "GET\n";
    strToSign += "ecs.amazonaws.com\n";
    strToSign += "/onca/xml\n"

    for( var prop in queryItems ) {
        if( prop === "Signature") {
            continue;
        }

        strToSign += ( prop+"="+ queryItems[prop]);
        strToSign += "&"
    }
    //removing last &
    strToSign = strToSign.slice(0,strToSign.length-1)


    var signature = Crypto.CryptoJS.HmacSHA1(strToSign, AWS_PASS);
    signature = base64(signature);

    return encodeURIComponent(signature);
}

Now we are almost done, all we need to do is to use created signature and make HTTP request. Following code shows how. There is nothing new here. I am creating complete URL from all required parameter and making request using this URL by XMLHttpRequest object.

function createUrl(queryItems )
{
    var url = END_POINT+"?";

    for( var prop in queryItems ) {
        url += ( prop+"="+ queryItems[prop]);
        url += "&"
    }
    //removing last &
    url = url.slice(0,url.length-1);
    return url;
}

function sendNetworkRequest(url,callback) {
    var http = new XMLHttpRequest();
    http.onreadystatechange = function() {
        if (http.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
            console.log("Headers -->");
            console.log(http.getAllResponseHeaders ());
            console.log("Last modified -->");
            console.log(http.getResponseHeader ("Last-Modified"));

        } else if (http.readyState === XMLHttpRequest.DONE) {
            console.log(http.responseText);
            callback(http.responseText);
        }
    }

    http.open("GET", url);
    http.send();
}