Fix prevent issue
[platform/framework/native/app-controls.git] / src / nfc-push-ui-app-control / src / NfcPushUiForm.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         NfcPushUiForm.cpp
20 * @brief        This file contains the implementation of NfcPushUiForm class.
21 */
22
23 #include <unique_ptr.h>
24 #include <FAppApp.h>
25 #include <FAppAppControl.h>
26 #include <FAppAppResource.h>
27 #include <FAppAppControlProviderManager.h>
28 #include <FUiAnimVisualElement.h>
29 #include <FUiSystemUtil.h>
30 #include <FUiAnimAnimationTransaction.h>
31 #include <FUiAnimEaseInOutTimingFunction.h>
32 #include <FUiAnimVisualElementPropertyAnimation.h>
33 #include <FBaseSysLog.h>
34 #include <FBaseColAllElementsDeleter.h>
35 #include <FIoFile.h>
36 #include <FMediaImage.h>
37 #include "NfcPushUiForm.h"
38
39 using namespace Tizen::Base;
40 using namespace Tizen::Base::Collection;
41 using namespace Tizen::App;
42 using namespace Tizen::Ui;
43 using namespace Tizen::Ui::Controls;
44 using namespace Tizen::Ui::Animations;
45 using namespace Tizen::Graphics;
46 using namespace Tizen::Net::Nfc;
47 using namespace Tizen::Media;
48
49 const int NfcPushUiForm::_DURATION_GROW_ = 667;
50 const int NfcPushUiForm::_DURATION_OPACITY_ = 497;
51 const int NfcPushUiForm::_DURATION_REPEAT_ = 516;
52 const int NfcPushUiForm::_DURATION_OPACITY2_ = 431;
53
54 NfcPushUiForm::NfcPushUiForm(void)
55         : __reqId(-1)
56         , __pCapturedScreen(null)
57         , __rect()
58         , __isCaptured(false)
59         , __iconPath()
60         , __description()
61         , __pNfcManager(null)
62         , __pVisualElementBounds(null)
63         , __pVisualElementOpacity(null)
64         , __pVisualElement(null)
65         , __startRect()
66         , __endRect()
67         , __startOpacity(0.0f)
68         , __endOpacity(0.0f)
69 {
70 }
71
72 NfcPushUiForm::~NfcPushUiForm(void)
73 {
74         delete __pCapturedScreen;
75         delete __pNfcManager;
76
77         if (__pVisualElement)
78         {
79                 __pVisualElement->Destroy();
80         }
81 }
82
83 bool
84 NfcPushUiForm::Initialize(RequestId reqId, const Tizen::Graphics::Rectangle& rect)
85 {
86         result r = E_SUCCESS;
87         std::unique_ptr<NfcManager> pNfcManager;
88
89         r = Construct(FORM_STYLE_NORMAL);
90         SysTryReturn(NID_NET_NFC, r == E_SUCCESS, false, r, "[%s] exception occurred.", GetErrorMessage(r));
91
92         // set app size
93         __rect = rect;
94
95         // set request ID
96         __reqId = reqId;
97
98         // NfcManager
99         pNfcManager.reset(new (std::nothrow) NfcManager());
100         SysTryCatch(NID_NET_NFC, pNfcManager != null, r = E_OUT_OF_MEMORY, r, "[%s] exception occurred.", GetErrorMessage(r));
101
102         // construct
103         r = pNfcManager->Construct(*this);
104         SysTryCatch(NID_NET_NFC, r == E_SUCCESS, , r, "[%s] exception occurred.", GetErrorMessage(r));
105
106         // set INfcDeviceDiscoveryEventListener
107         r = pNfcManager->AddDeviceDiscoveryEventListener(*this);
108         SysTryCatch(NID_NET_NFC, r == E_SUCCESS, , r, "[%s] exception occurred.", GetErrorMessage(r));
109
110         __pNfcManager = pNfcManager.release();
111
112         return true;
113
114 CATCH:
115         FinishAppControl(__reqId, APP_CTRL_RESULT_FAILED);
116         return false;
117 }
118
119 void
120 NfcPushUiForm::SetAppInfo(const String& iconPath, const String& description)
121 {
122         // icon path
123         if (Tizen::Io::File::IsFileExist(iconPath))
124         {
125                 __iconPath = iconPath;
126         }
127         else    // if icon path is empty, use default icon.
128         {
129                 SysLog(NID_NET_NFC, "There is not such icon. [%ls]", iconPath.GetPointer());
130                 __iconPath = App::GetInstance()->GetAppRootPath() + L"res/icon.png";
131                 SysLog(NID_NET_NFC, "So use default icon: [%ls]", __iconPath.GetPointer());
132         }
133
134         // description
135         __description = description;
136 }
137
138 result
139 NfcPushUiForm::OnInitializing(void)
140 {
141         result r = E_SUCCESS;
142
143         // touch event
144         AddTouchEventListener(*this);
145
146         // visual element
147         __pVisualElement = new (std::nothrow) VisualElement();
148         __pVisualElement->Construct();
149         __pVisualElement->SetName(L"VisualElement");
150         __pVisualElement->SetBounds(FloatRectangle(0.0f, 0.0f, 0.0f, 0.0f));
151         __pVisualElement->SetClipChildrenEnabled(false);
152         __pVisualElement->SetShowState(true);
153         GetVisualElement()->AttachChild(*__pVisualElement);
154
155         ////////////////////////////////////////////////////////////////////////////////
156         // bounds
157         ////////////////////////////////////////////////////////////////////////////////
158         __pVisualElementBounds = new (std::nothrow) VisualElement();
159         __pVisualElementBounds->Construct();
160         __pVisualElementBounds->SetName(L"Grow");
161         __pVisualElementBounds->SetBounds(FloatRectangle((__rect.width / 2.0f) - 75.0f, (__rect.height / 2.0f) - 75.0f, 150.0f, 150.0f));
162         __pVisualElementBounds->SetShowState(true);
163         __pVisualElementBounds->SetImplicitAnimationEnabled(false);
164         __pVisualElement->AttachChild(*__pVisualElementBounds);
165
166         __endRect = __pVisualElementBounds->GetBounds();
167         __startRect = FloatRectangle(__endRect.x + 75.0f, __endRect.y + 75.0f, 0, 0);
168
169         std::unique_ptr<Canvas> pCanvas(__pVisualElementBounds->GetCanvasN());
170         SysTryReturnResult(NID_NET_NFC, pCanvas != null, E_OUT_OF_MEMORY, "Failed to get canvas.");
171         pCanvas->SetForegroundColor(Color::GetColor(COLOR_ID_GREY));
172         pCanvas->SetLineStyle(LINE_STYLE_SOLID);
173         pCanvas->SetLineWidth(6);
174         pCanvas->DrawEllipse(Rectangle(25, 25, 100, 100));
175         pCanvas->SetLineWidth(4);
176         pCanvas->DrawEllipse(Rectangle(15, 15, 120, 120));
177         pCanvas->SetLineWidth(2);
178         pCanvas->DrawEllipse(Rectangle(5, 5, 140, 140));
179
180         __pVisualElementBounds->SetBounds(__startRect);
181
182         ////////////////////////////////////////////////////////////////////////////////
183         // Opacity rectangle
184         ////////////////////////////////////////////////////////////////////////////////
185         __pVisualElementOpacity = new (std::nothrow) VisualElement();
186         __pVisualElementOpacity->Construct();
187         __pVisualElementOpacity->SetName(L"Opacity");
188         __pVisualElementOpacity->SetBounds(FloatRectangle((__rect.width / 2) - 50, (__rect.height / 2) - 50, 100, 100));
189         __pVisualElementOpacity->SetShowState(true);
190         __pVisualElementOpacity->SetImplicitAnimationEnabled(false);
191         __pVisualElement->AttachChild(*__pVisualElementOpacity);
192
193         pCanvas.reset(__pVisualElementOpacity->GetCanvasN());
194         SysTryReturnResult(NID_NET_NFC, pCanvas != null, E_OUT_OF_MEMORY, "Failed to get canvas.");
195
196         std::unique_ptr<Bitmap> pBitmap;
197         Image image;
198
199         r = image.Construct();
200         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to construct an Image instance.");
201
202         // decode the bitmap
203         pBitmap.reset(image.DecodeN(__iconPath, BITMAP_PIXEL_FORMAT_ARGB8888));
204         SysTryReturnResult(NID_NET_NFC, pBitmap != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
205
206         // scale the bitmap
207         r = pBitmap->Scale(Dimension(100, 100));
208         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to scale the bitmap.");
209
210         __startOpacity = 0.0f;
211         __endOpacity = 1.0f;
212
213         // draw the bitmap
214         pCanvas->SetBackgroundColor(Color(0x00000000));
215         pCanvas->Clear();
216         r = pCanvas->DrawBitmap(Point(__rect.x, __rect.y), *pBitmap);
217         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to draw the bitmap.");
218
219         // set an opacity level
220         __pVisualElementOpacity->SetOpacity(__startOpacity);
221
222         SysLog(NID_NET_NFC, "start to play animation");
223         AnimationTransaction::Begin();
224         PlayBoundsAnimation(L"grow", 1, _DURATION_GROW_);
225         PlayOpacityAnimation(L"opacity", _DURATION_OPACITY_);
226         AnimationTransaction::Commit();
227
228         return r;
229 }
230
231 result
232 NfcPushUiForm::OnTerminating(void)
233 {
234         return E_SUCCESS;
235 }
236
237 result
238 NfcPushUiForm::OnDraw(void)
239 {
240         result r = E_SUCCESS;
241         Rectangle rect = GetClientAreaBounds();
242
243         if (__isCaptured == false)
244         {
245                 // get canvas from form
246                 r = CaptureScreen();
247                 SysTryCatch(NID_NET_NFC, r == E_SUCCESS, , r, "[%s] exception occurred.", GetErrorMessage(r));
248                 __isCaptured = true;
249         }
250
251         // captured screen
252         r = DrawBitmapToCanvas(rect);
253         SysTryCatch(NID_NET_NFC, r == E_SUCCESS, , r, "[%s] Failed to draw captured screen.", GetErrorMessage(r));
254
255         // guide text
256         r = DrawGuideTextToCanvas(rect);
257         SysTryCatch(NID_NET_NFC, r == E_SUCCESS, , r, "[%s] Failed to draw guide text.", GetErrorMessage(r));
258
259         // app info
260         r = DrawAppInfoToCanvas(rect);
261         SysTryCatch(NID_NET_NFC, r == E_SUCCESS, , r, "[%s] Failed to draw app info.", GetErrorMessage(r));
262
263         return r;
264
265 CATCH:
266         FinishAppControl(__reqId, APP_CTRL_RESULT_FAILED);
267         return r;
268 }
269
270 result
271 NfcPushUiForm::CaptureScreen(void)
272 {
273         if (__pCapturedScreen)
274         {
275                 delete __pCapturedScreen;
276                 __pCapturedScreen = null;
277         }
278
279         // capture the current screen
280         __pCapturedScreen = SystemUtil::CaptureScreenN();
281         SysTryReturnResult(NID_NET_NFC, __pCapturedScreen != null, GetLastResult(), "Failed to capture the screen.");
282
283         return E_SUCCESS;
284 }
285
286 result
287 NfcPushUiForm::DrawBitmapToCanvas(const Rectangle& rect)
288 {
289         result r = E_SUCCESS;
290         std::unique_ptr<Canvas> pCanvas;
291
292         // there should be a captured screen.
293         SysTryReturnResult(NID_NET_NFC, __pCapturedScreen != null, E_INVALID_STATE,
294                         "[E_INVALID_STATE] exception occurred. There is no captures screen.");
295
296         // get canvas
297         pCanvas.reset(GetCanvasN());
298         r = GetLastResult();
299         SysTryReturnResult(NID_NET_NFC, pCanvas != null, r,
300                         "[%s] exception occurred. Failed to get canvas instance.", GetErrorMessage(r));
301
302         // draw bitmap
303         r = pCanvas->DrawBitmap(rect, *__pCapturedScreen);
304         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r,
305                         "[%s] exception occurred. Failed to draw captured screen to canvas.", GetErrorMessage(r));
306
307         // darkening
308         r = pCanvas->FillRectangle(Color(0xC0000000), rect);
309         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r,
310                         "[%s] exception occurred. Failed to darken the captured screen.", GetErrorMessage(r));
311
312         return r;
313 }
314
315 result
316 NfcPushUiForm::DrawAppInfoToCanvas(const Tizen::Graphics::Rectangle& rect)
317 {
318         result r = E_SUCCESS;
319         const int textAreaWidth = rect.width;
320
321         std::unique_ptr<EnrichedText> pEnrichedText(new (std::nothrow) EnrichedText());
322         SysTryReturnResult(NID_NET_NFC, pEnrichedText != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
323
324         std::unique_ptr<TextElement> pTextElement(new (std::nothrow) TextElement());
325         SysTryReturnResult(NID_NET_NFC, pTextElement != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
326
327         r = pEnrichedText->Construct(Dimension(textAreaWidth, 200));
328         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to construct an enriched text.");
329
330         pEnrichedText->SetHorizontalAlignment(TEXT_ALIGNMENT_CENTER);
331         pEnrichedText->SetVerticalAlignment(TEXT_ALIGNMENT_MIDDLE);
332         pEnrichedText->SetTextWrapStyle(TEXT_WRAP_CHARACTER_WRAP);
333         pEnrichedText->SetTextAbbreviationEnabled(true);
334
335         // Creates a TextElement and sets attributes
336         r = pTextElement->Construct(__description);
337         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to construct a text element.");
338
339         pTextElement->SetTextColor(Color::GetColor(COLOR_ID_WHITE));
340         {
341                 Font font;
342                 font.Construct(FONT_STYLE_BOLD, 40);
343                 pTextElement->SetFont(font);
344         }
345
346         // Adds the TextElement and the bitmap to the EnrichedText
347         pEnrichedText->Add(*pTextElement);
348
349         // canvas
350         std::unique_ptr<Canvas> pCanvas(GetCanvasN());
351         SysTryReturnResult(NID_NET_NFC, pCanvas != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
352
353         // Draws the EnrichedText at the specified Point
354         pCanvas->DrawText(Point(0, (rect.height / 2) + 100), *pEnrichedText);
355
356         return r;
357 }
358
359 result
360 NfcPushUiForm::DrawGuideTextToCanvas(const Tizen::Graphics::Rectangle& rect)
361 {
362         result r = E_SUCCESS;
363         const int textAreaWidth = rect.width;
364         String sendNotiStr(L"Tap to send");
365         AppResource* pAppResource = App::GetInstance()->GetAppResource();
366
367         if (pAppResource)
368         {
369                 pAppResource->GetString(L"IDS_NFC_BODY_TAP_TO_SEND", sendNotiStr);
370         }
371
372         std::unique_ptr<EnrichedText> pEnrichedText(new (std::nothrow) EnrichedText());
373         SysTryReturnResult(NID_NET_NFC, pEnrichedText != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
374
375         std::unique_ptr<TextElement> pTextElement(new (std::nothrow) TextElement());
376         SysTryReturnResult(NID_NET_NFC, pTextElement != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
377
378         r = pEnrichedText->Construct(Dimension(textAreaWidth, 100));
379         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to construct an enriched text.");
380
381         r = pEnrichedText->SetHorizontalAlignment(TEXT_ALIGNMENT_CENTER);
382         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to set horizontal alignment.");
383
384         pEnrichedText->SetVerticalAlignment(TEXT_ALIGNMENT_MIDDLE);
385         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to set vertical alignment.");
386
387         pEnrichedText->SetTextWrapStyle(TEXT_WRAP_CHARACTER_WRAP);
388         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to set text wrap style.");
389
390         pEnrichedText->SetTextAbbreviationEnabled(true);
391         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to set abbreviation enabled.");
392
393         // Creates a TextElement and sets attributes
394         r = pTextElement->Construct(sendNotiStr);
395         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to construct a text element.");
396
397         pTextElement->SetTextColor(Color::GetColor(COLOR_ID_WHITE));
398         {
399                 Font font;
400                 font.Construct(FONT_STYLE_BOLD, 40);
401                 pTextElement->SetFont(font);
402         }
403
404         // Adds the TextElement and the bitmap to the EnrichedText
405         r = pEnrichedText->Add(*pTextElement);
406         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to add text element to enriched text.");
407
408         // canvas
409         std::unique_ptr<Canvas> pCanvas(GetCanvasN());
410         SysTryReturnResult(NID_NET_NFC, pCanvas != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
411
412         // Draws the EnrichedText at the specified Point
413         r = pCanvas->DrawText(Point((rect.width - textAreaWidth) / 2, (int)(rect.height / 4)), *pEnrichedText);
414         SysTryReturnResult(NID_NET_NFC, r == E_SUCCESS, r, "Failed to draw text to canvas.");
415
416         return r;
417 }
418
419 void
420 NfcPushUiForm::PlayBoundsAnimation(const Tizen::Base::String& animationName, int repeatCount, int duration, bool autoReverse)
421 {
422         std::unique_ptr<EaseInOutTimingFunction> pTimingFunction;
423         std::unique_ptr<VisualElementPropertyAnimation> pAnimation(new (std::nothrow) VisualElementPropertyAnimation());
424         SysTryReturnVoidResult(NID_NET_NFC, pAnimation != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
425
426         // bounds
427         pAnimation->SetPropertyName(L"bounds");
428         pAnimation->SetStartValue(Variant(__startRect));
429         pAnimation->SetEndValue(Variant(__endRect));
430         pAnimation->SetDuration(duration);
431         pAnimation->SetRepeatCount(repeatCount);
432         pAnimation->SetAutoReverseEnabled(autoReverse);
433         pAnimation->SetVisualElementAnimationStatusEventListener(this);
434         if (animationName == L"grow" || animationName == L"shrink")
435         {
436                 pTimingFunction.reset(new (std::nothrow) EaseInOutTimingFunction());
437                 pAnimation->SetTimingFunction(pTimingFunction.release());
438         }
439
440         __pVisualElementBounds->AddAnimation(animationName, *pAnimation);
441 }
442
443 void
444 NfcPushUiForm::PlayOpacityAnimation(const Tizen::Base::String& animationName, int duration)
445 {
446         std::unique_ptr<VisualElementPropertyAnimation> pAnimation(new (std::nothrow) VisualElementPropertyAnimation());
447         SysTryReturnVoidResult(NID_NET_NFC, pAnimation != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
448
449         //opacity
450         pAnimation->SetPropertyName(L"opacity");
451         pAnimation->SetStartValue(Variant(__startOpacity));
452         pAnimation->SetEndValue(Variant(__endOpacity));
453         pAnimation->SetDuration(duration);
454         pAnimation->SetVisualElementAnimationStatusEventListener(this);
455         if (animationName == L"opacity")
456         {
457                 pAnimation->SetDelay(247);
458         }
459
460         __pVisualElementOpacity->AddAnimation(animationName, *pAnimation);
461 }
462
463 void
464 NfcPushUiForm::FinishAppControl(RequestId reqId, AppCtrlResult appCtrlResult)
465 {
466         result r = E_SUCCESS;
467
468         // send result
469         r = AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appCtrlResult, null);
470         SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r, "[%s] exception occurred.", GetErrorMessage(r));
471
472         // terminate
473         SysLog(NID_NET_NFC, "Terminating this app control. [%d]", __reqId);
474         App::GetInstance()->Terminate();
475 }
476
477 void
478 NfcPushUiForm::OnVisualElementAnimationFinished(const VisualElementAnimation& animation, const String& keyName, VisualElement& target, bool completedNormally)
479 {
480         if(completedNormally)
481         {
482                 if (keyName == L"opacity")
483                 {
484                         float margin = (__endRect.width * 0.2f) / 2;
485                         __startRect = __endRect;
486                         __endRect = FloatRectangle(__startRect.x - margin, __startRect.y - margin,
487                                         __startRect.width + (margin * 2), __startRect.height + (margin * 2));
488
489                         // start second animation - repeat
490                         PlayBoundsAnimation(L"repeat", 0, _DURATION_REPEAT_, true);
491                 }
492                 else if (keyName == L"shrink")
493                 {
494                         // finish this app control with success
495
496                         // remove the guide text and app info
497                         Rectangle rect = GetClientAreaBounds();
498
499                         result r = E_SUCCESS;
500
501                         // remove the guide text and app description
502                         r = DrawBitmapToCanvas(rect);
503                         SysTryReturnVoidResult(NID_NET_NFC, r == E_SUCCESS, r, "[%s] Failed to remove guide text and app description.", GetErrorMessage(r));
504
505                         FinishAppControl(__reqId, APP_CTRL_RESULT_SUCCEEDED);
506                 }
507         }
508 }
509
510 // ITouchEventListener
511 void
512 NfcPushUiForm::OnTouchReleased(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo)
513 {
514         __startOpacity = __endOpacity;
515         __endOpacity = 0.0f;
516
517         // reset the circles size
518         __startRect = __endRect;
519         __endRect = FloatRectangle(__startRect.x + 90.0f, __startRect.y + 90.0f, 0, 0);
520
521         // play animation
522         AnimationTransaction::Begin();
523         PlayOpacityAnimation(L"opacity2", _DURATION_OPACITY2_);
524         PlayBoundsAnimation(L"shrink", 1, 667, false);
525         AnimationTransaction::Commit();
526 }
527
528 // INfcDeviceDiscoveryEventListener
529 void
530 NfcPushUiForm::OnNfcDeviceLost(void)
531 {
532         SysLog(NID_NET_NFC, "Devices are lost each other. (User-Cancelled) Terminating this app-control...");
533         FinishAppControl(__reqId, APP_CTRL_RESULT_CANCELED);
534 }