~aleteoryx/muditaos

ref: 6bbef804c0605b90a3aff579376e9ea940733238 muditaos/module-services/service-appmgr/ApplicationManager.hpp -rw-r--r-- 6.8 KiB
6bbef804 — Michał Kamoń [EGD-4284] missing include added (#956) 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <memory>      // for unique_ptr, allocator
#include <string>      // for string
#include <deque>       // for deque
#include <string_view> // for string_view
#include <vector>      // for vector

#include "Application.hpp"         // for Application, Application::State
#include "ApplicationLauncher.hpp" // for ApplicationLauncher
#include "messages/APMMessage.hpp"
#include "Service/Common.hpp"  // for ReturnCodes, ServicePowerMode
#include "Service/Message.hpp" // for Message_t, DataMessage (ptr only), ResponseMessage (ptr only)
#include "Service/Service.hpp" // for Service
#include "Service/Timer.hpp"   // for Timer
#include "SettingsRecord.hpp"  // for SettingsRecord
#include "SwitchData.hpp"      // for SwitchData

namespace app
{
    class ApplicationLauncher;
    namespace manager
    {
        class APMAction;
        class APMChangeLanguage;
        class APMConfirmClose;
        class APMConfirmSwitch;
        class APMRegister;
        class APMSwitch;
        class APMSwitchPrevApp;
    } // namespace manager
}

namespace app::manager
{
    class ApplicationHandle
    {
      public:
        static inline constexpr std::string_view InvalidAppName{"NONE"};

        using State = app::Application::State;
        using Name  = std::string;

        explicit ApplicationHandle(std::unique_ptr<app::ApplicationLauncher> &&_launcher);

        void setState(State state) noexcept;
        void run(sys::Service *caller);
        void runInBackground(sys::Service *caller);

        auto name() const -> Name;
        auto state() const noexcept -> State;
        auto preventsBlocking() const noexcept -> bool;
        auto closeable() const noexcept -> bool;
        auto started() const noexcept -> bool;

        std::unique_ptr<app::ApplicationLauncher> launcher; // Handle to the application's start function.
        std::unique_ptr<gui::SwitchData> switchData;
        std::string switchWindow;
        bool blockClosing =
            false; //< Informs the application manager that this application mustn't be closed temporarily.
                   // This flag is used to prevent application closing when application is closeable and there is
                   // incoming call. This flag is also used when closeable application is on front and there is a
                   // timeout to block the application.
    };

    class ApplicationManagerBase
    {
      public:
        using ApplicationsContainer = std::vector<std::unique_ptr<ApplicationHandle>>;
        using ApplicationsStack     = std::deque<ApplicationHandle::Name>;
        enum class State
        {
            Running,
            AwaitingFocusConfirmation,
            AwaitingCloseConfirmation,
            AwaitingLostFocusConfirmation
        };

        explicit ApplicationManagerBase(std::vector<std::unique_ptr<app::ApplicationLauncher>> &&launchers);
        virtual ~ApplicationManagerBase() = default;

        void pushApplication(const ApplicationHandle::Name &name);
        void popApplication();
        void clearStack();

        auto getFocusedApplication() const noexcept -> ApplicationHandle *;
        auto getLaunchingApplication() const noexcept -> ApplicationHandle *;
        auto getPreviousApplication() const noexcept -> ApplicationHandle *;
        auto getApplication(const ApplicationHandle::Name &name) const noexcept -> ApplicationHandle *;
        auto getApplications() const noexcept -> const ApplicationsContainer &
        {
            return applications;
        }

        void setState(State _state) noexcept;
        auto getState() const noexcept -> State
        {
            return state;
        }

      private:
        State state = State::Running;
        ApplicationsContainer applications;
        ApplicationsStack stack;
    };

    class ApplicationManager : public sys::Service, private ApplicationManagerBase
    {
      public:
        static inline const std::string ServiceName = "ApplicationManager";

        ApplicationManager(const std::string &serviceName,
                           std::vector<std::unique_ptr<app::ApplicationLauncher>> &&launchers,
                           const ApplicationHandle::Name &_rootApplicationName);

        auto InitHandler() -> sys::ReturnCodes override;
        auto DeinitHandler() -> sys::ReturnCodes override;
        auto SwitchPowerModeHandler(const sys::ServicePowerMode mode) -> sys::ReturnCodes override;
        auto DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) -> sys::Message_t override;

      private:
        auto startApplication(ApplicationHandle &app) -> bool;
        void startSystemServices();
        void startBackgroundApplications();
        void rebuildActiveApplications();
        void suspendSystemServices();
        auto closeServices() -> bool;
        auto closeApplications() -> bool;
        void closeService(const std::string &name);

        // Message handlers
        void registerMessageHandlers();
        auto handleAction(APMAction *actionMsg) -> bool;
        auto handleSwitchApplication(APMSwitch *msg) -> bool;
        auto handleCloseConfirmation(APMConfirmClose *msg) -> bool;
        auto handleSwitchConfirmation(APMConfirmSwitch *msg) -> bool;
        auto handleSwitchBack(APMSwitchPrevApp *msg) -> bool;
        auto handleRegisterApplication(APMRegister *msg) -> bool;
        auto handleLanguageChange(APMChangeLanguage *msg) -> bool;
        auto handlePowerSavingModeInit() -> bool;

        void requestApplicationClose(ApplicationHandle &app, bool isCloseable);
        void onApplicationSwitch(ApplicationHandle &app,
                                 std::unique_ptr<gui::SwitchData> &&data,
                                 std::string targetWindow);
        void onApplicationSwitchToPrev(ApplicationHandle &previousApp,
                                       std::unique_ptr<gui::SwitchData> &&data,
                                       std::string targetWindow = {});
        void onApplicationRegistered(ApplicationHandle &app, bool startInBackground);
        void onApplicationRegistrationFailure(ApplicationHandle &app);
        auto onSwitchConfirmed(ApplicationHandle &app) -> bool;
        auto onCloseConfirmed(ApplicationHandle &app) -> bool;
        void onPhoneLocked();

        ApplicationHandle::Name rootApplicationName;
        SettingsRecord settings;
        std::unique_ptr<sys::Timer> blockingTimer; //< timer to count time from last user's activity. If it reaches time
                                                   // defined in settings database application
                                                   // manager is sending signal to power manager and changing window to
                                                   // the desktop window in the blocked state.
    };
} // namespace app::manager