Wednesday, January 4, 2017

Scratch-Qt Snap with Ubuntu-App-Platform

Over the 2016 end-of-year holidays, I scratched an itch to write a Qt app that exercises a few capabilities.

My goals were to make:
  • QML app front end with a "Job" component. This has a button and a rectangle that rotates on animation.
  • Tap a "Job" button, and the associated C++ back end method runs in a dedicated thread (so the Qt GUI is not blocked)
  • While the Job's back end code runs, the QML animation is active (a rectangle next to the button goes from orange to purple and rotates), so the user knows that job is in process
  • When the back end code is done, it emits a signal that is heard and stops the animation: the rectangle turns back to orange and stops rotating), so the user knows the job is done
  • And, the snap obtains access to Qt and Ubuntu app libs provided by the Ubuntu-app-platform snap through the Content sharing interface. 
So, this approach would support a dashboard with lots of buttons, each of which is associated with C++ code, with a non-blocking GUI.

The app has other bits, including:
  • A simple shell (enter a command, see the result), which also has buttons to show Snap execution env
  • An oxide browser page
Nothing brand new here, just putting the pieces together for my own enjoyment :).









Let's look at some highlights.

Using the ubuntu-app-platform

As is well known now, the great thing about the ubuntu-app-platform snap is that it provides the libs (Qt/Ubuntu) needed to write an Ubuntu desktop app. Install this snap once, and use it in your app snaps through the Content Sharing interface (thus sharing disk space).

A few steps are needed.

Snapcraft.yaml 

We use the desktop-ubuntu-app-platform remote part (to pull in the ubuntu-app-platform build stuff). You can see the formal description and instructions for using this with:

snapcraft define desktop-ubuntu-app-platform

(You may need to run snapcraft update first.)

Here are the modifications you need in your snapcraft.yaml.

Define the platform plug

Define a plug that connects to the ubuntu-app-platform snap through the content interface like this:

  plugs:
    platform:
        interface: content
        content: ubuntu-app-platform1
        target: ubuntu-app-platform


This plug:
  • enables the snap to be connected to the "platform" interface
  • to access the platform slot's "ubuntu-app-platform1" content
  • by bind mounting (on interface connection) that content to the "ubuntu-app-platform" directory in my snap 

Use the platform plug

The apps section must also include platform in the list of plugs (interfaces) it uses:

apps:
  run:
    command: desktop-launch scratch-qt
    plugs: [platform, unity7, opengl, network-bind, gsettings, browser-support, pulseaudio]



Build your application part AFTER desktop-ubuntu-ap-platform

The application is a QML/C++ project that also imports Ubuntu.Components. Naturally, these libs need to be fetched during the snapcraft build process before the application that needs them is built. Therefore, you can use the convenient after: keyword to ensure the proper sequence, as follows:

parts:
    application:
        after: [desktop-ubuntu-app-platform]

CMake: make ubuntu-app-platform dir

The snap needs a directory named "ubuntu-app-platform" for the bind-mounting provided by the ubuntu-app-platform interface. I create this in CMake:

file(MAKE_DIRECTORY ubuntu-app-platform)
install(DIRECTORY "ubuntu-app-platform" DESTINATION ${DATA_DIR})


As a result, the directory is created during snapcraft in the parts/application/install directory:

$ ls parts/application/install/
components  graphics  lib  qml  ubuntu-app-platform


(My "application" part uses cmake plugin to build/install my qml/C++ app.)

Connect to the interface

The go.sh script builds (to prime stage), installs (via snap try prime), connects the interfaces, and launches the snap. The key  here is the interface connection:

snap connect scratch-qt:platform ubuntu-app-platform:platform

Update environment vars in wrapper

This snap has a wrapper script to launch qmlscene and the app.

Various environment variables need to be modified and exported to use the ubuntu-app-platform libs, including: LD_LIBRARY_PATH, QT_PLUGIN_PATH and QML2_IMPORT_PATH.


Non-blocking GUI

A key goal was to make it easy to run the C++ method associated with each  button tap without blocking the GUI, and allowing multiple C++ back-ends to run concurrently. Without implementing threads for this and moving these threads off the default GUI thread, the Qt GUI blocks until the back end processing associated with each button is completed.

Here's my approach.

I created a QML item (Job), a C++ class (Job), and registered the Job class into QML as part of my Scratchqt plugin. The Job displays as a button and a rectangle that rotates and changes color when the job is executing.

When you add a Job item, you specify its "job" string property. When you tap the Job button, it executes the JavaScript runMe() function, which starts the animation (indicating the work is in progress) and then calls the C++ Job::start(job) method.
 Job::start(job) creates an instance of the JobController class (constructed with the job so it knows which job to execute) and then emits Jobcontroller::operate signal. This operate signal is connected to the particular code to run, as explained below.

The JobController constructor creates a Jobs object on the heap.

Jobs class simply contains a method for each Job, for example: job1(), job2(), etc. These methods are where you put the back-end code to run on the particular Job button tap.

Jobs also has a jobDone signal. This is connected to Job::jobDone, as explained later.

The JobController object has a QThread. This is where the back-end execution occurs. The Jobs object is moved to the new QThread. This enables the QML GUI to remain responsive after the C++ back-end execution gets going.

JobController has an if/then/else construct to connect the "operate" signal (emitted by each Job:;start(job)) to the right Jobs slot (Jobs::job1, for example), depending on which Job it is (using the "job" that originates in the Jobs QML item). And then the QThread is started.

Lastly, JobController always connects the Jobs::jobDone signal to the Job::jobDone signal. This allows communication back into the QML so that when the particular back-end job is completed, the animation is turned off (via onJobDone).

Adding an independent Job

Add a new Job item in ThreadController.qml and adjust the values appropriately.

    Job {
        id: job5
        job: "job5"
        button_text: "Job 5"
        anchors.top: job4.bottom
    }
 

In the Jobs object jobs.h, add a new slot for your new job5 code:

public slots:
    void job1();
    void job2();
    void job3();
    void job4();
    void job5();


And in jobs.cpp, add the the method:

void Jobs::job5()
{
    qDebug() << "==== in Jobs::job5()";
    long sleepTime = 3000000;
    usleep(sleepTime);
    Q_EMIT jobDone();
}


In JobController.cpp constructor, add the if/then/else stanza to connect the operate signal to job5:

    else if (job_name == "job5")
    {  
        connect(this, &JobController::operate, jobs, &Jobs::job5);
    }


And here's the new job5 running (so is job3):


 









Monday, July 18, 2016

Running X Apps on Ubuntu Devices

Running X Apps on Ubuntu Devices You can install, launch, and use traditional debian-packaged X apps on Ubuntu devices. This may be unexpected given that Ubuntu devices do not seem to support user-installed debian packages, nor do they run the X Display Server. But it does work, courtesy of Mir/XMir and Libertine.

So here’s a bit of background to get started.

But first, please note that at this time, display and use of X apps on an external monitor is only available on the Pro5/M10 and on future devices. (BQ 4.5/E5 and Meizu MX4 do not support this feature.)

Hello Mir (Goodbye X)

Traditionally, and still on the Ubuntu Classic desktop with Unity 7, Ubuntu runs an X Display Server. Apps are debian packaged. And, they are written for X:

Due in part to X’s inherent security shortcomings, the Mir display server is now used on Ubuntu Devices under Unity 8 (although not yet by default on the desktop). XMir bridges traditional X apps to Mir. That is, apps written for X can run fine in a Mir/XMir environment:

Packages and the root file system

Ubuntu Classic has a root file system (rootfs) that is populated through installation of a carefully curated set of debian packages. At run time, users can install debian packages to add apps or modify their system.

This approach raises security concerns because debian packages execute installation scripts with root level privileges and because debian packages can alter what the rootfs provides by modifying or replacing core system components.

Ubuntu devices are designed for security and reliability. Ubuntu devices have a read-only rootfs that is small and tight, providing just what is needed and simplifying system updates. The rootfs is not modifiable by the user. Indeed it is mounted as a read-only partition. Users install apps through click packages that do not modify the rootfs.

Given all of this: how do users install debian packaged apps that use X on Ubuntu Devices? The answer is LIbertine with XMir.

Hello Libertine

Libertine is a system to manage app containers. It is specifically designed to support the many traditional X apps that are debian packaged. Each container is a separate Ubuntu rootfs populated through debian package installations. (Currently these containers are chroots: later, LXD contains will be supported. Also, currently the containers must be of the same Ubuntu series as the device: Vivid.)

So, you can install or create a libertine container, install debian packaged X apps into it, and launch them using the XApps scope. The apps access to the user’s key directories: Documents, Downloads, Music, Pictures, and Videos. So data files created and saved by an app in one container are available to apps in any other container, and indeed outside of the containers.

Let’s take a quick look at the XApps scope.

XApps Scope

This scope simply lists the containers and, for each container, it displays its apps. Here’s a look at a device with two containers. This system has two containers (Puritine and My Container). And each has a few apps:

  • Tap an app to launch it.
  • long press an app to hide it.
  • If you have any hidden apps, see them from the search icon (magnifying glass) and tap Hidden X Apps. Long press a hidden app to unhide it.
  • Note that a container with no apps does not display in the scope.
So how does one create and delete containers, and add or remove apps from them?

Libertine Container Manager

libertine-container-manager is a command line tool you use on the device to create and manage containers. This includes installing debian packaged apps into them. (These containers are created in the phablet user’s home directory and are not a part of the read-only rootfs.)

Note: libertine-container-manager currently cannot be run in the Terminal App. Instead please connect to your device from an Ubuntu system using phablet-shell.
Listing Containers
phablet@ubuntu-phablet:~$ libertine-container-manager list
puritine
my-container

The “puritine” container is pre-installed on many devices through the com.ubuntu.puritine click package (“Desktop Applications”):

phablet@ubuntu-phablet:~$ click list | grep puritine
com.ubuntu.puritine 0.11

The second container (“my-container”) was created on the device with libertine-container-manager.

Note: It is possible to pre-install customized containers through bespoke channels.
Creating a Libertine Container
You can create a new container on a device. The container needs a unique ID and (optionally) a name.

Note: The container must be the same Ubuntu series as the device, currently: vivid.

phablet@ubuntu-phablet:~$ libertine-container-manager create --id my-container --name "My Container" --distro vivid --type chroot

I: Retrieving Release
I: Retrieving Release.gpg
I: Checking Release signature
I: Valid Release signature (key id 790BC7277767219C42C86F933B4FE6ACC0B21F32)
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
[...]
Listing Apps in a Container
It’s easy to list the apps in a container. You just use the container’s id, as follows:

Note: We add the optional --json argument here and show only lines with “name” for display convenience.

phablet@ubuntu-phablet:~$ libertine-container-manager list-apps --id my-container --json | grep "\"name\""
"name": "Panel Manager",
"name": "Python (v3.4)",
"name": "Python (v2.7)",
"name": "gedit",
"name": "Help",
"name": "Notification Daemon",
"name": "Terminal",
Also note that all apps that install a .desktop file are listed by this command, although many of them are not displayed in the XApps scope since they are not appropriate.
Installing an app in a container
To install a debian package in a container, you just use install-package with the container id and the debian binary package name, as follows:

phablet@ubuntu-phablet:~$ libertine-container-manager install-package --id my-container --package terminator

The package and all of its dependencies are installed in the container. After this, assuming the package installs a .desktop file, it displays in the XApps scope and is launchable with a tap as expected.
Installing an app from a specific Launchpad PPA
By default, available debian packages are installed from the standard Ubuntu archive the chroot’s apt configuration points to. You can add a launchpad PPA, as follows:

phablet@ubuntu-phablet:~$ libertine-container-manager configure --id my-container --archive ppa:USER/PPA-NAME

(Currently, private PPAs are scheduled for an upcoming release.)

After this, you can install packages into the container as usual, including from the PPA.
Removing apps from a container
Remove a debian package from a container with:

phablet@ubuntu-phablet:~$ libertine-container-manager remove-package --id my-container --package PACKAGE_NAME
Libertine-container-manager help
Use the --help for top level help.

You can see details on each subcommand, for example remove-package, as follows:

phablet@ubuntu-phablet:~$ libertine-container-manager remove-package --help
usage: libertine-container-manager remove-package [-h] -p PACKAGE [-i ID] [-r]


optional arguments:
-h, --help show this help message and exit
-p PACKAGE, --package PACKAGE
Name of package to remove. Required. -i ID, --id ID Container identifier. Default container is used if
omitted.
-r, --readline Readline mode. Use text-based frontend during debconf
Interactions.
Updating a container
Want the debian packages in a container updated? Easy:

phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ libertine-container-manager update --id my-container
Executing a Command in a Container
phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ libertine-container-manager exec --command "apt-get update" --id my-container
Atteint http://ppa.launchpad.net vivid InRelease
Atteint http://ports.ubuntu.com vivid InRelease
Atteint http://ports.ubuntu.com vivid-updates InRelease
Atteint http://ppa.launchpad.net vivid/main armhf Packages
Atteint http://ppa.launchpad.net vivid/main Translation-en
Atteint http://ports.ubuntu.com vivid/main armhf Packages [...]

Note: Running the apt-get update command in a container may be useful to update the container’s knowledge of newly available packages without installing/updating them all. You can then see whether a package is available, with:

phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ libertine-container-manager exec --command "apt-cache policy firefox" --id my-container
firefox:
Installé : (aucun)
Candidat : 44.0+build3-0ubuntu0.15.04.1
Table de version :
44.0+build3-0ubuntu0.15.04.1 0
500 http://ports.ubuntu.com/ubuntu-ports/ vivid-updates/main armhf Packages
37.0+build2-0ubuntu1 0
500 http://ports.ubuntu.com/ubuntu-ports/ vivid/main armhf Packages

More about the Libertine Containers

As noted, the container is a directory containing an Ubuntu rootfs. Container directories are here:

phablet@ubuntu-phablet:~/.cache/libertine-container$ pwd
/home/phablet/.cache/libertine-container
phablet@ubuntu-phablet:~/.cache/libertine-container$ ls
my-container puritine
phablet@ubuntu-phablet:~/.cache/libertine-container$ cd my-container/
phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ ls
rootfs

You can get a bash shell into the container as follows:

phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ libertine-container-manager exec --command "/bin/bash" --id my-container
groups: cannot find name for group ID 1001
[...]
root@ubuntu-phablet:/#

Monday, April 7, 2014

New Unity 8 Scopes Docs


I have completed and published several documents on the Ubuntu development portal, scopes section. I hope these are useful when developing Unity 8 Scopes: 
The team also published these new docs:

Friday, March 7, 2014

Thursday, December 19, 2013

Cordova 3.3 adds Ubuntu

Upstream Cordova 3.3.0 is released just in time for the holidays with a gift we can all appreciate: built-in Ubuntu support!

Cordova: multi-platform HTML5 apps

Apache Cordova is a framework for HTML5 app development that simplifies building and distributing HTML5 apps across multiple platforms, like Android and iOS. With Cordova 3.3.0, Ubuntu is an official platform!

The cool idea Cordova starts with is a single www/ app source directory tree that is built to different platforms for distribution. Behind the scenes, the app is built as needed for each target platform. You can develop your HTML5 app once and build it for many mobile platforms, with a single command.

With Cordova 3.3.0, one simply adds the Ubuntu platform, builds the app, and runs the Ubuntu app. This is done for Ubuntu with the same Cordova commands as for other platforms. Yes, it is as simple as:

$ cordova create myapp REVERSEDOMAINNAME.myapp myapp
$ cd myapp
(Optionally modify www/*)
$ cordova build [ ubuntu ]
$ cordova run ubuntu

Plugins

Cordova is a lot more than an HTML5 cross-platform web framework though.
It provides JavaScript APIs that enable HTML5 apps to use of platform specific back-end code to access a common set of devices and capabilities. For example, you can access device Events (battery status, physical button clicks, and etc.), Gelocation, and a lot more. This is the Cordova "plugin" feature.

You can add Cordova standard plugins to an app easily with commands like this:

$ cordova plugin add org.apache.cordova.battery-status
(Optionally modify www/* to listen to the batterystatus event )
$ cordova build [ ubuntu ]
$ cordova run ubuntu

Keep an eye out for news about how Ubuntu click package cross compilation capabilities will soon weave together with Cordova to enable deployment of plugins that are compiled to specified target architecture, like the armhf architecture used in Ubuntu touch images (for phones, tablets and etc.).

Docs

As a side note, I'm happy to note that my documentation of initial Ubuntu platform support has landed and has been published at Cordova 3.3.0 docs.


Friday, November 8, 2013

Ubuntu HTML5 API docs

HTML5 API docs published

I'm pleased to note that the Ubuntu HTML5 API docs I wrote are now done and published on developer.ubuntu.com. These cover the complete set of JavaScript objects that are involved in the UbuntuUI framework for HTML5 apps (at this time). For each object, the docs show how the corresponding HTML is declared and, of course, all public methods are documented.

A couple notes:
  • I wrote an html5APIexerciser app that implements every available public method in the framework. This was helpful to ensure that what I wrote matched reality ;) It may be useful to folks exploring development of  Ubuntu HTML5 apps. The app can be run directly in a browser by opening its index.html, but it is also an Ubuntu SDK project, so it can be opened and run from the Ubuntu SDK, locally and on an attached device.
  • The html5APIexerciser app does not demonstrate the full set of Ubuntu CSS styles available. For example, the styles provide gorgeous toggle buttons and progress spinnners, but since they have no JavaScript objects and methods they are not included in the API docs. So be sure to explore the Gallery by installing the ubuntu-html5-theme-examples package and then checking out /usr/share/ubuntu-html5-theme/0.1/examples/
  • I decided to use yuidoc as the framework for adding source code comments as the basis for auto generated web docs.  After you install yuidoc using npm you can build the docs from source as follows:
  1. Get the ubuntu-html5-theme branch: bzr branch lp:ubuntu-html5-theme
  2. Move to the JavaScript directory: cd ubuntu-html5-theme/0.1/ambiance/js/
  3. Build the docs: yuidoc -c yuidoc.json . This creates the ./build directory.
  4. Launch the docs by opening build/index.html in your browser. They should look something like this 
Thanks to +Adnane Belmadiaf for some theme work and his always helpful consultation, to +Daniel Beck for his initial writeup of the Ubuntu HTML5 framework, and of course to the developer.ubuntu.com team for their always awesome work!




Friday, March 1, 2013

Apport-Valgrind 2.9 supports unpackaged executables

Apport-valgrind 2.9 picks up support for unpackaged [1] executables (thanks Martin Pitt for working with me to land my changes in trunk).

Here's what this means.
  • Previously if you ran apport-valgrind EXE, where EXE was not installed by a debian package, the process quit with a warning because it could only obtain debug symbol packages through debian dependencies
  • As of release 2.9, execution succeeds, and it obtains debug symbols packages based on  the shared object (.so) files that the EXE is linked to

Digging deeper into how it works

As explained here, apport-valgrind is a wrapper for valgrind, the venerable memory leak finder (among other things). 

Apport-valgrind first creates a sandbox directory that contains debug symbol files related to the executable you are checking for memory leaks. It then launches valgrind and points it also at the new sandbox directory. Valgrind creates memory leak stack traces, looking in the standard system directories for debug symbol files, but also in the generated sandbox directory. It uses the debug symbol files to create the most useful stack traces it can: stack traces that display source file names (instead of installed library file names) and function names (instead of "???", which is an unresolved symbol). All this is done without installing debug symbol packages onto your system: they are unpacked into the temporary sandbox directory, which is automatically deleted after use (unless an optional persistent sandbox is used). 

Release 2.9 uses a new technique for populating the sandbox directory that extends support for executables that are not installed by a package. (More on why that may be useful below.)

Flow for packaged EXE

Previously, the sandbox was populated only using debian dependencies of the debian package that installed the executable, like so:
  • Find the package that installed the executable
  • Find that package's full set of dependencies (all the way down, that is, recursively)
  • For each, get the best debug symbol package available (this depends on your system's apt configuration, for example whether you have added "ddebs.ubuntu.com", as described here)
  • Unpack the debug symbol packages into the sandbox
This code path still exists and is used for packaged executables.

Flow for unpackaged EXE

With 2.9, the sandbox is populated with the debug packages related to the executable's linked .so files, as reported by ldd, like so:
  • Use ldd to determine the executable's linked shared libraries (.so files)
  • Find the package that installed each linked shared library
  • For each, get the best debug symbol package available
  • Unpack the debug symbol packages into the sandbox

Use case

One use case I see is that one can now write a C program specifically to memory check a library with apport-valgrind simply by including and using the library. You do not need to rely only on existing debian packages to find executables that use the libraries in order to memory check them. And, you can target your C program to precisely target what you want to memory check, and no more.

For example: libappindicator.

As an exercise, I wanted to find memory leaks in application indicators (the icons on the top right like power, network, etc.), which means I needed to launch an app indicator at the command line with apport-valgrind (apport-valgrind EXE). So I tried to kill those processes, and they relaunched automatically. 

So I thought: write my own app indicator -- which turned out to be unnecessary: I found some sample C code that demonstrates how to write a simple application indicator here on developer.ubuntu.com. (Scroll down to "Typical usage (C version)".)

So I grabbed it. It includes a libappindicator header file:

#include <libappindicator/app-indicator.h>

I compiled and linked this code, like so:

$ gcc myappindicator.c $(pkg-config --cflags --libs appindicator3-0.1) -o myappindicator.o 

That produces the unpackaged executable myappindicator.o

Running this at the command line (./myappindicator.o) creates a new icon in the appindicator area that has a menu and pops up a dialog with a text editing area. The indicator icon's menu has a Quit item, which works as expected, quitting the application and removing its indicator, so all is well.

Then, I ran it under apport-valgrind [2], like so:
$ apport-valgrind ./myappindicator.o 

And voila, the valgrind log is generated: ./valgrind.log

This sample C code could be simplified to more precisely target (memory check) libappindicator functions.

Quality of the unpackaged stack traces?

OK, so it works. But does it work well? That is, can one expect the same number of unresolved symbols for an unpackaged executable as for its identical packaged version, even though the code paths to create the sandbox are quite different?

Easy to find out by running apport-valgrind twice, once on a normal packaged executable found on the current PATH (for example apport-valgrind notify-send), and then again on an instance of notify-send simply copied to the current directory (which makes it unpackaged, since dpkg cannot find any package that owns it in this location, and which invokes the new ldd-based code path instead of the dependency based code path). Then counting the number of unresolved symbols with grep, like so:

Packaged:
$ apport-valgrind notify-send 
..
$ grep -c \?\?\? valgrind.log
89

Unpackaged:
$ cp $(which notify-send) .
$ apport-valgrind ./notify-send 
..
$ grep -c \?\?\? valgrind.log
89

Success! The same number of unresolved symbols in both cases means that the unpackaged stack traces are (here, at least) just as good as the packaged stack traces.

Footnotes

[1] You can tell if an executable is packaged with dpkg -S $(which EXE). For example, to find the package that installed ls:

$ dpkg -S $(which ls)
coreutils: /bin/ls


The package is coreutils.

[2] Always upgrade your system (apt-get update and apt-get dist-upgrade) before running apport-valgrind in order to increase the quality of the stack traces by ensuring the installed libraries are the most recent and therefore will match with the most recent debug symbol packages.