Merge lp:~renatofilho/indicator-transfer/app-id-dm into lp:indicator-transfer/15.10
- app-id-dm
- Merge into trunk.15.10
Status: | Merged |
---|---|
Approved by: | Charles Kerr |
Approved revision: | 41 |
Merged at revision: | 38 |
Proposed branch: | lp:~renatofilho/indicator-transfer/app-id-dm |
Merge into: | lp:indicator-transfer/15.10 |
Diff against target: |
614 lines (+254/-210) 3 files modified
CMakeLists.txt (+2/-1) debian/rules (+2/-1) src/dm-plugin/dm-source.cpp (+250/-208) |
To merge this branch: | bzr merge lp:~renatofilho/indicator-transfer/app-id-dm |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Charles Kerr (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+272106@code.launchpad.net |
Commit message
Removed content hub dep from download manager plugin.
Uses download "app-id" property to show application information.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
- 37. By Renato Araujo Oliveira Filho
-
Fixed app info retrieve from click packages.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:37
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 38. By Renato Araujo Oliveira Filho
-
Does not show downloads which has 'ShowInIndicator' marked as false.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:38
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 39. By Renato Araujo Oliveira Filho
-
Fixed memory leak.
Charles Kerr (charlesk) wrote : | # |
Comments inline. Mostly looks good, a couple of minor variant leaks need fixing
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:39
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 40. By Renato Araujo Oliveira Filho
-
Parse "package-name" from download metadata.
"package-name" is used by update-manager when download update for exists apps.
- 41. By Renato Araujo Oliveira Filho
-
Fixed memory leaks.
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
> Comments inline. Mostly looks good, a couple of minor variant leaks need
> fixing
All leaks fixed.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:41
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Charles Kerr (charlesk) wrote : | # |
Some nice improvements in this patch. LGTM
- 42. By Renato Araujo Oliveira Filho
-
Fixed application icon name set.
- 43. By Renato Araujo Oliveira Filho
-
Trunk merged.
- 44. By Renato Araujo Oliveira Filho
-
Metadata.app_id has priority over destinationAppId.
- 45. By Renato Araujo Oliveira Filho
-
Run test sequential.
- 46. By Renato Araujo Oliveira Filho
-
Fix build rules.
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2015-08-19 17:53:32 +0000 |
3 | +++ CMakeLists.txt 2015-12-16 19:32:14 +0000 |
4 | @@ -47,7 +47,8 @@ |
5 | properties-cpp>=0.0.1 |
6 | click-0.4>=0.4.30 |
7 | json-glib-1.0 |
8 | - ubuntu-app-launch-2) |
9 | + ubuntu-app-launch-2 |
10 | + mirclient) |
11 | include_directories(SYSTEM ${SERVICE_DEPS_INCLUDE_DIRS}) |
12 | |
13 | ## |
14 | |
15 | === modified file 'debian/rules' |
16 | --- debian/rules 2015-07-15 14:41:03 +0000 |
17 | +++ debian/rules 2015-12-16 19:32:14 +0000 |
18 | @@ -8,4 +8,5 @@ |
19 | override_dh_install: |
20 | dh_install --fail-missing |
21 | |
22 | - |
23 | +override_dh_auto_test: |
24 | + ctest -j1 --output-on-failure |
25 | |
26 | === modified file 'src/dm-plugin/dm-source.cpp' |
27 | --- src/dm-plugin/dm-source.cpp 2015-08-12 13:49:41 +0000 |
28 | +++ src/dm-plugin/dm-source.cpp 2015-12-16 19:32:14 +0000 |
29 | @@ -22,7 +22,9 @@ |
30 | #include <click.h> |
31 | #include <ubuntu-app-launch.h> |
32 | |
33 | +#include <glib/gstdio.h> |
34 | #include <json-glib/json-glib.h> |
35 | +#include <gio/gdesktopappinfo.h> |
36 | |
37 | #include <algorithm> |
38 | #include <iostream> |
39 | @@ -37,10 +39,6 @@ |
40 | static constexpr char const * DM_MANAGER_IFACE_NAME {"com.canonical.applications.DownloadManager"}; |
41 | static constexpr char const * DM_DOWNLOAD_IFACE_NAME {"com.canonical.applications.Download"}; |
42 | |
43 | -static constexpr char const * CH_BUS_NAME {"com.ubuntu.content.dbus.Service"}; |
44 | -static constexpr char const * CH_TRANSFER_IFACE_NAME {"com.ubuntu.content.dbus.Transfer"}; |
45 | - |
46 | - |
47 | /** |
48 | * A Transfer whose state comes from content-hub and ubuntu-download-manager. |
49 | * |
50 | @@ -48,26 +46,20 @@ |
51 | * from ubuntu-download-manager. The ccad is used for pause/resume/cancel, |
52 | * state change / download progress signals, etc. |
53 | * |
54 | - * Each DMTransfer also tracks a com.ubuntu.content.dbus.Transfer (cucdt) |
55 | - * object from content-hub. The cucdt is used for learning the download's peer |
56 | - * and for calling Charge() to launch the peer's app. |
57 | */ |
58 | class DMTransfer: public Transfer |
59 | { |
60 | public: |
61 | |
62 | DMTransfer(GDBusConnection* connection, |
63 | - const std::string& ccad_path, |
64 | - const std::string& cucdt_path): |
65 | + const std::string& ccad_path): |
66 | m_bus(G_DBUS_CONNECTION(g_object_ref(connection))), |
67 | m_cancellable(g_cancellable_new()), |
68 | - m_ccad_path(ccad_path), |
69 | - m_cucdt_path(cucdt_path) |
70 | + m_ccad_path(ccad_path) |
71 | { |
72 | id = next_unique_id(); |
73 | time_started = time(nullptr); |
74 | get_ccad_properties(); |
75 | - get_cucdt_properties(); |
76 | } |
77 | |
78 | ~DMTransfer() |
79 | @@ -110,36 +102,29 @@ |
80 | |
81 | void open() |
82 | { |
83 | - /* Once a transfer is complete, an app can be launched to process |
84 | - it by calling Charge() with an empty variant list argument */ |
85 | - g_return_if_fail(!m_cucdt_path.empty()); |
86 | - g_dbus_connection_call(m_bus, |
87 | - CH_BUS_NAME, |
88 | - m_cucdt_path.c_str(), |
89 | - CH_TRANSFER_IFACE_NAME, |
90 | - "Charge", |
91 | - g_variant_new("(av)", nullptr), |
92 | - nullptr, |
93 | - G_DBUS_CALL_FLAGS_NONE, |
94 | - -1, // default timeout |
95 | - m_cancellable, |
96 | - on_cucdt_charge, // callback |
97 | - nullptr); // callback user_data |
98 | + open_app(); |
99 | } |
100 | |
101 | void open_app() |
102 | { |
103 | - g_return_if_fail(!m_peer_name.empty()); |
104 | - |
105 | - gchar* app_id = ubuntu_app_launch_triplet_to_app_id(m_peer_name.c_str(), nullptr, nullptr); |
106 | - g_debug("calling ubuntu_app_launch_start_application() for %s", app_id); |
107 | - ubuntu_app_launch_start_application(app_id, nullptr); |
108 | - g_free(app_id); |
109 | - } |
110 | - |
111 | - const std::string& cucdt_path() const |
112 | - { |
113 | - return m_cucdt_path; |
114 | + // destination app has priority over app_id |
115 | + std::string app_id = download_app_id(); |
116 | + |
117 | + if (app_id.empty() && !m_package_name.empty()) { |
118 | + app_id = std::string(ubuntu_app_launch_triplet_to_app_id(m_package_name.c_str(), |
119 | + "first-listed-app", |
120 | + "current-user-version")); |
121 | + } |
122 | + |
123 | + if (app_id.empty()) |
124 | + { |
125 | + g_warning("Fail to discovery app-id"); |
126 | + } |
127 | + else |
128 | + { |
129 | + g_debug("calling ubuntu_app_launch_start_application() for %s", app_id.c_str()); |
130 | + ubuntu_app_launch_start_application(app_id.c_str(), nullptr); |
131 | + } |
132 | } |
133 | |
134 | const std::string& ccad_path() const |
135 | @@ -147,17 +132,6 @@ |
136 | return m_ccad_path; |
137 | } |
138 | |
139 | - void handle_cucdt_signal(const gchar* signal_name, GVariant* parameters) |
140 | - { |
141 | - if (!g_strcmp0(signal_name, "StoreChanged")) |
142 | - { |
143 | - const gchar* uri = nullptr; |
144 | - g_variant_get_child(parameters, 0, "&s", &uri); |
145 | - if (uri != nullptr) |
146 | - set_store(uri); |
147 | - } |
148 | - } |
149 | - |
150 | void handle_ccad_signal(const gchar* signal_name, GVariant* parameters) |
151 | { |
152 | if (!g_strcmp0(signal_name, "started")) |
153 | @@ -234,12 +208,9 @@ |
154 | |
155 | private: |
156 | |
157 | - static void on_cucdt_charge(GObject * source, |
158 | - GAsyncResult * res, |
159 | - gpointer /*unused*/) |
160 | + const std::string& download_app_id() const |
161 | { |
162 | - auto v = connection_call_finish(source, res, "Error calling Charge()"); |
163 | - g_clear_pointer(&v, g_variant_unref); |
164 | + return m_app_id.empty() ? m_destination_app : m_app_id; |
165 | } |
166 | |
167 | void emit_changed_soon() |
168 | @@ -406,61 +377,6 @@ |
169 | } |
170 | } |
171 | |
172 | - void set_store(const char* store) |
173 | - { |
174 | - /** |
175 | - * This is a workaround until content-hub exposes a peer getter. |
176 | - * As an interim step, this code sniffs the peer by looking at the store. |
177 | - * the peer's listed in the directory component before HubIncoming, e.g.: |
178 | - * "/home/phablet/.cache/com.ubuntu.gallery/HubIncoming/4" |
179 | - */ |
180 | - char** strv = g_strsplit(store, "/", -1); |
181 | - int i=0; |
182 | - for ( ; strv && strv[i]; ++i) |
183 | - if (!g_strcmp0(strv[i], "HubIncoming") && (i>0)) |
184 | - set_peer_name(strv[i-1]); |
185 | - g_strfreev(strv); |
186 | - } |
187 | - |
188 | - void set_peer_name(const char* peer_name) |
189 | - { |
190 | - g_return_if_fail(peer_name && *peer_name); |
191 | - |
192 | - g_debug("changing '%s' peer_name to '%s'", m_ccad_path.c_str(), peer_name); |
193 | - m_peer_name = peer_name; |
194 | - |
195 | - /* If we can find a click icon for the peer, |
196 | - Use it as the transfer's icon */ |
197 | - |
198 | - GError* error = nullptr; |
199 | - auto user = click_user_new_for_user(nullptr, nullptr, &error); |
200 | - if (user != nullptr) |
201 | - { |
202 | - gchar* path = click_user_get_path(user, peer_name, &error); |
203 | - if (path != nullptr) |
204 | - { |
205 | - auto manifest = click_user_get_manifest(user, peer_name, &error); |
206 | - if (manifest != nullptr) |
207 | - { |
208 | - const auto icon_name = json_object_get_string_member(manifest, "icon"); |
209 | - if (icon_name != nullptr) |
210 | - { |
211 | - auto filename = g_build_filename(path, icon_name, nullptr); |
212 | - set_icon(filename); |
213 | - g_free(filename); |
214 | - } |
215 | - } |
216 | - g_free(path); |
217 | - } |
218 | - } |
219 | - |
220 | - if (error != nullptr) |
221 | - g_warning("Unable to get manifest for '%s' package: %s", peer_name, error->message); |
222 | - |
223 | - g_clear_object(&user); |
224 | - g_clear_error(&error); |
225 | - } |
226 | - |
227 | void set_icon(const char* filename) |
228 | { |
229 | const std::string tmp = filename ? filename : ""; |
230 | @@ -473,35 +389,6 @@ |
231 | } |
232 | |
233 | /*** |
234 | - **** Content Hub |
235 | - ***/ |
236 | - |
237 | - void get_cucdt_properties() |
238 | - { |
239 | - const auto bus_name = CH_BUS_NAME; |
240 | - const auto object_path = m_cucdt_path.c_str(); |
241 | - const auto interface_name = CH_TRANSFER_IFACE_NAME; |
242 | - |
243 | - g_dbus_connection_call(m_bus, bus_name, object_path, interface_name, |
244 | - "Store", nullptr, G_VARIANT_TYPE("(s)"), |
245 | - G_DBUS_CALL_FLAGS_NONE, -1, |
246 | - m_cancellable, on_cucdt_store, this); |
247 | - } |
248 | - |
249 | - static void on_cucdt_store(GObject* source, GAsyncResult* res, gpointer gself) |
250 | - { |
251 | - auto v = connection_call_finish(source, res, "Unable to get store"); |
252 | - if (v != nullptr) |
253 | - { |
254 | - const gchar* store = nullptr; |
255 | - g_variant_get_child(v, 0, "&s", &store); |
256 | - if (store != nullptr) |
257 | - static_cast<DMTransfer*>(gself)->set_store(store); |
258 | - g_variant_unref(v); |
259 | - } |
260 | - } |
261 | - |
262 | - /*** |
263 | **** DownloadManager |
264 | ***/ |
265 | |
266 | @@ -520,6 +407,25 @@ |
267 | "progress", nullptr, G_VARIANT_TYPE("(t)"), |
268 | G_DBUS_CALL_FLAGS_NONE, -1, |
269 | m_cancellable, on_ccad_progress, this); |
270 | + |
271 | + g_dbus_connection_call(m_bus, bus_name, object_path, interface_name, |
272 | + "metadata", nullptr, G_VARIANT_TYPE("(a{sv})"), |
273 | + G_DBUS_CALL_FLAGS_NONE, -1, |
274 | + m_cancellable, on_ccad_metadata, this); |
275 | + |
276 | + g_dbus_connection_call(m_bus, bus_name, object_path, |
277 | + "org.freedesktop.DBus.Properties", |
278 | + "Get", g_variant_new ("(ss)", interface_name, "DestinationApp"), |
279 | + G_VARIANT_TYPE ("(v)"), |
280 | + G_DBUS_CALL_FLAGS_NONE, -1, |
281 | + m_cancellable, on_ccad_destination_app, this); |
282 | + |
283 | + g_dbus_connection_call(m_bus, bus_name, object_path, |
284 | + "org.freedesktop.DBus.Properties", |
285 | + "Get", g_variant_new ("(ss)", interface_name, "Title"), |
286 | + G_VARIANT_TYPE ("(v)"), |
287 | + G_DBUS_CALL_FLAGS_NONE, -1, |
288 | + m_cancellable, on_ccad_title, this); |
289 | } |
290 | |
291 | static void on_ccad_total_size(GObject * source, |
292 | @@ -556,6 +462,91 @@ |
293 | } |
294 | } |
295 | |
296 | + static void on_ccad_metadata(GObject * source, |
297 | + GAsyncResult * res, |
298 | + gpointer gself) |
299 | + { |
300 | + auto v = connection_call_finish(source, res, "Error calling metadata()"); |
301 | + if (v != nullptr) |
302 | + { |
303 | + auto self = static_cast<DMTransfer*>(gself); |
304 | + GVariant *dict; |
305 | + GVariantIter iter; |
306 | + GVariant *value; |
307 | + gchar *key; |
308 | + |
309 | + dict = g_variant_get_child_value(v, 0); |
310 | + g_variant_iter_init (&iter, dict); |
311 | + |
312 | + self->m_app_id = ""; |
313 | + self->m_package_name = ""; |
314 | + |
315 | + while (g_variant_iter_next(&iter, "{sv}", &key, &value)) |
316 | + { |
317 | + if (g_strcmp0(key, "app-id") == 0) |
318 | + { |
319 | + self->m_app_id = std::string(g_variant_get_string(value, nullptr)); |
320 | + } |
321 | + |
322 | + // update-manager uses package-name |
323 | + if (g_strcmp0(key, "package-name") == 0) |
324 | + { |
325 | + self->m_package_name = std::string(g_variant_get_string(value, nullptr)); |
326 | + } |
327 | + |
328 | + // must free data for ourselves |
329 | + g_variant_unref(value); |
330 | + g_free (key); |
331 | + } |
332 | + |
333 | + g_variant_unref(dict); |
334 | + g_debug("App id: %s", self->m_app_id.c_str()); |
335 | + g_debug("Package name: %s", self->m_package_name.c_str()); |
336 | + self->update_app_info(); |
337 | + } |
338 | + } |
339 | + |
340 | + static void on_ccad_destination_app(GObject * source, |
341 | + GAsyncResult * res, |
342 | + gpointer gself) |
343 | + { |
344 | + auto v = connection_call_finish(source, res, "Error getting destinationApp property"); |
345 | + if (v != nullptr) |
346 | + { |
347 | + GVariant *value, *item; |
348 | + item = g_variant_get_child_value(v, 0); |
349 | + value = g_variant_get_variant(item); |
350 | + g_variant_unref(item); |
351 | + |
352 | + auto self = static_cast<DMTransfer*>(gself); |
353 | + self->m_destination_app = std::string(g_variant_get_string(value, nullptr)); |
354 | + g_debug("Destination app: %s", self->m_destination_app.c_str()); |
355 | + self->update_app_info(); |
356 | + g_variant_unref(v); |
357 | + } |
358 | + } |
359 | + |
360 | + static void on_ccad_title(GObject * source, |
361 | + GAsyncResult * res, |
362 | + gpointer gself) |
363 | + { |
364 | + auto v = connection_call_finish(source, res, "Error getting Title property"); |
365 | + if (v != nullptr) |
366 | + { |
367 | + GVariant *value, *item; |
368 | + item = g_variant_get_child_value(v, 0); |
369 | + value = g_variant_get_variant(item); |
370 | + g_variant_unref(item); |
371 | + |
372 | + auto self = static_cast<DMTransfer*>(gself); |
373 | + auto title = g_variant_get_string(value, nullptr); |
374 | + g_debug("Download title: %s", title); |
375 | + if (title && strlen(title)) |
376 | + self->set_title(title); |
377 | + g_variant_unref(v); |
378 | + } |
379 | + } |
380 | + |
381 | void call_ccad_method_no_args_no_response(const char* method_name) |
382 | { |
383 | const auto bus_name = DM_BUS_NAME; |
384 | @@ -570,6 +561,85 @@ |
385 | m_cancellable, nullptr, nullptr); |
386 | } |
387 | |
388 | + void update_app_info() |
389 | + { |
390 | + // destination app has priority over app_id |
391 | + std::string app_id = download_app_id(); |
392 | + |
393 | + if (!app_id.empty()) |
394 | + update_app_info_from_app_id(app_id); |
395 | + else if (!m_package_name.empty()) |
396 | + update_app_info_from_package_name(m_package_name); |
397 | + else |
398 | + g_warning("Download without app-id or package-name"); |
399 | + } |
400 | + |
401 | + void update_app_info_from_package_name(const std::string &package_name) |
402 | + { |
403 | + std::string app_id = std::string(ubuntu_app_launch_triplet_to_app_id(package_name.c_str(), |
404 | + "first-listed-app", |
405 | + "current-user-version")); |
406 | + if (!app_id.empty()) |
407 | + update_app_info_from_app_id(app_id); |
408 | + else |
409 | + g_warning("fail to retrive app-id from package: %s", package_name.c_str()); |
410 | + } |
411 | + |
412 | + void update_app_info_from_app_id(const std::string &app_id) |
413 | + { |
414 | + gchar *app_dir; |
415 | + gchar *app_desktop_file; |
416 | + |
417 | + if (!ubuntu_app_launch_application_info(app_id.c_str(), &app_dir, &app_desktop_file)) |
418 | + { |
419 | + g_warning("Fail to get app info: %s", app_id.c_str()); |
420 | + return; |
421 | + } |
422 | + |
423 | + g_debug("App data: %s : %s", app_dir, app_desktop_file); |
424 | + gchar *full_app_desktop_file = g_build_filename(app_dir, app_desktop_file, nullptr); |
425 | + GKeyFile *app_info = g_key_file_new(); |
426 | + GError *error = nullptr; |
427 | + |
428 | + g_debug("Open desktop file: %s", full_app_desktop_file); |
429 | + g_key_file_load_from_file(app_info, full_app_desktop_file, G_KEY_FILE_NONE, &error); |
430 | + if (error) |
431 | + { |
432 | + g_warning("Fail to open desktop info: %s:%s", full_app_desktop_file, error->message); |
433 | + g_free(full_app_desktop_file); |
434 | + g_key_file_free(app_info); |
435 | + g_error_free(error); |
436 | + } |
437 | + else |
438 | + { |
439 | + gchar *icon_name = g_key_file_get_string(app_info, "Desktop Entry", "Icon", &error); |
440 | + if (error == nullptr) |
441 | + { |
442 | + |
443 | + gchar *full_icon_name = g_build_filename(app_dir, icon_name, nullptr); |
444 | + g_debug("App icon: %s", icon_name); |
445 | + g_debug("App full icon name: %s", full_icon_name); |
446 | + // check if it is full path icon or a themed one |
447 | + if (g_file_test(full_icon_name, G_FILE_TEST_EXISTS)) |
448 | + set_icon(full_icon_name); |
449 | + else |
450 | + set_icon(icon_name); |
451 | + g_free(full_icon_name); |
452 | + } |
453 | + else |
454 | + { |
455 | + g_warning("Fail to retrive icon:", error->message); |
456 | + g_error_free(error); |
457 | + } |
458 | + g_free(icon_name); |
459 | + } |
460 | + |
461 | + g_key_file_free(app_info); |
462 | + g_free(full_app_desktop_file); |
463 | + g_free(app_dir); |
464 | + g_free(app_desktop_file); |
465 | + } |
466 | + |
467 | /*** |
468 | **** |
469 | ***/ |
470 | @@ -611,9 +681,10 @@ |
471 | |
472 | GDBusConnection* m_bus = nullptr; |
473 | GCancellable* m_cancellable = nullptr; |
474 | + std::string m_app_id; |
475 | + std::string m_destination_app; |
476 | + std::string m_package_name; |
477 | const std::string m_ccad_path; |
478 | - const std::string m_cucdt_path; |
479 | - std::string m_peer_name; |
480 | }; |
481 | |
482 | } // anonymous namespace |
483 | @@ -751,58 +822,9 @@ |
484 | this, |
485 | nullptr); |
486 | m_signal_subscriptions.insert(tag); |
487 | - |
488 | - tag = g_dbus_connection_signal_subscribe(bus, |
489 | - CH_BUS_NAME, |
490 | - CH_TRANSFER_IFACE_NAME, |
491 | - nullptr, |
492 | - nullptr, |
493 | - nullptr, |
494 | - G_DBUS_SIGNAL_FLAGS_NONE, |
495 | - on_transfer_signal_static, |
496 | - this, |
497 | - nullptr); |
498 | - m_signal_subscriptions.insert(tag); |
499 | - } |
500 | - } |
501 | - |
502 | - static void on_transfer_signal_static(GDBusConnection* /*connection*/, |
503 | - const gchar* /*sender_name*/, |
504 | - const gchar* object_path, |
505 | - const gchar* /*interface_name*/, |
506 | - const gchar* signal_name, |
507 | - GVariant* parameters, |
508 | - gpointer gself) |
509 | - { |
510 | - static_cast<Impl*>(gself)->on_transfer_signal(object_path, signal_name, parameters); |
511 | - } |
512 | - |
513 | - void on_transfer_signal(const gchar* cucdt_path, |
514 | - const gchar* signal_name, |
515 | - GVariant* parameters) |
516 | - { |
517 | - gchar* variant_str = g_variant_print(parameters, TRUE); |
518 | - g_debug("transfer signal: %s %s %s", cucdt_path, signal_name, variant_str); |
519 | - g_free(variant_str); |
520 | - |
521 | - if (!g_strcmp0(signal_name, "DownloadIdChanged")) |
522 | - { |
523 | - const char* ccad_path = nullptr; |
524 | - g_variant_get_child(parameters, 0, "&s", &ccad_path); |
525 | - g_return_if_fail(cucdt_path != nullptr); |
526 | - |
527 | - // ensure this ccad/cucdt pair is tracked |
528 | - if (!find_transfer_by_ccad_path(ccad_path)) |
529 | - create_new_transfer(ccad_path, cucdt_path); |
530 | - } |
531 | - else |
532 | - { |
533 | - // Route this signal to the DMTransfer for processing |
534 | - auto transfer = find_transfer_by_cucdt_path(cucdt_path); |
535 | - if (transfer) |
536 | - transfer->handle_cucdt_signal(signal_name, parameters); |
537 | - } |
538 | - } |
539 | + } |
540 | + } |
541 | + |
542 | |
543 | static void on_download_signal(GDBusConnection* /*connection*/, |
544 | const gchar* /*sender_name*/, |
545 | @@ -821,6 +843,8 @@ |
546 | auto transfer = self->find_transfer_by_ccad_path(ccad_path); |
547 | if (transfer) |
548 | transfer->handle_ccad_signal(signal_name, parameters); |
549 | + else |
550 | + self->create_new_transfer(ccad_path); |
551 | } |
552 | |
553 | /*** |
554 | @@ -840,27 +864,45 @@ |
555 | return nullptr; |
556 | } |
557 | |
558 | - std::shared_ptr<DMTransfer> find_transfer_by_cucdt_path(const std::string& path) |
559 | - { |
560 | - for (const auto& transfer : m_model->get_all()) |
561 | - { |
562 | - const auto tmp = std::static_pointer_cast<DMTransfer>(transfer); |
563 | - |
564 | - if (tmp && (path == tmp->cucdt_path())) |
565 | - return tmp; |
566 | - } |
567 | - |
568 | - return nullptr; |
569 | - } |
570 | - |
571 | - void create_new_transfer(const std::string& ccad_path, |
572 | - const std::string& cucdt_path) |
573 | + void create_new_transfer(const std::string& ccad_path) |
574 | { |
575 | // don't let transfers reappear after they've been cleared by the user |
576 | if (m_removed_ccad.count(ccad_path)) |
577 | return; |
578 | |
579 | - auto new_transfer = std::make_shared<DMTransfer>(m_bus, ccad_path, cucdt_path); |
580 | + // check if the download should appear on indicator |
581 | + GError *error = nullptr; |
582 | + auto show = g_dbus_connection_call_sync(m_bus, DM_BUS_NAME, ccad_path.c_str(), |
583 | + "org.freedesktop.DBus.Properties", |
584 | + "Get", g_variant_new ("(ss)", DM_DOWNLOAD_IFACE_NAME, "ShowInIndicator"), |
585 | + G_VARIANT_TYPE ("(v)"), |
586 | + G_DBUS_CALL_FLAGS_NONE, -1, |
587 | + m_cancellable, &error); |
588 | + if (show != nullptr) |
589 | + { |
590 | + GVariant *value, *item; |
591 | + item = g_variant_get_child_value(show, 0); |
592 | + value = g_variant_get_variant(item); |
593 | + bool show_in_idicator = g_variant_get_boolean(value); |
594 | + |
595 | + g_variant_unref(value); |
596 | + g_variant_unref(item); |
597 | + g_variant_unref(show); |
598 | + |
599 | + if (!show_in_idicator) |
600 | + { |
601 | + m_removed_ccad.insert(ccad_path); |
602 | + return; |
603 | + } |
604 | + } |
605 | + else if (error != nullptr) |
606 | + { |
607 | + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
608 | + g_warning("Fail to retrieve 'ShowInIndicator' property: %s", error->message); |
609 | + g_error_free(error); |
610 | + } |
611 | + |
612 | + auto new_transfer = std::make_shared<DMTransfer>(m_bus, ccad_path); |
613 | |
614 | m_model->add(new_transfer); |
615 |
PASSED: Continuous integration, rev:36 jenkins. qa.ubuntu. com/job/ indicator- transfer- ci/39/ jenkins. qa.ubuntu. com/job/ indicator- transfer- wily-amd64- ci/21 jenkins. qa.ubuntu. com/job/ indicator- transfer- wily-armhf- ci/21 jenkins. qa.ubuntu. com/job/ indicator- transfer- wily-armhf- ci/21/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/indicator- transfer- ci/39/rebuild
http://