35
35
************************/
37
37
/** All the interfaces that we run XMir for by default */
38
const std::set<std::string> XMIR_INTERFACES{"unity7", "x11"};
39
/** All the interfaces that we tell Unity support lifecycle */
40
const std::set<std::string> LIFECYCLE_INTERFACES{"unity8"};
38
const std::set<std::string> X11_INTERFACES{"unity7", "x11"};
39
/** The interface to indicate direct Mir support */
40
const std::string MIR_INTERFACE{"mir"};
41
/** The interface to indicate Ubuntu lifecycle support */
42
const std::string LIFECYCLE_INTERFACE{"unity8"};
41
43
/** Snappy has more restrictive appnames than everyone else */
42
44
const std::regex appnameRegex{"^[a-zA-Z0-9](?:-?[a-zA-Z0-9])*$"};
50
52
fields to the desktop spec that come from Snappy interfaces. */
51
53
class SnapInfo : public app_info::Desktop
53
/** The core interface for this snap */
54
std::string interface_;
55
55
/** AppID of snap */
59
59
SnapInfo(const AppID& appid,
60
60
const std::shared_ptr<Registry>& registry,
61
const std::string& interface,
61
const Snap::InterfaceInfo &interfaceInfo,
62
62
const std::string& snapDir)
64
64
[appid, snapDir]() -> std::shared_ptr<GKeyFile> {
113
113
app_info::DesktopFlags::NONE,
115
, interface_(interface)
120
/** Return the xMirEnable value based on whether the interface is
121
in the list of interfaces using XMir */
122
XMirEnable xMirEnable() override
124
if (XMIR_INTERFACES.find(interface_) != XMIR_INTERFACES.end())
126
return XMirEnable::from_raw(true);
130
return XMirEnable::from_raw(false);
134
/** Return the xMirEnable value based on whether the interface is
135
in the list of interfaces supporting the lifecycle */
136
UbuntuLifecycle supportsUbuntuLifecycle() override
138
if (LIFECYCLE_INTERFACES.find(interface_) != LIFECYCLE_INTERFACES.end())
140
return UbuntuLifecycle::from_raw(true);
144
return UbuntuLifecycle::from_raw(false);
117
_xMirEnable = std::get<0>(interfaceInfo);
118
_ubuntuLifecycle = std::get<1>(interfaceInfo);
148
121
/** Figures out the exec line for a snappy command. We're not using
207
180
\param appid Application ID of the snap
208
181
\param registry Registry to use for persistent connections
209
\param interface Primary interface that we found this snap for
182
\param interfaceInfo Metadata gleaned from the snap's interfaces
211
Snap::Snap(const AppID& appid, const std::shared_ptr<Registry>& registry, const std::string& interface)
184
Snap::Snap(const AppID& appid, const std::shared_ptr<Registry>& registry, const InterfaceInfo &interfaceInfo)
214
, interface_(interface)
216
188
pkgInfo_ = registry->impl->snapdInfo.pkgInfo(appid.package);
224
196
throw std::runtime_error("AppID does not match installed package for: " + std::string(appid));
227
info_ = std::make_shared<SnapInfo>(appid_, _registry, interface_, pkgInfo_->directory);
199
info_ = std::make_shared<SnapInfo>(appid_, _registry, interfaceInfo, pkgInfo_->directory);
229
201
g_debug("Application Snap object for AppID '%s'", std::string(appid).c_str());
232
/** Uses the findInterface() function to find the interface if we don't
204
/** Uses the findInterfaceInfo() function to find the interface if we don't
235
207
\param appid Application ID of the snap
236
208
\param registry Registry to use for persistent connections
238
210
Snap::Snap(const AppID& appid, const std::shared_ptr<Registry>& registry)
239
: Snap(appid, registry, findInterface(appid, registry))
211
: Snap(appid, registry, findInterfaceInfo(appid, registry))
259
231
std::set<std::shared_ptr<Application>, appcompare> apps;
261
auto addAppsForInterface = [&](const std::string& interface) {
233
auto lifecycleApps = registry->impl->snapdInfo.appsForInterface(LIFECYCLE_INTERFACE);
235
auto lifecycleForApp = [&](const AppID &appID) {
236
auto iterator = lifecycleApps.find(appID);
237
if (iterator == lifecycleApps.end())
239
return Application::Info::UbuntuLifecycle::from_raw(false);
243
return Application::Info::UbuntuLifecycle::from_raw(true);
247
auto addAppsForInterface = [&](const std::string& interface, app_info::Desktop::XMirEnable xMirEnable) {
262
248
for (const auto& id : registry->impl->snapdInfo.appsForInterface(interface))
250
auto interfaceInfo = std::make_tuple(xMirEnable, lifecycleForApp(id));
266
auto app = std::make_shared<Snap>(id, registry, interface);
253
auto app = std::make_shared<Snap>(id, registry, interfaceInfo);
267
254
apps.emplace(app);
269
256
catch (std::runtime_error& e)
276
for (const auto& interface : LIFECYCLE_INTERFACES)
278
addAppsForInterface(interface);
263
addAppsForInterface(MIR_INTERFACE, app_info::Desktop::XMirEnable::from_raw(false));
281
265
/* If an app has both, this will get rejected */
282
for (const auto& interface : XMIR_INTERFACES)
266
for (const auto& interface : X11_INTERFACES)
284
addAppsForInterface(interface);
268
addAppsForInterface(interface, app_info::Desktop::XMirEnable::from_raw(true));
287
271
return std::list<std::shared_ptr<Application>>(apps.begin(), apps.end());
296
/** Asks Snapd for the interfaces to determine which one the application
280
/** Asks Snapd for the interfaces to determine which ones the application
299
283
\param appid Application ID of the snap
300
284
\param registry Registry to use for persistent connections
302
std::string Snap::findInterface(const AppID& appid, const std::shared_ptr<Registry>& registry)
286
Snap::InterfaceInfo Snap::findInterfaceInfo(const AppID& appid, const std::shared_ptr<Registry>& registry)
304
288
auto ifaceset = registry->impl->snapdInfo.interfacesForAppId(appid);
306
for (const auto& interface : LIFECYCLE_INTERFACES)
308
if (ifaceset.find(interface) != ifaceset.end())
314
for (const auto& interface : XMIR_INTERFACES)
316
if (ifaceset.find(interface) != ifaceset.end())
322
throw std::runtime_error("Interface not found for: " + std::string(appid));
289
auto xMirEnable = app_info::Desktop::XMirEnable::from_raw(false);
290
auto ubuntuLifecycle = Application::Info::UbuntuLifecycle::from_raw(false);
292
if (ifaceset.find(LIFECYCLE_INTERFACE) != ifaceset.end())
294
ubuntuLifecycle = Application::Info::UbuntuLifecycle::from_raw(true);
297
if (ifaceset.find(MIR_INTERFACE) == ifaceset.end())
299
for (const auto& interface : X11_INTERFACES)
301
if (ifaceset.find(interface) != ifaceset.end())
303
xMirEnable = app_info::Desktop::XMirEnable::from_raw(true);
308
if (!xMirEnable.value())
310
throw std::runtime_error("Graphical interface not found for: " + std::string(appid));
314
return std::make_tuple(xMirEnable, ubuntuLifecycle);
325
317
/** Checks a PkgInfo structure to ensure that it matches the AppID */