on xenial help sign in
Fix the mess I made with the lifecycle of the mock Unity.Application singletons
commit81440538516cd9a1de6f350fad86a1c276d98353 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateThu 14 Apr 2016, 08:46 (11 years ago) parent2efb344
7 files changed+40−45
tests/mocks/Unity/Application/ApplicationInfo.cpp+3 tests/mocks/Unity/Application/ApplicationManager.cpp+2−16 tests/mocks/Unity/Application/ApplicationManager.h−4 tests/mocks/Unity/Application/MirSurface.cpp+4 tests/mocks/Unity/Application/UbuntuKeyboardInfo.cpp−2 tests/mocks/Unity/Application/UbuntuKeyboardInfo.h−9 tests/mocks/Unity/Application/plugin.cpp+31−14
tests/mocks/Unity/Application/ApplicationInfo.cpp+3
@@ -50,6 +50,8 @@ QString stateToStr(ApplicationInfo::State state)
5050#define DEBUG_MSG(params) ((void)0)
5151#endif
5252
53+#define WARNING_MSG(params) qWarning().nospace() << "Application["<<appId()<<"]::" << __func__ << " " << params
54+
5355ApplicationInfo::ApplicationInfo(const QString &appId, QObject *parent)
5456 : ApplicationInfoInterface(appId, parent)
5557 , m_appId(appId)
@@ -82,6 +84,7 @@ void ApplicationInfo::createSurface()
8284
8385 auto surfaceManager = SurfaceManager::instance();
8486 if (!surfaceManager) {
87+ WARNING_MSG("No SurfaceManager");
8588 return;
8689 }
8790
tests/mocks/Unity/Application/ApplicationManager.cpp+2−16
@@ -40,25 +40,10 @@
4040
4141namespace unityapi = unity::shell::application;
4242
43−ApplicationManager *ApplicationManager::the_application_manager = nullptr;
44−
45−ApplicationManager *ApplicationManager::singleton()
46−{
47− if (!the_application_manager) {
48− the_application_manager = new ApplicationManager();
49−
50− // Emit signal to notify Upstart that Mir is ready to receive client connections
51− // see http://upstart.ubuntu.com/cookbook/#expect-stop
52− if (qgetenv("UNITY_MIR_EMITS_SIGSTOP") == "1") {
53− raise(SIGSTOP);
54− }
55− }
56− return the_application_manager;
57−}
58−
5943ApplicationManager::ApplicationManager(QObject *parent)
6044 : ApplicationManagerInterface(parent)
6145{
46+ DEBUG_MSG("");
6247 buildListOfAvailableApplications();
6348
6449 // polling to find out when the toplevel window has been created as there's
@@ -68,6 +53,7 @@ ApplicationManager::ApplicationManager(QObject *parent)
6853 m_windowCreatedTimer.setSingleShot(false);
6954 m_windowCreatedTimer.start(200);
7055
56+ Q_ASSERT(MirFocusController::instance());
7157 connect(MirFocusController::instance(), &MirFocusController::focusedSurfaceChanged,
7258 this, &ApplicationManager::updateFocusedApplication, Qt::QueuedConnection);
7359}
tests/mocks/Unity/Application/ApplicationManager.h−4
@@ -47,8 +47,6 @@ class ApplicationManager : public ApplicationManagerInterface {
4747 ApplicationManager(QObject *parent = nullptr);
4848 virtual ~ApplicationManager();
4949
50− static ApplicationManager *singleton();
51−
5250 // QAbstractItemModel methods.
5351 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
5452 QVariant data(const QModelIndex& index, int role) const override;
@@ -90,8 +88,6 @@ class ApplicationManager : public ApplicationManagerInterface {
9088 QList<ApplicationInfo*> m_runningApplications;
9189 QList<ApplicationInfo*> m_availableApplications;
9290 QTimer m_windowCreatedTimer;
93−
94− static ApplicationManager *the_application_manager;
9591};
9692
9793Q_DECLARE_METATYPE(ApplicationManager*)
tests/mocks/Unity/Application/MirSurface.cpp+4
@@ -93,6 +93,7 @@ MirSurface::~MirSurface()
9393{
9494 DEBUG_MSG("");
9595
96+ // controller instance might have been already destroyed by QQmlEngine destructor
9697 auto controller = MirFocusController::instance();
9798 if (controller && controller->focusedSurface() == this) {
9899 controller->clear();
@@ -437,6 +438,7 @@ void MirSurface::setFocused(bool value)
437438 DEBUG_MSG(value);
438439
439440 auto controller = MirFocusController::instance();
441+ // controller instance might have been already destroyed by QQmlEngine destructor
440442 if (!controller) {
441443 return;
442444 }
@@ -452,6 +454,7 @@ bool MirSurface::focused() const
452454{
453455 auto controller = MirFocusController::instance();
454456
457+ // controller instance might have been already destroyed by QQmlEngine destructor
455458 return controller ? controller->focusedSurface() == this : false;
456459}
457460
@@ -490,6 +493,7 @@ MirFocusController* MirFocusController::instance()
490493
491494MirFocusController::MirFocusController()
492495{
496+ DEBUG_MSG("");
493497 Q_ASSERT(m_instance == nullptr);
494498 m_instance = this;
495499}
tests/mocks/Unity/Application/UbuntuKeyboardInfo.cpp−2
@@ -16,8 +16,6 @@
1616
1717#include "UbuntuKeyboardInfo.h"
1818
19−UbuntuKeyboardInfo *UbuntuKeyboardInfo::m_instance = nullptr;
20−
2119UbuntuKeyboardInfo::UbuntuKeyboardInfo(QObject *parent)
2220 : QObject(parent),
2321 m_x(0),
tests/mocks/Unity/Application/UbuntuKeyboardInfo.h−9
@@ -40,13 +40,6 @@ public:
4040 void setWidth(qreal value);
4141 void setHeight(qreal value);
4242
43− static UbuntuKeyboardInfo *singleton() {
44− if (!m_instance) {
45− m_instance = new UbuntuKeyboardInfo;
46− }
47− return m_instance;
48− }
49−
5043Q_SIGNALS:
5144 void xChanged(qreal x);
5245 void yChanged(qreal y);
@@ -59,8 +52,6 @@ private:
5952 qint32 m_y;
6053 qint32 m_width;
6154 qint32 m_height;
62−
63− static UbuntuKeyboardInfo *m_instance;
6455};
6556
6657#endif // UBUNTU_KEYBOARD_INFO_H
tests/mocks/Unity/Application/plugin.cpp+31−14
@@ -27,29 +27,46 @@
2727#include <qqml.h>
2828#include <QQmlEngine>
2929
30−static QObject* applicationManagerSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
31− Q_UNUSED(engine);
32− Q_UNUSED(scriptEngine);
33− return ApplicationManager::singleton();
30+namespace {
31+
32+// Creates the singletons that are called throughout C++ code
33+void createUnityApplicationSharedSingletons()
34+{
35+ // they have to be created in a specific order
36+ if (!MirFocusController::instance()) {
37+ new MirFocusController;
38+ }
39+ if (!SurfaceManager::instance()) {
40+ new SurfaceManager;
41+ }
42+}
43+
44+QObject* applicationManagerSingleton(QQmlEngine*, QJSEngine*)
45+{
46+ createUnityApplicationSharedSingletons();
47+ return new ApplicationManager;
3448}
3549
36−static QObject* surfaceManagerSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
37− Q_UNUSED(engine);
38− Q_UNUSED(scriptEngine);
39− // QQmlEngine takes ownership over it (ie, it's deleted on ~QQmlEngine)
40− return new SurfaceManager;
50+QObject* surfaceManagerSingleton(QQmlEngine*, QJSEngine*)
51+{
52+ createUnityApplicationSharedSingletons();
53+ return SurfaceManager::instance();
4154}
4255
43−static QObject* ubuntuKeyboardInfoSingleton(QQmlEngine*, QJSEngine*) {
44− return UbuntuKeyboardInfo::singleton();
56+QObject* ubuntuKeyboardInfoSingleton(QQmlEngine*, QJSEngine*)
57+{
58+ createUnityApplicationSharedSingletons();
59+ return new UbuntuKeyboardInfo;
4560}
4661
47−static QObject* mirFocusControllerSingleton(QQmlEngine*, QJSEngine*)
62+QObject* mirFocusControllerSingleton(QQmlEngine*, QJSEngine*)
4863{
49− // QQmlEngine takes ownership over it (ie, it's deleted on ~QQmlEngine)
50− return new MirFocusController;
64+ createUnityApplicationSharedSingletons();
65+ return MirFocusController::instance();
5166}
5267
68+} // anonymous namespace
69+
5370void FakeUnityApplicationQmlPlugin::registerTypes(const char *uri)
5471{
5572 qRegisterMetaType<ApplicationInfo*>("ApplicationInfo*");