Merge lp:~unity-team/unity/phablet.dashBar_bottomswipe into lp:unity/phablet
- phablet.dashBar_bottomswipe
- Merge into phablet
Status: | Rejected |
---|---|
Rejected by: | Andrea Cimitan |
Proposed branch: | lp:~unity-team/unity/phablet.dashBar_bottomswipe |
Merge into: | lp:unity/phablet |
Diff against target: |
465 lines (+311/-50) 5 files modified
CMakeLists.txt (+1/-0) Dash/DashBar.qml (+146/-46) tests/qmluitests/CMakeLists.txt (+1/-0) tests/qmluitests/UnityTestCase.qml (+6/-4) tests/qmluitests/tst_DashBar.qml (+157/-0) |
To merge this branch: | bzr merge lp:~unity-team/unity/phablet.dashBar_bottomswipe |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Michał Sawicz | Needs Fixing | ||
Michael Zanetti (community) | Needs Fixing | ||
Review via email: mp+150847@code.launchpad.net |
Commit message
Bottom swipe reveals the dash bar
Description of the change
Bottom swipe reveals the dash bar, integrating some logic from GenericToolbar.qml internal qml component used in the SDK
PS Jenkins bot (ps-jenkins) wrote : | # |
Michael Zanetti (mzanetti) wrote : | # |
misses tests
- 439. By Andrea Cimitan
-
Merged trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:439
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 440. By Andrea Cimitan
-
Merged trunk, modified unittests CMakeList, added WIP qmluitest DashBar
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:440
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
- 441. By Andrea Cimitan
-
Some more tests
- 442. By Andrea Cimitan
-
Merged trunk
- 443. By Andrea Cimitan
-
Add slow swipe
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:443
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 444. By Andrea Cimitan
-
Add test for hide after navigation
- 445. By Andrea Cimitan
-
Add test for itemSelected, added readonly property rowWidth for the wdth of the row inside the DashBar, made some properties readonly
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:445
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) wrote : | # |
Can we please have a separate MR with just the CMake tweaks?
Also, this looks a lot like a copy of what's there for the Launcher, could we not think of a way of abstracting that behaviour?
- 446. By Michael Zanetti
-
make it even more weird
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:446
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 447. By Andrea Cimitan
-
This is weird
- 448. By Andrea Cimitan
-
better debug
- 449. By Andrea Cimitan
-
Finished testing DashBar
- 450. By Andrea Cimitan
-
Revert old CMake for unittests
Andrea Cimitan (cimi) wrote : | # |
> Can we please have a separate MR with just the CMake tweaks?
>
I extracted and pushed lp:~unity-team/unity/phablet.unittests_new-cmake
> Also, this looks a lot like a copy of what's there for the Launcher, could we
> not think of a way of abstracting that behaviour?
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:447
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 451. By Andrea Cimitan
-
id: root is not used
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:450
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:451
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Andrea Cimitan (cimi) wrote : | # |
> misses tests
not anymore! :-)
Michael Zanetti (mzanetti) wrote : | # |
> > misses tests
>
> not anymore! :-)
Great! Testing looks ok. I couldn't verify because there are a bunch of merge conflicts by now. Anyways, once they are resolved its fine with me.
I think there is one Needs Fixing from Saviq left tho. The one about duplicating the dragging-code from the launcher.
Michael Zanetti (mzanetti) wrote : | # |
Can we please either fix or delete this?
Andrea Cimitan (cimi) wrote : | # |
There's a new branch using Panel SDK component
Unmerged revisions
- 451. By Andrea Cimitan
-
id: root is not used
- 450. By Andrea Cimitan
-
Revert old CMake for unittests
- 449. By Andrea Cimitan
-
Finished testing DashBar
- 448. By Andrea Cimitan
-
better debug
- 447. By Andrea Cimitan
-
This is weird
- 446. By Michael Zanetti
-
make it even more weird
- 445. By Andrea Cimitan
-
Add test for itemSelected, added readonly property rowWidth for the wdth of the row inside the DashBar, made some properties readonly
- 444. By Andrea Cimitan
-
Add test for hide after navigation
- 443. By Andrea Cimitan
-
Add slow swipe
- 442. By Andrea Cimitan
-
Merged trunk
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2013-03-19 09:16:26 +0000 |
3 | +++ CMakeLists.txt 2013-03-20 15:46:22 +0000 |
4 | @@ -32,6 +32,7 @@ |
5 | # Tests |
6 | enable_testing() |
7 | add_custom_target(check make test CTEST_OUTPUT_ON_FAILURE=1) |
8 | +add_dependencies(check make unittests CTEST_OUTPUT_ON_FAILURE=1) |
9 | |
10 | # Autopilot tests |
11 | include(autopilot) |
12 | |
13 | === modified file 'Dash/DashBar.qml' |
14 | --- Dash/DashBar.qml 2013-01-15 11:37:07 +0000 |
15 | +++ Dash/DashBar.qml 2013-03-20 15:46:22 +0000 |
16 | @@ -17,6 +17,7 @@ |
17 | import QtQuick 2.0 |
18 | import Ubuntu.Components 0.1 |
19 | import Unity 0.1 |
20 | +import "../Components" |
21 | |
22 | Item { |
23 | id: dashBar |
24 | @@ -24,23 +25,24 @@ |
25 | property var model |
26 | property int currentIndex |
27 | |
28 | - property int lineHeight: units.dp(2) |
29 | - property int itemSize: units.gu(7) |
30 | - property int iconSize: units.gu(2.5) |
31 | - property int initialHeight: lineHeight |
32 | - property int maxHeight: units.gu(6) |
33 | + readonly property alias rowWidth: row.width |
34 | + readonly property int lineHeight: units.dp(2) |
35 | + readonly property int itemSize: units.gu(7) |
36 | + readonly property int iconSize: units.gu(2.5) |
37 | + readonly property int initialHeight: lineHeight |
38 | + readonly property int maxHeight: units.gu(6) |
39 | |
40 | width: units.gu(40) |
41 | height: initialHeight |
42 | Behavior on height {NumberAnimation { duration: 300; easing.type: Easing.OutQuad}} |
43 | |
44 | - state: "initial" |
45 | + state: "hint" |
46 | |
47 | signal itemSelected(int index) |
48 | |
49 | function startNavigation() { |
50 | timeout.stop() |
51 | - dashBar.state = "navigation" |
52 | + dashBar.state = "spread" |
53 | } |
54 | |
55 | function stopNavigation() { |
56 | @@ -48,7 +50,140 @@ |
57 | } |
58 | |
59 | function finishNavigation() { |
60 | - dashBar.state = "initial" |
61 | + dashBar.state = "hint" |
62 | + } |
63 | + |
64 | + states: [ |
65 | + State { |
66 | + name: "hint" |
67 | + PropertyChanges { |
68 | + target: bar |
69 | + y: bar.height - initialHeight |
70 | + } |
71 | + PropertyChanges { |
72 | + target: dashBar |
73 | + height: initialHeight |
74 | + } |
75 | + }, |
76 | + State { |
77 | + name: "moving" |
78 | + PropertyChanges { |
79 | + target: bar |
80 | + y: MathUtils.clamp(bar.height, draggingArea.mouseY - internal.movingDelta, 0, bar.height) |
81 | + } |
82 | + PropertyChanges { |
83 | + target: dashBar |
84 | + height: Math.max(bar.height - bar.y, initialHeight) |
85 | + } |
86 | + }, |
87 | + State { |
88 | + name: "spread" |
89 | + PropertyChanges { |
90 | + target: bar |
91 | + y: 0 |
92 | + } |
93 | + PropertyChanges { |
94 | + target: dashBar |
95 | + height: maxHeight |
96 | + } |
97 | + } |
98 | + ] |
99 | + |
100 | + transitions: [ |
101 | + Transition { |
102 | + to: "hint" |
103 | + PropertyAnimation { |
104 | + target: bar |
105 | + properties: "y" |
106 | + duration: 100 |
107 | + easing.type: Easing.OutQuad |
108 | + } |
109 | + }, |
110 | + Transition { |
111 | + to: "spread" |
112 | + PropertyAnimation { |
113 | + target: bar |
114 | + properties: "y" |
115 | + duration: 100 |
116 | + easing.type: Easing.OutQuad |
117 | + } |
118 | + } |
119 | + ] |
120 | + |
121 | + QtObject { |
122 | + id: internal |
123 | + property string previousState: "hint" |
124 | + property int movingDelta |
125 | + } |
126 | + |
127 | + onStateChanged: { |
128 | + if (state == "hint" || (state == "moving" && internal.previousState == "hint")) { |
129 | + internal.movingDelta = dashBar.initialHeight + draggingArea.initialY - bar.height; |
130 | + } else if (state == "moving" && internal.previousState == "spread") { |
131 | + internal.movingDelta = draggingArea.initialY; |
132 | + } |
133 | + |
134 | + internal.previousState = state; |
135 | + } |
136 | + |
137 | + Timer { |
138 | + id: timeout |
139 | + interval: 1500 |
140 | + running: false |
141 | + repeat: false |
142 | + onTriggered: finishNavigation() |
143 | + } |
144 | + |
145 | + Item { |
146 | + id: bar |
147 | + height: maxHeight |
148 | + anchors { |
149 | + left: parent.left |
150 | + right: parent.right |
151 | + } |
152 | + |
153 | + y: dashBar.state == "spread" ? 0 : height - initialHeight |
154 | + } |
155 | + |
156 | + DraggingArea { |
157 | + orientation: Qt.Vertical |
158 | + id: draggingArea |
159 | + anchors { |
160 | + bottom: parent.bottom |
161 | + left: parent.left |
162 | + right: parent.right |
163 | + } |
164 | + height: dashBar.state == "spread" ? bar.height + units.gu(1) : units.gu(2) |
165 | + zeroVelocityCounts: true |
166 | + propagateComposedEvents: true |
167 | + |
168 | + property int initialY |
169 | + |
170 | + onPressed: { |
171 | + if (dashBar.state == "hint") |
172 | + initialY = mouseY |
173 | + } |
174 | + |
175 | + onPositionChanged: { |
176 | + dashBar.state = "moving"; |
177 | + } |
178 | + |
179 | + onReleased: finishMoving() |
180 | + // Mouse cursor moving out of the window while pressed on desktop |
181 | + onCanceled: finishMoving() |
182 | + |
183 | + // FIXME: Make all parameters below themable. |
184 | + // The value of 44 was copied from the Launcher. |
185 | + function finishMoving() { |
186 | + if (draggingArea.dragVelocity < -44) { |
187 | + dashBar.state = "spread"; |
188 | + } else if (draggingArea.dragVelocity > 44) { |
189 | + dashBar.state = "hint"; |
190 | + } else { |
191 | + dashBar.state = (bar.y < bar.height / 2) ? "spread" : "hint"; |
192 | + } |
193 | + timeout.restart() |
194 | + } |
195 | } |
196 | |
197 | Rectangle { |
198 | @@ -64,7 +199,7 @@ |
199 | anchors.horizontalCenter: parent.horizontalCenter |
200 | currentIndex: dashBar.currentIndex |
201 | onMovingChanged: if (moving) { timeout.stop() } else { timeout.restart() } |
202 | - interactive: visibleArea.widthRatio < 1 && dashBar.state == "navigation" |
203 | + interactive: visibleArea.widthRatio < 1 && dashBar.state == "spread" |
204 | delegate: |
205 | Item { |
206 | width: itemSize |
207 | @@ -85,22 +220,12 @@ |
208 | smooth: true |
209 | } |
210 | MouseArea { |
211 | - enabled: dashBar.state == "navigation" |
212 | + enabled: dashBar.state == "spread" |
213 | anchors.fill: parent |
214 | - onPressed: { |
215 | - timeout.stop() |
216 | - if (dashbar.state == "initial") { |
217 | - dashbar.state = "navigation" |
218 | - mouse.accepted = false |
219 | - } |
220 | - } |
221 | - |
222 | - onReleased: { |
223 | - timeout.restart() |
224 | - } |
225 | |
226 | onClicked: { |
227 | dashBar.itemSelected(index) |
228 | + timeout.restart() |
229 | } |
230 | } |
231 | } |
232 | @@ -119,30 +244,5 @@ |
233 | } |
234 | } |
235 | } |
236 | - |
237 | - Timer { |
238 | - id: timeout |
239 | - interval: 1500 |
240 | - running: false |
241 | - repeat: false |
242 | - onTriggered: finishNavigation() |
243 | - } |
244 | - |
245 | - states: [ |
246 | - State { |
247 | - name: "initial" |
248 | - PropertyChanges { |
249 | - target: dashBar |
250 | - height: initialHeight |
251 | - } |
252 | - }, |
253 | - State { |
254 | - name: "navigation" |
255 | - PropertyChanges { |
256 | - target: dashBar |
257 | - height: maxHeight |
258 | - } |
259 | - } |
260 | - ] |
261 | } |
262 | |
263 | |
264 | === modified file 'tests/qmluitests/CMakeLists.txt' |
265 | --- tests/qmluitests/CMakeLists.txt 2013-03-20 09:39:25 +0000 |
266 | +++ tests/qmluitests/CMakeLists.txt 2013-03-20 15:46:22 +0000 |
267 | @@ -20,6 +20,7 @@ |
268 | add_dependencies(qmluitests test${COMPONENT_NAME}) |
269 | endmacro(add_qml_test) |
270 | |
271 | +add_qml_test(DashBar ${CMAKE_SOURCE_DIR}/plugins) |
272 | add_qml_test(DraggingArea) |
273 | add_qml_test(FilterGrid ${CMAKE_BINARY_DIR}/plugins) |
274 | add_qml_test(Hud ${CMAKE_CURRENT_BINARY_DIR}/qml) |
275 | |
276 | === modified file 'tests/qmluitests/UnityTestCase.qml' |
277 | --- tests/qmluitests/UnityTestCase.qml 2013-03-20 14:43:40 +0000 |
278 | +++ tests/qmluitests/UnityTestCase.qml 2013-03-20 15:46:22 +0000 |
279 | @@ -26,11 +26,12 @@ |
280 | } |
281 | |
282 | // Flickable won't recognise a single mouse move as dragging the flickable. |
283 | - // Use 5 steps because it's what |
284 | + // Use 5 steps because it's what |
285 | // Qt uses in QQuickViewTestUtil::flick |
286 | - function mouseFlick(item, x, y, toX, toY, pressMouse, releaseMouse) { |
287 | - pressMouse = ((pressMouse != null) ? pressMouse : true); // Default to true for pressMouse if not present |
288 | - releaseMouse = ((releaseMouse != null) ? releaseMouse : true); // Default to true for releaseMouse if not present |
289 | + function mouseFlick(item, x, y, toX, toY, pressMouse, releaseMouse, duration) { |
290 | + if (pressMouse === undefined) pressMouse = true; // Default to true for pressMouse if not present |
291 | + if (releaseMouse === undefined) releaseMouse = true; // Default to true for releaseMouse if not present |
292 | + if (duration === undefined) duration = 0; // Default to 0 for duration if not present |
293 | var nIterations = 5 |
294 | var diffX = (toX - x) / nIterations |
295 | var diffY = (toY - y) / nIterations |
296 | @@ -40,6 +41,7 @@ |
297 | } |
298 | for (var i = 0; i < nIterations; ++i) { |
299 | fakeDateTime.currentTimeMs += 10 |
300 | + wait(duration / nIterations) |
301 | if (i === nIterations - 1) { |
302 | // Avoid any rounding errors by making the last move be at precisely |
303 | // the point specified |
304 | |
305 | === added file 'tests/qmluitests/tst_DashBar.qml' |
306 | --- tests/qmluitests/tst_DashBar.qml 1970-01-01 00:00:00 +0000 |
307 | +++ tests/qmluitests/tst_DashBar.qml 2013-03-20 15:46:22 +0000 |
308 | @@ -0,0 +1,157 @@ |
309 | +/* |
310 | + * Copyright 2013 Canonical Ltd. |
311 | + * |
312 | + * This program is free software; you can redistribute it and/or modify |
313 | + * it under the terms of the GNU General Public License as published by |
314 | + * the Free Software Foundation; version 3. |
315 | + * |
316 | + * This program is distributed in the hope that it will be useful, |
317 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
318 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
319 | + * GNU General Public License for more details. |
320 | + * |
321 | + * You should have received a copy of the GNU General Public License |
322 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
323 | + */ |
324 | + |
325 | +import QtQuick 2.0 |
326 | +import QtTest 1.0 |
327 | +import Unity 0.1 |
328 | +import "../../Dash" |
329 | + |
330 | +Item { |
331 | + width: units.gu(40) |
332 | + height: units.gu(71) |
333 | + |
334 | + DashBar { |
335 | + id: dashBar |
336 | + |
337 | + anchors { |
338 | + left: parent.left |
339 | + right: parent.right |
340 | + bottom: parent.bottom |
341 | + } |
342 | + model: Lenses {} |
343 | + } |
344 | + |
345 | + SignalSpy { |
346 | + id: signalSpy |
347 | + signalName: "itemSelected" |
348 | + target: dashBar |
349 | + } |
350 | + |
351 | + UnityTestCase { |
352 | + name: "DashBarTest" |
353 | + when: windowShown |
354 | + |
355 | + property alias model: dashBar.model |
356 | + property alias currentIndex: dashBar.currentIndex |
357 | + |
358 | + readonly property alias rowWidth: dashBar.rowWidth |
359 | + readonly property alias lineHeight: dashBar.lineHeight |
360 | + readonly property alias itemSize: dashBar.itemSize |
361 | + readonly property alias iconSize: dashBar.iconSize |
362 | + readonly property alias initialHeight: dashBar.initialHeight |
363 | + readonly property alias maxHeight: dashBar.maxHeight |
364 | + |
365 | + function checkInitialHeight() { |
366 | + // basically waits for the dashBar to hide... (initial status) |
367 | + tryCompare(dashBar, "height", dashBar.initialHeight) |
368 | + } |
369 | + |
370 | + function test_navigationAndHide() { |
371 | + checkInitialHeight() |
372 | + |
373 | + dashBar.startNavigation() |
374 | + tryCompare(dashBar, "height", dashBar.maxHeight) |
375 | + |
376 | + dashBar.finishNavigation() |
377 | + tryCompare(dashBar, "height", dashBar.initialHeight) |
378 | + } |
379 | + |
380 | + function test_bottomSwipeComplete() { |
381 | + checkInitialHeight() |
382 | + |
383 | + // (item, x, y, button, modifiers, delay) |
384 | + mousePress(parent, |
385 | + parent.width / 2, parent.height, |
386 | + Qt.LeftButton, Qt.NoModifier, 0); |
387 | + // (item, x, y, delay, button) |
388 | + mouseMove(parent, |
389 | + parent.width / 2, parent.height01, |
390 | + 0, Qt.LeftButton); |
391 | + // (item, x, y, button, modifiers, delay) |
392 | + mouseRelease(parent, |
393 | + parent.width / 2, parent.height01, |
394 | + Qt.LeftButton, Qt.NoModifier, 0); |
395 | + tryCompare(dashBar, "height", dashBar.maxHeight) |
396 | + } |
397 | + |
398 | + function test_bottomSwipeBack() { |
399 | + checkInitialHeight() |
400 | + |
401 | + mousePress(parent, |
402 | + parent.width / 2, parent.height, |
403 | + Qt.LeftButton, Qt.NoModifier, 0); |
404 | + mouseMove(parent, |
405 | + parent.width / 2, parent.height - dashBar.maxHeight / 2, |
406 | + 0, Qt.LeftButton); |
407 | + mouseMove(parent, |
408 | + parent.width / 2, parent.height, |
409 | + 0, Qt.LeftButton); |
410 | + mouseRelease(parent, |
411 | + parent.width / 2, parent.height, |
412 | + Qt.LeftButton, Qt.NoModifier, 0); |
413 | + tryCompare(dashBar, "height", dashBar.initialHeight) |
414 | + } |
415 | + |
416 | + function test_bottomSwipeHalfFast() { |
417 | + checkInitialHeight() |
418 | + |
419 | + mouseFlick(parent, |
420 | + parent.width / 2, parent.height, |
421 | + parent.width / 2, parent.height - 5, |
422 | + true, true, 0); |
423 | + tryCompare(dashBar, "height", dashBar.maxHeight) |
424 | + } |
425 | + |
426 | + function test_bottomSwipeHalfSlow() { |
427 | + checkInitialHeight() |
428 | + |
429 | + mouseFlick(parent, |
430 | + parent.width / 2, parent.height, |
431 | + parent.width / 2, parent.height - 5, |
432 | + true, true, 75); |
433 | + tryCompare(dashBar, "height", dashBar.initialHeight) |
434 | + } |
435 | + |
436 | + function test_itemSelected() { |
437 | + checkInitialHeight() |
438 | + signalSpy.clear() |
439 | + |
440 | + dashBar.startNavigation() |
441 | + tryCompare(dashBar, "height", dashBar.maxHeight) |
442 | + |
443 | + var rowStartX = dashBar.width / 2 - rowWidth / 2; |
444 | + for (var i = 0; i < model.rowCount(); i++) { |
445 | + // coordinate x in the middle of item with index 'i' |
446 | + var x = rowStartX + (rowWidth / model.rowCount()) * i + itemSize / 2 |
447 | + if (x > rowWidth) { |
448 | + /* FIXME exit the cycle if we have more lenses than dashBar width. |
449 | + Let's fix and test this behaviour when we'll have more lenses! */ |
450 | + break; |
451 | + } |
452 | + // FIXME workaround for a bug in SignalSpy |
453 | + signalSpy.clear() |
454 | + |
455 | + // (item, x, y, button, modifiers, delay) |
456 | + mouseClick(dashBar, x, dashBar.height / 2, Qt.LeftButton, Qt.NoModifier, 0) |
457 | + compare(signalSpy.count > 0, true, "signal itemSelected not triggered") |
458 | + compare(signalSpy.signalArguments[0][0], i, "signal itemSelected emitted unexpected index"); |
459 | + } |
460 | + |
461 | + dashBar.finishNavigation() |
462 | + } |
463 | + } |
464 | +} |
465 | + |
PASSED: Continuous integration, rev:438 jenkins. qa.ubuntu. com/job/ phablet- unity-ci/ 690/ jenkins. qa.ubuntu. com/job/ phablet- unity-ci/ ./build= panda-pbuilder, distribution= quantal, flavor= armhf/690/ console jenkins. qa.ubuntu. com/job/ phablet- unity-ci/ ./build= pbuilder- master, distribution= quantal, flavor= i386/690/ console
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: jenkins. qa.ubuntu. com/job/ phablet- unity-ci/ 690//rebuild/?
http://