Hemera Application Development

The flow for creating and deploying a Hemera application is quite simple and it breaks down into the following steps:

  1. Download and install the SDK. We assume that you have already done this, as described here.
  2. Create your first hemera application
  3. Build it
  4. Deploy it
  5. Start Developer Mode

You can do this either with or without Qt Creator.

Using Qt Creator

Create the application

Hemera Application project creation

Launch QtCreator and create a new project. You should see an option named "Hemera Qt Application". Once selected, you will be presented a screen for configuring your new application. The first thing you need to do is to select the type of Hemera Application you wish to create. Available choices are:

  • QML Only, QtQuick2 : a GUI application using QtQuick 2 with no C++ logic. Needs OpenGL on the target.
  • QML and C++, QtQuick2 : a GUI application using QtQuick 2 with C++ logic. Needs OpenGL on the target.
  • QML Only, QtQuick1 : a GUI application using QtQuick 2 with no C++ logic. Use only for targets without OpenGL support.
  • QML and C++, QtQuick1 : a GUI application using QtQuick 2 with C++ logic. Use only for targets without OpenGL support.
  • C++ only, QWindow : a GUI application using QWindow with no QML support and C++ logic. Needs OpenGL on the target.
  • C++ only, QWidgets : a GUI application using QWidgets with no QML support and C++ logic. Does not require OpenGL on the target.
  • C++ only, Headless : a non GUI application

You will need then to fill in the required information needed by the application:

  • Application domain: the domain of the application. This will also be used as the application's id. It has to be in a RDNS syntax
  • Application name: the application name
  • Application version: the application's version
  • Main class name: if the application has C++ logic, the main class' name
  • Organization name: the organization's name developing the application
  • Application description: a brief description of the application and what it does

Using the IDE

Hemera Application development main screen
Note
Even though this tutorial refers to a Qt5 application, all of the following procedures also apply to any other Hemera SDK.

When creating or loading an Hemera application project in Qt Creator, you are presented with the ha file as the buildsystem (currently, only ha-based buildsystems are supported in Qt Creator). You can then use the IDE to perform development tasks - refer to Qt Creator's manual for further details.

To deploy and run applications, you will need to have your Hemera targets already configured. Read Managing Hemera Devices and Emulators from Client SDK Tools if you still did not do that. Once targets are set up, you can configure your Kits for build and deployment.

Configure screen for Hemera projects

For each Hemera device and emulator you have configured, Qt Creator associates a Kit. To build your project for a specific target, add a Kit, and select the Kit associated to your target (it has the very same name). You will then be able to configure your Kit specifically for the project. If you do not have any specific need, default configuration is more than enough.

You can now use Qt Creator standard tools for building and running the application on the target. Pressing the Play/Run button will compile the application, deploy it to your target, and start it with Developer Mode.

Using the command line

You will need to create your manifest file (ha) manually. Create a new directory for your project, and once inside create a new text file named <applicationid>.ha. Depending on your application, you can use a different configuration object:

  • SimpleCppApplication: This is the most generic template, and usually what you want to use if you are building an application with C++/Qt5
  • SimpleQmlApplication: This template is used for those QtQuick2 applications without C++ logic.
  • SimpleQtQuick1Application: Just like SimpleQmlApplication, but for QtQuick1.

Populate then your ha file in this way:

import com.ispirata.Hemera.Settings 1.0
SimpleCppApplication {
applicationId: "com.organization.my.application"
name: "My Application"
description: "My first Hemera application ever"
version: "0.1"
organization: "My Organization"
sourceFiles: ["src/mymainclass.cpp"]
resourceFiles: ["images/image1.png"
,"images/image2.jpg"
,"images/image3.jpg"
,"qml/main.qml"]
features: Features.Video | Features.Audio
qtModules: QtModules.Core | QtModules.DBus | QtModules.Gui | QtModules.Qml | QtModules.Quick | QtModules.Multimedia
hemeraModules: HemeraModules.Core | HemeraModules.Gui
}

For further details on each specific field, consult the API documentation for Hemera::Qml::Settings::Application and Hemera::Qml::Settings::SimpleCppApplication.

This ha file is already enough for building your application.

Main C++ files

Once the manifest has been done, let's have a look at the main files:

Headless applications

#include <HemeraCore/HeadlessApplication>
class MyOwnApplication : public Hemera::HeadlessApplication
{
Q_OBJECT
Q_DISABLE_COPY(MyOwnApplication)
public:
explicit MyOwnApplication();
virtual ~MyOwnApplication();
protected:
virtual void initImpl() Q_DECL_OVERRIDE Q_DECL_FINAL;
virtual void startImpl() Q_DECL_OVERRIDE Q_DECL_FINAL;
virtual void stopImpl() Q_DECL_OVERRIDE Q_DECL_FINAL;
virtual void prepareForShutdown() Q_DECL_OVERRIDE Q_DECL_FINAL;
[... other logic here ...]
};
[... logic here ...]
void MyOwnApplication::initImpl()
{
// Do things
setReady();
}
void MyOwnApplication::startImpl()
{
// Do things
setStarted();
}
void MyOwnApplication::stopImpl()
{
// Do things
setStopped();
}
void MyOwnApplication::prepareForShutdown()
{
// Do things
setReadyForShutdown();
}

As you can see, there is no main file. The macro HEMERA_HEADLESS_APPLICATION_MAIN takes care of generating an appropriate main function. The strict requirement is to implement those four methods, and process any logic which needs to be done before notifying Gravity your application is ready. Failure in calling a set* method, will leave Gravity in an unusable state.

GUI applications

Hemera provides several classes for GUI applications, both for GL capable and uncapable devices. The base classes are, respectively, Hemera::GuiApplication and Hemera::WidgetsApplication. Both provide by default window management and manage the visibility of the UI. As such, control of the main widget/window must be given to the application, which will then take care of exposing the UI depending on the state of the Orbit/Application.

We will now have a look at how to build a C++ and Qt Quick2 application. The same procedure is applicable to Qt Quick 1 (no GL) applications, just by changing the classes/plugins used. Please refer to the API documentation for that.

#include <HemeraGui/QmlGuiApplication>
class MyOwnApplication : public Hemera::QmlGuiApplication
{
Q_OBJECT
Q_DISABLE_COPY(MyOwnApplication)
public:
explicit MyOwnApplication();
virtual ~MyOwnApplication();
protected:
virtual void initImpl() Q_DECL_OVERRIDE Q_DECL_FINAL;
virtual void startImpl() Q_DECL_OVERRIDE Q_DECL_FINAL;
virtual void stopImpl() Q_DECL_OVERRIDE Q_DECL_FINAL;
virtual void prepareForShutdown() Q_DECL_OVERRIDE Q_DECL_FINAL;
[... other logic here ...]
};
[... logic here ...]
MyOwnApplication::MyOwnApplication()
: Hemera::QmlGuiApplication(new SimpleApplicationProperties, QUrl(QStringLiteral("resource://qml/main.qml")))
{
}
void MyOwnApplication::initImpl()
{
// Do things
// Here you can inject stuff in the QML context, before the loading occurs.
rootContext()->setContextProperty(QLatin1String("myCppObject"), this);
setReady();
}
void MyOwnApplication::startImpl()
{
// Do things
setStarted();
}
void MyOwnApplication::stopImpl()
{
// Do things
setStopped();
}
void MyOwnApplication::prepareForShutdown()
{
// Do things
setReadyForShutdown();
}
HEMERA_GUI_APPLICATION_MAIN(MyOwnApplication)

In the constructor, we are passing the self-generated SimpleApplicationProperties, which is an autogenerated subclass of Hemera::ApplicationProperties. This applies to Headless applications as well. As a second parameter, we are supplying the path to our main Qml file. Note the use of the resource framework via the resource:// protocol.

At this stage, QmlGuiApplication takes care of everything else. We have a window for accessing the context before it's built in initImpl: if you need to inject properties into the object before QML files loads, this is the time to do it.

HEMERA_GUI_APPLICATION_MAIN takes care of the rest.

Build your application

To build your application you'll need the hsdk executable. Our toolchain internally uses cmake and make so, if you're familiar with these tools, you'll find this process even easier. For more information about every hsdk command you'll find in the following paragraphs, execute it with the --help flag.

These are the steps to build and package your Hemera application:

  1. Move into your Hemera project directory (the one that contains the .ha file). Its path must start from your home directory at the time of writing.
  2. hsdk configure: generates support files for a Hemera project. You must invoke it the first time and every time you change your .ha file.
  3. hsdk full-build: builds your project.
Note
Don't worry if you don't see any changes to your project directory during build. The intermediate build files are hidden inside the Emulator.

These steps are intended for building for a target Emulator (i586 architecture). Building for your target Device is a matter of telling full-build about your target. Supposing we're still on the same system we used in Managing Hemera Devices and Emulators from Client SDK Tools, we will need to specify the -d berta or --device berta option on the build step. This means:

hsdk full-build -d berta

Note
configure does not require any arch parameter.

Deploy your application

You can deploy your application to an Emulator or Device.

Once your target is defined, you can deploy your application through hsdk. The output of rpmbuild or full-build is a package named _ha-<applicationid>-<version>.<arch>.rpm. This is your packaged application ready to be deployed. To deploy it to a target, simply invoke:

hsdk deploy -d <device_name> <path-to-package>

where device_name is the desired Device and path-to-package is the path to your application package.

If you want to deploy on the emulator instead,

hsdk deploy -e <path-to-package>

Run your application

For running and testing your application, you can again use hsdk.

To run your application, you have to either create an Orbit for it or launch it as an Orbital Application. If you are still unfamiliar with this concept, you should read Base Hemera Concepts first.

Applications can be launched from the client through Developer Mode on the device. Developer Mode is always enabled for development Devices and Emulators, and disabled in production Devices. This method of launching applications is to be used for the sole purpose of testing and debugging, and is not supported on production devices. You should use Gravity for multitasking on a production Device instead.

We'll cover how to launch an Orbital Application through hsdk.

Running an Orbital Application with hsdk

It's just as easy as:

hsdk launch -d <device_name> <application-id>

or, for the emulator:

hsdk launch -e <application-id>

The application will be launched and its output will be displayed on the terminal. To terminate developer mode, simply CTRL+C in your console (equivalent to an interruption signal on windows). The device will restore its active orbit and hsdk will shutdown.

If you wish to debug your application, you can use the --debug switch:

hsdk launch --debug -d <device_name> <application-id>

When launching an application this way, the GDB console will open with the application stopped and waiting for a continue command. You can then refer to GDB documentation to learn about how to use GDB for debugging your application.

Documentation for hsdk launch also covers how to run valgrind and strace with your application.