Merge lp:~stolowski/unity-scopes-shell/fix-1484299-vivid into lp:unity-scopes-shell/trunk-15.04

Proposed by Paweł Stołowski
Status: Merged
Approved by: Marcus Tomlinson
Approved revision: 255
Merged at revision: 246
Proposed branch: lp:~stolowski/unity-scopes-shell/fix-1484299-vivid
Merge into: lp:unity-scopes-shell/trunk-15.04
Diff against target: 166 lines (+61/-2)
5 files modified
src/Unity/scope.cpp (+23/-1)
src/Unity/scope.h (+2/-0)
src/Unity/scopes.cpp (+4/-0)
src/Unity/settingsmodel.cpp (+29/-1)
src/Unity/settingsmodel.h (+3/-0)
To merge this branch: bzr merge lp:~stolowski/unity-scopes-shell/fix-1484299-vivid
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Marcus Tomlinson (community) Approve
Review via email: mp+268349@code.launchpad.net

Commit message

Fix crash when aggregator's settings view is opened shortly after a new child scope was installed. Fix invalidating of results in temp scopes.

Description of the change

Fix crash when aggregator's settings view is opened shortly after a new child scope was installed. There is a short window (5 seconds) where child scopes list can contain a just installed scope but scopes metadata hasn't been refreshed yet and doesn't know that scope id. If that situation is detected, mark settings as needing refreshing, and re-populate settings model after we have all the new metadata from the registry.

Also fixed invalidating of results in temp scopes (lines 71-74).

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

Did you intend to leave all those qDebug()'s in the code?

review: Needs Information
255. By Paweł Stołowski

Removed debug messages

Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

Looks good.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Unity/scope.cpp'
2--- src/Unity/scope.cpp 2015-07-08 09:29:51 +0000
3+++ src/Unity/scope.cpp 2015-08-20 08:17:43 +0000
4@@ -231,6 +231,11 @@
5
6 void Scope::metadataRefreshed()
7 {
8+ // refresh Settings view if needed
9+ if (require_child_scopes_refresh()) {
10+ update_child_scopes();
11+ }
12+
13 std::shared_ptr<scopes::ActivationResponse> response;
14 response.swap(m_delayedActivation);
15
16@@ -377,7 +382,7 @@
17 bool containsDepartments = m_rootDepartment.get() != nullptr;
18 // design decision - no navigation when doing searches
19 containsDepartments &= m_searchQuery.isEmpty();
20-
21+
22 if (containsDepartments != m_hasNavigation) {
23 m_hasNavigation = containsDepartments;
24 Q_EMIT hasNavigationChanged();
25@@ -862,6 +867,23 @@
26 return m_settingsModel.data();
27 }
28
29+bool Scope::require_child_scopes_refresh() const
30+{
31+ if (m_settingsModel && m_scopesInstance)
32+ {
33+ return m_settingsModel->require_child_scopes_refresh();
34+ }
35+ return false;
36+}
37+
38+void Scope::update_child_scopes()
39+{
40+ if (m_settingsModel && m_scopesInstance)
41+ {
42+ m_settingsModel->update_child_scopes(m_scopesInstance->getAllMetadata());
43+ }
44+}
45+
46 /*
47 Filters* Scope::filters() const
48 {
49
50=== modified file 'src/Unity/scope.h'
51--- src/Unity/scope.h 2015-07-08 08:25:28 +0000
52+++ src/Unity/scope.h 2015-08-20 08:17:43 +0000
53@@ -128,6 +128,8 @@
54 unity::shell::scopes::ScopeInterface::Status status() const override;
55 unity::shell::scopes::CategoriesInterface* categories() const override;
56 unity::shell::scopes::SettingsModelInterface* settings() const override;
57+ bool require_child_scopes_refresh() const;
58+ void update_child_scopes();
59 QString searchQuery() const override;
60 QString noResultsHint() const override;
61 QString formFactor() const override;
62
63=== modified file 'src/Unity/scopes.cpp'
64--- src/Unity/scopes.cpp 2015-07-06 17:14:14 +0000
65+++ src/Unity/scopes.cpp 2015-08-20 08:17:43 +0000
66@@ -577,6 +577,10 @@
67 Q_FOREACH(Scope::Ptr scope, m_scopes) {
68 scope->invalidateResults();
69 }
70+
71+ Q_FOREACH(Scope::Ptr scope, m_tempScopes) {
72+ scope->invalidateResults();
73+ }
74 }
75
76 QVariant Scopes::data(const QModelIndex& index, int role) const
77
78=== modified file 'src/Unity/settingsmodel.cpp'
79--- src/Unity/settingsmodel.cpp 2015-06-11 16:10:09 +0000
80+++ src/Unity/settingsmodel.cpp 2015-08-20 08:17:43 +0000
81@@ -32,7 +32,8 @@
82 SettingsModel::SettingsModel(const QDir& configDir, const QString& scopeId,
83 const QVariant& settingsDefinitions, QObject* parent,
84 int settingsTimeout)
85- : SettingsModelInterface(parent), m_scopeId(scopeId), m_settingsTimeout(settingsTimeout)
86+ : SettingsModelInterface(parent), m_scopeId(scopeId), m_settingsTimeout(settingsTimeout),
87+ m_requireChildScopesRefresh(false)
88 {
89 configDir.mkpath(scopeId);
90 QDir databaseDir = configDir.filePath(scopeId);
91@@ -207,6 +208,16 @@
92 return;
93 }
94
95+ const bool reset = m_requireChildScopesRefresh;
96+ if (reset) {
97+ // Reset the settings model to fix LP: #1484299, where a new child scope just finished installing
98+ // while settings view is created (and we crash); since this is really a corner case, just
99+ // resetting the model is fine.
100+ beginResetModel();
101+ }
102+
103+ m_requireChildScopesRefresh = false;
104+
105 m_child_scopes_data.clear();
106 m_child_scopes_data_by_id.clear();
107 m_child_scopes_timers.clear();
108@@ -214,6 +225,13 @@
109 for (sc::ChildScope const& child_scope : m_child_scopes)
110 {
111 QString id = child_scope.id.c_str();
112+ if (!scopes_metadata.contains(id)) {
113+ // if a child scope was just added to the registry, then scopes_metadata may not contain it yet because of the
114+ // scope registry refresh delay on scope add/removal (see LP: #1484299).
115+ qWarning() << "SettingsModel::update_child_scopes(): no scope with id '" + id + "'";
116+ m_requireChildScopesRefresh = true;
117+ continue;
118+ }
119 QString displayName = QString::fromStdString(_("Display results from %1")).arg(QString(scopes_metadata[id]->display_name().c_str()));
120
121 QSharedPointer<QTimer> timer(new QTimer());
122@@ -231,6 +249,11 @@
123 m_child_scopes_data << setting;
124 m_child_scopes_data_by_id[id] = setting;
125 }
126+
127+ if (reset) {
128+ endResetModel();
129+ Q_EMIT countChanged();
130+ }
131 }
132
133 bool SettingsModel::setData(const QModelIndex &index, const QVariant &value,
134@@ -290,6 +313,11 @@
135 return m_data.size() + m_child_scopes_data.size();
136 }
137
138+bool SettingsModel::require_child_scopes_refresh() const
139+{
140+ return m_requireChildScopesRefresh;
141+}
142+
143 void SettingsModel::settings_timeout()
144 {
145 QObject *timer = sender();
146
147=== modified file 'src/Unity/settingsmodel.h'
148--- src/Unity/settingsmodel.h 2015-01-22 08:21:33 +0000
149+++ src/Unity/settingsmodel.h 2015-08-20 08:17:43 +0000
150@@ -81,6 +81,8 @@
151
152 void update_child_scopes(QMap<QString, unity::scopes::ScopeMetadata::SPtr> const& scopes_metadata);
153
154+ bool require_child_scopes_refresh() const;
155+
156 Q_SIGNALS:
157 void settingsChanged();
158
159@@ -101,6 +103,7 @@
160 QMap<QString, QSharedPointer<Data>> m_child_scopes_data_by_id;
161 unity::scopes::ChildScopeList m_child_scopes;
162 QMap<QString, QSharedPointer<QTimer>> m_child_scopes_timers;
163+ bool m_requireChildScopesRefresh;
164 };
165
166 }

Subscribers

People subscribed via source and target branches

to all changes: