fix window raise on AppControl result
[platform/framework/native/app-controls.git] / src / platform-app-control / PlatformAppControlEntry.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file         PlatformAppControlEntry.cpp
20  * @brief       This is the implementation for the PlatformAppControlEntry.cpp.
21  */
22
23 #include <FBaseSysLog.h>
24 #include <FBaseColHashMap.h>
25
26 #include <FApp_Aul.h>
27 #include <FApp_AppArg.h>
28 #include <FApp_AppControlManager.h>
29 #include <FApp_AppMessageImpl.h>
30 #include <FApp_AppControlImpl.h>
31 #include <FApp_IAppControlPluginProvider.h>
32 #include <FApp_RequestManagerT.h>
33
34 #include "FApp_RequestInfo.h"
35 #include "FApp_AppControlPluginUtil.h"
36 #include "FApp_AppControlTerminateHandler.h"
37
38
39 using namespace Tizen::App;
40 using namespace Tizen::Base;
41 using namespace Tizen::Base::Collection;
42
43
44 namespace
45 {
46
47 class _AppControlPlugin
48         : public _IAppControlPluginProvider
49         , virtual public Tizen::Base::Runtime::IEventListener
50 {
51 public:
52         _AppControlPlugin(void) { __handler.SetResultCallback(OnAppControlTerminate, this); }
53
54         virtual ~_AppControlPlugin(void) {}
55
56         virtual result StartAppControlPlugin(int req, const AppId& appId, const _AppMessageImpl& message, int* pPid);
57
58         virtual result StopAppControlPlugin(int req);
59
60         virtual result Release(void) { delete this; return E_SUCCESS; }
61
62         static void OnAppControlResult(void* b, int requestCode, service_result_e res, void* userData);
63
64         static void OnAppControlTerminate(int req, int pid, void* data);
65
66 private:
67         _RequestManagerT<_RequestInfo> __requestManager;
68         _AppControlTerminateHandler __handler;
69 };
70
71
72 result
73 _AppControlPlugin::StartAppControlPlugin(int req, const AppId& appId, const _AppMessageImpl& message, int* pPid)
74 {
75         SysLog(NID_APP, "StartAppControl for %ls.", appId.GetPointer());
76
77         AppSvcResFn pCb = NULL;
78
79         if (req >= 0)
80         {
81                 // if there is no listener, then req is -1.
82                 pCb = OnAppControlResult;
83                 __handler.AddHandler(req);
84         }
85
86         int pid = _AppControlManager::GetInstance()->Launch(message, pCb, this, req);
87
88         result r = GetLastResult();
89         SysTryReturnResult(NID_APP, pid >0, r, "System error.");
90
91         if (pPid)
92         {
93                 *pPid = pid;
94         }
95
96         // appId is empty for implicit AppControl launch.
97         _RequestInfo* pItem = new (std::nothrow) _RequestInfo(req, pid, appId, message.GetApplicationId(), message.GetOperation());
98         if (pItem)
99         {
100                 const int ret = __requestManager.InsertItem(pItem);
101                 SysLog(NID_APP, "Request is added with %d.", ret);
102         }
103
104         if (req >= 0)
105         {
106                 __handler.SetHandlerData(req, pid);
107         }
108
109         SysLog(NID_APP, "StartAppControl: Launching %ls AppControl succeeded for process %d.", appId.GetPointer(), pid);
110
111         return r;
112 }
113
114
115 result
116 _AppControlPlugin::StopAppControlPlugin(int req)
117 {
118         __handler.RemoveHandler(req);
119
120         _RequestInfo* pItem = __requestManager.FindItem(req);
121         SysTryReturnResult(NID_APP, pItem != null, E_SYSTEM, "No request found for %d.", req);
122
123         const int processId = pItem->processId;
124         if (processId <=0)
125         {
126                 SysLogException(NID_APP, E_SYSTEM, "Request %d has invalid state with %ls.", req, pItem->originalAppId.GetPointer());
127                 __requestManager.RemoveItem(req);
128                 return E_SUCCESS;
129         }
130
131         result r = _AppControlPluginUtil::SendStopRequest(processId);
132         if (IsFailed(r))
133         {
134                 SysLogException(NID_APP, E_INVALID_OPERATION, "Failed to send stop request to %d.", processId);
135         }
136
137         SysLog(NID_APP, "Process %d is terminated.", processId);
138
139         __requestManager.RemoveItem(req);
140
141         return r;
142 }
143
144
145 void
146 _AppControlPlugin::OnAppControlResult(void* b, int requestCode, service_result_e res, void* userData)
147 {
148         SysLog(NID_APP, "AppControl result received with req code %d.", requestCode);
149
150         result r = E_SYSTEM;
151         bundle* pBundle = static_cast<bundle*>(b);
152         _AppControlPlugin* pThis = static_cast<_AppControlPlugin*>(userData);
153         SysTryReturnVoidResult(NID_APP, pThis != null, E_SYSTEM, "[E_SYSTEM] Invalid state for request %d", requestCode);
154
155         pThis->__handler.RemoveHandler(requestCode);
156
157         HashMap* pResult = new (std::nothrow) HashMap();
158         SysTryReturnVoidResult(NID_APP, pResult != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
159
160         r = pResult->Construct();
161
162         _AppArg::SetArgMap(pBundle, pResult);
163
164         pThis->__requestManager.RemoveItem(requestCode);
165
166         const bool isSubMode = _AppArg::IsSubMode(pBundle);
167         _AppControlManager::GetInstance()->FinishAppControl(requestCode, res, L"", L"", pResult, (isSubMode) ? _APPCONTROL_PROPERTY_SUBMODE : 0);
168
169         SysLog(NID_APP, "Request %d is removed from the list successfully.", requestCode);
170 }
171
172
173 void
174 _AppControlPlugin::OnAppControlTerminate(int req, int pid, void* userData)
175 {
176         SysLog(NID_APP, "AppControl terminate event received with req code %d for process %d.", req, pid);
177
178         _AppControlPlugin* pThis = static_cast<_AppControlPlugin*>(userData);
179         if (pThis)
180         {
181                 pThis->__handler.RemoveHandler(req);
182                 pThis->__requestManager.RemoveItem(req);
183         }
184
185         // APPSVC_OSP_RES_TERMINATE matches APP_CTRL_RESULT_TERMINATED
186         _AppControlManager::GetInstance()->FinishAppControl(req, APPSVC_OSP_RES_TERMINATE, null);
187 }
188
189 }
190
191
192 extern "C" _OSP_EXPORT_ _IAppControlPluginProvider*
193 GetAppControlProviderPlugin(void)
194 {
195         return new (std::nothrow) _AppControlPlugin;
196 }
197