Merge lp:~ted/ubuntu-app-launch/registry-cleanup into lp:ubuntu-app-launch

Proposed by Ted Gould
Status: Merged
Approved by: Charles Kerr
Approved revision: 328
Merged at revision: 310
Proposed branch: lp:~ted/ubuntu-app-launch/registry-cleanup
Merge into: lp:ubuntu-app-launch
Diff against target: 4035 lines (+920/-965)
40 files modified
libubuntu-app-launch/app-store-base.cpp (+8/-8)
libubuntu-app-launch/app-store-base.h (+13/-15)
libubuntu-app-launch/app-store-legacy.cpp (+14/-18)
libubuntu-app-launch/app-store-legacy.h (+8/-15)
libubuntu-app-launch/app-store-libertine.cpp (+13/-17)
libubuntu-app-launch/app-store-libertine.h (+8/-15)
libubuntu-app-launch/app-store-snap.cpp (+19/-23)
libubuntu-app-launch/app-store-snap.h (+8/-15)
libubuntu-app-launch/application-impl-base.cpp (+2/-2)
libubuntu-app-launch/application-impl-base.h (+10/-10)
libubuntu-app-launch/application-impl-legacy.cpp (+8/-8)
libubuntu-app-launch/application-impl-legacy.h (+1/-1)
libubuntu-app-launch/application-impl-libertine.cpp (+8/-8)
libubuntu-app-launch/application-impl-libertine.h (+1/-1)
libubuntu-app-launch/application-impl-snap.cpp (+13/-13)
libubuntu-app-launch/application-impl-snap.h (+4/-4)
libubuntu-app-launch/application-info-desktop.cpp (+3/-3)
libubuntu-app-launch/application-info-desktop.h (+5/-3)
libubuntu-app-launch/application.cpp (+45/-34)
libubuntu-app-launch/helper-impl.h (+2/-2)
libubuntu-app-launch/helper.cpp (+15/-17)
libubuntu-app-launch/info-watcher-zg.cpp (+1/-1)
libubuntu-app-launch/info-watcher-zg.h (+1/-1)
libubuntu-app-launch/info-watcher.cpp (+16/-2)
libubuntu-app-launch/info-watcher.h (+10/-1)
libubuntu-app-launch/jobs-base.cpp (+98/-118)
libubuntu-app-launch/jobs-base.h (+33/-26)
libubuntu-app-launch/jobs-systemd.cpp (+312/-352)
libubuntu-app-launch/jobs-systemd.h (+6/-2)
libubuntu-app-launch/registry-impl.cpp (+34/-16)
libubuntu-app-launch/registry-impl.h (+52/-22)
libubuntu-app-launch/registry.cpp (+27/-49)
libubuntu-app-launch/registry.h (+6/-4)
tests/application-info-desktop.cpp (+2/-2)
tests/info-watcher-zg.cpp (+2/-3)
tests/jobs-base-test.cpp (+2/-2)
tests/jobs-systemd.cpp (+26/-22)
tests/libual-cpp-test.cc (+40/-49)
tests/list-apps.cpp (+6/-6)
tests/registry-mock.h (+38/-55)
To merge this branch: bzr merge lp:~ted/ubuntu-app-launch/registry-cleanup
Reviewer Review Type Date Requested Status
unity-api-1-bot continuous-integration Approve
Charles Kerr (community) Approve
James Henstridge Abstain
Review via email: mp+321240@code.launchpad.net

Commit message

Cleanup registry references to make them consistent

Description of the change

Basically all this branch is doing is getting rid of the std::shared_ptr<Registry> that were invading the codebase. They're kinda needed at the API level, but they were sneaking into everything and messing up the lifecycles, which is why the linked bug happened. The result of that is lots of little changes everywhere.

For anything that leaves the protection of the UAL API it keeps a reference to the Registry::Impl object and can use that to reference the internal structures. Everything else is just getting a Registry& to be able to find stuff again.

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

FAILED: Continuous integration, rev:317
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/281/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1879/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1886
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1668/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1668/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1668
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1668/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1668
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1668/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1668
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1668/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1668/console

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

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

Making it so the registry mock doesn't allocate two implementations

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

FAILED: Continuous integration, rev:318
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/282/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1881/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1888
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1670/console
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1670/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1670
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1670/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1670
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1670/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1670/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1670
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1670/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
James Henstridge (jamesh) wrote :

I don't really know this code base, but seeing a merge that converts a bunch of smart pointers into raw pointers (which is essentially what these reference variables are) raises some red flags.

Is there a guarantee that all instances of these classes will be destroyed before the associated Registry instance? If not, you're just replacing indeterminate cleanup of the registry object for dangling pointers.

Some alternatives that might do what you want include:

1. add a shutdown() method that will do the cleanup, and then in other classes check to see if the registry has been shut down before using it.

2. use std::weak_ptr, so these other classes won't keep the registry alive, but also won't leave a dangling reference.

It's a bit hard to say what would be appropriate without looking into it more.

review: Abstain
Revision history for this message
Ted Gould (ted) wrote :

Yes, generally that is the case. Here we're talking about all objects that are owned directly by the object that is the raw pointer. Their lifecycle is guaranteed to be shorter than it.

For objects that could have a longer lifecycle than the Registry object we're using the smart pointer on the implementation to keep track of the resources.

The problem the smartpointers were causing is that they make it so the initialization is funky. You don't have the smart pointer until after the objects is initialized, so objects that are created during its initialization could take the smart pointer as a parameter. So to resolve that we had lazy initialization of the objects which was basically spaghetti all over the codebase. And that is what caused the linked bug, a path that didn't lazy initialize all the subobjects that were needed.

319. By Ted Gould

Make it so that we don't set all the objects on init of Impl, just with setters and getters in the Registry object.

320. By Ted Gould

Switch the jobs over to smart pointers

321. By Ted Gould

Switch App Stores over to using smart poitners

322. By Ted Gould

Now that the Impl is ready at init we can get the bus then too

323. By Ted Gould

Adapt tests to changes

324. By Ted Gould

Clean up the handling of the ZG Watcher

325. By Ted Gould

Fix zgwatcher setup

326. By Ted Gould

Ensure the jobs-systemd tests have a legacy appstore to use

327. By Ted Gould

Change around the zgWatcher and realize the test is really just a placeholder

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

FAILED: Continuous integration, rev:327
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/299/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1910/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1917
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1699
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1699/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1699
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1699/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1699
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1699/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1699
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1699/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1699
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1699/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1699/console

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

review: Needs Fixing (continuous-integration)
Revision history for this message
James Henstridge (jamesh) wrote :

Having objects that aren't fully constructed by their constructor can make it difficult to reason about code, so it'd be good to avoid that if at all possible.

If all you need is for a class to be able to create a shared pointer of itself, then std::enable_shared_from_this might help:

http://www.cplusplus.com/reference/memory/enable_shared_from_this/

There are a few caveats though:

1. You probably don't want to be using shared_from_this() from within the constructor if the constructor can throw an exception: then the object in the shared pointer will be destroyed.

2. You want to make sure the class is always instantiated into a shared pointer. Making the constructor private and offering a factory function to create a shared_ptr is one way to handle this.

Revision history for this message
Ted Gould (ted) wrote :

Cool, I didn't know about that, and it would help in some situations. I was able to put the smart pointers back in most cases by using a two-stage init of the implementation object. Since it's only created once, and in private code, it's an easy one to do that with and actually solves all the issues in this (rather small) codebase.

Thanks for pushing me to fix it.

Revision history for this message
Charles Kerr (charlesk) wrote :

This patch is a little confusing.

I don't think I understand the problem enough. It sounds like you're saying a second registry was created because of cyclical instantiation?

If that's the case, some of these changes seem arbitrary, e.g. keeping a registry_ pointer in the Base instead of passing it as an argument the subclasses' methods. if it's not done being created when passed as an argument, surely it's got less chance of being done in the subclass' constructors? And if that's not the rationale, why move it into the parent class?

There are also a handful of cases (commented inline) where arguments are passed in when the parent class already has the same pointer, so the inconsistency seems like it's signalling something about how the cyclical initialization's being repaired, but I have to admit I'm missing it.

Passing Registry::Impl pointers around outside of the Registry seems very strange as well. Maybe this is just cosmetic, i.e. if Impl has evolved into a public class and needs to renamed or moved.

Other comments inline.

review: Needs Information
Revision history for this message
Ted Gould (ted) wrote :

Comments inline.

Generally the problem was that the initialization of most of the objects that the Registry was doing to do its work were initialized at basically random times. This lead to things like the bug that is attached.

The reason that this was is because they all wanted to have access the shared resources in the registry so they were waiting around for a std::shared_ptr<Registry> that we couldn't generate internally. So when they got a chance to grab it they'd scoop it up and initialize themselves.

So what the branch does is instead have those internal objects use std::shared_ptr<Registry::Impl> for most of those things so that it *is* something we can generate internally and pass around. Which means we can initialize all the objects when we build the Registry object. Which makes init significantly more predictable.

Also, it removes a couple raw pointers and some other minor internal API cleanups.

328. By Ted Gould

Remove arbitrary change

Revision history for this message
Charles Kerr (charlesk) wrote :

Thanks for the clarification.

Let's file the entire initialization sequence away in "things to simplify." I agree that could be out of scope for this fix; approving.

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

PASSED: Continuous integration, rev:328
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/303/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1914
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1921
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1703/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'libubuntu-app-launch/app-store-base.cpp'
--- libubuntu-app-launch/app-store-base.cpp 2017-02-28 21:15:46 +0000
+++ libubuntu-app-launch/app-store-base.cpp 2017-04-04 21:22:36 +0000
@@ -29,8 +29,8 @@
29namespace app_store29namespace app_store
30{30{
3131
32Base::Base()32Base::Base(const std::shared_ptr<Registry::Impl>& registry)
33 : info_watcher::Base({})33 : info_watcher::Base(registry)
34{34{
35}35}
3636
@@ -38,14 +38,14 @@
38{38{
39}39}
4040
41std::list<std::shared_ptr<Base>> Base::allAppStores()41std::list<std::shared_ptr<Base>> Base::allAppStores(const std::shared_ptr<Registry::Impl>& registry)
42{42{
43 return {43 return {
44 std::make_shared<Legacy>() /* Legacy */44 std::make_shared<Legacy>(registry) /* Legacy */
45 ,45 ,
46 std::make_shared<Libertine>() /* Libertine */46 std::make_shared<Libertine>(registry) /* Libertine */
47 ,47 ,
48 std::make_shared<Snap>() /* Snappy */48 std::make_shared<Snap>(registry) /* Snappy */
49 };49 };
50}50}
5151
5252
=== modified file 'libubuntu-app-launch/app-store-base.h'
--- libubuntu-app-launch/app-store-base.h 2017-02-24 20:39:24 +0000
+++ libubuntu-app-launch/app-store-base.h 2017-04-04 21:22:36 +0000
@@ -28,36 +28,34 @@
28{28{
29namespace app_launch29namespace app_launch
30{30{
31namespace app_impls
32{
33class Base;
34}
31namespace app_store35namespace app_store
32{36{
3337
34class Base : public info_watcher::Base38class Base : public info_watcher::Base
35{39{
36public:40public:
37 Base();41 Base(const std::shared_ptr<Registry::Impl>& registry);
38 virtual ~Base();42 virtual ~Base();
3943
40 /* Discover tools */44 /* Discover tools */
41 virtual bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry) = 0;45 virtual bool verifyPackage(const AppID::Package& package) = 0;
42 virtual bool verifyAppname(const AppID::Package& package,46 virtual bool verifyAppname(const AppID::Package& package, const AppID::AppName& appname) = 0;
43 const AppID::AppName& appname,47 virtual AppID::AppName findAppname(const AppID::Package& package, AppID::ApplicationWildcard card) = 0;
44 const std::shared_ptr<Registry>& registry) = 0;48 virtual AppID::Version findVersion(const AppID::Package& package, const AppID::AppName& appname) = 0;
45 virtual AppID::AppName findAppname(const AppID::Package& package,49 virtual bool hasAppId(const AppID& appid) = 0;
46 AppID::ApplicationWildcard card,
47 const std::shared_ptr<Registry>& registry) = 0;
48 virtual AppID::Version findVersion(const AppID::Package& package,
49 const AppID::AppName& appname,
50 const std::shared_ptr<Registry>& registry) = 0;
51 virtual bool hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry) = 0;
5250
53 /* Possible apps */51 /* Possible apps */
54 virtual std::list<std::shared_ptr<Application>> list(const std::shared_ptr<Registry>& registry) = 0;52 virtual std::list<std::shared_ptr<Application>> list() = 0;
5553
56 /* Application Creation */54 /* Application Creation */
57 virtual std::shared_ptr<app_impls::Base> create(const AppID& appid, const std::shared_ptr<Registry>& registry) = 0;55 virtual std::shared_ptr<app_impls::Base> create(const AppID& appid) = 0;
5856
59 /* Static get all */57 /* Static get all */
60 static std::list<std::shared_ptr<Base>> allAppStores();58 static std::list<std::shared_ptr<Base>> allAppStores(const std::shared_ptr<Registry::Impl>& registry);
61};59};
6260
63} // namespace app_store61} // namespace app_store
6462
=== modified file 'libubuntu-app-launch/app-store-legacy.cpp'
--- libubuntu-app-launch/app-store-legacy.cpp 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/app-store-legacy.cpp 2017-04-04 21:22:36 +0000
@@ -30,7 +30,8 @@
30namespace app_store30namespace app_store
31{31{
3232
33Legacy::Legacy()33Legacy::Legacy(const std::shared_ptr<Registry::Impl>& registry)
34 : Base(registry)
34{35{
35}36}
3637
@@ -44,7 +45,7 @@
44 \param appid AppID to check45 \param appid AppID to check
45 \param registry persistent connections to use46 \param registry persistent connections to use
46*/47*/
47bool Legacy::hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry)48bool Legacy::hasAppId(const AppID& appid)
48{49{
49 try50 try
50 {51 {
@@ -53,7 +54,7 @@
53 return false;54 return false;
54 }55 }
5556
56 return verifyAppname(appid.package, appid.appname, registry);57 return verifyAppname(appid.package, appid.appname);
57 }58 }
58 catch (std::runtime_error& e)59 catch (std::runtime_error& e)
59 {60 {
@@ -66,7 +67,7 @@
66 \param package Container name67 \param package Container name
67 \param registry persistent connections to use68 \param registry persistent connections to use
68*/69*/
69bool Legacy::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry)70bool Legacy::verifyPackage(const AppID::Package& package)
70{71{
71 return package.value().empty();72 return package.value().empty();
72}73}
@@ -78,11 +79,9 @@
78 \param appname Application name to look for79 \param appname Application name to look for
79 \param registry persistent connections to use80 \param registry persistent connections to use
80*/81*/
81bool Legacy::verifyAppname(const AppID::Package& package,82bool Legacy::verifyAppname(const AppID::Package& package, const AppID::AppName& appname)
82 const AppID::AppName& appname,
83 const std::shared_ptr<Registry>& registry)
84{83{
85 if (!verifyPackage(package, registry))84 if (!verifyPackage(package))
86 {85 {
87 throw std::runtime_error{"Invalid Legacy package: " + std::string(package)};86 throw std::runtime_error{"Invalid Legacy package: " + std::string(package)};
88 }87 }
@@ -118,9 +117,7 @@
118 \param card Application search paths117 \param card Application search paths
119 \param registry persistent connections to use118 \param registry persistent connections to use
120*/119*/
121AppID::AppName Legacy::findAppname(const AppID::Package& package,120AppID::AppName Legacy::findAppname(const AppID::Package& package, AppID::ApplicationWildcard card)
122 AppID::ApplicationWildcard card,
123 const std::shared_ptr<Registry>& registry)
124{121{
125 throw std::runtime_error("Legacy apps can't be discovered by package");122 throw std::runtime_error("Legacy apps can't be discovered by package");
126}123}
@@ -131,17 +128,16 @@
131 \param appname Application name (unused)128 \param appname Application name (unused)
132 \param registry persistent connections to use (unused)129 \param registry persistent connections to use (unused)
133*/130*/
134AppID::Version Legacy::findVersion(const AppID::Package& package,131AppID::Version Legacy::findVersion(const AppID::Package& package, const AppID::AppName& appname)
135 const AppID::AppName& appname,
136 const std::shared_ptr<Registry>& registry)
137{132{
138 return AppID::Version::from_raw({});133 return AppID::Version::from_raw({});
139}134}
140135
141static const std::regex desktop_remover("^(.*)\\.desktop$");136static const std::regex desktop_remover("^(.*)\\.desktop$");
142137
143std::list<std::shared_ptr<Application>> Legacy::list(const std::shared_ptr<Registry>& registry)138std::list<std::shared_ptr<Application>> Legacy::list()
144{139{
140 auto reg = getReg();
145 std::list<std::shared_ptr<Application>> list;141 std::list<std::shared_ptr<Application>> list;
146 std::unique_ptr<GList, decltype(&g_list_free)> head(g_app_info_get_all(),142 std::unique_ptr<GList, decltype(&g_list_free)> head(g_app_info_get_all(),
147 [](GList* l) { g_list_free_full(l, g_object_unref); });143 [](GList* l) { g_list_free_full(l, g_object_unref); });
@@ -179,7 +175,7 @@
179175
180 try176 try
181 {177 {
182 auto app = std::make_shared<app_impls::Legacy>(AppID::AppName::from_raw(appname), registry);178 auto app = std::make_shared<app_impls::Legacy>(AppID::AppName::from_raw(appname), reg);
183 list.push_back(app);179 list.push_back(app);
184 }180 }
185 catch (std::runtime_error& e)181 catch (std::runtime_error& e)
@@ -191,9 +187,9 @@
191 return list;187 return list;
192}188}
193189
194std::shared_ptr<app_impls::Base> Legacy::create(const AppID& appid, const std::shared_ptr<Registry>& registry)190std::shared_ptr<app_impls::Base> Legacy::create(const AppID& appid)
195{191{
196 return std::make_shared<app_impls::Legacy>(appid.appname, registry);192 return std::make_shared<app_impls::Legacy>(appid.appname, getReg());
197}193}
198194
199} // namespace app_store195} // namespace app_store
200196
=== modified file 'libubuntu-app-launch/app-store-legacy.h'
--- libubuntu-app-launch/app-store-legacy.h 2017-02-24 20:39:24 +0000
+++ libubuntu-app-launch/app-store-legacy.h 2017-04-04 21:22:36 +0000
@@ -31,28 +31,21 @@
31class Legacy : public Base31class Legacy : public Base
32{32{
33public:33public:
34 Legacy();34 Legacy(const std::shared_ptr<Registry::Impl>& registry);
35 virtual ~Legacy();35 virtual ~Legacy();
3636
37 /* Discover tools */37 /* Discover tools */
38 virtual bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry) override;38 virtual bool verifyPackage(const AppID::Package& package) override;
39 virtual bool verifyAppname(const AppID::Package& package,39 virtual bool verifyAppname(const AppID::Package& package, const AppID::AppName& appname) override;
40 const AppID::AppName& appname,40 virtual AppID::AppName findAppname(const AppID::Package& package, AppID::ApplicationWildcard card) override;
41 const std::shared_ptr<Registry>& registry) override;41 virtual AppID::Version findVersion(const AppID::Package& package, const AppID::AppName& appname) override;
42 virtual AppID::AppName findAppname(const AppID::Package& package,42 virtual bool hasAppId(const AppID& appid) override;
43 AppID::ApplicationWildcard card,
44 const std::shared_ptr<Registry>& registry) override;
45 virtual AppID::Version findVersion(const AppID::Package& package,
46 const AppID::AppName& appname,
47 const std::shared_ptr<Registry>& registry) override;
48 virtual bool hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry) override;
4943
50 /* Possible apps */44 /* Possible apps */
51 virtual std::list<std::shared_ptr<Application>> list(const std::shared_ptr<Registry>& registry) override;45 virtual std::list<std::shared_ptr<Application>> list() override;
5246
53 /* Application Creation */47 /* Application Creation */
54 virtual std::shared_ptr<app_impls::Base> create(const AppID& appid,48 virtual std::shared_ptr<app_impls::Base> create(const AppID& appid) override;
55 const std::shared_ptr<Registry>& registry) override;
56};49};
5750
58} // namespace app_store51} // namespace app_store
5952
=== modified file 'libubuntu-app-launch/app-store-libertine.cpp'
--- libubuntu-app-launch/app-store-libertine.cpp 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/app-store-libertine.cpp 2017-04-04 21:22:36 +0000
@@ -30,7 +30,8 @@
30namespace app_store30namespace app_store
31{31{
3232
33Libertine::Libertine()33Libertine::Libertine(const std::shared_ptr<Registry::Impl>& registry)
34 : Base(registry)
34{35{
35}36}
3637
@@ -44,7 +45,7 @@
44 \param appid AppID to check45 \param appid AppID to check
45 \param registry persistent connections to use46 \param registry persistent connections to use
46*/47*/
47bool Libertine::hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry)48bool Libertine::hasAppId(const AppID& appid)
48{49{
49 try50 try
50 {51 {
@@ -53,7 +54,7 @@
53 return false;54 return false;
54 }55 }
5556
56 return verifyAppname(appid.package, appid.appname, registry);57 return verifyAppname(appid.package, appid.appname);
57 }58 }
58 catch (std::runtime_error& e)59 catch (std::runtime_error& e)
59 {60 {
@@ -67,7 +68,7 @@
67 \param package Container name68 \param package Container name
68 \param registry persistent connections to use69 \param registry persistent connections to use
69*/70*/
70bool Libertine::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry)71bool Libertine::verifyPackage(const AppID::Package& package)
71{72{
72 auto containers = unique_gcharv(libertine_list_containers());73 auto containers = unique_gcharv(libertine_list_containers());
7374
@@ -90,9 +91,7 @@
90 \param appname Application name to look for91 \param appname Application name to look for
91 \param registry persistent connections to use92 \param registry persistent connections to use
92*/93*/
93bool Libertine::verifyAppname(const AppID::Package& package,94bool Libertine::verifyAppname(const AppID::Package& package, const AppID::AppName& appname)
94 const AppID::AppName& appname,
95 const std::shared_ptr<Registry>& registry)
96{95{
97 auto apps = unique_gcharv(libertine_list_apps_for_container(package.value().c_str()));96 auto apps = unique_gcharv(libertine_list_apps_for_container(package.value().c_str()));
9897
@@ -115,9 +114,7 @@
115 \param card Application search paths114 \param card Application search paths
116 \param registry persistent connections to use115 \param registry persistent connections to use
117*/116*/
118AppID::AppName Libertine::findAppname(const AppID::Package& package,117AppID::AppName Libertine::findAppname(const AppID::Package& package, AppID::ApplicationWildcard card)
119 AppID::ApplicationWildcard card,
120 const std::shared_ptr<Registry>& registry)
121{118{
122 throw std::runtime_error("Legacy apps can't be discovered by package");119 throw std::runtime_error("Legacy apps can't be discovered by package");
123}120}
@@ -128,17 +125,16 @@
128 \param appname Application name (unused)125 \param appname Application name (unused)
129 \param registry persistent connections to use (unused)126 \param registry persistent connections to use (unused)
130*/127*/
131AppID::Version Libertine::findVersion(const AppID::Package& package,128AppID::Version Libertine::findVersion(const AppID::Package& package, const AppID::AppName& appname)
132 const AppID::AppName& appname,
133 const std::shared_ptr<Registry>& registry)
134{129{
135 return AppID::Version::from_raw("0.0");130 return AppID::Version::from_raw("0.0");
136}131}
137132
138std::list<std::shared_ptr<Application>> Libertine::list(const std::shared_ptr<Registry>& registry)133std::list<std::shared_ptr<Application>> Libertine::list()
139{134{
140 std::list<std::shared_ptr<Application>> applist;135 std::list<std::shared_ptr<Application>> applist;
141136
137 auto reg = getReg();
142 auto containers = unique_gcharv(libertine_list_containers());138 auto containers = unique_gcharv(libertine_list_containers());
143139
144 for (int i = 0; containers.get()[i] != nullptr; i++)140 for (int i = 0; containers.get()[i] != nullptr; i++)
@@ -151,7 +147,7 @@
151 try147 try
152 {148 {
153 auto appid = AppID::parse(apps.get()[j]);149 auto appid = AppID::parse(apps.get()[j]);
154 auto sapp = std::make_shared<app_impls::Libertine>(appid.package, appid.appname, registry);150 auto sapp = std::make_shared<app_impls::Libertine>(appid.package, appid.appname, reg);
155 applist.emplace_back(sapp);151 applist.emplace_back(sapp);
156 }152 }
157 catch (std::runtime_error& e)153 catch (std::runtime_error& e)
@@ -164,9 +160,9 @@
164 return applist;160 return applist;
165}161}
166162
167std::shared_ptr<app_impls::Base> Libertine::create(const AppID& appid, const std::shared_ptr<Registry>& registry)163std::shared_ptr<app_impls::Base> Libertine::create(const AppID& appid)
168{164{
169 return std::make_shared<app_impls::Libertine>(appid.package, appid.appname, registry);165 return std::make_shared<app_impls::Libertine>(appid.package, appid.appname, getReg());
170}166}
171167
172} // namespace app_store168} // namespace app_store
173169
=== modified file 'libubuntu-app-launch/app-store-libertine.h'
--- libubuntu-app-launch/app-store-libertine.h 2017-02-24 20:39:24 +0000
+++ libubuntu-app-launch/app-store-libertine.h 2017-04-04 21:22:36 +0000
@@ -31,28 +31,21 @@
31class Libertine : public Base31class Libertine : public Base
32{32{
33public:33public:
34 Libertine();34 Libertine(const std::shared_ptr<Registry::Impl>& registry);
35 virtual ~Libertine();35 virtual ~Libertine();
3636
37 /* Discover tools */37 /* Discover tools */
38 virtual bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry) override;38 virtual bool verifyPackage(const AppID::Package& package) override;
39 virtual bool verifyAppname(const AppID::Package& package,39 virtual bool verifyAppname(const AppID::Package& package, const AppID::AppName& appname) override;
40 const AppID::AppName& appname,40 virtual AppID::AppName findAppname(const AppID::Package& package, AppID::ApplicationWildcard card) override;
41 const std::shared_ptr<Registry>& registry) override;41 virtual AppID::Version findVersion(const AppID::Package& package, const AppID::AppName& appname) override;
42 virtual AppID::AppName findAppname(const AppID::Package& package,42 virtual bool hasAppId(const AppID& appid) override;
43 AppID::ApplicationWildcard card,
44 const std::shared_ptr<Registry>& registry) override;
45 virtual AppID::Version findVersion(const AppID::Package& package,
46 const AppID::AppName& appname,
47 const std::shared_ptr<Registry>& registry) override;
48 virtual bool hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry) override;
4943
50 /* Possible apps */44 /* Possible apps */
51 virtual std::list<std::shared_ptr<Application>> list(const std::shared_ptr<Registry>& registry) override;45 virtual std::list<std::shared_ptr<Application>> list() override;
5246
53 /* Application Creation */47 /* Application Creation */
54 virtual std::shared_ptr<app_impls::Base> create(const AppID& appid,48 virtual std::shared_ptr<app_impls::Base> create(const AppID& appid) override;
55 const std::shared_ptr<Registry>& registry) override;
56};49};
5750
58} // namespace app_store51} // namespace app_store
5952
=== modified file 'libubuntu-app-launch/app-store-snap.cpp'
--- libubuntu-app-launch/app-store-snap.cpp 2017-03-14 19:59:21 +0000
+++ libubuntu-app-launch/app-store-snap.cpp 2017-04-04 21:22:36 +0000
@@ -43,7 +43,8 @@
43/** Snappy has more restrictive appnames than everyone else */43/** Snappy has more restrictive appnames than everyone else */
44const std::regex appnameRegex{"^[a-zA-Z0-9](?:-?[a-zA-Z0-9])*$"};44const std::regex appnameRegex{"^[a-zA-Z0-9](?:-?[a-zA-Z0-9])*$"};
4545
46Snap::Snap()46Snap::Snap(const std::shared_ptr<Registry::Impl>& registry)
47 : Base(registry)
47{48{
48}49}
4950
@@ -59,7 +60,7 @@
59 \param appid Application ID of the snap60 \param appid Application ID of the snap
60 \param registry Registry to use for persistent connections61 \param registry Registry to use for persistent connections
61*/62*/
62bool Snap::hasAppId(const AppID& appId, const std::shared_ptr<Registry>& registry)63bool Snap::hasAppId(const AppID& appId)
63{64{
64 if (appId.package.value().empty() || appId.version.value().empty())65 if (appId.package.value().empty() || appId.version.value().empty())
65 {66 {
@@ -71,7 +72,7 @@
71 return false;72 return false;
72 }73 }
7374
74 auto pkginfo = registry->impl->snapdInfo.pkgInfo(appId.package);75 auto pkginfo = getReg()->snapdInfo.pkgInfo(appId.package);
75 return app_impls::Snap::checkPkgInfo(pkginfo, appId);76 return app_impls::Snap::checkPkgInfo(pkginfo, appId);
76}77}
7778
@@ -80,11 +81,11 @@
80 \param package Package name81 \param package Package name
81 \param registry Registry to use for persistent connections82 \param registry Registry to use for persistent connections
82*/83*/
83bool Snap::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry)84bool Snap::verifyPackage(const AppID::Package& package)
84{85{
85 try86 try
86 {87 {
87 auto pkgInfo = registry->impl->snapdInfo.pkgInfo(package);88 auto pkgInfo = getReg()->snapdInfo.pkgInfo(package);
88 return pkgInfo != nullptr;89 return pkgInfo != nullptr;
89 }90 }
90 catch (std::runtime_error& e)91 catch (std::runtime_error& e)
@@ -99,16 +100,14 @@
99 \param appname Command name100 \param appname Command name
100 \param registry Registry to use for persistent connections101 \param registry Registry to use for persistent connections
101*/102*/
102bool Snap::verifyAppname(const AppID::Package& package,103bool Snap::verifyAppname(const AppID::Package& package, const AppID::AppName& appname)
103 const AppID::AppName& appname,
104 const std::shared_ptr<Registry>& registry)
105{104{
106 if (!std::regex_match(appname.value(), appnameRegex))105 if (!std::regex_match(appname.value(), appnameRegex))
107 {106 {
108 return false;107 return false;
109 }108 }
110109
111 auto pkgInfo = registry->impl->snapdInfo.pkgInfo(package);110 auto pkgInfo = getReg()->snapdInfo.pkgInfo(package);
112111
113 if (!pkgInfo)112 if (!pkgInfo)
114 {113 {
@@ -125,11 +124,9 @@
125 \param card Wildcard to use for finding the appname124 \param card Wildcard to use for finding the appname
126 \param registry Registry to use for persistent connections125 \param registry Registry to use for persistent connections
127*/126*/
128AppID::AppName Snap::findAppname(const AppID::Package& package,127AppID::AppName Snap::findAppname(const AppID::Package& package, AppID::ApplicationWildcard card)
129 AppID::ApplicationWildcard card,
130 const std::shared_ptr<Registry>& registry)
131{128{
132 auto pkgInfo = registry->impl->snapdInfo.pkgInfo(package);129 auto pkgInfo = getReg()->snapdInfo.pkgInfo(package);
133130
134 if (!pkgInfo)131 if (!pkgInfo)
135 {132 {
@@ -165,11 +162,9 @@
165 \param appname Not used for snaps162 \param appname Not used for snaps
166 \param registry Registry to use for persistent connections163 \param registry Registry to use for persistent connections
167*/164*/
168AppID::Version Snap::findVersion(const AppID::Package& package,165AppID::Version Snap::findVersion(const AppID::Package& package, const AppID::AppName& appname)
169 const AppID::AppName& appname,
170 const std::shared_ptr<Registry>& registry)
171{166{
172 auto pkgInfo = registry->impl->snapdInfo.pkgInfo(package);167 auto pkgInfo = getReg()->snapdInfo.pkgInfo(package);
173 if (pkgInfo)168 if (pkgInfo)
174 {169 {
175 return AppID::Version::from_raw(pkgInfo->revision);170 return AppID::Version::from_raw(pkgInfo->revision);
@@ -194,11 +189,12 @@
194189
195 \param registry Registry to use for persistent connections190 \param registry Registry to use for persistent connections
196*/191*/
197std::list<std::shared_ptr<Application>> Snap::list(const std::shared_ptr<Registry>& registry)192std::list<std::shared_ptr<Application>> Snap::list()
198{193{
199 std::set<std::shared_ptr<Application>, appcompare> apps;194 std::set<std::shared_ptr<Application>, appcompare> apps;
195 auto reg = getReg();
200196
201 auto lifecycleApps = registry->impl->snapdInfo.appsForInterface(LIFECYCLE_INTERFACE);197 auto lifecycleApps = reg->snapdInfo.appsForInterface(LIFECYCLE_INTERFACE);
202198
203 auto lifecycleForApp = [&](const AppID& appID) {199 auto lifecycleForApp = [&](const AppID& appID) {
204 auto iterator = lifecycleApps.find(appID);200 auto iterator = lifecycleApps.find(appID);
@@ -213,12 +209,12 @@
213 };209 };
214210
215 auto addAppsForInterface = [&](const std::string& interface, app_info::Desktop::XMirEnable xMirEnable) {211 auto addAppsForInterface = [&](const std::string& interface, app_info::Desktop::XMirEnable xMirEnable) {
216 for (const auto& id : registry->impl->snapdInfo.appsForInterface(interface))212 for (const auto& id : reg->snapdInfo.appsForInterface(interface))
217 {213 {
218 auto interfaceInfo = std::make_tuple(xMirEnable, lifecycleForApp(id));214 auto interfaceInfo = std::make_tuple(xMirEnable, lifecycleForApp(id));
219 try215 try
220 {216 {
221 auto app = std::make_shared<app_impls::Snap>(id, registry, interfaceInfo);217 auto app = std::make_shared<app_impls::Snap>(id, reg, interfaceInfo);
222 apps.emplace(app);218 apps.emplace(app);
223 }219 }
224 catch (std::runtime_error& e)220 catch (std::runtime_error& e)
@@ -239,9 +235,9 @@
239 return std::list<std::shared_ptr<Application>>(apps.begin(), apps.end());235 return std::list<std::shared_ptr<Application>>(apps.begin(), apps.end());
240}236}
241237
242std::shared_ptr<app_impls::Base> Snap::create(const AppID& appid, const std::shared_ptr<Registry>& registry)238std::shared_ptr<app_impls::Base> Snap::create(const AppID& appid)
243{239{
244 return std::make_shared<app_impls::Snap>(appid, registry);240 return std::make_shared<app_impls::Snap>(appid, getReg());
245}241}
246242
247} // namespace app_store243} // namespace app_store
248244
=== modified file 'libubuntu-app-launch/app-store-snap.h'
--- libubuntu-app-launch/app-store-snap.h 2017-02-24 20:39:24 +0000
+++ libubuntu-app-launch/app-store-snap.h 2017-04-04 21:22:36 +0000
@@ -31,28 +31,21 @@
31class Snap : public Base31class Snap : public Base
32{32{
33public:33public:
34 Snap();34 Snap(const std::shared_ptr<Registry::Impl>& registry);
35 virtual ~Snap();35 virtual ~Snap();
3636
37 /* Discover tools */37 /* Discover tools */
38 virtual bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry) override;38 virtual bool verifyPackage(const AppID::Package& package) override;
39 virtual bool verifyAppname(const AppID::Package& package,39 virtual bool verifyAppname(const AppID::Package& package, const AppID::AppName& appname) override;
40 const AppID::AppName& appname,40 virtual AppID::AppName findAppname(const AppID::Package& package, AppID::ApplicationWildcard card) override;
41 const std::shared_ptr<Registry>& registry) override;41 virtual AppID::Version findVersion(const AppID::Package& package, const AppID::AppName& appname) override;
42 virtual AppID::AppName findAppname(const AppID::Package& package,42 virtual bool hasAppId(const AppID& appid) override;
43 AppID::ApplicationWildcard card,
44 const std::shared_ptr<Registry>& registry) override;
45 virtual AppID::Version findVersion(const AppID::Package& package,
46 const AppID::AppName& appname,
47 const std::shared_ptr<Registry>& registry) override;
48 virtual bool hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry) override;
4943
50 /* Possible apps */44 /* Possible apps */
51 virtual std::list<std::shared_ptr<Application>> list(const std::shared_ptr<Registry>& registry) override;45 virtual std::list<std::shared_ptr<Application>> list() override;
5246
53 /* Application Creation */47 /* Application Creation */
54 virtual std::shared_ptr<app_impls::Base> create(const AppID& appid,48 virtual std::shared_ptr<app_impls::Base> create(const AppID& appid) override;
55 const std::shared_ptr<Registry>& registry) override;
56};49};
5750
58} // namespace app_store51} // namespace app_store
5952
=== modified file 'libubuntu-app-launch/application-impl-base.cpp'
--- libubuntu-app-launch/application-impl-base.cpp 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/application-impl-base.cpp 2017-04-04 21:22:36 +0000
@@ -40,8 +40,8 @@
40namespace app_impls40namespace app_impls
41{41{
4242
43Base::Base(const std::shared_ptr<Registry>& registry)43Base::Base(const std::shared_ptr<Registry::Impl>& registry)
44 : _registry(registry)44 : registry_(registry)
45{45{
46 g_debug("Application construction: %p", static_cast<void*>(this));46 g_debug("Application construction: %p", static_cast<void*>(this));
47}47}
4848
=== modified file 'libubuntu-app-launch/application-impl-base.h'
--- libubuntu-app-launch/application-impl-base.h 2017-02-23 21:18:30 +0000
+++ libubuntu-app-launch/application-impl-base.h 2017-04-04 21:22:36 +0000
@@ -17,21 +17,21 @@
17 * Ted Gould <ted.gould@canonical.com>17 * Ted Gould <ted.gould@canonical.com>
18 */18 */
1919
20#pragma once
21
20#include "application-info-desktop.h"22#include "application-info-desktop.h"
21#include "application.h"23#include "application.h"
22#include "info-watcher.h"24#include "registry-impl.h"
2325#include "registry.h"
24extern "C" {
25#include "ubuntu-app-launch.h"
26#include <gio/gio.h>
27}
28
29#pragma once
3026
31namespace ubuntu27namespace ubuntu
32{28{
33namespace app_launch29namespace app_launch
34{30{
31namespace app_info
32{
33class Desktop;
34}
35namespace app_impls35namespace app_impls
36{36{
3737
@@ -41,7 +41,7 @@
41class Base : public ubuntu::app_launch::Application41class Base : public ubuntu::app_launch::Application
42{42{
43public:43public:
44 Base(const std::shared_ptr<Registry>& registry);44 Base(const std::shared_ptr<Registry::Impl>& registry);
45 virtual ~Base();45 virtual ~Base();
4646
47 bool hasInstances() override;47 bool hasInstances() override;
@@ -52,7 +52,7 @@
5252
53protected:53protected:
54 /** Pointer to the registry so we can ask it for things */54 /** Pointer to the registry so we can ask it for things */
55 std::shared_ptr<Registry> _registry;55 std::shared_ptr<Registry::Impl> registry_;
5656
57 static std::list<std::pair<std::string, std::string>> confinedEnv(const std::string& package,57 static std::list<std::pair<std::string, std::string>> confinedEnv(const std::string& package,
58 const std::string& pkgdir);58 const std::string& pkgdir);
5959
=== modified file 'libubuntu-app-launch/application-impl-legacy.cpp'
--- libubuntu-app-launch/application-impl-legacy.cpp 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/application-impl-legacy.cpp 2017-04-04 21:22:36 +0000
@@ -52,7 +52,7 @@
52 }52 }
53}53}
5454
55Legacy::Legacy(const AppID::AppName& appname, const std::shared_ptr<Registry>& registry)55Legacy::Legacy(const AppID::AppName& appname, const std::shared_ptr<Registry::Impl>& registry)
56 : Base(registry)56 : Base(registry)
57 , _appname(appname)57 , _appname(appname)
58{58{
@@ -73,7 +73,7 @@
73 flags |= app_info::DesktopFlags::XMIR_DEFAULT;73 flags |= app_info::DesktopFlags::XMIR_DEFAULT;
74 }74 }
7575
76 appinfo_ = std::make_shared<app_info::Desktop>(appId(), _keyfile, _basedir, rootDir, flags, _registry);76 appinfo_ = std::make_shared<app_info::Desktop>(appId(), _keyfile, _basedir, rootDir, flags, registry_);
7777
78 if (!_keyfile)78 if (!_keyfile)
79 {79 {
@@ -135,7 +135,7 @@
135135
136std::vector<std::shared_ptr<Application::Instance>> Legacy::instances()136std::vector<std::shared_ptr<Application::Instance>> Legacy::instances()
137{137{
138 auto vbase = _registry->impl->jobs->instances(appId(), "application-legacy");138 auto vbase = registry_->jobs()->instances(appId(), "application-legacy");
139 return std::vector<std::shared_ptr<Application::Instance>>(vbase.begin(), vbase.end());139 return std::vector<std::shared_ptr<Application::Instance>>(vbase.begin(), vbase.end());
140}140}
141141
@@ -222,8 +222,8 @@
222 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this, instance]() {222 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this, instance]() {
223 return launchEnv(instance);223 return launchEnv(instance);
224 };224 };
225 return _registry->impl->jobs->launch(appId(), "application-legacy", instance, urls,225 return registry_->jobs()->launch(appId(), "application-legacy", instance, urls, jobs::manager::launchMode::STANDARD,
226 jobs::manager::launchMode::STANDARD, envfunc);226 envfunc);
227}227}
228228
229/** Create an UpstartInstance for this AppID using the UpstartInstance launch229/** Create an UpstartInstance for this AppID using the UpstartInstance launch
@@ -237,13 +237,13 @@
237 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this, instance]() {237 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this, instance]() {
238 return launchEnv(instance);238 return launchEnv(instance);
239 };239 };
240 return _registry->impl->jobs->launch(appId(), "application-legacy", instance, urls, jobs::manager::launchMode::TEST,240 return registry_->jobs()->launch(appId(), "application-legacy", instance, urls, jobs::manager::launchMode::TEST,
241 envfunc);241 envfunc);
242}242}
243243
244std::shared_ptr<Application::Instance> Legacy::findInstance(const std::string& instanceid)244std::shared_ptr<Application::Instance> Legacy::findInstance(const std::string& instanceid)
245{245{
246 return _registry->impl->jobs->existing(appId(), "application-legacy", instanceid, std::vector<Application::URL>{});246 return registry_->jobs()->existing(appId(), "application-legacy", instanceid, std::vector<Application::URL>{});
247}247}
248248
249} // namespace app_impls249} // namespace app_impls
250250
=== modified file 'libubuntu-app-launch/application-impl-legacy.h'
--- libubuntu-app-launch/application-impl-legacy.h 2017-02-24 21:21:03 +0000
+++ libubuntu-app-launch/application-impl-legacy.h 2017-04-04 21:22:36 +0000
@@ -48,7 +48,7 @@
48class Legacy : public Base48class Legacy : public Base
49{49{
50public:50public:
51 Legacy(const AppID::AppName& appname, const std::shared_ptr<Registry>& registry);51 Legacy(const AppID::AppName& appname, const std::shared_ptr<Registry::Impl>& registry);
5252
53 AppID appId() override53 AppID appId() override
54 {54 {
5555
=== modified file 'libubuntu-app-launch/application-impl-libertine.cpp'
--- libubuntu-app-launch/application-impl-libertine.cpp 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/application-impl-libertine.cpp 2017-04-04 21:22:36 +0000
@@ -35,7 +35,7 @@
3535
36Libertine::Libertine(const AppID::Package& container,36Libertine::Libertine(const AppID::Package& container,
37 const AppID::AppName& appname,37 const AppID::AppName& appname,
38 const std::shared_ptr<Registry>& registry)38 const std::shared_ptr<Registry::Impl>& registry)
39 : Base(registry)39 : Base(registry)
40 , _container(container)40 , _container(container)
41 , _appname(appname)41 , _appname(appname)
@@ -68,7 +68,7 @@
68 container.value() + "'"};68 container.value() + "'"};
6969
70 appinfo_ = std::make_shared<app_info::Desktop>(appId(), _keyfile, _basedir, _container_path,70 appinfo_ = std::make_shared<app_info::Desktop>(appId(), _keyfile, _basedir, _container_path,
71 app_info::DesktopFlags::XMIR_DEFAULT, _registry);71 app_info::DesktopFlags::XMIR_DEFAULT, registry_);
7272
73 g_debug("Application Libertine object for container '%s' app '%s'", container.value().c_str(),73 g_debug("Application Libertine object for container '%s' app '%s'", container.value().c_str(),
74 appname.value().c_str());74 appname.value().c_str());
@@ -137,7 +137,7 @@
137137
138std::vector<std::shared_ptr<Application::Instance>> Libertine::instances()138std::vector<std::shared_ptr<Application::Instance>> Libertine::instances()
139{139{
140 auto vbase = _registry->impl->jobs->instances(appId(), "application-legacy");140 auto vbase = registry_->jobs()->instances(appId(), "application-legacy");
141 return std::vector<std::shared_ptr<Application::Instance>>(vbase.begin(), vbase.end());141 return std::vector<std::shared_ptr<Application::Instance>>(vbase.begin(), vbase.end());
142}142}
143143
@@ -181,21 +181,21 @@
181{181{
182 auto instance = getInstance(appinfo_);182 auto instance = getInstance(appinfo_);
183 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); };183 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); };
184 return _registry->impl->jobs->launch(appId(), "application-legacy", instance, urls,184 return registry_->jobs()->launch(appId(), "application-legacy", instance, urls, jobs::manager::launchMode::STANDARD,
185 jobs::manager::launchMode::STANDARD, envfunc);185 envfunc);
186}186}
187187
188std::shared_ptr<Application::Instance> Libertine::launchTest(const std::vector<Application::URL>& urls)188std::shared_ptr<Application::Instance> Libertine::launchTest(const std::vector<Application::URL>& urls)
189{189{
190 auto instance = getInstance(appinfo_);190 auto instance = getInstance(appinfo_);
191 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); };191 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); };
192 return _registry->impl->jobs->launch(appId(), "application-legacy", instance, urls, jobs::manager::launchMode::TEST,192 return registry_->jobs()->launch(appId(), "application-legacy", instance, urls, jobs::manager::launchMode::TEST,
193 envfunc);193 envfunc);
194}194}
195195
196std::shared_ptr<Application::Instance> Libertine::findInstance(const std::string& instanceid)196std::shared_ptr<Application::Instance> Libertine::findInstance(const std::string& instanceid)
197{197{
198 return _registry->impl->jobs->existing(appId(), "application-legacy", instanceid, std::vector<Application::URL>{});198 return registry_->jobs()->existing(appId(), "application-legacy", instanceid, std::vector<Application::URL>{});
199}199}
200200
201} // namespace app_impls201} // namespace app_impls
202202
=== modified file 'libubuntu-app-launch/application-impl-libertine.h'
--- libubuntu-app-launch/application-impl-libertine.h 2017-02-24 21:25:47 +0000
+++ libubuntu-app-launch/application-impl-libertine.h 2017-04-04 21:22:36 +0000
@@ -52,7 +52,7 @@
52public:52public:
53 Libertine(const AppID::Package& container,53 Libertine(const AppID::Package& container,
54 const AppID::AppName& appname,54 const AppID::AppName& appname,
55 const std::shared_ptr<Registry>& registry);55 const std::shared_ptr<Registry::Impl>& registry);
5656
57 AppID appId() override57 AppID appId() override
58 {58 {
5959
=== modified file 'libubuntu-app-launch/application-impl-snap.cpp'
--- libubuntu-app-launch/application-impl-snap.cpp 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/application-impl-snap.cpp 2017-04-04 21:22:36 +0000
@@ -62,7 +62,7 @@
6262
63public:63public:
64 SnapInfo(const AppID& appid,64 SnapInfo(const AppID& appid,
65 const std::shared_ptr<Registry>& registry,65 const std::shared_ptr<Registry::Impl>& registry,
66 const Snap::InterfaceInfo& interfaceInfo,66 const Snap::InterfaceInfo& interfaceInfo,
67 const std::string& snapDir)67 const std::string& snapDir)
68 : Desktop(appid,68 : Desktop(appid,
@@ -187,11 +187,11 @@
187 \param registry Registry to use for persistent connections187 \param registry Registry to use for persistent connections
188 \param interfaceInfo Metadata gleaned from the snap's interfaces188 \param interfaceInfo Metadata gleaned from the snap's interfaces
189*/189*/
190Snap::Snap(const AppID& appid, const std::shared_ptr<Registry>& registry, const InterfaceInfo& interfaceInfo)190Snap::Snap(const AppID& appid, const std::shared_ptr<Registry::Impl>& registry, const InterfaceInfo& interfaceInfo)
191 : Base(registry)191 : Base(registry)
192 , appid_(appid)192 , appid_(appid)
193{193{
194 pkgInfo_ = registry->impl->snapdInfo.pkgInfo(appid.package);194 pkgInfo_ = registry->snapdInfo.pkgInfo(appid.package);
195 if (!pkgInfo_)195 if (!pkgInfo_)
196 {196 {
197 throw std::runtime_error("Unable to get snap package info for AppID: " + std::string(appid));197 throw std::runtime_error("Unable to get snap package info for AppID: " + std::string(appid));
@@ -202,7 +202,7 @@
202 throw std::runtime_error("AppID does not match installed package for: " + std::string(appid));202 throw std::runtime_error("AppID does not match installed package for: " + std::string(appid));
203 }203 }
204204
205 info_ = std::make_shared<SnapInfo>(appid_, _registry, interfaceInfo, pkgInfo_->directory);205 info_ = std::make_shared<SnapInfo>(appid_, registry_, interfaceInfo, pkgInfo_->directory);
206206
207 g_debug("Application Snap object for AppID '%s'", std::string(appid).c_str());207 g_debug("Application Snap object for AppID '%s'", std::string(appid).c_str());
208}208}
@@ -213,7 +213,7 @@
213 \param appid Application ID of the snap213 \param appid Application ID of the snap
214 \param registry Registry to use for persistent connections214 \param registry Registry to use for persistent connections
215*/215*/
216Snap::Snap(const AppID& appid, const std::shared_ptr<Registry>& registry)216Snap::Snap(const AppID& appid, const std::shared_ptr<Registry::Impl>& registry)
217 : Snap(appid, registry, findInterfaceInfo(appid, registry))217 : Snap(appid, registry, findInterfaceInfo(appid, registry))
218{218{
219}219}
@@ -230,9 +230,9 @@
230 \param appid Application ID of the snap230 \param appid Application ID of the snap
231 \param registry Registry to use for persistent connections231 \param registry Registry to use for persistent connections
232*/232*/
233Snap::InterfaceInfo Snap::findInterfaceInfo(const AppID& appid, const std::shared_ptr<Registry>& registry)233Snap::InterfaceInfo Snap::findInterfaceInfo(const AppID& appid, const std::shared_ptr<Registry::Impl>& registry)
234{234{
235 auto ifaceset = registry->impl->snapdInfo.interfacesForAppId(appid);235 auto ifaceset = registry->snapdInfo.interfacesForAppId(appid);
236 auto xMirEnable = app_info::Desktop::XMirEnable::from_raw(false);236 auto xMirEnable = app_info::Desktop::XMirEnable::from_raw(false);
237 auto ubuntuLifecycle = Application::Info::UbuntuLifecycle::from_raw(false);237 auto ubuntuLifecycle = Application::Info::UbuntuLifecycle::from_raw(false);
238238
@@ -282,7 +282,7 @@
282/** Get all of the instances of this snap package that are running */282/** Get all of the instances of this snap package that are running */
283std::vector<std::shared_ptr<Application::Instance>> Snap::instances()283std::vector<std::shared_ptr<Application::Instance>> Snap::instances()
284{284{
285 auto vbase = _registry->impl->jobs->instances(appId(), "application-snap");285 auto vbase = registry_->jobs()->instances(appId(), "application-snap");
286 return std::vector<std::shared_ptr<Application::Instance>>(vbase.begin(), vbase.end());286 return std::vector<std::shared_ptr<Application::Instance>>(vbase.begin(), vbase.end());
287}287}
288288
@@ -326,8 +326,8 @@
326{326{
327 auto instance = getInstance(info_);327 auto instance = getInstance(info_);
328 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); };328 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); };
329 return _registry->impl->jobs->launch(appid_, "application-snap", instance, urls,329 return registry_->jobs()->launch(appid_, "application-snap", instance, urls, jobs::manager::launchMode::STANDARD,
330 jobs::manager::launchMode::STANDARD, envfunc);330 envfunc);
331}331}
332332
333/** Create a new instance of this Snap with a testing environment333/** Create a new instance of this Snap with a testing environment
@@ -339,13 +339,13 @@
339{339{
340 auto instance = getInstance(info_);340 auto instance = getInstance(info_);
341 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); };341 std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); };
342 return _registry->impl->jobs->launch(appid_, "application-snap", instance, urls, jobs::manager::launchMode::TEST,342 return registry_->jobs()->launch(appid_, "application-snap", instance, urls, jobs::manager::launchMode::TEST,
343 envfunc);343 envfunc);
344}344}
345345
346std::shared_ptr<Application::Instance> Snap::findInstance(const std::string& instanceid)346std::shared_ptr<Application::Instance> Snap::findInstance(const std::string& instanceid)
347{347{
348 return _registry->impl->jobs->existing(appId(), "application-snap", instanceid, std::vector<Application::URL>{});348 return registry_->jobs()->existing(appId(), "application-snap", instanceid, std::vector<Application::URL>{});
349}349}
350350
351} // namespace app_impls351} // namespace app_impls
352352
=== modified file 'libubuntu-app-launch/application-impl-snap.h'
--- libubuntu-app-launch/application-impl-snap.h 2017-03-14 19:35:43 +0000
+++ libubuntu-app-launch/application-impl-snap.h 2017-04-04 21:22:36 +0000
@@ -50,10 +50,10 @@
50public:50public:
51 typedef std::tuple<app_info::Desktop::XMirEnable, Application::Info::UbuntuLifecycle> InterfaceInfo;51 typedef std::tuple<app_info::Desktop::XMirEnable, Application::Info::UbuntuLifecycle> InterfaceInfo;
5252
53 Snap(const AppID& appid, const std::shared_ptr<Registry>& registry);53 Snap(const AppID& appid, const std::shared_ptr<Registry::Impl>& registry);
54 Snap(const AppID& appid, const std::shared_ptr<Registry>& registry, const InterfaceInfo& interfaceInfo);54 Snap(const AppID& appid, const std::shared_ptr<Registry::Impl>& registry, const InterfaceInfo& interfaceInfo);
5555
56 static std::list<std::shared_ptr<Application>> list(const std::shared_ptr<Registry>& registry);56 static std::list<std::shared_ptr<Application>> list(const std::shared_ptr<Registry::Impl>& registry);
5757
58 AppID appId() override;58 AppID appId() override;
5959
@@ -66,7 +66,7 @@
6666
67 virtual std::shared_ptr<Application::Instance> findInstance(const std::string& instanceid) override;67 virtual std::shared_ptr<Application::Instance> findInstance(const std::string& instanceid) override;
6868
69 static InterfaceInfo findInterfaceInfo(const AppID& appid, const std::shared_ptr<Registry>& registry);69 static InterfaceInfo findInterfaceInfo(const AppID& appid, const std::shared_ptr<Registry::Impl>& registry);
70 static bool checkPkgInfo(const std::shared_ptr<snapd::Info::PkgInfo>& pkginfo, const AppID& appid);70 static bool checkPkgInfo(const std::shared_ptr<snapd::Info::PkgInfo>& pkginfo, const AppID& appid);
7171
72private:72private:
7373
=== modified file 'libubuntu-app-launch/application-info-desktop.cpp'
--- libubuntu-app-launch/application-info-desktop.cpp 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/application-info-desktop.cpp 2017-04-04 21:22:36 +0000
@@ -265,7 +265,7 @@
265 const std::string& basePath,265 const std::string& basePath,
266 const std::string& rootDir,266 const std::string& rootDir,
267 std::bitset<2> flags,267 std::bitset<2> flags,
268 std::shared_ptr<Registry> registry)268 const std::shared_ptr<Registry::Impl>& registry)
269 : _keyfile([keyfile, flags]() {269 : _keyfile([keyfile, flags]() {
270 if (!keyfile)270 if (!keyfile)
271 {271 {
@@ -318,7 +318,7 @@
318 if (!iconName.value().empty() && iconName.value()[0] != '/')318 if (!iconName.value().empty() && iconName.value()[0] != '/')
319 {319 {
320 /* If it is not a direct filename look it up */320 /* If it is not a direct filename look it up */
321 return registry->impl->getIconFinder(basePath)->find(iconName);321 return registry->getIconFinder(basePath)->find(iconName);
322 }322 }
323 }323 }
324 return fileFromKeyfile<Application::Info::IconPath>(keyfile, basePath, rootDir, "Icon");324 return fileFromKeyfile<Application::Info::IconPath>(keyfile, basePath, rootDir, "Icon");
@@ -331,7 +331,7 @@
331 , _keywords(stringlistFromKeyfile<Application::Info::Keywords>(keyfile, "Keywords"))331 , _keywords(stringlistFromKeyfile<Application::Info::Keywords>(keyfile, "Keywords"))
332 , _popularity([registry, appid] {332 , _popularity([registry, appid] {
333 if (registry)333 if (registry)
334 return Registry::Impl::getZgWatcher(registry)->lookupAppPopularity(appid);334 return registry->getZgWatcher()->lookupAppPopularity(appid);
335 else335 else
336 return Application::Info::Popularity::from_raw(0);336 return Application::Info::Popularity::from_raw(0);
337 }())337 }())
338338
=== modified file 'libubuntu-app-launch/application-info-desktop.h'
--- libubuntu-app-launch/application-info-desktop.h 2017-02-09 04:28:16 +0000
+++ libubuntu-app-launch/application-info-desktop.h 2017-04-04 21:22:36 +0000
@@ -17,13 +17,15 @@
17 * Ted Gould <ted.gould@canonical.com>17 * Ted Gould <ted.gould@canonical.com>
18 */18 */
1919
20#pragma once
21
20#include "application.h"22#include "application.h"
23#include "registry-impl.h"
24#include "registry.h"
21#include <bitset>25#include <bitset>
22#include <glib.h>26#include <glib.h>
23#include <mutex>27#include <mutex>
2428
25#pragma once
26
27namespace ubuntu29namespace ubuntu
28{30{
29namespace app_launch31namespace app_launch
@@ -46,7 +48,7 @@
46 const std::string& basePath,48 const std::string& basePath,
47 const std::string& rootDir,49 const std::string& rootDir,
48 std::bitset<2> flags,50 std::bitset<2> flags,
49 std::shared_ptr<Registry> registry);51 const std::shared_ptr<Registry::Impl>& registry);
5052
51 const Application::Info::Name& name() override53 const Application::Info::Name& name() override
52 {54 {
5355
=== modified file 'libubuntu-app-launch/application.cpp'
--- libubuntu-app-launch/application.cpp 2017-02-25 15:58:27 +0000
+++ libubuntu-app-launch/application.cpp 2017-04-04 21:22:36 +0000
@@ -48,20 +48,7 @@
48 throw std::runtime_error("Invalid registry object");48 throw std::runtime_error("Invalid registry object");
49 }49 }
5050
51 if (!registry->impl->jobs)51 return registry->impl->createApp(appid);
52 {
53 registry->impl->jobs = jobs::manager::Base::determineFactory(registry);
54 }
55
56 for (const auto& appStore : registry->impl->appStores())
57 {
58 if (appStore->hasAppId(appid, registry))
59 {
60 return appStore->create(appid, registry);
61 }
62 }
63
64 throw std::runtime_error("Invalid app ID: " + std::string(appid));
65}52}
6653
67AppID::AppID()54AppID::AppID()
@@ -110,11 +97,16 @@
110AppID AppID::find(const std::string& sappid)97AppID AppID::find(const std::string& sappid)
111{98{
112 auto registry = Registry::getDefault();99 auto registry = Registry::getDefault();
113 return find(registry, sappid);100 return registry->impl->find(sappid);
114}101}
115102
116AppID AppID::find(const std::shared_ptr<Registry>& registry, const std::string& sappid)103AppID AppID::find(const std::shared_ptr<Registry>& registry, const std::string& sappid)
117{104{
105 return registry->impl->find(sappid);
106}
107
108AppID Registry::Impl::find(const std::string& sappid)
109{
118 std::smatch match;110 std::smatch match;
119111
120 if (std::regex_match(sappid, match, full_appid_regex))112 if (std::regex_match(sappid, match, full_appid_regex))
@@ -124,7 +116,7 @@
124 }116 }
125 else if (std::regex_match(sappid, match, short_appid_regex))117 else if (std::regex_match(sappid, match, short_appid_regex))
126 {118 {
127 return discover(registry, match[1].str(), match[2].str());119 return discover(match[1].str(), match[2].str(), AppID::VersionWildcard::CURRENT_USER_VERSION);
128 }120 }
129 else if (std::regex_match(sappid, match, legacy_appid_regex))121 else if (std::regex_match(sappid, match, legacy_appid_regex))
130 {122 {
@@ -181,33 +173,38 @@
181 const std::string& appname,173 const std::string& appname,
182 const std::string& version)174 const std::string& version)
183{175{
176 return registry->impl->discover(package, appname, version);
177}
178
179AppID Registry::Impl::discover(const std::string& package, const std::string& appname, const std::string& version)
180{
184 auto pkg = AppID::Package::from_raw(package);181 auto pkg = AppID::Package::from_raw(package);
185182
186 for (const auto& appStore : registry->impl->appStores())183 for (const auto& appStore : appStores())
187 {184 {
188 /* Figure out which type we have */185 /* Figure out which type we have */
189 try186 try
190 {187 {
191 if (appStore->verifyPackage(pkg, registry))188 if (appStore->verifyPackage(pkg))
192 {189 {
193 auto app = AppID::AppName::from_raw({});190 auto app = AppID::AppName::from_raw({});
194191
195 if (appname.empty() || appname == "first-listed-app")192 if (appname.empty() || appname == "first-listed-app")
196 {193 {
197 app = appStore->findAppname(pkg, ApplicationWildcard::FIRST_LISTED, registry);194 app = appStore->findAppname(pkg, AppID::ApplicationWildcard::FIRST_LISTED);
198 }195 }
199 else if (appname == "last-listed-app")196 else if (appname == "last-listed-app")
200 {197 {
201 app = appStore->findAppname(pkg, ApplicationWildcard::LAST_LISTED, registry);198 app = appStore->findAppname(pkg, AppID::ApplicationWildcard::LAST_LISTED);
202 }199 }
203 else if (appname == "only-listed-app")200 else if (appname == "only-listed-app")
204 {201 {
205 app = appStore->findAppname(pkg, ApplicationWildcard::ONLY_LISTED, registry);202 app = appStore->findAppname(pkg, AppID::ApplicationWildcard::ONLY_LISTED);
206 }203 }
207 else204 else
208 {205 {
209 app = AppID::AppName::from_raw(appname);206 app = AppID::AppName::from_raw(appname);
210 if (!appStore->verifyAppname(pkg, app, registry))207 if (!appStore->verifyAppname(pkg, app))
211 {208 {
212 throw std::runtime_error("App name passed in is not valid for this package type");209 throw std::runtime_error("App name passed in is not valid for this package type");
213 }210 }
@@ -216,12 +213,12 @@
216 auto ver = AppID::Version::from_raw({});213 auto ver = AppID::Version::from_raw({});
217 if (version.empty() || version == "current-user-version")214 if (version.empty() || version == "current-user-version")
218 {215 {
219 ver = appStore->findVersion(pkg, app, registry);216 ver = appStore->findVersion(pkg, app);
220 }217 }
221 else218 else
222 {219 {
223 ver = AppID::Version::from_raw(version);220 ver = AppID::Version::from_raw(version);
224 if (!appStore->hasAppId({pkg, app, ver}, registry))221 if (!appStore->hasAppId({pkg, app, ver}))
225 {222 {
226 throw std::runtime_error("Invalid version passed for this package type");223 throw std::runtime_error("Invalid version passed for this package type");
227 }224 }
@@ -244,16 +241,23 @@
244 ApplicationWildcard appwildcard,241 ApplicationWildcard appwildcard,
245 VersionWildcard versionwildcard)242 VersionWildcard versionwildcard)
246{243{
244 return registry->impl->discover(package, appwildcard, versionwildcard);
245}
246
247AppID Registry::Impl::discover(const std::string& package,
248 AppID::ApplicationWildcard appwildcard,
249 AppID::VersionWildcard versionwildcard)
250{
247 auto pkg = AppID::Package::from_raw(package);251 auto pkg = AppID::Package::from_raw(package);
248252
249 for (const auto& appStore : registry->impl->appStores())253 for (const auto& appStore : appStores())
250 {254 {
251 try255 try
252 {256 {
253 if (appStore->verifyPackage(pkg, registry))257 if (appStore->verifyPackage(pkg))
254 {258 {
255 auto app = appStore->findAppname(pkg, appwildcard, registry);259 auto app = appStore->findAppname(pkg, appwildcard);
256 auto ver = appStore->findVersion(pkg, app, registry);260 auto ver = appStore->findVersion(pkg, app);
257 return AppID{pkg, app, ver};261 return AppID{pkg, app, ver};
258 }262 }
259 }263 }
@@ -272,16 +276,23 @@
272 const std::string& appname,276 const std::string& appname,
273 VersionWildcard versionwildcard)277 VersionWildcard versionwildcard)
274{278{
279 return registry->impl->discover(package, appname, versionwildcard);
280}
281
282AppID Registry::Impl::discover(const std::string& package,
283 const std::string& appname,
284 AppID::VersionWildcard versionwildcard)
285{
275 auto pkg = AppID::Package::from_raw(package);286 auto pkg = AppID::Package::from_raw(package);
276 auto app = AppID::AppName::from_raw(appname);287 auto app = AppID::AppName::from_raw(appname);
277288
278 for (const auto& appStore : registry->impl->appStores())289 for (const auto& appStore : appStores())
279 {290 {
280 try291 try
281 {292 {
282 if (appStore->verifyPackage(pkg, registry) && appStore->verifyAppname(pkg, app, registry))293 if (appStore->verifyPackage(pkg) && appStore->verifyAppname(pkg, app))
283 {294 {
284 auto ver = appStore->findVersion(pkg, app, registry);295 auto ver = appStore->findVersion(pkg, app);
285 return AppID{pkg, app, ver};296 return AppID{pkg, app, ver};
286 }297 }
287 }298 }
@@ -298,19 +309,19 @@
298AppID AppID::discover(const std::string& package, const std::string& appname, const std::string& version)309AppID AppID::discover(const std::string& package, const std::string& appname, const std::string& version)
299{310{
300 auto registry = Registry::getDefault();311 auto registry = Registry::getDefault();
301 return discover(registry, package, appname, version);312 return registry->impl->discover(package, appname, version);
302}313}
303314
304AppID AppID::discover(const std::string& package, ApplicationWildcard appwildcard, VersionWildcard versionwildcard)315AppID AppID::discover(const std::string& package, ApplicationWildcard appwildcard, VersionWildcard versionwildcard)
305{316{
306 auto registry = Registry::getDefault();317 auto registry = Registry::getDefault();
307 return discover(registry, package, appwildcard, versionwildcard);318 return registry->impl->discover(package, appwildcard, versionwildcard);
308}319}
309320
310AppID AppID::discover(const std::string& package, const std::string& appname, VersionWildcard versionwildcard)321AppID AppID::discover(const std::string& package, const std::string& appname, VersionWildcard versionwildcard)
311{322{
312 auto registry = Registry::getDefault();323 auto registry = Registry::getDefault();
313 return discover(registry, package, appname, versionwildcard);324 return registry->impl->discover(package, appname, versionwildcard);
314}325}
315326
316enum class oom::Score : std::int32_t327enum class oom::Score : std::int32_t
317328
=== modified file 'libubuntu-app-launch/helper-impl.h'
--- libubuntu-app-launch/helper-impl.h 2017-03-14 03:23:02 +0000
+++ libubuntu-app-launch/helper-impl.h 2017-04-04 21:22:36 +0000
@@ -55,7 +55,7 @@
55class Base : public Helper55class Base : public Helper
56{56{
57public:57public:
58 Base(const Helper::Type& type, const AppID& appid, const std::shared_ptr<Registry>& registry);58 Base(const Helper::Type& type, const AppID& appid, const std::shared_ptr<Registry::Impl>& registry);
5959
60 AppID appId() override;60 AppID appId() override;
6161
@@ -70,7 +70,7 @@
70private:70private:
71 Helper::Type _type;71 Helper::Type _type;
72 AppID _appid;72 AppID _appid;
73 std::shared_ptr<Registry> _registry;73 std::shared_ptr<Registry::Impl> registry_;
7474
75 std::list<std::pair<std::string, std::string>> defaultEnv();75 std::list<std::pair<std::string, std::string>> defaultEnv();
76};76};
7777
=== modified file 'libubuntu-app-launch/helper.cpp'
--- libubuntu-app-launch/helper.cpp 2017-03-20 12:28:10 +0000
+++ libubuntu-app-launch/helper.cpp 2017-04-04 21:22:36 +0000
@@ -73,10 +73,10 @@
73 * Helper Class73 * Helper Class
74 **********************/74 **********************/
7575
76Base::Base(const Helper::Type& type, const AppID& appid, const std::shared_ptr<Registry>& registry)76Base::Base(const Helper::Type& type, const AppID& appid, const std::shared_ptr<Registry::Impl>& registry)
77 : _type(type)77 : _type(type)
78 , _appid(appid)78 , _appid(appid)
79 , _registry(registry)79 , registry_(registry)
80{80{
81}81}
8282
@@ -92,7 +92,7 @@
9292
93std::vector<std::shared_ptr<Helper::Instance>> Base::instances()93std::vector<std::shared_ptr<Helper::Instance>> Base::instances()
94{94{
95 auto insts = _registry->impl->jobs->instances(_appid, _type.value());95 auto insts = registry_->jobs()->instances(_appid, _type.value());
96 std::vector<std::shared_ptr<Helper::Instance>> wrapped{insts.size()};96 std::vector<std::shared_ptr<Helper::Instance>> wrapped{insts.size()};
9797
98 std::transform(insts.begin(), insts.end(), wrapped.begin(),98 std::transform(insts.begin(), insts.end(), wrapped.begin(),
@@ -104,7 +104,7 @@
104/** Find an instance that we already know the ID of */104/** Find an instance that we already know the ID of */
105std::shared_ptr<Helper::Instance> Base::existingInstance(const std::string& instanceid)105std::shared_ptr<Helper::Instance> Base::existingInstance(const std::string& instanceid)
106{106{
107 auto appinst = _registry->impl->jobs->existing(_appid, _type.value(), instanceid, {});107 auto appinst = registry_->jobs()->existing(_appid, _type.value(), instanceid, {});
108108
109 return std::make_shared<BaseInstance>(appinst);109 return std::make_shared<BaseInstance>(appinst);
110}110}
@@ -212,14 +212,14 @@
212 auto defaultenv = defaultEnv();212 auto defaultenv = defaultEnv();
213 std::function<std::list<std::pair<std::string, std::string>>()> envfunc = [defaultenv]() { return defaultenv; };213 std::function<std::list<std::pair<std::string, std::string>>()> envfunc = [defaultenv]() { return defaultenv; };
214214
215 return std::make_shared<BaseInstance>(_registry->impl->jobs->launch(215 return std::make_shared<BaseInstance>(registry_->jobs()->launch(
216 _appid, _type.value(), genInstanceId(), appURL(urls), jobs::manager::launchMode::STANDARD, envfunc));216 _appid, _type.value(), genInstanceId(), appURL(urls), jobs::manager::launchMode::STANDARD, envfunc));
217}217}
218218
219class MirFDProxy219class MirFDProxy
220{220{
221public:221public:
222 std::shared_ptr<Registry> reg_;222 std::shared_ptr<Registry::Impl> reg_;
223 ResourcePtr<int, void (*)(int)> mirfd;223 ResourcePtr<int, void (*)(int)> mirfd;
224 std::shared_ptr<proxySocketDemangler> skel;224 std::shared_ptr<proxySocketDemangler> skel;
225 ManagedSignalConnection<proxySocketDemangler> handle;225 ManagedSignalConnection<proxySocketDemangler> handle;
@@ -227,7 +227,7 @@
227 std::string name;227 std::string name;
228 guint timeout{0};228 guint timeout{0};
229229
230 MirFDProxy(MirPromptSession* session, const AppID& appid, const std::shared_ptr<Registry>& reg)230 MirFDProxy(MirPromptSession* session, const AppID& appid, const std::shared_ptr<Registry::Impl>& reg)
231 : reg_(reg)231 : reg_(reg)
232 , mirfd(0,232 , mirfd(0,
233 [](int fp) {233 [](int fp) {
@@ -235,7 +235,7 @@
235 close(fp);235 close(fp);
236 })236 })
237 , handle(SignalUnsubscriber<proxySocketDemangler>{})237 , handle(SignalUnsubscriber<proxySocketDemangler>{})
238 , name(g_dbus_connection_get_unique_name(reg->impl->_dbus.get()))238 , name(g_dbus_connection_get_unique_name(reg->_dbus.get()))
239 {239 {
240 if (appid.empty())240 if (appid.empty())
241 {241 {
@@ -268,7 +268,7 @@
268 }268 }
269269
270 /* Setup the DBus interface */270 /* Setup the DBus interface */
271 std::tie(skel, handle, path) = reg->impl->thread.executeOnThread<std::tuple<271 std::tie(skel, handle, path) = reg->thread.executeOnThread<std::tuple<
272 std::shared_ptr<proxySocketDemangler>, ManagedSignalConnection<proxySocketDemangler>, std::string>>(272 std::shared_ptr<proxySocketDemangler>, ManagedSignalConnection<proxySocketDemangler>, std::string>>(
273 [this, appid, reg]() {273 [this, appid, reg]() {
274 auto skel = share_gobject(proxy_socket_demangler_skeleton_new());274 auto skel = share_gobject(proxy_socket_demangler_skeleton_new());
@@ -285,7 +285,7 @@
285 GError* error = nullptr;285 GError* error = nullptr;
286 std::string tryname = "/com/canonical/UbuntuAppLaunch/" + dbusAppid + "/" + std::to_string(rand());286 std::string tryname = "/com/canonical/UbuntuAppLaunch/" + dbusAppid + "/" + std::to_string(rand());
287287
288 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(skel.get()), reg->impl->_dbus.get(),288 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(skel.get()), reg->_dbus.get(),
289 tryname.c_str(), &error);289 tryname.c_str(), &error);
290290
291 if (error == nullptr)291 if (error == nullptr)
@@ -355,7 +355,7 @@
355 auto reg = reg_;355 auto reg = reg_;
356 auto timeoutlocal = timeout;356 auto timeoutlocal = timeout;
357357
358 reg->impl->thread.executeOnThread([reg, timeoutlocal]() { reg->impl->thread.removeSource(timeoutlocal); });358 reg->thread.executeOnThread([reg, timeoutlocal]() { reg->thread.removeSource(timeoutlocal); });
359359
360 return true;360 return true;
361 }361 }
@@ -381,7 +381,7 @@
381 std::shared_ptr<MirFDProxy> proxy;381 std::shared_ptr<MirFDProxy> proxy;
382 try382 try
383 {383 {
384 proxy = std::make_shared<MirFDProxy>(session, _appid, _registry);384 proxy = std::make_shared<MirFDProxy>(session, _appid, registry_);
385 }385 }
386 catch (std::runtime_error& e)386 catch (std::runtime_error& e)
387 {387 {
@@ -401,10 +401,9 @@
401401
402 /* This will maintain a reference to the proxy for two402 /* This will maintain a reference to the proxy for two
403 seconds. And then it'll be dropped. */403 seconds. And then it'll be dropped. */
404 proxy->setTimeout(404 proxy->setTimeout(registry_->thread.timeout(std::chrono::seconds{2}, [proxy]() { g_debug("Mir Proxy Timeout"); }));
405 _registry->impl->thread.timeout(std::chrono::seconds{2}, [proxy]() { g_debug("Mir Proxy Timeout"); }));
406405
407 return std::make_shared<BaseInstance>(_registry->impl->jobs->launch(406 return std::make_shared<BaseInstance>(registry_->jobs()->launch(
408 _appid, _type.value(), genInstanceId(), appURL(urls), jobs::manager::launchMode::STANDARD, envfunc));407 _appid, _type.value(), genInstanceId(), appURL(urls), jobs::manager::launchMode::STANDARD, envfunc));
409}408}
410409
@@ -416,8 +415,7 @@
416415
417std::shared_ptr<Helper> Helper::create(Type type, AppID appid, std::shared_ptr<Registry> registry)416std::shared_ptr<Helper> Helper::create(Type type, AppID appid, std::shared_ptr<Registry> registry)
418{417{
419 /* Only one type today */418 return registry->impl->createHelper(type, appid, registry->impl);
420 return std::make_shared<helper_impls::Base>(type, appid, registry);
421}419}
422420
423/* Hardcore socket stuff */421/* Hardcore socket stuff */
424422
=== modified file 'libubuntu-app-launch/info-watcher-zg.cpp'
--- libubuntu-app-launch/info-watcher-zg.cpp 2017-02-10 16:50:40 +0000
+++ libubuntu-app-launch/info-watcher-zg.cpp 2017-04-04 21:22:36 +0000
@@ -28,7 +28,7 @@
28namespace info_watcher28namespace info_watcher
29{29{
3030
31Zeitgeist::Zeitgeist(const std::shared_ptr<Registry>& registry)31Zeitgeist::Zeitgeist(const std::shared_ptr<Registry::Impl>& registry)
32 : Base(registry)32 : Base(registry)
33{33{
34 g_debug("Created a ZG Watcher");34 g_debug("Created a ZG Watcher");
3535
=== modified file 'libubuntu-app-launch/info-watcher-zg.h'
--- libubuntu-app-launch/info-watcher-zg.h 2017-02-10 16:50:40 +0000
+++ libubuntu-app-launch/info-watcher-zg.h 2017-04-04 21:22:36 +0000
@@ -36,7 +36,7 @@
36class Zeitgeist : public Base36class Zeitgeist : public Base
37{37{
38public:38public:
39 Zeitgeist(const std::shared_ptr<Registry>& registry);39 Zeitgeist(const std::shared_ptr<Registry::Impl>& registry);
40 virtual ~Zeitgeist() = default;40 virtual ~Zeitgeist() = default;
4141
42 virtual Application::Info::Popularity lookupAppPopularity(const AppID& appid);42 virtual Application::Info::Popularity lookupAppPopularity(const AppID& appid);
4343
=== modified file 'libubuntu-app-launch/info-watcher.cpp'
--- libubuntu-app-launch/info-watcher.cpp 2017-02-08 21:31:37 +0000
+++ libubuntu-app-launch/info-watcher.cpp 2017-04-04 21:22:36 +0000
@@ -18,6 +18,7 @@
18 */18 */
1919
20#include "info-watcher.h"20#include "info-watcher.h"
21#include <glib.h>
2122
22namespace ubuntu23namespace ubuntu
23{24{
@@ -26,8 +27,21 @@
26namespace info_watcher27namespace info_watcher
27{28{
2829
29Base::Base(const std::shared_ptr<Registry>& registry)30Base::Base(const std::shared_ptr<Registry::Impl>& registry)
30{31 : registry_(registry)
32{
33}
34
35/** Accessor function to the registry that ensures we can still
36 get it, which we always should be able to, but in case. */
37std::shared_ptr<Registry::Impl> Base::getReg()
38{
39 auto reg = registry_.lock();
40 if (G_UNLIKELY(!reg))
41 {
42 throw std::runtime_error{"App Store lost track of the Registry that owns it"};
43 }
44 return reg;
31}45}
3246
33} // namespace info_watcher47} // namespace info_watcher
3448
=== modified file 'libubuntu-app-launch/info-watcher.h'
--- libubuntu-app-launch/info-watcher.h 2017-02-08 21:31:37 +0000
+++ libubuntu-app-launch/info-watcher.h 2017-04-04 21:22:36 +0000
@@ -35,7 +35,7 @@
35class Base35class Base
36{36{
37public:37public:
38 Base(const std::shared_ptr<Registry>& registry);38 Base(const std::shared_ptr<Registry::Impl>& registry);
39 virtual ~Base() = default;39 virtual ~Base() = default;
4040
41 virtual core::Signal<const std::shared_ptr<Application>&>& infoChanged()41 virtual core::Signal<const std::shared_ptr<Application>&>& infoChanged()
@@ -44,7 +44,16 @@
44 }44 }
4545
46protected:46protected:
47 /** Signal for info changed on an application */
47 core::Signal<const std::shared_ptr<Application>&> infoChanged_;48 core::Signal<const std::shared_ptr<Application>&> infoChanged_;
49
50 /** Accessor function to the registry that ensures we can still
51 get it, which we always should be able to, but in case. */
52 std::shared_ptr<Registry::Impl> getReg();
53
54private:
55 /** Pointer to our implementing registry */
56 std::weak_ptr<Registry::Impl> registry_;
48};57};
4958
50} // namespace info_watcher59} // namespace info_watcher
5160
=== modified file 'libubuntu-app-launch/jobs-base.cpp'
--- libubuntu-app-launch/jobs-base.cpp 2017-03-21 03:28:22 +0000
+++ libubuntu-app-launch/jobs-base.cpp 2017-04-04 21:22:36 +0000
@@ -43,10 +43,9 @@
43namespace manager43namespace manager
44{44{
4545
46Base::Base(const std::shared_ptr<Registry>& registry)46Base::Base(const std::shared_ptr<Registry::Impl>& registry)
47 : registry_(registry)47 : registry_{registry}
48 , allApplicationJobs_{"application-legacy", "application-snap"}48 , allApplicationJobs_{"application-legacy", "application-snap"}
49 , dbus_(registry->impl->_dbus)
50{49{
51}50}
5251
@@ -56,7 +55,7 @@
5655
57/** Should determine which jobs backend to use, but we only have56/** Should determine which jobs backend to use, but we only have
58 one right now. */57 one right now. */
59std::shared_ptr<Base> Base::determineFactory(std::shared_ptr<Registry> registry)58std::shared_ptr<Base> Base::determineFactory(const std::shared_ptr<Registry::Impl>& registry)
60{59{
61 g_debug("Building a systemd jobs manager");60 g_debug("Building a systemd jobs manager");
62 return std::make_shared<jobs::manager::SystemD>(registry);61 return std::make_shared<jobs::manager::SystemD>(registry);
@@ -79,10 +78,9 @@
7978
80 try79 try
81 {80 {
82 auto reg = registry_.lock();81 auto reg = getReg();
8382 auto appId = reg->find(appid);
84 auto appId = AppID::find(reg, appid);83 auto app = reg->createApp(appId);
85 auto app = Application::create(appId, reg);
86 auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid);84 auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid);
8785
88 sig_appStarted(app, inst);86 sig_appStarted(app, inst);
@@ -109,10 +107,9 @@
109107
110 try108 try
111 {109 {
112 auto reg = registry_.lock();110 auto reg = getReg();
113111 auto appId = reg->find(appid);
114 auto appId = AppID::find(reg, appid);112 auto app = reg->createApp(appId);
115 auto app = Application::create(appId, reg);
116 auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid);113 auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid);
117114
118 sig_appStopped(app, inst);115 sig_appStopped(app, inst);
@@ -141,10 +138,9 @@
141138
142 try139 try
143 {140 {
144 auto reg = registry_.lock();141 auto reg = getReg();
145142 auto appId = reg->find(appid);
146 auto appId = AppID::find(reg, appid);143 auto app = reg->createApp(appId);
147 auto app = Application::create(appId, reg);
148 auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid);144 auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid);
149145
150 sig_appFailed(app, inst, reason);146 sig_appFailed(app, inst, reason);
@@ -166,7 +162,7 @@
166{162{
167 /** Keeping a weak pointer because the handle is held by163 /** Keeping a weak pointer because the handle is held by
168 the registry implementation. */164 the registry implementation. */
169 std::weak_ptr<Registry> weakReg;165 std::weak_ptr<Registry::Impl> weakReg;
170};166};
171167
172/** Core handler for pause and resume events. Includes turning the GVariant168/** Core handler for pause and resume events. Includes turning the GVariant
@@ -175,7 +171,7 @@
175 const std::shared_ptr<Application::Instance>&,171 const std::shared_ptr<Application::Instance>&,
176 const std::vector<pid_t>&>& signal,172 const std::vector<pid_t>&>& signal,
177 const std::shared_ptr<GVariant>& params,173 const std::shared_ptr<GVariant>& params,
178 const std::shared_ptr<Registry>& reg)174 const std::shared_ptr<Registry::Impl>& reg)
179{175{
180 std::vector<pid_t> pids;176 std::vector<pid_t> pids;
181 auto vappid = unique_glib(g_variant_get_child_value(params.get(), 0));177 auto vappid = unique_glib(g_variant_get_child_value(params.get(), 0));
@@ -193,8 +189,8 @@
193 auto cappid = g_variant_get_string(vappid.get(), NULL);189 auto cappid = g_variant_get_string(vappid.get(), NULL);
194 auto cinstid = g_variant_get_string(vinstid.get(), NULL);190 auto cinstid = g_variant_get_string(vinstid.get(), NULL);
195191
196 auto appid = ubuntu::app_launch::AppID::find(reg, cappid);192 auto appid = reg->find(cappid);
197 auto app = Application::create(appid, reg);193 auto app = reg->createApp(appid);
198 auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(cinstid);194 auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(cinstid);
199195
200 signal(app, inst, pids);196 signal(app, inst, pids);
@@ -210,13 +206,12 @@
210 Base::appPaused()206 Base::appPaused()
211{207{
212 std::call_once(flag_appPaused, [this]() {208 std::call_once(flag_appPaused, [this]() {
213 auto reg = registry_.lock();209 auto reg = getReg();
214210 reg->thread.executeOnThread<bool>([this, reg]() {
215 reg->impl->thread.executeOnThread<bool>([this, reg]() {
216 upstartEventData* data = new upstartEventData{reg};211 upstartEventData* data = new upstartEventData{reg};
217212
218 handle_appPaused = managedDBusSignalConnection(213 handle_appPaused = managedDBusSignalConnection(
219 g_dbus_connection_signal_subscribe(reg->impl->_dbus.get(), /* bus */214 g_dbus_connection_signal_subscribe(reg->_dbus.get(), /* bus */
220 nullptr, /* sender */215 nullptr, /* sender */
221 "com.canonical.UbuntuAppLaunch", /* interface */216 "com.canonical.UbuntuAppLaunch", /* interface */
222 "ApplicationPaused", /* signal */217 "ApplicationPaused", /* signal */
@@ -235,7 +230,7 @@
235 }230 }
236231
237 auto sparams = share_glib(g_variant_ref(params));232 auto sparams = share_glib(g_variant_ref(params));
238 auto manager = std::dynamic_pointer_cast<Base>(reg->impl->jobs);233 auto manager = std::dynamic_pointer_cast<Base>(reg->jobs());
239 manager->pauseEventEmitted(manager->sig_appPaused, sparams, reg);234 manager->pauseEventEmitted(manager->sig_appPaused, sparams, reg);
240 }, /* callback */235 }, /* callback */
241 data, /* user data */236 data, /* user data */
@@ -243,7 +238,7 @@
243 auto data = reinterpret_cast<upstartEventData*>(user_data);238 auto data = reinterpret_cast<upstartEventData*>(user_data);
244 delete data;239 delete data;
245 }), /* user data destroy */240 }), /* user data destroy */
246 reg->impl->_dbus);241 reg->_dbus);
247242
248 return true;243 return true;
249 });244 });
@@ -260,13 +255,12 @@
260 Base::appResumed()255 Base::appResumed()
261{256{
262 std::call_once(flag_appResumed, [this]() {257 std::call_once(flag_appResumed, [this]() {
263 auto reg = registry_.lock();258 auto reg = getReg();
264259 reg->thread.executeOnThread<bool>([this, reg]() {
265 reg->impl->thread.executeOnThread<bool>([this, reg]() {
266 upstartEventData* data = new upstartEventData{reg};260 upstartEventData* data = new upstartEventData{reg};
267261
268 handle_appResumed = managedDBusSignalConnection(262 handle_appResumed = managedDBusSignalConnection(
269 g_dbus_connection_signal_subscribe(reg->impl->_dbus.get(), /* bus */263 g_dbus_connection_signal_subscribe(reg->_dbus.get(), /* bus */
270 nullptr, /* sender */264 nullptr, /* sender */
271 "com.canonical.UbuntuAppLaunch", /* interface */265 "com.canonical.UbuntuAppLaunch", /* interface */
272 "ApplicationResumed", /* signal */266 "ApplicationResumed", /* signal */
@@ -285,7 +279,7 @@
285 }279 }
286280
287 auto sparams = share_glib(g_variant_ref(params));281 auto sparams = share_glib(g_variant_ref(params));
288 auto manager = std::dynamic_pointer_cast<Base>(reg->impl->jobs);282 auto manager = std::dynamic_pointer_cast<Base>(reg->jobs());
289 manager->pauseEventEmitted(manager->sig_appResumed, sparams,283 manager->pauseEventEmitted(manager->sig_appResumed, sparams,
290 reg);284 reg);
291 }, /* callback */285 }, /* callback */
@@ -294,7 +288,7 @@
294 auto data = reinterpret_cast<upstartEventData*>(user_data);288 auto data = reinterpret_cast<upstartEventData*>(user_data);
295 delete data;289 delete data;
296 }), /* user data destroy */290 }), /* user data destroy */
297 reg->impl->_dbus);291 reg->_dbus);
298292
299 return true;293 return true;
300 });294 });
@@ -321,10 +315,9 @@
321315
322 try316 try
323 {317 {
324 auto reg = registry_.lock();318 auto reg = getReg();
325319 auto appId = reg->find(appid);
326 auto appId = ubuntu::app_launch::AppID::parse(appid);320 auto helper = reg->createHelper(type, appId, reg);
327 auto helper = Helper::create(type, appId, reg);
328 auto inst = std::dynamic_pointer_cast<helper_impls::Base>(helper)->existingInstance(instanceid);321 auto inst = std::dynamic_pointer_cast<helper_impls::Base>(helper)->existingInstance(instanceid);
329322
330 (*sig_helpersStarted.at(type.value()))(helper, inst);323 (*sig_helpersStarted.at(type.value()))(helper, inst);
@@ -361,10 +354,9 @@
361354
362 try355 try
363 {356 {
364 auto reg = registry_.lock();357 auto reg = getReg();
365
366 auto appId = ubuntu::app_launch::AppID::parse(appid);358 auto appId = ubuntu::app_launch::AppID::parse(appid);
367 auto helper = Helper::create(type, appId, reg);359 auto helper = reg->createHelper(type, appId, reg);
368 auto inst = std::dynamic_pointer_cast<helper_impls::Base>(helper)->existingInstance(instanceid);360 auto inst = std::dynamic_pointer_cast<helper_impls::Base>(helper)->existingInstance(instanceid);
369361
370 (*sig_helpersStopped.at(type.value()))(helper, inst);362 (*sig_helpersStopped.at(type.value()))(helper, inst);
@@ -401,10 +393,9 @@
401393
402 try394 try
403 {395 {
404 auto reg = registry_.lock();396 auto reg = getReg();
405
406 auto appId = ubuntu::app_launch::AppID::parse(appid);397 auto appId = ubuntu::app_launch::AppID::parse(appid);
407 auto helper = Helper::create(type, appId, reg);398 auto helper = reg->createHelper(type, appId, reg);
408 auto inst = std::dynamic_pointer_cast<helper_impls::Base>(helper)->existingInstance(instanceid);399 auto inst = std::dynamic_pointer_cast<helper_impls::Base>(helper)->existingInstance(instanceid);
409400
410 (*sig_helpersFailed.at(type.value()))(helper, inst, reason);401 (*sig_helpersFailed.at(type.value()))(helper, inst, reason);
@@ -427,7 +418,7 @@
427/** Take the GVariant of parameters and turn them into an application and418/** Take the GVariant of parameters and turn them into an application and
428 and instance. Easier to read in the smaller function */419 and instance. Easier to read in the smaller function */
429std::tuple<std::shared_ptr<Application>, std::shared_ptr<Application::Instance>> Base::managerParams(420std::tuple<std::shared_ptr<Application>, std::shared_ptr<Application::Instance>> Base::managerParams(
430 const std::shared_ptr<GVariant>& params, const std::shared_ptr<Registry>& reg)421 const std::shared_ptr<GVariant>& params, const std::shared_ptr<Registry::Impl>& reg)
431{422{
432 std::shared_ptr<Application> app;423 std::shared_ptr<Application> app;
433 std::shared_ptr<Application::Instance> instance;424 std::shared_ptr<Application::Instance> instance;
@@ -436,8 +427,10 @@
436 const gchar* cinstid = nullptr;427 const gchar* cinstid = nullptr;
437 g_variant_get(params.get(), "(&s&s)", &cappid, &cinstid);428 g_variant_get(params.get(), "(&s&s)", &cappid, &cinstid);
438429
439 auto appid = ubuntu::app_launch::AppID::find(reg, cappid);430 auto appid = reg->find(cappid);
440 app = ubuntu::app_launch::Application::create(appid, reg);431 app = reg->createApp(appid);
432
433 /* TODO Instance */
441434
442 return std::make_tuple(app, instance);435 return std::make_tuple(app, instance);
443}436}
@@ -448,8 +441,8 @@
448{441{
449 /* Keeping a weak pointer because the handle is held by442 /* Keeping a weak pointer because the handle is held by
450 the registry implementation. */443 the registry implementation. */
451 std::weak_ptr<Registry> weakReg;444 std::weak_ptr<Registry::Impl> weakReg;
452 std::function<void(const std::shared_ptr<Registry>& reg,445 std::function<void(const std::shared_ptr<Registry::Impl>& reg,
453 const std::shared_ptr<Application>& app,446 const std::shared_ptr<Application>& app,
454 const std::shared_ptr<Application::Instance>& instance,447 const std::shared_ptr<Application::Instance>& instance,
455 const std::shared_ptr<GDBusConnection>&,448 const std::shared_ptr<GDBusConnection>&,
@@ -462,19 +455,19 @@
462 code so it got pulled out into a function. Takes the same of the signal, the registry455 code so it got pulled out into a function. Takes the same of the signal, the registry
463 that we're using and a function to call after we've messaged all the parameters456 that we're using and a function to call after we've messaged all the parameters
464 into being something C++-ish. */457 into being something C++-ish. */
465guint Base::managerSignalHelper(const std::shared_ptr<Registry>& reg,458guint Base::managerSignalHelper(const std::string& signalname,
466 const std::string& signalname,459 std::function<void(const std::shared_ptr<Registry::Impl>& reg,
467 std::function<void(const std::shared_ptr<Registry>& reg,
468 const std::shared_ptr<Application>& app,460 const std::shared_ptr<Application>& app,
469 const std::shared_ptr<Application::Instance>& instance,461 const std::shared_ptr<Application::Instance>& instance,
470 const std::shared_ptr<GDBusConnection>&,462 const std::shared_ptr<GDBusConnection>&,
471 const std::string&,463 const std::string&,
472 const std::shared_ptr<GVariant>&)> responsefunc)464 const std::shared_ptr<GVariant>&)> responsefunc)
473{465{
466 auto reg = getReg();
474 managerEventData* focusdata = new managerEventData{reg, responsefunc};467 managerEventData* focusdata = new managerEventData{reg, responsefunc};
475468
476 return g_dbus_connection_signal_subscribe(469 return g_dbus_connection_signal_subscribe(
477 reg->impl->_dbus.get(), /* bus */470 reg->_dbus.get(), /* bus */
478 nullptr, /* sender */471 nullptr, /* sender */
479 "com.canonical.UbuntuAppLaunch", /* interface */472 "com.canonical.UbuntuAppLaunch", /* interface */
480 signalname.c_str(), /* signal */473 signalname.c_str(), /* signal */
@@ -494,7 +487,7 @@
494487
495 /* If we're still conneted and the manager has been cleared488 /* If we're still conneted and the manager has been cleared
496 we'll just be a no-op */489 we'll just be a no-op */
497 auto ljobs = std::dynamic_pointer_cast<Base>(reg->impl->jobs);490 auto ljobs = std::dynamic_pointer_cast<Base>(reg->jobs());
498 if (!ljobs->manager_)491 if (!ljobs->manager_)
499 {492 {
500 return;493 return;
@@ -540,41 +533,43 @@
540 manager_ = manager;533 manager_ = manager;
541534
542 std::call_once(flag_managerSignals, [this]() {535 std::call_once(flag_managerSignals, [this]() {
543 auto reg = registry_.lock();536 auto reg = getReg();
544537
545 if (!reg)538 if (!reg->thread.executeOnThread<bool>([this, reg]() {
546 {
547 g_warning("Registry object invalid!");
548 return;
549 }
550
551 if (!reg->impl->thread.executeOnThread<bool>([this, reg]() {
552 handle_managerSignalFocus = managedDBusSignalConnection(539 handle_managerSignalFocus = managedDBusSignalConnection(
553 managerSignalHelper(540 managerSignalHelper(
554 reg, "UnityFocusRequest",541 "UnityFocusRequest",
555 [](const std::shared_ptr<Registry>& reg, const std::shared_ptr<Application>& app,542 [](const std::shared_ptr<Registry::Impl>& reg, const std::shared_ptr<Application>& app,
556 const std::shared_ptr<Application::Instance>& instance,543 const std::shared_ptr<Application::Instance>& instance,
557 const std::shared_ptr<GDBusConnection>& conn, const std::string& sender,544 const std::shared_ptr<GDBusConnection>& conn, const std::string& sender,
558 const std::shared_ptr<GVariant>& params) {545 const std::shared_ptr<GVariant>& params) {
559 /* Nothing to do today */546 /* Nothing to do today */
560 std::dynamic_pointer_cast<Base>(reg->impl->jobs)547 std::dynamic_pointer_cast<Base>(reg->jobs())
561 ->manager_->focusRequest(app, instance, [](bool response) {548 ->manager_->focusRequest(app, instance, [](bool response) {
562 /* NOTE: We have no clue what thread this is gonna be549 /* NOTE: We have no
563 executed on, but since we're just talking to the GDBus550 clue what thread
564 thread it isn't an issue today. Be careful in changing551 this is gonna be
552 executed on, but
553 since we're just
554 talking to the
555 GDBus
556 thread it isn't an
557 issue today. Be
558 careful in
559 changing
565 this code. */560 this code. */
566 });561 });
567 }),562 }),
568 reg->impl->_dbus);563 reg->_dbus);
569 handle_managerSignalStarting = managedDBusSignalConnection(564 handle_managerSignalStarting = managedDBusSignalConnection(
570 managerSignalHelper(565 managerSignalHelper(
571 reg, "UnityStartingBroadcast",566 "UnityStartingBroadcast",
572 [](const std::shared_ptr<Registry>& reg, const std::shared_ptr<Application>& app,567 [](const std::shared_ptr<Registry::Impl>& reg, const std::shared_ptr<Application>& app,
573 const std::shared_ptr<Application::Instance>& instance,568 const std::shared_ptr<Application::Instance>& instance,
574 const std::shared_ptr<GDBusConnection>& conn, const std::string& sender,569 const std::shared_ptr<GDBusConnection>& conn, const std::string& sender,
575 const std::shared_ptr<GVariant>& params) {570 const std::shared_ptr<GVariant>& params) {
576571
577 std::dynamic_pointer_cast<Base>(reg->impl->jobs)572 std::dynamic_pointer_cast<Base>(reg->jobs())
578 ->manager_->startingRequest(app, instance, [conn, sender, params](bool response) {573 ->manager_->startingRequest(app, instance, [conn, sender, params](bool response) {
579 /* NOTE: We have no clue what thread this is gonna be574 /* NOTE: We have no clue what thread this is gonna be
580 executed on, but since we're just talking to the GDBus575 executed on, but since we're just talking to the GDBus
@@ -591,15 +586,15 @@
591 }586 }
592 });587 });
593 }),588 }),
594 reg->impl->_dbus);589 reg->_dbus);
595 handle_managerSignalResume = managedDBusSignalConnection(590 handle_managerSignalResume = managedDBusSignalConnection(
596 managerSignalHelper(591 managerSignalHelper(
597 reg, "UnityResumeRequest",592 "UnityResumeRequest",
598 [](const std::shared_ptr<Registry>& reg, const std::shared_ptr<Application>& app,593 [](const std::shared_ptr<Registry::Impl>& reg, const std::shared_ptr<Application>& app,
599 const std::shared_ptr<Application::Instance>& instance,594 const std::shared_ptr<Application::Instance>& instance,
600 const std::shared_ptr<GDBusConnection>& conn, const std::string& sender,595 const std::shared_ptr<GDBusConnection>& conn, const std::string& sender,
601 const std::shared_ptr<GVariant>& params) {596 const std::shared_ptr<GVariant>& params) {
602 std::dynamic_pointer_cast<Base>(reg->impl->jobs)597 std::dynamic_pointer_cast<Base>(reg->jobs())
603 ->manager_->resumeRequest(app, instance, [conn, sender, params](bool response) {598 ->manager_->resumeRequest(app, instance, [conn, sender, params](bool response) {
604 /* NOTE: We have no clue what thread this is gonna be599 /* NOTE: We have no clue what thread this is gonna be
605 executed on, but since we're just talking to the GDBus600 executed on, but since we're just talking to the GDBus
@@ -616,7 +611,7 @@
616 }611 }
617 });612 });
618 }),613 }),
619 reg->impl->_dbus);614 reg->_dbus);
620615
621 return true;616 return true;
622 }))617 }))
@@ -637,20 +632,13 @@
637 on the appids associated with the application jobs */632 on the appids associated with the application jobs */
638std::list<std::shared_ptr<Application>> Base::runningApps()633std::list<std::shared_ptr<Application>> Base::runningApps()
639{634{
640 auto registry = registry_.lock();635 auto reg = getReg();
641
642 if (!registry)
643 {
644 g_warning("Unable to list apps without a registry");
645 return {};
646 }
647
648 auto appids = runningAppIds(allApplicationJobs_);636 auto appids = runningAppIds(allApplicationJobs_);
649637
650 std::list<std::shared_ptr<Application>> apps;638 std::list<std::shared_ptr<Application>> apps;
651 for (const auto& appid : appids)639 for (const auto& appid : appids)
652 {640 {
653 auto id = AppID::find(registry, appid);641 auto id = reg->find(appid);
654 if (id.empty())642 if (id.empty())
655 {643 {
656 g_debug("Unable to handle AppID: %s", appid.c_str());644 g_debug("Unable to handle AppID: %s", appid.c_str());
@@ -659,7 +647,7 @@
659647
660 try648 try
661 {649 {
662 apps.emplace_back(Application::create(id, registry));650 apps.emplace_back(reg->createApp(id));
663 }651 }
664 catch (std::runtime_error& e)652 catch (std::runtime_error& e)
665 {653 {
@@ -674,27 +662,20 @@
674 on the appids associated with the application jobs */662 on the appids associated with the application jobs */
675std::list<std::shared_ptr<Helper>> Base::runningHelpers(const Helper::Type& type)663std::list<std::shared_ptr<Helper>> Base::runningHelpers(const Helper::Type& type)
676{664{
677 auto registry = registry_.lock();665 auto reg = getReg();
678
679 if (!registry)
680 {
681 g_warning("Unable to list helpers without a registry");
682 return {};
683 }
684
685 auto appids = runningAppIds({type.value()});666 auto appids = runningAppIds({type.value()});
686667
687 std::list<std::shared_ptr<Helper>> helpers;668 std::list<std::shared_ptr<Helper>> helpers;
688 for (const auto& appid : appids)669 for (const auto& appid : appids)
689 {670 {
690 auto id = AppID::parse(appid);671 auto id = reg->find(appid);
691 if (id.empty())672 if (id.empty())
692 {673 {
693 g_debug("Unable to handle AppID: %s", appid.c_str());674 g_debug("Unable to handle AppID: %s", appid.c_str());
694 continue;675 continue;
695 }676 }
696677
697 helpers.emplace_back(Helper::create(type, id, registry));678 helpers.emplace_back(reg->createHelper(type, id, reg));
698 }679 }
699680
700 return helpers;681 return helpers;
@@ -709,7 +690,7 @@
709 const std::string& job,690 const std::string& job,
710 const std::string& instance,691 const std::string& instance,
711 const std::vector<Application::URL>& urls,692 const std::vector<Application::URL>& urls,
712 const std::shared_ptr<Registry>& registry)693 const std::shared_ptr<Registry::Impl>& registry)
713 : appId_(appId)694 : appId_(appId)
714 , job_(job)695 , job_(job)
715 , instance_(instance)696 , instance_(instance)
@@ -742,7 +723,7 @@
742void Base::pause()723void Base::pause()
743{724{
744 g_debug("Pausing application: %s", std::string(appId_).c_str());725 g_debug("Pausing application: %s", std::string(appId_).c_str());
745 registry_->impl->zgSendEvent(appId_, ZEITGEIST_ZG_LEAVE_EVENT);726 registry_->zgSendEvent(appId_, ZEITGEIST_ZG_LEAVE_EVENT);
746727
747 auto pids = forAllPids([this](pid_t pid) {728 auto pids = forAllPids([this](pid_t pid) {
748 auto oomval = oom::paused();729 auto oomval = oom::paused();
@@ -759,7 +740,7 @@
759void Base::resume()740void Base::resume()
760{741{
761 g_debug("Resuming application: %s", std::string(appId_).c_str());742 g_debug("Resuming application: %s", std::string(appId_).c_str());
762 registry_->impl->zgSendEvent(appId_, ZEITGEIST_ZG_ACCESS_EVENT);743 registry_->zgSendEvent(appId_, ZEITGEIST_ZG_ACCESS_EVENT);
763744
764 auto pids = forAllPids([this](pid_t pid) {745 auto pids = forAllPids([this](pid_t pid) {
765 auto oomval = oom::focused();746 auto oomval = oom::focused();
@@ -782,7 +763,7 @@
782 g_variant_builder_init(&params, G_VARIANT_TYPE_TUPLE);763 g_variant_builder_init(&params, G_VARIANT_TYPE_TUPLE);
783 g_variant_builder_add_value(&params, g_variant_new_string(std::string(appId_).c_str()));764 g_variant_builder_add_value(&params, g_variant_new_string(std::string(appId_).c_str()));
784 g_variant_builder_add_value(&params, g_variant_new_string(instance_.c_str()));765 g_variant_builder_add_value(&params, g_variant_new_string(instance_.c_str()));
785 g_dbus_connection_emit_signal(registry_->impl->_dbus.get(), /* bus */766 g_dbus_connection_emit_signal(registry_->_dbus.get(), /* bus */
786 nullptr, /* destination */767 nullptr, /* destination */
787 "/", /* path */768 "/", /* path */
788 "com.canonical.UbuntuAppLaunch", /* interface */769 "com.canonical.UbuntuAppLaunch", /* interface */
@@ -835,7 +816,7 @@
835 \param pids List of PIDs to turn into variants to send816 \param pids List of PIDs to turn into variants to send
836 \param signal Name of the DBus signal to send817 \param signal Name of the DBus signal to send
837*/818*/
838void Base::pidListToDbus(const std::shared_ptr<Registry>& reg,819void Base::pidListToDbus(const std::shared_ptr<Registry::Impl>& reg,
839 const AppID& appid,820 const AppID& appid,
840 const std::string& instanceid,821 const std::string& instanceid,
841 const std::vector<pid_t>& pids,822 const std::vector<pid_t>& pids,
@@ -867,7 +848,7 @@
867 g_variant_builder_add_value(&params, vpids.get());848 g_variant_builder_add_value(&params, vpids.get());
868849
869 GError* error = nullptr;850 GError* error = nullptr;
870 g_dbus_connection_emit_signal(reg->impl->_dbus.get(), /* bus */851 g_dbus_connection_emit_signal(reg->_dbus.get(), /* bus */
871 nullptr, /* destination */852 nullptr, /* destination */
872 "/", /* path */853 "/", /* path */
873 "com.canonical.UbuntuAppLaunch", /* interface */854 "com.canonical.UbuntuAppLaunch", /* interface */
@@ -1039,22 +1020,21 @@
1039 std::array<const char*, 4> args = {OOM_HELPER, pidstr.c_str(), oomstr.c_str(), nullptr};1020 std::array<const char*, 4> args = {OOM_HELPER, pidstr.c_str(), oomstr.c_str(), nullptr};
10401021
1041 g_debug("Excuting OOM Helper (pid: %d, score: %d): %s", int(pid), int(oomvalue),1022 g_debug("Excuting OOM Helper (pid: %d, score: %d): %s", int(pid), int(oomvalue),
1042 std::accumulate(args.begin(), args.end(), std::string{},1023 std::accumulate(args.begin(), args.end(), std::string{}, [](const std::string& instr,
1043 [](const std::string& instr, const char* output) -> std::string {1024 const char* output) -> std::string {
1044 if (instr.empty())1025 if (instr.empty())
1045 {1026 {
1046 return output;1027 return output;
1047 }1028 }
1048 else if (output != nullptr)1029 else if (output != nullptr)
1049 {1030 {
1050 return instr + " " + std::string(output);1031 return instr + " " + std::string(output);
1051 }1032 }
1052 else1033 else
1053 {1034 {
1054 return instr;1035 return instr;
1055 }1036 }
1056 })1037 }).c_str());
1057 .c_str());
10581038
1059 g_spawn_async(nullptr, /* working dir */1039 g_spawn_async(nullptr, /* working dir */
1060 (char**)(args.data()), /* args */1040 (char**)(args.data()), /* args */
10611041
=== modified file 'libubuntu-app-launch/jobs-base.h'
--- libubuntu-app-launch/jobs-base.h 2017-03-21 03:28:22 +0000
+++ libubuntu-app-launch/jobs-base.h 2017-04-04 21:22:36 +0000
@@ -45,7 +45,7 @@
45 const std::string& job,45 const std::string& job,
46 const std::string& instance,46 const std::string& instance,
47 const std::vector<Application::URL>& urls,47 const std::vector<Application::URL>& urls,
48 const std::shared_ptr<Registry>& registry);48 const std::shared_ptr<Registry::Impl>& registry);
49 virtual ~Base() = default;49 virtual ~Base() = default;
5050
51 bool isRunning() override;51 bool isRunning() override;
@@ -74,10 +74,10 @@
74 should look at perhaps changing that. */74 should look at perhaps changing that. */
75 std::vector<Application::URL> urls_;75 std::vector<Application::URL> urls_;
76 /** A link to the registry we're using for connections */76 /** A link to the registry we're using for connections */
77 std::shared_ptr<Registry> registry_;77 std::shared_ptr<Registry::Impl> registry_;
7878
79 std::vector<pid_t> forAllPids(std::function<void(pid_t)> eachPid);79 std::vector<pid_t> forAllPids(std::function<void(pid_t)> eachPid);
80 static void pidListToDbus(const std::shared_ptr<Registry>& reg,80 static void pidListToDbus(const std::shared_ptr<Registry::Impl>& reg,
81 const AppID& appid,81 const AppID& appid,
82 const std::string& instanceid,82 const std::string& instanceid,
83 const std::vector<pid_t>& pids,83 const std::vector<pid_t>& pids,
@@ -104,7 +104,7 @@
104class Base104class Base
105{105{
106public:106public:
107 Base(const std::shared_ptr<Registry>& registry);107 Base(const std::shared_ptr<Registry::Impl>& registry);
108 virtual ~Base();108 virtual ~Base();
109109
110 virtual std::shared_ptr<Application::Instance> launch(110 virtual std::shared_ptr<Application::Instance> launch(
@@ -129,7 +129,7 @@
129129
130 const std::list<std::string>& getAllApplicationJobs() const;130 const std::list<std::string>& getAllApplicationJobs() const;
131131
132 static std::shared_ptr<Base> determineFactory(std::shared_ptr<Registry> registry);132 static std::shared_ptr<Base> determineFactory(const std::shared_ptr<Registry::Impl>& registry);
133133
134 /* Signals to apps */134 /* Signals to apps */
135 virtual core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&>&135 virtual core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&>&
@@ -153,9 +153,8 @@
153 Helper::Type type);153 Helper::Type type);
154 virtual core::Signal<const std::shared_ptr<Helper>&, const std::shared_ptr<Helper::Instance>&>& helperStopped(154 virtual core::Signal<const std::shared_ptr<Helper>&, const std::shared_ptr<Helper::Instance>&>& helperStopped(
155 Helper::Type type);155 Helper::Type type);
156 virtual core::Signal<const std::shared_ptr<Helper>&,156 virtual core::
157 const std::shared_ptr<Helper::Instance>&,157 Signal<const std::shared_ptr<Helper>&, const std::shared_ptr<Helper::Instance>&, Registry::FailureType>&
158 Registry::FailureType>&
159 helperFailed(Helper::Type type);158 helperFailed(Helper::Type type);
160 /* Job signals from implementations */159 /* Job signals from implementations */
161 virtual core::Signal<const std::string&, const std::string&, const std::string&>& jobStarted() = 0;160 virtual core::Signal<const std::string&, const std::string&, const std::string&>& jobStarted() = 0;
@@ -168,19 +167,28 @@
168 virtual void clearManager();167 virtual void clearManager();
169168
170protected:169protected:
170 /** Accessor function to the registry that ensures we can still
171 get it, which we always should be able to, but in case. */
172 std::shared_ptr<Registry::Impl> getReg()
173 {
174 auto reg = registry_.lock();
175 if (G_UNLIKELY(!reg))
176 {
177 throw std::runtime_error{"Jobs manager lost track of the Registry that owns it"};
178 }
179 return reg;
180 }
181
182 /** Application manager instance */
183 std::shared_ptr<Registry::Manager> manager_;
184
185private:
171 /** A link to the registry */186 /** A link to the registry */
172 std::weak_ptr<Registry> registry_;187 std::weak_ptr<Registry::Impl> registry_;
173188
174 /** A set of all the job names used by applications */189 /** A set of all the job names used by applications */
175 std::list<std::string> allApplicationJobs_;190 std::list<std::string> allApplicationJobs_;
176191
177 /** The DBus connection we're connecting to */
178 std::shared_ptr<GDBusConnection> dbus_;
179
180 /** Application manager instance */
181 std::shared_ptr<Registry::Manager> manager_;
182
183private:
184 /** Signal object for applications started */192 /** Signal object for applications started */
185 core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&> sig_appStarted;193 core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&> sig_appStarted;
186 /** Signal object for applications stopped */194 /** Signal object for applications stopped */
@@ -241,18 +249,17 @@
241 const std::shared_ptr<Application::Instance>&,249 const std::shared_ptr<Application::Instance>&,
242 const std::vector<pid_t>&>& signal,250 const std::vector<pid_t>&>& signal,
243 const std::shared_ptr<GVariant>& params,251 const std::shared_ptr<GVariant>& params,
244 const std::shared_ptr<Registry>& reg);252 const std::shared_ptr<Registry::Impl>& reg);
245253
246 static std::tuple<std::shared_ptr<Application>, std::shared_ptr<Application::Instance>> managerParams(254 static std::tuple<std::shared_ptr<Application>, std::shared_ptr<Application::Instance>> managerParams(
247 const std::shared_ptr<GVariant>& params, const std::shared_ptr<Registry>& reg);255 const std::shared_ptr<GVariant>& params, const std::shared_ptr<Registry::Impl>& reg);
248 static guint managerSignalHelper(const std::shared_ptr<Registry>& reg,256 guint managerSignalHelper(const std::string& signalname,
249 const std::string& signalname,257 std::function<void(const std::shared_ptr<Registry::Impl>& reg,
250 std::function<void(const std::shared_ptr<Registry>& reg,258 const std::shared_ptr<Application>& app,
251 const std::shared_ptr<Application>& app,259 const std::shared_ptr<Application::Instance>& instance,
252 const std::shared_ptr<Application::Instance>& instance,260 const std::shared_ptr<GDBusConnection>&,
253 const std::shared_ptr<GDBusConnection>&,261 const std::string&,
254 const std::string&,262 const std::shared_ptr<GVariant>&)> responsefunc);
255 const std::shared_ptr<GVariant>&)> responsefunc);
256};263};
257264
258} // namespace manager265} // namespace manager
259266
=== modified file 'libubuntu-app-launch/jobs-systemd.cpp'
--- libubuntu-app-launch/jobs-systemd.cpp 2017-03-21 03:28:22 +0000
+++ libubuntu-app-launch/jobs-systemd.cpp 2017-04-04 21:22:36 +0000
@@ -57,7 +57,7 @@
57 const std::string& job,57 const std::string& job,
58 const std::string& instance,58 const std::string& instance,
59 const std::vector<Application::URL>& urls,59 const std::vector<Application::URL>& urls,
60 const std::shared_ptr<Registry>& registry);60 const std::shared_ptr<Registry::Impl>& registry);
61 virtual ~SystemD()61 virtual ~SystemD()
62 {62 {
63 g_debug("Destroying a SystemD for '%s' instance '%s'", std::string(appId_).c_str(), instance_.c_str());63 g_debug("Destroying a SystemD for '%s' instance '%s'", std::string(appId_).c_str(), instance_.c_str());
@@ -76,7 +76,7 @@
76 const std::string& job,76 const std::string& job,
77 const std::string& instance,77 const std::string& instance,
78 const std::vector<Application::URL>& urls,78 const std::vector<Application::URL>& urls,
79 const std::shared_ptr<Registry>& registry)79 const std::shared_ptr<Registry::Impl>& registry)
80 : Base(appId, job, instance, urls, registry)80 : Base(appId, job, instance, urls, registry)
81{81{
82 g_debug("Creating a new SystemD for '%s' instance '%s'", std::string(appId).c_str(), instance.c_str());82 g_debug("Creating a new SystemD for '%s' instance '%s'", std::string(appId).c_str(), instance.c_str());
@@ -84,19 +84,19 @@
8484
85pid_t SystemD::primaryPid()85pid_t SystemD::primaryPid()
86{86{
87 auto manager = std::dynamic_pointer_cast<manager::SystemD>(registry_->impl->jobs);87 auto manager = std::dynamic_pointer_cast<manager::SystemD>(registry_->jobs());
88 return manager->unitPrimaryPid(appId_, job_, instance_);88 return manager->unitPrimaryPid(appId_, job_, instance_);
89}89}
9090
91std::vector<pid_t> SystemD::pids()91std::vector<pid_t> SystemD::pids()
92{92{
93 auto manager = std::dynamic_pointer_cast<manager::SystemD>(registry_->impl->jobs);93 auto manager = std::dynamic_pointer_cast<manager::SystemD>(registry_->jobs());
94 return manager->unitPids(appId_, job_, instance_);94 return manager->unitPids(appId_, job_, instance_);
95}95}
9696
97void SystemD::stop()97void SystemD::stop()
98{98{
99 auto manager = std::dynamic_pointer_cast<manager::SystemD>(registry_->impl->jobs);99 auto manager = std::dynamic_pointer_cast<manager::SystemD>(registry_->jobs());
100 manager->stopUnit(appId_, job_, instance_);100 manager->stopUnit(appId_, job_, instance_);
101}101}
102102
@@ -111,7 +111,7 @@
111// static const char * SYSTEMD_DBUS_IFACE_UNIT{"org.freedesktop.systemd1.Unit"};111// static const char * SYSTEMD_DBUS_IFACE_UNIT{"org.freedesktop.systemd1.Unit"};
112static const char* SYSTEMD_DBUS_IFACE_SERVICE{"org.freedesktop.systemd1.Service"};112static const char* SYSTEMD_DBUS_IFACE_SERVICE{"org.freedesktop.systemd1.Service"};
113113
114SystemD::SystemD(std::shared_ptr<Registry> registry)114SystemD::SystemD(const std::shared_ptr<Registry::Impl>& registry)
115 : Base(registry)115 : Base(registry)
116 , handle_unitNew(DBusSignalUnsubscriber{})116 , handle_unitNew(DBusSignalUnsubscriber{})
117 , handle_unitRemoved(DBusSignalUnsubscriber{})117 , handle_unitRemoved(DBusSignalUnsubscriber{})
@@ -129,8 +129,18 @@
129 cgroup_root_ = gcgroup_root;129 cgroup_root_ = gcgroup_root;
130 }130 }
131131
132 auto cancel = registry->impl->thread.getCancellable();132 if (getenv("UBUNTU_APP_LAUNCH_SYSTEMD_NO_RESET") != nullptr)
133 userbus_ = registry->impl->thread.executeOnThread<std::shared_ptr<GDBusConnection>>([this, cancel]() {133 {
134 noResetUnits_ = true;
135 }
136
137 setupUserbus(registry);
138}
139
140void SystemD::setupUserbus(const std::shared_ptr<Registry::Impl>& reg)
141{
142 auto cancel = reg->thread.getCancellable();
143 userbus_ = reg->thread.executeOnThread<std::shared_ptr<GDBusConnection>>([this, cancel]() {
134 GError* error = nullptr;144 GError* error = nullptr;
135 auto bus = std::shared_ptr<GDBusConnection>(145 auto bus = std::shared_ptr<GDBusConnection>(
136 [&]() -> GDBusConnection* {146 [&]() -> GDBusConnection* {
@@ -163,7 +173,7 @@
163 throw std::runtime_error(message);173 throw std::runtime_error(message);
164 }174 }
165175
166 /* If we don't subscribe, it doesn't send us signals :-( */176 /* If we don't subscribe, it doesn't send us signals */
167 g_dbus_connection_call(bus.get(), /* user bus */177 g_dbus_connection_call(bus.get(), /* user bus */
168 SYSTEMD_DBUS_ADDRESS, /* bus name */178 SYSTEMD_DBUS_ADDRESS, /* bus name */
169 SYSTEMD_DBUS_PATH_MANAGER, /* path */179 SYSTEMD_DBUS_PATH_MANAGER, /* path */
@@ -301,11 +311,6 @@
301311
302 return bus;312 return bus;
303 });313 });
304
305 if (getenv("UBUNTU_APP_LAUNCH_SYSTEMD_NO_RESET") != nullptr)
306 {
307 noResetUnits_ = true;
308 }
309}314}
310315
311SystemD::~SystemD()316SystemD::~SystemD()
@@ -354,14 +359,12 @@
354 while (g_variant_iter_loop(iter.get(), "(&s&s&s&s&s&s&ou&s&o)", &id, &description, &loadState, &activeState,359 while (g_variant_iter_loop(iter.get(), "(&s&s&s&s&s&s&ou&s&o)", &id, &description, &loadState, &activeState,
355 &subState, &following, &path, &jobId, &jobType, &jobPath))360 &subState, &following, &path, &jobId, &jobType, &jobPath))
356 {361 {
357 g_debug("List Units: %s", id);
358 try362 try
359 {363 {
360 unitNew(id, jobPath, bus);364 unitNew(id, jobPath, bus);
361 }365 }
362 catch (std::runtime_error& e)366 catch (std::runtime_error& e)
363 {367 {
364 g_debug("%s", e.what());
365 }368 }
366 }369 }
367}370}
@@ -511,12 +514,12 @@
511 if (g_strcmp0(remote_error, "org.freedesktop.systemd1.UnitExists") == 0)514 if (g_strcmp0(remote_error, "org.freedesktop.systemd1.UnitExists") == 0)
512 {515 {
513 auto urls = instance::SystemD::urlsToStrv(data->ptr->urls_);516 auto urls = instance::SystemD::urlsToStrv(data->ptr->urls_);
514 second_exec(data->bus.get(), /* DBus */517 second_exec(data->bus.get(), /* DBus */
515 data->ptr->registry_->impl->thread.getCancellable().get(), /* cancellable */518 data->ptr->registry_->thread.getCancellable().get(), /* cancellable */
516 data->ptr->primaryPid(), /* primary pid */519 data->ptr->primaryPid(), /* primary pid */
517 std::string(data->ptr->appId_).c_str(), /* appid */520 std::string(data->ptr->appId_).c_str(), /* appid */
518 data->ptr->instance_.c_str(), /* instance */521 data->ptr->instance_.c_str(), /* instance */
519 urls.get()); /* urls */522 urls.get()); /* urls */
520 }523 }
521524
522 g_free(remote_error);525 g_free(remote_error);
@@ -579,247 +582,246 @@
579 if (appId.empty())582 if (appId.empty())
580 return {};583 return {};
581584
582 bool isApplication =585 auto appJobs = getAllApplicationJobs();
583 std::find(allApplicationJobs_.begin(), allApplicationJobs_.end(), job) != allApplicationJobs_.end();586 bool isApplication = std::find(appJobs.begin(), appJobs.end(), job) != appJobs.end();
584587
585 auto registry = registry_.lock();588 auto reg = getReg();
586 return registry->impl->thread.executeOnThread<std::shared_ptr<instance::SystemD>>(589 return reg->thread.executeOnThread<std::shared_ptr<instance::SystemD>>([&]() -> std::shared_ptr<instance::SystemD> {
587 [&]() -> std::shared_ptr<instance::SystemD> {590 auto manager = std::dynamic_pointer_cast<manager::SystemD>(reg->jobs());
588 auto manager = std::dynamic_pointer_cast<manager::SystemD>(registry->impl->jobs);591 std::string appIdStr{appId};
589 std::string appIdStr{appId};592 g_debug("Initializing params for an new instance::SystemD for: %s", appIdStr.c_str());
590 g_debug("Initializing params for an new instance::SystemD for: %s", appIdStr.c_str());593
591594 tracepoint(ubuntu_app_launch, libual_start, appIdStr.c_str());
592 tracepoint(ubuntu_app_launch, libual_start, appIdStr.c_str());595
593596 int timeout = 1;
594 int timeout = 1;597 if (ubuntu::app_launch::Registry::Impl::isWatchingAppStarting())
595 if (ubuntu::app_launch::Registry::Impl::isWatchingAppStarting())598 {
596 {599 timeout = 0;
597 timeout = 0;600 }
598 }601
599602 handshake_t* handshake{nullptr};
600 handshake_t* handshake{nullptr};603
601604 if (isApplication)
602 if (isApplication)605 {
603 {606 handshake = starting_handshake_start(appIdStr.c_str(), instance.c_str(), timeout);
604 handshake = starting_handshake_start(appIdStr.c_str(), instance.c_str(), timeout);607 if (handshake == nullptr)
605 if (handshake == nullptr)608 {
606 {609 g_warning("Unable to setup starting handshake");
607 g_warning("Unable to setup starting handshake");610 }
608 }611 }
609 }612
610613 /* Figure out the unit name for the job */
611 /* Figure out the unit name for the job */614 auto unitname = unitName(SystemD::UnitInfo{appIdStr, job, instance});
612 auto unitname = unitName(SystemD::UnitInfo{appIdStr, job, instance});615
613616 /* Build up our environment */
614 /* Build up our environment */617 auto env = getenv();
615 auto env = getenv();618
616619 env.emplace_back(std::make_pair("APP_ID", appIdStr)); /* Application ID */
617 env.emplace_back(std::make_pair("APP_ID", appIdStr)); /* Application ID */620 env.emplace_back(std::make_pair("APP_LAUNCHER_PID", std::to_string(getpid()))); /* Who we are, for bugs */
618 env.emplace_back(std::make_pair("APP_LAUNCHER_PID", std::to_string(getpid()))); /* Who we are, for bugs */621
619622 copyEnv("DISPLAY", env);
620 copyEnv("DISPLAY", env);623
621624 for (const auto& prefix : {"DBUS_", "MIR_", "UBUNTU_APP_LAUNCH_"})
622 for (const auto& prefix : {"DBUS_", "MIR_", "UBUNTU_APP_LAUNCH_"})625 {
623 {626 copyEnvByPrefix(prefix, env);
624 copyEnvByPrefix(prefix, env);627 }
625 }628
626629 /* If we're in deb mode and launching legacy apps, they're gonna need
627 /* If we're in deb mode and launching legacy apps, they're gonna need630 * more context, they really have no other way to get it. */
628 * more context, they really have no other way to get it. */631 if (g_getenv("SNAP") == nullptr && appId.package.value().empty())
629 if (g_getenv("SNAP") == nullptr && appId.package.value().empty())632 {
630 {633 copyEnvByPrefix("QT_", env);
631 copyEnvByPrefix("QT_", env);634 copyEnvByPrefix("XDG_", env);
632 copyEnvByPrefix("XDG_", env);635 copyEnv("UBUNTU_APP_LAUNCH_XMIR_PATH", env);
633 copyEnv("UBUNTU_APP_LAUNCH_XMIR_PATH", env);636
634637 /* If we're in Unity8 we don't want to pass it's platform, we want
635 /* If we're in Unity8 we don't want to pass it's platform, we want638 * an application platform. */
636 * an application platform. */639 if (findEnv("QT_QPA_PLATFORM", env) == "mirserver")
637 if (findEnv("QT_QPA_PLATFORM", env) == "mirserver")640 {
638 {641 removeEnv("QT_QPA_PLATFORM", env);
639 removeEnv("QT_QPA_PLATFORM", env);642 env.emplace_back(std::make_pair("QT_QPA_PLATFORM", "ubuntumirclient"));
640 env.emplace_back(std::make_pair("QT_QPA_PLATFORM", "ubuntumirclient"));643 }
641 }644 }
642 }645
643646 /* Mir socket if we don't have one in our env */
644 /* Mir socket if we don't have one in our env */647 if (findEnv("MIR_SOCKET", env).empty())
645 if (findEnv("MIR_SOCKET", env).empty())648 {
646 {649 env.emplace_back(std::make_pair("MIR_SOCKET", g_get_user_runtime_dir() + std::string{"/mir_socket"}));
647 env.emplace_back(std::make_pair("MIR_SOCKET", g_get_user_runtime_dir() + std::string{"/mir_socket"}));650 }
648 }651
649652 if (!urls.empty())
650 if (!urls.empty())653 {
651 {654 auto accumfunc = [](const std::string& prev, Application::URL thisurl) -> std::string {
652 auto accumfunc = [](const std::string& prev, Application::URL thisurl) -> std::string {655 gchar* gescaped = g_shell_quote(thisurl.value().c_str());
653 gchar* gescaped = g_shell_quote(thisurl.value().c_str());656 std::string escaped;
654 std::string escaped;657 if (gescaped != nullptr)
655 if (gescaped != nullptr)658 {
656 {659 escaped = gescaped;
657 escaped = gescaped;660 g_free(gescaped);
658 g_free(gescaped);661 }
659 }662 else
660 else663 {
661 {664 g_warning("Unable to escape URL: %s", thisurl.value().c_str());
662 g_warning("Unable to escape URL: %s", thisurl.value().c_str());665 return prev;
663 return prev;666 }
664 }667
665668 if (prev.empty())
666 if (prev.empty())669 {
667 {670 return escaped;
668 return escaped;671 }
669 }672 else
670 else673 {
671 {674 return prev + " " + escaped;
672 return prev + " " + escaped;675 }
673 }676 };
674 };677 auto urlstring = std::accumulate(urls.begin(), urls.end(), std::string{}, accumfunc);
675 auto urlstring = std::accumulate(urls.begin(), urls.end(), std::string{}, accumfunc);678 env.emplace_back(std::make_pair("APP_URIS", urlstring));
676 env.emplace_back(std::make_pair("APP_URIS", urlstring));679 }
677 }680
678681 if (mode == launchMode::TEST)
679 if (mode == launchMode::TEST)682 {
680 {683 env.emplace_back(std::make_pair("QT_LOAD_TESTABILITY", "1"));
681 env.emplace_back(std::make_pair("QT_LOAD_TESTABILITY", "1"));684 }
682 }685
683686 /* Convert to GVariant */
684 /* Convert to GVariant */687 GVariantBuilder builder;
685 GVariantBuilder builder;688 g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);
686 g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);689
687690 g_variant_builder_add_value(&builder, g_variant_new_string(unitname.c_str()));
688 g_variant_builder_add_value(&builder, g_variant_new_string(unitname.c_str()));691 g_variant_builder_add_value(&builder, g_variant_new_string("replace")); // Job mode
689 g_variant_builder_add_value(&builder, g_variant_new_string("replace")); // Job mode692
690693 /* Parameter Array */
691 /* Parameter Array */694 g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);
692 g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);695
693696 /* ExecStart */
694 /* ExecStart */697 auto commands = parseExec(env);
695 auto commands = parseExec(env);698 if (!commands.empty())
696 if (!commands.empty())699 {
697 {
698 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
699 g_variant_builder_add_value(&builder, g_variant_new_string("ExecStart"));
700 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);
701 g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);
702
703 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
704
705 gchar* pathexec = g_find_program_in_path(commands[0].c_str());
706 if (pathexec != nullptr)
707 {
708 g_variant_builder_add_value(&builder, g_variant_new_take_string(pathexec));
709 }
710 else
711 {
712 g_debug("Unable to find '%s' in PATH=%s", commands[0].c_str(), g_getenv("PATH"));
713 g_variant_builder_add_value(&builder, g_variant_new_string(commands[0].c_str()));
714 }
715
716 g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);
717 for (const auto& param : commands)
718 {
719 g_variant_builder_add_value(&builder, g_variant_new_string(param.c_str()));
720 }
721 g_variant_builder_close(&builder);
722
723 g_variant_builder_add_value(&builder, g_variant_new_boolean(FALSE));
724
725 g_variant_builder_close(&builder);
726 g_variant_builder_close(&builder);
727 g_variant_builder_close(&builder);
728 g_variant_builder_close(&builder);
729 }
730
731 /* RemainAfterExit */
732 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);700 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
733 g_variant_builder_add_value(&builder, g_variant_new_string("RemainAfterExit"));701 g_variant_builder_add_value(&builder, g_variant_new_string("ExecStart"));
734 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);702 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);
703 g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);
704
705 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
706
707 gchar* pathexec = g_find_program_in_path(commands[0].c_str());
708 if (pathexec != nullptr)
709 {
710 g_variant_builder_add_value(&builder, g_variant_new_take_string(pathexec));
711 }
712 else
713 {
714 g_debug("Unable to find '%s' in PATH=%s", commands[0].c_str(), g_getenv("PATH"));
715 g_variant_builder_add_value(&builder, g_variant_new_string(commands[0].c_str()));
716 }
717
718 g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);
719 for (const auto& param : commands)
720 {
721 g_variant_builder_add_value(&builder, g_variant_new_string(param.c_str()));
722 }
723 g_variant_builder_close(&builder);
724
735 g_variant_builder_add_value(&builder, g_variant_new_boolean(FALSE));725 g_variant_builder_add_value(&builder, g_variant_new_boolean(FALSE));
736 g_variant_builder_close(&builder);726
737 g_variant_builder_close(&builder);727 g_variant_builder_close(&builder);
738728 g_variant_builder_close(&builder);
739 /* Type */729 g_variant_builder_close(&builder);
740 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);730 g_variant_builder_close(&builder);
741 g_variant_builder_add_value(&builder, g_variant_new_string("Type"));731 }
742 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);732
743 g_variant_builder_add_value(&builder, g_variant_new_string("oneshot"));733 /* RemainAfterExit */
744 g_variant_builder_close(&builder);734 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
745 g_variant_builder_close(&builder);735 g_variant_builder_add_value(&builder, g_variant_new_string("RemainAfterExit"));
746736 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);
747 /* Working Directory */737 g_variant_builder_add_value(&builder, g_variant_new_boolean(FALSE));
748 if (!findEnv("APP_DIR", env).empty())738 g_variant_builder_close(&builder);
749 {739 g_variant_builder_close(&builder);
750 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);740
751 g_variant_builder_add_value(&builder, g_variant_new_string("WorkingDirectory"));741 /* Type */
752 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);742 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
753 g_variant_builder_add_value(&builder, g_variant_new_string(findEnv("APP_DIR", env).c_str()));743 g_variant_builder_add_value(&builder, g_variant_new_string("Type"));
754 g_variant_builder_close(&builder);744 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);
755 g_variant_builder_close(&builder);745 g_variant_builder_add_value(&builder, g_variant_new_string("oneshot"));
756 }746 g_variant_builder_close(&builder);
757747 g_variant_builder_close(&builder);
758 /* Clean up env before shipping it */748
759 for (const auto& rmenv :749 /* Working Directory */
760 {"APP_XMIR_ENABLE", "APP_DIR", "APP_URIS", "APP_EXEC", "APP_EXEC_POLICY", "APP_LAUNCHER_PID",750 if (!findEnv("APP_DIR", env).empty())
761 "INSTANCE_ID", "MIR_SERVER_PLATFORM_PATH", "MIR_SERVER_PROMPT_FILE", "MIR_SERVER_HOST_SOCKET",751 {
762 "UBUNTU_APP_LAUNCH_OOM_HELPER", "UBUNTU_APP_LAUNCH_LEGACY_ROOT", "UBUNTU_APP_LAUNCH_XMIR_HELPER"})752 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
763 {753 g_variant_builder_add_value(&builder, g_variant_new_string("WorkingDirectory"));
764 removeEnv(rmenv, env);754 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);
765 }755 g_variant_builder_add_value(&builder, g_variant_new_string(findEnv("APP_DIR", env).c_str()));
766756 g_variant_builder_close(&builder);
767 g_debug("Environment length: %d", envSize(env));757 g_variant_builder_close(&builder);
768758 }
769 /* Environment */759
770 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);760 /* Clean up env before shipping it */
771 g_variant_builder_add_value(&builder, g_variant_new_string("Environment"));761 for (const auto& rmenv :
772 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);762 {"APP_XMIR_ENABLE", "APP_DIR", "APP_URIS", "APP_EXEC", "APP_EXEC_POLICY", "APP_LAUNCHER_PID",
773 g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);763 "INSTANCE_ID", "MIR_SERVER_PLATFORM_PATH", "MIR_SERVER_PROMPT_FILE", "MIR_SERVER_HOST_SOCKET",
774 for (const auto& envvar : env)764 "UBUNTU_APP_LAUNCH_OOM_HELPER", "UBUNTU_APP_LAUNCH_LEGACY_ROOT", "UBUNTU_APP_LAUNCH_XMIR_HELPER"})
775 {765 {
776 if (!envvar.first.empty() && !envvar.second.empty())766 removeEnv(rmenv, env);
777 {767 }
778 g_variant_builder_add_value(&builder, g_variant_new_take_string(g_strdup_printf(768
779 "%s=%s", envvar.first.c_str(), envvar.second.c_str())));769 g_debug("Environment length: %d", envSize(env));
780 // g_debug("Setting environment: %s=%s", envvar.first.c_str(), envvar.second.c_str());770
781 }771 /* Environment */
782 }772 g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
783773 g_variant_builder_add_value(&builder, g_variant_new_string("Environment"));
784 g_variant_builder_close(&builder);774 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARIANT);
785 g_variant_builder_close(&builder);775 g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);
786 g_variant_builder_close(&builder);776 for (const auto& envvar : env)
787777 {
788 /* Parameter Array */778 if (!envvar.first.empty() && !envvar.second.empty())
789 g_variant_builder_close(&builder);779 {
790780 g_variant_builder_add_value(&builder, g_variant_new_take_string(g_strdup_printf(
791 /* Dependent Units (none) */781 "%s=%s", envvar.first.c_str(), envvar.second.c_str())));
792 g_variant_builder_add_value(&builder, g_variant_new_array(G_VARIANT_TYPE("(sa(sv))"), nullptr, 0));782 // g_debug("Setting environment: %s=%s", envvar.first.c_str(), envvar.second.c_str());
793783 }
794 auto retval = std::make_shared<instance::SystemD>(appId, job, instance, urls, registry);784 }
795 auto chelper = new StartCHelper{};785
796 chelper->ptr = retval;786 g_variant_builder_close(&builder);
797 chelper->bus = registry->impl->_dbus;787 g_variant_builder_close(&builder);
798788 g_variant_builder_close(&builder);
799 tracepoint(ubuntu_app_launch, handshake_wait, appIdStr.c_str());789
800 starting_handshake_wait(handshake);790 /* Parameter Array */
801 tracepoint(ubuntu_app_launch, handshake_complete, appIdStr.c_str());791 g_variant_builder_close(&builder);
802792
803 /* Call the job start function */793 /* Dependent Units (none) */
804 g_debug("Asking systemd to start task for: %s", appIdStr.c_str());794 g_variant_builder_add_value(&builder, g_variant_new_array(G_VARIANT_TYPE("(sa(sv))"), nullptr, 0));
805 g_dbus_connection_call(manager->userbus_.get(), /* bus */795
806 SYSTEMD_DBUS_ADDRESS, /* service name */796 auto retval = std::make_shared<instance::SystemD>(appId, job, instance, urls, reg);
807 SYSTEMD_DBUS_PATH_MANAGER, /* Path */797 auto chelper = new StartCHelper{};
808 SYSTEMD_DBUS_IFACE_MANAGER, /* interface */798 chelper->ptr = retval;
809 "StartTransientUnit", /* method */799 chelper->bus = reg->_dbus;
810 g_variant_builder_end(&builder), /* params */800
811 G_VARIANT_TYPE("(o)"), /* return */801 tracepoint(ubuntu_app_launch, handshake_wait, appIdStr.c_str());
812 G_DBUS_CALL_FLAGS_NONE, /* flags */802 starting_handshake_wait(handshake);
813 -1, /* default timeout */803 tracepoint(ubuntu_app_launch, handshake_complete, appIdStr.c_str());
814 registry->impl->thread.getCancellable().get(), /* cancellable */804
815 application_start_cb, /* callback */805 /* Call the job start function */
816 chelper /* object */806 g_debug("Asking systemd to start task for: %s", appIdStr.c_str());
817 );807 g_dbus_connection_call(manager->userbus_.get(), /* bus */
818808 SYSTEMD_DBUS_ADDRESS, /* service name */
819 tracepoint(ubuntu_app_launch, libual_start_message_sent, appIdStr.c_str());809 SYSTEMD_DBUS_PATH_MANAGER, /* Path */
820810 SYSTEMD_DBUS_IFACE_MANAGER, /* interface */
821 return retval;811 "StartTransientUnit", /* method */
822 });812 g_variant_builder_end(&builder), /* params */
813 G_VARIANT_TYPE("(o)"), /* return */
814 G_DBUS_CALL_FLAGS_NONE, /* flags */
815 -1, /* default timeout */
816 reg->thread.getCancellable().get(), /* cancellable */
817 application_start_cb, /* callback */
818 chelper /* object */
819 );
820
821 tracepoint(ubuntu_app_launch, libual_start_message_sent, appIdStr.c_str());
822
823 return retval;
824 });
823}825}
824826
825std::shared_ptr<Application::Instance> SystemD::existing(const AppID& appId,827std::shared_ptr<Application::Instance> SystemD::existing(const AppID& appId,
@@ -827,20 +829,15 @@
827 const std::string& instance,829 const std::string& instance,
828 const std::vector<Application::URL>& urls)830 const std::vector<Application::URL>& urls)
829{831{
830 return std::make_shared<instance::SystemD>(appId, job, instance, urls, registry_.lock());832 return std::make_shared<instance::SystemD>(appId, job, instance, urls, getReg());
831}833}
832834
833std::vector<std::shared_ptr<instance::Base>> SystemD::instances(const AppID& appID, const std::string& job)835std::vector<std::shared_ptr<instance::Base>> SystemD::instances(const AppID& appID, const std::string& job)
834{836{
837 auto reg = getReg();
838
835 std::vector<std::shared_ptr<instance::Base>> instances;839 std::vector<std::shared_ptr<instance::Base>> instances;
836 std::vector<Application::URL> urls;840 std::vector<Application::URL> urls;
837 auto registry = registry_.lock();
838
839 if (!registry)
840 {
841 g_warning("Unable to list instances without a registry");
842 return {};
843 }
844841
845 std::string sappid{appID};842 std::string sappid{appID};
846 for (const auto& unit : unitPaths)843 for (const auto& unit : unitPaths)
@@ -857,7 +854,7 @@
857 continue;854 continue;
858 }855 }
859856
860 instances.emplace_back(std::make_shared<instance::SystemD>(appID, job, unitinfo.inst, urls, registry));857 instances.emplace_back(std::make_shared<instance::SystemD>(appID, job, unitinfo.inst, urls, reg));
861 }858 }
862859
863 g_debug("Found %d instances for AppID '%s'", int(instances.size()), std::string(appID).c_str());860 g_debug("Found %d instances for AppID '%s'", int(instances.size()), std::string(appID).c_str());
@@ -867,14 +864,6 @@
867864
868std::list<std::string> SystemD::runningAppIds(const std::list<std::string>& allJobs)865std::list<std::string> SystemD::runningAppIds(const std::list<std::string>& allJobs)
869{866{
870 auto registry = registry_.lock();
871
872 if (!registry)
873 {
874 g_warning("Unable to list instances without a registry");
875 return {};
876 }
877
878 std::set<std::string> appids;867 std::set<std::string> appids;
879868
880 for (const auto& unit : unitPaths)869 for (const auto& unit : unitPaths)
@@ -923,6 +912,7 @@
923912
924std::string SystemD::unitPath(const SystemD::UnitInfo& info)913std::string SystemD::unitPath(const SystemD::UnitInfo& info)
925{914{
915 auto reg = getReg();
926 auto data = unitPaths[info];916 auto data = unitPaths[info];
927917
928 if (!data)918 if (!data)
@@ -930,17 +920,9 @@
930 return {};920 return {};
931 }921 }
932922
933 auto registry = registry_.lock();
934
935 if (!registry)
936 {
937 g_warning("Unable to get registry to determine path");
938 return {};
939 }
940
941 /* Execute on the thread so that we're sure that we're not in923 /* Execute on the thread so that we're sure that we're not in
942 a dbus call to get the value. No racey for you! */924 a dbus call to get the value. No racey for you! */
943 return registry->impl->thread.executeOnThread<std::string>([&data]() { return data->unitpath; });925 return reg->thread.executeOnThread<std::string>([&data]() { return data->unitpath; });
944}926}
945927
946SystemD::UnitInfo SystemD::unitNew(const std::string& name,928SystemD::UnitInfo SystemD::unitNew(const std::string& name,
@@ -952,9 +934,11 @@
952 throw std::runtime_error{"Job path for unit is '/' so likely failed"};934 throw std::runtime_error{"Job path for unit is '/' so likely failed"};
953 }935 }
954936
937 auto info = parseUnit(name);
938
955 g_debug("New Unit: %s", name.c_str());939 g_debug("New Unit: %s", name.c_str());
956940
957 auto info = parseUnit(name);941 auto reg = getReg();
958942
959 auto data = std::make_shared<UnitData>();943 auto data = std::make_shared<UnitData>();
960 data->jobpath = path;944 data->jobpath = path;
@@ -971,24 +955,16 @@
971 comes an asking at this point we'll think that we have the955 comes an asking at this point we'll think that we have the
972 app, but not yet its path */956 app, but not yet its path */
973 GError* error{nullptr};957 GError* error{nullptr};
974 auto reg = registry_.lock();958 auto call = unique_glib(g_dbus_connection_call_sync(bus.get(), /* user bus */
975959 SYSTEMD_DBUS_ADDRESS, /* bus name */
976 if (!reg)960 SYSTEMD_DBUS_PATH_MANAGER, /* path */
977 {961 SYSTEMD_DBUS_IFACE_MANAGER, /* interface */
978 g_warning("Unable to get SystemD unit path for '%s': Registry out of scope", name.c_str());962 "GetUnit", /* method */
979 throw std::runtime_error{"Unable to get SystemD unit path for '" + name + "': Registry out of scope"};963 g_variant_new("(s)", name.c_str()), /* params */
980 }964 G_VARIANT_TYPE("(o)"), /* ret type */
981965 G_DBUS_CALL_FLAGS_NONE, /* flags */
982 auto call = unique_glib(g_dbus_connection_call_sync(bus.get(), /* user bus */966 -1, /* timeout */
983 SYSTEMD_DBUS_ADDRESS, /* bus name */967 reg->thread.getCancellable().get(), /* cancellable */
984 SYSTEMD_DBUS_PATH_MANAGER, /* path */
985 SYSTEMD_DBUS_IFACE_MANAGER, /* interface */
986 "GetUnit", /* method */
987 g_variant_new("(s)", name.c_str()), /* params */
988 G_VARIANT_TYPE("(o)"), /* ret type */
989 G_DBUS_CALL_FLAGS_NONE, /* flags */
990 -1, /* timeout */
991 reg->impl->thread.getCancellable().get(), /* cancellable */
992 &error));968 &error));
993969
994 if (error != nullptr)970 if (error != nullptr)
@@ -1023,14 +999,6 @@
1023999
1024pid_t SystemD::unitPrimaryPid(const AppID& appId, const std::string& job, const std::string& instance)1000pid_t SystemD::unitPrimaryPid(const AppID& appId, const std::string& job, const std::string& instance)
1025{1001{
1026 auto registry = registry_.lock();
1027
1028 if (!registry)
1029 {
1030 g_warning("Unable to get registry to determine primary PID");
1031 return 0;
1032 }
1033
1034 auto unitinfo = SystemD::UnitInfo{appId, job, instance};1002 auto unitinfo = SystemD::UnitInfo{appId, job, instance};
1035 auto unitname = unitName(unitinfo);1003 auto unitname = unitName(unitinfo);
1036 auto unitpath = unitPath(unitinfo);1004 auto unitpath = unitPath(unitinfo);
@@ -1040,7 +1008,9 @@
1040 return 0;1008 return 0;
1041 }1009 }
10421010
1043 return registry->impl->thread.executeOnThread<pid_t>([this, registry, unitname, unitpath]() {1011 auto reg = getReg();
1012
1013 return reg->thread.executeOnThread<pid_t>([this, unitname, unitpath, reg]() {
1044 GError* error{nullptr};1014 GError* error{nullptr};
1045 auto call = unique_glib(1015 auto call = unique_glib(
1046 g_dbus_connection_call_sync(userbus_.get(), /* user bus */1016 g_dbus_connection_call_sync(userbus_.get(), /* user bus */
@@ -1052,7 +1022,7 @@
1052 G_VARIANT_TYPE("(v)"), /* ret type */1022 G_VARIANT_TYPE("(v)"), /* ret type */
1053 G_DBUS_CALL_FLAGS_NONE, /* flags */1023 G_DBUS_CALL_FLAGS_NONE, /* flags */
1054 -1, /* timeout */1024 -1, /* timeout */
1055 registry->impl->thread.getCancellable().get(), /* cancellable */1025 reg->thread.getCancellable().get(), /* cancellable */
1056 &error));1026 &error));
10571027
1058 if (error != nullptr)1028 if (error != nullptr)
@@ -1080,14 +1050,6 @@
10801050
1081std::vector<pid_t> SystemD::unitPids(const AppID& appId, const std::string& job, const std::string& instance)1051std::vector<pid_t> SystemD::unitPids(const AppID& appId, const std::string& job, const std::string& instance)
1082{1052{
1083 auto registry = registry_.lock();
1084
1085 if (!registry)
1086 {
1087 g_warning("Unable to get registry to determine primary PID");
1088 return {};
1089 }
1090
1091 auto unitinfo = SystemD::UnitInfo{appId, job, instance};1053 auto unitinfo = SystemD::UnitInfo{appId, job, instance};
1092 auto unitname = unitName(unitinfo);1054 auto unitname = unitName(unitinfo);
1093 auto unitpath = unitPath(unitinfo);1055 auto unitpath = unitPath(unitinfo);
@@ -1097,7 +1059,9 @@
1097 return {};1059 return {};
1098 }1060 }
10991061
1100 auto cgrouppath = registry->impl->thread.executeOnThread<std::string>([this, registry, unitname, unitpath]() {1062 auto reg = getReg();
1063
1064 auto cgrouppath = reg->thread.executeOnThread<std::string>([this, unitname, unitpath, reg]() {
1101 GError* error{nullptr};1065 GError* error{nullptr};
1102 auto call = unique_glib(1066 auto call = unique_glib(
1103 g_dbus_connection_call_sync(userbus_.get(), /* user bus */1067 g_dbus_connection_call_sync(userbus_.get(), /* user bus */
@@ -1106,10 +1070,10 @@
1106 "org.freedesktop.DBus.Properties", /* interface */1070 "org.freedesktop.DBus.Properties", /* interface */
1107 "Get", /* method */1071 "Get", /* method */
1108 g_variant_new("(ss)", SYSTEMD_DBUS_IFACE_SERVICE, "ControlGroup"), /* params */1072 g_variant_new("(ss)", SYSTEMD_DBUS_IFACE_SERVICE, "ControlGroup"), /* params */
1109 G_VARIANT_TYPE("(v)"), /* ret type */1073 G_VARIANT_TYPE("(v)"), /* ret type */
1110 G_DBUS_CALL_FLAGS_NONE, /* flags */1074 G_DBUS_CALL_FLAGS_NONE, /* flags */
1111 -1, /* timeout */1075 -1, /* timeout */
1112 registry->impl->thread.getCancellable().get(), /* cancellable */1076 reg->thread.getCancellable().get(), /* cancellable */
1113 &error));1077 &error));
11141078
1115 if (error != nullptr)1079 if (error != nullptr)
@@ -1182,10 +1146,10 @@
11821146
1183void SystemD::stopUnit(const AppID& appId, const std::string& job, const std::string& instance)1147void SystemD::stopUnit(const AppID& appId, const std::string& job, const std::string& instance)
1184{1148{
1185 auto registry = registry_.lock();
1186 auto unitname = unitName(SystemD::UnitInfo{appId, job, instance});1149 auto unitname = unitName(SystemD::UnitInfo{appId, job, instance});
1150 auto reg = getReg();
11871151
1188 registry->impl->thread.executeOnThread<bool>([this, registry, unitname] {1152 reg->thread.executeOnThread<bool>([this, unitname, reg] {
1189 GError* error{nullptr};1153 GError* error{nullptr};
1190 unique_glib(g_dbus_connection_call_sync(1154 unique_glib(g_dbus_connection_call_sync(
1191 userbus_.get(), /* user bus */1155 userbus_.get(), /* user bus */
@@ -1194,13 +1158,13 @@
1194 SYSTEMD_DBUS_IFACE_MANAGER, /* interface */1158 SYSTEMD_DBUS_IFACE_MANAGER, /* interface */
1195 "StopUnit", /* method */1159 "StopUnit", /* method */
1196 g_variant_new(1160 g_variant_new(
1197 "(ss)", /* params */1161 "(ss)", /* params */
1198 unitname.c_str(), /* param: specify unit */1162 unitname.c_str(), /* param: specify unit */
1199 "replace-irreversibly"), /* param: replace the current job but don't allow us to be replaced */1163 "replace-irreversibly"), /* param: replace the current job but don't allow us to be replaced */
1200 G_VARIANT_TYPE("(o)"), /* ret type */1164 G_VARIANT_TYPE("(o)"), /* ret type */
1201 G_DBUS_CALL_FLAGS_NONE, /* flags */1165 G_DBUS_CALL_FLAGS_NONE, /* flags */
1202 -1, /* timeout */1166 -1, /* timeout */
1203 registry->impl->thread.getCancellable().get(), /* cancellable */1167 reg->thread.getCancellable().get(), /* cancellable */
1204 &error));1168 &error));
12051169
1206 if (error != nullptr)1170 if (error != nullptr)
@@ -1217,29 +1181,26 @@
12171181
1218core::Signal<const std::string&, const std::string&, const std::string&>& SystemD::jobStarted()1182core::Signal<const std::string&, const std::string&, const std::string&>& SystemD::jobStarted()
1219{1183{
1220 /* For systemd we're automatically listening to the UnitNew signal1184 /* Ensure we're connecting to the signals */
1221 and emitting on the object */
1222 return sig_jobStarted;1185 return sig_jobStarted;
1223}1186}
12241187
1225core::Signal<const std::string&, const std::string&, const std::string&>& SystemD::jobStopped()1188core::Signal<const std::string&, const std::string&, const std::string&>& SystemD::jobStopped()
1226{1189{
1227 /* For systemd we're automatically listening to the UnitRemoved signal1190 /* Ensure we're connecting to the signals */
1228 and emitting on the object */
1229 return sig_jobStopped;1191 return sig_jobStopped;
1230}1192}
12311193
1232struct FailedData1194struct FailedData
1233{1195{
1234 std::weak_ptr<Registry> registry;1196 std::weak_ptr<Registry::Impl> registry;
1235};1197};
12361198
1237core::Signal<const std::string&, const std::string&, const std::string&, Registry::FailureType>& SystemD::jobFailed()1199core::Signal<const std::string&, const std::string&, const std::string&, Registry::FailureType>& SystemD::jobFailed()
1238{1200{
1239 std::call_once(flag_appFailed, [this]() {1201 std::call_once(flag_appFailed, [this]() {
1240 auto reg = registry_.lock();1202 auto reg = getReg();
12411203 reg->thread.executeOnThread<bool>([this, reg]() {
1242 reg->impl->thread.executeOnThread<bool>([this, reg]() {
1243 auto data = new FailedData{reg};1204 auto data = new FailedData{reg};
12441205
1245 handle_appFailed = managedDBusSignalConnection(1206 handle_appFailed = managedDBusSignalConnection(
@@ -1258,11 +1219,10 @@
12581219
1259 if (!reg)1220 if (!reg)
1260 {1221 {
1261 g_warning("Registry object invalid!");1222 throw std::runtime_error{"Lost our connection with the registry"};
1262 return;
1263 }1223 }
12641224
1265 auto manager = std::dynamic_pointer_cast<SystemD>(reg->impl->jobs);1225 auto manager = std::dynamic_pointer_cast<SystemD>(reg->jobs());
12661226
1267 /* Check to see if this is a path we care about */1227 /* Check to see if this is a path we care about */
1268 bool pathfound{false};1228 bool pathfound{false};
@@ -1334,19 +1294,19 @@
1334 failed so that we can continue to work with it. This includes1294 failed so that we can continue to work with it. This includes
1335 starting it anew, which can fail if it is left in the failed1295 starting it anew, which can fail if it is left in the failed
1336 state. */1296 state. */
1337void SystemD::resetUnit(const UnitInfo& info) const1297void SystemD::resetUnit(const UnitInfo& info)
1338{1298{
1339 if (noResetUnits_)1299 if (noResetUnits_)
1340 {1300 {
1341 return;1301 return;
1342 }1302 }
13431303
1344 auto registry = registry_.lock();1304 auto reg = getReg();
1345 auto unitname = unitName(info);1305 auto unitname = unitName(info);
1346 auto bus = userbus_;1306 auto bus = userbus_;
1347 auto cancel = registry->impl->thread.getCancellable();1307 auto cancel = reg->thread.getCancellable();
13481308
1349 registry->impl->thread.executeOnThread([bus, unitname, cancel] {1309 reg->thread.executeOnThread([bus, unitname, cancel] {
1350 if (g_cancellable_is_cancelled(cancel.get()))1310 if (g_cancellable_is_cancelled(cancel.get()))
1351 {1311 {
1352 return;1312 return;
13531313
=== modified file 'libubuntu-app-launch/jobs-systemd.h'
--- libubuntu-app-launch/jobs-systemd.h 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/jobs-systemd.h 2017-04-04 21:22:36 +0000
@@ -41,7 +41,7 @@
41class SystemD : public Base41class SystemD : public Base
42{42{
43public:43public:
44 SystemD(std::shared_ptr<Registry> registry);44 SystemD(const std::shared_ptr<Registry::Impl>& registry);
45 virtual ~SystemD();45 virtual ~SystemD();
4646
47 virtual std::shared_ptr<Application::Instance> launch(47 virtual std::shared_ptr<Application::Instance> launch(
@@ -73,7 +73,11 @@
7373
74private:74private:
75 std::string cgroup_root_;75 std::string cgroup_root_;
76
77 /** Connection to the User DBus bus */
76 std::shared_ptr<GDBusConnection> userbus_;78 std::shared_ptr<GDBusConnection> userbus_;
79 /** Setup the bus and all the details in it */
80 void setupUserbus(const std::shared_ptr<Registry::Impl>& reg);
7781
78 core::Signal<const std::string&, const std::string&, const std::string&> sig_jobStarted;82 core::Signal<const std::string&, const std::string&, const std::string&> sig_jobStarted;
79 core::Signal<const std::string&, const std::string&, const std::string&> sig_jobStopped;83 core::Signal<const std::string&, const std::string&, const std::string&> sig_jobStopped;
@@ -131,7 +135,7 @@
131 static std::vector<std::string> parseExec(std::list<std::pair<std::string, std::string>>& env);135 static std::vector<std::string> parseExec(std::list<std::pair<std::string, std::string>>& env);
132 static void application_start_cb(GObject* obj, GAsyncResult* res, gpointer user_data);136 static void application_start_cb(GObject* obj, GAsyncResult* res, gpointer user_data);
133137
134 void resetUnit(const UnitInfo& info) const;138 void resetUnit(const UnitInfo& info);
135};139};
136140
137} // namespace manager141} // namespace manager
138142
=== modified file 'libubuntu-app-launch/registry-impl.cpp'
--- libubuntu-app-launch/registry-impl.cpp 2017-03-20 12:28:10 +0000
+++ libubuntu-app-launch/registry-impl.cpp 2017-04-04 21:22:36 +0000
@@ -20,6 +20,7 @@
20#include "registry-impl.h"20#include "registry-impl.h"
21#include "application-icon-finder.h"21#include "application-icon-finder.h"
22#include "application-impl-base.h"22#include "application-impl-base.h"
23#include "helper-impl.h"
23#include <regex>24#include <regex>
24#include <unity/util/GObjectMemory.h>25#include <unity/util/GObjectMemory.h>
25#include <unity/util/GlibMemory.h>26#include <unity/util/GlibMemory.h>
@@ -31,24 +32,19 @@
31namespace app_launch32namespace app_launch
32{33{
3334
34Registry::Impl::Impl(Registry& registry)35Registry::Impl::Impl()
35 : Impl(registry, app_store::Base::allAppStores())
36{
37}
38
39Registry::Impl::Impl(Registry& registry, std::list<std::shared_ptr<app_store::Base>> appStores)
40 : thread([]() {},36 : thread([]() {},
41 [this]() {37 [this]() {
42 zgLog_.reset();38 zgLog_.reset();
43 jobs.reset();39 jobs_.reset();
4440
45 if (_dbus)41 if (_dbus)
46 g_dbus_connection_flush_sync(_dbus.get(), nullptr, nullptr);42 g_dbus_connection_flush_sync(_dbus.get(), nullptr, nullptr);
47 _dbus.reset();43 _dbus.reset();
48 })44 })
49 , _registry{registry}45 , jobs_{}
50 , _iconFinders()46 , _iconFinders{}
51 , _appStores(appStores)47 , _appStores{}
52{48{
53 auto cancel = thread.getCancellable();49 auto cancel = thread.getCancellable();
54 _dbus = thread.executeOnThread<std::shared_ptr<GDBusConnection>>(50 _dbus = thread.executeOnThread<std::shared_ptr<GDBusConnection>>(
@@ -145,7 +141,7 @@
145 });141 });
146}142}
147143
148std::shared_ptr<IconFinder> Registry::Impl::getIconFinder(std::string basePath)144std::shared_ptr<IconFinder>& Registry::Impl::getIconFinder(std::string basePath)
149{145{
150 if (_iconFinders.find(basePath) == _iconFinders.end())146 if (_iconFinders.find(basePath) == _iconFinders.end())
151 {147 {
@@ -175,23 +171,45 @@
175 return watchingAppStarting_;171 return watchingAppStarting_;
176}172}
177173
178core::Signal<const std::shared_ptr<Application>&>& Registry::Impl::appInfoUpdated(const std::shared_ptr<Registry>& reg)174core::Signal<const std::shared_ptr<Application>&>& Registry::Impl::appInfoUpdated()
179{175{
180 std::call_once(flag_appInfoUpdated, [this, reg] {176 std::call_once(flag_appInfoUpdated, [this] {
181 g_debug("App Info Updated Signal Initialized");177 g_debug("App Info Updated Signal Initialized");
182178
183 std::list<std::shared_ptr<info_watcher::Base>> apps{_appStores.begin(), _appStores.end()};179 std::list<std::shared_ptr<info_watcher::Base>> apps{_appStores.begin(), _appStores.end()};
184 apps.push_back(Registry::Impl::getZgWatcher(reg));180 apps.push_back(getZgWatcher());
185181
186 for (const auto& app : apps)182 for (const auto& app : apps)
187 {183 {
188 infoWatchers_.emplace_back(184 infoWatchers_.emplace_back(
189 std::make_pair(app, app->infoChanged().connect(185 std::make_pair(app, app->infoChanged().connect([this](const std::shared_ptr<Application>& app) {
190 [this](const std::shared_ptr<Application>& app) { sig_appInfoUpdated(app); })));186 sig_appInfoUpdated(app);
187 })));
191 }188 }
192 });189 });
193 return sig_appInfoUpdated;190 return sig_appInfoUpdated;
194}191}
195192
193std::shared_ptr<Application> Registry::Impl::createApp(const AppID& appid)
194{
195 for (const auto& appStore : appStores())
196 {
197 if (appStore->hasAppId(appid))
198 {
199 return appStore->create(appid);
200 }
201 }
202
203 throw std::runtime_error("Invalid app ID: " + std::string(appid));
204}
205
206std::shared_ptr<Helper> Registry::Impl::createHelper(const Helper::Type& type,
207 const AppID& appid,
208 const std::shared_ptr<Registry::Impl>& sharedimpl)
209{
210 /* Only one type today */
211 return std::make_shared<helper_impls::Base>(type, appid, sharedimpl);
212}
213
196} // namespace app_launch214} // namespace app_launch
197} // namespace ubuntu215} // namespace ubuntu
198216
=== modified file 'libubuntu-app-launch/registry-impl.h'
--- libubuntu-app-launch/registry-impl.h 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/registry-impl.h 2017-04-04 21:22:36 +0000
@@ -17,6 +17,8 @@
17 * Ted Gould <ted.gould@canonical.com>17 * Ted Gould <ted.gould@canonical.com>
18 */18 */
1919
20#pragma once
21
20#include "app-store-base.h"22#include "app-store-base.h"
21#include "glib-thread.h"23#include "glib-thread.h"
22#include "info-watcher-zg.h"24#include "info-watcher-zg.h"
@@ -29,14 +31,16 @@
29#include <unordered_map>31#include <unordered_map>
30#include <zeitgeist.h>32#include <zeitgeist.h>
3133
32#pragma once
33
34namespace ubuntu34namespace ubuntu
35{35{
36namespace app_launch36namespace app_launch
37{37{
3838
39class IconFinder;39class IconFinder;
40namespace app_store
41{
42class Base;
43}
4044
41/** \private45/** \private
42 \brief Private implementation of the Registry object46 \brief Private implementation of the Registry object
@@ -45,8 +49,7 @@
45class Registry::Impl49class Registry::Impl
46{50{
47public:51public:
48 Impl(Registry& registry);52 Impl();
49 Impl(Registry& registry, std::list<std::shared_ptr<app_store::Base>> appStores);
5053
51 virtual ~Impl()54 virtual ~Impl()
52 {55 {
@@ -66,9 +69,7 @@
66 /** Snapd information object */69 /** Snapd information object */
67 snapd::Info snapdInfo;70 snapd::Info snapdInfo;
6871
69 std::shared_ptr<jobs::manager::Base> jobs;72 std::shared_ptr<IconFinder>& getIconFinder(std::string basePath);
70
71 std::shared_ptr<IconFinder> getIconFinder(std::string basePath);
7273
73 virtual void zgSendEvent(AppID appid, const std::string& eventtype);74 virtual void zgSendEvent(AppID appid, const std::string& eventtype);
7475
@@ -86,27 +87,59 @@
86 return oomHelper_;87 return oomHelper_;
87 }88 }
8889
89 static std::shared_ptr<info_watcher::Zeitgeist> getZgWatcher(const std::shared_ptr<Registry>& reg)90 std::shared_ptr<info_watcher::Zeitgeist> getZgWatcher()
90 {91 {
91 std::call_once(reg->impl->zgWatcherOnce_,92 return zgWatcher_;
92 [reg] { reg->impl->zgWatcher_ = std::make_shared<info_watcher::Zeitgeist>(reg); });93 }
93 return reg->impl->zgWatcher_;94
94 }95 void setZgWatcher(const std::shared_ptr<info_watcher::Zeitgeist>& watcher)
9596 {
96 core::Signal<const std::shared_ptr<Application>&>& appInfoUpdated(const std::shared_ptr<Registry>& reg);97 zgWatcher_ = watcher;
9798 }
98 std::list<std::shared_ptr<app_store::Base>> appStores()99
100 core::Signal<const std::shared_ptr<Application>&>& appInfoUpdated();
101
102 const std::list<std::shared_ptr<app_store::Base>>& appStores()
99 {103 {
100 return _appStores;104 return _appStores;
101 }105 }
102106
103 void setAppStores(std::list<std::shared_ptr<app_store::Base>>& newlist)107 void setAppStores(const std::list<std::shared_ptr<app_store::Base>>& newlist)
104 {108 {
105 _appStores = newlist;109 _appStores = newlist;
106 }110 }
107111
112 const std::shared_ptr<jobs::manager::Base>& jobs()
113 {
114 if (G_UNLIKELY(!jobs_))
115 {
116 throw std::runtime_error{"Registry Implmentation has no Jobs object"};
117 }
118 return jobs_;
119 }
120
121 void setJobs(const std::shared_ptr<jobs::manager::Base>& jobs)
122 {
123 jobs_ = jobs;
124 }
125
126 /* Create functions */
127 std::shared_ptr<Application> createApp(const AppID& appid);
128 std::shared_ptr<Helper> createHelper(const Helper::Type& type,
129 const AppID& appid,
130 const std::shared_ptr<Registry::Impl>& sharedimpl);
131
132 /* AppID functions */
133 AppID find(const std::string& sappid);
134 AppID discover(const std::string& package, const std::string& appname, const std::string& version);
135 AppID discover(const std::string& package,
136 AppID::ApplicationWildcard appwildcard,
137 AppID::VersionWildcard versionwildcard);
138 AppID discover(const std::string& package, const std::string& appname, AppID::VersionWildcard versionwildcard);
139
108private:140private:
109 Registry& _registry; /**< The Registry that we're spawned from */141 /** The job creation engine */
142 std::shared_ptr<jobs::manager::Base> jobs_;
110143
111 /** Shared instance of the Zeitgeist Log */144 /** Shared instance of the Zeitgeist Log */
112 std::shared_ptr<ZeitgeistLog> zgLog_;145 std::shared_ptr<ZeitgeistLog> zgLog_;
@@ -128,11 +161,8 @@
128 /** List of info watchers along with a signal handle to our connection to their update signal */161 /** List of info watchers along with a signal handle to our connection to their update signal */
129 std::list<std::pair<std::shared_ptr<info_watcher::Base>, core::ScopedConnection>> infoWatchers_;162 std::list<std::pair<std::shared_ptr<info_watcher::Base>, core::ScopedConnection>> infoWatchers_;
130163
131protected:
132 /** ZG Info Watcher */164 /** ZG Info Watcher */
133 std::shared_ptr<info_watcher::Zeitgeist> zgWatcher_;165 std::shared_ptr<info_watcher::Zeitgeist> zgWatcher_;
134 /** Init checker for ZG Watcher */
135 std::once_flag zgWatcherOnce_;
136};166};
137167
138} // namespace app_launch168} // namespace app_launch
139169
=== modified file 'libubuntu-app-launch/registry.cpp'
--- libubuntu-app-launch/registry.cpp 2017-03-20 10:13:50 +0000
+++ libubuntu-app-launch/registry.cpp 2017-04-04 21:22:36 +0000
@@ -21,6 +21,8 @@
21#include <numeric>21#include <numeric>
22#include <regex>22#include <regex>
2323
24#include "info-watcher-zg.h"
25#include "jobs-base.h"
24#include "registry-impl.h"26#include "registry-impl.h"
25#include "registry.h"27#include "registry.h"
2628
@@ -30,8 +32,17 @@
30{32{
3133
32Registry::Registry()34Registry::Registry()
33{35 : impl{std::make_shared<Impl>()}
34 impl = std::unique_ptr<Impl>(new Impl(*this));36{
37 impl->setJobs(jobs::manager::Base::determineFactory(impl));
38 impl->setAppStores(app_store::Base::allAppStores(impl));
39 impl->setZgWatcher(std::make_shared<info_watcher::Zeitgeist>(impl));
40}
41
42Registry::Registry(const std::shared_ptr<Impl>& inimpl)
43 : impl{inimpl}
44{
45 /* We're assuming the impl has been setup */
35}46}
3647
37Registry::~Registry()48Registry::~Registry()
@@ -40,12 +51,7 @@
4051
41std::list<std::shared_ptr<Application>> Registry::runningApps(std::shared_ptr<Registry> registry)52std::list<std::shared_ptr<Application>> Registry::runningApps(std::shared_ptr<Registry> registry)
42{53{
43 if (!registry->impl->jobs)54 return registry->impl->jobs()->runningApps();
44 {
45 registry->impl->jobs = jobs::manager::Base::determineFactory(registry);
46 }
47
48 return registry->impl->jobs->runningApps();
49}55}
5056
51std::list<std::shared_ptr<Application>> Registry::installedApps(std::shared_ptr<Registry> connection)57std::list<std::shared_ptr<Application>> Registry::installedApps(std::shared_ptr<Registry> connection)
@@ -54,7 +60,7 @@
5460
55 for (const auto& appStore : connection->impl->appStores())61 for (const auto& appStore : connection->impl->appStores())
56 {62 {
57 list.splice(list.begin(), appStore->list(connection));63 list.splice(list.begin(), appStore->list());
58 }64 }
5965
60 return list;66 return list;
@@ -62,37 +68,17 @@
6268
63std::list<std::shared_ptr<Helper>> Registry::runningHelpers(Helper::Type type, std::shared_ptr<Registry> registry)69std::list<std::shared_ptr<Helper>> Registry::runningHelpers(Helper::Type type, std::shared_ptr<Registry> registry)
64{70{
65 if (!registry->impl->jobs)71 return registry->impl->jobs()->runningHelpers(type);
66 {
67 registry->impl->jobs = jobs::manager::Base::determineFactory(registry);
68 }
69
70 return registry->impl->jobs->runningHelpers(type);
71}
72
73/* Quick little helper to bundle up standard code */
74inline void setJobs(const std::shared_ptr<Registry>& registry)
75{
76 if (!registry->impl->jobs)
77 {
78 registry->impl->jobs = jobs::manager::Base::determineFactory(registry);
79 }
80}72}
8173
82void Registry::setManager(const std::shared_ptr<Manager>& manager, const std::shared_ptr<Registry>& registry)74void Registry::setManager(const std::shared_ptr<Manager>& manager, const std::shared_ptr<Registry>& registry)
83{75{
84 setJobs(registry);76 registry->impl->jobs()->setManager(manager);
85 registry->impl->jobs->setManager(manager);
86}77}
8778
88void Registry::clearManager()79void Registry::clearManager()
89{80{
90 if (!impl->jobs)81 impl->jobs()->clearManager();
91 {
92 return;
93 }
94
95 impl->jobs->clearManager();
96}82}
9783
98std::shared_ptr<Registry> defaultRegistry;84std::shared_ptr<Registry> defaultRegistry;
@@ -114,22 +100,19 @@
114core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&>& Registry::appStarted(100core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&>& Registry::appStarted(
115 const std::shared_ptr<Registry>& reg)101 const std::shared_ptr<Registry>& reg)
116{102{
117 setJobs(reg);103 return reg->impl->jobs()->appStarted();
118 return reg->impl->jobs->appStarted();
119}104}
120105
121core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&>& Registry::appStopped(106core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&>& Registry::appStopped(
122 const std::shared_ptr<Registry>& reg)107 const std::shared_ptr<Registry>& reg)
123{108{
124 setJobs(reg);109 return reg->impl->jobs()->appStopped();
125 return reg->impl->jobs->appStopped();
126}110}
127111
128core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&, Registry::FailureType>&112core::Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&, Registry::FailureType>&
129 Registry::appFailed(const std::shared_ptr<Registry>& reg)113 Registry::appFailed(const std::shared_ptr<Registry>& reg)
130{114{
131 setJobs(reg);115 return reg->impl->jobs()->appFailed();
132 return reg->impl->jobs->appFailed();
133}116}
134117
135core::Signal<const std::shared_ptr<Application>&,118core::Signal<const std::shared_ptr<Application>&,
@@ -137,8 +120,7 @@
137 const std::vector<pid_t>&>&120 const std::vector<pid_t>&>&
138 Registry::appPaused(const std::shared_ptr<Registry>& reg)121 Registry::appPaused(const std::shared_ptr<Registry>& reg)
139{122{
140 setJobs(reg);123 return reg->impl->jobs()->appPaused();
141 return reg->impl->jobs->appPaused();
142}124}
143125
144core::Signal<const std::shared_ptr<Application>&,126core::Signal<const std::shared_ptr<Application>&,
@@ -146,34 +128,30 @@
146 const std::vector<pid_t>&>&128 const std::vector<pid_t>&>&
147 Registry::appResumed(const std::shared_ptr<Registry>& reg)129 Registry::appResumed(const std::shared_ptr<Registry>& reg)
148{130{
149 setJobs(reg);131 return reg->impl->jobs()->appResumed();
150 return reg->impl->jobs->appResumed();
151}132}
152133
153core::Signal<const std::shared_ptr<Helper>&, const std::shared_ptr<Helper::Instance>&>& Registry::helperStarted(134core::Signal<const std::shared_ptr<Helper>&, const std::shared_ptr<Helper::Instance>&>& Registry::helperStarted(
154 Helper::Type type, const std::shared_ptr<Registry>& reg)135 Helper::Type type, const std::shared_ptr<Registry>& reg)
155{136{
156 setJobs(reg);137 return reg->impl->jobs()->helperStarted(type);
157 return reg->impl->jobs->helperStarted(type);
158}138}
159139
160core::Signal<const std::shared_ptr<Helper>&, const std::shared_ptr<Helper::Instance>&>& Registry::helperStopped(140core::Signal<const std::shared_ptr<Helper>&, const std::shared_ptr<Helper::Instance>&>& Registry::helperStopped(
161 Helper::Type type, const std::shared_ptr<Registry>& reg)141 Helper::Type type, const std::shared_ptr<Registry>& reg)
162{142{
163 setJobs(reg);143 return reg->impl->jobs()->helperStopped(type);
164 return reg->impl->jobs->helperStopped(type);
165}144}
166145
167core::Signal<const std::shared_ptr<Helper>&, const std::shared_ptr<Helper::Instance>&, Registry::FailureType>&146core::Signal<const std::shared_ptr<Helper>&, const std::shared_ptr<Helper::Instance>&, Registry::FailureType>&
168 Registry::helperFailed(Helper::Type type, const std::shared_ptr<Registry>& reg)147 Registry::helperFailed(Helper::Type type, const std::shared_ptr<Registry>& reg)
169{148{
170 setJobs(reg);149 return reg->impl->jobs()->helperFailed(type);
171 return reg->impl->jobs->helperFailed(type);
172}150}
173151
174core::Signal<const std::shared_ptr<Application>&>& Registry::appInfoUpdated(const std::shared_ptr<Registry>& reg)152core::Signal<const std::shared_ptr<Application>&>& Registry::appInfoUpdated(const std::shared_ptr<Registry>& reg)
175{153{
176 return reg->impl->appInfoUpdated(reg);154 return reg->impl->appInfoUpdated();
177}155}
178156
179} // namespace app_launch157} // namespace app_launch
180158
=== modified file 'libubuntu-app-launch/registry.h'
--- libubuntu-app-launch/registry.h 2017-03-20 12:28:10 +0000
+++ libubuntu-app-launch/registry.h 2017-04-04 21:22:36 +0000
@@ -99,9 +99,8 @@
9999
100 \param reg Registry to get the handler from100 \param reg Registry to get the handler from
101 */101 */
102 static core::Signal<const std::shared_ptr<Application>&,102 static core::
103 const std::shared_ptr<Application::Instance>&,103 Signal<const std::shared_ptr<Application>&, const std::shared_ptr<Application::Instance>&, FailureType>&
104 FailureType>&
105 appFailed(const std::shared_ptr<Registry>& reg = getDefault());104 appFailed(const std::shared_ptr<Registry>& reg = getDefault());
106105
107 /** Get the signal object that is signaled when an application has been106 /** Get the signal object that is signaled when an application has been
@@ -269,7 +268,10 @@
269 /** \private */268 /** \private */
270 class Impl;269 class Impl;
271 /** \private */270 /** \private */
272 std::unique_ptr<Impl> impl;271 std::shared_ptr<Impl> impl;
272
273protected:
274 Registry(const std::shared_ptr<Impl>& inimpl);
273};275};
274276
275} // namespace app_launch277} // namespace app_launch
276278
=== modified file 'tests/application-info-desktop.cpp'
--- tests/application-info-desktop.cpp 2017-03-14 02:58:43 +0000
+++ tests/application-info-desktop.cpp 2017-04-04 21:22:36 +0000
@@ -88,7 +88,7 @@
88 {88 {
89 auto reg = registry();89 auto reg = registry();
9090
91 return std::dynamic_pointer_cast<zgWatcherMock>(reg->impl->getZgWatcher(reg));91 return std::dynamic_pointer_cast<zgWatcherMock>(reg->impl->getZgWatcher());
92 }92 }
93};93};
9494
@@ -410,7 +410,7 @@
410 auto keyfile = defaultKeyfile();410 auto keyfile = defaultKeyfile();
411 EXPECT_EQ(5u,411 EXPECT_EQ(5u,
412 ubuntu::app_launch::app_info::Desktop(simpleAppID(), keyfile, "/", {},412 ubuntu::app_launch::app_info::Desktop(simpleAppID(), keyfile, "/", {},
413 ubuntu::app_launch::app_info::DesktopFlags::NONE, registry())413 ubuntu::app_launch::app_info::DesktopFlags::NONE, registry()->impl)
414 .popularity()414 .popularity()
415 .value());415 .value());
416}416}
417417
=== modified file 'tests/info-watcher-zg.cpp'
--- tests/info-watcher-zg.cpp 2017-02-10 16:50:40 +0000
+++ tests/info-watcher-zg.cpp 2017-04-04 21:22:36 +0000
@@ -49,7 +49,6 @@
4949
50TEST_F(InfoWatcherZg, InitTest)50TEST_F(InfoWatcherZg, InitTest)
51{51{
52 auto watcher = std::make_shared<ubuntu::app_launch::info_watcher::Zeitgeist>(registry);52 /* Gets init by part of the mock now, we may need to split
5353 * that out when we want to test this more. */
54 watcher.reset();
55}54}
5655
=== modified file 'tests/jobs-base-test.cpp'
--- tests/jobs-base-test.cpp 2017-01-19 18:39:44 +0000
+++ tests/jobs-base-test.cpp 2017-04-04 21:22:36 +0000
@@ -34,7 +34,7 @@
34 const std::string& job,34 const std::string& job,
35 const std::string& instance,35 const std::string& instance,
36 const std::vector<ubuntu::app_launch::Application::URL>& urls,36 const std::vector<ubuntu::app_launch::Application::URL>& urls,
37 const std::shared_ptr<ubuntu::app_launch::Registry>& registry)37 const std::shared_ptr<ubuntu::app_launch::Registry::Impl>& registry)
38 : ubuntu::app_launch::jobs::instance::Base(appId, job, instance, urls, registry)38 : ubuntu::app_launch::jobs::instance::Base(appId, job, instance, urls, registry)
39 {39 {
40 }40 }
@@ -76,7 +76,7 @@
76 std::shared_ptr<instanceMock> simpleInstance()76 std::shared_ptr<instanceMock> simpleInstance()
77 {77 {
78 return std::make_shared<instanceMock>(simpleAppID(), "application-job", "1234567890",78 return std::make_shared<instanceMock>(simpleAppID(), "application-job", "1234567890",
79 std::vector<ubuntu::app_launch::Application::URL>{}, registry);79 std::vector<ubuntu::app_launch::Application::URL>{}, registry->impl);
80 }80 }
81};81};
8282
8383
=== modified file 'tests/jobs-systemd.cpp'
--- tests/jobs-systemd.cpp 2017-02-04 03:53:34 +0000
+++ tests/jobs-systemd.cpp 2017-04-04 21:22:36 +0000
@@ -18,6 +18,7 @@
18 */18 */
1919
20#include "jobs-systemd.h"20#include "jobs-systemd.h"
21#include "app-store-legacy.h"
2122
22#include "eventually-fixture.h"23#include "eventually-fixture.h"
23#include "registry-mock.h"24#include "registry-mock.h"
@@ -57,6 +58,7 @@
5758
58 dbus_test_service_start_tasks(service.get());59 dbus_test_service_start_tasks(service.get());
59 registry = std::make_shared<RegistryMock>();60 registry = std::make_shared<RegistryMock>();
61 registry->impl->setAppStores({std::make_shared<ubuntu::app_launch::app_store::Legacy>(registry->impl)});
6062
61 bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);63 bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
62 g_dbus_connection_set_exit_on_close(bus, FALSE);64 g_dbus_connection_set_exit_on_close(bus, FALSE);
@@ -96,13 +98,15 @@
96/* Make sure we can build an object and destroy it */98/* Make sure we can build an object and destroy it */
97TEST_F(JobsSystemd, Init)99TEST_F(JobsSystemd, Init)
98{100{
99 registry->impl->jobs = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);101 registry->impl->setJobs(std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl));
100}102}
101103
102/* Make sure we make the initial call to get signals and an initial list */104/* Make sure we make the initial call to get signals and an initial list */
103TEST_F(JobsSystemd, Startup)105TEST_F(JobsSystemd, Startup)
104{106{
105 registry->impl->jobs = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);107 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
108 registry->impl->setJobs(manager);
109 manager->runningApps();
106110
107 EXPECT_EVENTUALLY_FUNC_EQ(true, std::function<bool()>([this]() { return systemd->subscribeCallsCnt() > 0; }));111 EXPECT_EVENTUALLY_FUNC_EQ(true, std::function<bool()>([this]() { return systemd->subscribeCallsCnt() > 0; }));
108 EXPECT_EVENTUALLY_FUNC_EQ(true, std::function<bool()>([this]() -> bool { return systemd->listCallsCnt() > 0; }));112 EXPECT_EVENTUALLY_FUNC_EQ(true, std::function<bool()>([this]() -> bool { return systemd->listCallsCnt() > 0; }));
@@ -117,8 +121,8 @@
117/* Get the running apps and check out their instances */121/* Get the running apps and check out their instances */
118TEST_F(JobsSystemd, RunningApps)122TEST_F(JobsSystemd, RunningApps)
119{123{
120 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);124 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
121 registry->impl->jobs = manager;125 registry->impl->setJobs(manager);
122126
123 auto apps = manager->runningApps();127 auto apps = manager->runningApps();
124 ASSERT_FALSE(apps.empty());128 ASSERT_FALSE(apps.empty());
@@ -144,8 +148,8 @@
144/* Check to make sure we're getting the user bus path correctly */148/* Check to make sure we're getting the user bus path correctly */
145TEST_F(JobsSystemd, UserBusPath)149TEST_F(JobsSystemd, UserBusPath)
146{150{
147 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);151 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
148 registry->impl->jobs = manager;152 registry->impl->setJobs(manager);
149153
150 EXPECT_EQ(std::string{"/this/should/not/exist"}, manager->userBusPath());154 EXPECT_EQ(std::string{"/this/should/not/exist"}, manager->userBusPath());
151155
@@ -156,8 +160,8 @@
156/* PID Tools */160/* PID Tools */
157TEST_F(JobsSystemd, PidTools)161TEST_F(JobsSystemd, PidTools)
158{162{
159 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);163 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
160 registry->impl->jobs = manager;164 registry->impl->setJobs(manager);
161165
162 EXPECT_EQ(5, manager->unitPrimaryPid(singleAppID(), defaultJobName(), {}));166 EXPECT_EQ(5, manager->unitPrimaryPid(singleAppID(), defaultJobName(), {}));
163 std::vector<pid_t> pidlist{1, 2, 3, 4, 5};167 std::vector<pid_t> pidlist{1, 2, 3, 4, 5};
@@ -167,8 +171,8 @@
167/* PID Instance */171/* PID Instance */
168TEST_F(JobsSystemd, PidInstance)172TEST_F(JobsSystemd, PidInstance)
169{173{
170 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);174 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
171 registry->impl->jobs = manager;175 registry->impl->setJobs(manager);
172176
173 auto inst = manager->existing(singleAppID(), defaultJobName(), {}, {});177 auto inst = manager->existing(singleAppID(), defaultJobName(), {}, {});
174 EXPECT_TRUE(bool(inst));178 EXPECT_TRUE(bool(inst));
@@ -181,8 +185,8 @@
181/* Stopping a Job */185/* Stopping a Job */
182TEST_F(JobsSystemd, StopUnit)186TEST_F(JobsSystemd, StopUnit)
183{187{
184 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);188 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
185 registry->impl->jobs = manager;189 registry->impl->setJobs(manager);
186190
187 manager->stopUnit(singleAppID(), defaultJobName(), {});191 manager->stopUnit(singleAppID(), defaultJobName(), {});
188192
@@ -211,8 +215,8 @@
211/* Stop Instance */215/* Stop Instance */
212TEST_F(JobsSystemd, StopInstance)216TEST_F(JobsSystemd, StopInstance)
213{217{
214 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);218 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
215 registry->impl->jobs = manager;219 registry->impl->setJobs(manager);
216220
217 auto inst = manager->existing(singleAppID(), defaultJobName(), {}, {});221 auto inst = manager->existing(singleAppID(), defaultJobName(), {}, {});
218 EXPECT_TRUE(bool(inst));222 EXPECT_TRUE(bool(inst));
@@ -231,8 +235,8 @@
231/* Starting a new job */235/* Starting a new job */
232TEST_F(JobsSystemd, LaunchJob)236TEST_F(JobsSystemd, LaunchJob)
233{237{
234 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);238 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
235 registry->impl->jobs = manager;239 registry->impl->setJobs(manager);
236240
237 bool gotenv{false};241 bool gotenv{false};
238 std::function<std::list<std::pair<std::string, std::string>>()> getenvfunc =242 std::function<std::list<std::pair<std::string, std::string>>()> getenvfunc =
@@ -291,8 +295,8 @@
291295
292TEST_F(JobsSystemd, SignalNew)296TEST_F(JobsSystemd, SignalNew)
293{297{
294 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);298 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
295 registry->impl->jobs = manager;299 registry->impl->setJobs(manager);
296300
297 std::promise<ubuntu::app_launch::AppID> newunit;301 std::promise<ubuntu::app_launch::AppID> newunit;
298 manager->appStarted().connect([&](const std::shared_ptr<ubuntu::app_launch::Application> &app,302 manager->appStarted().connect([&](const std::shared_ptr<ubuntu::app_launch::Application> &app,
@@ -327,8 +331,8 @@
327331
328TEST_F(JobsSystemd, SignalRemove)332TEST_F(JobsSystemd, SignalRemove)
329{333{
330 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);334 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
331 registry->impl->jobs = manager;335 registry->impl->setJobs(manager);
332336
333 std::promise<ubuntu::app_launch::AppID> removeunit;337 std::promise<ubuntu::app_launch::AppID> removeunit;
334 manager->appStopped().connect([&](const std::shared_ptr<ubuntu::app_launch::Application> &app,338 manager->appStopped().connect([&](const std::shared_ptr<ubuntu::app_launch::Application> &app,
@@ -363,8 +367,8 @@
363367
364TEST_F(JobsSystemd, UnitFailure)368TEST_F(JobsSystemd, UnitFailure)
365{369{
366 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry);370 auto manager = std::make_shared<ubuntu::app_launch::jobs::manager::SystemD>(registry->impl);
367 registry->impl->jobs = manager;371 registry->impl->setJobs(manager);
368372
369 ubuntu::app_launch::AppID failedappid;373 ubuntu::app_launch::AppID failedappid;
370 manager->appFailed().connect([&](const std::shared_ptr<ubuntu::app_launch::Application> &app,374 manager->appFailed().connect([&](const std::shared_ptr<ubuntu::app_launch::Application> &app,
371375
=== modified file 'tests/libual-cpp-test.cc'
--- tests/libual-cpp-test.cc 2017-03-20 15:17:02 +0000
+++ tests/libual-cpp-test.cc 2017-04-04 21:22:36 +0000
@@ -258,16 +258,16 @@
258 {258 {
259 auto store = storeForHelper(appid);259 auto store = storeForHelper(appid);
260260
261 ON_CALL(*store, list(testing::_))261 ON_CALL(*store, list())
262 .WillByDefault(testing::Return(std::list<std::shared_ptr<ubuntu::app_launch::Application>>{}));262 .WillByDefault(testing::Return(std::list<std::shared_ptr<ubuntu::app_launch::Application>>{}));
263263
264 auto app = std::make_shared<MockApp>(appid, registry);264 auto app = std::make_shared<MockApp>(appid, registry->impl);
265 ON_CALL(*store, create(appid, testing::_)).WillByDefault(testing::Return(app));265 ON_CALL(*store, create(appid)).WillByDefault(testing::Return(app));
266266
267 if (!instanceid.empty())267 if (!instanceid.empty())
268 {268 {
269 std::vector<ubuntu::app_launch::Application::URL> urls;269 std::vector<ubuntu::app_launch::Application::URL> urls;
270 auto inst = std::make_shared<MockInst>(appid, jobtype, instanceid, urls, registry);270 auto inst = std::make_shared<MockInst>(appid, jobtype, instanceid, urls, registry->impl);
271 ON_CALL(*app, findInstance(instanceid)).WillByDefault(testing::Return(inst));271 ON_CALL(*app, findInstance(instanceid)).WillByDefault(testing::Return(inst));
272 ON_CALL(*app, launch(testing::_)).WillByDefault(testing::Return(inst));272 ON_CALL(*app, launch(testing::_)).WillByDefault(testing::Return(inst));
273 ON_CALL(*app, launchTest(testing::_)).WillByDefault(testing::Return(inst));273 ON_CALL(*app, launchTest(testing::_)).WillByDefault(testing::Return(inst));
@@ -286,15 +286,13 @@
286 std::shared_ptr<MockStore> storeForHelper(const ubuntu::app_launch::AppID& appid)286 std::shared_ptr<MockStore> storeForHelper(const ubuntu::app_launch::AppID& appid)
287 {287 {
288 /* Setup a store for looking up the AppID */288 /* Setup a store for looking up the AppID */
289 auto store = std::make_shared<MockStore>();289 auto store = std::make_shared<MockStore>(registry->impl);
290290
291 ON_CALL(*store, verifyPackage(appid.package, testing::_)).WillByDefault(testing::Return(true));291 ON_CALL(*store, verifyPackage(appid.package)).WillByDefault(testing::Return(true));
292 ON_CALL(*store, verifyAppname(appid.package, appid.appname, testing::_)).WillByDefault(testing::Return(true));292 ON_CALL(*store, verifyAppname(appid.package, appid.appname)).WillByDefault(testing::Return(true));
293 ON_CALL(*store, findAppname(appid.package, testing::_, testing::_))293 ON_CALL(*store, findAppname(appid.package, testing::_)).WillByDefault(testing::Return(appid.appname));
294 .WillByDefault(testing::Return(appid.appname));294 ON_CALL(*store, findVersion(appid.package, appid.appname)).WillByDefault(testing::Return(appid.version));
295 ON_CALL(*store, findVersion(appid.package, appid.appname, testing::_))295 ON_CALL(*store, hasAppId(appid)).WillByDefault(testing::Return(true));
296 .WillByDefault(testing::Return(appid.version));
297 ON_CALL(*store, hasAppId(appid, testing::_)).WillByDefault(testing::Return(true));
298296
299 std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>> list;297 std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>> list;
300 list.push_back(store);298 list.push_back(store);
@@ -435,46 +433,46 @@
435433
436TEST_F(LibUAL, ApplicationId)434TEST_F(LibUAL, ApplicationId)
437{435{
438 auto mockstore = std::make_shared<MockStore>();436 auto mockstore = std::make_shared<MockStore>(registry->impl);
439 registry =437 registry =
440 std::make_shared<RegistryMock>(std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>>{mockstore});438 std::make_shared<RegistryMock>(std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>>{mockstore},
439 std::shared_ptr<ubuntu::app_launch::jobs::manager::Base>{});
441440
442 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), testing::_))441 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good")))
443 .WillOnce(testing::Return(true));442 .WillOnce(testing::Return(true));
444 EXPECT_CALL(*mockstore, verifyAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),443 EXPECT_CALL(*mockstore, verifyAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),
445 ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_))444 ubuntu::app_launch::AppID::AppName::from_raw("application")))
446 .WillOnce(testing::Return(true));445 .WillOnce(testing::Return(true));
447 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),446 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),
448 ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_))447 ubuntu::app_launch::AppID::AppName::from_raw("application")))
449 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));448 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));
450449
451 /* Test with current-user-version, should return the version in the manifest */450 /* Test with current-user-version, should return the version in the manifest */
452 EXPECT_EQ("com.test.good_application_1.2.3",451 EXPECT_EQ("com.test.good_application_1.2.3",
453 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application"));452 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application"));
454453
455 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), testing::_))454 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good")))
456 .WillOnce(testing::Return(true));455 .WillOnce(testing::Return(true));
457 EXPECT_CALL(*mockstore, verifyAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),456 EXPECT_CALL(*mockstore, verifyAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),
458 ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_))457 ubuntu::app_launch::AppID::AppName::from_raw("application")))
459 .WillOnce(testing::Return(true));458 .WillOnce(testing::Return(true));
460 EXPECT_CALL(*mockstore,459 EXPECT_CALL(*mockstore,
461 hasAppId(ubuntu::app_launch::AppID{ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),460 hasAppId(ubuntu::app_launch::AppID{ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),
462 ubuntu::app_launch::AppID::AppName::from_raw("application"),461 ubuntu::app_launch::AppID::AppName::from_raw("application"),
463 ubuntu::app_launch::AppID::Version::from_raw("1.2.4")},462 ubuntu::app_launch::AppID::Version::from_raw("1.2.4")}))
464 testing::_))
465 .WillOnce(testing::Return(true));463 .WillOnce(testing::Return(true));
466464
467 /* Test with version specified, shouldn't even read the manifest */465 /* Test with version specified, shouldn't even read the manifest */
468 EXPECT_EQ("com.test.good_application_1.2.4",466 EXPECT_EQ("com.test.good_application_1.2.4",
469 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application", "1.2.4"));467 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application", "1.2.4"));
470468
471 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), testing::_))469 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good")))
472 .WillOnce(testing::Return(true));470 .WillOnce(testing::Return(true));
473 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),471 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),
474 ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED, testing::_))472 ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED))
475 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("application")));473 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("application")));
476 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),474 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),
477 ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_))475 ubuntu::app_launch::AppID::AppName::from_raw("application")))
478 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));476 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));
479477
480 /* Test with out a version or app, should return the version in the manifest */478 /* Test with out a version or app, should return the version in the manifest */
@@ -483,79 +481,72 @@
483 "current-user-version"));481 "current-user-version"));
484482
485 /* Make sure we can select the app from a list correctly */483 /* Make sure we can select the app from a list correctly */
486 EXPECT_CALL(*mockstore,484 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple")))
487 verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), testing::_))
488 .WillOnce(testing::Return(true));485 .WillOnce(testing::Return(true));
489 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),486 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),
490 ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED, testing::_))487 ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED))
491 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("first")));488 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("first")));
492 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),489 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),
493 ubuntu::app_launch::AppID::AppName::from_raw("first"), testing::_))490 ubuntu::app_launch::AppID::AppName::from_raw("first")))
494 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));491 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));
495 EXPECT_EQ("com.test.multiple_first_1.2.3",492 EXPECT_EQ("com.test.multiple_first_1.2.3",
496 (std::string)ubuntu::app_launch::AppID::discover(493 (std::string)ubuntu::app_launch::AppID::discover(
497 registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED));494 registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED));
498495
499 EXPECT_CALL(*mockstore,496 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple")))
500 verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), testing::_))
501 .WillOnce(testing::Return(true));497 .WillOnce(testing::Return(true));
502 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),498 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),
503 ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED, testing::_))499 ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED))
504 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("first")));500 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("first")));
505 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),501 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),
506 ubuntu::app_launch::AppID::AppName::from_raw("first"), testing::_))502 ubuntu::app_launch::AppID::AppName::from_raw("first")))
507 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));503 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));
508 EXPECT_EQ("com.test.multiple_first_1.2.3",504 EXPECT_EQ("com.test.multiple_first_1.2.3",
509 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.multiple"));505 (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.multiple"));
510506
511 EXPECT_CALL(*mockstore,507 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple")))
512 verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), testing::_))
513 .WillOnce(testing::Return(true));508 .WillOnce(testing::Return(true));
514 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),509 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),
515 ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED, testing::_))510 ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED))
516 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("fifth")));511 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("fifth")));
517 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),512 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),
518 ubuntu::app_launch::AppID::AppName::from_raw("fifth"), testing::_))513 ubuntu::app_launch::AppID::AppName::from_raw("fifth")))
519 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));514 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));
520 EXPECT_EQ("com.test.multiple_fifth_1.2.3",515 EXPECT_EQ("com.test.multiple_fifth_1.2.3",
521 (std::string)ubuntu::app_launch::AppID::discover(516 (std::string)ubuntu::app_launch::AppID::discover(
522 registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED));517 registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED));
523518
524 EXPECT_CALL(*mockstore,519 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple")))
525 verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), testing::_))
526 .WillOnce(testing::Return(true));520 .WillOnce(testing::Return(true));
527 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),521 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"),
528 ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED, testing::_))522 ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED))
529 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("")));523 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("")));
530 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(524 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(
531 registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));525 registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));
532526
533 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), testing::_))527 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good")))
534 .WillOnce(testing::Return(true));528 .WillOnce(testing::Return(true));
535 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),529 EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),
536 ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED, testing::_))530 ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED))
537 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("application")));531 .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("application")));
538 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),532 EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"),
539 ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_))533 ubuntu::app_launch::AppID::AppName::from_raw("application")))
540 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));534 .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3")));
541 EXPECT_EQ("com.test.good_application_1.2.3",535 EXPECT_EQ("com.test.good_application_1.2.3",
542 (std::string)ubuntu::app_launch::AppID::discover(536 (std::string)ubuntu::app_launch::AppID::discover(
543 registry, "com.test.good", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));537 registry, "com.test.good", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED));
544538
545 /* A bunch that should be NULL */539 /* A bunch that should be NULL */
546 EXPECT_CALL(*mockstore,540 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-hooks")))
547 verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-hooks"), testing::_))
548 .WillOnce(testing::Return(false));541 .WillOnce(testing::Return(false));
549 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-hooks"));542 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-hooks"));
550 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-json"), testing::_))543 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-json")))
551 .WillOnce(testing::Return(false));544 .WillOnce(testing::Return(false));
552 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-json"));545 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-json"));
553 EXPECT_CALL(*mockstore,546 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-object")))
554 verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-object"), testing::_))
555 .WillOnce(testing::Return(false));547 .WillOnce(testing::Return(false));
556 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-object"));548 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-object"));
557 EXPECT_CALL(*mockstore,549 EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-version")))
558 verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-version"), testing::_))
559 .WillOnce(testing::Return(false));550 .WillOnce(testing::Return(false));
560 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-version"));551 EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-version"));
561}552}
562553
=== modified file 'tests/list-apps.cpp'
--- tests/list-apps.cpp 2017-03-14 21:41:39 +0000
+++ tests/list-apps.cpp 2017-04-04 21:22:36 +0000
@@ -139,8 +139,8 @@
139TEST_F(ListApps, ListLegacy)139TEST_F(ListApps, ListLegacy)
140{140{
141 auto registry = std::make_shared<ubuntu::app_launch::Registry>();141 auto registry = std::make_shared<ubuntu::app_launch::Registry>();
142 ubuntu::app_launch::app_store::Legacy store;142 ubuntu::app_launch::app_store::Legacy store(registry->impl);
143 auto apps = store.list(registry);143 auto apps = store.list();
144144
145 printApps(apps);145 printApps(apps);
146146
@@ -154,8 +154,8 @@
154TEST_F(ListApps, ListLibertine)154TEST_F(ListApps, ListLibertine)
155{155{
156 auto registry = std::make_shared<ubuntu::app_launch::Registry>();156 auto registry = std::make_shared<ubuntu::app_launch::Registry>();
157 ubuntu::app_launch::app_store::Libertine store;157 ubuntu::app_launch::app_store::Libertine store(registry->impl);
158 auto apps = store.list(registry);158 auto apps = store.list();
159159
160 printApps(apps);160 printApps(apps);
161161
@@ -197,8 +197,8 @@
197 interfaces, x11Package, x11Package, x11Package}}; /* x11 check */197 interfaces, x11Package, x11Package, x11Package}}; /* x11 check */
198 auto registry = std::make_shared<ubuntu::app_launch::Registry>();198 auto registry = std::make_shared<ubuntu::app_launch::Registry>();
199199
200 ubuntu::app_launch::app_store::Snap store;200 ubuntu::app_launch::app_store::Snap store(registry->impl);
201 auto apps = store.list(registry);201 auto apps = store.list();
202202
203 printApps(apps);203 printApps(apps);
204204
205205
=== modified file 'tests/registry-mock.h'
--- tests/registry-mock.h 2017-03-20 10:13:50 +0000
+++ tests/registry-mock.h 2017-04-04 21:22:36 +0000
@@ -29,8 +29,8 @@
29class MockStore : public ubuntu::app_launch::app_store::Base29class MockStore : public ubuntu::app_launch::app_store::Base
30{30{
31public:31public:
32 MockStore()32 MockStore(const std::shared_ptr<ubuntu::app_launch::Registry::Impl>& registry)
33 : ubuntu::app_launch::app_store::Base()33 : ubuntu::app_launch::app_store::Base(registry)
34 {34 {
35 }35 }
3636
@@ -38,32 +38,22 @@
38 {38 {
39 }39 }
4040
41 MOCK_METHOD2(verifyPackage,41 MOCK_METHOD1(verifyPackage, bool(const ubuntu::app_launch::AppID::Package&));
42 bool(const ubuntu::app_launch::AppID::Package&, const std::shared_ptr<ubuntu::app_launch::Registry>&));42 MOCK_METHOD2(verifyAppname,
43 MOCK_METHOD3(verifyAppname,43 bool(const ubuntu::app_launch::AppID::Package&, const ubuntu::app_launch::AppID::AppName&));
44 bool(const ubuntu::app_launch::AppID::Package&,44 MOCK_METHOD2(findAppname,
45 const ubuntu::app_launch::AppID::AppName&,
46 const std::shared_ptr<ubuntu::app_launch::Registry>&));
47 MOCK_METHOD3(findAppname,
48 ubuntu::app_launch::AppID::AppName(const ubuntu::app_launch::AppID::Package&,45 ubuntu::app_launch::AppID::AppName(const ubuntu::app_launch::AppID::Package&,
49 ubuntu::app_launch::AppID::ApplicationWildcard,46 ubuntu::app_launch::AppID::ApplicationWildcard));
50 const std::shared_ptr<ubuntu::app_launch::Registry>&));47 MOCK_METHOD2(findVersion,
51 MOCK_METHOD3(findVersion,
52 ubuntu::app_launch::AppID::Version(const ubuntu::app_launch::AppID::Package&,48 ubuntu::app_launch::AppID::Version(const ubuntu::app_launch::AppID::Package&,
53 const ubuntu::app_launch::AppID::AppName&,49 const ubuntu::app_launch::AppID::AppName&));
54 const std::shared_ptr<ubuntu::app_launch::Registry>&));50 MOCK_METHOD1(hasAppId, bool(const ubuntu::app_launch::AppID&));
55 MOCK_METHOD2(hasAppId,
56 bool(const ubuntu::app_launch::AppID&, const std::shared_ptr<ubuntu::app_launch::Registry>&));
5751
58 /* Possible apps */52 /* Possible apps */
59 MOCK_METHOD1(list,53 MOCK_METHOD0(list, std::list<std::shared_ptr<ubuntu::app_launch::Application>>());
60 std::list<std::shared_ptr<ubuntu::app_launch::Application>>(
61 const std::shared_ptr<ubuntu::app_launch::Registry>&));
6254
63 /* Application Creation */55 /* Application Creation */
64 MOCK_METHOD2(create,56 MOCK_METHOD1(create, std::shared_ptr<ubuntu::app_launch::app_impls::Base>(const ubuntu::app_launch::AppID&));
65 std::shared_ptr<ubuntu::app_launch::app_impls::Base>(
66 const ubuntu::app_launch::AppID&, const std::shared_ptr<ubuntu::app_launch::Registry>&));
67};57};
6858
69class MockApp : public ubuntu::app_launch::app_impls::Base59class MockApp : public ubuntu::app_launch::app_impls::Base
@@ -71,7 +61,7 @@
71public:61public:
72 ubuntu::app_launch::AppID appid_;62 ubuntu::app_launch::AppID appid_;
7363
74 MockApp(const ubuntu::app_launch::AppID& appid, const std::shared_ptr<ubuntu::app_launch::Registry>& reg)64 MockApp(const ubuntu::app_launch::AppID& appid, const std::shared_ptr<ubuntu::app_launch::Registry::Impl>& reg)
75 : ubuntu::app_launch::app_impls::Base(reg)65 : ubuntu::app_launch::app_impls::Base(reg)
76 , appid_(appid)66 , appid_(appid)
77 {67 {
@@ -105,7 +95,7 @@
105 const std::string& job,95 const std::string& job,
106 const std::string& instance,96 const std::string& instance,
107 const std::vector<ubuntu::app_launch::Application::URL>& urls,97 const std::vector<ubuntu::app_launch::Application::URL>& urls,
108 const std::shared_ptr<ubuntu::app_launch::Registry>& registry)98 const std::shared_ptr<ubuntu::app_launch::Registry::Impl>& registry)
109 : ubuntu::app_launch::jobs::instance::Base(appId, job, instance, urls, registry){};99 : ubuntu::app_launch::jobs::instance::Base(appId, job, instance, urls, registry){};
110 ~MockInst(){};100 ~MockInst(){};
111101
@@ -117,7 +107,7 @@
117class MockJobsManager : public ubuntu::app_launch::jobs::manager::Base107class MockJobsManager : public ubuntu::app_launch::jobs::manager::Base
118{108{
119public:109public:
120 MockJobsManager(const std::shared_ptr<ubuntu::app_launch::Registry>& reg)110 MockJobsManager(const std::shared_ptr<ubuntu::app_launch::Registry::Impl>& reg)
121 : ubuntu::app_launch::jobs::manager::Base(reg)111 : ubuntu::app_launch::jobs::manager::Base(reg)
122 {112 {
123 }113 }
@@ -164,8 +154,8 @@
164class zgWatcherMock : public ubuntu::app_launch::info_watcher::Zeitgeist154class zgWatcherMock : public ubuntu::app_launch::info_watcher::Zeitgeist
165{155{
166public:156public:
167 zgWatcherMock()157 zgWatcherMock(const std::shared_ptr<ubuntu::app_launch::Registry::Impl>& registry)
168 : ubuntu::app_launch::info_watcher::Zeitgeist({})158 : ubuntu::app_launch::info_watcher::Zeitgeist(registry)
169 {159 {
170 }160 }
171161
@@ -180,31 +170,10 @@
180class RegistryImplMock : public ubuntu::app_launch::Registry::Impl170class RegistryImplMock : public ubuntu::app_launch::Registry::Impl
181{171{
182public:172public:
183 RegistryImplMock(ubuntu::app_launch::Registry& reg)173 RegistryImplMock()
184 : ubuntu::app_launch::Registry::Impl(reg)174 : ubuntu::app_launch::Registry::Impl()
185 {175 {
186 setupZgWatcher();176 g_debug("Registry Mock Implementation Created");
187
188 g_debug("Registry Mock Implementation Created");
189 }
190
191 RegistryImplMock(ubuntu::app_launch::Registry& reg,
192 std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>> appStores)
193 : ubuntu::app_launch::Registry::Impl(reg, appStores)
194 {
195 setupZgWatcher();
196
197 g_debug("Registry Mock Implementation Created");
198 }
199
200 void setupZgWatcher()
201 {
202 auto zgWatcher = std::make_shared<zgWatcherMock>();
203 zgWatcher_ = zgWatcher;
204 std::call_once(zgWatcherOnce_, [] {});
205
206 ON_CALL(*zgWatcher, lookupAppPopularity(testing::_))
207 .WillByDefault(testing::Return(ubuntu::app_launch::Application::Info::Popularity::from_raw(1u)));
208 }177 }
209178
210 ~RegistryImplMock()179 ~RegistryImplMock()
@@ -219,15 +188,29 @@
219{188{
220public:189public:
221 RegistryMock()190 RegistryMock()
191 : Registry(std::make_shared<RegistryImplMock>())
222 {192 {
193 auto zgWatcher = std::make_shared<zgWatcherMock>(impl);
194 ON_CALL(*zgWatcher, lookupAppPopularity(testing::_))
195 .WillByDefault(testing::Return(ubuntu::app_launch::Application::Info::Popularity::from_raw(1u)));
196 impl->setZgWatcher(zgWatcher);
197
223 g_debug("Registry Mock Created");198 g_debug("Registry Mock Created");
224 impl = std::unique_ptr<RegistryImplMock>(new RegistryImplMock(*this));
225 }199 }
226200
227 RegistryMock(std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>> appStores)201 RegistryMock(std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>> appStores,
202 std::shared_ptr<ubuntu::app_launch::jobs::manager::Base> jobManager)
203 : Registry(std::make_shared<RegistryImplMock>())
228 {204 {
205 impl->setAppStores(appStores);
206 impl->setJobs(jobManager);
207
208 auto zgWatcher = std::make_shared<zgWatcherMock>(impl);
209 ON_CALL(*zgWatcher, lookupAppPopularity(testing::_))
210 .WillByDefault(testing::Return(ubuntu::app_launch::Application::Info::Popularity::from_raw(1u)));
211 impl->setZgWatcher(zgWatcher);
212
229 g_debug("Registry Mock Created");213 g_debug("Registry Mock Created");
230 impl = std::unique_ptr<RegistryImplMock>(new RegistryImplMock(*this, appStores));
231 }214 }
232215
233 ~RegistryMock()216 ~RegistryMock()

Subscribers

People subscribed via source and target branches