~mir-team/unity-mir/devel-mir-next

« back to all changes in this revision

Viewing changes to src/modules/Unity/Application/application_manager.cpp

  • Committer: CI bot
  • Author(s): Gerry Boland
  • Date: 2014-05-16 12:20:55 UTC
  • mfrom: (219.1.16 shortAppIds)
  • Revision ID: ps-jenkins@lists.canonical.com-20140516122055-e5jw3w0k5obulsdr
Add support for short appIds

Shells should use only short AppIds (i.e. appId without the version string). In order to support this, needed to
- slightly decouple appId from the desktop file path, now need to ask the ApplicationController implementation for the path to the desktop file
- DesktopFileReader now just a dumb file reader
- in the upstart ApplicationController interface & implementation, convert any long appIds to short appIds
- in ApplicationManager, to ease transition, have startApplication support both long & short appIds. But otherwise it uses short appIds only. Fixes: 1239750

Show diffs side-by-side

added added

removed removed

Lines of Context:
76
76
        );
77
77
}
78
78
 
 
79
// FIXME: To be removed once shell has fully adopted short appIds!!
 
80
QString toShortAppIdIfPossible(const QString &appId) {
 
81
    QRegExp longAppIdMask("[a-z0-9][a-z0-9+.-]+_[a-zA-Z0-9+.-]+_[0-9][a-zA-Z0-9.+:~-]*");
 
82
    if (longAppIdMask.exactMatch(appId)) {
 
83
        LOG("WARNING: long App ID encountered: %s", qPrintable(appId));
 
84
        // input string a long AppId, chop the version string off the end
 
85
        QStringList parts = appId.split("_");
 
86
        return QString("%1_%2").arg(parts.first()).arg(parts.at(1));
 
87
    }
 
88
    return appId;
 
89
}
79
90
 
80
91
void connectToSessionListener(ApplicationManager * manager, SessionListener * listener)
81
92
{
262
273
    return m_applications.at(index);
263
274
}
264
275
 
265
 
Application* ApplicationManager::findApplication(const QString &appId) const
 
276
Application* ApplicationManager::findApplication(const QString &inputAppId) const
266
277
{
 
278
    const QString appId = toShortAppIdIfPossible(inputAppId);
 
279
 
267
280
    for (Application *app : m_applications) {
268
281
        if (app->appId() == appId) {
269
282
            return app;
272
285
    return nullptr;
273
286
}
274
287
 
275
 
bool ApplicationManager::requestFocusApplication(const QString &appId)
 
288
bool ApplicationManager::requestFocusApplication(const QString &inputAppId)
276
289
{
 
290
    const QString appId = toShortAppIdIfPossible(inputAppId);
 
291
 
277
292
    DLOG("ApplicationManager::requestFocusApplication (this=%p, appId=%s)", this, qPrintable(appId));
278
293
    Application *application = findApplication(appId);
279
294
 
355
370
        application->setState(Application::Running);
356
371
}
357
372
 
358
 
bool ApplicationManager::focusApplication(const QString &appId)
 
373
bool ApplicationManager::focusApplication(const QString &inputAppId)
359
374
{
 
375
    const QString appId = toShortAppIdIfPossible(inputAppId);
 
376
 
360
377
    Application *application = findApplication(appId);
361
378
    DLOG("ApplicationManager::focusApplication (this=%p, application=%p, appId=%s)", this, application, qPrintable(appId));
362
379
 
412
429
    return startApplication(appId, NoFlag, arguments);
413
430
}
414
431
 
415
 
Application *ApplicationManager::startApplication(const QString &appId, ExecFlags flags,
 
432
/**
 
433
 * @brief ApplicationManager::startApplication launches an application identified by an "application id" or appId.
 
434
 *
 
435
 * Note: due to an implementation detail, appIds come in two forms:
 
436
 * * long appId: $(click_package)_$(application)_$(version)
 
437
 * * short appId: $(click_package)_$(application)
 
438
 * It is expected that the shell uses _only_ short appIds (but long appIds are accepted by this method for legacy
 
439
 * reasons - but be warned, this ability will be removed)
 
440
 *
 
441
 * Unless stated otherwise, we always use short appIds in this API.
 
442
 *
 
443
 * @param inputAppId AppId of application to launch (long appId supported)
 
444
 * @param flags Shell specific flags to modify the initial state of the application
 
445
 * @param arguments Command line arguments to pass to the application to be launched
 
446
 * @return Pointer to Application object representing the launched process
 
447
 */
 
448
Application *ApplicationManager::startApplication(const QString &inputAppId, ExecFlags flags,
416
449
                                                  const QStringList &arguments)
417
450
{
 
451
    QString appId = toShortAppIdIfPossible(inputAppId);
418
452
    DLOG("ApplicationManager::startApplication (this=%p, appId=%s)", this, qPrintable(appId));
419
453
 
420
454
    if (!m_taskController->start(appId, arguments)) {
425
459
    {
426
460
        Application * application = findApplication(appId);
427
461
        if (application) {
428
 
            DLOG("ApplicationManager::startApplication - application already "
429
 
                 "exists: (this=%p, app=%p, appId=%s)",
 
462
            DLOG("ApplicationManager::startApplication - application already exists: (this=%p, app=%p, appId=%s)",
430
463
                 this, application, qPrintable(appId));
 
464
            return application;
431
465
        }
432
466
    }
433
467
 
434
468
    Application* application = new Application(
435
469
                m_taskController,
436
 
                m_desktopFileReaderFactory->createInstanceForAppId(appId),
 
470
                m_desktopFileReaderFactory->createInstance(appId, m_taskController->findDesktopFileForAppId(appId)),
437
471
                Application::Starting,
438
472
                arguments,
439
473
                this);
467
501
    if (!application) { // if shell did not start this application, but upstart did
468
502
        application = new Application(
469
503
                    m_taskController,
470
 
                    m_desktopFileReaderFactory->createInstanceForAppId(appId),
 
504
                    m_desktopFileReaderFactory->createInstance(appId, m_taskController->findDesktopFileForAppId(appId)),
471
505
                    Application::Starting,
472
506
                    QStringList(), this);
473
507
        if (!application->isValid()) {
489
523
    }
490
524
}
491
525
 
492
 
bool ApplicationManager::stopApplication(const QString &appId)
 
526
bool ApplicationManager::stopApplication(const QString &inputAppId)
493
527
{
 
528
    const QString appId = toShortAppIdIfPossible(inputAppId);
 
529
 
494
530
    Application *application = findApplication(appId);
495
531
    DLOG("ApplicationManager::stopApplication (this=%p, application=%p, appId=%s)", this, application, qPrintable(appId));
496
532
 
504
540
    remove(application);
505
541
    m_dbusWindowStack->WindowDestroyed(0, application->appId());
506
542
 
507
 
    bool result = m_taskController->stop(application->appId());
 
543
    bool result = m_taskController->stop(application->longAppId());
508
544
 
509
545
    LOG_IF(result == false, "FAILED to ask Upstart to stop application '%s'", qPrintable(application->appId()));
510
546
 
521
557
    return result;
522
558
}
523
559
 
524
 
bool ApplicationManager::updateScreenshot(const QString &appId)
 
560
bool ApplicationManager::updateScreenshot(const QString &inputAppId)
525
561
{
 
562
    const QString appId = toShortAppIdIfPossible(inputAppId);
 
563
 
526
564
    Application *application = findApplication(appId);
527
565
 
528
566
    if (!application) {
642
680
 
643
681
    for (Application *app : m_applications) {
644
682
        if (app->state() == Application::Starting
645
 
                && m_taskController->appIdHasProcessId(app->appId(), pid)) {
 
683
                && m_taskController->appIdHasProcessId(app->longAppId(), pid)) {
646
684
            app->setPid(pid);
647
685
            DLOG("ApplicationManager::authorizeSession - connecting: application=%p and pid=%lld", app, pid);
648
686
            authorized = true;
678
716
 
679
717
    DLOG("Process supplied desktop_file_hint, loading '%s'", desktopFileName.get().toLatin1().data());
680
718
 
 
719
    // Guess appId from the desktop file hint
 
720
    QString appId = toShortAppIdIfPossible(desktopFileName.get().remove(QRegExp(".desktop$")).split('/').last());
 
721
 
681
722
    // FIXME: right now we support --desktop_file_hint=appId for historical reasons. So let's try that in
682
723
    // case we didn't get an existing .desktop file path
683
724
    DesktopFileReader* desktopData;
684
725
    if (QFileInfo(desktopFileName.get()).exists()) {
685
 
        desktopData = m_desktopFileReaderFactory->createInstanceForDesktopFile(QFileInfo(desktopFileName.get()));
 
726
        desktopData = m_desktopFileReaderFactory->createInstance(appId, QFileInfo(desktopFileName.get()));
686
727
    } else {
687
 
        desktopData = m_desktopFileReaderFactory->createInstanceForAppId(desktopFileName.get());
 
728
        desktopData = m_desktopFileReaderFactory->createInstance(appId, m_taskController->findDesktopFileForAppId(appId));
688
729
    }
689
730
 
690
731
    if (!desktopData->loaded()) {