Merge lp:~abreu-alexandre/webbrowser-app/xenial-fix-application-name-setup into lp:webbrowser-app/xenial

Proposed by Alexandre Abreu
Status: Needs review
Proposed branch: lp:~abreu-alexandre/webbrowser-app/xenial-fix-application-name-setup
Merge into: lp:webbrowser-app/xenial
Diff against target: 316 lines (+110/-37)
10 files modified
src/app/browserapplication.cpp (+32/-24)
src/app/browserapplication.h (+1/-2)
src/app/config.h.in (+0/-1)
src/app/single-instance-manager.cpp (+39/-3)
src/app/single-instance-manager.h (+1/-1)
src/app/webbrowser/webbrowser-app.cpp (+1/-1)
src/app/webcontainer/webapp-container.cpp (+27/-1)
src/app/webcontainer/webapp-container.h (+1/-0)
tests/autopilot/webapp_container/tests/__init__.py (+4/-0)
tests/unittests/single-instance-manager/tst_SingleInstanceManagerTests.cpp (+4/-4)
To merge this branch: bzr merge lp:~abreu-alexandre/webbrowser-app/xenial-fix-application-name-setup
Reviewer Review Type Date Requested Status
Ubuntu Phablet Team Pending
Review via email: mp+294395@code.launchpad.net

Commit message

Fix container/webbrowser app_id; Properly set applicationname based on package name and app name

Description of the change

Fix container/webbrowser app_id; Properly set applicationname based on package name and app name

To post a comment you must log in.

Unmerged revisions

1418. By Alexandre Abreu

Fix container/webbrowser app_id; Properly set applicationname based on package name and app name

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/app/browserapplication.cpp'
--- src/app/browserapplication.cpp 2016-03-29 11:01:18 +0000
+++ src/app/browserapplication.cpp 2016-05-11 16:04:27 +0000
@@ -98,16 +98,6 @@
98 return host;98 return host;
99}99}
100100
101QString BrowserApplication::appId() const
102{
103 Q_FOREACH(const QString& argument, m_arguments) {
104 if (argument.startsWith("--app-id=")) {
105 return argument.split("--app-id=")[1];
106 }
107 }
108 return QString();
109}
110
111#define MAKE_SINGLETON_FACTORY(type) \101#define MAKE_SINGLETON_FACTORY(type) \
112 static QObject* type##_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine) { \102 static QObject* type##_singleton_factory(QQmlEngine* engine, QJSEngine* scriptEngine) { \
113 Q_UNUSED(engine); \103 Q_UNUSED(engine); \
@@ -119,36 +109,54 @@
119MAKE_SINGLETON_FACTORY(MimeDatabase)109MAKE_SINGLETON_FACTORY(MimeDatabase)
120MAKE_SINGLETON_FACTORY(Direction)110MAKE_SINGLETON_FACTORY(Direction)
121111
122112bool BrowserApplication::initialize(const QString& qmlFileSubPath
123bool BrowserApplication::initialize(const QString& qmlFileSubPath)113 , const QString& appId)
124{114{
125 Q_ASSERT(m_window == 0);115 Q_ASSERT(m_window == 0);
126116
117 if (appId.isEmpty()) {
118 qCritical() << "Cannot initialize the runtime environment: "
119 "no application id detected.";
120 return false;
121 }
122
127 if (m_arguments.contains("--help") || m_arguments.contains("-h")) {123 if (m_arguments.contains("--help") || m_arguments.contains("-h")) {
128 printUsage();124 printUsage();
129 return false;125 return false;
130 }126 }
131127
132 // Handle legacy platforms (i.e. current desktop versions, where
133 // applications are not started by the Ubuntu ApplicationManager).
134 if (qgetenv("APP_ID").isEmpty()) {
135 QString id = appId();
136 if (id.isEmpty()) {
137 id = QStringLiteral(APP_ID);
138 }
139 qputenv("APP_ID", id.toUtf8());
140 }
141 // Ensure that application-specific data is written where it ought to.128 // Ensure that application-specific data is written where it ought to.
142 QStringList appIdParts =129 QStringList appIdParts = appId.split('_');
143 QString::fromUtf8(qgetenv("APP_ID")).split('_');130
144 QCoreApplication::setApplicationName(appIdParts.first());131 QCoreApplication::setApplicationName(appIdParts.first());
145 QCoreApplication::setOrganizationDomain(QCoreApplication::applicationName());132 QCoreApplication::setOrganizationDomain(QCoreApplication::applicationName());
133
146 // Get also the the first two components of the app ID: <package>_<app>,134 // Get also the the first two components of the app ID: <package>_<app>,
147 // which is needed by Online Accounts.135 // which is needed by Online Accounts.
148 QString unversionedAppId = QStringList(appIdParts.mid(0, 2)).join('_');136 QString unversionedAppId = QStringList(appIdParts.mid(0, 2)).join('_');
149137
150 // Ensure only one instance of the app is running.138 // Ensure only one instance of the app is running.
151 if (m_singleton.run(m_arguments)) {139 // For webapps using the container as a launcher, the predicate that
140 // is used to determine if this running instance is a duplicate of
141 // a running one, is based on the current APP_ID.
142 // The app id is formed as: <package name>_<app name>_<version>
143
144 // Where the <package name> is specified in the the manifest.json as
145 // "appName" and is specific for the whole click package.
146
147 // The <app name> portion is based on the desktop file name and is a short
148 // app name. This name is meaningful when more than one desktop file is
149 // found in a given click package.
150
151 // IMPORTANT:
152 // 1. When a click application contains more than one desktop file
153 // the bundle is considered a single app from the point of view of the
154 // cache and resource file locations. THOSE FILES ARE THEN SHARED between
155 // the instances.
156 // 2. To make sure that if more than one desktop file is found in a click package,
157 // those apps are not considered the same instance, the instance existance predicate
158 // is based on the <package name> AND the <app name> detailed above.
159 if (m_singleton.run(m_arguments, appId)) {
152 connect(&m_singleton, SIGNAL(newInstanceLaunched(const QStringList&)),160 connect(&m_singleton, SIGNAL(newInstanceLaunched(const QStringList&)),
153 SLOT(onNewInstanceLaunched(const QStringList&)));161 SLOT(onNewInstanceLaunched(const QStringList&)));
154 } else {162 } else {
155163
=== modified file 'src/app/browserapplication.h'
--- src/app/browserapplication.h 2016-01-15 09:29:22 +0000
+++ src/app/browserapplication.h 2016-05-11 16:04:27 +0000
@@ -45,7 +45,7 @@
45 BrowserApplication(int& argc, char** argv);45 BrowserApplication(int& argc, char** argv);
46 ~BrowserApplication();46 ~BrowserApplication();
4747
48 bool initialize(const QString& qmlFileSubPath);48 bool initialize(const QString& qmlFileSubPath, const QString& appId);
49 int run();49 int run();
5050
51protected:51protected:
@@ -63,7 +63,6 @@
63 void onNewInstanceLaunched(const QStringList& arguments) const;63 void onNewInstanceLaunched(const QStringList& arguments) const;
6464
65private:65private:
66 QString appId() const;
67 QString inspectorPort() const;66 QString inspectorPort() const;
68 QString inspectorHost() const;67 QString inspectorHost() const;
6968
7069
=== modified file 'src/app/config.h.in'
--- src/app/config.h.in 2015-05-14 05:57:01 +0000
+++ src/app/config.h.in 2016-05-11 16:04:27 +0000
@@ -23,7 +23,6 @@
23#include <QtCore/QDir>23#include <QtCore/QDir>
24#include <QtCore/QString>24#include <QtCore/QString>
2525
26#define APP_ID "webbrowser-app"
27#define REMOTE_INSPECTOR_PORT 922126#define REMOTE_INSPECTOR_PORT 9221
2827
29inline bool isRunningInstalled()28inline bool isRunningInstalled()
3029
=== modified file 'src/app/single-instance-manager.cpp'
--- src/app/single-instance-manager.cpp 2016-04-08 13:49:25 +0000
+++ src/app/single-instance-manager.cpp 2016-05-11 16:04:27 +0000
@@ -33,12 +33,48 @@
33#include "single-instance-manager.h"33#include "single-instance-manager.h"
3434
35namespace {35namespace {
36
36const int kWaitForRunningInstanceToRespondMs = 1000;37const int kWaitForRunningInstanceToRespondMs = 1000;
37const int kWaitForRunningInstanceToAckMs = 1000;38const int kWaitForRunningInstanceToAckMs = 1000;
38const int kDataStreamVersion = QDataStream::Qt_5_0;39const int kDataStreamVersion = QDataStream::Qt_5_0;
39const QString kHeaderToken = QStringLiteral("MESSAGE");40const QString kHeaderToken = QStringLiteral("MESSAGE");
40const QString kAckToken = QStringLiteral("ACK");41const QString kAckToken = QStringLiteral("ACK");
41}42
43QString getProfilePathFromAppId(const QString& appId)
44{
45 QString profilePath =
46 QStandardPaths::writableLocation(QStandardPaths::DataLocation);
47
48 QStringList appIdParts = appId.split('_', QString::SkipEmptyParts);
49
50 QString appDesktopName;
51
52 // We try to get the "short app name" to try to uniquely identify
53 // the single instance profile path.
54
55 // In cases where you have a single click with multiple apps in it,
56 // the "app name" as defined in the click manifest.json file will be
57 // a proper way to distinguish a unique instance, it needs to take
58 // the desktop name into account.
59
60 // At the moment there is no clean way to get those click app name
61 // paths, see:
62 // https://launchpad.net/bugs/1555542
63
64 if (appIdParts.size() >= 3) {
65 // Assume that we have a APP_ID that corresponds to:
66 // <manifest app name>_<desktop app name>_<version>
67 appDesktopName = appIdParts[1];
68 } else {
69 // We either run on desktop or as the webbrowser
70 appDesktopName = appIdParts.first();
71 }
72
73 return profilePath + QDir::separator() + appDesktopName;
74}
75
76}
77
4278
43SingleInstanceManager::SingleInstanceManager(QObject* parent)79SingleInstanceManager::SingleInstanceManager(QObject* parent)
44 : QObject(parent)80 : QObject(parent)
@@ -54,13 +90,13 @@
54 return false;90 return false;
55}91}
5692
57bool SingleInstanceManager::run(const QStringList& arguments)93bool SingleInstanceManager::run(const QStringList& arguments, const QString& appId)
58{94{
59 if (m_server.isListening()) {95 if (m_server.isListening()) {
60 return false;96 return false;
61 }97 }
6298
63 QDir profile(QStandardPaths::writableLocation(QStandardPaths::DataLocation));99 QDir profile(getProfilePathFromAppId(appId));
64 if (!profile.exists()) {100 if (!profile.exists()) {
65 if (!QDir::root().mkpath(profile.absolutePath())) {101 if (!QDir::root().mkpath(profile.absolutePath())) {
66 qCritical() << "Failed to create profile directory,"102 qCritical() << "Failed to create profile directory,"
67103
=== modified file 'src/app/single-instance-manager.h'
--- src/app/single-instance-manager.h 2016-01-15 10:06:31 +0000
+++ src/app/single-instance-manager.h 2016-05-11 16:04:27 +0000
@@ -33,7 +33,7 @@
33public:33public:
34 SingleInstanceManager(QObject* parent=nullptr);34 SingleInstanceManager(QObject* parent=nullptr);
3535
36 bool run(const QStringList& arguments);36 bool run(const QStringList& arguments, const QString& appId);
3737
38Q_SIGNALS:38Q_SIGNALS:
39 void newInstanceLaunched(const QStringList& arguments) const;39 void newInstanceLaunched(const QStringList& arguments) const;
4040
=== modified file 'src/app/webbrowser/webbrowser-app.cpp'
--- src/app/webbrowser/webbrowser-app.cpp 2016-02-05 15:20:10 +0000
+++ src/app/webbrowser/webbrowser-app.cpp 2016-05-11 16:04:27 +0000
@@ -76,7 +76,7 @@
76 qmlRegisterSingletonType<DownloadsModel>(uri, 0, 1, "DownloadsModel", DownloadsModel_singleton_factory);76 qmlRegisterSingletonType<DownloadsModel>(uri, 0, 1, "DownloadsModel", DownloadsModel_singleton_factory);
77 qmlRegisterType<TextSearchFilterModel>(uri, 0, 1, "TextSearchFilterModel");77 qmlRegisterType<TextSearchFilterModel>(uri, 0, 1, "TextSearchFilterModel");
7878
79 if (BrowserApplication::initialize("webbrowser/webbrowser-app.qml")) {79 if (BrowserApplication::initialize("webbrowser/webbrowser-app.qml", QStringLiteral("webbrowser-app"))) {
80 QStringList searchEnginesSearchPaths;80 QStringList searchEnginesSearchPaths;
81 searchEnginesSearchPaths << QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/searchengines";81 searchEnginesSearchPaths << QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/searchengines";
82 searchEnginesSearchPaths << UbuntuBrowserDirectory() + "/webbrowser/searchengines";82 searchEnginesSearchPaths << UbuntuBrowserDirectory() + "/webbrowser/searchengines";
8383
=== modified file 'src/app/webcontainer/webapp-container.cpp'
--- src/app/webcontainer/webapp-container.cpp 2016-02-29 13:32:17 +0000
+++ src/app/webcontainer/webapp-container.cpp 2016-05-11 16:04:27 +0000
@@ -92,12 +92,38 @@
92{92{
93}93}
9494
95QString WebappContainer::appId() const
96{
97 Q_FOREACH(const QString& argument, m_arguments) {
98 if (argument.startsWith("--app-id=")) {
99 return argument.split("--app-id=")[1];
100 }
101 }
102 return QString();
103}
95104
96bool WebappContainer::initialize()105bool WebappContainer::initialize()
97{106{
98 earlyEnvironment();107 earlyEnvironment();
99108
100 if (BrowserApplication::initialize("webcontainer/webapp-container.qml")) {109 if (qgetenv("APP_ID").isEmpty()) {
110 QString id = appId();
111 if (id.isEmpty()) {
112 qCritical() << "The application has been launched with no "
113 "explicit or system provided app id. "
114 "An application id can be set by using the --app-id "
115 "command line parameter and setting it to a unique "
116 "application specific value or using the APP_ID environment "
117 "variable.";
118 return false;
119 }
120 qputenv("APP_ID", id.toUtf8());
121 }
122
123 if (BrowserApplication::initialize(
124 "webcontainer/webapp-container.qml",
125 QString::fromUtf8(qgetenv("APP_ID")))) {
126
101 parseCommandLine();127 parseCommandLine();
102 parseExtraConfiguration();128 parseExtraConfiguration();
103129
104130
=== modified file 'src/app/webcontainer/webapp-container.h'
--- src/app/webcontainer/webapp-container.h 2016-02-27 21:45:57 +0000
+++ src/app/webcontainer/webapp-container.h 2016-05-11 16:04:27 +0000
@@ -54,6 +54,7 @@
54 bool shouldNotValidateCommandLineUrls() const;54 bool shouldNotValidateCommandLineUrls() const;
55 bool isValidLocalIntentFilterFile(const QString& filename) const;55 bool isValidLocalIntentFilterFile(const QString& filename) const;
56 void setupLocalSchemeFilterIfAny(QQmlContext* context, const QString& webappSearchPath);56 void setupLocalSchemeFilterIfAny(QQmlContext* context, const QString& webappSearchPath);
57 QString appId() const;
5758
58private:59private:
59 QString m_webappName;60 QString m_webappName;
6061
=== modified file 'tests/autopilot/webapp_container/tests/__init__.py'
--- tests/autopilot/webapp_container/tests/__init__.py 2016-01-22 10:19:34 +0000
+++ tests/autopilot/webapp_container/tests/__init__.py 2016-05-11 16:04:27 +0000
@@ -57,6 +57,10 @@
57 args.append(57 args.append(
58 '--desktop_file_hint=/usr/share/applications/'58 '--desktop_file_hint=/usr/share/applications/'
59 'webbrowser-app.desktop')59 'webbrowser-app.desktop')
60
61 if next(filter(lambda e: e.startswith('--appid'), args), None) is None:
62 args.append('--app-id=running.test')
63
60 if envvars:64 if envvars:
61 for envvar_key in envvars:65 for envvar_key in envvars:
62 self.useFixture(fixtures.EnvironmentVariable(66 self.useFixture(fixtures.EnvironmentVariable(
6367
=== modified file 'tests/unittests/single-instance-manager/tst_SingleInstanceManagerTests.cpp'
--- tests/unittests/single-instance-manager/tst_SingleInstanceManagerTests.cpp 2016-01-18 14:45:12 +0000
+++ tests/unittests/single-instance-manager/tst_SingleInstanceManagerTests.cpp 2016-05-11 16:04:27 +0000
@@ -50,18 +50,18 @@
5050
51 void test_cannot_run_twice_same_instance()51 void test_cannot_run_twice_same_instance()
52 {52 {
53 QVERIFY(singleton->run(QStringList()));53 QVERIFY(singleton->run(QStringList(), "appid"));
54 QVERIFY(!singleton->run(QStringList()));54 QVERIFY(!singleton->run(QStringList(), "appid"));
55 QVERIFY(newInstanceSpy->isEmpty());55 QVERIFY(newInstanceSpy->isEmpty());
56 }56 }
5757
58 void test_arguments_passed_to_already_running_instance()58 void test_arguments_passed_to_already_running_instance()
59 {59 {
60 QVERIFY(singleton->run(QStringList()));60 QVERIFY(singleton->run(QStringList(), "appid"));
61 SingleInstanceManager other;61 SingleInstanceManager other;
62 QStringList args;62 QStringList args;
63 args << QStringLiteral("foo") << QStringLiteral("bar") << QStringLiteral("baz");63 args << QStringLiteral("foo") << QStringLiteral("bar") << QStringLiteral("baz");
64 QVERIFY(!other.run(args));64 QVERIFY(!other.run(args, "appid"));
65 newInstanceSpy->wait();65 newInstanceSpy->wait();
66 QCOMPARE(newInstanceSpy->first().at(0).toStringList(), args);66 QCOMPARE(newInstanceSpy->first().at(0).toStringList(), args);
67 }67 }

Subscribers

People subscribed via source and target branches