~gerboland/qtmir/ual-catch-exception

« back to all changes in this revision

Viewing changes to tests/modules/ApplicationManager/application_manager_test.cpp

  • Committer: CI Train Bot
  • Author(s): Daniel d'Andrada
  • Date: 2016-04-13 18:38:49 UTC
  • mfrom: (466.2.16 surfaceListModel)
  • Revision ID: ci-train-bot@canonical.com-20160413183849-qdqd0akyoa4rdl9i
Surface-based window management

- Session is no longer exported to QML. It's now an internal qtmir concept.
Approved by: Gerry Boland

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include <condition_variable>
20
20
#include <QSignalSpy>
21
21
 
 
22
#include <Unity/Application/mirfocuscontroller.h>
22
23
#include <Unity/Application/timer.h>
23
24
 
24
25
#include <fake_desktopfilereader.h>
26
27
#include <mock_surface.h>
27
28
#include <qtmir_test.h>
28
29
 
29
 
 
30
30
using namespace qtmir;
31
31
using mir::scene::MockSession;
32
32
 
33
33
namespace ms = mir::scene;
 
34
namespace unityapi = unity::shell::application;
34
35
 
35
36
class ApplicationManagerTests : public ::testing::QtMirTest
36
37
{
38
39
    ApplicationManagerTests()
39
40
    {}
40
41
 
 
42
    ~ApplicationManagerTests() {
 
43
    }
 
44
 
41
45
    inline void onSessionStarting(const std::shared_ptr<mir::scene::Session> &session) {
42
46
        applicationManager.onSessionStarting(session);
43
47
        sessionManager.onSessionStarting(session);
354
358
    EXPECT_EQ(first_session, the_app->session()->session());
355
359
}
356
360
 
357
 
TEST_F(ApplicationManagerTests, focused_app_can_rerequest_focus)
358
 
{
359
 
    using namespace ::testing;
360
 
    const pid_t a_procId = 5921;
361
 
    const char an_app_id[] = "some_app";
362
 
    QByteArray a_cmd("/usr/bin/app1 --desktop_file_hint=some_app");
363
 
    FakeMirSurface *aSurface = new FakeMirSurface;
364
 
 
365
 
    ON_CALL(procInfo, command_line(_)).WillByDefault(Return(a_cmd));
366
 
    ON_CALL(*taskController, appIdHasProcessId(_,_)).WillByDefault(Return(false));
367
 
 
368
 
    bool authed = true;
369
 
 
370
 
    std::shared_ptr<mir::scene::Session> a_session = std::make_shared<MockSession>("Oo", a_procId);
371
 
 
372
 
    applicationManager.authorizeSession(a_procId, authed);
373
 
    onSessionStarting(a_session);
374
 
    onSessionCreatedSurface(a_session.get(), aSurface);
375
 
    aSurface->drawFirstFrame();
376
 
 
377
 
    Application * the_app = applicationManager.findApplication(an_app_id);
378
 
    applicationManager.focusApplication(an_app_id);
379
 
 
380
 
    EXPECT_EQ(Application::Running, the_app->state());
381
 
    EXPECT_EQ(true, the_app->focused());
382
 
 
383
 
    applicationManager.focusApplication(an_app_id);
384
 
    EXPECT_EQ(true, the_app->focused());
385
 
}
386
 
 
387
361
TEST_F(ApplicationManagerTests,starting_app_is_suspended_when_it_gets_ready_if_requested)
388
362
{
389
363
    using namespace ::testing;
488
462
        .WillOnce(Return(true));
489
463
 
490
464
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
491
 
    QSignalSpy addedSpy(&applicationManager, SIGNAL(applicationAdded(const QString &)));
492
465
 
493
466
    // start the application
494
467
    Application *theApp = applicationManager.startApplication(appId);
502
475
    // check signals were emitted
503
476
    EXPECT_EQ(2, countSpy.count()); //FIXME(greyback)
504
477
    EXPECT_EQ(1, applicationManager.count());
505
 
    EXPECT_EQ(1, addedSpy.count());
506
 
    EXPECT_EQ(appId, addedSpy.takeFirst().at(0).toString());
507
478
 
508
479
    // check application in list of apps
509
480
    Application *theAppAgain = applicationManager.findApplication(appId);
529
500
    ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
530
501
 
531
502
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
532
 
    QSignalSpy addedSpy(&applicationManager, SIGNAL(applicationAdded(const QString &)));
533
503
    QSignalSpy focusSpy(&applicationManager, SIGNAL(focusRequested(const QString &)));
534
504
 
535
505
    // upstart sends notification that the application was started
546
516
    // check signals were emitted
547
517
    EXPECT_EQ(2, countSpy.count()); //FIXME(greyback)
548
518
    EXPECT_EQ(1, applicationManager.count());
549
 
    EXPECT_EQ(1, addedSpy.count());
550
 
    EXPECT_EQ(appId, addedSpy.takeFirst().at(0).toString());
551
519
    EXPECT_EQ(1, focusSpy.count());
552
520
    EXPECT_EQ(appId, focusSpy.takeFirst().at(0).toString());
553
521
}
578
546
    ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
579
547
 
580
548
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
581
 
    QSignalSpy addedSpy(&applicationManager, SIGNAL(applicationAdded(const QString &)));
582
549
 
583
550
    // Mir requests authentication for an application that was started
584
551
    bool authed = false;
596
563
    // check signals were emitted
597
564
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
598
565
    EXPECT_EQ(applicationManager.count(), 1);
599
 
    EXPECT_EQ(addedSpy.count(), 1);
600
 
    EXPECT_EQ(addedSpy.takeFirst().at(0).toString(), appId);
601
566
}
602
567
 
603
568
/*
617
582
        .WillOnce(Return(cmdLine));
618
583
 
619
584
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
620
 
    QSignalSpy addedSpy(&applicationManager, SIGNAL(applicationAdded(const QString &)));
621
585
 
622
586
    // Mir requests authentication for an application that was started
623
587
    bool authed = true;
631
595
    // check no new signals were emitted
632
596
    EXPECT_EQ(countSpy.count(), 0);
633
597
    EXPECT_EQ(applicationManager.count(), 0);
634
 
    EXPECT_EQ(addedSpy.count(), 0);
635
598
}
636
599
 
637
600
/*
763
726
    applicationManager.startApplication(appId);
764
727
 
765
728
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
766
 
    QSignalSpy addedSpy(&applicationManager, SIGNAL(applicationAdded(const QString &)));
767
729
 
768
730
    // upstart sends notification that the application was started
769
731
    applicationManager.onProcessStarting(appId);
771
733
    // check no new signals were emitted and application state unchanged
772
734
    EXPECT_EQ(countSpy.count(), 0);
773
735
    EXPECT_EQ(applicationManager.count(), 1);
774
 
    EXPECT_EQ(addedSpy.count(), 0);
775
736
 
776
737
    Application *theApp = applicationManager.findApplication(appId);
777
738
    EXPECT_EQ(Application::Starting, theApp->state());
799
760
    applicationManager.onProcessStarting(appId);
800
761
 
801
762
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
802
 
    QSignalSpy addedSpy(&applicationManager, SIGNAL(applicationAdded(const QString &)));
803
763
 
804
764
    std::shared_ptr<mir::scene::Session> session = std::make_shared<MockSession>("", procId);
805
765
 
810
770
 
811
771
    EXPECT_EQ(countSpy.count(), 0);
812
772
    EXPECT_EQ(applicationManager.count(), 1);
813
 
    EXPECT_EQ(addedSpy.count(), 0);
814
773
 
815
774
    // Check application state and session are correctly set
816
775
    Application *theApp = applicationManager.findApplication(appId);
880
839
    onSessionStarting(session);
881
840
 
882
841
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
883
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
884
842
 
885
843
    EXPECT_CALL(*taskController, stop(appId))
886
844
        .Times(1)
889
847
    // Stop app
890
848
    applicationManager.stopApplication(appId);
891
849
 
 
850
    Mock::VerifyAndClearExpectations(taskController);
 
851
 
 
852
    // emulate mir session dying and taskController emitting processStopped(appId) in response
 
853
    // to the taskController->stop(appId) call from applicationManager
 
854
    onSessionStopping(session);
 
855
    applicationManager.onProcessStopped(appId);
 
856
 
892
857
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
893
858
    EXPECT_EQ(applicationManager.count(), 0);
894
 
    EXPECT_EQ(removedSpy.count(), 1);
895
 
    EXPECT_EQ(removedSpy.takeFirst().at(0).toString(), appId);
896
859
}
897
860
 
898
861
/*
912
875
        .Times(1)
913
876
        .WillOnce(Return(true));
914
877
 
915
 
    applicationManager.startApplication(appId);
916
 
    applicationManager.onProcessStarting(appId);
917
 
    std::shared_ptr<mir::scene::Session> session = std::make_shared<MockSession>("", procId);
918
 
    bool authed = true;
919
 
    applicationManager.authorizeSession(procId, authed);
920
 
    onSessionStarting(session);
921
 
 
922
 
    FakeMirSurface *surface = new FakeMirSurface;
923
 
    onSessionCreatedSurface(session.get(), surface);
924
 
    surface->drawFirstFrame();
925
 
 
926
 
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
927
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
928
 
 
929
 
    // Stop app
930
 
    applicationManager.stopApplication(appId);
931
 
 
932
 
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
933
 
    EXPECT_EQ(applicationManager.count(), 0);
934
 
    EXPECT_EQ(removedSpy.count(), 1);
935
 
    EXPECT_EQ(removedSpy.takeFirst().at(0).toString(), appId);
936
 
}
937
 
 
938
 
/*
939
 
 * Test that a suspended application is stopped correctly
940
 
 */
941
 
TEST_F(ApplicationManagerTests,shellStopsSuspendedAppCorrectly)
942
 
{
943
 
    using namespace ::testing;
944
 
    const QString appId("testAppId");
945
 
    const pid_t procId = 5551;
946
 
 
947
 
    // Set up Mocks & signal watcher
948
 
    ON_CALL(*taskController, primaryPidForAppId(appId)).WillByDefault(Return(procId));
949
 
    ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Invoke(createMockDesktopFileReader));
950
 
 
951
 
    EXPECT_CALL(*taskController, start(appId, _))
952
 
        .Times(1)
953
 
        .WillOnce(Return(true));
954
 
 
955
 
    Application *application = applicationManager.startApplication(appId);
956
 
    applicationManager.onProcessStarting(appId);
957
 
    std::shared_ptr<mir::scene::Session> session = std::make_shared<MockSession>("", procId);
958
 
    bool authed = true;
959
 
    applicationManager.authorizeSession(procId, authed);
960
 
    onSessionStarting(session);
961
 
    applicationManager.onProcessStarting(appId);
962
 
 
963
 
    FakeMirSurface *surface = new FakeMirSurface;
964
 
    onSessionCreatedSurface(session.get(), surface);
965
 
    surface->drawFirstFrame();
966
 
 
967
 
    suspend(application);
968
 
 
969
 
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
970
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
971
 
 
972
 
    // Stop app
973
 
    applicationManager.stopApplication(appId);
974
 
 
975
 
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
976
 
    EXPECT_EQ(applicationManager.count(), 0);
977
 
    EXPECT_EQ(removedSpy.count(), 1);
978
 
    EXPECT_EQ(removedSpy.takeFirst().at(0).toString(), appId);
 
878
    Application *app = applicationManager.startApplication(appId);
 
879
    applicationManager.onProcessStarting(appId);
 
880
    std::shared_ptr<mir::scene::Session> session = std::make_shared<NiceMock<MockSession>>("", procId);
 
881
    bool authed = true;
 
882
    applicationManager.authorizeSession(procId, authed);
 
883
    onSessionStarting(session);
 
884
 
 
885
    FakeMirSurface *surface = new FakeMirSurface;
 
886
    onSessionCreatedSurface(session.get(), surface);
 
887
    surface->drawFirstFrame();
 
888
 
 
889
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
 
890
 
 
891
    QSignalSpy closeRequestedSpy(surface, SIGNAL(closeRequested()));
 
892
 
 
893
    // Stop app
 
894
    applicationManager.stopApplication(appId);
 
895
 
 
896
    // Asking ApplicationManager to stop the application just makes it request its surfaces to be
 
897
    // closed
 
898
    EXPECT_EQ(1, closeRequestedSpy.count());
 
899
 
 
900
    // comply
 
901
    delete surface;
 
902
    surface = nullptr;
 
903
 
 
904
    // now it's the turn of the application process itself to go away, since its last surface has gone
 
905
    EXPECT_EQ(Application::InternalState::Closing, app->internalState());
 
906
 
 
907
    // Simulates that the application complied to the close() request and stopped itself
 
908
    onSessionStopping(session);
 
909
    applicationManager.onProcessStopped(appId);
 
910
 
 
911
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
 
912
    EXPECT_EQ(applicationManager.count(), 0);
979
913
}
980
914
 
981
915
/*
1007
941
    surface->drawFirstFrame();
1008
942
 
1009
943
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1010
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1011
944
 
1012
945
    onSessionStopping(session);
1013
946
    // Upstart notifies of stopping app
1015
948
 
1016
949
    EXPECT_EQ(2, countSpy.count()); //FIXME(greyback)
1017
950
    EXPECT_EQ(0, applicationManager.count());
1018
 
    EXPECT_EQ(1, removedSpy.count());
1019
 
    EXPECT_EQ(appId, removedSpy.takeFirst().at(0).toString());
1020
951
}
1021
952
 
1022
953
/*
1049
980
    surface->drawFirstFrame();
1050
981
 
1051
982
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1052
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1053
983
 
1054
984
    onSessionStopping(session);
1055
985
 
1061
991
 
1062
992
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
1063
993
    EXPECT_EQ(applicationManager.count(), 0);
1064
 
    EXPECT_EQ(removedSpy.count(), 1);
1065
 
    EXPECT_EQ(removedSpy.takeFirst().at(0).toString(), appId);
1066
994
}
1067
995
 
1068
996
/*
1100
1028
 
1101
1029
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1102
1030
    QSignalSpy focusSpy(&applicationManager, SIGNAL(focusedApplicationIdChanged()));
1103
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1104
1031
 
1105
1032
    // Mir reports disconnection
1106
1033
    onSessionStopping(session);
1115
1042
 
1116
1043
    EXPECT_EQ(0, countSpy.count());
1117
1044
    EXPECT_EQ(1, applicationManager.count());
1118
 
    EXPECT_EQ(0, removedSpy.count());
1119
1045
}
1120
1046
 
1121
1047
/*
1155
1081
 
1156
1082
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1157
1083
    QSignalSpy focusSpy(&applicationManager, SIGNAL(focusedApplicationIdChanged()));
1158
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1159
1084
 
1160
1085
    // Mir reports disconnection
1161
1086
    onSessionStopping(session);
1170
1095
 
1171
1096
    EXPECT_EQ(countSpy.count(), 0);
1172
1097
    EXPECT_EQ(applicationManager.count(), 1);
1173
 
    EXPECT_EQ(removedSpy.count(), 0);
1174
1098
}
1175
1099
 
1176
1100
/*
1198
1122
    onSessionStarting(session);
1199
1123
 
1200
1124
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1201
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1202
1125
 
1203
1126
    // Mir notifies of stopping app
1204
1127
    onSessionStopping(session);
1205
1128
 
1206
1129
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
1207
1130
    EXPECT_EQ(applicationManager.count(), 0);
1208
 
    EXPECT_EQ(removedSpy.count(), 1);
1209
 
    EXPECT_EQ(removedSpy.takeFirst().at(0).toString(), appId);
1210
1131
}
1211
1132
 
1212
1133
/*
1239
1160
    surface->drawFirstFrame();
1240
1161
 
1241
1162
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1242
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1243
1163
 
1244
1164
    // Mir notifies of stopping app
1245
1165
    onSessionStopping(session);
1246
1166
 
1247
1167
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
1248
1168
    EXPECT_EQ(applicationManager.count(), 0);
1249
 
    EXPECT_EQ(removedSpy.count(), 1);
1250
 
    EXPECT_EQ(removedSpy.takeFirst().at(0).toString(), appId);
1251
1169
}
1252
1170
 
1253
1171
/*
1288
1206
    surface->drawFirstFrame();
1289
1207
 
1290
1208
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1291
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1292
1209
 
1293
1210
    // Mir notifies of stopping app
1294
1211
    onSessionStopping(session);
1295
1212
 
1296
1213
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
1297
1214
    EXPECT_EQ(applicationManager.count(), 0);
1298
 
    EXPECT_EQ(removedSpy.count(), 1);
1299
1215
 
1300
1216
    Application *app = applicationManager.findApplication(appId);
1301
1217
    EXPECT_EQ(nullptr, app);
1346
1262
    ASSERT_EQ(Application::InternalState::Suspended, app->internalState());
1347
1263
 
1348
1264
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1349
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1350
1265
 
1351
1266
    // Mir notifies of stopping app
1352
1267
    onSessionStopping(session);
1353
1268
 
1354
1269
    EXPECT_EQ(0, countSpy.count());
1355
1270
    EXPECT_EQ(1, applicationManager.count());
1356
 
    EXPECT_EQ(0, removedSpy.count());
1357
1271
 
1358
1272
    EXPECT_EQ(Application::Stopped, app->state());
1359
1273
}
1382
1296
    applicationManager.authorizeSession(procId, authed);
1383
1297
    onSessionStarting(session);
1384
1298
 
 
1299
    Mock::VerifyAndClearExpectations(taskController);
1385
1300
    EXPECT_CALL(*taskController, stop(appId))
1386
1301
        .Times(1)
1387
1302
        .WillOnce(Return(true));
1389
1304
    applicationManager.stopApplication(appId);
1390
1305
 
1391
1306
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1392
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1393
1307
 
1394
1308
    // the mir session always ends before upstart notifies the process has stopped
1395
1309
    onSessionStopping(session);
1398
1312
    applicationManager.onProcessStopped(appId);
1399
1313
 
1400
1314
    EXPECT_EQ(0, countSpy.count());
1401
 
    EXPECT_EQ(0, removedSpy.count());
1402
1315
}
1403
1316
 
1404
1317
/*
1445
1358
    surface->drawFirstFrame();
1446
1359
 
1447
1360
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1448
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1449
1361
 
1450
1362
    // Mir notifies of stopping app/Session
1451
1363
    onSessionStopping(session2);
1453
1365
 
1454
1366
    EXPECT_EQ(countSpy.count(), 2); //FIXME(greyback)
1455
1367
    EXPECT_EQ(applicationManager.count(), 0);
1456
 
    EXPECT_EQ(removedSpy.count(), 1);
1457
 
    EXPECT_EQ(removedSpy.takeFirst().at(0).toString(), appId);
1458
1368
}
1459
1369
 
1460
1370
/*
1508
1418
    EXPECT_EQ(Application::Suspended, app->state());
1509
1419
 
1510
1420
    QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1511
 
    QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1512
1421
 
1513
1422
    // Mir notifies of stopping app/Session
1514
1423
    onSessionStopping(session2);
1515
1424
    onSessionStopping(session1);
1516
1425
 
1517
1426
    EXPECT_EQ(0, countSpy.count());
1518
 
    EXPECT_EQ(0, removedSpy.count());
1519
1427
}
1520
1428
 
1521
1429
/*
1531
1439
    const QString appId("testAppId");
1532
1440
    const pid_t procId = 5551;
1533
1441
 
 
1442
    int argc = 0;
 
1443
    char* argv[0];
 
1444
    QCoreApplication qtApp(argc, argv); // app for deleteLater event
 
1445
 
1534
1446
    // Set up Mocks & signal watcher
1535
1447
    ON_CALL(*taskController, primaryPidForAppId(appId)).WillByDefault(Return(procId));
1536
1448
    ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Invoke(createMockDesktopFileReader));
1552
1464
    surface->drawFirstFrame();
1553
1465
    suspend(app);
1554
1466
 
 
1467
    surface->setLive(false);
1555
1468
    onSessionStopping(session);
1556
1469
    applicationManager.onProcessFailed(appId, TaskController::Error::APPLICATION_CRASHED);
1557
1470
    applicationManager.onProcessStopped(appId);
1558
1471
 
1559
1472
    EXPECT_EQ(Application::Stopped, app->state());
1560
1473
 
 
1474
    delete surface; surface = nullptr;
 
1475
 
 
1476
    // Session should have called deleteLater() on itself, as it's zombie and doesn't hold any surface
 
1477
    // But DeferredDelete is special: likes to be called out specifically or it won't come out
 
1478
    qtApp.sendPostedEvents(app->session(), QEvent::DeferredDelete);
 
1479
    qtApp.sendPostedEvents();
 
1480
 
 
1481
    ASSERT_EQ(app->session(), nullptr);
 
1482
 
1561
1483
    QSignalSpy focusRequestSpy(&applicationManager, SIGNAL(focusRequested(const QString &)));
1562
1484
 
1563
1485
    // Upstart re-launches app
1853
1775
    applicationManager.authorizeSession(procId, authed);
1854
1776
    onSessionStarting(session);
1855
1777
 
1856
 
    QSignalSpy spy(app, SIGNAL(destroyed(QObject*)));
1857
 
    QObject::connect(app, &QObject::destroyed, app, [&qtApp](){ qtApp.quit(); });
 
1778
    Mock::VerifyAndClearExpectations(taskController);
1858
1779
 
1859
1780
    // Stop app
1860
1781
 
 
1782
    QSignalSpy appDestroyedSpy(app, SIGNAL(destroyed(QObject*)));
 
1783
 
1861
1784
    EXPECT_CALL(*taskController, stop(appId))
1862
1785
        .Times(1)
1863
1786
        .WillOnce(Return(true));
1870
1793
    // Upstart notifies of stopping app
1871
1794
    applicationManager.onProcessStopped(appId);
1872
1795
 
1873
 
    qtApp.exec();
1874
 
    EXPECT_EQ(1, spy.count());
 
1796
    // DeferredDelete is special: likes to be called out specifically or it won't come out
 
1797
    qtApp.sendPostedEvents(app, QEvent::DeferredDelete);
 
1798
    qtApp.sendPostedEvents();
 
1799
 
 
1800
    EXPECT_EQ(1, appDestroyedSpy.count());
1875
1801
}
1876
1802
 
1877
1803
/*
1922
1848
 
1923
1849
    // Asking ApplicationManager to stop the application just makes it request its surfaces to be
1924
1850
    // closed
 
1851
    EXPECT_EQ(1, closeRequestedSpy.count());
 
1852
 
 
1853
    // comply
 
1854
    delete surface;
 
1855
    surface = nullptr;
 
1856
 
 
1857
    // now it's the turn of the application process itself to go away, since its last surface has gone
1925
1858
    EXPECT_EQ(Application::InternalState::Closing, app->internalState());
1926
 
    EXPECT_EQ(1, closeRequestedSpy.count());
1927
1859
 
1928
1860
    // Trying to start a new instance of this app while we are still waiting for its current
1929
1861
    // instance to end yields no immediate result. This command gets queued instead.
1930
1862
    EXPECT_EQ(nullptr, applicationManager.startApplication(appId));
1931
1863
 
1932
 
    QSignalSpy appAddedSpy(&applicationManager, SIGNAL(applicationAdded(const QString&)));
 
1864
    QSignalSpy appAddedSpy(&applicationManager, &QAbstractItemModel::rowsInserted);
1933
1865
 
1934
1866
    // Simulates that the application complied to the close() request and stopped itself
1935
1867
    onSessionStopping(session);
1943
1875
}
1944
1876
 
1945
1877
/*
1946
 
 * Test that there is an attempt at polite exiting of the app by requesting closure of the surface.
1947
 
 */
1948
 
TEST_F(ApplicationManagerTests,suspendedApplicationResumesClosesAndDeletes)
1949
 
{
1950
 
    using namespace ::testing;
1951
 
 
1952
 
    const QString appId("testAppId");
1953
 
    quint64 procId = 5551;
1954
 
    Application* app = startApplication(procId, appId);
1955
 
    std::shared_ptr<mir::scene::Session> session = app->session()->session();
1956
 
 
1957
 
    FakeMirSurface *surface = new FakeMirSurface;
1958
 
    onSessionCreatedSurface(session.get(), surface);
1959
 
    surface->drawFirstFrame();
1960
 
    EXPECT_EQ(Application::InternalState::Running, app->internalState());
1961
 
    EXPECT_EQ(SessionInterface::Running,  app->session()->state());
1962
 
 
1963
 
    // Suspend the application.
1964
 
    suspend(app);
1965
 
    EXPECT_EQ(Application::InternalState::Suspended, app->internalState());
1966
 
 
1967
 
    // Stop app
1968
 
    applicationManager.stopApplication(appId);
1969
 
    EXPECT_EQ(Application::InternalState::Closing, app->internalState());
1970
 
    EXPECT_EQ(SessionInterface::Running,  app->session()->state());
1971
 
}
1972
 
 
1973
 
/*
1974
 
 * Test that a application which fails to close will eventually be forceable closed.
1975
 
 */
1976
 
TEST_F(ApplicationManagerTests,failedApplicationCloseEventualyDeletesApplication)
 
1878
  Change focus between surfaces of different applications and check that
 
1879
  ApplicationManager::focusedApplicationId changes accordingly
 
1880
 */
 
1881
TEST_F(ApplicationManagerTests,focusedApplicationId)
1977
1882
{
1978
1883
    using namespace ::testing;
1979
1884
 
1980
1885
    int argc = 0;
1981
1886
    char* argv[0];
1982
 
    QCoreApplication qtApp(argc, argv); // app for deleteLater event
 
1887
    QCoreApplication qtApp(argc, argv);
 
1888
 
 
1889
    const QString appId1("testAppId1");
 
1890
    quint64 procId1 = 5551;
 
1891
    const QString appId2("testAppId2");
 
1892
    quint64 procId2 = 5552;
 
1893
 
 
1894
    ON_CALL(*taskController, primaryPidForAppId(appId1)).WillByDefault(Return(procId1));
 
1895
    ON_CALL(desktopFileReaderFactory, createInstance(appId1, _)).WillByDefault(Invoke(createMockDesktopFileReader));
 
1896
    ON_CALL(*taskController, primaryPidForAppId(appId2)).WillByDefault(Return(procId2));
 
1897
    ON_CALL(desktopFileReaderFactory, createInstance(appId2, _)).WillByDefault(Invoke(createMockDesktopFileReader));
 
1898
 
 
1899
    EXPECT_CALL(*taskController, start(appId1, _))
 
1900
        .Times(1)
 
1901
        .WillOnce(Return(true));
 
1902
 
 
1903
    auto app1 = applicationManager.startApplication(appId1);
 
1904
    applicationManager.onProcessStarting(appId1);
 
1905
    std::shared_ptr<mir::scene::Session> session1 = std::make_shared<MockSession>("", procId1);
 
1906
    bool authed = true;
 
1907
    applicationManager.authorizeSession(procId1, authed);
 
1908
    onSessionStarting(session1);
 
1909
 
 
1910
    FakeMirSurface *surface1 = new FakeMirSurface;
 
1911
    surface1->setSession(app1->session());
 
1912
    onSessionCreatedSurface(session1.get(), surface1);
 
1913
    surface1->drawFirstFrame();
 
1914
 
 
1915
    EXPECT_EQ(Application::InternalState::Running, app1->internalState());
 
1916
 
 
1917
    QSignalSpy focusedApplicationIdChangedSpy(&applicationManager,
 
1918
            &unityapi::ApplicationManagerInterface::focusedApplicationIdChanged);
 
1919
 
 
1920
    MirFocusController::instance()->setFocusedSurface(surface1);
 
1921
    qtApp.processEvents(); // process queued signal-slot connections
 
1922
 
 
1923
    EXPECT_EQ(1, focusedApplicationIdChangedSpy.count());
 
1924
    EXPECT_EQ(appId1, applicationManager.focusedApplicationId());
 
1925
 
 
1926
    EXPECT_CALL(*taskController, start(appId2, _))
 
1927
        .Times(1)
 
1928
        .WillOnce(Return(true));
 
1929
 
 
1930
    auto app2 = applicationManager.startApplication(appId2);
 
1931
    applicationManager.onProcessStarting(appId2);
 
1932
    std::shared_ptr<mir::scene::Session> session2 = std::make_shared<MockSession>("", procId2);
 
1933
    authed = true;
 
1934
    applicationManager.authorizeSession(procId2, authed);
 
1935
    onSessionStarting(session2);
 
1936
 
 
1937
    FakeMirSurface *surface2 = new FakeMirSurface;
 
1938
    surface2->setSession(app2->session());
 
1939
    onSessionCreatedSurface(session2.get(), surface2);
 
1940
    surface2->drawFirstFrame();
 
1941
 
 
1942
    EXPECT_EQ(Application::InternalState::Running, app2->internalState());
 
1943
 
 
1944
    MirFocusController::instance()->setFocusedSurface(surface2);
 
1945
    qtApp.processEvents(); // process queued signal-slot connections
 
1946
 
 
1947
    EXPECT_EQ(2, focusedApplicationIdChangedSpy.count());
 
1948
    EXPECT_EQ(appId2, applicationManager.focusedApplicationId());
 
1949
 
 
1950
    MirFocusController::instance()->setFocusedSurface(surface1);
 
1951
    qtApp.processEvents(); // process queued signal-slot connections
 
1952
 
 
1953
    EXPECT_EQ(3, focusedApplicationIdChangedSpy.count());
 
1954
    EXPECT_EQ(appId1, applicationManager.focusedApplicationId());
 
1955
 
 
1956
    // clean up
 
1957
    delete surface1;
 
1958
    delete surface2;
 
1959
}
 
1960
 
 
1961
/*
 
1962
 This is the compatibility mode between application-centric window management
 
1963
 and the new (proper) surface-based window management
 
1964
 
 
1965
 Whenever a surface request focus, its corresponding application should do likewise,
 
1966
 causing ApplicationManager::focusRequested(appId) to be emitted as well.
 
1967
 */
 
1968
TEST_F(ApplicationManagerTests,surfaceFocusRequestGeneratesApplicationFocusRequest)
 
1969
{
 
1970
    using namespace ::testing;
1983
1971
 
1984
1972
    const QString appId("testAppId");
1985
1973
    quint64 procId = 5551;
1986
1974
 
1987
 
    ON_CALL(procInfo,command_line(procId)).WillByDefault(Return(QByteArray("/usr/bin/testAppId")));
1988
 
    ON_CALL(*taskController,appIdHasProcessId(appId, procId)).WillByDefault(Return(true));
 
1975
    ON_CALL(*taskController, primaryPidForAppId(appId)).WillByDefault(Return(procId));
 
1976
    ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Invoke(createMockDesktopFileReader));
1989
1977
 
1990
 
    ON_CALL(desktopFileReaderFactory, createInstance(appId, _))
1991
 
        .WillByDefault(Invoke(
1992
 
            [](const QString &appId, const QFileInfo&) { return new FakeDesktopFileReader(appId); }
1993
 
        ));
 
1978
    EXPECT_CALL(*taskController, start(appId, _))
 
1979
        .Times(1)
 
1980
        .WillOnce(Return(true));
1994
1981
 
1995
1982
    auto app = applicationManager.startApplication(appId);
1996
1983
    applicationManager.onProcessStarting(appId);
2005
1992
 
2006
1993
    EXPECT_EQ(Application::InternalState::Running, app->internalState());
2007
1994
 
2008
 
    QSharedPointer<FakeTimeSource> fakeTimeSource(new FakeTimeSource);
2009
 
    FakeTimer *fakeCloseTimer = new FakeTimer(fakeTimeSource);
2010
 
    app->setCloseTimer(fakeCloseTimer);
2011
 
 
2012
 
    EXPECT_CALL(*taskController, stop(appId))
2013
 
        .Times(1)
2014
 
        .WillOnce(Invoke(
2015
 
            [this, session](const QString &appIdParam) {
2016
 
                // No point in emitting it as applicationManager is not connected to the taskController
2017
 
                // FIXME: Connect applicationManager to taskController so that we have a better test environment!
2018
 
                // In the meantime call the ApplicationManager method directly, emulating the missing
2019
 
                // signal-slot connection
2020
 
                // Q_EMIT taskController->processStopped(appIdParam);
2021
 
                onSessionStopping(session);
2022
 
                applicationManager.onProcessStopped(appIdParam);
2023
 
                return true;
2024
 
            }
2025
 
        ));
2026
 
 
2027
 
    QSignalSpy appDestroyedSpy(app, SIGNAL(destroyed(QObject*)));
2028
 
 
2029
 
    // Stop app
2030
 
    applicationManager.stopApplication(appId);
2031
 
 
2032
 
    if (fakeCloseTimer->isRunning()) {
2033
 
        // Simulate that closeTimer has timed out.
2034
 
        fakeTimeSource->m_msecsSinceReference = fakeCloseTimer->nextTimeoutTime() + 1;
2035
 
        fakeCloseTimer->update();
2036
 
    }
2037
 
 
2038
 
    // DeferredDelete is special: likes to be called out specifically or it won't come out
2039
 
    qtApp.sendPostedEvents(app, QEvent::DeferredDelete);
2040
 
    qtApp.sendPostedEvents();
2041
 
 
2042
 
    EXPECT_EQ(1, appDestroyedSpy.count());
2043
 
}
2044
 
 
2045
 
/*
2046
 
 * Test that an application that is suspended after its session is stopped is closed
2047
 
 */
2048
 
TEST_F(ApplicationManagerTests,CloseWhenSuspendedAfterSessionStopped)
2049
 
{
2050
 
    using namespace ::testing;
2051
 
 
2052
 
    const QString appId("testAppId");
2053
 
    quint64 procId = 5551;
2054
 
 
2055
 
    auto application = startApplication(procId, "testAppId");
2056
 
 
2057
 
    qtmir::Session* session(static_cast<qtmir::Session*>(application->session()));
2058
 
 
2059
 
    FakeMirSurface *surface = new FakeMirSurface;
2060
 
    onSessionCreatedSurface(session->session().get(), surface);
2061
 
    surface->drawFirstFrame();
2062
 
    EXPECT_EQ(Application::InternalState::Running, application->internalState());
2063
 
 
2064
 
    // session is suspended
2065
 
    application->setRequestedState(Application::RequestedSuspended);
2066
 
    EXPECT_EQ(Application::InternalState::SuspendingWaitSession, application->internalState());
2067
 
    session->doSuspend();
2068
 
    EXPECT_EQ(Application::InternalState::SuspendingWaitProcess, application->internalState());
2069
 
    session->setLive(false);
2070
 
    EXPECT_EQ(Application::InternalState::Closing, application->internalState());
2071
 
 
2072
 
    // The process can be suspended after the session has dissapeared.
2073
 
    applicationManager.onProcessSuspended(application->appId());
2074
 
    EXPECT_EQ(Application::InternalState::Closing, application->internalState());
2075
 
 
2076
 
    QSignalSpy spy(application, SIGNAL(stopped()));
2077
 
    applicationManager.onProcessStopped(application->appId());
2078
 
    EXPECT_EQ(Application::Stopped, application->state());
2079
 
    EXPECT_EQ(spy.count(), 1);
2080
 
}
2081
 
 
2082
 
/*
2083
 
 * Test that an application that fails while suspended will stop on close request
2084
 
 */
2085
 
TEST_F(ApplicationManagerTests,CloseWhenSuspendedProcessFailed)
2086
 
{
2087
 
    using namespace ::testing;
2088
 
 
2089
 
    const QString appId("testAppId");
2090
 
    quint64 procId = 5551;
2091
 
 
2092
 
    auto application = startApplication(procId, "testAppId");
2093
 
 
2094
 
    qtmir::Session* session(static_cast<qtmir::Session*>(application->session()));
2095
 
 
2096
 
    FakeMirSurface *surface = new FakeMirSurface;
2097
 
    onSessionCreatedSurface(session->session().get(), surface);
2098
 
    surface->drawFirstFrame();
2099
 
    EXPECT_EQ(Application::InternalState::Running, application->internalState());
2100
 
 
2101
 
    // Session is suspended
2102
 
    suspend(application);
2103
 
 
2104
 
    // Process failed
2105
 
    onSessionStopping(session->session());
2106
 
    applicationManager.onProcessFailed(appId, TaskController::Error::APPLICATION_FAILED_TO_START);
2107
 
    applicationManager.onProcessStopped(appId);
2108
 
    EXPECT_EQ(Application::InternalState::StoppedResumable, application->internalState());
2109
 
 
2110
 
    QSignalSpy spy(application, SIGNAL(stopped()));
2111
 
    application->close();
2112
 
 
2113
 
    EXPECT_EQ(Application::Stopped, application->state());
2114
 
    EXPECT_EQ(spy.count(), 1);
 
1995
    QSignalSpy focusRequestedSpy(&applicationManager,
 
1996
            &unityapi::ApplicationManagerInterface::focusRequested);
 
1997
 
 
1998
    surface->requestFocus();
 
1999
 
 
2000
    EXPECT_EQ(1, focusRequestedSpy.count());
2115
2001
}