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

Proposed by Ken VanDine
Status: Merged
Approved by: Ken VanDine
Approved revision: 1119
Merged at revision: 1129
Proposed branch: lp:~unity-api-team/ubuntu-system-settings/apneditor
Merge into: lp:ubuntu-system-settings
Prerequisite: lp:~jonas-drange/ubuntu-system-settings/cellular-slot2-online-status-not-persisting-1375832
Diff against target: 1590 lines (+1297/-90)
11 files modified
plugins/cellular/CMakeLists.txt (+4/-0)
plugins/cellular/Components/CMakeLists.txt (+6/-0)
plugins/cellular/Components/MultiSim.qml (+4/-4)
plugins/cellular/Components/SingleSim.qml (+4/-3)
plugins/cellular/CustomApnEditor.qml (+326/-0)
plugins/cellular/PageChooseApn.qml (+610/-0)
plugins/cellular/PageChooseCarrier.qml (+163/-80)
plugins/cellular/PageChooseCarriers.qml (+4/-3)
plugins/cellular/ofonoactivator.cpp (+132/-0)
plugins/cellular/ofonoactivator.h (+42/-0)
plugins/cellular/plugin.cpp (+2/-0)
To merge this branch: bzr merge lp:~unity-api-team/ubuntu-system-settings/apneditor
Reviewer Review Type Date Requested Status
Ken VanDine Approve
PS Jenkins bot continuous-integration Needs Fixing
Iain Lane Pending
Jonas G. Drange Pending
Review via email: mp+237138@code.launchpad.net

This proposal supersedes a proposal from 2014-07-21.

Commit message

Add an APN editor.

Description of the change

Bug affecting the landing:
https://bugs.launchpad.net/ubuntu/+source/network-manager/+bug/1378102

As of our platform is not currently able to handle max. 1 MMS APN[0], here is the "logic" of the editor:

- it will always create a custom internet APN if none exists for the system
- ofono provisioning might add Internet APN's that are also used for MMS
  - these are identified by having a MessageCenter property set, although
    strictly speaking this is violating ofono API
- When user switches between Internet APNs, NetworkManager is told
  to activate the selected APN through ofonoActivator::activate()
- as the system is only able to handle one MMS APN, custom MMS APN is only
  created if user explicitly configures one
  - if there is a provisioned MMS APN it will get removed and one custom one
    created
  - as the QOfono API does not offer a way to directly access an APN created
    with ConnectionManager::addContext(), we have to detect a newly created
    MMS APN by magic (isEmptyCustom()) and lazily populate it when detected
    (pendingMmsData)
- Any configured MMS APN (both custom and provisioned) will be removed if
  user activates a dual Internet APN with MMS capability

[0] https://bugs.launchpad.net/bugs/1362795

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:798
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1028/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2226
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1853
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/220
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/220
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/220/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/220
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2437
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3408
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3408/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10130
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1557
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2072
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2072/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:799
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1029/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2248
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1865
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/221
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/221
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/221/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/221
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2453
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3432
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3432/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10148
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1567
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2084
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2084/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:800
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1035/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2327
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1914
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/227
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/227
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/227/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/227
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2509
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3538
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3538/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10230
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1605
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2144
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2144/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:801
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1040/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2369
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1940
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/232
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/232
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/232/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/232
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2546
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3589
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3589/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10280
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1625
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2185
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2185/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Iain Lane (laney) wrote : Posted in a previous version of this proposal

Not reviewed, but please make sure to wrap all lines at 80 characters and fix the copyright years.

Revision history for this message
Jussi Pakkanen (jpakkane) wrote : Posted in a previous version of this proposal

We don't have an 80 character line limit any more. It's 132 now. See for example:

https://bazaar.launchpad.net/~unity-team/unity-api/trunk/view/head:/astyle-config

Revision history for this message
Iain Lane (laney) wrote : Posted in a previous version of this proposal

On Wed, Jul 23, 2014 at 02:08:11PM -0000, Jussi Pakkanen wrote:
> We don't have an 80 character line limit any more. It's 132 now. See for example:

Who decided this for ubuntu-system-settings.

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

Revision history for this message
Sebastien Bacher (seb128) wrote : Posted in a previous version of this proposal

@Jussi, the document you pointed is not from the settings project, we use a 80 chars wrap count here

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:802
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1042/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2378
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1945
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/234
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/234
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/234/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/234
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2550
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3599
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3599/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10284
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1628
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2190
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2190/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Iain Lane (laney) wrote : Posted in a previous version of this proposal

On Wed, Jul 23, 2014 at 03:15:53PM -0000, Sebastien Bacher wrote:
> @Jussi, the document you pointed is not from the settings project, we use a 80 chars wrap count here

However we are discussing it - GNOME recommends between 80 and 120 & we
might align on this.

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

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:803
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1043/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2385
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1948
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/235
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/235
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/235/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/235
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2555
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3607
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3607/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10289
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1631
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2193
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2193/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:805
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1048/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2418
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1970
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/240
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/240
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/240/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/240
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2587
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3649
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3649/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10331
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1649
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2220
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2220/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:807
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1064/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2503
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/2021
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/256
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/256
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/256/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/256
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2655
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3746
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3746/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10428
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1690
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2274
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2274/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:809
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1222/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/3462
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/2722
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/415
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/411
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/411/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/414
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/3366
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/4709
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/4709/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/11380
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/2199
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2999
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2999/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Iain Lane (laney) wrote : Posted in a previous version of this proposal

Please could you make sure the AP tests are passing. Also remove all stray warnings.

If this isn't ready - some comments suggest it isn't - set the branch to WIP please.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:810
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1223/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/3473
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/2730
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/416
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/412
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/412/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/415
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/3374
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/4720
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/4720/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/11394
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/2206
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/3007
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/3007/artifact/work/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Jonas G. Drange (jonas-drange) wrote : Posted in a previous version of this proposal

See inline comments. There's some Loader magic going on. Happy to explain, but for now, remove the data preference code in PageComponent as well as the code that re-creates a lot of ofono objects.

review: Needs Fixing
Revision history for this message
Jussi Pakkanen (jpakkane) wrote : Posted in a previous version of this proposal

Fixed one, need some help with the other. Thanks.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Ken VanDine (ken-vandine) wrote : Posted in a previous version of this proposal

There are a number of asserts in the code with comments that they should be removed, like:
// just asserting to verify the logic
// remove once proven functional

Those should probably removed.

There are a number of places with commented out code (like properties), other than the TODOs and place holders for future work. Please remove them if they aren't needed.

review: Needs Fixing
Revision history for this message
Pat McGowan (pat-mcgowan) wrote : Posted in a previous version of this proposal
Download full text (3.9 KiB)

I see the following output using those debs

2014-08-27 16:23:38,267 - WARNING - file:///usr/share/ubuntu/settings/system/qml-plugins/cellular/PageChooseCarrier.qml:67:17: Unable to assign [undefined] to QObject*
2014-08-27 16:23:38,308 - WARNING - QOfonoNetworkOperator::registerOperator() failed: QDBusError("org.ofono.Error.AccessDenied", "Operation not permitted")
2014-08-27 16:23:38,308 - WARNING - registerComplete failed with error: org.ofono.Error.AccessDenied Operation not permitted Falling back to default
2014-08-27 16:24:12,488 - WARNING - file:///usr/share/ubuntu/settings/system/qml-plugins/cellular/PageChooseApn.qml:268:5: QML Connections: Cannot assign to non-existent propert
y "onContextsChanged"
2014-08-27 16:24:12,493 - WARNING - file:///usr/share/ubuntu/settings/system/qml-plugins/cellular/PageChooseApn.qml:55: TypeError: Cannot read property 'contexts' of undefined
2014-08-27 16:24:12,494 - WARNING - file:///usr/share/ubuntu/settings/system/qml-plugins/cellular/PageChooseApn.qml:269:17: Unable to assign [undefined] to QObject*
pa

and this is syslog:

Aug 20 09:04:19 ubuntu-phablet URfkill[22242]: Modem found: '/ril_0'
Aug 20 09:04:19 ubuntu-phablet URfkill[22242]: killswitch state: KILLSWITCH_STATE_NO_ADAPTER new_state: KILLSWITCH_STATE_UNBLOCKED
Aug 20 09:04:19 ubuntu-phablet URfkill[22242]: Setting device 100 (WWAN) to unblocked
Aug 20 09:04:19 ubuntu-phablet URfkill[22242]: device_changed_cb: Fake Manufacturer Fake Modem Model
Aug 20 09:04:19 ubuntu-phablet URfkill[22242]: killswitch state: KILLSWITCH_STATE_UNBLOCKED new_state: KILLSWITCH_STATE_SOFT_BLOCKED
Aug 20 09:04:19 ubuntu-phablet URfkill[22242]: <warning> Could not set Online property in oFono: GDBus.Error:org.ofono.Error.Failed: Operation failed
Aug 20 09:04:19 ubuntu-phablet NetworkManager[1633]: <warn> OFONO modem set enabled failed: (19) Method "SetProperty" with signature "sv" on interface "org.ofono.ConnectionManag
er" doesn't exist
Aug 20 09:04:19 ubuntu-phablet /03mmsproxy: Adding route for MMS connection /310410528924256/context2 on /ril_0 (rmnet_usb0)
Aug 20 09:04:19 ubuntu-phablet /03mmsproxy: failed to add route: org.freedesktop.DBus.Error.UnknownObject: Method "GetProperties" with signature "" on interface "org.ofono.Conne
ctionContext" doesn't exist
Aug 20 09:04:19 ubuntu-phablet kernel: [34624.654748] mmc0: mmc_start_bkops: Starting bkops
Aug 20 09:04:20 ubuntu-phablet kernel: [34626.169291] mdm_power_down_common: MDM2AP_STATUS never went low. Doing a hard reset
Aug 20 09:04:21 ubuntu-phablet NetworkManager[1633]: <info> Auto-activating connection '/310410528924256/context2'.
Aug 20 09:04:21 ubuntu-phablet NetworkManager[1633]: <info> Activation (/ril_0) starting connection '/310410528924256/context2'
Aug 20 09:04:21 ubuntu-phablet NetworkManager[1633]: <info> (/ril_0): device state change: disconnected -> prepare (reason 'none') [30 40 0]
Aug 20 09:04:21 ubuntu-phablet NetworkManager[1633]: <info> Activation (/ril_0) Stage 1 of 5 (Device Prepare) scheduled...
Aug 20 09:04:21 ubuntu-phablet NetworkManager[1633]: <info> Activation (/ril_0) Stage 1 of 5 (Device Prepare) started...
Aug 20 09:04:21 ubuntu-phablet NetworkManager[1633]: <info> Activation (...

Read more...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote : Posted in a previous version of this proposal

OK, after extensive testing this should be good to go.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Pat McGowan (pat-mcgowan) wrote : Posted in a previous version of this proposal

I get a large number (>50) of these when I enter the APN panel
2014-08-29 08:58:11,004 - WARNING - file:///usr/share/ubuntu/settings/system/qml-plugins/cellular/PageChooseCarrier.qml:28:1: QML PageChooseCarrier: Binding loop detected for property "height"

Revision history for this message
Pat McGowan (pat-mcgowan) wrote : Posted in a previous version of this proposal

actually the above happens when you scroll the page

Revision history for this message
Pat McGowan (pat-mcgowan) wrote : Posted in a previous version of this proposal

note to test these debs you need latest from
https://launchpad.net/ubuntu/utopic/armhf/accountsservice-ubuntu-schemas/0.0.3+14.10.20140827-0ubuntu1

Other than the binding loop seems good

Revision history for this message
Jonas G. Drange (jonas-drange) wrote : Posted in a previous version of this proposal

WFM (krillin, telenor)

review: Approve
Revision history for this message
Ken VanDine (ken-vandine) wrote : Posted in a previous version of this proposal

CI is failing because you changed the carrierSelector from an ItemSelector to an OptionSelector but didn't change the tests to match.

review: Needs Fixing
Revision history for this message
Ken VanDine (ken-vandine) wrote : Posted in a previous version of this proposal

Inline comment, typo in a visible string.

review: Needs Fixing
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote : Posted in a previous version of this proposal

> I get a large number (>50) of these when I enter the APN panel
> 2014-08-29 08:58:11,004 - WARNING - file:///usr/share/ubuntu/settings/system
> /qml-plugins/cellular/PageChooseCarrier.qml:28:1: QML PageChooseCarrier:
> Binding loop detected for property "height"

This is a height property of the top level ItemPage which is not even being modified in PageChooseCarrier.qml at all. I would suspect it something to do with UITK or the OSK work that has gone in to the low levels.

If this does not affect the UX in any visible way, I would say it's totally minor and no reason to block the landing.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Ken VanDine (ken-vandine) wrote : Posted in a previous version of this proposal

You're anchoring the buttonRectangle to parent.bottom, which causes it to get pushed up above the input fields when the OSK is displayed. You should put it inside the flickable, so they stay below the inputs.

review: Needs Fixing
Revision history for this message
Ken VanDine (ken-vandine) wrote : Posted in a previous version of this proposal

Testing on krillin, I can't get a working context for my t-mobile US SIM. Looking at the output of list-contexts, it isn't setting the value I entered for MessageCenter.

Looking at the upstart logs, I see this output when trying to set the context:
2014-08-29 15:39:19,973 - CRITICAL - Context error on /ril_0/context3: Invalid arguments in method call

review: Needs Fixing
Revision history for this message
Ken VanDine (ken-vandine) wrote : Posted in a previous version of this proposal

After re-reading the MP description, I see that the failure I get above is consistent with bug 1362068. So apparently this can't work until we get that bug fixed?

Revision history for this message
Ken VanDine (ken-vandine) wrote : Posted in a previous version of this proposal

The implementation is considerably different from the [1]design, has someone from design looked at this?

[1] https://wiki.ubuntu.com/Networking

Revision history for this message
Jussi Pakkanen (jpakkane) wrote : Posted in a previous version of this proposal

Here's the design review.

------

Thanks for helping me get the APN settings going on my handset. For
your convenience, I've attached a couple of screenshots of what I see.
Comparing the current implementation with
<https://wiki.ubuntu.com/Networking#apn-mobile>:

* "On the carrier screen, the “APN” item should be insensitive
    whenever the SIM is not associated with a carrier."

    When I'm in Flight Mode, (a) the carrier menu is empty, but (b) the
    "APN" item is still choosable. At least one of those is wrong
    (possibly both).

* On the APN screen, the radio lists are in Ubuntu shapes. If these
    are quick to remove, please remove them. Compare with the
    "Automatically"/"Manually" list on the Cellular screen, which
    looks much nicer.

* "The “Internet APN:” and “MMS APN:” radio lists should each consist
    of: * a “None” item, if no APN is currently activated for that
    connection type;..."

    On my handset, there are two items in the "Internet APN:" list, but
    neither of them are selected. If it's really true that no Internet
    APN is set on my phone, there should be a selected "None" item.

* Consequently, in the "MMS APN:" list, if I tap "Same APN as for
    Internet", I get a dialog: "Error: No Internet APN has been
    selected." Abolish this dialog, and instead just make that "Same
    APN" item insensitive whenever no Internet APN is selected.

* "Choosing “Custom Internet APN…” or “Custom MMS APN…” should open
    the relevant dialog..."

    These screens are currently stack pages instead of dialogs. This
    means that I can enter some settings, complete or not, then tap
    the Back button, and it isn't clear whether those settings will be
    saved or not, which is pretty confusing. Even worse, in the "Custom
    MMS APN" screen, the "Password" field is hidden partly under the
    "Cancel" and "Save" buttons, and partly under the OSK. And the
    field labels are weirdly close to the left edge of the screen.

* "“Internet APN”, “MMS APN”, “MMSC”, and “Proxy” should be URL
    fields (using the URL OSK and ignoring non-URL characters)..."

    Currently, "Internet APN", "MMS APN", "MMSC", and "Proxy" are all
    normal text fields, allowing impossible characters, and assuming
    that I want to capitalize and spell-check their contents when I do
    not.

* "...auto-inserting http:// on unfocus if no protocol was entered."

    This doesn't happen.

* When I tap "Activate", even after entering a non-existent APN name,
    the settings are apparently accepted without being tried.

Though I'm a perfectionist, I have a low bar for whether a feature is
better than nothing. But that last point is what makes me say no, this
isn't ready to land. If custom APNs aren't implemented at all yet, the
buttons and screens to specify them shouldn't be present, because
that's actively misleading. And if they are implemented, why is a
non-existent APN accepted?

Revision history for this message
Matthew Paul Thomas (mpt) wrote : Posted in a previous version of this proposal

Antti has explained to me the current asynchronous and uncommunicative API that makes validating a custom APN impossible to implement for MMS, and impractically difficult for Internet, at least without a new API. So I withdraw the last point, and instead suggest that "Activate" should be merely "OK" (since it won't be doing any activation right then).

Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote : Posted in a previous version of this proposal

> Here's the design review.
>
> ------
>
> Thanks for helping me get the APN settings going on my handset. For
> your convenience, I've attached a couple of screenshots of what I see.
> Comparing the current implementation with
> <https://wiki.ubuntu.com/Networking#apn-mobile>:
>
> * "On the carrier screen, the “APN” item should be insensitive
> whenever the SIM is not associated with a carrier."
>
> When I'm in Flight Mode, (a) the carrier menu is empty, but (b) the
> "APN" item is still choosable. At least one of those is wrong
> (possibly both).

Fixed both.

> * On the APN screen, the radio lists are in Ubuntu shapes. If these
> are quick to remove, please remove them. Compare with the
> "Automatically"/"Manually" list on the Cellular screen, which
> looks much nicer.

We could argue that the OptionSelector looks way better, but let's be consistently ugly ;)
Fixed.

> * "The “Internet APN:” and “MMS APN:” radio lists should each consist
> of: * a “None” item, if no APN is currently activated for that
> connection type;..."
>
> On my handset, there are two items in the "Internet APN:" list, but
> neither of them are selected. If it's really true that no Internet
> APN is set on my phone, there should be a selected "None" item.

Will land this separately when we get nuntium support for multiple MMS APN contexts.

> * Consequently, in the "MMS APN:" list, if I tap "Same APN as for
> Internet", I get a dialog: "Error: No Internet APN has been
> selected." Abolish this dialog, and instead just make that "Same
> APN" item insensitive whenever no Internet APN is selected.

Done. No more dialogs.

> * "Choosing “Custom Internet APN…” or “Custom MMS APN…” should open
> the relevant dialog..."
>
> These screens are currently stack pages instead of dialogs. This
> means that I can enter some settings, complete or not, then tap
> the Back button, and it isn't clear whether those settings will be
> saved or not, which is pretty confusing. Even worse, in the "Custom
> MMS APN" screen, the "Password" field is hidden partly under the
> "Cancel" and "Save" buttons, and partly under the OSK. And the
> field labels are weirdly close to the left edge of the screen.

jgdx takes care of this in a separate landing.

> * "“Internet APN”, “MMS APN”, “MMSC”, and “Proxy” should be URL
> fields (using the URL OSK and ignoring non-URL characters)..."
>
> Currently, "Internet APN", "MMS APN", "MMSC", and "Proxy" are all
> normal text fields, allowing impossible characters, and assuming
> that I want to capitalize and spell-check their contents when I do
> not.

I set the relevant hints, but seems the TextField is not validating based on them. We should at least now get a custom OSK for them.

> * "...auto-inserting http:// on unfocus if no protocol was entered."
>
> This doesn't happen.

Nope. Will either fix this on the next landing or file a medium bug.

Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote : Posted in a previous version of this proposal

> Antti has explained to me the current asynchronous and uncommunicative API
> that makes validating a custom APN impossible to implement for MMS, and
> impractically difficult for Internet, at least without a new API. So I
> withdraw the last point, and instead suggest that "Activate" should be merely
> "OK" (since it won't be doing any activation right then).

For Internet it's "Activate" as that we can actually try to activate but don't get any feedback if it succeeds or not. If the config is bad, NM starts to try the other available APNs until it either finds one that works or gives up. You see the selected APN changing in the list while NM does it's magic.

For MMS it's "Save" as that is what it does.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote : Posted in a previous version of this proposal

APN editor: Buttons stay pressed after first tap:
https://bugs.launchpad.net/ubuntu/+source/ubuntu-system-settings/+bug/1376696

APN editor: Grey selection box when tapping just below/above the last/first entry.
https://bugs.launchpad.net/ubuntu/+source/ubuntu-system-settings/+bug/1376713

APN editor: Pressing enter key should shift focus to next field.
https://bugs.launchpad.net/ubuntu/+source/ubuntu-system-settings/+bug/1376714

APN editor: Selected APN states don't persist on exit and re-entry
https://bugs.launchpad.net/ubuntu/+source/ubuntu-system-settings/+bug/1376720

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Ken VanDine (ken-vandine) wrote : Posted in a previous version of this proposal

Please put the button rectangle inside the flickable instead of anchoring the flickable to the top. We've run into this problem in a number of places in other plugins, putting them inside the flickable has worked out much better.

Please see inline comments

review: Needs Fixing
Revision history for this message
Jonas G. Drange (jonas-drange) wrote : Posted in a previous version of this proposal

Could you quickly improve the throwing of exceptions? It might be a bit cryptic as it is?

Also, I added a comment about the tmp variable not being a copy (forgive me if that was intended) and a small inconsistency referring to the __suppress… flag.

See inline comments.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1111. By Launchpad Translations on behalf of system-settings-touch

Launchpad automatic translations update.

Revision history for this message
Pat McGowan (pat-mcgowan) wrote :

Installed packages from the silo and tested the UI.
I made a test apn that did not work and the selection for active went back to the original.

My second sim has no signal so the UI did not enable the APN editing option which I assume is intended.

It occurs to me there seems to be a flaw in the general UI. If "Same APN as for internet" is enabled then the custom internet APN page needs to include the MMS settings.

The custom panel was supposed to be pre-populated with the currently active APN information.
Choosing “Custom Internet APN…” or “Custom MMS APN…” should open the relevant dialog, pre-filled with the details of the already-selected APN so that you can view, tweak, or replace them as necessary.

I wonder if we should also show the protocol field as IPv4 without an option to change it.

Revision history for this message
Pat McGowan (pat-mcgowan) wrote :

I tried to make a custom Internet APN that matched the active one and it would not be accepted

Context2 below is what is being used, context3 I made. Note the "settings" are missing from our editor,not sure if they are required.

[ /ril_0 ]
    [ /ril_0/context1 ]
        IPv6.Settings = { }
        Password =
        Settings = { }
        MessageCenter = http://mmsc.mobile.att.net
        MessageProxy = proxy.mobile.att.net:80
        Type = internet
        Username =
        Active = 0
        Name = ATT Phone
        Protocol = ip
        AccessPointName = nxtgenphone

    [ /ril_0/context2 ]
        IPv6.Settings = { }
        Password =
        Settings = { Gateway=10.208.157.220 DomainNameServers=172.16.145.103,172.16.145.103, Netmask=255.255.255.0 Method=static Address=10.208.157.220 Interface=ccmni0 }
        MessageCenter = http://mmsc.cingular.com/
        MessageProxy = wireless.cingular.com
        Type = internet
        Username =
        Active = 1
        Name = ATT WAP
        Protocol = ip
        AccessPointName = wap.cingular

    [ /ril_0/context3 ]
        IPv6.Settings = { }
        Password =
        Settings = { }
        Type = internet
        Username =
        Active = 0
        Name = ___ubuntu_custom_apn_internet
        Protocol = ip
        AccessPointName = wap.cingular

Revision history for this message
Pat McGowan (pat-mcgowan) wrote :

T-Mobile users simply need to create a custom apn with a change of protocol from ipv6 to ip(v4). The UI will not be clear to them, they will see a custom APN that looks the same as their current APN since we do not show the protocol field. Be nice to illustrate the faulty setting perhaps.

[ /ril_1 ]
    [ /ril_1/context1 ]
        Username =
        Settings = { }
        Protocol = ipv6
        AccessPointName = fast.t-mobile.com
        IPv6.Settings = { }
        Active = 0
        Name = T-Mobile GPRS
        MessageProxy =
        MessageCenter = http://mms.msg.eng.t-mobile.com/mms/wapenc
        Password =
        Type = internet

1112. By Launchpad Translations on behalf of system-settings-touch

Launchpad automatic translations update.

1113. By Launchpad Translations on behalf of system-settings-touch

Launchpad automatic translations update.

Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote : Posted in a previous version of this proposal

Fixed by the review comments in r980. The only non-trivial comments are:

Ken VanDine (ken-vandine) wrote:
> I think you shouldn't be anchoring to the buttonRectangle,
> the buttonRectangle should be in the Flickable.

Yes. I know, but in this case the user usually just enters two of the top fields and having the buttons always visible has some value. I took great care on verifying that the buttons react properly on the viewport changes. If I get it to break on my last testing round, then I will put the buttons inside the flickable, OK?

Ken VanDine (ken-vandine) wrote:
> Does this really return an empty list?
> Perhaps it would be safer to set connections to a QStringList()

the connection list is an array of object paths. QDBusPendingReply quarantees that .value() returns a default constructed T, which in this case is an empty array of dbus-paths.

For the logic that follows it's really irrelevant if an empty list is received (that is also a valid reply).

Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote : Posted in a previous version of this proposal

Now resolving merge conflicts.
IMHO the dynamic SIM logic is a bit broken, but it's more or less a design question. Let's continue on that after this MP is in.

Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

> Installed packages from the silo and tested the UI.
> I made a test apn that did not work and the selection for active went back to
> the original.

OK, this needs a bit more investigating. Was it an Internet APN or MMS?
https://bugs.launchpad.net/ubuntu/+source/ubuntu-system-settings/+bug/1376720

possible causes: ofono not updating the Active properties correctly, NM not setting the Active properties correctly, APN editor not reacting to the Active properties correctly.

> My second sim has no signal so the UI did not enable the APN editing option
> which I assume is intended.

Yes, you can only access the APN editor page if your phone is registered to a network.

> It occurs to me there seems to be a flaw in the general UI. If "Same APN as
> for internet" is enabled then the custom internet APN page needs to include
> the MMS settings.
>
> The custom panel was supposed to be pre-populated with the currently active
> APN information.
> Choosing “Custom Internet APN…” or “Custom MMS APN…” should open the relevant
> dialog, pre-filled with the details of the already-selected APN so that you
> can view, tweak, or replace them as necessary.

This is for provisioned APN's. The ones that come from ofono and android provider database. Such Internet APNs can and do define shared APN's. You can't create one right now through the UI. If the provisioning fails for both Internet and MMS, then yes, the user would need to create two separate APN's (one for Internet, one for MMS).

We don't allow editing of the provisioned APNs (for now). There is only one Custom APN which is separate from the provisioned ones.

The whole "use the same values as for Internet" in the MMS editor was getting so messy that I disabled that toggle for now. We should enable that once we allow editing of the provisioned APNs.

> I wonder if we should also show the protocol field as IPv4 without an option
> to change it.

My opinion this would be that we keep it hidden until we actually support both.

Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

> I tried to make a custom Internet APN that matched the active one and it would
> not be accepted

 :/

> Context2 below is what is being used, context3 I made. Note the "settings" are
> missing from our editor,not sure if they are required.
>
> [ /ril_0 ]
> [ /ril_0/context1 ]
> IPv6.Settings = { }
> Password =
> Settings = { }
> MessageCenter = http://mmsc.mobile.att.net
> MessageProxy = proxy.mobile.att.net:80
> Type = internet
> Username =
> Active = 0
> Name = ATT Phone
> Protocol = ip
> AccessPointName = nxtgenphone
>
> [ /ril_0/context2 ]
> IPv6.Settings = { }
> Password =
> Settings = { Gateway=10.208.157.220
> DomainNameServers=172.16.145.103,172.16.145.103, Netmask=255.255.255.0
> Method=static Address=10.208.157.220 Interface=ccmni0 }
> MessageCenter = http://mmsc.cingular.com/
> MessageProxy = wireless.cingular.com
> Type = internet
> Username =
> Active = 1
> Name = ATT WAP
> Protocol = ip
> AccessPointName = wap.cingular
>
> [ /ril_0/context3 ]
> IPv6.Settings = { }
> Password =
> Settings = { }
> Type = internet
> Username =
> Active = 0
> Name = ___ubuntu_custom_apn_internet
> Protocol = ip
> AccessPointName = wap.cingular

the data looks valid, it's just the static DNS and IP assignments that worry me. We don't support that in the editor right now. I'll finish my testing as it could be that you have just unlucky settings on your SIM that we can't support right now.

Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

> T-Mobile users simply need to create a custom apn with a change of protocol
> from ipv6 to ip(v4). The UI will not be clear to them, they will see a custom
> APN that looks the same as their current APN since we do not show the protocol
> field. Be nice to illustrate the faulty setting perhaps.
>
> [ /ril_1 ]
> [ /ril_1/context1 ]
> Username =
> Settings = { }
> Protocol = ipv6
> AccessPointName = fast.t-mobile.com
> IPv6.Settings = { }
> Active = 0
> Name = T-Mobile GPRS
> MessageProxy =
> MessageCenter = http://mms.msg.eng.t-mobile.com/mms/wapenc
> Password =
> Type = internet

Is that above now faulty or not?

So, this is an automatically provisioned APN, right? As I said above, we don't currently support editing provisioned APNs. Instead we should modify the file we use for provisioning and change the protocol there directly.

OR if we now do support also IPv6 APNs then we must include the protocol field to the editor.

Revision history for this message
Ken VanDine (ken-vandine) wrote :

It's not activating my custom internet APN for t-mobile. After creating it, it goes back out and neither are selected. After a few seconds the provisioned APN is selected again instead of the custom. Here's the output of list-contexts:

[ /ril_0 ]
    [ /ril_0/context1 ]
        Name = T-Mobile GPRS
        Password =
        IPv6.Settings = { }
        Type = internet
        Settings = { Netmask=255.255.255.0 DomainNameServers=10.177.0.34,10.163.103.140, Method=static Gateway=33.97.153.25 Interface=rmnet_usb0 Address=33.97.153.24 }
        Protocol = ip
        AccessPointName = fast.t-mobile.com
        Username =
        MessageCenter = http://mms.msg.eng.t-mobile.com/mms/wapenc
        MessageProxy =
        Active = 1

    [ /ril_0/context2 ]
        Name = ___ubuntu_custom_apn_internet
        Password =
        IPv6.Settings = { }
        Type = internet
        Settings = { }
        Protocol = ip
        AccessPointName = fast.t-mobile.com
        Username =
        Active = 0

    [ /ril_0/context3 ]
        Name = ___ubuntu_custom_apn_mms
        Password =
        IPv6.Settings = { }
        Type = mms
        Settings = { }
        Protocol = ip
        AccessPointName = fast.t-mobile.com
        Username =
        MessageCenter = http://mms.msg.eng.t-mobile.com/mms/wapenc
        MessageProxy =
        Active = 0

review: Needs Information
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

> It's not activating my custom internet APN for t-mobile. After creating it,
> it goes back out and neither are selected. After a few seconds the
> provisioned APN is selected again instead of the custom. Here's the output of
> list-contexts:
>
> [ /ril_0 ]
> [ /ril_0/context1 ]
> Name = T-Mobile GPRS
> Password =
> IPv6.Settings = { }
> Type = internet
> Settings = { Netmask=255.255.255.0
> DomainNameServers=10.177.0.34,10.163.103.140, Method=static
> Gateway=33.97.153.25 Interface=rmnet_usb0 Address=33.97.153.24 }
> Protocol = ip
> AccessPointName = fast.t-mobile.com
> Username =
> MessageCenter = http://mms.msg.eng.t-mobile.com/mms/wapenc
> MessageProxy =
> Active = 1
>
> [ /ril_0/context2 ]
> Name = ___ubuntu_custom_apn_internet
> Password =
> IPv6.Settings = { }
> Type = internet
> Settings = { }
> Protocol = ip
> AccessPointName = fast.t-mobile.com
> Username =
> Active = 0
>
> [ /ril_0/context3 ]
> Name = ___ubuntu_custom_apn_mms
> Password =
> IPv6.Settings = { }
> Type = mms
> Settings = { }
> Protocol = ip
> AccessPointName = fast.t-mobile.com
> Username =
> MessageCenter = http://mms.msg.eng.t-mobile.com/mms/wapenc
> MessageProxy =
> Active = 0

We identified a NM bug which prevents activating Custom Internet APN if there already is a provisioned one active at the same time.

There also was a bug in switching between multiple provisioned Internet APNs, now fixed in the branch.

Revision history for this message
Ken VanDine (ken-vandine) wrote :

I'll approve the code, it seems to work in the case where the user doesn't have a context that can be activated. I want to wait until we triage the NM bug before top approving and preparing to land.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1114. By Launchpad Translations on behalf of system-settings-touch

Launchpad automatic translations update.

Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

I think the activation of new contexts should also be fixed at the APN editor level. You should be able to explicitly Disconnect an interface if it's found to currently be connected as per NetworkManager, without having to bother with which context was activated. Once disconnected, you would be able to freely activate a new context.

The issue with doing automatic deactivation just before activating a new context in NM directly is that all of these are time-sensitive operations; and can't be run synchronously (otherwise it would cause visible delays when you try to activate the connection and weird behavior in the indicators). When running them async; it's still possible for the disconnect to be delayed enough that the deactivation of the old context and activation of the new one to happen pretty much simultaneously; in other words, you'll still risk failure cases; which can be safely avoided by explicitly disconnecting the device and connecting a new context altogether when trying to activate a newly-created context.

Revision history for this message
Ken VanDine (ken-vandine) wrote :

I agree with what Mathieu said, we should handle it in the apneditor. Fixing it in NM is nice too, but we should still do the disconnect ourselves.

review: Needs Fixing
1115. By Jonas G. Drange

[wifi/phone] dynamically chooses what SIM to use when there's only one present. Fixes: 1375832
Approved by: Ken VanDine, PS Jenkins bot

1116. By PS Jenkins bot

Releasing 0.3+14.10.20141007-0ubuntu1

1117. By Launchpad Translations on behalf of system-settings-touch

Launchpad automatic translations update.

1118. By Launchpad Translations on behalf of system-settings-touch

Launchpad automatic translations update.

1119. By Ken VanDine

merged apneditor

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

When there is no working APN I can define and activate a new Internet APN
When there is a working APN, no other APNs will activate

I can define an MMS APN which matches the existing working dual internet/mms APN, but it will not activate. The UI shows it selected however.
I suspect that AT&T may not support activating 2 different APNs and the UI should support defining an internet apn that does both.

The custom internet apn screen offers cancel and activate while the mms screen offers cancel and save.

Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

> When there is no working APN I can define and activate a new Internet APN
> When there is a working APN, no other APNs will activate

Are the other APNs valid? You can only activate a valid APN.

> I can define an MMS APN which matches the existing working dual internet/mms
> APN, but it will not activate. The UI shows it selected however.

MMS APNs activate only for a short period of time when MMS message is either sent or received. ofono Activate is not applicable here. The selection is correct, as you only have a single MMS context, so that one is the one that nuntium will use.

> The custom internet apn screen offers cancel and activate while the mms screen
> offers cancel and save.

This is agreed with mpt, I though the design has also been updated. Internet APN can be activated, but MMS apn can only be saved. hence the difference.

Revision history for this message
Ken VanDine (ken-vandine) wrote :

I think we need to get this landed and iterate to improve it. It seems to create a valid APN for some networks.

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-08-17 14:50:51 +0000
3+++ plugins/cellular/CMakeLists.txt 2014-10-09 14:10:12 +0000
4@@ -4,6 +4,8 @@
5 install(FILES settings-cellular.svg DESTINATION ${PLUGIN_MANIFEST_DIR}/icons)
6
7 set(QML_SOURCES
8+ CustomApnEditor.qml
9+ PageChooseApn.qml
10 PageChooseCarrier.qml
11 PageChooseCarriers.qml
12 PageComponent.qml
13@@ -18,6 +20,8 @@
14 plugin.h
15 hotspotmanager.cpp
16 hotspotmanager.h
17+ ofonoactivator.cpp
18+ ofonoactivator.h
19 nm_manager_proxy.h
20 nm_settings_proxy.h
21 nm_settings_connection_proxy.h
22
23=== modified file 'plugins/cellular/Components/CMakeLists.txt'
24--- plugins/cellular/Components/CMakeLists.txt 2014-08-21 20:25:08 +0000
25+++ plugins/cellular/Components/CMakeLists.txt 2014-10-09 14:10:12 +0000
26@@ -9,3 +9,9 @@
27 SimEditor.qml
28 )
29 install(FILES ${QML_SOURCES} DESTINATION ${PLUGIN_QML_DIR}/cellular/Components)
30+
31+# add a phony target to get the files visible in Qt Creator.
32+add_custom_target(
33+ plugins_cellular_components_sources
34+ SOURCES ${QML_SOURCES}
35+)
36
37=== modified file 'plugins/cellular/Components/MultiSim.qml'
38--- plugins/cellular/Components/MultiSim.qml 2014-08-19 23:24:04 +0000
39+++ plugins/cellular/Components/MultiSim.qml 2014-10-09 14:10:12 +0000
40@@ -33,7 +33,7 @@
41 property var settings: phoneSettings
42
43 CellularMultiSim {
44- anchors { left: parent.left; right: parent.right }
45+ anchors { left: parent.left; right: parent.right }
46 }
47
48 ListItem.Divider {}
49@@ -79,13 +79,13 @@
50 ListItem.Divider {}
51
52 SimEditor {
53- anchors { left: parent.left; right: parent.right }
54+ anchors { left: parent.left; right: parent.right }
55 }
56
57 ListItem.Divider {}
58
59 DefaultSim {
60- anchors { left: parent.left; right: parent.right }
61+ anchors { left: parent.left; right: parent.right }
62 }
63
64 GSettings {
65@@ -99,7 +99,7 @@
66 if (!simNames[m0]) {
67 simNames[m0] = "SIM 1";
68 }
69- if (!simNames[m1]) {
70+ if (!simNames[m1]) {
71 simNames[m1] = "SIM 2";
72 }
73 phoneSettings.simNames = simNames;
74
75=== modified file 'plugins/cellular/Components/SingleSim.qml'
76--- plugins/cellular/Components/SingleSim.qml 2014-08-22 10:53:16 +0000
77+++ plugins/cellular/Components/SingleSim.qml 2014-10-09 14:10:12 +0000
78@@ -28,10 +28,10 @@
79 property var sim
80
81 CellularSingleSim {
82- anchors { left: parent.left; right: parent.right }
83+ anchors { left: parent.left; right: parent.right }
84 }
85
86- ListItem.Divider {}
87+ ListItem.Divider {}
88
89 ListItem.SingleValue {
90 text : i18n.tr("Hotspot disabled because Wi-Fi is off.")
91@@ -60,9 +60,10 @@
92 objectName: "chooseCarrier"
93 progression: enabled
94 value: sim.netReg.name || i18n.tr("N/A")
95+ enabled: sim.netReg.status !== ""
96 onClicked: {
97 pageStack.push(Qt.resolvedUrl("../PageChooseCarrier.qml"), {
98- netReg: sim.netReg,
99+ sim: sim,
100 title: i18n.tr("Carrier")
101 })
102 }
103
104=== added file 'plugins/cellular/CustomApnEditor.qml'
105--- plugins/cellular/CustomApnEditor.qml 1970-01-01 00:00:00 +0000
106+++ plugins/cellular/CustomApnEditor.qml 2014-10-09 14:10:12 +0000
107@@ -0,0 +1,326 @@
108+/*
109+ * This file is part of system-settings
110+ *
111+ * Copyright (C) 2014 Canonical Ltd.
112+ *
113+ * Contact: Pat McGowan <pat.mcgowan@canonical.com>
114+ *
115+ * This program is free software: you can redistribute it and/or modify it
116+ * under the terms of the GNU General Public License version 3, as published
117+ * by the Free Software Foundation.
118+ *
119+ * This program is distributed in the hope that it will be useful, but
120+ * WITHOUT ANY WARRANTY; without even the implied warranties of
121+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
122+ * PURPOSE. See the GNU General Public License for more details.
123+ *
124+ * You should have received a copy of the GNU General Public License along
125+ * with this program. If not, see <http://www.gnu.org/licenses/>.
126+ */
127+
128+import QtQuick 2.0
129+import QtQuick.Layouts 1.1
130+import SystemSettings 1.0
131+import Ubuntu.Components 1.1
132+import Ubuntu.Components.ListItems 1.0 as ListItem
133+
134+ItemPage {
135+ objectName: "customapnPage"
136+ id: root
137+
138+ // "internet" or "mms"
139+ property var type
140+
141+ // dict of "type" : ctx
142+ property var contexts;
143+
144+ /// work around LP(#1361919)
145+ property var activateCb;
146+
147+ QtObject {
148+ id: d
149+ property var typeText : type === "internet" ? i18n.tr("Internet") : i18n.tr("MMS")
150+ property bool isMms : type === "mms"
151+
152+ property bool isValid : false
153+
154+ function validateFields() {
155+ if (apnName.text === "") {
156+ isValid = false;
157+ return
158+ }
159+ if (isMms) {
160+ if (mmsc.text === "") {
161+ isValid = false;
162+ return;
163+ }
164+ /// @todo validate proxy
165+ /// @todo force port to be integer and validate it's value
166+ }
167+
168+ // @todo the rest
169+ isValid = true;
170+ }
171+ }
172+
173+ //TRANSLATORS: %1 is either i18n.tr("Internet") or i18n.tr("MMS")
174+ title: i18n.tr("Custom %1 APN").arg(d.typeText)
175+
176+ // workaround of getting the following error on startup:
177+ // WARNING - ... : QML Page: Binding loop detected for property "flickable"
178+ flickable: null
179+ Component.onCompleted: {
180+ flickable: scrollWidget
181+
182+ var ctx;
183+ if (d.isMms) {
184+ ctx = contexts["mms"];
185+ if (ctx === undefined) {
186+ // @bug LP(:#1362795)
187+ return;
188+ }
189+ } else {
190+ ctx = contexts["internet"]
191+ }
192+
193+ apnName.text = ctx.accessPointName;
194+ userName.text = ctx.username;
195+ pword.text = ctx.password;
196+ mmsc.text = ctx.messageCenter;
197+ var proxyText = ctx.messageProxy.split(":");
198+ proxy.text = proxyText[0] !== undefined ? proxyText[0] : "";
199+ port.text = proxyText[1] !== undefined ? proxyText[1] : "";
200+ /// @todo protocol values
201+
202+ if (d.isMms) {
203+ /// @todo disabled for now
204+ doBoth.checked = false;
205+ return;
206+ var internetApn = contexts["internet"]
207+ if (ctx.accessPointName === internetApn.accessPointName &&
208+ ctx.username == internetApn.username &&
209+ ctx.password == internetApn.password
210+ /* auth + procol */) {
211+ doBoth.checked = true;
212+ }
213+ else
214+ doBoth.checked = false;
215+ }
216+ }
217+
218+ Flickable {
219+ id: scrollWidget
220+ anchors {
221+ top: parent.top
222+ left: parent.left
223+ right: parent.right
224+ bottom: parent.bottom
225+ margins: units.gu(2)
226+ }
227+ contentWidth: parent.width
228+ clip: true
229+ contentHeight: theContents.height
230+ boundsBehavior: (contentHeight > height) ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
231+ flickableDirection: Flickable.VerticalFlick
232+
233+ ColumnLayout {
234+ id: theContents
235+ anchors {
236+ left: parent.left
237+ right: parent.right
238+ }
239+ spacing: units.gu(2)
240+
241+ ListItem.Standard {
242+ id: sameSwitch
243+ anchors {
244+ left: parent.left
245+ right: parent.right
246+ }
247+ /// @todo disable for now
248+ //visible: d.isMms
249+ visible: false
250+ text: i18n.tr("Same APN as for Internet")
251+ control: Switch {
252+ id: doBoth
253+ checked: false
254+ anchors.verticalCenter: parent.verticalCenter
255+ onClicked: {
256+ if (checked) {
257+ var internetApn = contexts["internet"]
258+ apnName.text = internetApn.accessPointName;
259+ userName.text = internetApn.username;
260+ pword.text = internetApn.password;
261+ }
262+ }
263+ }
264+ }
265+
266+ GridLayout {
267+ id: theGrid
268+ columns: 2
269+ columnSpacing: units.gu(1)
270+ rowSpacing: units.gu(1)
271+ anchors{
272+ right: parent.right
273+ left:parent.left
274+ }
275+
276+ Label {
277+ //TRANSLATORS: %1 is either i18n.tr("Internet") or i18n.tr("MMS")
278+ text: i18n.tr("%1 APN").arg(d.typeText)
279+ }
280+ TextField {
281+ id: apnName
282+ enabled: !doBoth.checked
283+ onTextChanged: d.validateFields()
284+ inputMethodHints: Qt.ImhUrlCharactersOnly | Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
285+ }
286+
287+ Label {
288+ text: i18n.tr("MMSC")
289+ visible: d.isMms
290+ }
291+ TextField {
292+ id: mmsc
293+ visible: d.isMms
294+ onTextChanged: d.validateFields()
295+ inputMethodHints: Qt.ImhUrlCharactersOnly | Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
296+ }
297+ Label {
298+ text: i18n.tr("Proxy")
299+ visible: d.isMms
300+ }
301+ TextField {
302+ id: proxy
303+ visible: d.isMms
304+ onTextChanged: d.validateFields()
305+ inputMethodHints: Qt.ImhUrlCharactersOnly | Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
306+ }
307+ Label {
308+ text: "Port"
309+ visible: d.isMms
310+ }
311+ TextField {
312+ id: port
313+ visible: d.isMms
314+ maximumLength: 4
315+ onTextChanged: d.validateFields()
316+ inputMethodHints: Qt.ImhDigitsOnly | Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
317+ }
318+
319+ Label {
320+ text: i18n.tr("Username")
321+ }
322+ TextField {
323+ id: userName
324+ enabled: !doBoth.checked
325+ inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
326+ }
327+
328+ Label {
329+ text: i18n.tr("Password")
330+ }
331+ TextField {
332+ id: pword
333+ enabled: !doBoth.checked
334+ inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
335+ }
336+ /// @todo support for ipv6 will be added after RTM
337+ }
338+
339+ Item {
340+ id: buttonRectangle
341+
342+ height: cancelButton.height + units.gu(2)
343+
344+ anchors {
345+ left: parent.left
346+ right: parent.right
347+ }
348+
349+ Button {
350+ id: cancelButton
351+
352+ text: i18n.tr("Cancel")
353+
354+ anchors {
355+ left: parent.left
356+ right: parent.horizontalCenter
357+ bottom: parent.bottom
358+ topMargin: units.gu(1)
359+ rightMargin: units.gu(1)
360+ bottomMargin: units.gu(1)
361+ }
362+
363+ onClicked: {
364+ pageStack.pop()
365+ }
366+ }
367+
368+ Button {
369+ id: confirmButton
370+
371+ text: d.isMms ? i18n.tr("Save") : i18n.tr("Activate")
372+
373+ anchors {
374+ left: parent.horizontalCenter
375+ right: parent.right
376+ bottom: parent.bottom
377+ topMargin: units.gu(1)
378+ leftMargin: units.gu(1)
379+ rightMargin: units.gu(4)
380+ bottomMargin: units.gu(1)
381+ }
382+
383+ enabled: d.isValid;
384+
385+ onClicked: {
386+ var ctx;
387+ if (d.isMms)
388+ ctx = contexts["mms"];
389+ else
390+ ctx = contexts["internet"];
391+
392+ /// @bug LP(:#1362795)
393+ if (d.isMms && ctx === undefined) {
394+ var mmsData = ({})
395+ mmsData["accessPointName"] = apnName.text;
396+ mmsData["username"] = userName.text;
397+ mmsData["password"] = pword.text;
398+ mmsData["messageCenter"] = mmsc.text
399+ var proxyValue = "";
400+ if (proxy.text !== "") {
401+ proxyValue = proxy.text;
402+ if (port.text !== "")
403+ proxyValue = proxyValue + ":" + port.text;
404+ }
405+ mmsData["messageProxy"] = proxyValue;
406+ activateCb("mms", undefined, mmsData);
407+ pageStack.pop();
408+ return;
409+ }
410+
411+ ctx.accessPointName = apnName.text;
412+ ctx.username = userName.text;
413+ ctx.password = pword.text;
414+ if (d.isMms) {
415+ ctx.messageCenter = mmsc.text;
416+ var proxyValue = "";
417+ if (proxy.text !== "") {
418+ proxyValue = proxy.text;
419+ if (port.text !== "")
420+ proxyValue = proxyValue + ":" + port.text;
421+ }
422+ ctx.messageProxy = proxyValue
423+ }
424+ /// @todo map protocol values
425+
426+ activateCb(ctx.type, ctx.contextPath);
427+ pageStack.pop();
428+ }
429+ }
430+ } // item for buttons
431+ } // the contents
432+ } // the flickable
433+}
434
435=== added file 'plugins/cellular/PageChooseApn.qml'
436--- plugins/cellular/PageChooseApn.qml 1970-01-01 00:00:00 +0000
437+++ plugins/cellular/PageChooseApn.qml 2014-10-09 14:10:12 +0000
438@@ -0,0 +1,610 @@
439+/*
440+ * This file is part of system-settings
441+ *
442+ * Copyright (C) 2014 Canonical Ltd.
443+ *
444+ * Contact: Pat McGowan <pat.mcgowan@canonical.com>
445+ *
446+ * This program is free software: you can redistribute it and/or modify it
447+ * under the terms of the GNU General Public License version 3, as published
448+ * by the Free Software Foundation.
449+ *
450+ * This program is distributed in the hope that it will be useful, but
451+ * WITHOUT ANY WARRANTY; without even the implied warranties of
452+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
453+ * PURPOSE. See the GNU General Public License for more details.
454+ *
455+ * You should have received a copy of the GNU General Public License along
456+ * with this program. If not, see <http://www.gnu.org/licenses/>.
457+ */
458+
459+import QtQuick 2.0
460+import SystemSettings 1.0
461+import Ubuntu.Components 1.1
462+import Ubuntu.Components.Popups 0.1
463+import Ubuntu.Components.ListItems 0.1 as ListItem
464+import MeeGo.QOfono 0.2
465+import Ubuntu.SystemSettings.Cellular 1.0
466+
467+ItemPage {
468+ id: root
469+ title: i18n.tr("APN")
470+ objectName: "apnPage"
471+
472+ property var sim
473+
474+ QtObject {
475+ id: d
476+
477+ // map of contextPath : connCtx
478+ property var mContexts: ({})
479+
480+ readonly property string mCustomContextNameInternet: "___ubuntu_custom_apn_internet"
481+ readonly property string mCustomContextNameMms: "___ubuntu_custom_apn_mms"
482+ property var mCustomContextInternet : undefined
483+ property var mCustomContextMms : undefined
484+
485+ // LP(:#1362795)
486+ property var pendingCustomMmsData : ({})
487+
488+ // suppress any actions that we don't want to take
489+ // when updating selectedIndexes, etc
490+ property bool __suppressActivation : true;
491+
492+ function isEmptyCustom (type, ctx)
493+ {
494+ /* OK, this sucks _hard_,
495+ * QOfono does not return the added context, so instead we have to "figure it out"
496+ * by looking for "contextAdded" for totally empty context with default Name values.
497+ * LP(#1361864)
498+ */
499+
500+ var targetName = "";
501+ var targetAccessPointName = "";
502+ if (type === "internet") {
503+ targetName = "Internet";
504+ targetAccessPointName = "";
505+ } else if (type == "mms") {
506+ targetName = "MMS";
507+ targetAccessPointName = "";
508+ }
509+
510+ if (ctx.type === type &&
511+ ctx.name === targetName &&
512+ ctx.accessPointName === targetAccessPointName)
513+ return true;
514+ return false;
515+ }
516+
517+ function updateContexts()
518+ {
519+ var tmp = sim.connMan.contexts.slice(0);
520+ var added = tmp.filter(function(i) {
521+ return mContexts[i] === undefined;
522+ });
523+ var removed = Object.keys(mContexts).filter(function(i) {
524+ return tmp.indexOf(i) === -1;
525+ })
526+
527+ removed.forEach(function(currentValue, index, array) {
528+ // just asserting to verify the logic
529+ // remove once proven functional
530+ // the exception gives a very nice log error message from QmlEngine and does not
531+ // have any side effects
532+ if (mContexts[currentValue] === undefined) {
533+ throw "updateContexts: removed is broken";
534+ }
535+
536+ if (mContexts[currentValue].name === mCustomContextNameInternet)
537+ mCustomContextInternet = undefined
538+ else if (mContexts[currentValue].name === mCustomContextNameMms)
539+ mCustomContextMms = undefined
540+
541+ mContexts[currentValue].destroy();
542+ delete mContexts[currentValue];
543+ });
544+
545+ added.forEach(function(currentValue, index, array) {
546+ // just asserting to verify the logic
547+ // remove once proven functional
548+ // the exception gives a very nice log error message from QmlEngine and does not
549+ // have any side effects
550+ if (mContexts[currentValue] !== undefined) {
551+ throw "updateContexts: added is broken";
552+ }
553+
554+ var ctx = connCtx.createObject(parent,
555+ {
556+ "contextPath": currentValue
557+ });
558+ mContexts[currentValue] = ctx;
559+
560+ if (isEmptyCustom("internet", ctx))
561+ {
562+ ctx.name = mCustomContextNameInternet;
563+ // name updates async, so return here and
564+ // have the buildLists() called from Context::onNameChanged
565+ return;
566+ } else if (isEmptyCustom("mms", ctx))
567+ {
568+ ctx.name = mCustomContextNameMms;
569+ ctx.accessPointName = pendingCustomMmsData["accessPointName"];
570+ ctx.username = pendingCustomMmsData["username"];
571+ ctx.password = pendingCustomMmsData["password"];
572+ ctx.messageCenter = pendingCustomMmsData["messageCenter"];
573+ ctx.messageProxy = pendingCustomMmsData["messageProxy"];
574+ pendingCustomMmsData = ({});
575+ // values update async, so return here and
576+ // have the buildLists() called from Context::onNameChanged
577+ return;
578+ }
579+ });
580+
581+ // just asserting to verify the logic
582+ // remove once proven functional
583+ // the exception gives a very nice log error message from QmlEngine and does not
584+ // have any side effects
585+ if (Object.keys(mContexts).length !== tmp.length) {
586+ throw "Object.keys(contexts).length !== tmp.length";
587+ }
588+ tmp.forEach(function(currentValue, index, array) {
589+ if (mContexts[currentValue] === undefined)
590+ throw "contexts[currentValue] === undefined";
591+ });
592+
593+ buildLists();
594+ }
595+
596+ // expects updateContexts() to have ran before executing.
597+ function checkAndCreateCustomContexts()
598+ {
599+ var customInternet = Object.keys(mContexts).filter(function (i) {
600+ var ctx = mContexts[i];
601+ return ctx.name === mCustomContextNameInternet ||
602+ isEmptyCustom("internet", ctx);
603+ });
604+ var customMms = Object.keys(mContexts).filter(function (i) {
605+ var ctx = mContexts[i];
606+ return ctx.name === mCustomContextNameMms ||
607+ isEmptyCustom("mms", ctx);
608+ });
609+
610+ // make sure there is only one context per type
611+ if (customInternet.length > 1) {
612+ customInternet.forEach(function(currentValue, index, array) {
613+ if (index === 0)
614+ return;
615+ sim.connMan.removeContext(currentValue);
616+ });
617+ }
618+ if (customMms.length > 1) {
619+ customMms.forEach(function(currentValue, index, array) {
620+ if (index === 0)
621+ return;
622+ sim.connMan.removeContext(currentValue);
623+ });
624+ }
625+
626+ if (customInternet.length === 0) {
627+ sim.connMan.addContext("internet");
628+ }
629+
630+ // @bug don't create the custom MMS context
631+ // LP(:#1362795)
632+ // if (customMms.length === 0) {
633+ // sim.connMan.addContext("mms");
634+ // }
635+
636+ buildLists();
637+ }
638+
639+ property var mInternetApns : [];
640+ property var mMmsApns : [];
641+ function buildLists()
642+ {
643+ d.__suppressActivation = true;
644+
645+ var internet = [];
646+ var mms = [];
647+
648+ internet = Object.keys(mContexts).filter(function(i) {
649+ var ctx = mContexts[i];
650+ if (ctx.type === "internet") {
651+ if (ctx.name === mCustomContextNameInternet) {
652+ mCustomContextInternet = ctx
653+ // don't add yet
654+ return false;
655+ }
656+ return true;
657+ }
658+ return false;
659+ });
660+ mms = Object.keys(mContexts).filter(function(i) {
661+ var ctx = mContexts[i];
662+ if ( ctx.type === "mms") {
663+ if (ctx.name === mCustomContextNameMms) {
664+ mCustomContextMms = ctx;
665+ // don't add yet
666+ return false;
667+ }
668+ return true;
669+ }
670+ return false;
671+ });
672+
673+ // make sure customized are the last on the lists
674+ if (mCustomContextInternet !== undefined)
675+ internet = internet.concat([mCustomContextInternet.contextPath])
676+ if (mCustomContextMms !== undefined)
677+ mms = mms.concat([mCustomContextMms.contextPath])
678+ else {
679+ /// @bug LP(#1361864)
680+ // add anyway a "dummy" Custom so we can show at least the one provisioned
681+ // MMS context as long as the user does not hit "Custom" in the MMS list.
682+ mms = mms.concat(["dummycustom"])
683+ }
684+
685+ // add "Same APN as for Internet" to be the first on the MMS list
686+ mms = ["/same/as/internet"].concat(mms);
687+
688+ mInternetApns = internet;
689+ mMmsApns = mms;
690+
691+ d.__suppressActivation = false;
692+ }
693+
694+ function openApnEditor(type) {
695+ var ctx;
696+ if (type === "internet") {
697+ ctx = mCustomContextInternet;
698+ } else if (type == "mms") {
699+ ctx = mCustomContextMms;
700+ }
701+ /// can't modify active context
702+ if (ctx !== undefined && ctx.active)
703+ ctx.active = false;
704+
705+ pageStack.push(Qt.resolvedUrl("CustomApnEditor.qml"),
706+ {
707+ type: type,
708+ contexts: {"internet": mCustomContextInternet,
709+ "mms": mCustomContextMms},
710+ activateCb: activateHelper
711+ });
712+ }
713+
714+ function activateHelper(type, contextPath, customMmsData) {
715+ if (type === "internet") {
716+ activator.activate(contextPath, sim.simMng.subscriberIdentity, sim.simMng.modemPath)
717+ }
718+ else if (type === "mms") {
719+ if (contextPath === undefined) {
720+ // LP(:#1362795)
721+ pendingCustomMmsData = customMmsData
722+ /// remove any provisioned ones..
723+ var remove = []
724+ Object.keys(mContexts).forEach(function(currentValue, index, array) {
725+ var ctx = mContexts[currentValue];
726+ if (ctx.type === "mms")
727+ remove = remove.concat([ctx.contextPath])
728+ });
729+ remove.forEach(function(currentValue, index, array) {
730+ sim.connMan.removeContext(currentValue);
731+ });
732+ sim.connMan.addContext("mms")
733+ }
734+ } else {
735+ // somebody is calling the function wrong
736+ // the exception gives a very nice log error message from QmlEngine and does not
737+ // have any side effects
738+ throw "activateHelper: bad data: type: " + type + ", contextPath: " + contextPath + ", customMmsData: " + customMmsData;
739+ }
740+ }
741+ }
742+
743+ OfonoActivator {
744+ id:activator
745+ }
746+
747+ Component {
748+ id: connCtx
749+ OfonoContextConnection {
750+
751+ // add helper property to detect dual internet/MMS contexts
752+ property bool dual : false
753+ Component.onCompleted:{
754+ if (type == "internet")
755+ if (messageCenter !== "")
756+ dual = true
757+ }
758+
759+ onActiveChanged: if (type === "internet") internetApnSelector.updateSelectedIndex()
760+ onNameChanged: d.buildLists()
761+ onAccessPointNameChanged: d.buildLists()
762+ onReportError: console.error("Context error on " + contextPath + ": " + errorString)
763+ }
764+ }
765+
766+ Connections {
767+ target: sim.connMan
768+ onContextsChanged: d.updateContexts()
769+
770+ Component.onCompleted: {
771+ d.updateContexts();
772+
773+
774+ /// @todo workaround the work around that the UI currently only supports max. 1 MMS context
775+ /// remove once nuntium stuff is implemented
776+ // remove all but one MMS context
777+ var mms = Object.keys(d.mContexts).filter(function(i) {
778+ var ctx = d.mContexts[i]
779+ if (ctx.type === "mms")
780+ return true;
781+ return false;
782+ });
783+ mms = mms.slice(1);
784+ mms.forEach(function(currentValue, index, array) {
785+ sim.connMan.removeContext(currentValue);
786+ });
787+
788+
789+ // do this once.
790+ d.checkAndCreateCustomContexts();
791+ }
792+ }
793+
794+ Flickable {
795+ id: scrollWidget
796+ anchors.fill: parent
797+ contentHeight: contentItem.childrenRect.height
798+ boundsBehavior: (contentHeight > root.height) ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
799+ flickableDirection: Flickable.VerticalFlick
800+
801+ Column {
802+ anchors {
803+ left: parent.left
804+ right: parent.right
805+ }
806+
807+ ListItem.Standard {
808+ id: heading1
809+ objectName: "internetapn"
810+ text: i18n.tr("Internet APN:")
811+ progression: false
812+ }
813+ ListItem.ThinDivider {}
814+ ListItem.SingleControl {
815+ control: ListItem.ItemSelector {
816+ id: internetApnSelector
817+ width: parent.width - units.gu(4)
818+ model: d.mInternetApns
819+ expanded: true
820+ selectedIndex: -1
821+ onModelChanged: updateSelectedIndex()
822+
823+ function updateSelectedIndex()
824+ {
825+ var tmp = d.__suppressActivation
826+ d.__suppressActivation = true;
827+ var idx = -1;
828+ if (model) {
829+ model.forEach(function(currentValue, index, array) {
830+ if (d.mContexts[currentValue].active)
831+ idx = index;
832+ });
833+ }
834+ selectedIndex = idx;
835+ d.__suppressActivation = tmp;
836+ }
837+
838+ delegate: OptionSelectorDelegate {
839+ showDivider: false
840+ text: {
841+ var ctx = d.mContexts[modelData];
842+ if (ctx.name !== "") {
843+ if (ctx.name !== d.mCustomContextNameInternet) {
844+ return ctx.name
845+ } else {
846+ //: user visible name of the custom Internet APN
847+ return i18n.tr("Custom");
848+ }
849+ } else {
850+ return ctx.accessPointName
851+ }
852+ }
853+ }
854+ onSelectedIndexChanged: {
855+ if (selectedIndex === -1) {
856+ if (mmsApnSelector && mmsApnSelector.model[mmsApnSelector.selectedIndex] === "/same/as/internet")
857+ mmsApnSelector.selectedIndex = -1;
858+ return;
859+ }
860+
861+ var ctx = d.mContexts[model[selectedIndex]];
862+ if(ctx.dual) {
863+ if (!d.mCustomContextMms)
864+ mmsApnSelector.selectedIndex = mmsApnSelector.model.indexOf("/same/as/internet");
865+ }
866+ else if (mmsApnSelector.model[mmsApnSelector.selectedIndex] === "/same/as/internet")
867+ mmsApnSelector.selectedIndex = -1;
868+
869+ if (d.__suppressActivation)
870+ return;
871+
872+ if (d.mCustomContextInternet && model[selectedIndex] === d.mCustomContextInternet.contextPath) {
873+ if (d.mCustomContextInternet.accessPointName === "") {
874+ d.openApnEditor("internet");
875+ updateSelectedIndex();
876+ return;
877+ }
878+ }
879+
880+ d.activateHelper("internet", ctx.contextPath);
881+ }
882+ }
883+ }
884+ ListItem.SingleControl {
885+ control: Button {
886+ objectName: "customApnEdit"
887+ text: i18n.tr("Custom Internet APN…")
888+ width: parent.width - units.gu(4)
889+ onClicked: d.openApnEditor("internet")
890+ }
891+ }
892+
893+ ListItem.Divider {}
894+
895+ ListItem.Standard {
896+ id: heading2
897+ objectName: "mmsapn"
898+ text: i18n.tr("MMS APN:")
899+ progression: false
900+ }
901+ ListItem.ThinDivider {}
902+ ListItem.SingleControl {
903+ control: ListItem.ItemSelector {
904+ id: mmsApnSelector
905+ width: parent.width - units.gu(4)
906+ model: d.mMmsApns
907+ expanded: true
908+ selectedIndex: -1
909+ delegate: OptionSelectorDelegate {
910+ showDivider: modelData === "/same/as/internet"
911+ enabled: {
912+ if (modelData !== "/same/as/internet")
913+ return true;
914+ else {
915+ var tmp = d.mContexts[internetApnSelector.model[internetApnSelector.selectedIndex]]
916+ return tmp === undefined ? false : tmp.dual
917+ }
918+ }
919+ // work around OptionSelectorDelegate not having a visual change depending on being disabled
920+ opacity: enabled ? 1.0 : 0.5
921+ text: {
922+ if (modelData === "/same/as/internet") {
923+ return i18n.tr("Same APN as for Internet");
924+ }
925+ if (modelData === "dummycustom") {
926+ return i18n.tr("Custom");
927+ }
928+ var ctx = d.mContexts[modelData];
929+ if (ctx.name !== "") {
930+ if (ctx.name !== d.mCustomContextNameMms) {
931+ return ctx.name
932+ } else {
933+ //: user visible name of the custom MMS APN
934+ return i18n.tr("Custom");
935+ }
936+ } else {
937+ return ctx.accessPointName
938+ }
939+ }
940+ }
941+ onModelChanged: updateSelectedIndex();
942+ function updateSelectedIndex()
943+ {
944+ // if we have custom MMS context, it must be active.
945+ // @bug LP(#1361864)
946+ var tmp = d.__suppressActivation;
947+ d.__suppressActivation = true;
948+ if (d.mCustomContextMms) {
949+ selectedIndex = model.indexOf(d.mCustomContextMms.contextPath);
950+ } else if (model.length === 3) {
951+ /* meaning we have:
952+ * 0 - /same/as/internet
953+ * 1 - some provisioned one
954+ * 2 - dummycustom
955+ */
956+ selectedIndex = 1;
957+ } else if (internetApnSelector.model && internetApnSelector.selectedIndex !== -1) {
958+ if (d.mContexts[internetApnSelector.model[internetApnSelector.selectedIndex]].dual) {
959+ selectedIndex = model.indexOf("/same/as/internet");
960+ } else
961+ selectedIndex = -1;
962+ } else {
963+ selectedIndex = -1;
964+ }
965+ d.__suppressActivation = tmp;
966+ }
967+
968+ onSelectedIndexChanged: {
969+ if (selectedIndex === -1 || d.__suppressActivation)
970+ return;
971+
972+ if (model[selectedIndex] === "/same/as/internet") {
973+ // @bug delete _any_ actual MMS context
974+ // LP:(#1362795)
975+ var remove = [];
976+ Object.keys(d.mContexts).forEach(function(currentValue, index, array) {
977+ var ctx = d.mContexts[currentValue];
978+ if (ctx.type === "mms")
979+ remove = remove.concat([ctx.contextPath]);
980+ });
981+ remove.forEach(function(currentValue, index, array) {
982+ sim.connMan.removeContext(currentValue);
983+ });
984+ return;
985+ }
986+
987+ if (model[selectedIndex] === "dummycustom") {
988+ d.openApnEditor("mms");
989+ updateSelectedIndex()
990+ return;
991+ }
992+
993+ // no need to "activate" anything.
994+ // just fall through return here.
995+ // once we actually are able to suppport multiple MMS contexts
996+ // on the system, add some code here to set one of them active
997+ }
998+ }
999+ }
1000+ ListItem.SingleControl {
1001+ control: Button {
1002+ objectName: "customApnEdit"
1003+ text: i18n.tr("Custom MMS APN…")
1004+ width: parent.width - units.gu(4)
1005+ onClicked: d.openApnEditor("mms")
1006+ }
1007+ }
1008+
1009+ // @todo: no means of doing any meaningful reset right now.
1010+ // LP(#1338758)
1011+ // ListItem.ThinDivider {}
1012+ // ListItem.SingleControl {
1013+ // control: Button {
1014+ // objectName: "resetButton"
1015+ // text: i18n.tr("Reset APN Settings")
1016+ // width: parent.width - units.gu(4)
1017+ // onClicked: {
1018+ // PopupUtils.open(resetDialog)
1019+ // }
1020+ // }
1021+ // }
1022+ }
1023+ }
1024+
1025+ Component {
1026+ id: resetDialog
1027+ Dialog {
1028+ id: dialogue
1029+ title: i18n.tr("Reset APN Settings")
1030+ text: i18n.tr("Are you sure that you want to Reset APN Settings?")
1031+ Button {
1032+ text: i18n.tr("Cancel")
1033+ onClicked: PopupUtils.close(dialogue)
1034+ }
1035+ Button {
1036+ text: i18n.tr("Reset")
1037+ color: UbuntuColors.orange
1038+ onClicked: {
1039+ // delete all APNs
1040+ // kick ofono per
1041+ // https://bugs.launchpad.net/ubuntu/+source/ofono/+bug/1338758
1042+
1043+ }
1044+ }
1045+
1046+ }
1047+ }
1048+}
1049
1050=== modified file 'plugins/cellular/PageChooseCarrier.qml'
1051--- plugins/cellular/PageChooseCarrier.qml 2014-07-24 19:00:45 +0000
1052+++ plugins/cellular/PageChooseCarrier.qml 2014-10-09 14:10:12 +0000
1053@@ -19,55 +19,103 @@
1054 */
1055
1056 import QtQuick 2.0
1057+import QtQuick.Layouts 1.1
1058 import SystemSettings 1.0
1059-import Ubuntu.Components 0.1
1060-import Ubuntu.Components.ListItems 0.1 as ListItem
1061+import Ubuntu.Components 1.1
1062+import Ubuntu.Components.ListItems 1.0 as ListItem
1063 import MeeGo.QOfono 0.2
1064
1065 ItemPage {
1066- title: title
1067+ id: root
1068+ title: i18n.tr("Carrier")
1069+
1070 objectName: "chooseCarrierPage"
1071
1072- property var netReg
1073- property var operators: []
1074- property bool scanning: false
1075+ property var sim
1076+
1077 property variant operatorNames
1078- property variant operatorStatus
1079- property int curOp
1080- Component.onCompleted: buildLists();
1081+ property int mode
1082+
1083+ QtObject {
1084+ id: d
1085+ property bool __suppressActivation : true;
1086+ }
1087+
1088+ Component.onCompleted: {
1089+ updateNetworkOperators();
1090+ }
1091
1092 Connections {
1093- target: netReg
1094- onStatusChanged: {
1095- if (netReg.status === "registered")
1096- buildLists();
1097- }
1098- onNetworkOperatorsChanged: buildLists();
1099- onScanFinished: scanning = false;
1100- onScanError: {
1101- scanning = false;
1102- console.warn ("onScanError: " + message);
1103- }
1104+ target: sim.netReg
1105+ onNetworkOperatorsChanged: updateNetworkOperators();
1106+ onCurrentOperatorPathChanged: buildLists();
1107+ }
1108+
1109+ // map of operatorPath : netOp
1110+ property var operators: ({})
1111+ function updateNetworkOperators()
1112+ {
1113+ var tmp = sim.netReg.networkOperators;
1114+ var added = tmp.filter(function(i) {
1115+ return operators[i] === undefined;
1116+ });
1117+ var removed = Object.keys(operators).filter(function(i) {
1118+ return tmp.indexOf(i) === -1;
1119+ })
1120+
1121+ removed.forEach(function(currentValue, index, array) {
1122+ // just asserting to verify the logic
1123+ // remove once proven functional
1124+ if (operators[currentValue] === undefined) {
1125+ throw "updateNetworkOperators: removed is broken";
1126+ }
1127+
1128+ operators[currentValue].destroy();
1129+ delete operators[currentValue];
1130+ });
1131+
1132+ added.forEach(function(currentValue, index, array) {
1133+ // just asserting to verify the logic
1134+ // remove once proven functional
1135+ if (operators[currentValue] !== undefined) {
1136+ throw "updateNetworkOperators: added is broken";
1137+ }
1138+
1139+ operators[currentValue] = netOp.createObject(parent,
1140+ {
1141+ "operatorPath": currentValue
1142+ });
1143+ });
1144+
1145+ // just asserting to verify the logic
1146+ // remove once proven functional
1147+ if (Object.keys(operators).length !== tmp.length) {
1148+ throw "Object.keys(operators).length !== tmp.length";
1149+ }
1150+ tmp.forEach(function(currentValue, index, array) {
1151+ if (operators[currentValue] === undefined)
1152+ throw "operators[currentValue] === undefined";
1153+ });
1154+
1155+ buildLists();
1156 }
1157
1158 function buildLists()
1159 {
1160- var ops = [];
1161+ d.__suppressActivation = true;
1162 var oN = new Array();
1163- var oS = new Array();
1164- for (var i = 0; i < netReg.networkOperators.length; i++) {
1165- var tempOp = netOp.createObject(parent, {"operatorPath": netReg.networkOperators[i]});
1166+
1167+ for (var i in operators) {
1168+ var tempOp = operators[i];
1169 if (tempOp.status === "forbidden")
1170 continue
1171 oN.push(tempOp.name);
1172- oS.push(tempOp.status);
1173- ops.push(tempOp)
1174 }
1175- curOp = oS.indexOf("current");
1176 operatorNames = oN;
1177- operatorStatus = oS;
1178- operators = ops;
1179- carrierSelector.selectedIndex = curOp;
1180+
1181+ var cur = operators[sim.netReg.currentOperatorPath];
1182+ carrierSelector.selectedIndex = cur === undefined ? -1 : operatorNames.indexOf(cur.name);
1183+ d.__suppressActivation = false;
1184 }
1185
1186 Component {
1187@@ -78,78 +126,113 @@
1188 console.warn("registerComplete failed with error: " + errorString);
1189 } else if (error !== OfonoNetworkOperator.NoError) {
1190 console.warn("registerComplete failed with error: " + errorString + " Falling back to default");
1191- netReg.registration();
1192+ sim.netReg.registration();
1193 }
1194 }
1195+ onNameChanged: buildLists();
1196+ onStatusChanged: buildLists();
1197 }
1198 }
1199
1200 Flickable {
1201+ id: scrollWidget
1202 anchors.fill: parent
1203 contentWidth: parent.width
1204 contentHeight: parent.height
1205 boundsBehavior: (contentHeight > parent.height) ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
1206
1207- Column {
1208- anchors.left: parent.left
1209- anchors.right: parent.right
1210+ ColumnLayout {
1211+ anchors {
1212+ left: parent.left
1213+ right: parent.right
1214+ }
1215
1216 ListItem.ItemSelector {
1217 id: chooseCarrier
1218 objectName: "autoChooseCarrierSelector"
1219 expanded: true
1220- enabled: netReg.mode !== "auto-only"
1221+ enabled: sim.netReg.mode !== "auto-only"
1222 text: i18n.tr("Choose carrier:")
1223 model: [i18n.tr("Automatically"), i18n.tr("Manually")]
1224- selectedIndex: netReg.mode === "manual" ? 1 : 0
1225+
1226+ delegate: OptionSelectorDelegate { showDivider: false }
1227+ selectedIndex: sim.netReg.mode === "manual" ? 1 : 0
1228+
1229+ // we only want to do this per user input
1230 onSelectedIndexChanged: {
1231- if (selectedIndex === 0)
1232- netReg.registration();
1233+ if (selectedIndex === -1 || d.__suppressActivation)
1234+ return;
1235+
1236+ if (selectedIndex === 0) {
1237+ sim.netReg.registration();
1238+ } else if (selectedIndex === 1) {
1239+ if (sim.netReg.status !== "searching")
1240+ sim.netReg.scan();
1241+ }
1242 }
1243 }
1244-
1245- ListItem.ItemSelector {
1246- id: carrierSelector
1247- objectName: "carrierSelector"
1248- expanded: enabled
1249+ ListItem.SingleControl {
1250 enabled: chooseCarrier.selectedIndex === 1
1251- model: operatorNames
1252- onSelectedIndexChanged: {
1253- if ((selectedIndex !== curOp) && operators[selectedIndex]) {
1254- operators[selectedIndex].registerOperator();
1255- }
1256- }
1257- }
1258- }
1259-
1260- ListItem.SingleControl {
1261- anchors.bottom: parent.bottom
1262- control: Button {
1263- objectName: "refreshButton"
1264- width: parent.width - units.gu(4)
1265- text: i18n.tr("Refresh")
1266- enabled: (netReg.status !== "searching") && (netReg.status !== "denied")
1267- onTriggered: {
1268- scanning = true;
1269- netReg.scan();
1270- }
1271- }
1272- }
1273-
1274- ActivityIndicator {
1275- id: activityIndicator
1276- anchors.centerIn: parent
1277- running: scanning
1278- }
1279-
1280- Label {
1281- anchors {
1282- top: activityIndicator.bottom
1283- topMargin: units.gu(2)
1284- horizontalCenter: activityIndicator.horizontalCenter
1285- }
1286- text: i18n.tr("Searching")
1287- visible: activityIndicator.running
1288+ anchors {
1289+ left: parent.left
1290+ leftMargin: units.gu(0)
1291+ }
1292+ control: ColumnLayout {
1293+ id: child
1294+ width: parent.width - units.gu(4)
1295+ anchors.left: parent.left
1296+ RowLayout {
1297+ id: searchingRow
1298+ spacing: units.gu(1)
1299+
1300+ visible: sim.netReg.status === "searching"
1301+ ActivityIndicator {
1302+ id: activityIndicator
1303+ anchors.verticalCenter: parent.verticalCenter
1304+ running: parent.visible
1305+ }
1306+ Label {
1307+ anchors.verticalCenter: parent.verticalCenter
1308+ text: i18n.tr("Searching for carriers…")
1309+ }
1310+ }
1311+ ListItem.ItemSelector {
1312+ id: carrierSelector
1313+ objectName: "carrierSelector"
1314+ expanded: true
1315+ enabled: sim.netReg.status !== "searching" && chooseCarrier.selectedIndex === 1
1316+ // work around ItemSelector not having a visual change depending on being disabled
1317+ opacity: enabled ? 1.0 : 0.5
1318+ width: parent.width
1319+ model: operatorNames
1320+ delegate: OptionSelectorDelegate { enabled: carrierSelector.enabled; showDivider: false }
1321+ onSelectedIndexChanged: {
1322+ if (selectedIndex === -1 || d.__suppressActivation)
1323+ return;
1324+
1325+ // this assumes operator names are unique,
1326+ // revise if not so
1327+ for (var op in operators) {
1328+ if (operators[op].name === operatorNames[selectedIndex]) {
1329+ operators[op].registerOperator();
1330+ return;
1331+ }
1332+ }
1333+ // just asserting to verify the logic
1334+ // remove once proven functional
1335+ throw "should not be reached.";
1336+ }
1337+ }
1338+ }
1339+ }
1340+ ListItem.Standard {
1341+ text: i18n.tr("APN")
1342+ progression: true
1343+ enabled: sim.connMan.powered
1344+ onClicked: {
1345+ pageStack.push(Qt.resolvedUrl("PageChooseApn.qml"), {sim: sim})
1346+ }
1347+ }
1348 }
1349 }
1350 }
1351
1352=== modified file 'plugins/cellular/PageChooseCarriers.qml'
1353--- plugins/cellular/PageChooseCarriers.qml 2014-08-17 14:50:51 +0000
1354+++ plugins/cellular/PageChooseCarriers.qml 2014-10-09 14:10:12 +0000
1355@@ -21,7 +21,6 @@
1356 import SystemSettings 1.0
1357 import Ubuntu.Components 0.1
1358 import Ubuntu.Components.ListItems 0.1 as ListItem
1359-import MeeGo.QOfono 0.2
1360
1361 ItemPage {
1362 id: root
1363@@ -47,10 +46,11 @@
1364 ListItem.SingleValue {
1365 objectName: "chooseCarrierSim1"
1366 value: sims[0].netReg.name ? sims[0].netReg.name : i18n.tr("N/A")
1367+ enabled: sims[0].netReg.status !== ""
1368 progression: true
1369 onClicked: {
1370 pageStack.push(Qt.resolvedUrl("PageChooseCarrier.qml"), {
1371- netReg: sims[0].netReg,
1372+ sim: sims[0],
1373 title: sims[0].title
1374 })
1375 }
1376@@ -63,10 +63,11 @@
1377 ListItem.SingleValue {
1378 objectName: "chooseCarrierSim2"
1379 value: sims[1].netReg.name ? sims[1].netReg.name : i18n.tr("N/A")
1380+ enabled: sims[1].netReg.status !== ""
1381 progression: true
1382 onClicked: {
1383 pageStack.push(Qt.resolvedUrl("PageChooseCarrier.qml"), {
1384- netReg: sims[1].netReg,
1385+ sim: sims[1],
1386 title: sims[1].title
1387 })
1388 }
1389
1390=== added file 'plugins/cellular/ofonoactivator.cpp'
1391--- plugins/cellular/ofonoactivator.cpp 1970-01-01 00:00:00 +0000
1392+++ plugins/cellular/ofonoactivator.cpp 2014-10-09 14:10:12 +0000
1393@@ -0,0 +1,132 @@
1394+/*
1395+ * Copyright (C) 2014 Canonical, Ltd.
1396+ *
1397+ * Authors:
1398+ * Jussi Pakkanen <jussi.pakkanen@canonical.com>
1399+ *
1400+ * This program is free software: you can redistribute it and/or modify it
1401+ * under the terms of the GNU General Public License version 3, as published
1402+ * by the Free Software Foundation.
1403+ *
1404+ * This library is distributed in the hope that it will be useful, but WITHOUT
1405+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1406+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
1407+ * details.
1408+ *
1409+ * You should have received a copy of the GNU General Public License
1410+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1411+ */
1412+
1413+#include "ofonoactivator.h"
1414+
1415+#include"nm_manager_proxy.h"
1416+#include"nm_settings_proxy.h"
1417+#include"nm_settings_connection_proxy.h"
1418+#include<QCoreApplication>
1419+
1420+typedef QMap<QString,QVariantMap> Vardict;
1421+Q_DECLARE_METATYPE(Vardict)
1422+
1423+namespace {
1424+
1425+QString nmService("org.freedesktop.NetworkManager");
1426+QString nmSettingsPath("/org/freedesktop/NetworkManager/Settings");
1427+QString nmPath("/org/freedesktop/NetworkManager");
1428+
1429+QDBusObjectPath detectConnection(const QString &ofonoContext, const QString imsi) {
1430+ auto ofonoContextBase = ofonoContext.split('/').back();
1431+ auto target = "/" + imsi + "/" + ofonoContextBase;
1432+
1433+ OrgFreedesktopNetworkManagerSettingsInterface settings(nmService, nmSettingsPath,
1434+ QDBusConnection::systemBus());
1435+ auto reply = settings.ListConnections();
1436+ reply.waitForFinished();
1437+ if(!reply.isValid()) {
1438+ qWarning() << "Error getting connection list: " << reply.error().message() << "\n";
1439+ }
1440+ auto connections = reply.value(); // Empty list if failed.
1441+
1442+ for(const auto &c : connections) {
1443+ OrgFreedesktopNetworkManagerSettingsConnectionInterface connProxy(nmService,
1444+ c.path(), QDBusConnection::systemBus());
1445+ auto reply2 = connProxy.GetSettings();
1446+ reply2.waitForFinished();
1447+ if(!reply2.isValid()) {
1448+ qWarning() << "Error getting property: " << reply2.error().message() << "\n";
1449+ continue;
1450+ }
1451+ auto settings = reply2.value();
1452+ auto id = settings["connection"]["id"].toString();
1453+ if(id == target) {
1454+ return c;
1455+ }
1456+ }
1457+ return QDBusObjectPath("");
1458+}
1459+
1460+QDBusObjectPath detectDevice(const QString &modemPath) {
1461+ OrgFreedesktopNetworkManagerInterface nm(nmService, nmPath, QDBusConnection::systemBus());
1462+ auto reply = nm.GetDevices();
1463+ reply.waitForFinished();
1464+ auto devices = reply.value();
1465+
1466+ for(const auto &device : devices) {
1467+ QDBusInterface iface(nmService, device.path(), "org.freedesktop.DBus.Properties",
1468+ QDBusConnection::systemBus());
1469+ QDBusReply<QDBusVariant> ifaceReply = iface.call("Get",
1470+ "org.freedesktop.NetworkManager.Device", "Interface");
1471+ if(!ifaceReply.isValid()) {
1472+ qWarning() << "Error getting property: " << ifaceReply.error().message() << "\n";
1473+ continue;
1474+ }
1475+ auto devIface = ifaceReply.value().variant().toString();
1476+ if(devIface == modemPath) {
1477+ return device;
1478+ }
1479+ }
1480+ return QDBusObjectPath("");
1481+}
1482+}
1483+
1484+void activateOfono(QDBusObjectPath connection, QDBusObjectPath device)
1485+{
1486+ OrgFreedesktopNetworkManagerInterface nm(nmService, nmPath, QDBusConnection::systemBus());
1487+
1488+
1489+ /// @bug https://bugs.launchpad.net/ubuntu/+source/network-manager/+bug/1378102
1490+ /// This is a big and fat workaround for the above bug
1491+ // this is probably racy as well as we are not tracking the ActiveConnection to know
1492+ // when the Device has actually disconnected.
1493+ QDBusInterface dev_iface("org.freedesktop.NetworkManager",
1494+ device.path(),
1495+ "org.freedesktop.NetworkManager.Device",
1496+ nm.connection());
1497+ dev_iface.call("Disconnect");
1498+
1499+
1500+ nm.ActivateConnection(connection, device, QDBusObjectPath("/"));
1501+}
1502+
1503+OfonoActivator::OfonoActivator(QObject *parent) : QObject(parent) {
1504+ static bool isRegistered = false;
1505+ if(!isRegistered) {
1506+ qDBusRegisterMetaType<Vardict>();
1507+ isRegistered = true;
1508+ }
1509+}
1510+
1511+Q_INVOKABLE bool OfonoActivator::activate(const QString ofonoContext, const QString imsi, const QString modemPath)
1512+{
1513+ auto dev = detectDevice(modemPath);
1514+ if(dev.path() == "") {
1515+ qWarning() << "Could not detect device object to use for Ofono activation.\n";
1516+ return false;
1517+ }
1518+ auto conn = detectConnection(ofonoContext, imsi);
1519+ if(conn.path() == "") {
1520+ qWarning() << "Could not detect connection object to use for Ofono activation.\n";
1521+ return false;
1522+ }
1523+ activateOfono(conn, dev);
1524+ return true;
1525+}
1526
1527=== added file 'plugins/cellular/ofonoactivator.h'
1528--- plugins/cellular/ofonoactivator.h 1970-01-01 00:00:00 +0000
1529+++ plugins/cellular/ofonoactivator.h 2014-10-09 14:10:12 +0000
1530@@ -0,0 +1,42 @@
1531+/*
1532+ * Copyright (C) 2014 Canonical, Ltd.
1533+ *
1534+ * Authors:
1535+ * Jussi Pakkanen <jussi.pakkanen@canonical.com>
1536+ *
1537+ * This program is free software: you can redistribute it and/or modify it
1538+ * under the terms of the GNU General Public License version 3, as published
1539+ * by the Free Software Foundation.
1540+ *
1541+ * This library is distributed in the hope that it will be useful, but WITHOUT
1542+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1543+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
1544+ * details.
1545+ *
1546+ * You should have received a copy of the GNU General Public License
1547+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1548+ */
1549+
1550+#ifndef OFONO_ACTIVATOR
1551+#define OFONO_ACTIVATOR
1552+
1553+#include <QObject>
1554+
1555+/**
1556+ * For exposing ofono controls to qml.
1557+ */
1558+
1559+class OfonoActivator : public QObject {
1560+ Q_OBJECT
1561+
1562+public:
1563+ OfonoActivator(QObject *parent = nullptr);
1564+ ~OfonoActivator() {};
1565+
1566+ Q_INVOKABLE bool activate(const QString ofonoContext, const QString imsi, const QString modemPath);
1567+
1568+private:
1569+};
1570+
1571+
1572+#endif
1573
1574=== modified file 'plugins/cellular/plugin.cpp'
1575--- plugins/cellular/plugin.cpp 2014-07-23 13:44:31 +0000
1576+++ plugins/cellular/plugin.cpp 2014-10-09 14:10:12 +0000
1577@@ -20,11 +20,13 @@
1578 #include <QtQml>
1579 #include <QtQml/QQmlContext>
1580 #include "hotspotmanager.h"
1581+#include "ofonoactivator.h"
1582
1583 void BackendPlugin::registerTypes(const char *uri)
1584 {
1585 Q_ASSERT(uri == QLatin1String("Ubuntu.SystemSettings.Cellular"));
1586 qmlRegisterType<HotspotManager>(uri, 1, 0, "HotspotManager");
1587+ qmlRegisterType<OfonoActivator>(uri, 1, 0, "OfonoActivator");
1588 }
1589
1590 void BackendPlugin::initializeEngine(QQmlEngine *engine, const char *uri)

Subscribers

People subscribed via source and target branches