2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.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
9 // http://floralicense.org/license/
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.
19 * @file NfcMessagePushDelegate.cpp
20 * @brief This is the implementation file for the %NfcMessagePushDelegate class.
23 #include <unique_ptr.h>
25 #include <vconf-internal-nfc-keys.h>
26 #include <vconf-internal-setting-keys.h>
27 #include <Ecore_Evas.h>
29 #include <app_manager.h>
30 #include <FAppAppControl.h>
31 #include <FAppAppManager.h>
32 #include <FBaseSysLog.h>
33 #include <FBaseByteBuffer.h>
34 #include <FBaseUtilStringUtil.h>
35 #include <FBaseColArrayList.h>
37 #include <FIoFileAttributes.h>
38 #include "NfcMessagePushDelegate.h"
39 #include "NfcMessageRegisterService.h"
42 using namespace Tizen::Base;
43 using namespace Tizen::Base::Utility;
44 using namespace Tizen::App;
45 using namespace Tizen::Io;
46 using namespace Tizen::Base::Collection;
48 const wchar_t* NfcMessagePushDelegate::_NFC_PUSH_UI_AC_PROVIDER_ID = L"http://tizen.org/appcontrol/provider/nfcpushui";
49 const wchar_t* NfcMessagePushDelegate::_NFC_PUSH_UI_AC_OPERATION_ID = L"http://tizen.org/appcontrol/operation/nfc/animation/show";
53 void operator()(char* pChar)
59 NfcMessagePushDelegate::NfcMessagePushDelegate(void)
60 : __isPushEnabled(false)
61 , __p2pTargetHandle(null)
63 // Checks whether the reserved push feature is enabled or disabled
66 // set vconf callback about the Reserved Push setting
67 vconf_notify_key_changed(VCONFKEY_NFC_PREDEFINED_ITEM_STATE, OnNfcReservedPushStateChanged, this);
70 NfcMessagePushDelegate::~NfcMessagePushDelegate(void)
73 // unset vconf callback
74 vconf_ignore_key_changed(VCONFKEY_NFC_PREDEFINED_ITEM_STATE, OnNfcReservedPushStateChanged);
78 NfcMessagePushDelegate::Initialize(void)
80 // set NFC target discovered callback
81 nfc_manager_set_p2p_target_discovered_cb(&OnNfcDeviceDiscovered, this);
85 NfcMessagePushDelegate::Deinitialize(void)
87 nfc_manager_unset_p2p_target_discovered_cb();
91 NfcMessagePushDelegate::UpdatePushEnabled(void)
96 // get the value for the predefined item
97 vconfRes = vconf_get_bool(VCONFKEY_NFC_PREDEFINED_ITEM_STATE, &isEnabled);
98 SysTryReturnVoidResult(NID_NET_NFC, vconfRes == 0, E_SYSTEM,
99 "[E_SYSTEM] Failed to get the vconf - reserved push state - value.");
101 __isPushEnabled = (isEnabled == 0) ? false : true;
103 SysLog(NID_NET_NFC, "The Reserved Push is %s.", __isPushEnabled ? "enabled" : "disabled");
107 NfcMessagePushDelegate::IsHomeScreenAtTopmost(void)
109 // unique_ptr<char, _CharDeleter> pHomeScreenId;
110 unique_ptr<char, _CharDeleter> pHomeMenuId;
111 char* pTopmostAppId = 0;
112 Ecore_X_Window activeWin = 0;
114 Eina_Bool ecoreRes = EINA_FALSE;
115 int appRes = APP_MANAGER_ERROR_NONE;
116 bool thisRes = false;
118 // get the value for the home menu app id
119 pHomeMenuId.reset(vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME));
120 SysTryReturn(NID_NET_NFC, pHomeMenuId != null, false, E_SYSTEM, "[E_SYSTEM] Failed to get the Home Menu App ID.");
121 SysLog(NID_NET_NFC, "Home Menu ID: %s", pHomeMenuId.get());
123 // get the value for the home screen app id
124 // TODO: block the below code for preventing build error in RSA because the specified vconf key is not defined in RSA
125 // pHomeScreenId.reset(vconf_get_str(VCONFKEY_SETAPPL_SELECTED_HOMESCREEN_PACKAGE_NAME));
126 // SysTryReturn(NID_NET_NFC, pHomeScreenId != null, false, E_SYSTEM, "[E_SYSTEM] Failed to get the Home Screen App ID.");
127 // SysLog(NID_NET_NFC, "Home Screen ID: %s", pHomeScreenId.get());
129 // get the topmost (focused) window
130 activeWin = ecore_x_window_focus_get();
132 // get the PID(process ID) of the topmost window
133 ecoreRes = ecore_x_netwm_pid_get(activeWin, &winPid);
134 SysTryReturn(NID_NET_NFC, ecoreRes == EINA_TRUE, false, E_SYSTEM, "[E_SYSTEM] Failed to get the PID of the active window.");
136 // get the App ID of the topmost window through PID
137 appRes = app_manager_get_app_id(winPid, &pTopmostAppId);
138 SysTryReturn(NID_NET_NFC, (appRes == APP_MANAGER_ERROR_NONE) && (pTopmostAppId != null), false, E_SYSTEM,
139 "[E_SYSTEM] Failed to get the topmost app ID.");
140 SysLog(NID_NET_NFC, "Topmost App ID: %s", pTopmostAppId);
142 // compare the topmost App ID with the Home screen App ID and the Home menu App ID
143 // TODO: block the below conditions for preventing build error in RSA
144 // if ((strcmp(pHomeScreenId.get(), pTopmostAppId) == 0) || (strcmp(pHomeMenuId.get(), pTopmostAppId) == 0))
145 if (strcmp(pHomeMenuId.get(), pTopmostAppId) == 0)
147 SysLog(NID_NET_NFC, "Home screen or Home menu is the topmost running app.");
157 NfcMessagePushDelegate::SendReservedMessage(nfc_p2p_target_h targetH)
159 ByteBuffer messageBuffer;
160 int nfcRes = NFC_ERROR_NONE;
161 result r = E_SUCCESS;
163 FileAttributes msgFileAttr;
165 nfc_ndef_message_h ndefMessageH = NULL;
166 char* pSelectedItem = null;
167 String selectedItemStr;
169 // get the value for the predefined item
170 pSelectedItem = vconf_get_str(VCONFKEY_NFC_PREDEFINED_ITEM);
171 SysTryReturnVoidResult(NID_NET_NFC, pSelectedItem != null, E_SYSTEM,
172 "[E_SYSTEM] Failed to get the selected item among the item list.");
174 selectedItemStr = String(pSelectedItem);
176 SysLog(NID_NET_NFC, "Try to send the reserved NDEF message (ID: %ls) to the detected peer device...",
177 selectedItemStr.GetPointer());
179 // make the push message file path which consists of the directory path, appId as the name, and "ndef" as the extension.
180 msgFilePath = NfcMessageRegisterService::_PUSH_MESSAGE_DIRECTORY + selectedItemStr +
181 NfcMessageRegisterService::_PUSH_MESSAGE_EXT_NAME;
183 // create a ByteBuffer instance to fill the content of the message file into it.
184 r = File::GetAttributes(msgFilePath, msgFileAttr);
185 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, E_OPERATION_FAILED,
186 "[E_OPERATION_FAILED] Getting the size of the NDEF message file has failed. (File path: %ls)",
187 msgFilePath.GetPointer());
189 r = messageBuffer.Construct(msgFileAttr.GetFileSize());
190 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, E_OPERATION_FAILED,
191 "[E_OPERATION_FAILED] Construction of the ByteBuffer for reading has failed.");
193 // get NdefMessage from the file
194 r = msgFile.Construct(msgFilePath, L"r");
195 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, E_OPERATION_FAILED,
196 "[E_OPERATION_FAILED] Construction of the push message file for reading has failed. (File path: %ls)",
197 msgFilePath.GetPointer());
199 r = msgFile.Read(messageBuffer);
200 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, E_OPERATION_FAILED,
201 "[E_OPERATION_FAILED] Reading the NDEF message file has failed.");
202 messageBuffer.Flip();
204 SysLog(NID_NET_NFC, "Reading the reserved NDEF message is successful.");
206 // send the reserved NDEF message as a raw format - byte array type.
207 nfcRes = nfc_ndef_message_create_from_rawdata(&ndefMessageH, messageBuffer.GetPointer() + messageBuffer.GetPosition(),
208 messageBuffer.GetRemaining());
209 SysTryReturnVoidResult(NID_NET_NFC, nfcRes == NFC_ERROR_NONE, E_OPERATION_FAILED,
210 "[E_OPERATION_FAILED] Failed to convert raw data to NDEF message [0x%08X].", nfcRes);
212 nfcRes = nfc_p2p_send(targetH, ndefMessageH, &OnNdefMessageSent, null);
213 nfc_ndef_message_destroy(ndefMessageH); // free the resources. (the result is ignored)
214 SysTryReturnVoidResult(NID_NET_NFC, nfcRes == NFC_ERROR_NONE, E_OPERATION_FAILED,
215 "[E_OPERATION_FAILED] Failed to send the NDEF message [0x%08X].", nfcRes);
217 SysLog(NID_NET_NFC, "Sending the reserved NDEF message is successfully started.");
221 NfcMessagePushDelegate::InvokeNfcPushUiAppControl(const String& iconPath, const String& appName, const String& description)
223 result r = E_SUCCESS;
224 std::unique_ptr<ArrayList> pDataList;
225 std::unique_ptr<String> pData1;
226 std::unique_ptr<String> pData2;
227 std::unique_ptr<String> pData3;
228 std::unique_ptr<AppControl> pAc;
230 // array list for args
231 pDataList.reset(new (std::nothrow) ArrayList());
232 SysTryReturnVoidResult(NID_NET_NFC, pDataList != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
233 r = pDataList->Construct();
234 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r, "[%s] An unexpected error has occurred.", GetErrorMessage(r));
237 pData1.reset(new (std::nothrow) String(L"iconPath:"));
238 SysTryReturnVoidResult(NID_NET_NFC, pData1 != null, E_OUT_OF_MEMORY, "Insufficient memory.");
239 r = pData1->Append(iconPath);
240 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r,
241 "[%s] exception occurred. Failed to make a parameter for icon path.", GetErrorMessage(r));
242 r = pDataList->Add(*pData1);
243 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r,
244 "[%s] exception occurred. Failed to make a parameter for icon path.", GetErrorMessage(r));
247 pData2.reset(new (std::nothrow) String(L"appName:"));
248 SysTryReturnVoidResult(NID_NET_NFC, pData2 != null, E_OUT_OF_MEMORY, "[%s] Insufficient memory.", GetErrorMessage(r));
249 r = pData2->Append(appName);
250 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r,
251 "[%s] exception occurred. Failed to make a parameter for app name.", GetErrorMessage(r));
252 r = pDataList->Add(*pData2);
253 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r,
254 "[%s] exception occurred. Failed to make a parameter for app name.", GetErrorMessage(r));
257 pData3.reset(new (std::nothrow) String(L"description:"));
258 SysTryReturnVoidResult(NID_NET_NFC, pData3 != null, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
259 r = pData3->Append(description);
260 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r,
261 "[%s] exception occurred. Failed to make a parameter for description.", GetErrorMessage(r));
262 r = pDataList->Add(*pData3);
263 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r,
264 "[%s] exception occurred. Failed to make a parameter for description.", GetErrorMessage(r));
267 pAc.reset(AppManager::FindAppControlN(_NFC_PUSH_UI_AC_PROVIDER_ID, _NFC_PUSH_UI_AC_OPERATION_ID));
268 SysTryReturnVoidResult(NID_NET_NFC, pAc != null, GetLastResult(),
269 "[%s] exception occurred. Failed to find app control.", GetErrorMessage(GetLastResult()));
272 r = pAc->Start(pDataList.get(), this);
273 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r,
274 "[%s] exception occurred. Failed to start app control", GetErrorMessage(r));
280 NfcMessagePushDelegate::OnNfcDeviceDiscovered(nfc_discovered_type_e type, nfc_p2p_target_h target, void* pUserData)
282 NfcMessagePushDelegate* pDelegate = null;
284 pDelegate = static_cast<NfcMessagePushDelegate*>(pUserData);
286 if(type == NFC_DISCOVERED_TYPE_ATTACHED)
288 SysLog(NID_NET_NFC, "NFC peer device is detected. (Reserved Push is %s)",
289 pDelegate->__isPushEnabled ? "ENABLED" : "DISABLED");
290 if ((target != NULL) && pDelegate->__isPushEnabled && pDelegate->IsHomeScreenAtTopmost())
292 // set p2p target handle
293 pDelegate->__p2pTargetHandle = target;
295 ////////////////////////////////////////////////////////////////////////////////
296 // TODO. invoke app control. This should uncommented soon.
297 ////////////////////////////////////////////////////////////////////////////////
298 // SysLog(NID_NET_NFC, "invoking app control...");
299 // pDelegate->InvokeNfcPushUiAppControl(L"temporary/icon/path/", L"app name", L"this is app description.");
300 ////////////////////////////////////////////////////////////////////////////////
303 else if (type == NFC_DISCOVERED_TYPE_DETACHED)
305 SysLog(NID_NET_NFC, "NFC peer device is lost.");
306 pDelegate->__p2pTargetHandle = null;
308 // ignore other cases
311 //-----------------------------------------------------------------------------------------------------------------------
312 // VCONFKEY_NFC_PREDEFINED_ITEM_STATE "db/nfc/predefined_item_state /* Enable or disable the Reserved Push feature */
313 //-----------------------------------------------------------------------------------------------------------------------
315 NfcMessagePushDelegate::OnNfcReservedPushStateChanged(keynode_t* pKeyNode, void* pUserData)
317 char* pKeyStr = null;
318 NfcMessagePushDelegate* pDelegate = null;
320 SysLog(NID_NET_NFC, "The key changed event (VCONFKEY_NFC_PREDEFINED_ITEM_STATE) is invoked.");
322 // check the key name
323 pKeyStr = vconf_keynode_get_name(pKeyNode);
324 SysTryReturnVoidResult(NID_NET_NFC, pKeyStr != null, E_SYSTEM, "[E_SYSTEM] Failed to get the vconf pKeyNode name.");
325 SysTryReturnVoidResult(NID_NET_NFC, strcmp(pKeyStr, VCONFKEY_NFC_PREDEFINED_ITEM_STATE) == 0, E_SYSTEM,
326 "[E_SYSTEM] the vconf key name is not about the state for Reserved Push.");
328 pDelegate = static_cast<NfcMessagePushDelegate*>(pUserData);
329 pDelegate->UpdatePushEnabled();
333 NfcMessagePushDelegate::OnNdefMessageSent(nfc_error_e res, void* pUserData)
335 SysTryReturnVoidResult(NID_NET_NFC, res == NFC_ERROR_NONE, E_OPERATION_FAILED,
336 "[E_OPERATION_FAILED] Sending the NDEF Message has failed [0x%08X].", res);
338 SysLog(NID_NET_NFC, "The NDEF Message has successfully sent to the target device.");
342 NfcMessagePushDelegate::OnAppControlCompleted(const Tizen::Base::String& providerId, const Tizen::Base::String& operationId, const Tizen::Base::Collection::IList* pResultList)
344 result r = E_SUCCESS;
345 String* pAppControlResult = null;
347 if (providerId == _NFC_PUSH_UI_AC_PROVIDER_ID && operationId == _NFC_PUSH_UI_AC_OPERATION_ID)
349 SysTryReturnVoidResult(NID_NET_NFC, pResultList != null, E_OPERATION_FAILED,
350 "[E_OPERATION_FAILED] NfcPushUi app control completed. But no result come.");
352 pAppControlResult = (Tizen::Base::String*)(pResultList->GetAt(0));
353 SysTryReturnVoidResult(NID_NET_NFC, pAppControlResult != null, E_OPERATION_FAILED,
354 "[E_OPERATION_FAILED] There is no result in the array list.");
356 // check the app control result
357 if (pAppControlResult->Equals(APPCONTROL_RESULT_SUCCEEDED))
359 SysLog(NID_NET_NFC, "APPCONTROL_RESULT_SUCCEEDED was come.");
360 SysTryReturnVoidResult(NID_NET_NFC, __p2pTargetHandle != null, E_OPERATION_FAILED,
361 "[E_OPERATION_FAILED] There is no attached device.");
363 // send reserved NDEF message
364 SendReservedMessage(__p2pTargetHandle);
366 SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r,
367 "[%s] Sending of the reserved push message file has failed.", GetErrorMessage(r));
369 else if (pAppControlResult->Equals(APPCONTROL_RESULT_CANCELED))
371 SysLog(NID_NET_NFC, "APPCONTROL_RESULT_CANCELED was come.");
373 else if (pAppControlResult->Equals(APPCONTROL_RESULT_FAILED))
375 SysLog(NID_NET_NFC, "APPCONTROL_RESULT_FAILED was come.");