Merge lp:~unity-api-team/ubuntu-system-settings/hotspot into lp:ubuntu-system-settings

Proposed by Antti Kaijanmäki
Status: Merged
Approved by: Iain Lane
Approved revision: 755
Merged at revision: 778
Proposed branch: lp:~unity-api-team/ubuntu-system-settings/hotspot
Merge into: lp:ubuntu-system-settings
Diff against target: 1051 lines (+960/-6)
12 files modified
plugins/cellular/CMakeLists.txt (+18/-6)
plugins/cellular/Hotspot.qml (+76/-0)
plugins/cellular/HotspotSetup.qml (+103/-0)
plugins/cellular/PageComponent.qml (+29/-0)
plugins/cellular/hotspotmanager.cpp (+248/-0)
plugins/cellular/hotspotmanager.h (+53/-0)
plugins/cellular/nm_manager_proxy.h (+207/-0)
plugins/cellular/nm_settings_connection_proxy.h (+74/-0)
plugins/cellular/nm_settings_proxy.h (+84/-0)
plugins/cellular/plugin.cpp (+32/-0)
plugins/cellular/plugin.h (+34/-0)
plugins/cellular/qmldir (+2/-0)
To merge this branch: bzr merge lp:~unity-api-team/ubuntu-system-settings/hotspot
Reviewer Review Type Date Requested Status
Iain Lane Approve
PS Jenkins bot continuous-integration Approve
Antti Kaijanmäki (community) Approve
Review via email: mp+224399@code.launchpad.net

Commit message

Add support for creating a hotspot.

To post a comment you must log in.
Revision history for this message
Antti Kaijanmäki (kaijanmaki) :
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

LGTM.

review: Approve
Revision history for this message
Iain Lane (laney) wrote :

Ta. Mostly good. Some small-ish comments inline.

I didn't test runtime yet, but it looks like you haven't implemented the design <https://wiki.ubuntu.com/Networking#phone-cellular> fully. In particular the labels and dialogs aren't there. Please give this a pass through to implement the design as best you can. I know dialogs are tricky currently so see what you can do there.

review: Needs Fixing
746. By Jussi Pakkanen

Fixed issues raised in review.

Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

> I didn't test runtime yet, but it looks like you haven't implemented the design
> <https://wiki.ubuntu.com/Networking#phone-cellular> fully

We are in the process of discussing the final shape of that with mpt so things may still change. Replies to non-design related issues below.

Revision history for this message
Iain Lane (laney) wrote :

(Don't know how to respond to inline comments; we've been talking about the 'DbusHelper name')

In all other panels we've used qmlRegisterType() (not singleton) and the naming scheme I outlined. I don't know what the wifi panel does (didn't review this one), but doing it like this would be consistent with the rest of u-s-s.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:745
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-api-team/ubuntu-system-settings/hotspot/+merge/224399/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/902/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/1281
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1128
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/94
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/94
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/94/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/94
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/1598
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2180
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2180/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/8933
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/932
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1271
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1271/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/902/rebuild

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

FAILED: Continuous integration, rev:746
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-api-team/ubuntu-system-settings/hotspot/+merge/224399/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/904/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/1310
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1145
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/96
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/96
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/96/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/96
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/1625
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2213
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2213/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/8964
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/946
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1288
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1288/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/904/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

I made it into a singleton as there is only one NM instance ever so it seemed like the natural thing to do.

Revision history for this message
Iain Lane (laney) wrote :

I want you to change that but I won't insist on it. I understand the logic and I think that it's possible to argue for either approach. What tips the balance for me is mainly consistency with the rest of u-s-s.

Please rename "DbusHelper" to something that describes what the module is doing though. The fact that it uses D-Bus in the background is an implementation detail that shouldn't be exposed to users of the API.

(Optional) I think it would be nicer API if the get* and is* methods were instead properties.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:746
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/908/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/1387
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1205
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/100
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/100
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/100/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/100
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/1690
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2334
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2334/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/9077
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/995
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1351
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1351/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/908/rebuild

review: Approve (continuous-integration)
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

> Please rename "DbusHelper" to something that describes what the module is
> doing though. The fact that it uses D-Bus in the background is an
> implementation detail that shouldn't be exposed to users of the API.

Just out of academic curiosity, does this matter that much as it's private API anyway?
All these modules are installed under
/usr/lib/<arch>/ubuntu-system-settings/private/
and are not available to 3rd party applications.

747. By Jussi Pakkanen

DBusHelper is no longer a singleton.

748. By Jussi Pakkanen

Renamed hotspot helper class.

Revision history for this message
Iain Lane (laney) wrote :

On Tue, Jul 01, 2014 at 10:33:04AM -0000, Antti Kaijanmäki wrote:
> > Please rename "DbusHelper" to something that describes what the module is
> > doing though. The fact that it uses D-Bus in the background is an
> > implementation detail that shouldn't be exposed to users of the API.
>
> Just out of academic curiosity, does this matter that much as it's private API anyway?
> All these modules are installed under
> /usr/lib/<arch>/ubuntu-system-settings/private/
> and are not available to 3rd party applications.

We have cases within system-settings itself where API from one panel is
used in another, and the wizard does this too.

--
Iain Lane [ <email address hidden> ]
Debian Developer [ <email address hidden> ]
Ubuntu Developer [ <email address hidden> ]

Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

Made the class a non-singleton and renamed it as requested.

Originally I wanted to have the given methods as properties but decided against it. I don't remember the exact reason, but it made some implementation bits difficult (or at least did at the time).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:748
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/911/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/1394
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1209
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/103
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/103
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/103/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/103
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/1695
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2343
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2343/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/9083
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/998
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1355
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1355/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/911/rebuild

review: Approve (continuous-integration)
Revision history for this message
Iain Lane (laney) wrote :

Thanks. I'm not sure what issues you're referring to but no worries.

Please make sure to get the design updated.

I just ran it. Here's the results of that.

The first time I tried it it didn't appear to work at all. I was able to toggle the hotspot on, but the network wasn't visible. On the console I got 'Failed to start adhoc network: "Device not managed by NetworkManager or unavailable". Turned out that this was because I'd disabled wifi from the indicator previously. After enabling that I was able to see the network in nm-applet, but it is greyed out. On the console at this point I see 'WARNING - Error getting connamd: "Method "Get" with signature "ss" on interface "org.freedesktop.DBus.Properties" doesn't exist' (connamd typo).

Also it was unclear to me why the enable toggle was insensitive until I read the code and saw it was waiting for me to enter a passphrase.

If you want to land this right now with these issues I would be happy to do so if we hide the entry item under "visible: showAllUI" so that it's hidden by default but testers can enable it by launching with USS_SHOW_ALL_UI=1. Otherwise I'll want to see some of these issues fixed, or at least someone else with a device confirming that it works for them.

review: Needs Fixing
749. By Jussi Pakkanen

Hide hotspot settings when wifi is disabled.

750. By Jussi Pakkanen

Add text to specify that WPA password must be 8 characters or more.

Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

The cellular menu now prevents you from going into the hotspot page when wifi is disabled. Instead it displays some text explaining this. Note that this is NOT YET tested on actual hardware. On the desktop it seems to work, so please verify this with proper packages (once they get built) before approving.

I also added an explanatory text on the hotspot dialog that says that the password must be >= 8 characters long.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:750
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/916/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/1454
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1252
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/108
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/108
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/108/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/108
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/1743
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2420
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2420/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/9148
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1032
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1400
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1400/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/916/rebuild

review: Approve (continuous-integration)
Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

There seems to be two issues:

1. you need to unjoin all other networks before creating a hotspot
2. the hotspot network comes up but trying to join it with a laptop fails

I have no idea what is causing #2. NM reports that everything is fine and the hotspot is started. Could this be a NM/driver problem?

Revision history for this message
Iain Lane (laney) wrote :

> There seems to be two issues:
>
> 1. you need to unjoin all other networks before creating a hotspot

Could you do this? Put some text in saying that's what will happen and then disconnect. Will need to restore the state on disabling.

Related question: what happens to the ad-hoc network if you restart the phone?

> 2. the hotspot network comes up but trying to join it with a laptop fails
>
> I have no idea what is causing #2. NM reports that everything is fine and the
> hotspot is started. Could this be a NM/driver problem?

I suggest you ask cyphermox for help here.

Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

I can do #1 but the question is whether we should merge what we have currently and fix this later. This is not a huge amount of work but there has been pressure to get this functionality merged in sooner rather than later. I'll let you make the call on that one.

Interestingly on the desktop creating a hotspot automatically disconnects you from a wifi connection. So maybe the reason #2 is happening is the same as for #1?

Revision history for this message
Iain Lane (laney) wrote :

I'm betting people will try this straight away and then we'll be hit with bug reports.

Do you want to poke at #2 for a bit? It sounds rather showstoppery to me - do you agree?

751. By Jussi Pakkanen

Added margins.

752. By Jussi Pakkanen

Pregenerate a password.

753. By Jussi Pakkanen

Use enabled instead of readonly to work around toolkit issue.

Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

Changed the code to create a random password for user convenience.

Also, when trying to enable hotspot on the device, this gets printed to syslog:

Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.498335] wlan: [1343:E :PE ] limMlmAddBss: 1672: TRYING TO HIDE SSID 0
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.498701] wlan: [1343:E :PE ] mlm_add_sta: 1573: GF: 0, ChnlWidth: 0, MimoPS: 0, lsigTXOP: 0, dsssCCK: 0, SGI20: 0, SGI400
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.513382] wlan: [1343:F :PE ] limProcessIbssMlmAddBssRsp: 2524: could not activate Heartbeat timer
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.513748] VOS ASSERT in logDebug Line 219
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.513931] ------------[ cut here ]------------
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.513962] WARNING: at /build/buildd/linux-mako-3.4.0/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/logApi.c:219 logDebug+0xc0/0xf4()
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.513992] Modules linked in:
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514023] [<c00150d0>] (unwind_backtrace+0x0/0xe8) from [<c08cbf68>] (dump_stack+0x20/0x24)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514053] [<c08cbf68>] (dump_stack+0x20/0x24) from [<c0075628>] (warn_slowpath_common+0x5c/0x74)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514114] [<c0075628>] (warn_slowpath_common+0x5c/0x74) from [<c00756fc>] (warn_slowpath_null+0x2c/0x34)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514145] [<c00756fc>] (warn_slowpath_null+0x2c/0x34) from [<c069aad4>] (logDebug+0xc0/0xf4)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514175] [<c069aad4>] (logDebug+0xc0/0xf4) from [<c05e06cc>] (limLog+0x48/0x50)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514236] [<c05e06cc>] (limLog+0x48/0x50) from [<c05fdce8>] (limProcessMlmAddBssRsp+0x168/0xd40)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514267] [<c05fdce8>] (limProcessMlmAddBssRsp+0x168/0xd40) from [<c05f5010>] (limProcessMessages+0xe74/0x10ac)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514297] [<c05f5010>] (limProcessMessages+0xe74/0x10ac) from [<c05f5560>] (limMessageProcessor+0x274/0x2bc)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514328] [<c05f5560>] (limMessageProcessor+0x274/0x2bc) from [<c05db1a8>] (peProcessMessages+0x54/0x5c)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514358] [<c05db1a8>] (peProcessMessages+0x54/0x5c) from [<c06ba540>] (VosMCThread+0x44c/0x68c)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514419] [<c06ba540>] (VosMCThread+0x44c/0x68c) from [<c0095954>] (kthread+0x9c/0xa8)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514450] [<c0095954>] (kthread+0x9c/0xa8) from [<c000ee74>] (kernel_thread_exit+0x0/0x8)
Jul 3 12:42:18 ubuntu-phablet kernel: [ 6023.514480] ---[ end trace 166bc5cdcf3371f7 ]---
Jul 3 12:42:28 ubuntu-phablet kernel: [ 6033.381839] healthd: battery l=84 v=4182 t=23.2 h=2 st=2 c=-180 chg=u

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:751
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/926/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/1518
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1315
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/118
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/118
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/118/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/118
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/1801
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2498
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2498/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/9238
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1086
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1479
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1479/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/926/rebuild

review: Approve (continuous-integration)
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

N4 seems to have a kernel driver issue. The driver is reporting it supports ad-hoc network mode, but clearly the device fails to create one.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:753
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/928/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/1525
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1323
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/120
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/120
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/120/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/120
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/1807
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2507
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2507/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/9246
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1094
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1487
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1487/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/928/rebuild

review: Approve (continuous-integration)
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :
754. By Jussi Pakkanen

Made layout match design (more).

755. By Jussi Pakkanen

Hide hotspot settings because it does not work on N4.

Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

After some discussions it was decided that we hide the hotspot settings as discussed above so people don't try to use it on devices that have a broken wifi driver (e.g. N4).

The widget layout has also been reworked so it now matches the design spec.

This should now be ready for merging finally.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:754
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/931/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/1573
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1349
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/123
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/123
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/123/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/123
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/1852
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2570
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2570/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/9308
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1116
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1513
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1513/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/931/rebuild

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

PASSED: Continuous integration, rev:755
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/932/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/1592
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1358
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/124
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/124
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/124/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/124
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/1867
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2593
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/2593/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/9329
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1125
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1522
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/1522/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/932/rebuild

review: Approve (continuous-integration)
Revision history for this message
Iain Lane (laney) wrote :

Okay. There's going to be some design work required before this could be enabled for everyone, the ad-hoc bug notwithstanding. But if it's hidden then fine by me.

Cheers.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/cellular/CMakeLists.txt'
2--- plugins/cellular/CMakeLists.txt 2014-06-18 17:37:07 +0000
3+++ plugins/cellular/CMakeLists.txt 2014-07-04 12:59:29 +0000
4@@ -3,14 +3,26 @@
5
6 set(QML_SOURCES
7 ChooseCarrier.qml
8+ Hotspot.qml
9+ HotspotSetup.qml
10 PageComponent.qml
11 )
12
13-# We need a dummy target so the QML files show up in Qt Creator
14-# If this plugin gets some C++ sources, remove this.
15-add_custom_target(cellular-holder
16-COMMAND echo This is just a dummy.
17-SOURCES ${QML_SOURCES})
18-
19+
20+add_library(UbuntuCellularPanel MODULE
21+ plugin.cpp
22+ plugin.h
23+ hotspotmanager.cpp
24+ hotspotmanager.h
25+ nm_manager_proxy.h
26+ nm_settings_proxy.h
27+ nm_settings_connection_proxy.h
28+ ${QML_SOURCES}
29+)
30+qt5_use_modules(UbuntuCellularPanel Qml Quick DBus)
31+
32+set(PLUG_DIR ${PLUGIN_PRIVATE_MODULE_DIR}/Ubuntu/SystemSettings/Cellular)
33+install(TARGETS UbuntuCellularPanel DESTINATION ${PLUG_DIR})
34+install(FILES qmldir DESTINATION ${PLUG_DIR})
35 install(FILES ${QML_SOURCES} DESTINATION ${PLUGIN_QML_DIR}/cellular)
36 install(FILES settings-cellular.svg DESTINATION ${PLUGIN_MANIFEST_DIR}/icons)
37
38=== added file 'plugins/cellular/Hotspot.qml'
39--- plugins/cellular/Hotspot.qml 1970-01-01 00:00:00 +0000
40+++ plugins/cellular/Hotspot.qml 2014-07-04 12:59:29 +0000
41@@ -0,0 +1,76 @@
42+/*
43+ * This file is part of system-settings
44+ *
45+ * Copyright (C) 2014 Canonical Ltd.
46+ *
47+ * This program is free software: you can redistribute it and/or modify it
48+ * under the terms of the GNU General Public License version 3, as published
49+ * by the Free Software Foundation.
50+ *
51+ * This program is distributed in the hope that it will be useful, but
52+ * WITHOUT ANY WARRANTY; without even the implied warranties of
53+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
54+ * PURPOSE. See the GNU General Public License for more details.
55+ *
56+ * You should have received a copy of the GNU General Public License along
57+ * with this program. If not, see <http://www.gnu.org/licenses/>.
58+ */
59+
60+import QtQuick 2.0
61+import SystemSettings 1.0
62+import Ubuntu.Components 0.1
63+import Ubuntu.Components.ListItems 0.1 as ListItem
64+import Ubuntu.SystemSettings.Cellular 1.0
65+
66+ItemPage {
67+
68+ id: hotspot
69+
70+ title: i18n.tr("Wi-Fi hotspot")
71+
72+ HotspotManager {
73+ id: hotspotManager
74+ }
75+
76+ Column {
77+
78+ anchors.fill: parent
79+
80+ ListItem.Standard {
81+ text: i18n.tr("Hotspot")
82+ control: Switch {
83+ id: hotspotSwitch
84+ checked: hotspotManager.isHotspotActive()
85+ onTriggered: {
86+ if(checked) {
87+ hotspotManager.enableHotspot()
88+ } else {
89+ hotspotManager.disableHotspot()
90+ }
91+ }
92+ }
93+ }
94+
95+ Label {
96+ width: parent.width
97+ wrapMode: Text.WordWrap
98+ anchors.leftMargin: units.gu(2)
99+ anchors.rightMargin: units.gu(2)
100+ text : hotspotSwitch.enabled ?
101+ i18n.tr("When hotspot is on, other devices can user your cellular data connection over Wi-Fi. Normal data charges apply.")
102+ : i18n.tr("Other devices can user your cellular data connection over the Wi-Fi network. Normal data charges apply.")
103+ }
104+
105+ Button {
106+ text: i18n.tr("Set up hotspot")
107+ anchors.left: parent.left
108+ anchors.right: parent.right
109+ anchors.leftMargin: units.gu(2)
110+ anchors.rightMargin: units.gu(2)
111+ onClicked: {
112+ pageStack.push(Qt.resolvedUrl("HotspotSetup.qml"), {hotspotManager: hotspotManager})
113+ }
114+ }
115+
116+ }
117+}
118
119=== added file 'plugins/cellular/HotspotSetup.qml'
120--- plugins/cellular/HotspotSetup.qml 1970-01-01 00:00:00 +0000
121+++ plugins/cellular/HotspotSetup.qml 2014-07-04 12:59:29 +0000
122@@ -0,0 +1,103 @@
123+/*
124+ * This file is part of system-settings
125+ *
126+ * Copyright (C) 2014 Canonical Ltd.
127+ *
128+ * This program is free software: you can redistribute it and/or modify it
129+ * under the terms of the GNU General Public License version 3, as published
130+ * by the Free Software Foundation.
131+ *
132+ * This program is distributed in the hope that it will be useful, but
133+ * WITHOUT ANY WARRANTY; without even the implied warranties of
134+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
135+ * PURPOSE. See the GNU General Public License for more details.
136+ *
137+ * You should have received a copy of the GNU General Public License along
138+ * with this program. If not, see <http://www.gnu.org/licenses/>.
139+ */
140+
141+import QtQuick 2.0
142+import QtQuick.Layouts 1.1
143+import SystemSettings 1.0
144+import Ubuntu.Components 0.1
145+import Ubuntu.Components.ListItems 0.1 as ListItem
146+import Ubuntu.SystemSettings.Cellular 1.0
147+
148+ItemPage {
149+
150+ id: hotspotSetup
151+ title: i18n.tr("Change hotspot setup")
152+
153+ property var hotspotManager: null
154+
155+
156+ Column {
157+
158+ anchors.fill: parent
159+
160+ ListItem.Standard {
161+ id: ssidLabel
162+ text: i18n.tr("Hotspot name")
163+ }
164+
165+ TextField {
166+ id: ssidField
167+ text: hotspotManager.getHotspotName()
168+ anchors.left: parent.left
169+ anchors.right: parent.right
170+ anchors.leftMargin: units.gu(2)
171+ anchors.rightMargin: units.gu(2)
172+ }
173+
174+ ListItem.Standard {
175+ id: passwordLabel
176+ text: i18n.tr("Key (must be 8 characters or longer)")
177+ }
178+
179+ TextField {
180+ id: passwordField
181+ text: hotspotManager.getHotspotPassword()
182+ echoMode: passwordVisibleSwitch.checked ? TextInput.Normal : TextInput.Password
183+ anchors.left: parent.left
184+ anchors.right: parent.right
185+ anchors.leftMargin: units.gu(2)
186+ anchors.rightMargin: units.gu(2)
187+ }
188+
189+ ListItem.Standard {
190+ text: i18n.tr("Show key")
191+ id: passwordVisible
192+ control: Switch {
193+ id: passwordVisibleSwitch
194+ }
195+ }
196+
197+ RowLayout {
198+ anchors {
199+ left: parent.left
200+ right: parent.right
201+ margins: units.gu(2)
202+ }
203+
204+ Button {
205+ id: cancelButton
206+ Layout.fillWidth: true
207+ text: i18n.tr("Cancel")
208+ onClicked: {
209+ pageStack.pop()
210+ }
211+ }
212+
213+ Button {
214+ id: connectButton
215+ Layout.fillWidth: true
216+ text: i18n.tr("Change")
217+ enabled: ssidField.text != "" && passwordField.length >= 8
218+ onClicked: {
219+ hotspotManager.setupHotspot(ssidField.text, passwordField.text)
220+ pageStack.pop()
221+ }
222+ }
223+ }
224+ }
225+}
226
227=== modified file 'plugins/cellular/PageComponent.qml'
228--- plugins/cellular/PageComponent.qml 2014-06-18 17:37:07 +0000
229+++ plugins/cellular/PageComponent.qml 2014-07-04 12:59:29 +0000
230@@ -23,11 +23,25 @@
231 import Ubuntu.Components 0.1
232 import Ubuntu.Components.ListItems 0.1 as ListItem
233 import Ubuntu.SystemSettings.Phone 1.0
234+import QMenuModel 0.1
235
236 ItemPage {
237 title: i18n.tr("Cellular")
238 objectName: "cellularPage"
239
240+ QDBusActionGroup {
241+ id: actionGroup
242+ busType: 1
243+ busName: "com.canonical.indicator.network"
244+ objectPath: "/com/canonical/indicator/network"
245+
246+ property variant actionObject: action("wifi.enable")
247+
248+ Component.onCompleted: {
249+ start()
250+ }
251+ }
252+
253 NetworkRegistration {
254 id: netReg
255 onModeChanged: {
256@@ -107,6 +121,21 @@
257 }
258 }
259
260+ ListItem.SingleValue {
261+ text : i18n.tr("Hotspot disabled because Wi-Fi is off.")
262+ visible: showAllUI && !hotspotItem.visible
263+ }
264+
265+ ListItem.SingleValue {
266+ id: hotspotItem
267+ text: i18n.tr("Wi-Fi hotspot")
268+ progression: true
269+ onClicked: {
270+ pageStack.push(Qt.resolvedUrl("Hotspot.qml"))
271+ }
272+ visible: showAllUI && (actionGroup.actionObject.valid ? actionGroup.actionObject.state : false)
273+ }
274+
275 ListItem.Standard {
276 text: i18n.tr("Data usage statistics")
277 progression: true
278
279=== added file 'plugins/cellular/hotspotmanager.cpp'
280--- plugins/cellular/hotspotmanager.cpp 1970-01-01 00:00:00 +0000
281+++ plugins/cellular/hotspotmanager.cpp 2014-07-04 12:59:29 +0000
282@@ -0,0 +1,248 @@
283+/*
284+ * Copyright (C) 2014 Canonical, Ltd.
285+ *
286+ * Authors:
287+ * Jussi Pakkanen <jussi.pakkanen@canonical.com>
288+ *
289+ * This program is free software: you can redistribute it and/or modify it
290+ * under the terms of the GNU General Public License version 3, as published
291+ * by the Free Software Foundation.
292+ *
293+ * This library is distributed in the hope that it will be useful, but WITHOUT
294+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
295+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
296+ * details.
297+ *
298+ * You should have received a copy of the GNU General Public License
299+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
300+ */
301+
302+#include "nm_manager_proxy.h"
303+#include "nm_settings_proxy.h"
304+#include "nm_settings_connection_proxy.h"
305+#include "hotspotmanager.h"
306+#include <QStringList>
307+#include <QDBusReply>
308+#include <QtDebug>
309+#include <QDBusInterface>
310+#include <QDBusMetaType>
311+
312+typedef QMap<QString, QVariantMap> nmConnectionArg;
313+Q_DECLARE_METATYPE(nmConnectionArg)
314+
315+namespace {
316+
317+const QString nm_service("org.freedesktop.NetworkManager");
318+const QString nm_settings_object("/org/freedesktop/NetworkManager/Settings");
319+const QString nm_settings_interface("org.freedesktop.NetworkManager.Settings");
320+const QString nm_connection_interface("org.freedesktop.NetworkManager.Settings.Connection");
321+const QString nm_dbus_path("/org/freedesktop/NetworkManager");
322+const QString nm_device_interface("org.freedesktop.NetworkManager.Device");
323+
324+#define NM_METHOD_NAME "AddAndActivateConnection"
325+
326+void startAdhoc(const QByteArray &ssid, const QString &password, const QDBusObjectPath &devicePath) {
327+ nmConnectionArg connection;
328+
329+ QDBusObjectPath specific("/");
330+
331+ QVariantMap wireless;
332+ wireless[QStringLiteral("security")] = QVariant(QStringLiteral("802-11-wireless-security"));
333+ wireless[QStringLiteral("ssid")] = QVariant(ssid);
334+ wireless[QStringLiteral("mode")] = QVariant(QStringLiteral("adhoc"));
335+ connection["802-11-wireless"] = wireless;
336+
337+ QVariantMap connsettings;
338+ connsettings[QStringLiteral("autoconnect")] = QVariant(false);
339+ connsettings[QStringLiteral("uuid")] = QVariant(QStringLiteral("aab22b5d-7342-48dc-8920-1b7da31d6829"));
340+ connsettings[QStringLiteral("type")] = QVariant(QStringLiteral("802-11-wireless"));
341+ connection["connection"] = connsettings;
342+
343+ QVariantMap ipv4;
344+ ipv4[QStringLiteral("addressess")] = QVariant(QStringList());
345+ ipv4[QStringLiteral("dns")] = QVariant(QStringList());
346+ ipv4[QStringLiteral("method")] = QVariant(QStringLiteral("shared"));
347+ ipv4[QStringLiteral("routes")] = QVariant(QStringList());
348+ connection["ipv4"] = ipv4;
349+
350+ QVariantMap security;
351+ security[QStringLiteral("proto")] = QVariant(QStringList{"rsn"});
352+ security[QStringLiteral("pairwise")] = QVariant(QStringList{"ccmp"});
353+ security[QStringLiteral("group")] = QVariant(QStringList{"ccmp"});
354+ security[QStringLiteral("key-mgmt")] = QVariant(QStringLiteral("wpa-psk"));
355+ security[QStringLiteral("psk")] = QVariant(password);
356+ connection["802-11-wireless-security"] = security;
357+
358+ OrgFreedesktopNetworkManagerInterface mgr(nm_service,
359+ nm_dbus_path,
360+ QDBusConnection::systemBus());
361+ auto reply = mgr.AddAndActivateConnection(connection, devicePath, specific);
362+ reply.waitForFinished();
363+ if(!reply.isValid()) {
364+ qWarning() << "Failed to start adhoc network: " << reply.error().message() << "\n";
365+ }
366+}
367+
368+bool detectAdhoc(QString &dbusPath, QByteArray &ssid, QString &password, bool &isActive) {
369+ static const QString activeIface("org.freedesktop.NetworkManager.Connection.Active");
370+ static const QString connProp("Connection");
371+ OrgFreedesktopNetworkManagerInterface mgr(nm_service,
372+ nm_dbus_path,
373+ QDBusConnection::systemBus());
374+ auto activeConnections = mgr.activeConnections();
375+ OrgFreedesktopNetworkManagerSettingsInterface settings(nm_service, nm_settings_object,
376+ QDBusConnection::systemBus());
377+ QSet<QDBusObjectPath> actives;
378+ auto r = settings.ListConnections();
379+ r.waitForFinished();
380+ for(const auto &conn : activeConnections) {
381+ QDBusInterface iface(nm_service, conn.path(), "org.freedesktop.DBus.Properties",
382+ QDBusConnection::systemBus());
383+ QDBusReply<QVariant> conname = iface.call("Get", activeIface, connProp);
384+ if(!conname.isValid()) {
385+ qWarning() << "Error getting connamd: " << conname.error().message() << "\n";
386+ continue;
387+ }
388+ QDBusObjectPath mainConnection = qvariant_cast<QDBusObjectPath>(conname.value());
389+ actives.insert(mainConnection);
390+ }
391+ const char wifiKey[] = "802-11-wireless";
392+ for(const auto &i : r.value()) {
393+ OrgFreedesktopNetworkManagerSettingsConnectionInterface conn(nm_service,
394+ i.path(),
395+ QDBusConnection::systemBus());
396+ auto reply = conn.GetSettings();
397+ reply.waitForFinished();
398+ auto s = reply.value();
399+ if(s.find(wifiKey) != s.end()) {
400+ auto wsetup = s[wifiKey];
401+ if(wsetup["mode"] == "adhoc") {
402+ dbusPath = i.path();
403+ ssid = wsetup["ssid"].toByteArray();
404+ auto pwdReply = conn.GetSecrets("802-11-wireless-security");
405+ pwdReply.waitForFinished();
406+ password = pwdReply.value()["802-11-wireless-security"]["psk"].toString();
407+ isActive = false;
408+ for(const auto &ac : actives) {
409+ if(i == ac) {
410+ isActive = true;
411+ break;
412+ }
413+ }
414+ return true;
415+ }
416+ }
417+ }
418+ return false;
419+}
420+
421+QDBusObjectPath detectWirelessDevice() {
422+ OrgFreedesktopNetworkManagerInterface mgr(nm_service,
423+ nm_dbus_path,
424+ QDBusConnection::systemBus());
425+ auto devices = mgr.GetDevices();
426+ devices.waitForFinished();
427+ for(const auto &dpath : devices.value()) {
428+ QDBusInterface iface(nm_service, dpath.path(), "org.freedesktop.DBus.Properties",
429+ QDBusConnection::systemBus());
430+ QDBusReply<QVariant> typeReply = iface.call("Get", "org.freedesktop.NetworkManager.Device", "DeviceType");
431+ auto typeInt = qvariant_cast<int>(typeReply.value());
432+ if(typeInt == 2) {
433+ return dpath; // Assumptions are that there is only one wifi device and it is not hotpluggable.
434+ }
435+ }
436+ qWarning() << "Wireless device not found, hotspot functionality is inoperative.\n";
437+ return QDBusObjectPath();
438+}
439+
440+std::string generate_password() {
441+ static const std::string items("abcdefghijklmnopqrstuvwxyz01234567890");
442+ const int passwordLength = 8;
443+ std::string result;
444+ for(int i=0; i<passwordLength; i++) {
445+ result.push_back(items[std::rand() % items.length()]);
446+ }
447+ return result;
448+}
449+
450+}
451+
452+HotspotManager::HotspotManager(QObject *parent) : QObject(parent),
453+ m_devicePath(detectWirelessDevice()) {
454+ static bool isRegistered = false;
455+ if(!isRegistered) {
456+ qDBusRegisterMetaType<nmConnectionArg>();
457+ isRegistered = true;
458+ }
459+ if(!detectAdhoc(m_settingsPath, m_ssid, m_password, m_isActive)) {
460+ m_settingsPath = "";
461+ m_ssid = "Ubuntu hotspot";
462+ m_password = generate_password().c_str();
463+ m_isActive = false;
464+ }
465+}
466+
467+QByteArray HotspotManager::getHotspotName() {
468+ return m_ssid;
469+}
470+
471+QString HotspotManager::getHotspotPassword() {
472+ return m_password;
473+}
474+
475+void HotspotManager::setupHotspot(QByteArray ssid_, QString password_) {
476+ m_ssid = ssid_;
477+ m_password = password_;
478+}
479+
480+void HotspotManager::enableHotspot() {
481+ if(!m_settingsPath.isEmpty()) {
482+ // Prints a warning message if the connection has disappeared already.
483+ destroyHotspot();
484+ // NM returns from the dbus call immediately but only destroys the
485+ // connection some time later. There is no callback for when this happens.
486+ // So this is the best we can do with reasonable effort.
487+ QThread::sleep(1);
488+ }
489+ startAdhoc(m_ssid, m_password, m_devicePath);
490+ detectAdhoc(m_settingsPath, m_ssid, m_password, m_isActive);
491+}
492+
493+bool HotspotManager::isHotspotActive() {
494+ return m_isActive;
495+}
496+
497+void HotspotManager::disableHotspot() {
498+ static const QString activeIface("org.freedesktop.NetworkManager.Connection.Active");
499+ static const QString connProp("Connection");
500+ OrgFreedesktopNetworkManagerInterface mgr(nm_service,
501+ nm_dbus_path,
502+ QDBusConnection::systemBus());
503+ auto activeConnections = mgr.activeConnections();
504+ for(const auto &aConn : activeConnections) {
505+ QDBusInterface iface(nm_service, aConn.path(), "org.freedesktop.DBus.Properties",
506+ QDBusConnection::systemBus());
507+ QDBusReply<QVariant> conname = iface.call("Get", activeIface, connProp);
508+ QDBusObjectPath backingConnection = qvariant_cast<QDBusObjectPath>(conname.value());
509+ if(backingConnection.path() == m_settingsPath) {
510+ mgr.DeactivateConnection(aConn);
511+ return;
512+ }
513+ }
514+ qWarning() << "Could not find a hotspot setup to disable.\n";
515+}
516+
517+void HotspotManager::destroyHotspot() {
518+ if(m_settingsPath.isEmpty()) {
519+ qWarning() << "Tried to destroy nonexisting hotspot.\n";
520+ return;
521+ }
522+ QDBusInterface control(nm_service, m_settingsPath, nm_connection_interface,
523+ QDBusConnection::systemBus());
524+ QDBusReply<void> reply = control.call("Delete");
525+ if(!reply.isValid()) {
526+ qWarning() << "Could not disconnect adhoc network: " << reply.error().message() << "\n";
527+ } else {
528+ m_isActive = false;
529+ }
530+}
531
532=== added file 'plugins/cellular/hotspotmanager.h'
533--- plugins/cellular/hotspotmanager.h 1970-01-01 00:00:00 +0000
534+++ plugins/cellular/hotspotmanager.h 2014-07-04 12:59:29 +0000
535@@ -0,0 +1,53 @@
536+/*
537+ * Copyright (C) 2014 Canonical, Ltd.
538+ *
539+ * Authors:
540+ * Jussi Pakkanen <jussi.pakkanen@canonical.com>
541+ *
542+ * This program is free software: you can redistribute it and/or modify it
543+ * under the terms of the GNU General Public License version 3, as published
544+ * by the Free Software Foundation.
545+ *
546+ * This library is distributed in the hope that it will be useful, but WITHOUT
547+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
548+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
549+ * details.
550+ *
551+ * You should have received a copy of the GNU General Public License
552+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
553+ */
554+
555+#ifndef CELLULAR_DBUS_HELPER
556+#define CELLULAR_DBUS_HELPER
557+
558+#include <QObject>
559+#include <QDBusObjectPath>
560+/**
561+ * For exposing dbus data to Qml.
562+ */
563+
564+class HotspotManager : public QObject {
565+ Q_OBJECT
566+
567+public:
568+ HotspotManager(QObject *parent = nullptr);
569+ ~HotspotManager() {};
570+
571+ Q_INVOKABLE QByteArray getHotspotName();
572+ Q_INVOKABLE QString getHotspotPassword();
573+ Q_INVOKABLE void setupHotspot(QByteArray ssid, QString password);
574+ Q_INVOKABLE bool isHotspotActive();
575+ Q_INVOKABLE void enableHotspot();
576+ Q_INVOKABLE void disableHotspot();
577+ void destroyHotspot();
578+
579+private:
580+ QByteArray m_ssid;
581+ QString m_password;
582+ QString m_settingsPath;
583+ QDBusObjectPath m_devicePath;
584+ bool m_isActive;
585+};
586+
587+
588+#endif
589
590=== added file 'plugins/cellular/nm_manager_proxy.h'
591--- plugins/cellular/nm_manager_proxy.h 1970-01-01 00:00:00 +0000
592+++ plugins/cellular/nm_manager_proxy.h 2014-07-04 12:59:29 +0000
593@@ -0,0 +1,207 @@
594+/*
595+ * This file was generated by qdbusxml2cpp version 0.8
596+ * Command line was: qdbusxml2cpp -N -p nm_manager_proxy.h -v nm-manager-introspection.xml
597+ *
598+ * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
599+ *
600+ * This is an auto-generated file.
601+ * Do not edit! All changes made to it will be lost.
602+ */
603+
604+#ifndef NM_MANAGER_PROXY_H_1403027877
605+#define NM_MANAGER_PROXY_H_1403027877
606+
607+#include <QtCore/QObject>
608+#include <QtCore/QByteArray>
609+#include <QtCore/QList>
610+#include <QtCore/QMap>
611+#include <QtCore/QString>
612+#include <QtCore/QStringList>
613+#include <QtCore/QVariant>
614+#include <QtDBus/QtDBus>
615+
616+/*
617+ * Proxy class for interface org.freedesktop.NetworkManager
618+ */
619+class OrgFreedesktopNetworkManagerInterface: public QDBusAbstractInterface
620+{
621+ Q_OBJECT
622+public:
623+ static inline const char *staticInterfaceName()
624+ { return "org.freedesktop.NetworkManager"; }
625+
626+public:
627+ OrgFreedesktopNetworkManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0)
628+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
629+ {}
630+
631+ ~OrgFreedesktopNetworkManagerInterface()
632+ {}
633+
634+ Q_PROPERTY(QDBusObjectPath ActivatingConnection READ activatingConnection)
635+ inline QDBusObjectPath activatingConnection() const
636+ { return qvariant_cast< QDBusObjectPath >(property("ActivatingConnection")); }
637+
638+ Q_PROPERTY(QList<QDBusObjectPath> ActiveConnections READ activeConnections)
639+ inline QList<QDBusObjectPath> activeConnections() const
640+ { return qvariant_cast< QList<QDBusObjectPath> >(property("ActiveConnections")); }
641+
642+ Q_PROPERTY(uint Connectivity READ connectivity)
643+ inline uint connectivity() const
644+ { return qvariant_cast< uint >(property("Connectivity")); }
645+
646+ Q_PROPERTY(bool NetworkingEnabled READ networkingEnabled)
647+ inline bool networkingEnabled() const
648+ { return qvariant_cast< bool >(property("NetworkingEnabled")); }
649+
650+ Q_PROPERTY(QDBusObjectPath PrimaryConnection READ primaryConnection)
651+ inline QDBusObjectPath primaryConnection() const
652+ { return qvariant_cast< QDBusObjectPath >(property("PrimaryConnection")); }
653+
654+ Q_PROPERTY(uint State READ state)
655+ inline uint state() const
656+ { return qvariant_cast< uint >(property("State")); }
657+
658+ Q_PROPERTY(QString Version READ version)
659+ inline QString version() const
660+ { return qvariant_cast< QString >(property("Version")); }
661+
662+ Q_PROPERTY(bool WimaxEnabled READ wimaxEnabled WRITE setWimaxEnabled)
663+ inline bool wimaxEnabled() const
664+ { return qvariant_cast< bool >(property("WimaxEnabled")); }
665+ inline void setWimaxEnabled(bool value)
666+ { setProperty("WimaxEnabled", QVariant::fromValue(value)); }
667+
668+ Q_PROPERTY(bool WimaxHardwareEnabled READ wimaxHardwareEnabled)
669+ inline bool wimaxHardwareEnabled() const
670+ { return qvariant_cast< bool >(property("WimaxHardwareEnabled")); }
671+
672+ Q_PROPERTY(bool WirelessEnabled READ wirelessEnabled WRITE setWirelessEnabled)
673+ inline bool wirelessEnabled() const
674+ { return qvariant_cast< bool >(property("WirelessEnabled")); }
675+ inline void setWirelessEnabled(bool value)
676+ { setProperty("WirelessEnabled", QVariant::fromValue(value)); }
677+
678+ Q_PROPERTY(bool WirelessHardwareEnabled READ wirelessHardwareEnabled)
679+ inline bool wirelessHardwareEnabled() const
680+ { return qvariant_cast< bool >(property("WirelessHardwareEnabled")); }
681+
682+ Q_PROPERTY(bool WwanEnabled READ wwanEnabled WRITE setWwanEnabled)
683+ inline bool wwanEnabled() const
684+ { return qvariant_cast< bool >(property("WwanEnabled")); }
685+ inline void setWwanEnabled(bool value)
686+ { setProperty("WwanEnabled", QVariant::fromValue(value)); }
687+
688+ Q_PROPERTY(bool WwanHardwareEnabled READ wwanHardwareEnabled)
689+ inline bool wwanHardwareEnabled() const
690+ { return qvariant_cast< bool >(property("WwanHardwareEnabled")); }
691+
692+public Q_SLOTS: // METHODS
693+ inline QDBusPendingReply<QDBusObjectPath> ActivateConnection(const QDBusObjectPath &connection, const QDBusObjectPath &device, const QDBusObjectPath &specific_object)
694+ {
695+ QList<QVariant> argumentList;
696+ argumentList << QVariant::fromValue(connection) << QVariant::fromValue(device) << QVariant::fromValue(specific_object);
697+ return asyncCallWithArgumentList(QLatin1String("ActivateConnection"), argumentList);
698+ }
699+
700+ inline QDBusPendingReply<QDBusObjectPath, QDBusObjectPath> AddAndActivateConnection(const QMap<QString, QVariantMap> &connection, const QDBusObjectPath &device, const QDBusObjectPath &specific_object)
701+ {
702+ QList<QVariant> argumentList;
703+ argumentList << QVariant::fromValue(connection) << QVariant::fromValue(device) << QVariant::fromValue(specific_object);
704+ return asyncCallWithArgumentList(QLatin1String("AddAndActivateConnection"), argumentList);
705+ }
706+ inline QDBusReply<QDBusObjectPath> AddAndActivateConnection(const QMap<QString, QVariantMap> &connection, const QDBusObjectPath &device, const QDBusObjectPath &specific_object, QDBusObjectPath &active_connection)
707+ {
708+ QList<QVariant> argumentList;
709+ argumentList << QVariant::fromValue(connection) << QVariant::fromValue(device) << QVariant::fromValue(specific_object);
710+ QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("AddAndActivateConnection"), argumentList);
711+ if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) {
712+ active_connection = qdbus_cast<QDBusObjectPath>(reply.arguments().at(1));
713+ }
714+ return reply;
715+ }
716+
717+ inline QDBusPendingReply<uint> CheckConnectivity()
718+ {
719+ QList<QVariant> argumentList;
720+ return asyncCallWithArgumentList(QLatin1String("CheckConnectivity"), argumentList);
721+ }
722+
723+ inline QDBusPendingReply<> DeactivateConnection(const QDBusObjectPath &active_connection)
724+ {
725+ QList<QVariant> argumentList;
726+ argumentList << QVariant::fromValue(active_connection);
727+ return asyncCallWithArgumentList(QLatin1String("DeactivateConnection"), argumentList);
728+ }
729+
730+ inline QDBusPendingReply<> Enable(bool enable)
731+ {
732+ QList<QVariant> argumentList;
733+ argumentList << QVariant::fromValue(enable);
734+ return asyncCallWithArgumentList(QLatin1String("Enable"), argumentList);
735+ }
736+
737+ inline QDBusPendingReply<QDBusObjectPath> GetDeviceByIpIface(const QString &iface)
738+ {
739+ QList<QVariant> argumentList;
740+ argumentList << QVariant::fromValue(iface);
741+ return asyncCallWithArgumentList(QLatin1String("GetDeviceByIpIface"), argumentList);
742+ }
743+
744+ inline QDBusPendingReply<QList<QDBusObjectPath> > GetDevices()
745+ {
746+ QList<QVariant> argumentList;
747+ return asyncCallWithArgumentList(QLatin1String("GetDevices"), argumentList);
748+ }
749+
750+ inline QDBusPendingReply<QString, QString> GetLogging()
751+ {
752+ QList<QVariant> argumentList;
753+ return asyncCallWithArgumentList(QLatin1String("GetLogging"), argumentList);
754+ }
755+ inline QDBusReply<QString> GetLogging(QString &domains)
756+ {
757+ QList<QVariant> argumentList;
758+ QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("GetLogging"), argumentList);
759+ if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) {
760+ domains = qdbus_cast<QString>(reply.arguments().at(1));
761+ }
762+ return reply;
763+ }
764+
765+ inline QDBusPendingReply<QMap<QString, QString> > GetPermissions()
766+ {
767+ QList<QVariant> argumentList;
768+ return asyncCallWithArgumentList(QLatin1String("GetPermissions"), argumentList);
769+ }
770+
771+ inline QDBusPendingReply<> SetLogging(const QString &level, const QString &domains)
772+ {
773+ QList<QVariant> argumentList;
774+ argumentList << QVariant::fromValue(level) << QVariant::fromValue(domains);
775+ return asyncCallWithArgumentList(QLatin1String("SetLogging"), argumentList);
776+ }
777+
778+ inline QDBusPendingReply<> Sleep(bool sleep)
779+ {
780+ QList<QVariant> argumentList;
781+ argumentList << QVariant::fromValue(sleep);
782+ return asyncCallWithArgumentList(QLatin1String("Sleep"), argumentList);
783+ }
784+
785+ inline QDBusPendingReply<uint> state()
786+ {
787+ QList<QVariant> argumentList;
788+ return asyncCallWithArgumentList(QLatin1String("state"), argumentList);
789+ }
790+
791+Q_SIGNALS: // SIGNALS
792+ void CheckPermissions();
793+ void DeviceAdded(const QDBusObjectPath &in0);
794+ void DeviceRemoved(const QDBusObjectPath &in0);
795+ void PropertiesChanged(const QVariantMap &in0);
796+ void StateChanged(uint in0);
797+};
798+
799+#endif
800+
801
802=== added file 'plugins/cellular/nm_settings_connection_proxy.h'
803--- plugins/cellular/nm_settings_connection_proxy.h 1970-01-01 00:00:00 +0000
804+++ plugins/cellular/nm_settings_connection_proxy.h 2014-07-04 12:59:29 +0000
805@@ -0,0 +1,74 @@
806+/*
807+ * This file was generated by qdbusxml2cpp version 0.8
808+ * Command line was: qdbusxml2cpp -N -p nm_settings_connection_proxy.h -v nm-settings-connection-introspection.xml
809+ *
810+ * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
811+ *
812+ * This is an auto-generated file.
813+ * Do not edit! All changes made to it will be lost.
814+ */
815+
816+#ifndef NM_SETTINGS_CONNECTION_PROXY_H_1402664031
817+#define NM_SETTINGS_CONNECTION_PROXY_H_1402664031
818+
819+#include <QtCore/QObject>
820+#include <QtCore/QByteArray>
821+#include <QtCore/QList>
822+#include <QtCore/QMap>
823+#include <QtCore/QString>
824+#include <QtCore/QStringList>
825+#include <QtCore/QVariant>
826+#include <QtDBus/QtDBus>
827+
828+/*
829+ * Proxy class for interface org.freedesktop.NetworkManager.Settings.Connection
830+ */
831+class OrgFreedesktopNetworkManagerSettingsConnectionInterface: public QDBusAbstractInterface
832+{
833+ Q_OBJECT
834+public:
835+ static inline const char *staticInterfaceName()
836+ { return "org.freedesktop.NetworkManager.Settings.Connection"; }
837+
838+public:
839+ OrgFreedesktopNetworkManagerSettingsConnectionInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0)
840+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
841+ {}
842+
843+
844+ ~OrgFreedesktopNetworkManagerSettingsConnectionInterface()
845+ {}
846+
847+public Q_SLOTS: // METHODS
848+ inline QDBusPendingReply<> Delete()
849+ {
850+ QList<QVariant> argumentList;
851+ return asyncCallWithArgumentList(QLatin1String("Delete"), argumentList);
852+ }
853+
854+ inline QDBusPendingReply<QMap<QString, QVariantMap> > GetSecrets(const QString &setting_name)
855+ {
856+ QList<QVariant> argumentList;
857+ argumentList << QVariant::fromValue(setting_name);
858+ return asyncCallWithArgumentList(QLatin1String("GetSecrets"), argumentList);
859+ }
860+
861+ inline QDBusPendingReply<QMap<QString, QVariantMap> > GetSettings()
862+ {
863+ QList<QVariant> argumentList;
864+ return asyncCallWithArgumentList(QLatin1String("GetSettings"), argumentList);
865+ }
866+
867+ inline QDBusPendingReply<> Update(const QMap<QString, QVariantMap> &properties)
868+ {
869+ QList<QVariant> argumentList;
870+ argumentList << QVariant::fromValue(properties);
871+ return asyncCallWithArgumentList(QLatin1String("Update"), argumentList);
872+ }
873+
874+Q_SIGNALS: // SIGNALS
875+ void Removed();
876+ void Updated();
877+};
878+
879+#endif
880
881=== added file 'plugins/cellular/nm_settings_proxy.h'
882--- plugins/cellular/nm_settings_proxy.h 1970-01-01 00:00:00 +0000
883+++ plugins/cellular/nm_settings_proxy.h 2014-07-04 12:59:29 +0000
884@@ -0,0 +1,84 @@
885+/*
886+ * This file was generated by qdbusxml2cpp version 0.8
887+ * Command line was: qdbusxml2cpp -N -p nm_settings_proxy.h -v nm-settings-introspection.xml
888+ *
889+ * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
890+ *
891+ * This is an auto-generated file.
892+ * Do not edit! All changes made to it will be lost.
893+ */
894+
895+#ifndef NM_SETTINGS_PROXY_H_1402663916
896+#define NM_SETTINGS_PROXY_H_1402663916
897+
898+#include <QtCore/QObject>
899+#include <QtCore/QByteArray>
900+#include <QtCore/QList>
901+#include <QtCore/QMap>
902+#include <QtCore/QString>
903+#include <QtCore/QStringList>
904+#include <QtCore/QVariant>
905+#include <QtDBus/QtDBus>
906+
907+/*
908+ * Proxy class for interface org.freedesktop.NetworkManager.Settings
909+ */
910+class OrgFreedesktopNetworkManagerSettingsInterface: public QDBusAbstractInterface
911+{
912+ Q_OBJECT
913+public:
914+ static inline const char *staticInterfaceName()
915+ { return "org.freedesktop.NetworkManager.Settings"; }
916+
917+public:
918+ OrgFreedesktopNetworkManagerSettingsInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0)
919+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
920+ {}
921+
922+ ~OrgFreedesktopNetworkManagerSettingsInterface()
923+ {}
924+
925+ Q_PROPERTY(bool CanModify READ canModify)
926+ inline bool canModify() const
927+ { return qvariant_cast< bool >(property("CanModify")); }
928+
929+ Q_PROPERTY(QString Hostname READ hostname)
930+ inline QString hostname() const
931+ { return qvariant_cast< QString >(property("Hostname")); }
932+
933+public Q_SLOTS: // METHODS
934+ inline QDBusPendingReply<QDBusObjectPath> AddConnection(const QMap<QString, QVariantMap> &connection)
935+ {
936+ QList<QVariant> argumentList;
937+ argumentList << QVariant::fromValue(connection);
938+ return asyncCallWithArgumentList(QLatin1String("AddConnection"), argumentList);
939+ }
940+
941+ inline QDBusPendingReply<QDBusObjectPath> GetConnectionByUuid(const QString &uuid)
942+ {
943+ QList<QVariant> argumentList;
944+ argumentList << QVariant::fromValue(uuid);
945+ return asyncCallWithArgumentList(QLatin1String("GetConnectionByUuid"), argumentList);
946+ }
947+
948+ inline QDBusPendingReply<QList<QDBusObjectPath> > ListConnections()
949+ {
950+ QList<QVariant> argumentList;
951+ return asyncCallWithArgumentList(QLatin1String("ListConnections"), argumentList);
952+ }
953+
954+ inline QDBusPendingReply<> SaveHostname(const QString &hostname)
955+ {
956+ QList<QVariant> argumentList;
957+ argumentList << QVariant::fromValue(hostname);
958+ return asyncCallWithArgumentList(QLatin1String("SaveHostname"), argumentList);
959+ }
960+
961+Q_SIGNALS: // SIGNALS
962+ void NewConnection(const QDBusObjectPath &in0);
963+ void PropertiesChanged(const QVariantMap &in0);
964+};
965+
966+#endif
967+
968+
969
970=== added file 'plugins/cellular/plugin.cpp'
971--- plugins/cellular/plugin.cpp 1970-01-01 00:00:00 +0000
972+++ plugins/cellular/plugin.cpp 2014-07-04 12:59:29 +0000
973@@ -0,0 +1,32 @@
974+/*
975+ * Copyright (C) 2013 Canonical Ltd
976+ *
977+ * This program is free software: you can redistribute it and/or modify
978+ * it under the terms of the GNU General Public License version 3 as
979+ * published by the Free Software Foundation.
980+ *
981+ * This program is distributed in the hope that it will be useful,
982+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
983+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
984+ * GNU General Public License for more details.
985+ *
986+ * You should have received a copy of the GNU General Public License
987+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
988+ *
989+*/
990+
991+#include <QtQml>
992+#include <QtQml/QQmlContext>
993+#include "plugin.h"
994+#include "hotspotmanager.h"
995+
996+void BackendPlugin::registerTypes(const char *uri)
997+{
998+ Q_ASSERT(uri == QLatin1String("Ubuntu.SystemSettings.Cellular"));
999+ qmlRegisterType<HotspotManager>(uri, 1, 0, "HotspotManager");
1000+}
1001+
1002+void BackendPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
1003+{
1004+ QQmlExtensionPlugin::initializeEngine(engine, uri);
1005+}
1006
1007=== added file 'plugins/cellular/plugin.h'
1008--- plugins/cellular/plugin.h 1970-01-01 00:00:00 +0000
1009+++ plugins/cellular/plugin.h 2014-07-04 12:59:29 +0000
1010@@ -0,0 +1,34 @@
1011+/*
1012+ * Copyright (C) 2014 Canonical Ltd
1013+ *
1014+ * This program is free software: you can redistribute it and/or modify
1015+ * it under the terms of the GNU General Public License version 3 as
1016+ * published by the Free Software Foundation.
1017+ *
1018+ * This program is distributed in the hope that it will be useful,
1019+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1020+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1021+ * GNU General Public License for more details.
1022+ *
1023+ * You should have received a copy of the GNU General Public License
1024+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1025+ *
1026+*/
1027+
1028+#ifndef PLUGIN_H
1029+#define PLUGIN_H
1030+
1031+#include <QtQml/QQmlEngine>
1032+#include <QtQml/QQmlExtensionPlugin>
1033+
1034+class BackendPlugin: public QQmlExtensionPlugin
1035+{
1036+ Q_OBJECT
1037+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
1038+
1039+public:
1040+ void registerTypes(const char *uri);
1041+ void initializeEngine(QQmlEngine *engine, const char *uri);
1042+};
1043+
1044+#endif // PLUGIN_H
1045
1046=== added file 'plugins/cellular/qmldir'
1047--- plugins/cellular/qmldir 1970-01-01 00:00:00 +0000
1048+++ plugins/cellular/qmldir 2014-07-04 12:59:29 +0000
1049@@ -0,0 +1,2 @@
1050+module Ubuntu.SystemSettings.Cellular
1051+plugin UbuntuCellularPanel

Subscribers

People subscribed via source and target branches