Tracking Usage

One of the long standing goals of Unity has been to provide an application focused presentation of the desktop. Under X11 this proves tricky as anyone can connect into X and doesn't necessarily have to give information on what applications they're associated with. So we wrote BAMF, which does a pretty good job of matching windows to applications, but it could never be perfect because there simply wasn't enough information available. When we started to rethink the world assuming a non-X11 display server we knew there was one thing we really wanted, to never ever have something like BAMF again.

This meant designing, from startup to shutdown, a complete tracking of an application before it started creating windows in the display server. We then were able to use the same mechanisms to create a consistent and secure environment for the applications. This is both good for developers and users as their applications start in a predictable way each and every time it's started. And we also setup the per-application AppArmor confinement that the application lives in.

Enough backstory, what's really important to this blog post is that we also get an event when an application starts and stops which is a reliable event. So I wrote a little tool that takes those events out of the log and presents them as usage data. It is cleverly called:

$ ubuntu-app-usage

And it presents a list of all the applications that you've used on the system along with how long you've used them. How long do you spend messing around on the web? Now you know. You're welcome.

It's not perfect in that it uses all the time that you've used the device, it'd be nice to query the last week or the last year to see that data as well. Perhaps even a percentage of time. I might add those little things in the future, if you're interested you can beat me too it.

posted on Fri, 14 Nov 2014 at 13:35 | permanent link

HUD for the command line

HUD shown over terminal app with commands visible

Most expert users know how powerful the command line is on their Ubuntu system, but one of the common criticisms of it is that the commands themselves are hard to discover and remember the exact syntax for. To help a little bit with this I've created a small patch to the Ubuntu Terminal which adds entries into the HUD so that they can be searched by how people might think of the feature. Hopefully this will provide a way to introduce people to the command line, and provide experienced users with some commands that they might have not known about on their Ubuntu Phone. Let's look at one of the commands I added:

UnityActions.Action {
  text: i18n.tr("Networking Status")
  keywords: i18n.tr("Wireless;Ethernet;Access Points")
  onTriggered: ksession.sendText("\x03\nnm-tool\n")
}

This command quite simply prints out the status of the networking on the device. But some folks probably don't think of it as networking, they just want to search for the wireless status. By using the HUD keywords feature we're able to add a list of other possible search strings for the command. Now someone can type wireless status into the HUD and figure out the command that they need. This is a powerful way to discover new functionality. Plus (and this is really important) these can all be translated into their local language.

It is tradition in my family to spend this weekend looking for brightly colored eggs that have been hidden. If you update your terminal application I hope you'll be able to enjoy the same tradition this weekend.

posted on Fri, 18 Apr 2014 at 12:46 | permanent link

Measuring Upstart App Launch using LTTng

One of the goals of this cycle is to decrease application startup times on the Ubuntu phone images. Part of my work there was to look at the time taken by Upstart App Launch in initializing the environment for the application. One of the tricky parts of measuring the performance of initialization is that it contains several small utilities and scripts that span multiple Upstart jobs. It's hard to get a probe inside the system to determine what is going on without seriously disrupting it.

For measuring everything together I decided to use LTTng which loads a small kernel module that records tracepoints submitted by userspace programs using the userspace tracer library. This works really well for Upstart App Launch because we can add tracepoints to each tool, and see the aggregate results.

Adding the tracepoints was pretty straight forward (even though it was my first time doing it). Then I used Thomas Voß's DBus to LTTng bridge, though I had to add signal support.

To setup your Ubuntu Touch device to get some results you'll need to make the image writable and add a couple of packages:

$ sudo touch /userdata/.writable_image
$ sudo reboot
# Let it reboot
$ sudo apt-get update
$ sudo apt-get install lttng-modules-dkms lttng-tools
$ sudo reboot
# Rebooting again, shouldn't need to, but eh, let's be sure

You then need to setup the Upstart App Launch environment variable to get it registering with LTTng:

$ initctl set-env --global LTTNG_UST_REGISTER_TIMEOUT=-1

Then you need to setup a LTTng session to run your test. (NOTE: this configuration allows all events through, but you can easily add event filters if that makes sense for your task)

$ lttng create browser-start
$ lttng enable-event -u -a
$ lttng start

To get the Upstart starting events from DBus into LTTng:

$ dbus-monitor --profile sender=com.ubuntu.Upstart,member=EventEmitted,arg0=starting | ./dbus_monitor_lttng_bridge 

And at last we can run our test, in this case starting the webbrowser once from not running and once to change URLs:

$ url-dispatcher http://ubuntu.com
# wait for start
$ url-dispatcher http://canonical.com

And then shut things down:

$ lttng stop
$ lttng destroy browser-start

This then creates a set of traces in your home directory. I pulled them over to my laptop to look at them, thougth you could analyze them on the device. For complex traces there are more complex tools that are available, but for what I needed babletrace was enough. All of this contributed to a set of results that we are no using to optimize upstart-app-launch to make applications start faster!

posted on Mon, 16 Dec 2013 at 13:17 | permanent link

Emergent Complexity

When looking at Upstart it comes off as very simple. Almost too much so. It's just events. And jobs that take those events. And not much else. You're so used to configuring every last detail of a system to ensure that it's tightly tuned for every possible scenario, certainly you need more tools than just events! When you let go of that preconception and really start to understand it, you realize that events are not only enough, but they're exactly what you need.

One might have thought – as at first I certainly did – that if the rules for a program were simple then this would mean that its behavior must also be correspondingly simple. For our everyday experience in building things tends to give us the intuition that creating complexity is somehow difficult, and requires rules or plans that are themselves complex. But the pivotal discovery that I made some eighteen years ago is that in the world of programs such intuition is not even close to correct. — Stephen Wolfram, A New Kind of Science.

And so we take these simple jobs that we've built and we start to build a system. They each just wait on a set of events, and some emit events as they go along, and the system starts to take form. But where are our initialization phases and guarantees and complex dependencies? (writing code to solve them is fun!) They still exist, but as an emergent behavior of the system. Let's look at Graphviz diagram of the Ubuntu Saucy system init:


(Graphviz | Full SVG)

Without zooming in and just looking at the shapes that emerge you start to see a natural grouping of the jobs. And there are stages of the boot. There are types of jobs that are gathered together. There'd be even more if initctl2dot could break down the runlevel job into its various values. What we see is a the complex boot of a modern operating system broken down into pieces for analysis. What we see is a model of the behavior of the system, but that model is the only place that the complexity actually exists, it becomes the emergent behavior of the system. And that, that is why Upstart can be so simple and yet be powerful enough to boot a modern Linux system.

posted on Sun, 04 Aug 2013 at 00:06 | permanent link

Application-focused Control

I love BAMF, may it die a peaceful death. BAMF was always stuck trying to solve an unsolvable problem, trying to recreate information and associations that had been lost through the X11 protocol and general fuzziness about what should happen. BAMF then had to handle a wide variety of corner cases and try to bring things back into a situation of sanity. And I loved BAMF because I didn't have to do that myself, BAMF did it, and all of its clients just got sanity. We knew when starting another display system we didn't want another BAMF.

With Mir there is a closer tie between applications as a whole and their windows. When an application asks for a session it specifies who it is, then Unity can make sure it understands who it is, and gets a chance to veto the connection. This means that Unity can check on the status of who the app says it is before it gets any windows and can track that directly throughout the application session. To do this we're using what we call the "Application ID", which for most apps you have today is the name of their desktop file (e.g., "inkscape", "gedit").

Let's look at an overly verbose message sequence diagram to see how this works. Note: all of the columns on here aren't separate processes, the diagram is made to explain this idea, not to represent the system architecture.


(svg | msc)

What we can see here is that because Upstart is doing process tracking, and making sure it knows the state of the application, Unity have have assurances of the application's name and existence. It then can work with Mir to block applications that do have proper configurations and can't be matched well. 100% matching, by design.

posted on Wed, 24 Jul 2013 at 11:55 | permanent link

Application Centric User Experience

One of the design goals of Unity was to have an Application-centric user experience. Components like the Launcher consolidate all of the windows into a single icon instead of a set like the GNOME 2 panel. Nothing else in Ubuntu thinks about applications in this way making it a difficult user experience to create. X11 worries about windows. DBus worries about connections. The kernel focuses on PIDs. None of these were focused on applications, just parts of applications. We created the BAMF Application Matching Framework (BAMF) to try and consolidate these, and while it has done a heroic job, its task is simply impossible. We need to push this concept lower into the stack.

First we looked at the display server and started thinking about how it could be more application centric. That effort resulted in Mir. Mir gets connections from applications and manages their associated windows together. They can have multiple windows, but they always get tracked back to the application that created them. Unity can then always associate and manage them together, as an application, without any trickery.

Application confinement also provides another piece of this puzzle. It creates a unified set of security policies for the application independent of how many submodules or processes exist for it. One cache directory, set of settings and policies follow the application around. Apparmor provides a consistent and flexible way of managing the policies along with the security that we need to keep users safe.

To start to look at the process management aspect of this I started talking to James Hunt about using Upstart, our process manager in Ubuntu. Working together we came up with a small little upstart user session job that can start and stop applications, and also track them. I've pushed the first versions of that to a test repository in Launchpad. What this script provides is the simple semantics of doing:

$ start application APP_ID=gedit
$ stop application APP_ID=gedit
to manage the application. Of course, the application lifecycle is also important, but Upstart provides us an guaranteed way of making sure the application stops at the end of the session.

Upstart can also help us to guarantee application uniqueness. If you try and start an application twice you get this:

$ start application APP_ID=inkscape
application (inkscape) start/running, process 30878
$ start application APP_ID=inkscape
start: Job is already running: application (inkscape)
This way we can ensure that a single icon on the launcher associates to a set of processes, managed by the process manager itself. In the past libraries like libunique have accomplished this using DBus name registration. Which, for the most part, works. Using DBus registration relies on well behaving applications, which basically guarantee their own uniqueness. By using Upstart we can have misbehaving applications, and still guarantee their uniqueness for the Unity to show the user.

We're just getting started on getting this setup and working. The schedule isn't yet final for vUDS next week, but I imagine we'll get a session for it. Come and join in and help us define this feature if it interests you.

posted on Tue, 07 May 2013 at 08:16 | permanent link

Bustle Boot Log Under Upstart

For a while I've had a little project for debugging the desktop. Basically it starts tracking all of the DBus events on the user session startup so that you can figure out what's going on. This is especially an issue for indicators, where they're started at login, and sometimes it can be hard to track what is happening.

Previously it was pretty hard to inject into the startup of the session. Getting in the middle of building a very long command line was risky and pretty fragile. Not proud of what I had to do. Now that I have Upstart user session running, I took the opportunity port this debugging script over to Upstart.

Now I have this one simple configuration file that can be dropped in /usr/share/upstart/sessions and gets started immediately after dbus:

description "Bustle Boot Log"
author "Ted Gould "

start on started dbus
stop on desktop-end

script
	rm -f ~/.cache/bustle-boot-log/boot-log.bustle
	mkdir -p ~/.cache/bustle-boot-log/
	timeout -s INT 30 bustle-pcap --session ~/.cache/bustle-boot-log/boot-log.bustle &
end script

The beauty of this is that I can inject this small little script in, and have Upstart figure out all the startup mess. I also have minimal impact on the natural desktop boot which is critcial for testing. Simple things to make debugging easier.

posted on Tue, 30 Apr 2013 at 14:59 | permanent link

Indicators in Upstart

I've started to prototype and lay the foundations for the indicators to use the Upstart User Sessions. It's an exciting change to our desktop foundations, and while it's still very fresh, I think it's important to start understanding what it can do for us. For right now you're going to need a patch to Unity and a patch to indicator-network to even get anything working, not recommended for trying at home.

Previously for indicators the way that they've worked is that a small loadable module was loaded by the panel service that had indicator specific UI in it. That plugin also took care of the responsibility to restart the indicator backend, respawning it if it crashed. While this works and it has created a robust desktop (most people don't notice when their indicator backends crash) it has had some downsides. For one, it makes it difficult to build and test new backends as you pretty much have to restart Unity to stop the previous service from getting respawned. Also all the debugging messages end up coming under the DBus process in ~/.xsession-errors because we were using DBus activation to start them.

With upstart user sessions we're now getting a lot more power and flexibility in managing the jobs in the user session, it makes sense that indicators would start to use it to control the backend services. This comes with a set of advantages.

The first one is that there is better developer control of the state of the process. It's really easy to start and stop the service:

$ stop indicator-network
$ start indicator-network
and the ever exciting:
$ restart indicator-network
All of these ensure that the same commands are run each time in a recreatable way. Plus give the user and/or developer full control.

Upstart also takes the output of each process and puts it into its own log file. So for our example here there is a ~/.cache/upstart/indicator-network.log that contains all of the junk that the backend spits out. While this is nice to just make xsession-errors cleaner, it also means that we can have a really nice apport-hook to pick up that file. Hopefully this will lead to easier debugging of every indicator backend bug because they'll have more focused information on what the issue is. You can also file general bugs with ubuntu-bug indicator-network and get that same information attached.

In the future we'll also be able to do fine tuned job control using external events. So we could have the indicator network backend not start if you don't have any networking devices, but startup as soon as you plug in that USB cellular modem. We're not there yet, but I'm excited that we'll be able to reduce the memory and CPU footprint on devices that don't have all the features of higher end devices, scaling as the features are required.

Those that know me know that I love diagrams and visualizations, and so I'll have to real quickly say that I'm excited about being able to map our desktop startup using intlctl2dot. This gives a Graphviz visualization of startup and how things will interact. I expect this to be a critical debugging tool in the future.

What's next? Getting all the indicators over to the branch new Saucy world. We also want to get application indicators using a similar scheme and get a fast responsive desktop. Hope to have a blog post or two on that in the near future.

posted on Thu, 25 Apr 2013 at 12:30 | permanent link

Inflation's Creative Destruction

Going to sleep last night I started thinking about inflation, which meant that I got to sleep later than I'd wished, but it also lead to some interesting thoughts about where the US economy is currently. Popularly inflation is considered bad, or something that needs to be controlled through monetary policy. And that we have. In the US we've seen record low inflation rates, to the point where we've lowered interest rates to where it's practically a useless lever on the economy. It seems to me that we need higher inflation.

Inflation powers the creative destruction that makes capitalism work as an economic system. For value to increase relative to inflation we must reprice things, and they must continue to have more value to the people in the economy. If weak products just stick around, with their current value in tact, they effectively stagnate as they don't get ground under the treadmill of inflation. This is the evolutionary gauntlet that destroys those who are not fit to compete. Perhaps capitalism is driven less by an invisible hand and more an invisible treadmill.

We can as a country control inflation and increase it artificially through policy in government. Policy programs like farm and transportation subsidies ensure that food prices don't rise. Starting to remove many of these would force farmers to charge more, which in turn would effect derivatives like meat and dairy to raise prices, effectively pushing inflation into play.

The economy is an ecosystem of stored value, consumers and producers. By eliminating inflation as a mechanism inside that ecosystem we've allowed the balance to be shifted and created a system that is off balance. We should adopt legislative policies to increase inflation.

posted on Wed, 03 Apr 2013 at 09:33 | permanent link

Introducing HUD 2.0

As you might have noticed in the tablet information we've put some time and effort into imaging the next steps for the HUD. For the last few months I've been leading a team to bring that into a reality on the tablet.

Screenshot of HUD

Managing complexity

One of the problems facing application developers on a device like a tablet is adding functionality without making the entire interface feel cluttered. We even made the problem harder by emphasizing a content focused strategy in our SDK. Where do you put controls? There are various tools including toolbars, but none of them scale to even a moderately complex application. With the power of today's devices ever increasing, it's clear that tablet applications are going to become more complex.

We could just tell application authors not to do it. Save that complexity for your desktop UI. But that wouldn't be convergence, that'd be creating silos for you applications to live in.

By using HUD we allow applications to expose rich functionality that is available to the user via search. Users can search through the actions exposed by the application to find the functionality that they need. We combine that with historical usage and recently used items to take into account what functionality the user uses in the application. It's the rich functionality of your application, customized for the individual user.

Designed for HUD

One of the things we realized early in the HUD 2.0 efforts is that we can no longer just passively take data from applications and make things better. We needed to go beyond menu sucking to having applications actively targeting the HUD. We're building HUD functionality directly into the SDK making it easily available for application developers to add actions that are visible in the HUD.

By providing a way for applications to export both actions and their descriptions to the HUD directly we can make that interaction much richer. We can do things like get the keywords pragmatically so that they're included next to the original item definitions. This also allows us to define actions that have additional properties that can be adjusted with UI elements, we're calling these parameterized actions.

Screenshot of HUD using a parameterized action

Parameterized actions provide a way for applications to create a small autogenerated UI for simple settings and items that can be quick to edit. Let's be clear, autogenerated UI's aren't the best UI's, but if done right can be attractive and effective. We aim to do it right. Hopefully your application has a primary UI that is beautiful and tailored for its specific task that is then supplemented with additional settings and actions in the HUD, parameterized actions are no different there.

Currently in the code we only have support for sliders of integer percentages. That's pretty limiting. We plan on expanding that to most of the base widgets in the toolkit.

Voice

While talking to yourself makes you seem crazy, talking to your tablet is just cool. With the HUD we realized that we had a relatively small data set, and so it would be possible to get reasonable voice recognition using the resources available in the device. That makes a great way to interact with an application, keyboards are chunky on any handheld device (but needed for when you're supposed to be paying attention to the person talking) and voice makes interacting much more fluid.

Screenshot of HUD doing voice

We built the voice feature around two different Open Source voice engines: Pocket Sphinx and Julius. While we started with Pocket Sphinx we weren't entirely happy with it's performance, and found Julius to start faster and provide better results. Unfortunately Julius is licensed with the 4-clause BSD license, putting it in multiverse and making it so that we can't link to it in the Ubuntu archive version of HUD. We're looking at ways to make it so that people who do want to install it from multiverse can easily use Julius, but what we'd really like is to make the Pocket Sphinx support really great. It's something we'd love help with. We're not voice experts, but some of you might be, let's make the distributable free software solution the best solution.

Enhancing Search

When we did user testing of the first version of the HUD one of the biggest problems users had was composing a search in the terms used in the applications. It turns out users search for "Send E-mail" instead of "Compose New Message". I'm sure there are even some people who want to "Clear History" but others want to "Delete" it. To help this situation we've introduced keywords that can be added as a sidecar file to legacy applications, and defined directly for libhud exported actions. These can then be searched for as well, increasing the ability of application authors to provide different ways to express the same action.

Issues

One of the issues that the HUD has in general is discoverability. How do I know that this cool new app I downloaded can do color balancing? Does every app need to run a Superbowl ad to make consumers realize their features? We've got some ideas, but come and share yours on the unity-design mailing list.

Shut up and take my app

While the source is published, we still don't have beautiful documentation and developer help out there yet. We're working on it. You're welcome to look at the source code, or just hang tight, I'll have another blog post soon.

posted on Thu, 21 Feb 2013 at 13:41 | permanent link