~townsend/ubuntu-app-launch/remove-xmir-helpers

« back to all changes in this revision

Viewing changes to libubuntu-app-launch/application-impl-snap.cpp

  • Committer: Chris Townsend
  • Date: 2017-03-20 17:23:40 UTC
  • mfrom: (269.1.31 ubuntu-app-launch)
  • Revision ID: christopher.townsend@canonical.com-20170320172340-hvurwg8xst2dq9j2
MergeĀ lp:ubuntu-app-launch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
 ************************/
36
36
 
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])*$"};
43
45
 
50
52
    fields to the desktop spec that come from Snappy interfaces. */
51
53
class SnapInfo : public app_info::Desktop
52
54
{
53
 
    /** The core interface for this snap */
54
 
    std::string interface_;
55
55
    /** AppID of snap */
56
56
    AppID appId_;
57
57
 
58
58
public:
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)
63
63
        : Desktop(appid,
64
64
                  [appid, snapDir]() -> std::shared_ptr<GKeyFile> {
112
112
                  snapDir,
113
113
                  app_info::DesktopFlags::NONE,
114
114
                  registry)
115
 
        , interface_(interface)
116
115
        , appId_(appid)
117
116
    {
118
 
    }
119
 
 
120
 
    /** Return the xMirEnable value based on whether the interface is
121
 
        in the list of interfaces using XMir */
122
 
    XMirEnable xMirEnable() override
123
 
    {
124
 
        if (XMIR_INTERFACES.find(interface_) != XMIR_INTERFACES.end())
125
 
        {
126
 
            return XMirEnable::from_raw(true);
127
 
        }
128
 
        else
129
 
        {
130
 
            return XMirEnable::from_raw(false);
131
 
        }
132
 
    }
133
 
 
134
 
    /** Return the xMirEnable value based on whether the interface is
135
 
        in the list of interfaces supporting the lifecycle */
136
 
    UbuntuLifecycle supportsUbuntuLifecycle() override
137
 
    {
138
 
        if (LIFECYCLE_INTERFACES.find(interface_) != LIFECYCLE_INTERFACES.end())
139
 
        {
140
 
            return UbuntuLifecycle::from_raw(true);
141
 
        }
142
 
        else
143
 
        {
144
 
            return UbuntuLifecycle::from_raw(false);
145
 
        }
 
117
        _xMirEnable = std::get<0>(interfaceInfo);
 
118
        _ubuntuLifecycle = std::get<1>(interfaceInfo);
146
119
    }
147
120
 
148
121
    /** Figures out the exec line for a snappy command. We're not using
206
179
 
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
210
183
*/
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)
212
185
    : Base(registry)
213
186
    , appid_(appid)
214
 
    , interface_(interface)
215
187
{
216
188
    pkgInfo_ = registry->impl->snapdInfo.pkgInfo(appid.package);
217
189
    if (!pkgInfo_)
224
196
        throw std::runtime_error("AppID does not match installed package for: " + std::string(appid));
225
197
    }
226
198
 
227
 
    info_ = std::make_shared<SnapInfo>(appid_, _registry, interface_, pkgInfo_->directory);
 
199
    info_ = std::make_shared<SnapInfo>(appid_, _registry, interfaceInfo, pkgInfo_->directory);
228
200
 
229
201
    g_debug("Application Snap object for AppID '%s'", std::string(appid).c_str());
230
202
}
231
203
 
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
233
205
    have one.
234
206
 
235
207
    \param appid Application ID of the snap
236
208
    \param registry Registry to use for persistent connections
237
209
*/
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))
240
212
{
241
213
}
242
214
 
258
230
{
259
231
    std::set<std::shared_ptr<Application>, appcompare> apps;
260
232
 
261
 
    auto addAppsForInterface = [&](const std::string& interface) {
 
233
    auto lifecycleApps = registry->impl->snapdInfo.appsForInterface(LIFECYCLE_INTERFACE);
 
234
 
 
235
    auto lifecycleForApp = [&](const AppID &appID) {
 
236
        auto iterator = lifecycleApps.find(appID);
 
237
        if (iterator == lifecycleApps.end())
 
238
        {
 
239
            return Application::Info::UbuntuLifecycle::from_raw(false);
 
240
        }
 
241
        else
 
242
        {
 
243
            return Application::Info::UbuntuLifecycle::from_raw(true);
 
244
        }
 
245
    };
 
246
 
 
247
    auto addAppsForInterface = [&](const std::string& interface, app_info::Desktop::XMirEnable xMirEnable) {
262
248
        for (const auto& id : registry->impl->snapdInfo.appsForInterface(interface))
263
249
        {
 
250
            auto interfaceInfo = std::make_tuple(xMirEnable, lifecycleForApp(id));
264
251
            try
265
252
            {
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);
268
255
            }
269
256
            catch (std::runtime_error& e)
273
260
        }
274
261
    };
275
262
 
276
 
    for (const auto& interface : LIFECYCLE_INTERFACES)
277
 
    {
278
 
        addAppsForInterface(interface);
279
 
    }
 
263
    addAppsForInterface(MIR_INTERFACE, app_info::Desktop::XMirEnable::from_raw(false));
280
264
 
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)
283
267
    {
284
 
        addAppsForInterface(interface);
 
268
        addAppsForInterface(interface, app_info::Desktop::XMirEnable::from_raw(true));
285
269
    }
286
270
 
287
271
    return std::list<std::shared_ptr<Application>>(apps.begin(), apps.end());
293
277
    return appid_;
294
278
}
295
279
 
296
 
/** Asks Snapd for the interfaces to determine which one the application
 
280
/** Asks Snapd for the interfaces to determine which ones the application
297
281
    can support.
298
282
 
299
283
    \param appid Application ID of the snap
300
284
    \param registry Registry to use for persistent connections
301
285
*/
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)
303
287
{
304
288
    auto ifaceset = registry->impl->snapdInfo.interfacesForAppId(appid);
305
 
 
306
 
    for (const auto& interface : LIFECYCLE_INTERFACES)
307
 
    {
308
 
        if (ifaceset.find(interface) != ifaceset.end())
309
 
        {
310
 
            return interface;
311
 
        }
312
 
    }
313
 
 
314
 
    for (const auto& interface : XMIR_INTERFACES)
315
 
    {
316
 
        if (ifaceset.find(interface) != ifaceset.end())
317
 
        {
318
 
            return interface;
319
 
        }
320
 
    }
321
 
 
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);
 
291
 
 
292
    if (ifaceset.find(LIFECYCLE_INTERFACE) != ifaceset.end())
 
293
    {
 
294
        ubuntuLifecycle = Application::Info::UbuntuLifecycle::from_raw(true);
 
295
    }
 
296
 
 
297
    if (ifaceset.find(MIR_INTERFACE) == ifaceset.end())
 
298
    {
 
299
        for (const auto& interface : X11_INTERFACES)
 
300
        {
 
301
            if (ifaceset.find(interface) != ifaceset.end())
 
302
            {
 
303
                xMirEnable = app_info::Desktop::XMirEnable::from_raw(true);
 
304
                break;
 
305
            }
 
306
        }
 
307
 
 
308
        if (!xMirEnable.value())
 
309
        {
 
310
            throw std::runtime_error("Graphical interface not found for: " + std::string(appid));
 
311
        }
 
312
    }
 
313
 
 
314
    return std::make_tuple(xMirEnable, ubuntuLifecycle);
323
315
}
324
316
 
325
317
/** Checks a PkgInfo structure to ensure that it matches the AppID */