23
Plugin-based IVI Architectures with Qt Vladimir Moolle, Krzysztof Krzewniak, Integrated Computer Solutions, Inc.

Plugin-based IVI Architectures with Qt

  • Upload
    ics

  • View
    237

  • Download
    7

Embed Size (px)

Citation preview

Page 1: Plugin-based IVI Architectures with Qt

Plugin-based IVI Architectures with QtVladimir Moolle, Krzysztof Krzewniak,Integrated Computer Solutions, Inc.

Page 2: Plugin-based IVI Architectures with Qt

Plugins as such -- what are they?

• One of the ways of making an IVI system more flexible in terms of testing, deployment and maintainability

• Plugins are dynamic (shared) libraries, loaded by the application “explicitly” (not linked to), standard example -- your favorite image editor (probably) or Qt Creator

• A curious Qt-specific case -- static “plugins”, mostly an artifact of the differences between build / deploy process of monolithic and non-monolithic applications (Note / question: has anyone seen static plugins outside of Qt?)

• Note: for static VS dynamic libraries 101, you can visit:https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_applicationhttp://www.network-theory.co.uk/docs/gccintro/gccintro_25.html

2

Page 3: Plugin-based IVI Architectures with Qt

Plugins in Qt the framework

• Why? Ease of extending the framework / applications (example: adding a new database driver does not involve Qt libraries’ or even application rebuild)

• Used for: database drivers (above), image formats, etc.

• Designer and Qt Creator heavily rely on plugins as well

• You can define your own plugin formats

• Note -- for the description of the mechanism, check:http://doc.qt.io/qt-5/plugins-howto.html https://wiki.qt.io/Plugins http://doc.qt.io/qt-5/plugins.html

3

Page 4: Plugin-based IVI Architectures with Qt

Plugins in QML

• It goes without question that QML is the technology of choice for automotive IVIs, when it comes to Qt

• The “standard” QML plugins (referenced by “plugin” entries in qmldir) are QQmlExtensionPlugin-based and provide custom C++-implemented components as well as register the types; QQmlExtensionPlugin rely on the regular plugin loading mechanism (see the previous slide)

• Unlike the regular plugins (which are enumerated and loaded at startup), the QML ones have traditionally been lazy-loaded (Question to the audience: is this the case with the QML compiler?), meaning, a plugin may even never be loaded with certain execution paths (note: whole module / plugin “chains” / trees can be left out)

4

Page 5: Plugin-based IVI Architectures with Qt

Fundamentals of a good plugin-based IVI architecture• Plugin interfaces and what the plugins supply should be chosen to match the project’s

specifics in terms of intended levels of component reusability, team setup, field deployment setup, etc.

• If possible, inter-plugin dependencies should be minimized or explicitly manifested, as otherwise deployment and API compatibility issues might arise.

5

Page 6: Plugin-based IVI Architectures with Qt

• The part of the system responsible for loading the plugins and providing an interface the plugins can use to influence the IVI (request popups, interruptions, etc.) should be a library.This ensures plugins can be developed and tested independently (including the ability to use mock setups in case of hardware scarcity scenarios etc.)

Fundamentals of a good plugin-based IVI architecture (core functionality separation)

6

Main IVI Binary Core Library

Plugin 1

Plugin n

Page 7: Plugin-based IVI Architectures with Qt

Fundamentals of a good plugin-based IVI architecture (IP protection)• Relying on fixed interfaces and compiled binary code, can help protect both the 3rd party

suppliers’ and the IVI vendor’s IP

7

Plugin 1 Vendor Plugin 2 VendorIVI Vendor

Plugin-to-core library interface(bi-directional)

Page 8: Plugin-based IVI Architectures with Qt

Example IVI architecture (overview)

• To illustrate some possible approaches, an example IVI architecture was implemented

• The demo architecture does not utilize QML plugins, but rather uses QPluginLoader directly, as the plugins in the demo architecture not only provide the QML types but also enough information to compose the UI out of those types’ instances

• Three “types” of plugins are supported:• Feature plugins -- realizing the actual functionality like phone or media management• Layout plugins -- defining the way feature-provided visuals (feature previews, shortcuts,

views and popups -- more on that below) are organized on screen• Theme plugins -- responsible for customizing the common controls and providing a global

palette

8

Page 9: Plugin-based IVI Architectures with Qt

Feature Interface(non-virtual methods stripped)class FeatureInterface{public: virtual void cleanup() {}

virtual void installTranslations(QCoreApplication *app) const { Q_UNUSED(app) } virtual void registerTypes() const {} virtual void exportContextProperties(QQmlContext *context) const { Q_UNUSED(context) }

virtual QUrl previewItemUrl() const = 0; virtual QUrl mainItemUrl() const = 0; virtual QUrl shortcutUrl() const = 0;

virtual int majorVersion() const { return 0; } virtual int minorVersion() const { return 0; }};

9

Page 10: Plugin-based IVI Architectures with Qt

Main Layout Interface(non-virtual methods stripped)class MainLayoutInterface{public: virtual void cleanup() {}

virtual QUrl layoutRootUrl() const = 0; virtual void exportContextProperties(QQmlContext *context) const { Q_UNUSED(context) }

virtual int majorVersion() const { return 0; } virtual int minorVersion() const { return 0; }};

10

Page 11: Plugin-based IVI Architectures with Qt

Theme Interface(non-virtual methods stripped)class ThemeInterface{public: virtual void cleanup() {}

virtual void addImageProviders(QQmlEngine *e); virtual QUrl mainThemeObjectUrl() const = 0;

virtual int majorVersion() const { return 0; } virtual int minorVersion() const { return 0; }};

11

Page 12: Plugin-based IVI Architectures with Qt

Example IVI architecture (resource initialization, QML paths and type registration)• Plugin resources (QRC) are initialized automatically, as plugins are shared libraries

(see http://doc.qt.io/qt-5/resources.html#using-resources-in-a-library for an intro)

• The QRC file names can be the same (say, “Resource.qrc”) across different plugins, given the nature of QRC initialization in shared libraries (and plugins are just those, again)

• In contrast, QML (and not only) paths in resources should be unique (and probably, version-based) so when a new version of a plugin is loaded, there would be no confusion on the side of the resource system or the QML engine

• Note: QML type registrations are not per-engine, but rather global, i.e.

qmlRegisterSingletonType <Phone::Controller>("PhoneFeature", majorVersion(), minorVersion(), "PhoneController" , Phone::Controller::qmlInstance);

12

Page 13: Plugin-based IVI Architectures with Qt

Example IVI architecture (the core library)• The core library registers the common QML types like:

• Panels• Buttons• ThemableItem’s -- basic Items that can be themed using enums• TextLabel’s -- basic text items with enum-based coloring

• It manages the feature model, a QAbstractListModel subclass exposing the loaded features’ properties (like main QML item’s URL)

• It provides an API for the plugins to request and dismiss popups, with the option to have the plugin notified that its popup was dismissed through a callback

• It also takes care of providing a theme manager object as well as a base class for new theme definitions

13

Page 14: Plugin-based IVI Architectures with Qt

Plugin loading

• Code flow, simplified: QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); const QJsonObject metaData = loader.metaData(); auto it = metaData.find(QLatin1String("IID")); if (it != metaData.constEnd()) { const QString iid = it.value().toString(); if (iid.compare(QLatin1String(FeatureInterface_iid )) == 0) { FeatureInterface *interface = qobject_cast<FeatureInterface*>(loader.instance()); if (interface) { interface->installTransaltions(qApp); interface->registerTypes(); interface->exportContextProperties(engine->rootContext()); m_featureModel->addFeature(interface); } } //Other interface iid cases }

14

Page 15: Plugin-based IVI Architectures with Qt

Plugins: physical structure(the perils of double moc-ing)

• Note: in case of QObject-based plugin interfaces, be sure to not have their header files in HEADERS in both the plugins and the core library, as that would lead to MOC-generated object / binary code linked into both as well

• Consequently, do not share the plugin interface headers via .pri files, but rather use INCLUDEPATH

• Lastly, for plugins to even be able to link, the MOC-produced code for the interface classes should reside in a shared library (in the demonstrated architecture, the same applies to non-QObject-based interfaces and the core library)

15

Page 16: Plugin-based IVI Architectures with Qt

Plugins: physical structure(continued)

• The arrows in the diagram below show the link- and run-time dependencies of the plugin code on the shared code in the core library

16

Core Library Binary code for the plugin interface Plugin 1 .Binary code for the plugin’s

implementation of the interface

Plugin n .Binary code for the plugin’s implementation of the interface

Page 17: Plugin-based IVI Architectures with Qt

Demo: empty IVI

• No layout• No theme• No features

17

Page 18: Plugin-based IVI Architectures with Qt

Demo: a single feature in a layout, themed

• A phone management feature(just a mock)

• Wouldn’t work on its own, so a tiled layout is used

• Requires a theme to be usable

18

Page 19: Plugin-based IVI Architectures with Qt

Demo: an alternative layout

• Another layout plugin added and dynamically picked

• Switching between the layouts on the fly is perfectly possible and seamless

19

Page 20: Plugin-based IVI Architectures with Qt

Demo: another theme

• Another theme added

• Themes can be changed dynamically

20

Page 21: Plugin-based IVI Architectures with Qt

Demo: a pure QML plugin

• Extra features can be added as pure QML plugins

• Pure QML plugins don’t get to add any context properties and custom C++ types

21

Page 22: Plugin-based IVI Architectures with Qt

Demo: reloading a plugin

22

• Plugins can be reloaded, if a new version is available

• Technically, this leaves the plugin library in application memory, but all data structures (most importantly, QML items) created by the old plugin are cleaned up (garbage collected)

Page 23: Plugin-based IVI Architectures with Qt

Thank you!The authors can be reached at:

[email protected][email protected]

The source and these slides are soon coming to https://github.com/vmoolle/qtsummit2017demo

Questions?