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
1=== modified file 'docs/index.rst'
2--- docs/index.rst 2016-04-29 14:20:11 +0000
3+++ docs/index.rst 2016-09-06 16:14:41 +0000
4@@ -109,7 +109,7 @@
5 Application Icon Finder
6 ------------------------
7
8-.. doxygenclass:: ubuntu::app_launch::app_info::IconFinder
9+.. doxygenclass:: ubuntu::app_launch::IconFinder
10 :project: libubuntu-app-launch
11 :members:
12 :protected-members:
13@@ -146,6 +146,16 @@
14 :private-members:
15 :undoc-members:
16
17+Upstart Instance
18+----------------
19+
20+.. doxygenclass:: ubuntu::app_launch::app_impls::UpstartInstance
21+ :project: libubuntu-app-launch
22+ :members:
23+ :protected-members:
24+ :private-members:
25+ :undoc-members:
26+
27 Quality
28 =======
29
30
31=== modified file 'libubuntu-app-launch/app-info.c'
32--- libubuntu-app-launch/app-info.c 2016-09-06 16:14:40 +0000
33+++ libubuntu-app-launch/app-info.c 2016-09-06 16:14:41 +0000
34@@ -21,7 +21,9 @@
35 #include <click.h>
36
37 #include "ubuntu-app-launch.h"
38-#include "app-info.h"
39+
40+/* Prototypes */
41+static gboolean app_info_libertine (const gchar * appid, gchar ** appdir, gchar ** appdesktop);
42
43 /* Try and get a manifest and do a couple sanity checks on it */
44 static JsonObject *
45@@ -76,130 +78,6 @@
46 return manifest;
47 }
48
49-/* Types of search we can do for an app name */
50-enum _app_name_t {
51- APP_NAME_ONLY,
52- APP_NAME_FIRST,
53- APP_NAME_LAST
54-};
55-typedef enum _app_name_t app_name_t;
56-
57-/* Figure out the app name if it's one of the keywords */
58-static const gchar *
59-manifest_app_name (JsonObject ** manifest, const gchar * pkg, const gchar * original_app)
60-{
61- app_name_t app_type = APP_NAME_FIRST;
62-
63- if (original_app == NULL) {
64- /* first */
65- } else if (g_strcmp0(original_app, "first-listed-app") == 0) {
66- /* first */
67- } else if (g_strcmp0(original_app, "last-listed-app") == 0) {
68- app_type = APP_NAME_LAST;
69- } else if (g_strcmp0(original_app, "only-listed-app") == 0) {
70- app_type = APP_NAME_ONLY;
71- } else {
72- return original_app;
73- }
74-
75- if (*manifest == NULL) {
76- *manifest = get_manifest(pkg, NULL);
77- }
78-
79- JsonObject * hooks = json_object_get_object_member(*manifest, "hooks");
80-
81- if (hooks == NULL) {
82- return NULL;
83- }
84-
85- GList * apps = json_object_get_members(hooks);
86- if (apps == NULL) {
87- return NULL;
88- }
89-
90- const gchar * retapp = NULL;
91-
92- switch (app_type) {
93- case APP_NAME_ONLY:
94- if (g_list_length(apps) == 1) {
95- retapp = (const gchar *)apps->data;
96- }
97- break;
98- case APP_NAME_FIRST:
99- retapp = (const gchar *)apps->data;
100- break;
101- case APP_NAME_LAST:
102- retapp = (const gchar *)(g_list_last(apps)->data);
103- break;
104- default:
105- break;
106- }
107-
108- g_list_free(apps);
109-
110- return retapp;
111-}
112-
113-/* Figure out the app version using the manifest */
114-static const gchar *
115-manifest_version (JsonObject ** manifest, const gchar * pkg, const gchar * original_ver)
116-{
117- if (original_ver != NULL && g_strcmp0(original_ver, "current-user-version") != 0) {
118- return original_ver;
119- } else {
120- if (*manifest == NULL) {
121- *manifest = get_manifest(pkg, NULL);
122- }
123- g_return_val_if_fail(*manifest != NULL, NULL);
124-
125- return g_strdup(json_object_get_string_member(*manifest, "version"));
126- }
127-
128- return NULL;
129-}
130-
131-/* A click triplet can require using the Click DB and getting a
132- manifest. This code does that to look up the versions */
133-gchar *
134-click_triplet_to_app_id (const gchar * pkg, const gchar * app, const gchar * ver)
135-{
136- const gchar * version = NULL;
137- const gchar * application = NULL;
138- JsonObject * manifest = NULL;
139-
140- version = manifest_version(&manifest, pkg, ver);
141- g_return_val_if_fail(version != NULL, NULL);
142-
143- application = manifest_app_name(&manifest, pkg, app);
144- g_return_val_if_fail(application != NULL, NULL);
145-
146- gchar * retval = g_strdup_printf("%s_%s_%s", pkg, application, version);
147-
148- /* The object may hold allocation for some of our strings used above */
149- if (manifest)
150- json_object_unref(manifest);
151-
152- return retval;
153-}
154-
155-/* Build an appid how we think it should exist and then make sure
156- we can find it. Then pull it together. */
157-gchar *
158-libertine_triplet_to_app_id (const gchar * pkg, const gchar * app, const gchar * ver)
159-{
160- if (app == NULL) {
161- return NULL;
162- }
163-
164- gchar * synthappid = g_strdup_printf("%s_%s_0.0", pkg, app);
165- if (app_info_libertine(synthappid, NULL, NULL)) {
166- return synthappid;
167- } else {
168- g_free(synthappid);
169- return NULL;
170- }
171-}
172-
173 /* Look to see if the app id results in a desktop file, if so, fill in the params */
174 static gboolean
175 evaluate_dir (const gchar * dir, const gchar * desktop, gchar ** appdir, gchar ** appdesktop)
176@@ -224,7 +102,7 @@
177 }
178
179 /* Handle the legacy case where we look through the data directories */
180-gboolean
181+static gboolean
182 app_info_legacy (const gchar * appid, gchar ** appdir, gchar ** appdesktop)
183 {
184 gchar * desktop = g_strdup_printf("%s.desktop", appid);
185@@ -248,7 +126,7 @@
186 }
187
188 /* Handle the libertine case where we look in the container */
189-gboolean
190+static gboolean
191 app_info_libertine (const gchar * appid, gchar ** appdir, gchar ** appdesktop)
192 {
193 char * container = NULL;
194@@ -301,7 +179,7 @@
195 }
196
197 /* Get the information on where the desktop file is from libclick */
198-gboolean
199+static gboolean
200 app_info_click (const gchar * appid, gchar ** appdir, gchar ** appdesktop)
201 {
202 gchar * package = NULL;
203
204=== removed file 'libubuntu-app-launch/app-info.h'
205--- libubuntu-app-launch/app-info.h 2016-06-07 01:49:09 +0000
206+++ libubuntu-app-launch/app-info.h 1970-01-01 00:00:00 +0000
207@@ -1,35 +0,0 @@
208-/*
209- * Copyright © 2015 Canonical Ltd.
210- *
211- * This program is free software: you can redistribute it and/or modify it
212- * under the terms of the GNU General Public License version 3, as published
213- * by the Free Software Foundation.
214- *
215- * This program is distributed in the hope that it will be useful, but
216- * WITHOUT ANY WARRANTY; without even the implied warranties of
217- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
218- * PURPOSE. See the GNU General Public License for more details.
219- *
220- * You should have received a copy of the GNU General Public License along
221- * with this program. If not, see <http://www.gnu.org/licenses/>.
222- *
223- * Authors:
224- * Ted Gould <ted.gould@canonical.com>
225- */
226-
227-#pragma once
228-
229-#include <gio/gio.h>
230-
231-G_BEGIN_DECLS
232-
233-gboolean app_info_legacy (const gchar * appid, gchar ** appdir, gchar ** appdesktop);
234-gboolean app_info_libertine (const gchar * appid, gchar ** appdir, gchar ** appdesktop);
235-gboolean app_info_click (const gchar * appid, gchar ** appdir, gchar ** appdesktop);
236-
237-gchar * click_triplet_to_app_id (const gchar * pkg, const gchar * app, const gchar * ver);
238-gchar * libertine_triplet_to_app_id (const gchar * pkg, const gchar * app, const gchar * ver);
239-
240-gboolean start_application_core (GDBusConnection * con, GCancellable * cancel, const gchar * appid, const gchar * const * uris, gboolean test);
241-
242-G_END_DECLS
243
244=== modified file 'libubuntu-app-launch/appid.h'
245--- libubuntu-app-launch/appid.h 2016-06-09 14:55:34 +0000
246+++ libubuntu-app-launch/appid.h 2016-09-06 16:14:41 +0000
247@@ -17,6 +17,7 @@
248 * Ted Gould <ted.gould@canonical.com>
249 */
250
251+#include <memory>
252 #include <string>
253
254 #include "type-tagger.h"
255@@ -29,6 +30,8 @@
256 namespace app_launch
257 {
258
259+class Registry;
260+
261 /** \brief The set of information that is used to uniquely identify an
262 application in Ubuntu.
263
264@@ -104,9 +107,21 @@
265 It can be used, but is slower than parse() if you've got well formed data
266 already.
267
268+ \note This will use the default registry instance, it is generally
269+ recommended to have your own instead of using the default.
270+
271 \param sappid String with the concatenated AppID
272 */
273 static AppID find(const std::string& sappid);
274+ /** Find is a more tollerant version of parse(), it handles legacy applications,
275+ short AppIDs ($package_$app) and other forms of that are in common usage.
276+ It can be used, but is slower than parse() if you've got well formed data
277+ already.
278+
279+ \param registry Registry instance to use for persistant connections
280+ \param sappid String with the concatenated AppID
281+ */
282+ static AppID find(const std::shared_ptr<Registry>& registry, const std::string& sappid);
283 /** Check to see whether a string is a valid AppID string
284
285 \param sappid String with the concatenated AppID
286@@ -130,6 +145,9 @@
287 /** Find the AppID for an application where you only know the package
288 name.
289
290+ \note This will use the default registry instance, it is generally
291+ recommended to have your own instead of using the default.
292+
293 \param package Name of the package
294 \param appwildcard Specification of how to search the manifest for apps
295 \param versionwildcard Specification of how to search for the version
296@@ -140,6 +158,9 @@
297 /** Find the AppID for an application where you know the package
298 name and application name.
299
300+ \note This will use the default registry instance, it is generally
301+ recommended to have your own instead of using the default.
302+
303 \param package Name of the package
304 \param appname Name of the application
305 \param versionwildcard Specification of how to search for the version
306@@ -149,15 +170,55 @@
307 VersionWildcard versionwildcard = VersionWildcard::CURRENT_USER_VERSION);
308 /** Create an AppID providing known strings of packages and names
309
310+ \note This will use the default registry instance, it is generally
311+ recommended to have your own instead of using the default.
312+
313 \param package Name of the package
314 \param appname Name of the application
315 \param version Version of the package
316 */
317 static AppID discover(const std::string& package, const std::string& appname, const std::string& version);
318+
319+ /** Find the AppID for an application where you only know the package
320+ name.
321+
322+ \param registry Registry instance to use for persistant connections
323+ \param package Name of the package
324+ \param appwildcard Specification of how to search the manifest for apps
325+ \param versionwildcard Specification of how to search for the version
326+ */
327+ static AppID discover(const std::shared_ptr<Registry>& registry,
328+ const std::string& package,
329+ ApplicationWildcard appwildcard = ApplicationWildcard::FIRST_LISTED,
330+ VersionWildcard versionwildcard = VersionWildcard::CURRENT_USER_VERSION);
331+ /** Find the AppID for an application where you know the package
332+ name and application name.
333+
334+ \param registry Registry instance to use for persistant connections
335+ \param package Name of the package
336+ \param appname Name of the application
337+ \param versionwildcard Specification of how to search for the version
338+ */
339+ static AppID discover(const std::shared_ptr<Registry>& registry,
340+ const std::string& package,
341+ const std::string& appname,
342+ VersionWildcard versionwildcard = VersionWildcard::CURRENT_USER_VERSION);
343+ /** Create an AppID providing known strings of packages and names
344+
345+ \param registry Registry instance to use for persistant connections
346+ \param package Name of the package
347+ \param appname Name of the application
348+ \param version Version of the package
349+ */
350+ static AppID discover(const std::shared_ptr<Registry>& registry,
351+ const std::string& package,
352+ const std::string& appname,
353+ const std::string& version);
354 };
355
356 bool operator==(const AppID& a, const AppID& b);
357 bool operator!=(const AppID& a, const AppID& b);
358+bool operator<(const AppID& a, const AppID& b);
359
360 } // namespace app_launch
361 } // namespace ubuntu
362
363=== modified file 'libubuntu-app-launch/application-impl-click.cpp'
364--- libubuntu-app-launch/application-impl-click.cpp 2016-09-06 16:14:40 +0000
365+++ libubuntu-app-launch/application-impl-click.cpp 2016-09-06 16:14:41 +0000
366@@ -58,6 +58,115 @@
367 return _appid;
368 }
369
370+/** Check to see if this AppID has a desktop file that is in our link
371+ farm built by Click. Click puts a symoblic link there for every
372+ valid AppID.
373+
374+ \param appid Application ID to check
375+ \param registry Persistent connections to use
376+*/
377+bool Click::hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry)
378+{
379+ std::string appiddesktop = std::string(appid) + ".desktop";
380+ gchar* click_link = nullptr;
381+ const gchar* link_farm_dir = g_getenv("UBUNTU_APP_LAUNCH_LINK_FARM");
382+ if (G_LIKELY(link_farm_dir == nullptr))
383+ {
384+ click_link =
385+ g_build_filename(g_get_user_cache_dir(), "ubuntu-app-launch", "desktop", appiddesktop.c_str(), NULL);
386+ }
387+ else
388+ {
389+ click_link = g_build_filename(link_farm_dir, appiddesktop.c_str(), NULL);
390+ }
391+
392+ bool click = g_file_test(click_link, G_FILE_TEST_EXISTS);
393+ g_free(click_link);
394+
395+ return click;
396+}
397+
398+/** Tries to get the Click manifest for a package. If it can successfully
399+ get the manifest returns true.
400+
401+ \param package Name of the package
402+ \param registry Persistent connections to use
403+*/
404+bool Click::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry)
405+{
406+ return registry->impl->getClickManifest(package) != nullptr;
407+}
408+
409+/** Verifies the applicaiton name by getting the list of applications
410+ in the package manifest and seeing if the appname is in the list.
411+
412+ \param package Name of the package
413+ \param appname Name of the application
414+ \param registry Persistent connections to use
415+*/
416+bool Click::verifyAppname(const AppID::Package& package,
417+ const AppID::AppName& appname,
418+ const std::shared_ptr<Registry>& registry)
419+{
420+ auto manifest = registry->impl->getClickManifest(package);
421+ auto apps = manifestApps(manifest);
422+
423+ return std::find_if(apps.begin(), apps.end(), [&appname](const AppID::AppName& listApp) -> bool {
424+ return appname.value() == listApp.value();
425+ }) != apps.end();
426+}
427+
428+/** Finds an application name based on a wildcard search. Gets the list
429+ from the manifest, and then returns a value from that list.
430+
431+ \param package Name of the package
432+ \param card Wildcard to search as
433+ \param registry Persistent connections to use
434+*/
435+AppID::AppName Click::findAppname(const AppID::Package& package,
436+ AppID::ApplicationWildcard card,
437+ const std::shared_ptr<Registry>& registry)
438+{
439+ auto manifest = registry->impl->getClickManifest(package);
440+ auto apps = manifestApps(manifest);
441+
442+ if (apps.empty())
443+ {
444+ throw std::runtime_error("No apps in package '" + package.value() + "' to find");
445+ }
446+
447+ switch (card)
448+ {
449+ case AppID::ApplicationWildcard::FIRST_LISTED:
450+ return *apps.begin();
451+ case AppID::ApplicationWildcard::LAST_LISTED:
452+ return *apps.rbegin();
453+ case AppID::ApplicationWildcard::ONLY_LISTED:
454+ if (apps.size() != 1)
455+ {
456+ throw std::runtime_error("More than a single app in package '" + package.value() +
457+ "' when requested to find only app");
458+ }
459+ return *apps.begin();
460+ }
461+
462+ throw std::logic_error("Got a value of the app wildcard enum that can't exist");
463+}
464+
465+/** Find the version of a package that that is requested
466+
467+ \param package Name of the package
468+ \param appname Name of the application (not used)
469+ \param registry Persistent connections to use
470+*/
471+AppID::Version Click::findVersion(const AppID::Package& package,
472+ const AppID::AppName& appname,
473+ const std::shared_ptr<Registry>& registry)
474+{
475+ auto manifest = registry->impl->getClickManifest(package);
476+ return manifestVersion(manifest);
477+}
478+
479 std::shared_ptr<Application::Info> Click::info()
480 {
481 if (!_info)
482
483=== modified file 'libubuntu-app-launch/application-impl-click.h'
484--- libubuntu-app-launch/application-impl-click.h 2016-09-06 16:14:40 +0000
485+++ libubuntu-app-launch/application-impl-click.h 2016-09-06 16:14:41 +0000
486@@ -32,6 +32,20 @@
487 namespace app_impls
488 {
489
490+/** Application Implmentation for Click packages. Click packages
491+ are installed via the click tool and have information avaialable
492+ on them via libclick. There is one version per-user on the system
493+ and a Ubuntu App Launch hook makes a link to each of those versions
494+ in the user's cache directory. Click ensures this is up-to-date.
495+
496+ Application IDs for Click packages are the standard it was built on.
497+ Typically a package name is "$(application).$(developer id)" though
498+ there isn't a requirement in the local Click tools to require that. The
499+ appname element is gotten from the JSON manifest in the Click package and
500+ should reference a desktop file. All Click packages also have a version.
501+
502+ More info: http://click.readthedocs.io/
503+*/
504 class Click : public Base
505 {
506 public:
507@@ -49,6 +63,19 @@
508 std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override;
509 std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override;
510
511+ static bool hasAppId(const AppID& appId, const std::shared_ptr<Registry>& registry);
512+
513+ static bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry);
514+ static bool verifyAppname(const AppID::Package& package,
515+ const AppID::AppName& appname,
516+ const std::shared_ptr<Registry>& registry);
517+ static AppID::AppName findAppname(const AppID::Package& package,
518+ AppID::ApplicationWildcard card,
519+ const std::shared_ptr<Registry>& registry);
520+ static AppID::Version findVersion(const AppID::Package& package,
521+ const AppID::AppName& appname,
522+ const std::shared_ptr<Registry>& registry);
523+
524 private:
525 AppID _appid;
526
527
528=== modified file 'libubuntu-app-launch/application-impl-legacy.cpp'
529--- libubuntu-app-launch/application-impl-legacy.cpp 2016-09-06 16:14:40 +0000
530+++ libubuntu-app-launch/application-impl-legacy.cpp 2016-09-06 16:14:41 +0000
531@@ -57,7 +57,7 @@
532
533 std::tuple<std::string, std::shared_ptr<GKeyFile>, std::string> keyfileForApp(const AppID::AppName& name)
534 {
535- std::string desktopName = name.value() + ".desktop";
536+ auto desktopName = name.value() + ".desktop";
537 std::string desktopPath;
538 auto keyfilecheck = [desktopName, &desktopPath](const std::string& dir) -> std::shared_ptr<GKeyFile> {
539 auto fullname = g_build_filename(dir.c_str(), "applications", desktopName.c_str(), nullptr);
540@@ -99,14 +99,110 @@
541
542 std::shared_ptr<Application::Info> Legacy::info()
543 {
544- if (!appinfo_)
545- {
546- appinfo_ = std::make_shared<app_info::Desktop>(_keyfile, _basedir, app_info::DesktopFlags::ALLOW_NO_DISPLAY,
547- _registry);
548- }
549 return appinfo_;
550 }
551
552+/** Checks the AppID by ensuring the version and package are empty
553+ then looks for the application.
554+
555+ \param appid AppID to check
556+ \param registry persistent connections to use
557+*/
558+bool Legacy::hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry)
559+{
560+ try
561+ {
562+ if (!appid.version.value().empty())
563+ {
564+ return false;
565+ }
566+
567+ return verifyAppname(appid.package, appid.appname, registry);
568+ }
569+ catch (std::runtime_error& e)
570+ {
571+ return false;
572+ }
573+}
574+
575+/** Ensure the package is empty
576+
577+ \param package Container name
578+ \param registry persistent connections to use
579+*/
580+bool Legacy::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry)
581+{
582+ return package.value().empty();
583+}
584+
585+/** Looks for an application by looking through the system and user
586+ application directories to find the desktop file.
587+
588+ \param package Container name
589+ \param appname Application name to look for
590+ \param registry persistent connections to use
591+*/
592+bool Legacy::verifyAppname(const AppID::Package& package,
593+ const AppID::AppName& appname,
594+ const std::shared_ptr<Registry>& registry)
595+{
596+ if (!verifyPackage(package, registry))
597+ {
598+ throw std::runtime_error{"Invalid Legacy package: " + std::string(package)};
599+ }
600+
601+ auto desktop = std::string(appname) + ".desktop";
602+ auto evaldir = [&desktop](const gchar* dir) -> bool {
603+ char* fulldir = g_build_filename(dir, "applications", desktop.c_str(), nullptr);
604+ gboolean found = g_file_test(fulldir, G_FILE_TEST_EXISTS);
605+ g_free(fulldir);
606+ return found == TRUE;
607+ };
608+
609+ if (evaldir(g_get_user_data_dir()))
610+ {
611+ return true;
612+ }
613+
614+ const char* const* data_dirs = g_get_system_data_dirs();
615+ for (int i = 0; data_dirs[i] != nullptr; i++)
616+ {
617+ if (evaldir(data_dirs[i]))
618+ {
619+ return true;
620+ }
621+ }
622+
623+ return false;
624+}
625+
626+/** We don't really have a way to implement this for Legacy, any
627+ search wouldn't really make sense. We just throw an error.
628+
629+ \param package Container name
630+ \param card Application search paths
631+ \param registry persistent connections to use
632+*/
633+AppID::AppName Legacy::findAppname(const AppID::Package& package,
634+ AppID::ApplicationWildcard card,
635+ const std::shared_ptr<Registry>& registry)
636+{
637+ throw std::runtime_error("Legacy apps can't be discovered by package");
638+}
639+
640+/** Function to return an empty string
641+
642+ \param package Container name (unused)
643+ \param appname Application name (unused)
644+ \param registry persistent connections to use (unused)
645+*/
646+AppID::Version Legacy::findVersion(const AppID::Package& package,
647+ const AppID::AppName& appname,
648+ const std::shared_ptr<Registry>& registry)
649+{
650+ return AppID::Version::from_raw({});
651+}
652+
653 static const std::regex desktop_remover("^(.*)\\.desktop$");
654
655 std::list<std::shared_ptr<Application>> Legacy::list(const std::shared_ptr<Registry>& registry)
656
657=== modified file 'libubuntu-app-launch/application-impl-legacy.h'
658--- libubuntu-app-launch/application-impl-legacy.h 2016-09-06 16:14:40 +0000
659+++ libubuntu-app-launch/application-impl-legacy.h 2016-09-06 16:14:41 +0000
660@@ -31,6 +31,19 @@
661 namespace app_impls
662 {
663
664+/** Application Implementation for Legacy applications. These are applications
665+ that are typically installed as Debian packages on the base system. The
666+ standard place for them to put their desktop files is in /usr/share/applications
667+ though other directories may be used by setting the appropriate XDG environment
668+ variables. This implementation makes use of the GIO Desktop Appinfo functions
669+ which do caching of those files to make access faster.
670+
671+ AppIDs for legacy applications only include the Appname variable. Both the package
672+ and the version entries are empty strings. The appname variable is the filename
673+ of the desktop file describing the application with the ".desktop" suffix.
674+
675+ More info: https://specifications.freedesktop.org/desktop-entry-spec/latest/
676+*/
677 class Legacy : public Base
678 {
679 public:
680@@ -50,6 +63,19 @@
681 std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override;
682 std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override;
683
684+ static bool hasAppId(const AppID& appId, const std::shared_ptr<Registry>& registry);
685+
686+ static bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry);
687+ static bool verifyAppname(const AppID::Package& package,
688+ const AppID::AppName& appname,
689+ const std::shared_ptr<Registry>& registry);
690+ static AppID::AppName findAppname(const AppID::Package& package,
691+ AppID::ApplicationWildcard card,
692+ const std::shared_ptr<Registry>& registry);
693+ static AppID::Version findVersion(const AppID::Package& package,
694+ const AppID::AppName& appname,
695+ const std::shared_ptr<Registry>& registry);
696+
697 private:
698 AppID::AppName _appname;
699 std::string _basedir;
700
701=== modified file 'libubuntu-app-launch/application-impl-libertine.cpp'
702--- libubuntu-app-launch/application-impl-libertine.cpp 2016-09-06 16:14:40 +0000
703+++ libubuntu-app-launch/application-impl-libertine.cpp 2016-09-06 16:14:41 +0000
704@@ -106,6 +106,103 @@
705 return keyfile;
706 }
707
708+/** Checks the AppID by making sure the version is "0.0" and then
709+ calling verifyAppname() to check the rest.
710+
711+ \param appid AppID to check
712+ \param registry persistent connections to use
713+*/
714+bool Libertine::hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry)
715+{
716+ try
717+ {
718+ if (appid.version.value() != "0.0")
719+ {
720+ return false;
721+ }
722+
723+ return verifyAppname(appid.package, appid.appname, registry);
724+ }
725+ catch (std::runtime_error& e)
726+ {
727+ return false;
728+ }
729+}
730+
731+/** Verify a package name by getting the list of containers from
732+ liblibertine and ensuring it is in that list.
733+
734+ \param package Container name
735+ \param registry persistent connections to use
736+*/
737+bool Libertine::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry)
738+{
739+ auto containers = std::shared_ptr<gchar*>(libertine_list_containers(), g_strfreev);
740+
741+ for (int i = 0; containers.get()[i] != nullptr; i++)
742+ {
743+ auto container = containers.get()[i];
744+ if (container == package.value())
745+ {
746+ return true;
747+ }
748+ }
749+
750+ return false;
751+}
752+
753+/** Gets the list of applications from the container using liblibertine
754+ and see if @appname is in that list.
755+
756+ \param package Container name
757+ \param appname Application name to look for
758+ \param registry persistent connections to use
759+*/
760+bool Libertine::verifyAppname(const AppID::Package& package,
761+ const AppID::AppName& appname,
762+ const std::shared_ptr<Registry>& registry)
763+{
764+ auto apps = std::shared_ptr<gchar*>(libertine_list_apps_for_container(package.value().c_str()), g_strfreev);
765+
766+ for (int i = 0; apps.get()[i] != nullptr; i++)
767+ {
768+ auto appid = AppID::parse(apps.get()[i]);
769+ if (appid.appname.value() == appname.value())
770+ {
771+ return true;
772+ }
773+ }
774+
775+ return false;
776+}
777+
778+/** We don't really have a way to implement this for Libertine, any
779+ search wouldn't really make sense. We just throw an error.
780+
781+ \param package Container name
782+ \param card Application search paths
783+ \param registry persistent connections to use
784+*/
785+AppID::AppName Libertine::findAppname(const AppID::Package& package,
786+ AppID::ApplicationWildcard card,
787+ const std::shared_ptr<Registry>& registry)
788+{
789+ throw std::runtime_error("Legacy apps can't be discovered by package");
790+}
791+
792+/** Function to return "0.0"
793+
794+ \param package Container name (unused)
795+ \param appname Application name (unused)
796+ \param registry persistent connections to use (unused)
797+*/
798+AppID::Version Libertine::findVersion(const AppID::Package& package,
799+ const AppID::AppName& appname,
800+ const std::shared_ptr<Registry>& registry)
801+{
802+ return AppID::Version::from_raw("0.0");
803+}
804+
805 std::list<std::shared_ptr<Application>> Libertine::list(const std::shared_ptr<Registry>& registry)
806 {
807 std::list<std::shared_ptr<Application>> applist;
808
809=== modified file 'libubuntu-app-launch/application-impl-libertine.h'
810--- libubuntu-app-launch/application-impl-libertine.h 2016-09-06 16:14:40 +0000
811+++ libubuntu-app-launch/application-impl-libertine.h 2016-09-06 16:14:41 +0000
812@@ -30,6 +30,23 @@
813 namespace app_impls
814 {
815
816+/** Application Implmentation for the Libertine container system. Libertine
817+ sets up containers that are read/write on a read only system, to all for
818+ more dynamic packaging systems (like deb) to work. This provides some
819+ compatibility for older applications or those who are only distributed in
820+ packaging systems requiring full system access.
821+
822+ Application IDs for Libertine applications have the package field as the
823+ name of the container. The appname is similar to that of the Legacy() implementation
824+ as the filename of the desktop file defining the application without the
825+ ".desktop" suffix. UAL has no way to know the version, so it is always hard
826+ coded to "0.0".
827+
828+ Libertine applications always are setup with XMir and started using the
829+ libertine-launch utility which configures the environment for the container.
830+
831+ More info: https://wiki.ubuntu.com/Touch/Libertine
832+*/
833 class Libertine : public Base
834 {
835 public:
836@@ -51,6 +68,19 @@
837 std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override;
838 std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override;
839
840+ static bool hasAppId(const AppID& appId, const std::shared_ptr<Registry>& registry);
841+
842+ static bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry);
843+ static bool verifyAppname(const AppID::Package& package,
844+ const AppID::AppName& appname,
845+ const std::shared_ptr<Registry>& registry);
846+ static AppID::AppName findAppname(const AppID::Package& package,
847+ AppID::ApplicationWildcard card,
848+ const std::shared_ptr<Registry>& registry);
849+ static AppID::Version findVersion(const AppID::Package& package,
850+ const AppID::AppName& appname,
851+ const std::shared_ptr<Registry>& registry);
852+
853 private:
854 AppID::Package _container;
855 AppID::AppName _appname;
856
857=== modified file 'libubuntu-app-launch/application.cpp'
858--- libubuntu-app-launch/application.cpp 2016-08-17 15:24:23 +0000
859+++ libubuntu-app-launch/application.cpp 2016-09-06 16:14:41 +0000
860@@ -18,7 +18,6 @@
861 */
862
863 extern "C" {
864-#include "app-info.h"
865 #include "ubuntu-app-launch.h"
866 }
867
868@@ -26,7 +25,9 @@
869 #include "application-impl-legacy.h"
870 #include "application-impl-libertine.h"
871 #include "application.h"
872+#include "registry.h"
873
874+#include <functional>
875 #include <iostream>
876 #include <regex>
877
878@@ -42,22 +43,21 @@
879 throw std::runtime_error("AppID is empty");
880 }
881
882- std::string sappid = appid;
883- if (app_info_click(sappid.c_str(), NULL, NULL))
884+ if (app_impls::Click::hasAppId(appid, registry))
885 {
886 return std::make_shared<app_impls::Click>(appid, registry);
887 }
888- else if (app_info_libertine(sappid.c_str(), NULL, NULL))
889+ else if (app_impls::Libertine::hasAppId(appid, registry))
890 {
891 return std::make_shared<app_impls::Libertine>(appid.package, appid.appname, registry);
892 }
893- else if (app_info_legacy(sappid.c_str(), NULL, NULL))
894+ else if (app_impls::Legacy::hasAppId(appid, registry))
895 {
896 return std::make_shared<app_impls::Legacy>(appid.appname, registry);
897 }
898 else
899 {
900- throw std::runtime_error("Invalid app ID: " + sappid);
901+ throw std::runtime_error("Invalid app ID: " + std::string(appid));
902 }
903 }
904
905@@ -106,6 +106,12 @@
906
907 AppID AppID::find(const std::string& sappid)
908 {
909+ auto registry = Registry::getDefault();
910+ return find(registry, sappid);
911+}
912+
913+AppID AppID::find(const std::shared_ptr<Registry>& registry, const std::string& sappid)
914+{
915 std::smatch match;
916
917 if (std::regex_match(sappid, match, full_appid_regex))
918@@ -115,7 +121,7 @@
919 }
920 else if (std::regex_match(sappid, match, short_appid_regex))
921 {
922- return discover(match[1].str(), match[2].str());
923+ return discover(registry, match[1].str(), match[2].str());
924 }
925 else if (std::regex_match(sappid, match, legacy_appid_regex))
926 {
927@@ -156,67 +162,183 @@
928 a.version.value() != b.version.value();
929 }
930
931+/** Convert each AppID to a string and then compare the strings */
932+bool operator<(const AppID& a, const AppID& b)
933+{
934+ return std::string(a) < std::string(b);
935+}
936+
937 bool AppID::empty() const
938 {
939 return package.value().empty() && appname.value().empty() && version.value().empty();
940 }
941
942-std::string app_wildcard(AppID::ApplicationWildcard card)
943-{
944- switch (card)
945- {
946- case AppID::ApplicationWildcard::FIRST_LISTED:
947- return "first-listed-app";
948- case AppID::ApplicationWildcard::LAST_LISTED:
949- return "last-listed-app";
950- case AppID::ApplicationWildcard::ONLY_LISTED:
951- return "only-listed-app";
952- }
953-
954- return "";
955-}
956-
957-std::string ver_wildcard(AppID::VersionWildcard card)
958-{
959- switch (card)
960- {
961- case AppID::VersionWildcard::CURRENT_USER_VERSION:
962- return "current-user-version";
963- }
964-
965- return "";
966+/** Basically we're making our own VTable of static functions. Static
967+ functions don't go in the normal VTables, so we can't use our class
968+ inheritance here to help. So we're just packing these puppies into
969+ a data structure and iterating over it. */
970+struct DiscoverTools
971+{
972+ std::function<bool(const AppID::Package& package, const std::shared_ptr<Registry>& registry)> verifyPackage;
973+ std::function<bool(
974+ const AppID::Package& package, const AppID::AppName& appname, const std::shared_ptr<Registry>& registry)>
975+ verifyAppname;
976+ std::function<AppID::AppName(
977+ const AppID::Package& package, AppID::ApplicationWildcard card, const std::shared_ptr<Registry>& registry)>
978+ findAppname;
979+ std::function<AppID::Version(
980+ const AppID::Package& package, const AppID::AppName& appname, const std::shared_ptr<Registry>& registry)>
981+ findVersion;
982+ std::function<bool(const AppID& appid, const std::shared_ptr<Registry>& registry)> hasAppId;
983+};
984+
985+/** The tools in order that they should be used */
986+static const std::vector<DiscoverTools> discoverTools{
987+ /* Click */
988+ {app_impls::Click::verifyPackage, app_impls::Click::verifyAppname, app_impls::Click::findAppname,
989+ app_impls::Click::findVersion, app_impls::Click::hasAppId},
990+ /* Libertine */
991+ {app_impls::Libertine::verifyPackage, app_impls::Libertine::verifyAppname, app_impls::Libertine::findAppname,
992+ app_impls::Libertine::findVersion, app_impls::Libertine::hasAppId},
993+ /* Legacy */
994+ {app_impls::Legacy::verifyPackage, app_impls::Legacy::verifyAppname, app_impls::Legacy::findAppname,
995+ app_impls::Legacy::findVersion, app_impls::Legacy::hasAppId}};
996+
997+AppID AppID::discover(const std::shared_ptr<Registry>& registry,
998+ const std::string& package,
999+ const std::string& appname,
1000+ const std::string& version)
1001+{
1002+ auto pkg = AppID::Package::from_raw(package);
1003+
1004+ for (const auto& tools : discoverTools)
1005+ {
1006+ /* Figure out which type we have */
1007+ try
1008+ {
1009+ if (tools.verifyPackage(pkg, registry))
1010+ {
1011+ auto app = AppID::AppName::from_raw({});
1012+
1013+ if (appname.empty() || appname == "first-listed-app")
1014+ {
1015+ app = tools.findAppname(pkg, ApplicationWildcard::FIRST_LISTED, registry);
1016+ }
1017+ else if (appname == "last-listed-app")
1018+ {
1019+ app = tools.findAppname(pkg, ApplicationWildcard::LAST_LISTED, registry);
1020+ }
1021+ else if (appname == "only-listed-app")
1022+ {
1023+ app = tools.findAppname(pkg, ApplicationWildcard::ONLY_LISTED, registry);
1024+ }
1025+ else
1026+ {
1027+ app = AppID::AppName::from_raw(appname);
1028+ if (!tools.verifyAppname(pkg, app, registry))
1029+ {
1030+ throw std::runtime_error("App name passed in is not valid for this package type");
1031+ }
1032+ }
1033+
1034+ auto ver = AppID::Version::from_raw({});
1035+ if (version.empty() || version == "current-user-version")
1036+ {
1037+ ver = tools.findVersion(pkg, app, registry);
1038+ }
1039+ else
1040+ {
1041+ ver = AppID::Version::from_raw(version);
1042+ if (!tools.hasAppId({pkg, app, ver}, registry))
1043+ {
1044+ throw std::runtime_error("Invalid version passed for this package type");
1045+ }
1046+ }
1047+
1048+ return AppID{pkg, app, ver};
1049+ }
1050+ }
1051+ catch (std::runtime_error& e)
1052+ {
1053+ continue;
1054+ }
1055+ }
1056+
1057+ return {};
1058+}
1059+
1060+AppID AppID::discover(const std::shared_ptr<Registry>& registry,
1061+ const std::string& package,
1062+ ApplicationWildcard appwildcard,
1063+ VersionWildcard versionwildcard)
1064+{
1065+ auto pkg = AppID::Package::from_raw(package);
1066+
1067+ for (const auto& tools : discoverTools)
1068+ {
1069+ try
1070+ {
1071+ if (tools.verifyPackage(pkg, registry))
1072+ {
1073+ auto app = tools.findAppname(pkg, appwildcard, registry);
1074+ auto ver = tools.findVersion(pkg, app, registry);
1075+ return AppID{pkg, app, ver};
1076+ }
1077+ }
1078+ catch (std::runtime_error& e)
1079+ {
1080+ /* Normal, try another */
1081+ continue;
1082+ }
1083+ }
1084+
1085+ return {};
1086+}
1087+
1088+AppID AppID::discover(const std::shared_ptr<Registry>& registry,
1089+ const std::string& package,
1090+ const std::string& appname,
1091+ VersionWildcard versionwildcard)
1092+{
1093+ auto pkg = AppID::Package::from_raw(package);
1094+ auto app = AppID::AppName::from_raw(appname);
1095+
1096+ for (const auto& tools : discoverTools)
1097+ {
1098+ try
1099+ {
1100+ if (tools.verifyPackage(pkg, registry) && tools.verifyAppname(pkg, app, registry))
1101+ {
1102+ auto ver = tools.findVersion(pkg, app, registry);
1103+ return AppID{pkg, app, ver};
1104+ }
1105+ }
1106+ catch (std::runtime_error& e)
1107+ {
1108+ /* Normal, try another */
1109+ continue;
1110+ }
1111+ }
1112+
1113+ return {};
1114 }
1115
1116 AppID AppID::discover(const std::string& package, const std::string& appname, const std::string& version)
1117 {
1118- auto cappid = ubuntu_app_launch_triplet_to_app_id(package.c_str(), appname.c_str(), version.c_str());
1119-
1120- auto appid = cappid != nullptr ? AppID::parse(cappid) : AppID::parse("");
1121-
1122- g_free(cappid);
1123-
1124- return appid;
1125+ auto registry = Registry::getDefault();
1126+ return discover(registry, package, appname, version);
1127 }
1128
1129 AppID AppID::discover(const std::string& package, ApplicationWildcard appwildcard, VersionWildcard versionwildcard)
1130 {
1131- return discover(package, app_wildcard(appwildcard), ver_wildcard(versionwildcard));
1132+ auto registry = Registry::getDefault();
1133+ return discover(registry, package, appwildcard, versionwildcard);
1134 }
1135
1136 AppID AppID::discover(const std::string& package, const std::string& appname, VersionWildcard versionwildcard)
1137 {
1138- auto appid = discover(package, appname, ver_wildcard(versionwildcard));
1139-
1140- if (appid.empty())
1141- {
1142- /* If we weren't able to go that route, we can see if it's libertine */
1143- if (app_info_libertine((package + "_" + appname + "_0.0").c_str(), nullptr, nullptr))
1144- {
1145- appid = AppID(Package::from_raw(package), AppName::from_raw(appname), Version::from_raw("0.0"));
1146- }
1147- }
1148-
1149- return appid;
1150+ auto registry = Registry::getDefault();
1151+ return discover(registry, package, appname, versionwildcard);
1152 }
1153
1154 enum class oom::Score : std::int32_t
1155
1156=== modified file 'libubuntu-app-launch/registry.cpp'
1157--- libubuntu-app-launch/registry.cpp 2016-08-17 15:24:23 +0000
1158+++ libubuntu-app-launch/registry.cpp 2016-09-06 16:14:41 +0000
1159@@ -91,7 +91,7 @@
1160 std::list<std::shared_ptr<Application>> apps;
1161 for (auto instance : instanceset)
1162 {
1163- auto appid = AppID::find(instance);
1164+ auto appid = AppID::find(connection, instance);
1165 auto app = Application::create(appid, connection);
1166 apps.push_back(app);
1167 }
1168
1169=== modified file 'libubuntu-app-launch/ubuntu-app-launch.cpp'
1170--- libubuntu-app-launch/ubuntu-app-launch.cpp 2016-09-06 16:14:40 +0000
1171+++ libubuntu-app-launch/ubuntu-app-launch.cpp 2016-09-06 16:14:41 +0000
1172@@ -27,7 +27,6 @@
1173 #include <errno.h>
1174 #include <zeitgeist.h>
1175
1176-#include "app-info.h"
1177 #include "ubuntu-app-launch-trace.h"
1178 #include "helpers.h"
1179 #include "ual-tracepoint.h"
1180@@ -948,16 +947,24 @@
1181 {
1182 g_return_val_if_fail(pkg != NULL, NULL);
1183
1184- /* Check if is a libertine container */
1185- gchar * libertinepath = g_build_filename(g_get_user_cache_dir(), "libertine-container", pkg, NULL);
1186- gboolean libcontainer = g_file_test(libertinepath, G_FILE_TEST_EXISTS);
1187- g_free(libertinepath);
1188-
1189- if (libcontainer) {
1190- return libertine_triplet_to_app_id(pkg, app, ver);
1191- } else {
1192- return click_triplet_to_app_id(pkg, app, ver);
1193- }
1194+ std::string package{pkg};
1195+ std::string appname;
1196+ std::string version;
1197+
1198+ if (app != nullptr) {
1199+ appname = app;
1200+ }
1201+
1202+ if (ver != nullptr) {
1203+ version = ver;
1204+ }
1205+
1206+ auto appid = ubuntu::app_launch::AppID::discover(package, appname, version);
1207+ if (appid.empty()) {
1208+ return nullptr;
1209+ }
1210+
1211+ return g_strdup(std::string(appid).c_str());
1212 }
1213
1214 /* Print an error if we couldn't start it */
1215
1216=== modified file 'tests/libual-cpp-test.cc'
1217--- tests/libual-cpp-test.cc 2016-09-06 16:14:40 +0000
1218+++ tests/libual-cpp-test.cc 2016-09-06 16:14:41 +0000
1219@@ -22,6 +22,7 @@
1220 #include <functional>
1221 #include <future>
1222 #include <gio/gio.h>
1223+#include <glib/gstdio.h>
1224 #include <gtest/gtest.h>
1225 #include <libdbustest/dbus-test.h>
1226 #include <numeric>
1227@@ -310,7 +311,7 @@
1228 }
1229 };
1230
1231-TEST_F(LibUAL, StartApplication)
1232+TEST_F(LibUAL, StartClickApplication)
1233 {
1234 DbusTestDbusMockObject* obj =
1235 dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);
1236@@ -367,7 +368,7 @@
1237 return;
1238 }
1239
1240-TEST_F(LibUAL, StartApplicationTest)
1241+TEST_F(LibUAL, StartClickApplicationTest)
1242 {
1243 DbusTestDbusMockObject* obj =
1244 dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);
1245@@ -395,7 +396,7 @@
1246 g_variant_unref(env);
1247 }
1248
1249-TEST_F(LibUAL, StopApplication)
1250+TEST_F(LibUAL, StopClickApplication)
1251 {
1252 DbusTestDbusMockObject* obj =
1253 dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL);
1254@@ -424,7 +425,7 @@
1255 std::string(CMAKE_SOURCE_DIR "/libertine-data/upstart/application-click-com.test.good_application_1.2.3.log"),
1256 app->instances()[0]->logPath());
1257
1258- appid = ubuntu::app_launch::AppID::find("single");
1259+ appid = ubuntu::app_launch::AppID::find(registry, "single");
1260 app = ubuntu::app_launch::Application::create(appid, registry);
1261
1262 ASSERT_LT(0, app->instances().size());
1263@@ -432,7 +433,7 @@
1264 EXPECT_EQ(std::string(CMAKE_SOURCE_DIR "/libertine-data/upstart/application-legacy-single-.log"),
1265 app->instances()[0]->logPath());
1266
1267- appid = ubuntu::app_launch::AppID::find("multiple");
1268+ appid = ubuntu::app_launch::AppID::find(registry, "multiple");
1269 app = ubuntu::app_launch::Application::create(appid, registry);
1270
1271 EXPECT_EQ(std::string(CMAKE_SOURCE_DIR "/libertine-data/upstart/application-legacy-multiple-2342345.log"),
1272@@ -454,9 +455,10 @@
1273 EXPECT_TRUE(app->instances()[0]->hasPid(300));
1274
1275 /* Check primary pid, which comes from Upstart */
1276+ EXPECT_TRUE(app->instances()[0]->isRunning());
1277 EXPECT_EQ(getpid(), app->instances()[0]->primaryPid());
1278
1279- auto multiappid = ubuntu::app_launch::AppID::find("multiple");
1280+ auto multiappid = ubuntu::app_launch::AppID::find(registry, "multiple");
1281 auto multiapp = ubuntu::app_launch::Application::create(multiappid, registry);
1282 auto instances = multiapp->instances();
1283 ASSERT_LT(0, instances.size());
1284@@ -488,7 +490,7 @@
1285 ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(cgmock, cgobject, NULL));
1286
1287 /* Legacy Single Instance */
1288- auto singleappid = ubuntu::app_launch::AppID::find("single");
1289+ auto singleappid = ubuntu::app_launch::AppID::find(registry, "single");
1290 auto singleapp = ubuntu::app_launch::Application::create(singleappid, registry);
1291
1292 ASSERT_LT(0, singleapp->instances().size());
1293@@ -517,50 +519,53 @@
1294
1295 /* Test with current-user-version, should return the version in the manifest */
1296 EXPECT_EQ("com.test.good_application_1.2.3",
1297- (std::string)ubuntu::app_launch::AppID::discover("com.test.good", "application"));
1298+ (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application"));
1299
1300 /* Test with version specified, shouldn't even read the manifest */
1301 EXPECT_EQ("com.test.good_application_1.2.4",
1302- (std::string)ubuntu::app_launch::AppID::discover("com.test.good", "application", "1.2.4"));
1303+ (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application", "1.2.4"));
1304
1305 /* Test with out a version or app, should return the version in the manifest */
1306- EXPECT_EQ("com.test.good_application_1.2.3", (std::string)ubuntu::app_launch::AppID::discover(
1307- "com.test.good", "first-listed-app", "current-user-version"));
1308+ EXPECT_EQ("com.test.good_application_1.2.3",
1309+ (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "first-listed-app",
1310+ "current-user-version"));
1311
1312 /* Make sure we can select the app from a list correctly */
1313 EXPECT_EQ("com.test.multiple_first_1.2.3",
1314 (std::string)ubuntu::app_launch::AppID::discover(
1315- "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED));
1316- EXPECT_EQ("com.test.multiple_first_1.2.3", (std::string)ubuntu::app_launch::AppID::discover("com.test.multiple"));
1317+ registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED));
1318+ EXPECT_EQ("com.test.multiple_first_1.2.3",
1319+ (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.multiple"));
1320 EXPECT_EQ("com.test.multiple_fifth_1.2.3",
1321 (std::string)ubuntu::app_launch::AppID::discover(
1322- "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED));
1323+ registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED));
1324 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(
1325- "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));
1326+ registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));
1327 EXPECT_EQ("com.test.good_application_1.2.3",
1328 (std::string)ubuntu::app_launch::AppID::discover(
1329- "com.test.good", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));
1330+ registry, "com.test.good", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));
1331
1332 /* A bunch that should be NULL */
1333- EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("com.test.no-hooks"));
1334- EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("com.test.no-json"));
1335- EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("com.test.no-object"));
1336- EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("com.test.no-version"));
1337+ EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-hooks"));
1338+ EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-json"));
1339+ EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-object"));
1340+ EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-version"));
1341
1342 /* Libertine tests */
1343- EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("container-name"));
1344- EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover("container-name", "not-exist"));
1345- EXPECT_EQ("container-name_test_0.0", (std::string)ubuntu::app_launch::AppID::discover("container-name", "test"));
1346+ EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name"));
1347+ EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name", "not-exist"));
1348+ EXPECT_EQ("container-name_test_0.0",
1349+ (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name", "test"));
1350 EXPECT_EQ("container-name_user-app_0.0",
1351- (std::string)ubuntu::app_launch::AppID::discover("container-name", "user-app"));
1352+ (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name", "user-app"));
1353 }
1354
1355 TEST_F(LibUAL, AppIdParse)
1356 {
1357 EXPECT_FALSE(ubuntu::app_launch::AppID::parse("com.ubuntu.test_test_123").empty());
1358- EXPECT_FALSE(ubuntu::app_launch::AppID::find("inkscape").empty());
1359+ EXPECT_FALSE(ubuntu::app_launch::AppID::find(registry, "inkscape").empty());
1360 EXPECT_FALSE(ubuntu::app_launch::AppID::parse("chatter.robert-ancell_chatter_2").empty());
1361- EXPECT_FALSE(ubuntu::app_launch::AppID::find("chatter.robert-ancell_chatter").empty());
1362+ EXPECT_FALSE(ubuntu::app_launch::AppID::find(registry, "chatter.robert-ancell_chatter").empty());
1363
1364 auto id = ubuntu::app_launch::AppID::parse("com.ubuntu.test_test_123");
1365
1366@@ -887,7 +892,7 @@
1367 dbus_test_dbus_mock_get_object(mock, "/com/test/application_legacy", "com.ubuntu.Upstart0_6.Job", NULL);
1368
1369 /* Check for a single-instance app */
1370- auto singleappid = ubuntu::app_launch::AppID::find("single");
1371+ auto singleappid = ubuntu::app_launch::AppID::find(registry, "single");
1372 auto singleapp = ubuntu::app_launch::Application::create(singleappid, registry);
1373
1374 singleapp->launch();
1375@@ -912,7 +917,7 @@
1376 ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(mock, obj, NULL));
1377
1378 /* Check for a multi-instance app */
1379- auto multipleappid = ubuntu::app_launch::AppID::find("multiple");
1380+ auto multipleappid = ubuntu::app_launch::AppID::find(registry, "multiple");
1381 auto multipleapp = ubuntu::app_launch::Application::create(multipleappid, registry);
1382
1383 multipleapp->launch();
1384@@ -1382,7 +1387,7 @@
1385 signal_increment, &resumed_count, nullptr);
1386
1387 /* Get our app object */
1388- auto appid = ubuntu::app_launch::AppID::find("com.test.good_application_1.2.3");
1389+ auto appid = ubuntu::app_launch::AppID::find(registry, "com.test.good_application_1.2.3");
1390 auto app = ubuntu::app_launch::Application::create(appid, registry);
1391
1392 ASSERT_EQ(1, app->instances().size());
1393@@ -1488,7 +1493,7 @@
1394 dbus_test_task_get_state(DBUS_TEST_TASK(zgmock)) != DBUS_TEST_TASK_STATE_RUNNING);
1395
1396 /* Get our app object */
1397- auto appid = ubuntu::app_launch::AppID::find("com.test.good_application_1.2.3");
1398+ auto appid = ubuntu::app_launch::AppID::find(registry, "com.test.good_application_1.2.3");
1399 auto app = ubuntu::app_launch::Application::create(appid, registry);
1400
1401 ASSERT_EQ(1, app->instances().size());
1402@@ -1569,7 +1574,7 @@
1403 EXPECT_EVENTUALLY_EQ(DBUS_TEST_TASK_STATE_RUNNING, dbus_test_task_get_state(DBUS_TEST_TASK(cgmock2)));
1404
1405 /* Get our app object */
1406- auto appid = ubuntu::app_launch::AppID::find("com.test.good_application_1.2.3");
1407+ auto appid = ubuntu::app_launch::AppID::find(registry, "com.test.good_application_1.2.3");
1408 auto app = ubuntu::app_launch::Application::create(appid, registry);
1409
1410 ASSERT_EQ(1, app->instances().size());
1411@@ -1780,7 +1785,7 @@
1412 EXPECT_EQ("Application", app->info()->name().value());
1413
1414 /* Correct values from a legacy */
1415- auto barid = ubuntu::app_launch::AppID::find("bar");
1416+ auto barid = ubuntu::app_launch::AppID::find(registry, "bar");
1417 EXPECT_THROW(ubuntu::app_launch::Application::create(barid, registry), std::runtime_error);
1418
1419 /* Correct values for libertine */

Subscribers

People subscribed via source and target branches