Merge lp:~ted/ubuntu-app-launch/snappy-backend-no-snap into lp:ubuntu-app-launch/16.10

Proposed by Ted Gould
Status: Merged
Approved by: Ted Gould
Approved revision: 371
Merged at revision: 252
Proposed branch: lp:~ted/ubuntu-app-launch/snappy-backend-no-snap
Merge into: lp:ubuntu-app-launch/16.10
Prerequisite: lp:~ted/ubuntu-app-launch/snappy-backend-no-find-discover
Diff against target: 1419 lines (+698/-265)
14 files modified
docs/index.rst (+11/-1)
libubuntu-app-launch/app-info.c (+6/-128)
libubuntu-app-launch/app-info.h (+0/-35)
libubuntu-app-launch/appid.h (+61/-0)
libubuntu-app-launch/application-impl-click.cpp (+109/-0)
libubuntu-app-launch/application-impl-click.h (+27/-0)
libubuntu-app-launch/application-impl-legacy.cpp (+102/-6)
libubuntu-app-launch/application-impl-legacy.h (+26/-0)
libubuntu-app-launch/application-impl-libertine.cpp (+97/-0)
libubuntu-app-launch/application-impl-libertine.h (+30/-0)
libubuntu-app-launch/application.cpp (+173/-51)
libubuntu-app-launch/registry.cpp (+1/-1)
libubuntu-app-launch/ubuntu-app-launch.cpp (+18/-11)
tests/libual-cpp-test.cc (+37/-32)
To merge this branch: bzr merge lp:~ted/ubuntu-app-launch/snappy-backend-no-snap
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
unity-api-1-bot continuous-integration Approve
Review via email: mp+302025@code.launchpad.net

This proposal supersedes a proposal from 2016-08-03.

Commit message

Make find and discover use the application implementation functions.

Description of the change

This MR migrates the the find and discover functions over to the C++ interfaces, and importantly pushes the implementation of the various parts into the implementation classes. This was done so that we can easily add implementations (say for snappy) and have it work to find/discover AppIDs correctly.

To post a comment you must log in.
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:352
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~ted/ubuntu-app-launch/snappy-backend-no-snap/+merge/301966/+edit-commit-message

https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/18/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/277/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/283
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/217
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/217
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/217
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/146/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/146/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/146/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/146/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/146/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/146/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/146/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/146/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/146/console

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/18/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:357
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/30/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/301/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/307
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/236
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/236
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/236
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/165/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/165/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/165/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/165/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/165/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/165/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/165/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/165/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/165/console

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/30/rebuild

review: Needs Fixing (continuous-integration)
358. By Ted Gould

Pull through OOM updates

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:358
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/51/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/379/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/385
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/302
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/302
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/302
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/232/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/232/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/232/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/232/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/232/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/232/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/232/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/232/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/232/console

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/51/rebuild

review: Needs Fixing (continuous-integration)
359. By Ted Gould

Fix legacy instance pull through

360. By Ted Gould

Updating to trunk

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:360
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/62/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/454/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/460
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/364
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/364
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/364
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/294/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/294/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/294/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/294/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/294/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/294/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/294/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/294/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/294/console

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/62/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

By some yardstick this was an easier review -- the code diff is smaller -- but I had a lot of questions about the type-specific methods.

Questions and comments inline

Revision history for this message
Ted Gould (ted) wrote :
Download full text (5.3 KiB)

On Wed, 2016-08-24 at 18:53 +0000, Charles Kerr wrote:
> By some yardstick this was an easier review -- the code diff is
> smaller -- but I had a lot of questions about the type-specific
> methods.

I think a lot of your questions came from not knowing the different
AppID schemes, which really means we didn't do a good job of
documenting that. So I tried to do that with narrative text on each of
the implementations: r363

> > +    if (apps.size() == 0)
> apps is a std::list<> so size() has to walk the list.
>
> Since size is used twice in this function (here and in ONLY_LISTED
> below) better to store it in a temporary.
>
> In general, better to say "if (!foo.empty())" than "if (foo.size() ==
> 0)"

List size is constant since C++11: http://en.cppreference.com/w/cpp/con
tainer/list/size

But yes, empty would look better. r364

> > +    switch (card)
> > +    {
> > +        case AppID::ApplicationWildcard::FIRST_LISTED:
> > +            return *apps.begin();
> > +        case AppID::ApplicationWildcard::LAST_LISTED:
> out-of-scope for this review, but as an aside, what's the use case
> for LAST_LISTED?

Added for completeness, seemed odd to have first and only but not last.
I think almost everyone uses first.

> > +    catch (std::runtime_error& e)
> > +    {
> > +        return false;
> does e.what need to be logged here? Looks like the answer is 'no' but
> wanted to be sure

No, it gets checked a fair amount and would be too chatty.

> +bool Legacy::verifyPackage(const AppID::Package& package, const
> > std::shared_ptr<Registry>& registry)
> > +{
> > +    return package.value().empty();
> (needinfo) Wait, whaaaat? Why would a function named verifyPackage()
> return true iff no package?

For Legacy apps the package field is empty.

> > +    std::string desktop = std::string(appname) + ".desktop";
> redundant type information, suggest auto on lhs
> > >
> > +    std::function<bool(const gchar* dir)> evaldir =
> > [&desktop](const gchar* dir) {
> redundant type information, suggest auto on lhs

r365

> > +AppID::Version Legacy::findVersion(const AppID::Package& package,
> > +                                   const AppID::AppName& appname,
> > +                                   const
> > std::shared_ptr<Registry>& registry)
> > +{
> > +    return AppID::Version::from_raw({});
> (needinfo) Why does findAppname() throw but findVersion() returns
> empty?

So my thought there was that if you're looking for the version, the
answer is always "", but we can't ever find an application, so that's
an error.

> > +/** Checks the AppID by making sure the version is "0.0" and then
> > +    calling verifyAppname() to check the rest.
> (needinfo) Same "whaaaat" as above, I think I'm missing some context
> here. I don't understand what this is for, nor why a 0.0 test is
> useful

All Libertine applications have a version string of "0.0".

Using it as a test to reject things quickly. Since basically our
algorithm is "try all implementations" we end up with wanting to reject
as much as possible.

> > +    catch (std::runtime_error& e)
> > +    {
> > +        return false;
> is this normal, or should e.what() be logged?

Normal.

> > +        auto container =...

Read more...

361. By Ted Gould

Bring in updates to no-find-discover branch

362. By Ted Gould

Fix abicheck

363. By Ted Gould

Write text explaining the app id schemes for the various backends

364. By Ted Gould

Use empty instead of checking the size

365. By Ted Gould

Going full auto

366. By Ted Gould

Removing a string cast

367. By Ted Gould

Spelling fix

368. By Ted Gould

Make sure we don't copy the tools structures

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:368
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/66/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/475/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/481
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/386
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/386
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/386
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/316/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/316
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/316/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/316
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/316/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/316/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/316
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/316/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/316
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/316/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/316/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/316
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/316/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/316
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/316/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/66/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Thanks for the changes, especially the extra explanations. :)

review: Approve
369. By Ted Gould

Grab changes and Jenkins fixes

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:369
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/79/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/506
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/512
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/417
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/417
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/417
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/347
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/347/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/347
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/347/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/347
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/347/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/347
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/347/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/347
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/347/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/347
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/347/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/347
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/347/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/347
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/347/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/347
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/347/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/79/rebuild

review: Approve (continuous-integration)
370. By Ted Gould

Getting some list bus love

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:370
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/83/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/512
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/518
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/423
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/423
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/423
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/353
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/353/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/353
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/353/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/353
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/353/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/353
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/353/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/353
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/353/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/353
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/353/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/353
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/353/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/353
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/353/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/353
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/353/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/83/rebuild

review: Approve (continuous-integration)
371. By Ted Gould

Merging trunk

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:371
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/93/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/563
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/569
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/397
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/397/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/397
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/397/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/397
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/397/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/397
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/397/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/397
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/397/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/397
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/397/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/397
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/397/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/397
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/397/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/397
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/397/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/93/rebuild

review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Reapprove to pick up r370

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'docs/index.rst'
--- docs/index.rst 2016-04-29 14:20:11 +0000
+++ docs/index.rst 2016-09-06 16:14:41 +0000
@@ -109,7 +109,7 @@
109Application Icon Finder109Application Icon Finder
110------------------------110------------------------
111111
112.. doxygenclass:: ubuntu::app_launch::app_info::IconFinder112.. doxygenclass:: ubuntu::app_launch::IconFinder
113 :project: libubuntu-app-launch113 :project: libubuntu-app-launch
114 :members:114 :members:
115 :protected-members:115 :protected-members:
@@ -146,6 +146,16 @@
146 :private-members:146 :private-members:
147 :undoc-members:147 :undoc-members:
148148
149Upstart Instance
150----------------
151
152.. doxygenclass:: ubuntu::app_launch::app_impls::UpstartInstance
153 :project: libubuntu-app-launch
154 :members:
155 :protected-members:
156 :private-members:
157 :undoc-members:
158
149Quality159Quality
150=======160=======
151161
152162
=== modified file 'libubuntu-app-launch/app-info.c'
--- libubuntu-app-launch/app-info.c 2016-09-06 16:14:40 +0000
+++ libubuntu-app-launch/app-info.c 2016-09-06 16:14:41 +0000
@@ -21,7 +21,9 @@
21#include <click.h>21#include <click.h>
2222
23#include "ubuntu-app-launch.h"23#include "ubuntu-app-launch.h"
24#include "app-info.h"24
25/* Prototypes */
26static gboolean app_info_libertine (const gchar * appid, gchar ** appdir, gchar ** appdesktop);
2527
26/* Try and get a manifest and do a couple sanity checks on it */28/* Try and get a manifest and do a couple sanity checks on it */
27static JsonObject *29static JsonObject *
@@ -76,130 +78,6 @@
76 return manifest;78 return manifest;
77}79}
7880
79/* Types of search we can do for an app name */
80enum _app_name_t {
81 APP_NAME_ONLY,
82 APP_NAME_FIRST,
83 APP_NAME_LAST
84};
85typedef enum _app_name_t app_name_t;
86
87/* Figure out the app name if it's one of the keywords */
88static const gchar *
89manifest_app_name (JsonObject ** manifest, const gchar * pkg, const gchar * original_app)
90{
91 app_name_t app_type = APP_NAME_FIRST;
92
93 if (original_app == NULL) {
94 /* first */
95 } else if (g_strcmp0(original_app, "first-listed-app") == 0) {
96 /* first */
97 } else if (g_strcmp0(original_app, "last-listed-app") == 0) {
98 app_type = APP_NAME_LAST;
99 } else if (g_strcmp0(original_app, "only-listed-app") == 0) {
100 app_type = APP_NAME_ONLY;
101 } else {
102 return original_app;
103 }
104
105 if (*manifest == NULL) {
106 *manifest = get_manifest(pkg, NULL);
107 }
108
109 JsonObject * hooks = json_object_get_object_member(*manifest, "hooks");
110
111 if (hooks == NULL) {
112 return NULL;
113 }
114
115 GList * apps = json_object_get_members(hooks);
116 if (apps == NULL) {
117 return NULL;
118 }
119
120 const gchar * retapp = NULL;
121
122 switch (app_type) {
123 case APP_NAME_ONLY:
124 if (g_list_length(apps) == 1) {
125 retapp = (const gchar *)apps->data;
126 }
127 break;
128 case APP_NAME_FIRST:
129 retapp = (const gchar *)apps->data;
130 break;
131 case APP_NAME_LAST:
132 retapp = (const gchar *)(g_list_last(apps)->data);
133 break;
134 default:
135 break;
136 }
137
138 g_list_free(apps);
139
140 return retapp;
141}
142
143/* Figure out the app version using the manifest */
144static const gchar *
145manifest_version (JsonObject ** manifest, const gchar * pkg, const gchar * original_ver)
146{
147 if (original_ver != NULL && g_strcmp0(original_ver, "current-user-version") != 0) {
148 return original_ver;
149 } else {
150 if (*manifest == NULL) {
151 *manifest = get_manifest(pkg, NULL);
152 }
153 g_return_val_if_fail(*manifest != NULL, NULL);
154
155 return g_strdup(json_object_get_string_member(*manifest, "version"));
156 }
157
158 return NULL;
159}
160
161/* A click triplet can require using the Click DB and getting a
162 manifest. This code does that to look up the versions */
163gchar *
164click_triplet_to_app_id (const gchar * pkg, const gchar * app, const gchar * ver)
165{
166 const gchar * version = NULL;
167 const gchar * application = NULL;
168 JsonObject * manifest = NULL;
169
170 version = manifest_version(&manifest, pkg, ver);
171 g_return_val_if_fail(version != NULL, NULL);
172
173 application = manifest_app_name(&manifest, pkg, app);
174 g_return_val_if_fail(application != NULL, NULL);
175
176 gchar * retval = g_strdup_printf("%s_%s_%s", pkg, application, version);
177
178 /* The object may hold allocation for some of our strings used above */
179 if (manifest)
180 json_object_unref(manifest);
181
182 return retval;
183}
184
185/* Build an appid how we think it should exist and then make sure
186 we can find it. Then pull it together. */
187gchar *
188libertine_triplet_to_app_id (const gchar * pkg, const gchar * app, const gchar * ver)
189{
190 if (app == NULL) {
191 return NULL;
192 }
193
194 gchar * synthappid = g_strdup_printf("%s_%s_0.0", pkg, app);
195 if (app_info_libertine(synthappid, NULL, NULL)) {
196 return synthappid;
197 } else {
198 g_free(synthappid);
199 return NULL;
200 }
201}
202
203/* Look to see if the app id results in a desktop file, if so, fill in the params */81/* Look to see if the app id results in a desktop file, if so, fill in the params */
204static gboolean82static gboolean
205evaluate_dir (const gchar * dir, const gchar * desktop, gchar ** appdir, gchar ** appdesktop)83evaluate_dir (const gchar * dir, const gchar * desktop, gchar ** appdir, gchar ** appdesktop)
@@ -224,7 +102,7 @@
224}102}
225103
226/* Handle the legacy case where we look through the data directories */104/* Handle the legacy case where we look through the data directories */
227gboolean105static gboolean
228app_info_legacy (const gchar * appid, gchar ** appdir, gchar ** appdesktop)106app_info_legacy (const gchar * appid, gchar ** appdir, gchar ** appdesktop)
229{107{
230 gchar * desktop = g_strdup_printf("%s.desktop", appid);108 gchar * desktop = g_strdup_printf("%s.desktop", appid);
@@ -248,7 +126,7 @@
248}126}
249127
250/* Handle the libertine case where we look in the container */128/* Handle the libertine case where we look in the container */
251gboolean129static gboolean
252app_info_libertine (const gchar * appid, gchar ** appdir, gchar ** appdesktop)130app_info_libertine (const gchar * appid, gchar ** appdir, gchar ** appdesktop)
253{131{
254 char * container = NULL;132 char * container = NULL;
@@ -301,7 +179,7 @@
301}179}
302180
303/* Get the information on where the desktop file is from libclick */181/* Get the information on where the desktop file is from libclick */
304gboolean182static gboolean
305app_info_click (const gchar * appid, gchar ** appdir, gchar ** appdesktop)183app_info_click (const gchar * appid, gchar ** appdir, gchar ** appdesktop)
306{184{
307 gchar * package = NULL;185 gchar * package = NULL;
308186
=== removed file 'libubuntu-app-launch/app-info.h'
--- libubuntu-app-launch/app-info.h 2016-06-07 01:49:09 +0000
+++ libubuntu-app-launch/app-info.h 1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Ted Gould <ted.gould@canonical.com>
18 */
19
20#pragma once
21
22#include <gio/gio.h>
23
24G_BEGIN_DECLS
25
26gboolean app_info_legacy (const gchar * appid, gchar ** appdir, gchar ** appdesktop);
27gboolean app_info_libertine (const gchar * appid, gchar ** appdir, gchar ** appdesktop);
28gboolean app_info_click (const gchar * appid, gchar ** appdir, gchar ** appdesktop);
29
30gchar * click_triplet_to_app_id (const gchar * pkg, const gchar * app, const gchar * ver);
31gchar * libertine_triplet_to_app_id (const gchar * pkg, const gchar * app, const gchar * ver);
32
33gboolean start_application_core (GDBusConnection * con, GCancellable * cancel, const gchar * appid, const gchar * const * uris, gboolean test);
34
35G_END_DECLS
360
=== modified file 'libubuntu-app-launch/appid.h'
--- libubuntu-app-launch/appid.h 2016-06-09 14:55:34 +0000
+++ libubuntu-app-launch/appid.h 2016-09-06 16:14:41 +0000
@@ -17,6 +17,7 @@
17 * Ted Gould <ted.gould@canonical.com>17 * Ted Gould <ted.gould@canonical.com>
18 */18 */
1919
20#include <memory>
20#include <string>21#include <string>
2122
22#include "type-tagger.h"23#include "type-tagger.h"
@@ -29,6 +30,8 @@
29namespace app_launch30namespace app_launch
30{31{
3132
33class Registry;
34
32/** \brief The set of information that is used to uniquely identify an35/** \brief The set of information that is used to uniquely identify an
33 application in Ubuntu.36 application in Ubuntu.
3437
@@ -104,9 +107,21 @@
104 It can be used, but is slower than parse() if you've got well formed data107 It can be used, but is slower than parse() if you've got well formed data
105 already.108 already.
106109
110 \note This will use the default registry instance, it is generally
111 recommended to have your own instead of using the default.
112
107 \param sappid String with the concatenated AppID113 \param sappid String with the concatenated AppID
108 */114 */
109 static AppID find(const std::string& sappid);115 static AppID find(const std::string& sappid);
116 /** Find is a more tollerant version of parse(), it handles legacy applications,
117 short AppIDs ($package_$app) and other forms of that are in common usage.
118 It can be used, but is slower than parse() if you've got well formed data
119 already.
120
121 \param registry Registry instance to use for persistant connections
122 \param sappid String with the concatenated AppID
123 */
124 static AppID find(const std::shared_ptr<Registry>& registry, const std::string& sappid);
110 /** Check to see whether a string is a valid AppID string125 /** Check to see whether a string is a valid AppID string
111126
112 \param sappid String with the concatenated AppID127 \param sappid String with the concatenated AppID
@@ -130,6 +145,9 @@
130 /** Find the AppID for an application where you only know the package145 /** Find the AppID for an application where you only know the package
131 name.146 name.
132147
148 \note This will use the default registry instance, it is generally
149 recommended to have your own instead of using the default.
150
133 \param package Name of the package151 \param package Name of the package
134 \param appwildcard Specification of how to search the manifest for apps152 \param appwildcard Specification of how to search the manifest for apps
135 \param versionwildcard Specification of how to search for the version153 \param versionwildcard Specification of how to search for the version
@@ -140,6 +158,9 @@
140 /** Find the AppID for an application where you know the package158 /** Find the AppID for an application where you know the package
141 name and application name.159 name and application name.
142160
161 \note This will use the default registry instance, it is generally
162 recommended to have your own instead of using the default.
163
143 \param package Name of the package164 \param package Name of the package
144 \param appname Name of the application165 \param appname Name of the application
145 \param versionwildcard Specification of how to search for the version166 \param versionwildcard Specification of how to search for the version
@@ -149,15 +170,55 @@
149 VersionWildcard versionwildcard = VersionWildcard::CURRENT_USER_VERSION);170 VersionWildcard versionwildcard = VersionWildcard::CURRENT_USER_VERSION);
150 /** Create an AppID providing known strings of packages and names171 /** Create an AppID providing known strings of packages and names
151172
173 \note This will use the default registry instance, it is generally
174 recommended to have your own instead of using the default.
175
152 \param package Name of the package176 \param package Name of the package
153 \param appname Name of the application177 \param appname Name of the application
154 \param version Version of the package178 \param version Version of the package
155 */179 */
156 static AppID discover(const std::string& package, const std::string& appname, const std::string& version);180 static AppID discover(const std::string& package, const std::string& appname, const std::string& version);
181
182 /** Find the AppID for an application where you only know the package
183 name.
184
185 \param registry Registry instance to use for persistant connections
186 \param package Name of the package
187 \param appwildcard Specification of how to search the manifest for apps
188 \param versionwildcard Specification of how to search for the version
189 */
190 static AppID discover(const std::shared_ptr<Registry>& registry,
191 const std::string& package,
192 ApplicationWildcard appwildcard = ApplicationWildcard::FIRST_LISTED,
193 VersionWildcard versionwildcard = VersionWildcard::CURRENT_USER_VERSION);
194 /** Find the AppID for an application where you know the package
195 name and application name.
196
197 \param registry Registry instance to use for persistant connections
198 \param package Name of the package
199 \param appname Name of the application
200 \param versionwildcard Specification of how to search for the version
201 */
202 static AppID discover(const std::shared_ptr<Registry>& registry,
203 const std::string& package,
204 const std::string& appname,
205 VersionWildcard versionwildcard = VersionWildcard::CURRENT_USER_VERSION);
206 /** Create an AppID providing known strings of packages and names
207
208 \param registry Registry instance to use for persistant connections
209 \param package Name of the package
210 \param appname Name of the application
211 \param version Version of the package
212 */
213 static AppID discover(const std::shared_ptr<Registry>& registry,
214 const std::string& package,
215 const std::string& appname,
216 const std::string& version);
157};217};
158218
159bool operator==(const AppID& a, const AppID& b);219bool operator==(const AppID& a, const AppID& b);
160bool operator!=(const AppID& a, const AppID& b);220bool operator!=(const AppID& a, const AppID& b);
221bool operator<(const AppID& a, const AppID& b);
161222
162} // namespace app_launch223} // namespace app_launch
163} // namespace ubuntu224} // namespace ubuntu
164225
=== modified file 'libubuntu-app-launch/application-impl-click.cpp'
--- libubuntu-app-launch/application-impl-click.cpp 2016-09-06 16:14:40 +0000
+++ libubuntu-app-launch/application-impl-click.cpp 2016-09-06 16:14:41 +0000
@@ -58,6 +58,115 @@
58 return _appid;58 return _appid;
59}59}
6060
61/** Check to see if this AppID has a desktop file that is in our link
62 farm built by Click. Click puts a symoblic link there for every
63 valid AppID.
64
65 \param appid Application ID to check
66 \param registry Persistent connections to use
67*/
68bool Click::hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry)
69{
70 std::string appiddesktop = std::string(appid) + ".desktop";
71 gchar* click_link = nullptr;
72 const gchar* link_farm_dir = g_getenv("UBUNTU_APP_LAUNCH_LINK_FARM");
73 if (G_LIKELY(link_farm_dir == nullptr))
74 {
75 click_link =
76 g_build_filename(g_get_user_cache_dir(), "ubuntu-app-launch", "desktop", appiddesktop.c_str(), NULL);
77 }
78 else
79 {
80 click_link = g_build_filename(link_farm_dir, appiddesktop.c_str(), NULL);
81 }
82
83 bool click = g_file_test(click_link, G_FILE_TEST_EXISTS);
84 g_free(click_link);
85
86 return click;
87}
88
89/** Tries to get the Click manifest for a package. If it can successfully
90 get the manifest returns true.
91
92 \param package Name of the package
93 \param registry Persistent connections to use
94*/
95bool Click::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry)
96{
97 return registry->impl->getClickManifest(package) != nullptr;
98}
99
100/** Verifies the applicaiton name by getting the list of applications
101 in the package manifest and seeing if the appname is in the list.
102
103 \param package Name of the package
104 \param appname Name of the application
105 \param registry Persistent connections to use
106*/
107bool Click::verifyAppname(const AppID::Package& package,
108 const AppID::AppName& appname,
109 const std::shared_ptr<Registry>& registry)
110{
111 auto manifest = registry->impl->getClickManifest(package);
112 auto apps = manifestApps(manifest);
113
114 return std::find_if(apps.begin(), apps.end(), [&appname](const AppID::AppName& listApp) -> bool {
115 return appname.value() == listApp.value();
116 }) != apps.end();
117}
118
119/** Finds an application name based on a wildcard search. Gets the list
120 from the manifest, and then returns a value from that list.
121
122 \param package Name of the package
123 \param card Wildcard to search as
124 \param registry Persistent connections to use
125*/
126AppID::AppName Click::findAppname(const AppID::Package& package,
127 AppID::ApplicationWildcard card,
128 const std::shared_ptr<Registry>& registry)
129{
130 auto manifest = registry->impl->getClickManifest(package);
131 auto apps = manifestApps(manifest);
132
133 if (apps.empty())
134 {
135 throw std::runtime_error("No apps in package '" + package.value() + "' to find");
136 }
137
138 switch (card)
139 {
140 case AppID::ApplicationWildcard::FIRST_LISTED:
141 return *apps.begin();
142 case AppID::ApplicationWildcard::LAST_LISTED:
143 return *apps.rbegin();
144 case AppID::ApplicationWildcard::ONLY_LISTED:
145 if (apps.size() != 1)
146 {
147 throw std::runtime_error("More than a single app in package '" + package.value() +
148 "' when requested to find only app");
149 }
150 return *apps.begin();
151 }
152
153 throw std::logic_error("Got a value of the app wildcard enum that can't exist");
154}
155
156/** Find the version of a package that that is requested
157
158 \param package Name of the package
159 \param appname Name of the application (not used)
160 \param registry Persistent connections to use
161*/
162AppID::Version Click::findVersion(const AppID::Package& package,
163 const AppID::AppName& appname,
164 const std::shared_ptr<Registry>& registry)
165{
166 auto manifest = registry->impl->getClickManifest(package);
167 return manifestVersion(manifest);
168}
169
61std::shared_ptr<Application::Info> Click::info()170std::shared_ptr<Application::Info> Click::info()
62{171{
63 if (!_info)172 if (!_info)
64173
=== modified file 'libubuntu-app-launch/application-impl-click.h'
--- libubuntu-app-launch/application-impl-click.h 2016-09-06 16:14:40 +0000
+++ libubuntu-app-launch/application-impl-click.h 2016-09-06 16:14:41 +0000
@@ -32,6 +32,20 @@
32namespace app_impls32namespace app_impls
33{33{
3434
35/** Application Implmentation for Click packages. Click packages
36 are installed via the click tool and have information avaialable
37 on them via libclick. There is one version per-user on the system
38 and a Ubuntu App Launch hook makes a link to each of those versions
39 in the user's cache directory. Click ensures this is up-to-date.
40
41 Application IDs for Click packages are the standard it was built on.
42 Typically a package name is "$(application).$(developer id)" though
43 there isn't a requirement in the local Click tools to require that. The
44 appname element is gotten from the JSON manifest in the Click package and
45 should reference a desktop file. All Click packages also have a version.
46
47 More info: http://click.readthedocs.io/
48*/
35class Click : public Base49class Click : public Base
36{50{
37public:51public:
@@ -49,6 +63,19 @@
49 std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override;63 std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override;
50 std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override;64 std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override;
5165
66 static bool hasAppId(const AppID& appId, const std::shared_ptr<Registry>& registry);
67
68 static bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry);
69 static bool verifyAppname(const AppID::Package& package,
70 const AppID::AppName& appname,
71 const std::shared_ptr<Registry>& registry);
72 static AppID::AppName findAppname(const AppID::Package& package,
73 AppID::ApplicationWildcard card,
74 const std::shared_ptr<Registry>& registry);
75 static AppID::Version findVersion(const AppID::Package& package,
76 const AppID::AppName& appname,
77 const std::shared_ptr<Registry>& registry);
78
52private:79private:
53 AppID _appid;80 AppID _appid;
5481
5582
=== modified file 'libubuntu-app-launch/application-impl-legacy.cpp'
--- libubuntu-app-launch/application-impl-legacy.cpp 2016-09-06 16:14:40 +0000
+++ libubuntu-app-launch/application-impl-legacy.cpp 2016-09-06 16:14:41 +0000
@@ -57,7 +57,7 @@
5757
58std::tuple<std::string, std::shared_ptr<GKeyFile>, std::string> keyfileForApp(const AppID::AppName& name)58std::tuple<std::string, std::shared_ptr<GKeyFile>, std::string> keyfileForApp(const AppID::AppName& name)
59{59{
60 std::string desktopName = name.value() + ".desktop";60 auto desktopName = name.value() + ".desktop";
61 std::string desktopPath;61 std::string desktopPath;
62 auto keyfilecheck = [desktopName, &desktopPath](const std::string& dir) -> std::shared_ptr<GKeyFile> {62 auto keyfilecheck = [desktopName, &desktopPath](const std::string& dir) -> std::shared_ptr<GKeyFile> {
63 auto fullname = g_build_filename(dir.c_str(), "applications", desktopName.c_str(), nullptr);63 auto fullname = g_build_filename(dir.c_str(), "applications", desktopName.c_str(), nullptr);
@@ -99,14 +99,110 @@
9999
100std::shared_ptr<Application::Info> Legacy::info()100std::shared_ptr<Application::Info> Legacy::info()
101{101{
102 if (!appinfo_)
103 {
104 appinfo_ = std::make_shared<app_info::Desktop>(_keyfile, _basedir, app_info::DesktopFlags::ALLOW_NO_DISPLAY,
105 _registry);
106 }
107 return appinfo_;102 return appinfo_;
108}103}
109104
105/** Checks the AppID by ensuring the version and package are empty
106 then looks for the application.
107
108 \param appid AppID to check
109 \param registry persistent connections to use
110*/
111bool Legacy::hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry)
112{
113 try
114 {
115 if (!appid.version.value().empty())
116 {
117 return false;
118 }
119
120 return verifyAppname(appid.package, appid.appname, registry);
121 }
122 catch (std::runtime_error& e)
123 {
124 return false;
125 }
126}
127
128/** Ensure the package is empty
129
130 \param package Container name
131 \param registry persistent connections to use
132*/
133bool Legacy::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry)
134{
135 return package.value().empty();
136}
137
138/** Looks for an application by looking through the system and user
139 application directories to find the desktop file.
140
141 \param package Container name
142 \param appname Application name to look for
143 \param registry persistent connections to use
144*/
145bool Legacy::verifyAppname(const AppID::Package& package,
146 const AppID::AppName& appname,
147 const std::shared_ptr<Registry>& registry)
148{
149 if (!verifyPackage(package, registry))
150 {
151 throw std::runtime_error{"Invalid Legacy package: " + std::string(package)};
152 }
153
154 auto desktop = std::string(appname) + ".desktop";
155 auto evaldir = [&desktop](const gchar* dir) -> bool {
156 char* fulldir = g_build_filename(dir, "applications", desktop.c_str(), nullptr);
157 gboolean found = g_file_test(fulldir, G_FILE_TEST_EXISTS);
158 g_free(fulldir);
159 return found == TRUE;
160 };
161
162 if (evaldir(g_get_user_data_dir()))
163 {
164 return true;
165 }
166
167 const char* const* data_dirs = g_get_system_data_dirs();
168 for (int i = 0; data_dirs[i] != nullptr; i++)
169 {
170 if (evaldir(data_dirs[i]))
171 {
172 return true;
173 }
174 }
175
176 return false;
177}
178
179/** We don't really have a way to implement this for Legacy, any
180 search wouldn't really make sense. We just throw an error.
181
182 \param package Container name
183 \param card Application search paths
184 \param registry persistent connections to use
185*/
186AppID::AppName Legacy::findAppname(const AppID::Package& package,
187 AppID::ApplicationWildcard card,
188 const std::shared_ptr<Registry>& registry)
189{
190 throw std::runtime_error("Legacy apps can't be discovered by package");
191}
192
193/** Function to return an empty string
194
195 \param package Container name (unused)
196 \param appname Application name (unused)
197 \param registry persistent connections to use (unused)
198*/
199AppID::Version Legacy::findVersion(const AppID::Package& package,
200 const AppID::AppName& appname,
201 const std::shared_ptr<Registry>& registry)
202{
203 return AppID::Version::from_raw({});
204}
205
110static const std::regex desktop_remover("^(.*)\\.desktop$");206static const std::regex desktop_remover("^(.*)\\.desktop$");
111207
112std::list<std::shared_ptr<Application>> Legacy::list(const std::shared_ptr<Registry>& registry)208std::list<std::shared_ptr<Application>> Legacy::list(const std::shared_ptr<Registry>& registry)
113209
=== modified file 'libubuntu-app-launch/application-impl-legacy.h'
--- libubuntu-app-launch/application-impl-legacy.h 2016-09-06 16:14:40 +0000
+++ libubuntu-app-launch/application-impl-legacy.h 2016-09-06 16:14:41 +0000
@@ -31,6 +31,19 @@
31namespace app_impls31namespace app_impls
32{32{
3333
34/** Application Implementation for Legacy applications. These are applications
35 that are typically installed as Debian packages on the base system. The
36 standard place for them to put their desktop files is in /usr/share/applications
37 though other directories may be used by setting the appropriate XDG environment
38 variables. This implementation makes use of the GIO Desktop Appinfo functions
39 which do caching of those files to make access faster.
40
41 AppIDs for legacy applications only include the Appname variable. Both the package
42 and the version entries are empty strings. The appname variable is the filename
43 of the desktop file describing the application with the ".desktop" suffix.
44
45 More info: https://specifications.freedesktop.org/desktop-entry-spec/latest/
46*/
34class Legacy : public Base47class Legacy : public Base
35{48{
36public:49public:
@@ -50,6 +63,19 @@
50 std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override;63 std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override;
51 std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override;64 std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override;
5265
66 static bool hasAppId(const AppID& appId, const std::shared_ptr<Registry>& registry);
67
68 static bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry);
69 static bool verifyAppname(const AppID::Package& package,
70 const AppID::AppName& appname,
71 const std::shared_ptr<Registry>& registry);
72 static AppID::AppName findAppname(const AppID::Package& package,
73 AppID::ApplicationWildcard card,
74 const std::shared_ptr<Registry>& registry);
75 static AppID::Version findVersion(const AppID::Package& package,
76 const AppID::AppName& appname,
77 const std::shared_ptr<Registry>& registry);
78
53private:79private:
54 AppID::AppName _appname;80 AppID::AppName _appname;
55 std::string _basedir;81 std::string _basedir;
5682
=== modified file 'libubuntu-app-launch/application-impl-libertine.cpp'
--- libubuntu-app-launch/application-impl-libertine.cpp 2016-09-06 16:14:40 +0000
+++ libubuntu-app-launch/application-impl-libertine.cpp 2016-09-06 16:14:41 +0000
@@ -106,6 +106,103 @@
106 return keyfile;106 return keyfile;
107}107}
108108
109/** Checks the AppID by making sure the version is "0.0" and then
110 calling verifyAppname() to check the rest.
111
112 \param appid AppID to check
113 \param registry persistent connections to use
114*/
115bool Libertine::hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry)
116{
117 try
118 {
119 if (appid.version.value() != "0.0")
120 {
121 return false;
122 }
123
124 return verifyAppname(appid.package, appid.appname, registry);
125 }
126 catch (std::runtime_error& e)
127 {
128 return false;
129 }
130}
131
132/** Verify a package name by getting the list of containers from
133 liblibertine and ensuring it is in that list.
134
135 \param package Container name
136 \param registry persistent connections to use
137*/
138bool Libertine::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry)
139{
140 auto containers = std::shared_ptr<gchar*>(libertine_list_containers(), g_strfreev);
141
142 for (int i = 0; containers.get()[i] != nullptr; i++)
143 {
144 auto container = containers.get()[i];
145 if (container == package.value())
146 {
147 return true;
148 }
149 }
150
151 return false;
152}
153
154/** Gets the list of applications from the container using liblibertine
155 and see if @appname is in that list.
156
157 \param package Container name
158 \param appname Application name to look for
159 \param registry persistent connections to use
160*/
161bool Libertine::verifyAppname(const AppID::Package& package,
162 const AppID::AppName& appname,
163 const std::shared_ptr<Registry>& registry)
164{
165 auto apps = std::shared_ptr<gchar*>(libertine_list_apps_for_container(package.value().c_str()), g_strfreev);
166
167 for (int i = 0; apps.get()[i] != nullptr; i++)
168 {
169 auto appid = AppID::parse(apps.get()[i]);
170 if (appid.appname.value() == appname.value())
171 {
172 return true;
173 }
174 }
175
176 return false;
177}
178
179/** We don't really have a way to implement this for Libertine, any
180 search wouldn't really make sense. We just throw an error.
181
182 \param package Container name
183 \param card Application search paths
184 \param registry persistent connections to use
185*/
186AppID::AppName Libertine::findAppname(const AppID::Package& package,
187 AppID::ApplicationWildcard card,
188 const std::shared_ptr<Registry>& registry)
189{
190 throw std::runtime_error("Legacy apps can't be discovered by package");
191}
192
193/** Function to return "0.0"
194
195 \param package Container name (unused)
196 \param appname Application name (unused)
197 \param registry persistent connections to use (unused)
198*/
199AppID::Version Libertine::findVersion(const AppID::Package& package,
200 const AppID::AppName& appname,
201 const std::shared_ptr<Registry>& registry)
202{
203 return AppID::Version::from_raw("0.0");
204}
205
109std::list<std::shared_ptr<Application>> Libertine::list(const std::shared_ptr<Registry>& registry)206std::list<std::shared_ptr<Application>> Libertine::list(const std::shared_ptr<Registry>& registry)
110{207{
111 std::list<std::shared_ptr<Application>> applist;208 std::list<std::shared_ptr<Application>> applist;
112209
=== modified file 'libubuntu-app-launch/application-impl-libertine.h'
--- libubuntu-app-launch/application-impl-libertine.h 2016-09-06 16:14:40 +0000
+++ libubuntu-app-launch/application-impl-libertine.h 2016-09-06 16:14:41 +0000
@@ -30,6 +30,23 @@
30namespace app_impls30namespace app_impls
31{31{
3232
33/** Application Implmentation for the Libertine container system. Libertine
34 sets up containers that are read/write on a read only system, to all for
35 more dynamic packaging systems (like deb) to work. This provides some
36 compatibility for older applications or those who are only distributed in
37 packaging systems requiring full system access.
38
39 Application IDs for Libertine applications have the package field as the
40 name of the container. The appname is similar to that of the Legacy() implementation
41 as the filename of the desktop file defining the application without the
42 ".desktop" suffix. UAL has no way to know the version, so it is always hard
43 coded to "0.0".
44
45 Libertine applications always are setup with XMir and started using the
46 libertine-launch utility which configures the environment for the container.
47
48 More info: https://wiki.ubuntu.com/Touch/Libertine
49*/
33class Libertine : public Base50class Libertine : public Base
34{51{
35public:52public:
@@ -51,6 +68,19 @@
51 std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override;68 std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override;
52 std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override;69 std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override;
5370
71 static bool hasAppId(const AppID& appId, const std::shared_ptr<Registry>& registry);
72
73 static bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry);
74 static bool verifyAppname(const AppID::Package& package,
75 const AppID::AppName& appname,
76 const std::shared_ptr<Registry>& registry);
77 static AppID::AppName findAppname(const AppID::Package& package,
78 AppID::ApplicationWildcard card,
79 const std::shared_ptr<Registry>& registry);
80 static AppID::Version findVersion(const AppID::Package& package,
81 const AppID::AppName& appname,
82 const std::shared_ptr<Registry>& registry);
83
54private:84private:
55 AppID::Package _container;85 AppID::Package _container;
56 AppID::AppName _appname;86 AppID::AppName _appname;
5787
=== modified file 'libubuntu-app-launch/application.cpp'
--- libubuntu-app-launch/application.cpp 2016-08-17 15:24:23 +0000
+++ libubuntu-app-launch/application.cpp 2016-09-06 16:14:41 +0000
@@ -18,7 +18,6 @@
18 */18 */
1919
20extern "C" {20extern "C" {
21#include "app-info.h"
22#include "ubuntu-app-launch.h"21#include "ubuntu-app-launch.h"
23}22}
2423
@@ -26,7 +25,9 @@
26#include "application-impl-legacy.h"25#include "application-impl-legacy.h"
27#include "application-impl-libertine.h"26#include "application-impl-libertine.h"
28#include "application.h"27#include "application.h"
28#include "registry.h"
2929
30#include <functional>
30#include <iostream>31#include <iostream>
31#include <regex>32#include <regex>
3233
@@ -42,22 +43,21 @@
42 throw std::runtime_error("AppID is empty");43 throw std::runtime_error("AppID is empty");
43 }44 }
4445
45 std::string sappid = appid;46 if (app_impls::Click::hasAppId(appid, registry))
46 if (app_info_click(sappid.c_str(), NULL, NULL))
47 {47 {
48 return std::make_shared<app_impls::Click>(appid, registry);48 return std::make_shared<app_impls::Click>(appid, registry);
49 }49 }
50 else if (app_info_libertine(sappid.c_str(), NULL, NULL))50 else if (app_impls::Libertine::hasAppId(appid, registry))
51 {51 {
52 return std::make_shared<app_impls::Libertine>(appid.package, appid.appname, registry);52 return std::make_shared<app_impls::Libertine>(appid.package, appid.appname, registry);
53 }53 }
54 else if (app_info_legacy(sappid.c_str(), NULL, NULL))54 else if (app_impls::Legacy::hasAppId(appid, registry))
55 {55 {
56 return std::make_shared<app_impls::Legacy>(appid.appname, registry);56 return std::make_shared<app_impls::Legacy>(appid.appname, registry);
57 }57 }
58 else58 else
59 {59 {
60 throw std::runtime_error("Invalid app ID: " + sappid);60 throw std::runtime_error("Invalid app ID: " + std::string(appid));
61 }61 }
62}62}
6363
@@ -106,6 +106,12 @@
106106
107AppID AppID::find(const std::string& sappid)107AppID AppID::find(const std::string& sappid)
108{108{
109 auto registry = Registry::getDefault();
110 return find(registry, sappid);
111}
112
113AppID AppID::find(const std::shared_ptr<Registry>& registry, const std::string& sappid)
114{
109 std::smatch match;115 std::smatch match;
110116
111 if (std::regex_match(sappid, match, full_appid_regex))117 if (std::regex_match(sappid, match, full_appid_regex))
@@ -115,7 +121,7 @@
115 }121 }
116 else if (std::regex_match(sappid, match, short_appid_regex))122 else if (std::regex_match(sappid, match, short_appid_regex))
117 {123 {
118 return discover(match[1].str(), match[2].str());124 return discover(registry, match[1].str(), match[2].str());
119 }125 }
120 else if (std::regex_match(sappid, match, legacy_appid_regex))126 else if (std::regex_match(sappid, match, legacy_appid_regex))
121 {127 {
@@ -156,67 +162,183 @@
156 a.version.value() != b.version.value();162 a.version.value() != b.version.value();
157}163}
158164
165/** Convert each AppID to a string and then compare the strings */
166bool operator<(const AppID& a, const AppID& b)
167{
168 return std::string(a) < std::string(b);
169}
170
159bool AppID::empty() const171bool AppID::empty() const
160{172{
161 return package.value().empty() && appname.value().empty() && version.value().empty();173 return package.value().empty() && appname.value().empty() && version.value().empty();
162}174}
163175
164std::string app_wildcard(AppID::ApplicationWildcard card)176/** Basically we're making our own VTable of static functions. Static
165{177 functions don't go in the normal VTables, so we can't use our class
166 switch (card)178 inheritance here to help. So we're just packing these puppies into
167 {179 a data structure and iterating over it. */
168 case AppID::ApplicationWildcard::FIRST_LISTED:180struct DiscoverTools
169 return "first-listed-app";181{
170 case AppID::ApplicationWildcard::LAST_LISTED:182 std::function<bool(const AppID::Package& package, const std::shared_ptr<Registry>& registry)> verifyPackage;
171 return "last-listed-app";183 std::function<bool(
172 case AppID::ApplicationWildcard::ONLY_LISTED:184 const AppID::Package& package, const AppID::AppName& appname, const std::shared_ptr<Registry>& registry)>
173 return "only-listed-app";185 verifyAppname;
174 }186 std::function<AppID::AppName(
175187 const AppID::Package& package, AppID::ApplicationWildcard card, const std::shared_ptr<Registry>& registry)>
176 return "";188 findAppname;
177}189 std::function<AppID::Version(
178190 const AppID::Package& package, const AppID::AppName& appname, const std::shared_ptr<Registry>& registry)>
179std::string ver_wildcard(AppID::VersionWildcard card)191 findVersion;
180{192 std::function<bool(const AppID& appid, const std::shared_ptr<Registry>& registry)> hasAppId;
181 switch (card)193};
182 {194
183 case AppID::VersionWildcard::CURRENT_USER_VERSION:195/** The tools in order that they should be used */
184 return "current-user-version";196static const std::vector<DiscoverTools> discoverTools{
185 }197 /* Click */
186198 {app_impls::Click::verifyPackage, app_impls::Click::verifyAppname, app_impls::Click::findAppname,
187 return "";199 app_impls::Click::findVersion, app_impls::Click::hasAppId},
200 /* Libertine */
201 {app_impls::Libertine::verifyPackage, app_impls::Libertine::verifyAppname, app_impls::Libertine::findAppname,
202 app_impls::Libertine::findVersion, app_impls::Libertine::hasAppId},
203 /* Legacy */
204 {app_impls::Legacy::verifyPackage, app_impls::Legacy::verifyAppname, app_impls::Legacy::findAppname,
205 app_impls::Legacy::findVersion, app_impls::Legacy::hasAppId}};
206
207AppID AppID::discover(const std::shared_ptr<Registry>& registry,
208 const std::string& package,
209 const std::string& appname,
210 const std::string& version)
211{
212 auto pkg = AppID::Package::from_raw(package);
213
214 for (const auto& tools : discoverTools)
215 {
216 /* Figure out which type we have */
217 try
218 {
219 if (tools.verifyPackage(pkg, registry))
220 {
221 auto app = AppID::AppName::from_raw({});
222
223 if (appname.empty() || appname == "first-listed-app")
224 {
225 app = tools.findAppname(pkg, ApplicationWildcard::FIRST_LISTED, registry);
226 }
227 else if (appname == "last-listed-app")
228 {
229 app = tools.findAppname(pkg, ApplicationWildcard::LAST_LISTED, registry);
230 }
231 else if (appname == "only-listed-app")
232 {
233 app = tools.findAppname(pkg, ApplicationWildcard::ONLY_LISTED, registry);
234 }
235 else
236 {
237 app = AppID::AppName::from_raw(appname);
238 if (!tools.verifyAppname(pkg, app, registry))
239 {
240 throw std::runtime_error("App name passed in is not valid for this package type");
241 }
242 }
243
244 auto ver = AppID::Version::from_raw({});
245 if (version.empty() || version == "current-user-version")
246 {
247 ver = tools.findVersion(pkg, app, registry);
248 }
249 else
250 {
251 ver = AppID::Version::from_raw(version);
252 if (!tools.hasAppId({pkg, app, ver}, registry))
253 {
254 throw std::runtime_error("Invalid version passed for this package type");
255 }
256 }
257
258 return AppID{pkg, app, ver};
259 }
260 }
261 catch (std::runtime_error& e)
262 {
263 continue;
264 }
265 }
266
267 return {};
268}
269
270AppID AppID::discover(const std::shared_ptr<Registry>& registry,
271 const std::string& package,
272 ApplicationWildcard appwildcard,
273 VersionWildcard versionwildcard)
274{
275 auto pkg = AppID::Package::from_raw(package);
276
277 for (const auto& tools : discoverTools)
278 {
279 try
280 {
281 if (tools.verifyPackage(pkg, registry))
282 {
283 auto app = tools.findAppname(pkg, appwildcard, registry);
284 auto ver = tools.findVersion(pkg, app, registry);
285 return AppID{pkg, app, ver};
286 }
287 }
288 catch (std::runtime_error& e)
289 {
290 /* Normal, try another */
291 continue;
292 }
293 }
294
295 return {};
296}
297
298AppID AppID::discover(const std::shared_ptr<Registry>& registry,
299 const std::string& package,
300 const std::string& appname,
301 VersionWildcard versionwildcard)
302{
303 auto pkg = AppID::Package::from_raw(package);
304 auto app = AppID::AppName::from_raw(appname);
305
306 for (const auto& tools : discoverTools)
307 {
308 try
309 {
310 if (tools.verifyPackage(pkg, registry) && tools.verifyAppname(pkg, app, registry))
311 {
312 auto ver = tools.findVersion(pkg, app, registry);
313 return AppID{pkg, app, ver};
314 }
315 }
316 catch (std::runtime_error& e)
317 {
318 /* Normal, try another */
319 continue;
320 }
321 }
322
323 return {};
188}324}
189325
190AppID AppID::discover(const std::string& package, const std::string& appname, const std::string& version)326AppID AppID::discover(const std::string& package, const std::string& appname, const std::string& version)
191{327{
192 auto cappid = ubuntu_app_launch_triplet_to_app_id(package.c_str(), appname.c_str(), version.c_str());328 auto registry = Registry::getDefault();
193329 return discover(registry, package, appname, version);
194 auto appid = cappid != nullptr ? AppID::parse(cappid) : AppID::parse("");
195
196 g_free(cappid);
197
198 return appid;
199}330}
200331
201AppID AppID::discover(const std::string& package, ApplicationWildcard appwildcard, VersionWildcard versionwildcard)332AppID AppID::discover(const std::string& package, ApplicationWildcard appwildcard, VersionWildcard versionwildcard)
202{333{
203 return discover(package, app_wildcard(appwildcard), ver_wildcard(versionwildcard));334 auto registry = Registry::getDefault();
335 return discover(registry, package, appwildcard, versionwildcard);
204}336}
205337
206AppID AppID::discover(const std::string& package, const std::string& appname, VersionWildcard versionwildcard)338AppID AppID::discover(const std::string& package, const std::string& appname, VersionWildcard versionwildcard)
207{339{
208 auto appid = discover(package, appname, ver_wildcard(versionwildcard));340 auto registry = Registry::getDefault();
209341 return discover(registry, package, appname, versionwildcard);
210 if (appid.empty())
211 {
212 /* If we weren't able to go that route, we can see if it's libertine */
213 if (app_info_libertine((package + "_" + appname + "_0.0").c_str(), nullptr, nullptr))
214 {
215 appid = AppID(Package::from_raw(package), AppName::from_raw(appname), Version::from_raw("0.0"));
216 }
217 }
218
219 return appid;
220}342}
221343
222enum class oom::Score : std::int32_t344enum class oom::Score : std::int32_t
223345
=== modified file 'libubuntu-app-launch/registry.cpp'
--- libubuntu-app-launch/registry.cpp 2016-08-17 15:24:23 +0000
+++ libubuntu-app-launch/registry.cpp 2016-09-06 16:14:41 +0000
@@ -91,7 +91,7 @@
91 std::list<std::shared_ptr<Application>> apps;91 std::list<std::shared_ptr<Application>> apps;
92 for (auto instance : instanceset)92 for (auto instance : instanceset)
93 {93 {
94 auto appid = AppID::find(instance);94 auto appid = AppID::find(connection, instance);
95 auto app = Application::create(appid, connection);95 auto app = Application::create(appid, connection);
96 apps.push_back(app);96 apps.push_back(app);
97 }97 }
9898
=== modified file 'libubuntu-app-launch/ubuntu-app-launch.cpp'
--- libubuntu-app-launch/ubuntu-app-launch.cpp 2016-09-06 16:14:40 +0000
+++ libubuntu-app-launch/ubuntu-app-launch.cpp 2016-09-06 16:14:41 +0000
@@ -27,7 +27,6 @@
27#include <errno.h>27#include <errno.h>
28#include <zeitgeist.h>28#include <zeitgeist.h>
2929
30#include "app-info.h"
31#include "ubuntu-app-launch-trace.h"30#include "ubuntu-app-launch-trace.h"
32#include "helpers.h"31#include "helpers.h"
33#include "ual-tracepoint.h"32#include "ual-tracepoint.h"
@@ -948,16 +947,24 @@
948{947{
949 g_return_val_if_fail(pkg != NULL, NULL);948 g_return_val_if_fail(pkg != NULL, NULL);
950949
951 /* Check if is a libertine container */950 std::string package{pkg};
952 gchar * libertinepath = g_build_filename(g_get_user_cache_dir(), "libertine-container", pkg, NULL);951 std::string appname;
953 gboolean libcontainer = g_file_test(libertinepath, G_FILE_TEST_EXISTS);952 std::string version;
954 g_free(libertinepath);953
955954 if (app != nullptr) {
956 if (libcontainer) {955 appname = app;
957 return libertine_triplet_to_app_id(pkg, app, ver);956 }
958 } else {957
959 return click_triplet_to_app_id(pkg, app, ver);958 if (ver != nullptr) {
960 }959 version = ver;
960 }
961
962 auto appid = ubuntu::app_launch::AppID::discover(package, appname, version);
963 if (appid.empty()) {
964 return nullptr;
965 }
966
967 return g_strdup(std::string(appid).c_str());
961}968}
962969
963/* Print an error if we couldn't start it */970/* Print an error if we couldn't start it */
964971
=== modified file 'tests/libual-cpp-test.cc'
--- tests/libual-cpp-test.cc 2016-09-06 16:14:40 +0000
+++ tests/libual-cpp-test.cc 2016-09-06 16:14:41 +0000
@@ -22,6 +22,7 @@
22#include <functional>22#include <functional>
23#include <future>23#include <future>
24#include <gio/gio.h>24#include <gio/gio.h>
25#include <glib/gstdio.h>
25#include <gtest/gtest.h>26#include <gtest/gtest.h>
26#include <libdbustest/dbus-test.h>27#include <libdbustest/dbus-test.h>
27#include <numeric>28#include <numeric>
@@ -310,7 +311,7 @@
310 }311 }
311};312};
312313
313TEST_F(LibUAL, StartApplication)314TEST_F(LibUAL, StartClickApplication)
314{315{
315 DbusTestDbusMockObject* obj =316 DbusTestDbusMockObject* obj =
316 dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);317 dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);
@@ -367,7 +368,7 @@
367 return;368 return;
368}369}
369370
370TEST_F(LibUAL, StartApplicationTest)371TEST_F(LibUAL, StartClickApplicationTest)
371{372{
372 DbusTestDbusMockObject* obj =373 DbusTestDbusMockObject* obj =
373 dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);374 dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);
@@ -395,7 +396,7 @@
395 g_variant_unref(env);396 g_variant_unref(env);
396}397}
397398
398TEST_F(LibUAL, StopApplication)399TEST_F(LibUAL, StopClickApplication)
399{400{
400 DbusTestDbusMockObject* obj =401 DbusTestDbusMockObject* obj =
401 dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);402 dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);
@@ -424,7 +425,7 @@
424 std::string(CMAKE_SOURCE_DIR "/libertine-data/upstart/application-click-com.test.good_application_1.2.3.log"),425 std::string(CMAKE_SOURCE_DIR "/libertine-data/upstart/application-click-com.test.good_application_1.2.3.log"),
425 app->instances()[0]->logPath());426 app->instances()[0]->logPath());
426427
427 appid = ubuntu::app_launch::AppID::find("single");428 appid = ubuntu::app_launch::AppID::find(registry, "single");
428 app = ubuntu::app_launch::Application::create(appid, registry);429 app = ubuntu::app_launch::Application::create(appid, registry);
429430
430 ASSERT_LT(0, app->instances().size());431 ASSERT_LT(0, app->instances().size());
@@ -432,7 +433,7 @@
432 EXPECT_EQ(std::string(CMAKE_SOURCE_DIR "/libertine-data/upstart/application-legacy-single-.log"),433 EXPECT_EQ(std::string(CMAKE_SOURCE_DIR "/libertine-data/upstart/application-legacy-single-.log"),
433 app->instances()[0]->logPath());434 app->instances()[0]->logPath());
434435
435 appid = ubuntu::app_launch::AppID::find("multiple");436 appid = ubuntu::app_launch::AppID::find(registry, "multiple");
436 app = ubuntu::app_launch::Application::create(appid, registry);437 app = ubuntu::app_launch::Application::create(appid, registry);
437438
438 EXPECT_EQ(std::string(CMAKE_SOURCE_DIR "/libertine-data/upstart/application-legacy-multiple-2342345.log"),439 EXPECT_EQ(std::string(CMAKE_SOURCE_DIR "/libertine-data/upstart/application-legacy-multiple-2342345.log"),
@@ -454,9 +455,10 @@
454 EXPECT_TRUE(app->instances()[0]->hasPid(300));455 EXPECT_TRUE(app->instances()[0]->hasPid(300));
455456
456 /* Check primary pid, which comes from Upstart */457 /* Check primary pid, which comes from Upstart */
458 EXPECT_TRUE(app->instances()[0]->isRunning());
457 EXPECT_EQ(getpid(), app->instances()[0]->primaryPid());459 EXPECT_EQ(getpid(), app->instances()[0]->primaryPid());
458460
459 auto multiappid = ubuntu::app_launch::AppID::find("multiple");461 auto multiappid = ubuntu::app_launch::AppID::find(registry, "multiple");
460 auto multiapp = ubuntu::app_launch::Application::create(multiappid, registry);462 auto multiapp = ubuntu::app_launch::Application::create(multiappid, registry);
461 auto instances = multiapp->instances();463 auto instances = multiapp->instances();
462 ASSERT_LT(0, instances.size());464 ASSERT_LT(0, instances.size());
@@ -488,7 +490,7 @@
488 ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(cgmock, cgobject, NULL));490 ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(cgmock, cgobject, NULL));
489491
490 /* Legacy Single Instance */492 /* Legacy Single Instance */
491 auto singleappid = ubuntu::app_launch::AppID::find("single");493 auto singleappid = ubuntu::app_launch::AppID::find(registry, "single");
492 auto singleapp = ubuntu::app_launch::Application::create(singleappid, registry);494 auto singleapp = ubuntu::app_launch::Application::create(singleappid, registry);
493495
494 ASSERT_LT(0, singleapp->instances().size());496 ASSERT_LT(0, singleapp->instances().size());
@@ -517,50 +519,53 @@
517519
518 /* Test with current-user-version, should return the version in the manifest */520 /* Test with current-user-version, should return the version in the manifest */
519 EXPECT_EQ("com.test.good_application_1.2.3",521 EXPECT_EQ("com.test.good_application_1.2.3",
520 (std::string)ubuntu::app_launch::AppID::discover("com.test.good", "application"));522 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application"));
521523
522 /* Test with version specified, shouldn't even read the manifest */524 /* Test with version specified, shouldn't even read the manifest */
523 EXPECT_EQ("com.test.good_application_1.2.4",525 EXPECT_EQ("com.test.good_application_1.2.4",
524 (std::string)ubuntu::app_launch::AppID::discover("com.test.good", "application", "1.2.4"));526 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application", "1.2.4"));
525527
526 /* Test with out a version or app, should return the version in the manifest */528 /* Test with out a version or app, should return the version in the manifest */
527 EXPECT_EQ("com.test.good_application_1.2.3", (std::string)ubuntu::app_launch::AppID::discover(529 EXPECT_EQ("com.test.good_application_1.2.3",
528 "com.test.good", "first-listed-app", "current-user-version"));530 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "first-listed-app",
531 "current-user-version"));
529532
530 /* Make sure we can select the app from a list correctly */533 /* Make sure we can select the app from a list correctly */
531 EXPECT_EQ("com.test.multiple_first_1.2.3",534 EXPECT_EQ("com.test.multiple_first_1.2.3",
532 (std::string)ubuntu::app_launch::AppID::discover(535 (std::string)ubuntu::app_launch::AppID::discover(
533 "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED));536 registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED));
534 EXPECT_EQ("com.test.multiple_first_1.2.3", (std::string)ubuntu::app_launch::AppID::discover("com.test.multiple"));537 EXPECT_EQ("com.test.multiple_first_1.2.3",
538 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.multiple"));
535 EXPECT_EQ("com.test.multiple_fifth_1.2.3",539 EXPECT_EQ("com.test.multiple_fifth_1.2.3",
536 (std::string)ubuntu::app_launch::AppID::discover(540 (std::string)ubuntu::app_launch::AppID::discover(
537 "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED));541 registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED));
538 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(542 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(
539 "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));543 registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));
540 EXPECT_EQ("com.test.good_application_1.2.3",544 EXPECT_EQ("com.test.good_application_1.2.3",
541 (std::string)ubuntu::app_launch::AppID::discover(545 (std::string)ubuntu::app_launch::AppID::discover(
542 "com.test.good", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));546 registry, "com.test.good", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));
543547
544 /* A bunch that should be NULL */548 /* A bunch that should be NULL */
545 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("com.test.no-hooks"));549 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-hooks"));
546 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("com.test.no-json"));550 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-json"));
547 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("com.test.no-object"));551 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-object"));
548 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("com.test.no-version"));552 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-version"));
549553
550 /* Libertine tests */554 /* Libertine tests */
551 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("container-name"));555 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name"));
552 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("container-name", "not-exist"));556 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name", "not-exist"));
553 EXPECT_EQ("container-name_test_0.0", (std::string)ubuntu::app_launch::AppID::discover("container-name", "test"));557 EXPECT_EQ("container-name_test_0.0",
558 (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name", "test"));
554 EXPECT_EQ("container-name_user-app_0.0",559 EXPECT_EQ("container-name_user-app_0.0",
555 (std::string)ubuntu::app_launch::AppID::discover("container-name", "user-app"));560 (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name", "user-app"));
556}561}
557562
558TEST_F(LibUAL, AppIdParse)563TEST_F(LibUAL, AppIdParse)
559{564{
560 EXPECT_FALSE(ubuntu::app_launch::AppID::parse("com.ubuntu.test_test_123").empty());565 EXPECT_FALSE(ubuntu::app_launch::AppID::parse("com.ubuntu.test_test_123").empty());
561 EXPECT_FALSE(ubuntu::app_launch::AppID::find("inkscape").empty());566 EXPECT_FALSE(ubuntu::app_launch::AppID::find(registry, "inkscape").empty());
562 EXPECT_FALSE(ubuntu::app_launch::AppID::parse("chatter.robert-ancell_chatter_2").empty());567 EXPECT_FALSE(ubuntu::app_launch::AppID::parse("chatter.robert-ancell_chatter_2").empty());
563 EXPECT_FALSE(ubuntu::app_launch::AppID::find("chatter.robert-ancell_chatter").empty());568 EXPECT_FALSE(ubuntu::app_launch::AppID::find(registry, "chatter.robert-ancell_chatter").empty());
564569
565 auto id = ubuntu::app_launch::AppID::parse("com.ubuntu.test_test_123");570 auto id = ubuntu::app_launch::AppID::parse("com.ubuntu.test_test_123");
566571
@@ -887,7 +892,7 @@
887 dbus_test_dbus_mock_get_object(mock, "/com/test/application_legacy", "com.ubuntu.Upstart0_6.Job", NULL);892 dbus_test_dbus_mock_get_object(mock, "/com/test/application_legacy", "com.ubuntu.Upstart0_6.Job", NULL);
888893
889 /* Check for a single-instance app */894 /* Check for a single-instance app */
890 auto singleappid = ubuntu::app_launch::AppID::find("single");895 auto singleappid = ubuntu::app_launch::AppID::find(registry, "single");
891 auto singleapp = ubuntu::app_launch::Application::create(singleappid, registry);896 auto singleapp = ubuntu::app_launch::Application::create(singleappid, registry);
892897
893 singleapp->launch();898 singleapp->launch();
@@ -912,7 +917,7 @@
912 ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(mock, obj, NULL));917 ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(mock, obj, NULL));
913918
914 /* Check for a multi-instance app */919 /* Check for a multi-instance app */
915 auto multipleappid = ubuntu::app_launch::AppID::find("multiple");920 auto multipleappid = ubuntu::app_launch::AppID::find(registry, "multiple");
916 auto multipleapp = ubuntu::app_launch::Application::create(multipleappid, registry);921 auto multipleapp = ubuntu::app_launch::Application::create(multipleappid, registry);
917922
918 multipleapp->launch();923 multipleapp->launch();
@@ -1382,7 +1387,7 @@
1382 signal_increment, &resumed_count, nullptr);1387 signal_increment, &resumed_count, nullptr);
13831388
1384 /* Get our app object */1389 /* Get our app object */
1385 auto appid = ubuntu::app_launch::AppID::find("com.test.good_application_1.2.3");1390 auto appid = ubuntu::app_launch::AppID::find(registry, "com.test.good_application_1.2.3");
1386 auto app = ubuntu::app_launch::Application::create(appid, registry);1391 auto app = ubuntu::app_launch::Application::create(appid, registry);
13871392
1388 ASSERT_EQ(1, app->instances().size());1393 ASSERT_EQ(1, app->instances().size());
@@ -1488,7 +1493,7 @@
1488 dbus_test_task_get_state(DBUS_TEST_TASK(zgmock)) != DBUS_TEST_TASK_STATE_RUNNING);1493 dbus_test_task_get_state(DBUS_TEST_TASK(zgmock)) != DBUS_TEST_TASK_STATE_RUNNING);
14891494
1490 /* Get our app object */1495 /* Get our app object */
1491 auto appid = ubuntu::app_launch::AppID::find("com.test.good_application_1.2.3");1496 auto appid = ubuntu::app_launch::AppID::find(registry, "com.test.good_application_1.2.3");
1492 auto app = ubuntu::app_launch::Application::create(appid, registry);1497 auto app = ubuntu::app_launch::Application::create(appid, registry);
14931498
1494 ASSERT_EQ(1, app->instances().size());1499 ASSERT_EQ(1, app->instances().size());
@@ -1569,7 +1574,7 @@
1569 EXPECT_EVENTUALLY_EQ(DBUS_TEST_TASK_STATE_RUNNING, dbus_test_task_get_state(DBUS_TEST_TASK(cgmock2)));1574 EXPECT_EVENTUALLY_EQ(DBUS_TEST_TASK_STATE_RUNNING, dbus_test_task_get_state(DBUS_TEST_TASK(cgmock2)));
15701575
1571 /* Get our app object */1576 /* Get our app object */
1572 auto appid = ubuntu::app_launch::AppID::find("com.test.good_application_1.2.3");1577 auto appid = ubuntu::app_launch::AppID::find(registry, "com.test.good_application_1.2.3");
1573 auto app = ubuntu::app_launch::Application::create(appid, registry);1578 auto app = ubuntu::app_launch::Application::create(appid, registry);
15741579
1575 ASSERT_EQ(1, app->instances().size());1580 ASSERT_EQ(1, app->instances().size());
@@ -1780,7 +1785,7 @@
1780 EXPECT_EQ("Application", app->info()->name().value());1785 EXPECT_EQ("Application", app->info()->name().value());
17811786
1782 /* Correct values from a legacy */1787 /* Correct values from a legacy */
1783 auto barid = ubuntu::app_launch::AppID::find("bar");1788 auto barid = ubuntu::app_launch::AppID::find(registry, "bar");
1784 EXPECT_THROW(ubuntu::app_launch::Application::create(barid, registry), std::runtime_error);1789 EXPECT_THROW(ubuntu::app_launch::Application::create(barid, registry), std::runtime_error);
17851790
1786 /* Correct values for libertine */1791 /* Correct values for libertine */

Subscribers

People subscribed via source and target branches