Merge lp:~abreu-alexandre/unity-webapps-qml/download-api into lp:unity-webapps-qml
- download-api
- Merge into trunk
Status: | Needs review | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~abreu-alexandre/unity-webapps-qml/download-api | ||||
Merge into: | lp:unity-webapps-qml | ||||
Diff against target: |
1451 lines (+1057/-133) 16 files modified
debian/control (+1/-0) examples/api-bindings/download-manager/main.qml.in (+33/-0) examples/api-bindings/download-manager/www/index.html (+35/-0) examples/api-bindings/download-manager/www/js/app.js (+58/-0) src/Ubuntu/UnityWebApps/UnityWebApps.pro (+5/-1) src/Ubuntu/UnityWebApps/UnityWebApps.qml (+5/-0) src/Ubuntu/UnityWebApps/bindings/download-manager/backend/download-api.js (+392/-0) src/Ubuntu/UnityWebApps/bindings/download-manager/client/download-api.js (+457/-0) src/Ubuntu/UnityWebApps/unity-webapps-api.js.in (+2/-0) tests/integration/autopilot/qml/FullWebViewApp.qml (+0/-2) tests/integration/autopilot/unity_webapps_qml/emulators/__init__.py (+0/-1) tests/integration/autopilot/unity_webapps_qml/tests/__init__.py (+26/-16) tests/integration/autopilot/unity_webapps_qml/tests/test_hud.py (+0/-81) tests/integration/autopilot/unity_webapps_qml/tests/test_injectedOnWebapp.py (+37/-14) tests/integration/autopilot/unity_webapps_qml/tests/test_launcher.py (+4/-12) tests/integration/autopilot/unity_webapps_qml/tests/test_mediaplayer.py (+2/-6) |
||||
To merge this branch: | bzr merge lp:~abreu-alexandre/unity-webapps-qml/download-api | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
WebApps | Pending | ||
Review via email: mp+212537@code.launchpad.net |
Commit message
Bindings for the download manager
Description of the change
Bindings for the download manager
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:95
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:102
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 102. By Alexandre Abreu
-
Add application api Fixes: 1278485
- 103. By PS Jenkins bot
-
Releasing 0.1+14.
04.20140328- 0ubuntu1 - 104. By Alexandre Abreu
-
Fixes to the runtime-api:
- have inputMethodName return its value,
- have the client register listeners for property changed, - 105. By PS Jenkins bot
-
Releasing 0.1+14.
04.20140328. 1-0ubuntu1 - 106. By Alexandre Abreu
-
Add some missing files striclty for doc generation for the runtime-api
- 107. By Alexandre Abreu
-
There is currently an issue on Ubuntu Desktop with webapps running in the container and bamf/unity that when a local desktop file exists (and a webapp icon has been pinned to the launcher through its global /usr/share desktop file), the webapp icons are duplicated in the launcher.
Various fixes have been made to mitigate the issue in bamf but it seems to still be around.
This is voluntarily discarded for now and left around to get to the bottom of the issue in a timely fashion.
Fixes: 1300864 - 108. By PS Jenkins bot
-
Releasing 0.1+14.
04.20140401. 1-0ubuntu1 - 109. By Alexandre Abreu
-
Update the oxide bits to account for oxide moving to 1.0
- 110. By PS Jenkins bot
-
Releasing 0.1+14.
04.20140407- 0ubuntu1 - 111. By Timo Jyrinki
-
Depend on liboxideqtcore0 to limit archs to be built to the set for which webapps-qml is installable for.
- 112. By PS Jenkins bot
-
Releasing 0.1+14.
04.20140408- 0ubuntu1 - 113. By Ricardo Salveti
-
releasing package unity-webapps-qml version 0.1+14.
04.20140408- 0ubuntu2 - 114. By Alexandre Abreu
-
Add UA override capabilities to webapps; clean some code and tests, Fixes: 1245465
- 115. By PS Jenkins bot
-
Releasing 0.1+14.
10.20140506. 1-0ubuntu1
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:117
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 116. By Alexandre Abreu
-
Cleanup the structure of the QML bindings to make it clearer. No Changes in functionality all features are still working & same,
This is an updated version of: https:/
/code.launchpad .net/~abreu- alexandre/ unity-webapps- qml/restructure -cleanup- bindings- qml-structure/ +merge/ 208148 with the latest changes that got in in between Fixes: 1288801 - 117. By Alexandre Abreu
-
Simplifies the manifest.json handling in some instances. More precisely when one is using a custom model search path for the webapp lookup, some restrictions are being put on what is expected to be found in the folder among which:
- a common/ subfolder (even if the webapp doesnt require one),
- one or more unity-webapps-* folders with manifest.json & *.user.js files in it,More over the manifest files do require user scripts to be defined.
This imposes a set of constraints over a given webapp that simply wants to use the container (w/o js injection).
This simplifies it an allows one to define a manifest.json file (still with some required elements, but a smaller set), directly in the model search path. E.g. something like:
{
"name": "MyWebApp",
"homepage": "http://www.bbc. co.uk/news/",
"domain": "bbc.co.uk",
"includes": []
}will do,
or to avoid any confusion w/ the click manifest.json file, one also searches for a webapp-
properties. json w/ the same content as above. - 118. By PS Jenkins bot
-
Releasing 0.1+14.
10.20140514. 2-0ubuntu1
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:119
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:120
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 119. By Alexandre Abreu
-
fix AP tests on touch
- 120. By Alexandre Abreu
-
download ap support; fix ap tests
Unmerged revisions
- 120. By Alexandre Abreu
-
download ap support; fix ap tests
- 119. By Alexandre Abreu
-
fix AP tests on touch
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2014-04-30 01:13:30 +0000 |
3 | +++ debian/control 2014-05-21 13:06:21 +0000 |
4 | @@ -37,6 +37,7 @@ |
5 | ${misc:Depends}, |
6 | ${shlibs:Depends}, |
7 | Suggests: qtdeclarative5-ubuntu-content0.1, |
8 | + qtdeclarative5-ubuntu-download-manager0.1 |
9 | Description: Unity Webapps QML component |
10 | Unity Webapps QML is a QML component that binds to a QML WebView and allows |
11 | running javascript code to access Ubuntu stack components. |
12 | |
13 | === added directory 'examples/api-bindings/download-manager' |
14 | === added file 'examples/api-bindings/download-manager/main.qml.in' |
15 | --- examples/api-bindings/download-manager/main.qml.in 1970-01-01 00:00:00 +0000 |
16 | +++ examples/api-bindings/download-manager/main.qml.in 2014-05-21 13:06:21 +0000 |
17 | @@ -0,0 +1,33 @@ |
18 | +import QtQuick 2.0 |
19 | +import QtWebKit 3.0 |
20 | +import QtWebKit.experimental 1.0 |
21 | +import Ubuntu.Components 0.1 |
22 | +import Ubuntu.UnityWebApps 0.1 |
23 | + |
24 | +MainView { |
25 | + id: root |
26 | + focus: true |
27 | + applicationName: \"helloworld\" |
28 | + |
29 | + width: units.gu(100) |
30 | + height: units.gu(100) |
31 | + |
32 | + WebView { |
33 | + id: webview |
34 | + anchors.fill: parent |
35 | + url: \"file://$$OUT_PWD/download-manager/www/index.html\" |
36 | + |
37 | + experimental.preferences.navigatorQtObjectEnabled: true |
38 | + experimental.preferences.developerExtrasEnabled: true |
39 | + |
40 | + function getUnityWebappsProxies() { |
41 | + return UnityWebAppsUtils.makeProxiesForQtWebViewBindee(webview); |
42 | + } |
43 | + |
44 | + UnityWebApps { |
45 | + id: webapps |
46 | + bindee: webview |
47 | + injectExtraUbuntuApis: true |
48 | + } |
49 | + } |
50 | +} |
51 | |
52 | === added directory 'examples/api-bindings/download-manager/www' |
53 | === added file 'examples/api-bindings/download-manager/www/index.html' |
54 | --- examples/api-bindings/download-manager/www/index.html 1970-01-01 00:00:00 +0000 |
55 | +++ examples/api-bindings/download-manager/www/index.html 2014-05-21 13:06:21 +0000 |
56 | @@ -0,0 +1,35 @@ |
57 | +<!DOCTYPE html> |
58 | +<html> |
59 | + |
60 | + <meta charset="utf-8" /> |
61 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
62 | + |
63 | + <head> |
64 | + <title>Download Api example</title> |
65 | + <script src="./js/app.js"></script> |
66 | + </head> |
67 | + |
68 | + <body> |
69 | + |
70 | + <div> |
71 | + http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png <input type="button" id="download1"></input> |
72 | + </div> |
73 | + |
74 | + <div> |
75 | + http://files.meetup.com/596486/La%20CANADA%20FIRES%20FROM%20CULVER%20CITY%20-%20(10%20MEG%20FILE).jpg <input type="button" id="download2"></input> |
76 | + </div> |
77 | + |
78 | + <div> |
79 | + Progress: |
80 | + <span id="progress">0</span>% |
81 | + </div> |
82 | + |
83 | + <div> |
84 | + Results: |
85 | + <div id="results"> |
86 | + </div> |
87 | + </div> |
88 | + |
89 | + </body> |
90 | + |
91 | +</html> |
92 | |
93 | === added directory 'examples/api-bindings/download-manager/www/js' |
94 | === added file 'examples/api-bindings/download-manager/www/js/app.js' |
95 | --- examples/api-bindings/download-manager/www/js/app.js 1970-01-01 00:00:00 +0000 |
96 | +++ examples/api-bindings/download-manager/www/js/app.js 2014-05-21 13:06:21 +0000 |
97 | @@ -0,0 +1,58 @@ |
98 | +window.onload = function() { |
99 | + var api = external.getUnityObject('1.0'); |
100 | + |
101 | + document.getElementById('download1').addEventListener('click', function() { |
102 | + api.DownloadApi.downloadFile('http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png' |
103 | + , {} |
104 | + , function(download) { |
105 | + if (download.status === "Success") |
106 | + displayImageUri(download.path); |
107 | + setResult(JSON.stringify(download.path)) |
108 | + }); |
109 | + }); |
110 | + |
111 | + document.getElementById('download2').addEventListener('click', function() { |
112 | + api.DownloadApi.createDownloadManager({}, function(manager) { |
113 | + manager.downloadsChanged(function(downloads) { |
114 | + if (downloads && downloads.length !== 0) { |
115 | + setResult('Downloading a 10 MB image'); |
116 | + downloads[0].progressChanged(function(progress) { |
117 | + setProgress(progress); |
118 | + }); |
119 | + downloads[0].finished(function(path) { |
120 | + displayImageUri(path); |
121 | + downloads[0].destroy(); |
122 | + }); |
123 | + downloads[0].canceled(function() { |
124 | + setResults('Download opertaion cancelled'); |
125 | + }); |
126 | + downloads[0].start(); |
127 | + } |
128 | + }); |
129 | + manager.download("http://files.meetup.com/596486/La%20CANADA%20FIRES%20FROM%20CULVER%20CITY%20-%20(10%20MEG%20FILE).jpg"); |
130 | + }); |
131 | + }); |
132 | + |
133 | + function displayImageUri(image) { |
134 | + var res = document.getElementById('results'); |
135 | + |
136 | + var img = document.createElement('img'); |
137 | + |
138 | + img.setAttribute('src', image); |
139 | + img.setAttribute('height', '100px'); |
140 | + img.setAttribute('width', '100px'); |
141 | + |
142 | + res.appendChild(img); |
143 | + }; |
144 | + |
145 | + function setResult(results) { |
146 | + var resultEl = document.getElementById('results'); |
147 | + resultEl.innerHTML += results + '<br>'; |
148 | + }; |
149 | + |
150 | + function setProgress(progress) { |
151 | + var resultEl = document.getElementById('progress'); |
152 | + resultEl.innerHTML = progress; |
153 | + }; |
154 | +}; |
155 | + |
156 | |
157 | === modified file 'src/Ubuntu/UnityWebApps/UnityWebApps.pro' |
158 | --- src/Ubuntu/UnityWebApps/UnityWebApps.pro 2014-05-08 13:01:07 +0000 |
159 | +++ src/Ubuntu/UnityWebApps/UnityWebApps.pro 2014-05-21 13:06:21 +0000 |
160 | @@ -68,11 +68,15 @@ |
161 | runtime_api_binding_backend_js_files.path = $$installPath/bindings/runtime-api/backend/ |
162 | runtime_api_binding_backend_js_files.files = ./bindings/runtime-api/backend/runtime-api.js |
163 | |
164 | +download_api_binding_backend_js_files.path = $$installPath/bindings/download-manager/backend/ |
165 | +download_api_binding_backend_js_files.files = ./bindings/download-manager/backend/download-api.js |
166 | + |
167 | INSTALLS += qmldir_file \ |
168 | qml_files \ |
169 | js_files \ |
170 | content_hub_binding_backend_js_files \ |
171 | alarm_binding_backend_js_files \ |
172 | online_accounts_binding_backend_js_files \ |
173 | - runtime_api_binding_backend_js_files |
174 | + runtime_api_binding_backend_js_files \ |
175 | + download_api_binding_backend_js_files |
176 | |
177 | |
178 | === modified file 'src/Ubuntu/UnityWebApps/UnityWebApps.qml' |
179 | --- src/Ubuntu/UnityWebApps/UnityWebApps.qml 2014-05-08 13:58:56 +0000 |
180 | +++ src/Ubuntu/UnityWebApps/UnityWebApps.qml 2014-05-21 13:06:21 +0000 |
181 | @@ -26,6 +26,7 @@ |
182 | import "./bindings/alarm-api/backend/alarm-api.js" as AlarmApiBackend |
183 | import "./bindings/content-hub/backend/content-hub.js" as ContentHubApiBackend |
184 | import "./bindings/online-accounts/backend/online-accounts.js" as OnlineAccountsApiBackend |
185 | +import "./bindings/download-manager/backend/download-api.js" as DownloadApiBackend |
186 | |
187 | |
188 | /*! |
189 | @@ -656,6 +657,10 @@ |
190 | return RuntimeApiBackend.createRuntimeApi(UnityBackends.backendDelegate) |
191 | }), |
192 | |
193 | + DownloadApi: __injectResourceIfExtraApisAreEnabled(function() { |
194 | + return DownloadApiBackend.createDownloadApi(UnityBackends.backendDelegate) |
195 | + }), |
196 | + |
197 | Launcher: { |
198 | setCount: function (count) { |
199 | if (!initialized) |
200 | |
201 | === added directory 'src/Ubuntu/UnityWebApps/bindings/download-manager' |
202 | === added directory 'src/Ubuntu/UnityWebApps/bindings/download-manager/backend' |
203 | === added file 'src/Ubuntu/UnityWebApps/bindings/download-manager/backend/download-api.js' |
204 | --- src/Ubuntu/UnityWebApps/bindings/download-manager/backend/download-api.js 1970-01-01 00:00:00 +0000 |
205 | +++ src/Ubuntu/UnityWebApps/bindings/download-manager/backend/download-api.js 2014-05-21 13:06:21 +0000 |
206 | @@ -0,0 +1,392 @@ |
207 | +/** |
208 | + * |
209 | + * Download API backend binding |
210 | + * |
211 | + */ |
212 | +function createDownloadApi(backendDelegate) { |
213 | + var PLUGIN_URI = 'Ubuntu.DownloadManager'; |
214 | + var VERSION = 0.1; |
215 | + |
216 | + function SingleDownload(singledownload, objectid) { |
217 | + var id = objectid; |
218 | + if ( ! singledownload) { |
219 | + var result = backendDelegate.createQmlObject( |
220 | + PLUGIN_URI, VERSION, 'SingleDownload'); |
221 | + id = result.id; |
222 | + singledownload = result.object; |
223 | + } |
224 | + if ( ! id) { |
225 | + id = backendDelegate.storeQmlObject(singledownload, |
226 | + PLUGIN_URI, VERSION, 'SingleDownload'); |
227 | + } |
228 | + |
229 | + this._id = id; |
230 | + this._object = singledownload; |
231 | + }; |
232 | + SingleDownload.prototype = { |
233 | + _validate: function() { |
234 | + if (! this._object) |
235 | + throw new TypeError("Invalid object null"); |
236 | + }, |
237 | + |
238 | + destroy: function() { |
239 | + if (! this._object) |
240 | + return; |
241 | + this._object.destroy(); |
242 | + backendDelegate.deleteId(this._id); |
243 | + }, |
244 | + |
245 | + // object methods |
246 | + serialize: function() { |
247 | + return { |
248 | + type: 'object-proxy', |
249 | + apiid: 'DownloadApi', |
250 | + objecttype: 'SingleDownload', |
251 | + objectid: this._id, |
252 | + } |
253 | + }, |
254 | + |
255 | + // methods |
256 | + |
257 | + cancel: function() { |
258 | + this._validate(); |
259 | + this._object.cancel(); |
260 | + }, |
261 | + start: function() { |
262 | + this._validate(); |
263 | + this._object.start(); |
264 | + }, |
265 | + pause: function() { |
266 | + this._validate(); |
267 | + this._object.pause(); |
268 | + }, |
269 | + resume: function() { |
270 | + this._validate(); |
271 | + this._object.resume(); |
272 | + }, |
273 | + download: function(url) { |
274 | + this._validate(); |
275 | + this._object.download(url); |
276 | + }, |
277 | + |
278 | + |
279 | + // properties |
280 | + autoStart: function(callback) { |
281 | + this._validate(); |
282 | + callback(this._object.autoStart); |
283 | + }, |
284 | + setAutoStart: function(shouldAutoStart, callback) { |
285 | + this._validate(); |
286 | + this._object.autoStart = shouldAutoStart; |
287 | + if (callback && typeof(callback) === 'function') |
288 | + callback(); |
289 | + }, |
290 | + |
291 | + allowMobileDownload: function(callback) { |
292 | + this._validate(); |
293 | + callback(this._object.allowMobileDownload); |
294 | + }, |
295 | + setAllowMobileDownload: function(allow, callback) { |
296 | + this._validate(); |
297 | + this._object.allowMobileDownload = allow; |
298 | + if (callback && typeof(callback) === 'function') |
299 | + callback(); |
300 | + }, |
301 | + |
302 | + isCompleted: function(callback) { |
303 | + this._validate(); |
304 | + callback(this._object.isCompleted); |
305 | + }, |
306 | + isCompletedChanged: function(callback) { |
307 | + this._validate(); |
308 | + if (callback && typeof(callback) === 'function') { |
309 | + var self = this; |
310 | + this._object.isCompletedChanged.connect(function() { |
311 | + callback(self._object.isCompleted); |
312 | + }); |
313 | + } |
314 | + }, |
315 | + |
316 | + downloadInProgress: function(callback) { |
317 | + this._validate(); |
318 | + callback(this._object.downloadInProgress); |
319 | + }, |
320 | + downloadInProgressChanged: function(callback) { |
321 | + this._validate(); |
322 | + if (callback && typeof(callback) === 'function') { |
323 | + var self = this; |
324 | + this._object.downloadInProgressChanged.connect(function() { |
325 | + callback(self._object.downloadInProgress); |
326 | + }); |
327 | + } |
328 | + }, |
329 | + |
330 | + progress: function(callback) { |
331 | + this._validate(); |
332 | + callback(this._object.progress); |
333 | + }, |
334 | + progressChanged: function(callback) { |
335 | + this._validate(); |
336 | + if (callback && typeof(callback) === 'function') { |
337 | + var self = this; |
338 | + this._object.progressChanged.connect(function() { |
339 | + callback(self._object.progress); |
340 | + }); |
341 | + } |
342 | + }, |
343 | + |
344 | + downloading: function(callback) { |
345 | + this._validate(); |
346 | + callback(this._object.downloading); |
347 | + }, |
348 | + downloadingChanged: function(callback) { |
349 | + this._validate(); |
350 | + if (callback && typeof(callback) === 'function') { |
351 | + var self = this; |
352 | + this._object.downloadingChanged.connect(function() { |
353 | + callback(self._object.downloading); |
354 | + }); |
355 | + } |
356 | + }, |
357 | + |
358 | + errorMessage: function(callback) { |
359 | + this._validate(); |
360 | + callback(this._object.errorMessage); |
361 | + }, |
362 | + errorChanged: function(callback) { |
363 | + this._validate(); |
364 | + if (callback && typeof(callback) === 'function') { |
365 | + var self = this; |
366 | + this._object.errorChanged.connect(function() { |
367 | + callback(self._object.errorMessage); |
368 | + }); |
369 | + } |
370 | + }, |
371 | + |
372 | + finished: function(callback) { |
373 | + this._validate(); |
374 | + if (callback && typeof(callback) === 'function') { |
375 | + this._object.finished.connect(callback); |
376 | + } |
377 | + }, |
378 | + |
379 | + canceled: function(callback) { |
380 | + this._validate(); |
381 | + if (callback && typeof(callback) === 'function') { |
382 | + this._object.canceled.connect(callback); |
383 | + } |
384 | + }, |
385 | + |
386 | + paused: function(callback) { |
387 | + this._validate(); |
388 | + if (callback && typeof(callback) === 'function') { |
389 | + this._object.paused.connect(callback); |
390 | + } |
391 | + }, |
392 | + |
393 | + // internal |
394 | + |
395 | + internal: { |
396 | + error: function(self) { |
397 | + return self._object.error; |
398 | + } |
399 | + } |
400 | + }; |
401 | + |
402 | + function DownloadManager(downloadManager, objectid) { |
403 | + var id = objectid; |
404 | + if ( ! downloadManager) { |
405 | + var result = backendDelegate.createQmlObject( |
406 | + PLUGIN_URI, VERSION, 'DownloadManager'); |
407 | + id = result.id; |
408 | + downloadManager = result.object; |
409 | + } |
410 | + if ( ! id) { |
411 | + id = backendDelegate.storeQmlObject(downloadManager, |
412 | + PLUGIN_URI, VERSION, 'DownloadManager'); |
413 | + } |
414 | + |
415 | + this._id = id; |
416 | + this._object = downloadManager; |
417 | + }; |
418 | + DownloadManager.prototype = { |
419 | + _validate: function() { |
420 | + if (! this._object) |
421 | + throw new TypeError("Invalid object null"); |
422 | + }, |
423 | + |
424 | + destroy: function() { |
425 | + if (! this._object) |
426 | + return; |
427 | + this._object.destroy(); |
428 | + backendDelegate.deleteId(this._id); |
429 | + }, |
430 | + |
431 | + // object methods |
432 | + serialize: function() { |
433 | + return { |
434 | + type: 'object-proxy', |
435 | + apiid: 'DownloadApi', |
436 | + objecttype: 'DownloadManager', |
437 | + objectid: this._id, |
438 | + } |
439 | + }, |
440 | + |
441 | + // methods |
442 | + download: function(url) { |
443 | + this._validate(); |
444 | + this._object.download(url); |
445 | + }, |
446 | + |
447 | + // properties |
448 | + autoStart: function(callback) { |
449 | + this._validate(); |
450 | + callback(this._object.autoStart); |
451 | + }, |
452 | + setAutoStart: function(shouldAutoStart, callback) { |
453 | + this._validate(); |
454 | + this._object.autoStart = shouldAutoStart; |
455 | + if (callback && typeof(callback) === 'function') |
456 | + callback(); |
457 | + }, |
458 | + |
459 | + cleanDownloads: function(callback) { |
460 | + this._validate(); |
461 | + callback(this._object.cleanDownloads); |
462 | + }, |
463 | + setCleanDownloads: function(clean, callback) { |
464 | + this._validate(); |
465 | + this._object.cleanDownloads = clean; |
466 | + if (callback && typeof(callback) === 'function') |
467 | + callback(); |
468 | + }, |
469 | + |
470 | + errorMessage: function(callback) { |
471 | + this._validate(); |
472 | + callback(this._object.errorMessage); |
473 | + }, |
474 | + errorChanged: function(callback) { |
475 | + this._validate(); |
476 | + if (callback && typeof(callback) === 'function') { |
477 | + var self = this; |
478 | + this._object.errorChanged.connect(function() { |
479 | + callback(self._object.errorMessage); |
480 | + }); |
481 | + } |
482 | + }, |
483 | + |
484 | + downloads: function(callback) { |
485 | + this._validate(); |
486 | + if (callback && typeof(callback) === 'function') { |
487 | + var downloadCount = this._object.downloads.length; |
488 | + var downloads = []; |
489 | + for (var i = 0; i < downloadCount; ++i) { |
490 | + var download = |
491 | + new SingleDownload(this._object.downloads[i]); |
492 | + downloads.push(download.serialize()); |
493 | + } |
494 | + callback(downloads); |
495 | + } |
496 | + }, |
497 | + downloadsChanged: function(callback) { |
498 | + this._validate(); |
499 | + if (callback && typeof(callback) === 'function') { |
500 | + var self = this; |
501 | + this._object.downloadsChanged.connect(function() { |
502 | + self.downloads(callback); |
503 | + }); |
504 | + } |
505 | + }, |
506 | + }; |
507 | + |
508 | + function _constructorFromName(className) { |
509 | + var constructorPerName = { |
510 | + "SingleDownload": SingleDownload, |
511 | + "DownloadManager": DownloadManager, |
512 | + }; |
513 | + return className in constructorPerName |
514 | + ? constructorPerName[className] |
515 | + : null; |
516 | + } |
517 | + |
518 | + return { |
519 | + createDownloadManager: function(options, callback) { |
520 | + if (! callback || typeof callback !== 'function') |
521 | + return; |
522 | + |
523 | + var autoStart = |
524 | + options && options.autoStart === undefined |
525 | + ? false : options.autoStart; |
526 | + var cleanDownloads = |
527 | + options && options.cleanDownloads === undefined |
528 | + ? false : options.cleanDownloads; |
529 | + |
530 | + var manager = new DownloadManager(); |
531 | + manager.setAutoStart(autoStart); |
532 | + manager.setCleanDownloads(cleanDownloads); |
533 | + |
534 | + callback(manager.serialize()); |
535 | + }, |
536 | + |
537 | + downloadFile: function(url, options, onCompleted, onProgress, onError) { |
538 | + var download = new SingleDownload(); |
539 | + |
540 | + var allowMobileDownload = |
541 | + options && options.allowMobileDownload === undefined ? false : options.allowMobileDownload; |
542 | + var throttle = |
543 | + options && options.throttle ? options.throttle : undefined; |
544 | + |
545 | + if (allowMobileDownload === true) |
546 | + download.setAllowMobileDownload(allowMobileDownload); |
547 | + |
548 | + if (throttle !== undefined) |
549 | + download.setThrottle(throttle); |
550 | + |
551 | + if (onProgress && typeof onProgress === 'function') { |
552 | + download.progressChanged(onProgress); |
553 | + } |
554 | + |
555 | + if (onError && typeof onError === 'function') { |
556 | + download.errorChanged(onError); |
557 | + } |
558 | + |
559 | + if (onCompleted && typeof onCompleted === 'function') { |
560 | + download.finished(function(path) { |
561 | + onCompleted({status: "Success", path: path, download: download.serialize()}) |
562 | + }); |
563 | + download.canceled(function(success) { |
564 | + onCompleted({status: "Cancelled", download: download.serialize()}) |
565 | + }); |
566 | + } |
567 | + |
568 | + download.setAutoStart(true); |
569 | + download.download(url); |
570 | + }, |
571 | + |
572 | + |
573 | + // Internal |
574 | + |
575 | + dispatchToObject: function(infos) { |
576 | + var args = infos.args; |
577 | + var callback = infos.callback; |
578 | + var method_name = infos.method_name; |
579 | + var objectid = infos.objectid; |
580 | + var class_name = infos.class_name; |
581 | + |
582 | + if (callback) |
583 | + args.push(callback); |
584 | + |
585 | + var o = backendDelegate.objectFromId(objectid); |
586 | + if (o == null) { |
587 | + console.debug('Cannot dispatch to unknown object: ' + objectid); |
588 | + return; |
589 | + } |
590 | + |
591 | + var Constructor = _constructorFromName(class_name); |
592 | + |
593 | + var instance = new Constructor(o, objectid); |
594 | + |
595 | + instance[method_name].apply(instance, args); |
596 | + } |
597 | + }; |
598 | +} |
599 | |
600 | === added directory 'src/Ubuntu/UnityWebApps/bindings/download-manager/client' |
601 | === added file 'src/Ubuntu/UnityWebApps/bindings/download-manager/client/download-api.js' |
602 | --- src/Ubuntu/UnityWebApps/bindings/download-manager/client/download-api.js 1970-01-01 00:00:00 +0000 |
603 | +++ src/Ubuntu/UnityWebApps/bindings/download-manager/client/download-api.js 2014-05-21 13:06:21 +0000 |
604 | @@ -0,0 +1,457 @@ |
605 | +/** |
606 | + * DownloadApi gives access to Download management. |
607 | + |
608 | + * @module DownloadApi |
609 | + */ |
610 | +function createDownloadApi(backendBridge) { |
611 | + var PLUGIN_URI = 'DownloadApi'; |
612 | + |
613 | +/** |
614 | + * SingleDownload provides facilities for downloading a single |
615 | + * file, track the process, react to error conditions, etc. |
616 | + * |
617 | + * @class SingleDownload |
618 | + * @constructor |
619 | + * @example |
620 | + |
621 | + */ |
622 | + function SingleDownload(id) { |
623 | + this._proxy = backendBridge.createRemoteObject( |
624 | + PLUGIN_URI, 'SingleDownload', id); |
625 | + }; |
626 | + SingleDownload.prototype = { |
627 | + |
628 | + /** |
629 | + * This property retrieves if the downloads should start automatically, or let the user |
630 | + * decide when to start them calling the "start()" method on each download. |
631 | + * |
632 | + * @method autoStart |
633 | + * @param callback {Function(Error)} |
634 | + */ |
635 | + autoStart: function(callback) { |
636 | + this._proxy.call('autoStart', [], callback); |
637 | + }, |
638 | + /** |
639 | + * This property sets if the downloads should start automatically, or let the user |
640 | + * decide when to start them calling the "start()" method on each download. |
641 | + * |
642 | + * @method setAutoStart |
643 | + * @param shouldAutoStart {Bool} |
644 | + * @param callback (optional) {Function()} To be called after the value is set. |
645 | + */ |
646 | + setAutoStart: function(shouldAutoStart, callback) { |
647 | + this._proxy.call('setAutoStart', [shouldAutoStart], callback); |
648 | + }, |
649 | + |
650 | + /** |
651 | + * Retrieves the current error message (if any) |
652 | + * |
653 | + * @method errorMessage |
654 | + * @param callback {Function(String)} Called with the current error message. |
655 | + */ |
656 | + errorMessage: function(callback) { |
657 | + this._proxy.call('errorMessage', [], callback); |
658 | + }, |
659 | + /** |
660 | + * Sets up a callback that is to be called when error message changes. |
661 | + * |
662 | + * @method errorChanged |
663 | + * @param callback {Function(String)} Called with the current error message. |
664 | + */ |
665 | + errorChanged: function(callback) { |
666 | + this._proxy.call('errorChanged', [callback]); |
667 | + }, |
668 | + |
669 | + /** |
670 | + * Retrieves the property that determines if the download handled by this object |
671 | + * will work under mobile data connection. |
672 | + * |
673 | + * @method allowMobileDownload |
674 | + * @param callback {Function(Bool)} Called with the current value. |
675 | + */ |
676 | + allowMobileDownload: function(callback) { |
677 | + this._proxy.call('allowMobileDownload', [], callback); |
678 | + }, |
679 | + /** |
680 | + * Sets the property that determines if the download handled by this object |
681 | + * will work under mobile data connection. |
682 | + * |
683 | + * @method setAllowMobileDownload |
684 | + * @param allow {Bool} |
685 | + * @param callback (optional) {Function()} Called after the value has been set. |
686 | + */ |
687 | + setAllowMobileDownload: function(allow, callback) { |
688 | + this._proxy.call('setAllowMobileDownload', [allow], callback); |
689 | + }, |
690 | + |
691 | + /** |
692 | + * Retrieves the current state of the download. True if the download already finished, False otherwise. |
693 | + * |
694 | + * @method isCompleted |
695 | + * @param callback {Function(Bool)} Called with the current value. |
696 | + */ |
697 | + isCompleted: function(callback) { |
698 | + this._proxy.call('isCompleted', [], callback); |
699 | + }, |
700 | + /** |
701 | + * Sets up a callback that is to be called when the download completion status changes. |
702 | + * |
703 | + * @method isCompletedChanged |
704 | + * @param callback {Function(Bool)} Function to be called when the download completion status changes. Called with a boolean corresponding to the current value. |
705 | + */ |
706 | + isCompletedChanged: function(callback) { |
707 | + this._proxy.call('isCompletedChanged', [callback]); |
708 | + }, |
709 | + |
710 | + /** |
711 | + * Retrieves the property that indicates if the download is active whatever its internal status is (paused etc.). |
712 | + * If a download is active, the value will be True. It will become False when the download |
713 | + * finished or get canceled. |
714 | + * |
715 | + * @method downloadInProgress |
716 | + * @param callback {Function(Bool)} Called with the current value. |
717 | + */ |
718 | + downloadInProgress: function(callback) { |
719 | + this._proxy.call('downloadInProgress', [], callback); |
720 | + }, |
721 | + /** |
722 | + * Sets up a callback that is to be called when the download progress status changes. |
723 | + * |
724 | + * @method downloadInProgressChanged |
725 | + * @param callback {Function(Bool)} Function to be called when the downloading progress status changes. Called with a boolean corresponding to the current value. |
726 | + */ |
727 | + downloadInProgressChanged: function(callback) { |
728 | + this._proxy.call('downloadInProgressChanged', [callback]); |
729 | + }, |
730 | + |
731 | + /** |
732 | + * Retrieves the property that reports the current progress in percentage of the download, from 0 to 100. |
733 | + * |
734 | + * @method progress |
735 | + * @param callback {Function(Int)} Called with the current value. |
736 | + */ |
737 | + progress: function(callback) { |
738 | + this._proxy.call('progress', [], callback); |
739 | + }, |
740 | + /** |
741 | + * Sets up a callback that is to be called when the progress value changes. |
742 | + * |
743 | + * @method progressChanged |
744 | + * @param callback {Function(Int)} Function to be called when the progress value changes. Called with the current value. |
745 | + */ |
746 | + progressChanged: function(callback) { |
747 | + this._proxy.call('progressChanged', [callback]); |
748 | + }, |
749 | + |
750 | + /** |
751 | + * Retrieves the property that represents the current state of the download. |
752 | + * False if paused or not downloading anything. |
753 | + * True if the file is currently being downloaded. |
754 | + * |
755 | + * @method downloading |
756 | + * @param callback {Function(Bool)} Called with the current value. |
757 | + */ |
758 | + downloading: function(callback) { |
759 | + this._proxy.call('downloading', [], callback); |
760 | + }, |
761 | + /** |
762 | + * Sets up a callback that is to be called when the downloading status changes. |
763 | + * |
764 | + * @method progressChanged |
765 | + * @param callback {Function(Bool)} Function to be called when the downloading status changes. Called with the current value. |
766 | + */ |
767 | + downloadingChanged: function(callback) { |
768 | + this._proxy.call('downloadingChanged', [callback]); |
769 | + }, |
770 | + |
771 | + /** |
772 | + * Sets up a callback that is to be called when the download is finished. |
773 | + * |
774 | + * @method finished |
775 | + * @param callback {Function(String)} Function to be called when the download is finished. Called with a the path of the downloaded file. |
776 | + */ |
777 | + finished: function(callback) { |
778 | + this._proxy.call('finished', [callback]); |
779 | + }, |
780 | + |
781 | + /** |
782 | + * Sets up a callback that is to be called when the download is canceled. |
783 | + * |
784 | + * @method canceled |
785 | + * @param callback {Function(Bool)} Function to be called when the download is canceled. Called with a boolean indicating if the operation was successful. |
786 | + */ |
787 | + canceled: function(callback) { |
788 | + this._proxy.call('canceled', [callback]); |
789 | + }, |
790 | + |
791 | + /** |
792 | + * Sets up a callback that is to be called when the download is paused. |
793 | + * |
794 | + * @method paused |
795 | + * @param callback {Function(Bool)} Function to be called when the download is paused. Called with a boolean indicating if the operation was successful. |
796 | + */ |
797 | + paused: function(callback) { |
798 | + this._proxy.call('paused', [callback]); |
799 | + }, |
800 | + |
801 | + /** |
802 | + * Starts a download. |
803 | + * |
804 | + * @method start |
805 | + */ |
806 | + start: function() { |
807 | + this._proxy.call('start', []); |
808 | + }, |
809 | + |
810 | + /** |
811 | + * Pauses a download. |
812 | + * |
813 | + * @method pause |
814 | + */ |
815 | + pause: function() { |
816 | + this._proxy.call('pause', []); |
817 | + }, |
818 | + |
819 | + /** |
820 | + * Resumes a download. |
821 | + * |
822 | + * @method resume |
823 | + */ |
824 | + resume: function() { |
825 | + this._proxy.call('resume', []); |
826 | + }, |
827 | + |
828 | + /** |
829 | + * Cancels a download. |
830 | + * |
831 | + * @method cancel |
832 | + */ |
833 | + cancel: function() { |
834 | + this._proxy.call('cancel', []); |
835 | + }, |
836 | + |
837 | + /** |
838 | + * Downloads a given item by url. |
839 | + * |
840 | + * @method download |
841 | + * @param url {String} Url of the file to download. |
842 | + */ |
843 | + download: function(url) { |
844 | + this._proxy.call('download', []); |
845 | + }, |
846 | + |
847 | + // extras |
848 | + |
849 | + /** |
850 | + * Destroys the remote object. This proxy object is not valid anymore. |
851 | + * |
852 | + * @method destroy |
853 | + */ |
854 | + destroy: function() { |
855 | + this._proxy.call('destroy', []); |
856 | + }, |
857 | + }; |
858 | + |
859 | + |
860 | + /** |
861 | + * DownloadManager provides facilities for downloading a several |
862 | + * files, list the current downloads in progress or finished, |
863 | + * and dynamically update the content of those to show the current |
864 | + * downloads. |
865 | +. * |
866 | + * @class DownloadManager |
867 | + * @constructor |
868 | + * @example |
869 | + * |
870 | + */ |
871 | + function DownloadManager(id) { |
872 | + this._proxy = backendBridge.createRemoteObject( |
873 | + PLUGIN_URI, 'DownloadManager', id); |
874 | + }; |
875 | + DownloadManager.prototype = { |
876 | + |
877 | + /** |
878 | + * This property sets if the downloads should start automatically, or let the user |
879 | + * decide when to start them calling the "start()" method on each download object. |
880 | + * |
881 | + * @method autoStart |
882 | + * @param callback {Function(Error)} |
883 | + */ |
884 | + autoStart: function(callback) { |
885 | + this._proxy.call('autoStart', [], callback); |
886 | + }, |
887 | + /** |
888 | + * This property sets if the downloads should start automatically, or let the user |
889 | + * decide when to start them calling the "start()" method on each download object. |
890 | + * |
891 | + * @method setAutoStart |
892 | + * @param shouldAutoStart {Bool} |
893 | + * @param callback (optional) {Function()} To be called after the value is set. |
894 | + */ |
895 | + setAutoStart: function(shouldAutoStart, callback) { |
896 | + this._proxy.call('setAutoStart', [shouldAutoStart], callback); |
897 | + }, |
898 | + |
899 | + /** |
900 | + * Retrieves the clean download flag value. |
901 | + * |
902 | + * @method cleanDownloads |
903 | + * @param callback {Function(Bool)} Called with the current value of the clean download flag |
904 | + */ |
905 | + cleanDownloads: function(callback) { |
906 | + this._proxy.call('cleanDownloads', [], callback); |
907 | + }, |
908 | + /** |
909 | + * Sets the value of the clean download flag. This informs the download manager that |
910 | + * the list of SingleDownload listed by the 'downloads' property should only contain |
911 | + * the downloads in progress. Those that finishes are being removed from the list. |
912 | + * |
913 | + * @method setCleanDownloads |
914 | + * @param clean {Bool} |
915 | + * @param callback (optional) {Function()} To be called after the value is set. |
916 | + */ |
917 | + setCleanDownloads: function(clean, callback) { |
918 | + this._proxy.call('setCleanDownloads', [clean], callback); |
919 | + }, |
920 | + |
921 | + /** |
922 | + * Retrieves the current error message (if any) |
923 | + * |
924 | + * @method errorMessage |
925 | + * @param callback {Function(String)} Called with the current error message. |
926 | + */ |
927 | + errorMessage: function(callback) { |
928 | + this._proxy.call('errorMessage', [], callback); |
929 | + }, |
930 | + /** |
931 | + * Sets up a callback that is to be called when error message changes. |
932 | + * |
933 | + * @method errorChanged |
934 | + * @param callback {Function(String)} Called with the current error message. |
935 | + */ |
936 | + errorChanged: function(callback) { |
937 | + this._proxy.call('errorChanged', [callback]); |
938 | + }, |
939 | + |
940 | + /** |
941 | + * Retrieves the current set of download being proceeded. |
942 | + * |
943 | + * @method downloads |
944 | + * @param callback {Function(List of SingleDownload)} Called with the current set of download objects. |
945 | + */ |
946 | + downloads: function(callback) { |
947 | + this._proxy.call('downloads', [], callback); |
948 | + }, |
949 | + /** |
950 | + * Sets up a callback that is to be called when the set of urls being downloaded |
951 | + * changes (items being added or removed). |
952 | + * |
953 | + * @method downloadsChanged |
954 | + * @param callback {Function(List of SingleDownload)} Called with the current set of download objects. |
955 | + */ |
956 | + downloadsChanged: function(callback) { |
957 | + this._proxy.call('downloadsChanged', [callback]); |
958 | + }, |
959 | + |
960 | + /** |
961 | + * Starts a download operation for the given url. |
962 | + * |
963 | + * @method download |
964 | + * @param url {String} |
965 | + */ |
966 | + download: function(url) { |
967 | + this._proxy.call('download', [url]); |
968 | + }, |
969 | + |
970 | + // extras |
971 | + |
972 | + /** |
973 | + * Destroys the remote object. This proxy object is not valid anymore. |
974 | + * |
975 | + * @method destroy |
976 | + */ |
977 | + destroy: function() { |
978 | + this._proxy.call('destroy', []); |
979 | + }, |
980 | + }; |
981 | + |
982 | + function _constructorFromName(className) { |
983 | + var constructorPerName = { |
984 | + "SingleDownload": SingleDownload, |
985 | + "DownloadManager": DownloadManager, |
986 | + }; |
987 | + return className in constructorPerName |
988 | + ? constructorPerName[className] |
989 | + : null; |
990 | + }; |
991 | + |
992 | +/** |
993 | + * The DownloadApi object |
994 | + |
995 | + * @class DownloadApi |
996 | + * @constructor |
997 | + * @example |
998 | + |
999 | + */ |
1000 | + return { |
1001 | + |
1002 | + /** |
1003 | + * Creates a download manager object. |
1004 | + * |
1005 | + * @method createDownloadManager |
1006 | + * @param options {Object} A dictionary of download options. The option keys are: |
1007 | + * - autoStart: This property sets if the downloads should start automatically, or let the user |
1008 | + * decide when to start them calling the "start()" method on each download. |
1009 | + * - cleanDownloads: This informs the download manager that the list of SingleDownload listed by |
1010 | + * the 'downloads' property should only contain the downloads in progress. Those that |
1011 | + * finishes are being removed from the list |
1012 | + * @param callback {Function(DownloadManager)} Function called with the DownloadManager object created. |
1013 | + */ |
1014 | + createDownloadManager: function(options, callback) { |
1015 | + backendBridge.call('DownloadApi.createDownloadManager' |
1016 | + , [options] |
1017 | + , callback); |
1018 | + }, |
1019 | + |
1020 | + /** |
1021 | + * Download a file. |
1022 | + * |
1023 | + * @method downloadFile |
1024 | + * @param url {String} Function called with the created Alarm. |
1025 | + * @param options {Object} A dictionary of download options. The option keys are: |
1026 | + * - allowMobileDownload: |
1027 | + * - throttle: |
1028 | + * @param onCompleted {Function(Object)} Function called when the download completes. The function is called with an dictionary with the following keys: |
1029 | + * - status: status of the download ("Success" or "Cancelled") |
1030 | + * - path: path of the downloaded resource |
1031 | + * - download: SingleDownload object that performed the download (so that it can be inspected & destroyed) |
1032 | + * @param onProgress {Function(Float)} (optional) Function called with current progress. |
1033 | + * @param onError {Function(String)} (optional) Function called when an error occurs with the error message. |
1034 | + * - error: |
1035 | + * - downloads: |
1036 | + */ |
1037 | + downloadFile: function(url, options, onCompleted, onProgress, onError) { |
1038 | + if ( ! onCompleted || typeof onCompleted !== 'function') |
1039 | + throw Error("Invalid (null) onCompleted callback"); |
1040 | + |
1041 | + if ( ! url || typeof url !== 'string') |
1042 | + throw Error("Invalid (null) url"); |
1043 | + |
1044 | + backendBridge.call('DownloadApi.downloadFile' |
1045 | + , [url, options, onCompleted, onProgress, onError]); |
1046 | + }, |
1047 | + |
1048 | + // Internal |
1049 | + |
1050 | + /** |
1051 | + * @private |
1052 | + * |
1053 | + */ |
1054 | + createObjectWrapper: function(objectType, objectId, content) { |
1055 | + var Constructor = _constructorFromName(objectType); |
1056 | + return new Constructor(objectId, content); |
1057 | + }, |
1058 | + }; |
1059 | +}; |
1060 | + |
1061 | + |
1062 | |
1063 | === modified file 'src/Ubuntu/UnityWebApps/unity-webapps-api.js.in' |
1064 | --- src/Ubuntu/UnityWebApps/unity-webapps-api.js.in 2014-03-26 15:52:46 +0000 |
1065 | +++ src/Ubuntu/UnityWebApps/unity-webapps-api.js.in 2014-05-21 13:06:21 +0000 |
1066 | @@ -34,6 +34,7 @@ |
1067 | //@include ./bindings/content-hub/client/content-hub.js |
1068 | //@include ./bindings/online-accounts/client/online-accounts.js |
1069 | //@include ./bindings/runtime-api/client/runtime-api.js |
1070 | + //@include ./bindings/download-manager/client/download-api.js |
1071 | //@include ./common/js/unity-backend-messaging-proxy.js |
1072 | //@include ./common/js/unity-binding-proxy.js |
1073 | //@include ./common/js/unity-binding-bridge.js |
1074 | @@ -282,6 +283,7 @@ |
1075 | AlarmApi: createAlarmApi(backend), |
1076 | ContentHub: createContentHubApi(backend), |
1077 | RuntimeApi: createRuntimeApi(backend), |
1078 | + DownloadApi: createDownloadApi(backend), |
1079 | }; |
1080 | |
1081 | return api; |
1082 | |
1083 | === modified file 'tests/integration/autopilot/qml/FullWebViewApp.qml' |
1084 | --- tests/integration/autopilot/qml/FullWebViewApp.qml 2014-04-22 15:40:04 +0000 |
1085 | +++ tests/integration/autopilot/qml/FullWebViewApp.qml 2014-05-21 13:06:21 +0000 |
1086 | @@ -66,8 +66,6 @@ |
1087 | experimental.preferences.navigatorQtObjectEnabled: true |
1088 | experimental.preferences.developerExtrasEnabled: true |
1089 | |
1090 | - onLoadingChanged: console.debug('onLoadingChanged: loading changed: ' + loadRequest.url + ', status: ' + loadRequest.status) |
1091 | - |
1092 | function getUnityWebappsProxies() { |
1093 | return UnityWebAppsUtils.makeProxiesForQtWebViewBindee(webView); |
1094 | } |
1095 | |
1096 | === modified file 'tests/integration/autopilot/unity_webapps_qml/emulators/__init__.py' |
1097 | --- tests/integration/autopilot/unity_webapps_qml/emulators/__init__.py 2013-06-17 14:46:51 +0000 |
1098 | +++ tests/integration/autopilot/unity_webapps_qml/emulators/__init__.py 2014-05-21 13:06:21 +0000 |
1099 | @@ -4,4 +4,3 @@ |
1100 | # This program is free software: you can redistribute it and/or modify it |
1101 | # under the terms of the GNU General Public License version 3, as published |
1102 | # by the Free Software Foundation. |
1103 | - |
1104 | |
1105 | === modified file 'tests/integration/autopilot/unity_webapps_qml/tests/__init__.py' |
1106 | --- tests/integration/autopilot/unity_webapps_qml/tests/__init__.py 2014-04-22 15:40:04 +0000 |
1107 | +++ tests/integration/autopilot/unity_webapps_qml/tests/__init__.py 2014-05-21 13:06:21 +0000 |
1108 | @@ -9,23 +9,29 @@ |
1109 | |
1110 | import os |
1111 | import os.path |
1112 | -import shutil |
1113 | -import tempfile |
1114 | import json |
1115 | |
1116 | -from testtools.matchers import Contains, Equals, GreaterThan |
1117 | +from autopilot import platform |
1118 | +from testtools.matchers import Equals, GreaterThan |
1119 | from autopilot.matchers import Eventually |
1120 | |
1121 | -from unity.emulators.unity import Unity |
1122 | - |
1123 | -from unity.tests import UnityTestCase |
1124 | - |
1125 | -class UnityWebappsTestCaseBase(UnityTestCase): |
1126 | - LOCAL_QML_LAUNCHER_APP_PATH = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), '../../../../../tools/qml-launcher/unity-webapps-qml-launcher') |
1127 | +from autopilot.testcase import AutopilotTestCase |
1128 | + |
1129 | +if platform.model() == 'Desktop': |
1130 | + from unity.tests import UnityTestCase |
1131 | + UnityWebappsTestCaseBaseParent = UnityTestCase |
1132 | +else: |
1133 | + UnityWebappsTestCaseBaseParent = AutopilotTestCase |
1134 | + |
1135 | +class UnityWebappsTestCaseBase(UnityWebappsTestCaseBaseParent): |
1136 | + LOCAL_QML_LAUNCHER_APP_PATH = "%s/%s" % ( |
1137 | + os.path.dirname(os.path.realpath(__file__)), |
1138 | + '../../../../../tools/qml-launcher/unity-webapps-qml-launcher') |
1139 | INSTALLED_QML_LAUNCHER_APP_PATH = 'unity-webapps-qml-launcher' |
1140 | |
1141 | # TODO create __init__.py.in |
1142 | - LOCAL_BROWSER_CONTAINER_PATH = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), '../../qml/FullWebViewApp.qml') |
1143 | + LOCAL_BROWSER_CONTAINER_PATH = "%s/%s" % ( |
1144 | + os.path.dirname(os.path.realpath(__file__)), '../../qml/FullWebViewApp.qml') |
1145 | INSTALLED_BROWSER_CONTAINER_PATH = '/usr/share/unity-webapps-qml/autopilot-tests/qml/FullWebViewApp.qml' |
1146 | |
1147 | BASE_URL = '' |
1148 | @@ -44,10 +50,15 @@ |
1149 | return self.INSTALLED_QML_LAUNCHER_APP_PATH |
1150 | |
1151 | def get_launch_params(self, url): |
1152 | - base_params = ['--qml=' + self.get_qml_browser_container_path(), '--url=' + url, '--app-id=unitywebappsqmllauncher', '--webappName=unitywebappsqmllauncher'] |
1153 | + base_params = ['--qml=' + self.get_qml_browser_container_path(), |
1154 | + '--url=' + url, |
1155 | + '--app-id=unitywebappsqmllauncher', |
1156 | + '--webappName=unitywebappsqmllauncher'] |
1157 | if os.path.exists(self.LOCAL_QML_LAUNCHER_APP_PATH): |
1158 | # we are local |
1159 | - base_params.append('--import=' + os.path.join (os.path.dirname(os.path.realpath(__file__)), '../../../../../src')) |
1160 | + base_params.append( |
1161 | + '--import=' + os.path.join(os.path.dirname(os.path.realpath(__file__)), |
1162 | + '../../../../../src')) |
1163 | return base_params |
1164 | |
1165 | def launch_with_html_filepath(self, html_filepath): |
1166 | @@ -58,8 +69,8 @@ |
1167 | |
1168 | print 'Launching test with params:', params |
1169 | self.app = self.launch_test_application(self.get_qml_launcher_path(), |
1170 | - *params, |
1171 | - app_type='qt') |
1172 | + *params, |
1173 | + app_type='qt') |
1174 | |
1175 | self.assert_url_eventually_loaded(url) |
1176 | self.webviewContainer = self.get_webviewContainer() |
1177 | @@ -97,5 +108,4 @@ |
1178 | webview.slots.evalInPageUnsafe(expr) |
1179 | self.assertThat(lambda: self.watcher.num_emissions, Eventually(GreaterThan(prev_emissions))) |
1180 | results = json.loads(webview.get_signal_emissions('resultUpdated(QString)')[-1][0]) |
1181 | - return results.has_key('result') and results['result'] or None |
1182 | - |
1183 | + return 'result' in results and results['result'] or None |
1184 | |
1185 | === removed file 'tests/integration/autopilot/unity_webapps_qml/tests/test_hud.py' |
1186 | --- tests/integration/autopilot/unity_webapps_qml/tests/test_hud.py 2014-04-22 15:40:04 +0000 |
1187 | +++ tests/integration/autopilot/unity_webapps_qml/tests/test_hud.py 1970-01-01 00:00:00 +0000 |
1188 | @@ -1,81 +0,0 @@ |
1189 | -#!/usr/bin/env python |
1190 | -# Copyright 2013 Canonical |
1191 | -# |
1192 | -# This program is free software: you can redistribute it and/or modify it |
1193 | -# under the terms of the GNU General Public License version 3, as published |
1194 | -# by the Free Software Foundation. |
1195 | - |
1196 | -import os |
1197 | -import time |
1198 | - |
1199 | -from testtools.matchers import Equals, GreaterThan, NotEquals |
1200 | -from autopilot.matchers import Eventually |
1201 | - |
1202 | -from autopilot import platform |
1203 | - |
1204 | -from unity.emulators.icons import HudLauncherIcon |
1205 | -from unity.emulators import ensure_unity_is_running |
1206 | - |
1207 | -from unity_webapps_qml.tests import UnityWebappsTestCaseBase |
1208 | - |
1209 | -class UnityWebappsHudTestCase(UnityWebappsTestCaseBase): |
1210 | - LOCAL_HTML_TEST_FILE = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), '../../html/test_webapps_hud.html') |
1211 | - INSTALLED_HTML_TEST_FILE = '/usr/share/unity-webapps-qml/autopilot-tests/html/test_webapps_hud.html' |
1212 | - |
1213 | - def get_html_test_file(self): |
1214 | - if os.path.exists(self.LOCAL_HTML_TEST_FILE): |
1215 | - return os.path.abspath(self.LOCAL_HTML_TEST_FILE) |
1216 | - return self.INSTALLED_HTML_TEST_FILE |
1217 | - |
1218 | - def setUp(self): |
1219 | - super(UnityWebappsHudTestCase, self).setUp() |
1220 | - # On Touch the dbus unity if does is not exposed |
1221 | - if platform.model() == 'Desktop': |
1222 | - ensure_unity_is_running() |
1223 | - self.launch_with_html_filepath(self.get_html_test_file()) |
1224 | - |
1225 | - def test_addAction(self): |
1226 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe("return document.getElementById('status').innerHTML;"), Eventually(Equals('actionadded'))) |
1227 | - |
1228 | - self.unity.hud.ensure_visible() |
1229 | - self.addCleanup(self.unity.hud.ensure_hidden) |
1230 | - |
1231 | - self.keyboard.type("Hello") |
1232 | - self.keyboard.press_and_release("Enter") |
1233 | - |
1234 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe("return document.getElementById('content').style.display;"), Eventually(Equals('none'))) |
1235 | - |
1236 | - def test_clearAction(self): |
1237 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe("return document.getElementById('status').innerHTML;"), Eventually(Equals('actionadded'))) |
1238 | - expr = """ |
1239 | - var e = new CustomEvent ("unity-webapps-do-call", {"detail": JSON.stringify({"name": 'clearAction', 'args': ['Hello']})}); |
1240 | - document.dispatchEvent (e); |
1241 | - return true; |
1242 | - """ |
1243 | - self.eval_expression_in_page_unsafe(expr) |
1244 | - |
1245 | - self.unity.hud.ensure_visible() |
1246 | - self.addCleanup(self.unity.hud.ensure_hidden) |
1247 | - |
1248 | - self.keyboard.type("Hello") |
1249 | - self.keyboard.press_and_release("Enter") |
1250 | - self.assertThat(self.eval_expression_in_page_unsafe("return document.getElementById('content').style.display;"), NotEquals('none')) |
1251 | - |
1252 | - def test_clearActions(self): |
1253 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe("return document.getElementById('status').innerHTML;"), Eventually(Equals('actionadded'))) |
1254 | - expr = """ |
1255 | - var e = new CustomEvent ("unity-webapps-do-call", {"detail": JSON.stringify({"name": 'clearActions', 'args': []})}); |
1256 | - document.dispatchEvent (e); |
1257 | - return true; |
1258 | - """ |
1259 | - |
1260 | - self.eval_expression_in_page_unsafe(expr) |
1261 | - |
1262 | - actions = ['Hello', 'Another action'] |
1263 | - for action in actions: |
1264 | - self.unity.hud.ensure_visible() |
1265 | - self.addCleanup(self.unity.hud.ensure_hidden) |
1266 | - self.keyboard.type(action) |
1267 | - self.keyboard.press_and_release("Enter") |
1268 | - |
1269 | - self.assertThat(self.eval_expression_in_page_unsafe("return document.getElementById('content').style.display;"), NotEquals('none')) |
1270 | |
1271 | === modified file 'tests/integration/autopilot/unity_webapps_qml/tests/test_injectedOnWebapp.py' |
1272 | --- tests/integration/autopilot/unity_webapps_qml/tests/test_injectedOnWebapp.py 2014-04-22 15:40:04 +0000 |
1273 | +++ tests/integration/autopilot/unity_webapps_qml/tests/test_injectedOnWebapp.py 2014-05-21 13:06:21 +0000 |
1274 | @@ -7,16 +7,18 @@ |
1275 | |
1276 | from __future__ import absolute_import |
1277 | |
1278 | -import time |
1279 | import os |
1280 | |
1281 | -from testtools.matchers import Equals, GreaterThan, NotEquals |
1282 | +from testtools.matchers import Equals |
1283 | from autopilot.matchers import Eventually |
1284 | |
1285 | from unity_webapps_qml.tests import UnityWebappsTestCaseBase |
1286 | |
1287 | + |
1288 | class UnityWebappsApiInjectedTestCaseBase(UnityWebappsTestCaseBase): |
1289 | - LOCAL_HTML_TEST_FILE = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), '../../html/test_webapps_api_injected.html') |
1290 | + LOCAL_HTML_TEST_FILE = "%s/%s" % ( |
1291 | + os.path.dirname(os.path.realpath(__file__)), |
1292 | + '../../html/test_webapps_api_injected.html') |
1293 | |
1294 | INSTALLED_HTML_TEST_FILE = '/usr/share/unity-webapps-qml/autopilot-tests/html/test_webapps_api_injected.html' |
1295 | |
1296 | @@ -30,28 +32,44 @@ |
1297 | self.launch_with_html_filepath(self.get_html_test_file()) |
1298 | |
1299 | def test_getUnityObjectFound(self): |
1300 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe('return window.external.getUnityObject("1.0") != null'), Eventually(Equals(True))) |
1301 | + self.assertThat( |
1302 | + lambda: self.eval_expression_in_page_unsafe( |
1303 | + 'return window.external.getUnityObject("1.0") != null'), |
1304 | + Eventually(Equals(True))) |
1305 | |
1306 | def test_actionsApiFound(self): |
1307 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe('return window.external.getUnityObject("1.0") != null;'), Eventually(Equals(True))) |
1308 | + self.assertThat( |
1309 | + lambda: self.eval_expression_in_page_unsafe( |
1310 | + 'return window.external.getUnityObject("1.0") != null;'), |
1311 | + Eventually(Equals(True))) |
1312 | |
1313 | expression = """ |
1314 | var unity = window.external.getUnityObject("1.0"); |
1315 | return unity.addAction != null && unity.clearActions != null && unity.clearAction != null; |
1316 | """ |
1317 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe(expression), Eventually(Equals(True))) |
1318 | + self.assertThat( |
1319 | + lambda: self.eval_expression_in_page_unsafe(expression), |
1320 | + Eventually(Equals(True))) |
1321 | |
1322 | def test_notificationApiFound(self): |
1323 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe('return window.external.getUnityObject("1.0") != null;'), Eventually(Equals(True))) |
1324 | + self.assertThat( |
1325 | + lambda: self.eval_expression_in_page_unsafe( |
1326 | + 'return window.external.getUnityObject("1.0") != null;'), |
1327 | + Eventually(Equals(True))) |
1328 | |
1329 | expression = """ |
1330 | var unity = window.external.getUnityObject("1.0"); |
1331 | return unity.Notification != null && unity.Notification.showNotification != null; |
1332 | """ |
1333 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe(expression), Eventually(Equals(True))) |
1334 | + self.assertThat( |
1335 | + lambda: self.eval_expression_in_page_unsafe(expression), |
1336 | + Eventually(Equals(True))) |
1337 | |
1338 | def test_messagingIndicatorApiFound(self): |
1339 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe('return window.external.getUnityObject("1.0") != null;'), Eventually(Equals(True))) |
1340 | + self.assertThat( |
1341 | + lambda: self.eval_expression_in_page_unsafe( |
1342 | + 'return window.external.getUnityObject("1.0") != null;'), |
1343 | + Eventually(Equals(True))) |
1344 | |
1345 | expression = """ |
1346 | var unity = window.external.getUnityObject("1.0"); |
1347 | @@ -61,15 +79,20 @@ |
1348 | unity.MessagingIndicator.clearIndicators != null && |
1349 | unity.MessagingIndicator.showIndicator != null; |
1350 | """ |
1351 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe(expression), Eventually(Equals(True))) |
1352 | + self.assertThat( |
1353 | + lambda: self.eval_expression_in_page_unsafe(expression), |
1354 | + Eventually(Equals(True))) |
1355 | |
1356 | def test_ubuntuReadyEventSent(self): |
1357 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe('return window.external.getUnityObject("1.0") != null;'), Eventually(Equals(True))) |
1358 | + self.assertThat( |
1359 | + lambda: self.eval_expression_in_page_unsafe( |
1360 | + 'return window.external.getUnityObject("1.0") != null;'), |
1361 | + Eventually(Equals(True))) |
1362 | |
1363 | expression = """ |
1364 | var api_ready_count = window.localStorage['ubuntu-webapps-api-ready-key']; |
1365 | return api_ready_count != null && api_ready_count > 0; |
1366 | """ |
1367 | - self.assertThat(lambda: self.eval_expression_in_page_unsafe(expression), Eventually(Equals(True))) |
1368 | - |
1369 | - |
1370 | + self.assertThat( |
1371 | + lambda: self.eval_expression_in_page_unsafe(expression), |
1372 | + Eventually(Equals(True))) |
1373 | |
1374 | === modified file 'tests/integration/autopilot/unity_webapps_qml/tests/test_launcher.py' |
1375 | --- tests/integration/autopilot/unity_webapps_qml/tests/test_launcher.py 2013-09-23 19:59:29 +0000 |
1376 | +++ tests/integration/autopilot/unity_webapps_qml/tests/test_launcher.py 2014-05-21 13:06:21 +0000 |
1377 | @@ -6,21 +6,16 @@ |
1378 | # by the Free Software Foundation. |
1379 | |
1380 | import os |
1381 | -import time |
1382 | - |
1383 | -from gi.repository import Unity, GObject |
1384 | - |
1385 | -from testtools.matchers import Equals, GreaterThan, NotEquals |
1386 | + |
1387 | +from testtools.matchers import Equals, NotEquals |
1388 | from testtools import skipUnless |
1389 | |
1390 | from autopilot import platform |
1391 | from autopilot.matchers import Eventually |
1392 | |
1393 | -from unity.emulators.icons import HudLauncherIcon |
1394 | -from unity.emulators import ensure_unity_is_running |
1395 | - |
1396 | from unity_webapps_qml.tests import UnityWebappsTestCaseBase |
1397 | |
1398 | + |
1399 | class UnityWebappsLauncherTestCase(UnityWebappsTestCaseBase): |
1400 | LOCAL_HTML_TEST_FILE = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), '../../html/test_webapps_launcher.html') |
1401 | INSTALLED_HTML_TEST_FILE = '/usr/share/unity-webapps-qml/autopilot-tests/html/test_webapps_launcher.html' |
1402 | @@ -34,6 +29,7 @@ |
1403 | super(UnityWebappsLauncherTestCase, self).setUp() |
1404 | # On Touch the dbus unity if does is not exposed |
1405 | if platform.model() == 'Desktop': |
1406 | + from unity.emulators import ensure_unity_is_running |
1407 | ensure_unity_is_running() |
1408 | self.launch_with_html_filepath(self.get_html_test_file()) |
1409 | |
1410 | @@ -55,11 +51,8 @@ |
1411 | return true; |
1412 | """ |
1413 | self.eval_expression_in_page_unsafe(expr) |
1414 | - |
1415 | self.assertThat(lambda: self.eval_expression_in_page_unsafe("return document.getElementById('status').innerHTML;"), Eventually(Equals('42'))) |
1416 | |
1417 | - # self.assertThat(launcher.get_property('progress'), Equals(0.09375)) |
1418 | - |
1419 | @skipUnless(platform.model() == 'Desktop', "Only runs on the Desktop") |
1420 | def test_checkProgress(self): |
1421 | self.assertThat(lambda: self.eval_expression_in_page_unsafe("return document.getElementById('status').innerHTML;"), Eventually(Equals('launcher-updated'))) |
1422 | @@ -78,6 +71,5 @@ |
1423 | return true; |
1424 | """ |
1425 | self.eval_expression_in_page_unsafe(expr) |
1426 | - |
1427 | self.assertThat(lambda: self.eval_expression_in_page_unsafe("return document.getElementById('status').innerHTML;"), Eventually(Equals('0.09375'))) |
1428 | |
1429 | |
1430 | === modified file 'tests/integration/autopilot/unity_webapps_qml/tests/test_mediaplayer.py' |
1431 | --- tests/integration/autopilot/unity_webapps_qml/tests/test_mediaplayer.py 2013-09-23 19:59:29 +0000 |
1432 | +++ tests/integration/autopilot/unity_webapps_qml/tests/test_mediaplayer.py 2014-05-21 13:06:21 +0000 |
1433 | @@ -6,11 +6,8 @@ |
1434 | # by the Free Software Foundation. |
1435 | |
1436 | import os |
1437 | -import time |
1438 | - |
1439 | -from gi.repository import Unity, GObject |
1440 | - |
1441 | -from testtools.matchers import Equals, GreaterThan, NotEquals |
1442 | + |
1443 | +from testtools.matchers import Equals |
1444 | from testtools import skipUnless |
1445 | |
1446 | from autopilot import platform |
1447 | @@ -108,4 +105,3 @@ |
1448 | self.eval_expression_in_page_unsafe(expr) |
1449 | |
1450 | self.assertThat(lambda: self.eval_expression_in_page_unsafe("return document.getElementById('status').innerHTML;"), Eventually(Equals('true'))) |
1451 | - |
Tested, works fine!