2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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 FWebCtrl_Web.cpp
20 * @brief The file contains the definition of _Web class.
22 * The file contains the definition of _Web class.
25 #include <FBaseByteBuffer.h>
26 #include <FBaseColLinkedListT.h>
27 #include <FBaseSysLog.h>
28 #include <FBaseColIListT.h>
29 #include <FGrpPoint.h>
30 #include <FGrpBitmap.h>
31 #include <FGrpCanvas.h>
32 #include <FWebCtrlWebSetting.h>
33 #include <FGrp_CoordinateSystem.h>
34 #include <FUiAnim_EflNode.h>
35 #include <FUiAnim_VisualElement.h>
36 #include <FUi_TouchManager.h>
37 #include "FWebCtrl_EflWebkit.h"
38 #include "FWebCtrl_GestureState.h"
39 #include "FWebCtrl_Web.h"
40 #include "FWebCtrl_WebImpl.h"
41 #include "FWebCtrl_WebSettingImpl.h"
42 #include "FWebCtrl_Utility.h"
45 using namespace Tizen::Base;
46 using namespace Tizen::Base::Collection;
47 using namespace Tizen::Graphics;
48 using namespace Tizen::Ui;
49 using namespace Tizen::Ui::Animations;
52 namespace Tizen { namespace Web { namespace Controls
56 static const char WEB_CTRL[] = "webcontrol";
60 : __pGestureHandler(null)
62 , __pGestureFlick(null)
63 , __pGestureLongPress(null)
64 , __pGestureDoubleTap(null)
65 , __pTouchEventInfoList(null)
66 , __pTapGestureHandler(null)
67 , __pDoubleTapGestureHandler(null)
68 , __pPanningGestureHandler(null)
69 , __pFlickGestureHandler(null)
70 , __pPinchGestureHandler(null)
72 SetBackgroundColor(Color(0, 0, 0, 0));
78 RemoveGestureListener();
83 _Web::CreateWebN(void)
87 std::unique_ptr<_Web> pWeb(new (std::nothrow) _Web());
88 SysTryReturn(NID_WEB_CTRL, pWeb.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
90 pWeb->AcquireHandle();
91 pWeb->SetMultiTouchEnabled(true);
92 pWeb->SetTouchMoveAllowance(TOUCH_MOVE_ALLOWANCE_NORMAL);
94 r = pWeb->AddGestureListeners();
95 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
97 r = pWeb->InitializeGestureStates();
98 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
100 return pWeb.release();
105 _Web::CreateWebkitEvasObject(void)
107 result r = E_SUCCESS;
109 std::unique_ptr<_EflWebkit> pEflWebkit(new (std::nothrow) _EflWebkit());
110 SysTryReturnResult(NID_WEB_CTRL, pEflWebkit.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
112 r = pEflWebkit->Construct(GetAbsoluteBounds(), *GetVisualElement());
113 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
115 __pEflWebkit = std::move(pEflWebkit);
122 _Web::InitializeGestureStates(void)
124 __pPinchGestureHandler = std::unique_ptr<_PinchGestureState>(new (std::nothrow) _PinchGestureState(this));
125 SysTryReturnResult(NID_WEB_CTRL, __pPinchGestureHandler.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
127 __pTapGestureHandler = std::unique_ptr<_TapGestureState>(new (std::nothrow) _TapGestureState(this, __pPinchGestureHandler.get()));
128 SysTryReturnResult(NID_WEB_CTRL, __pTapGestureHandler.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
130 __pDoubleTapGestureHandler = std::unique_ptr<_DoubleTapGestureState>(new (std::nothrow) _DoubleTapGestureState(this));
131 SysTryReturnResult(NID_WEB_CTRL, __pDoubleTapGestureHandler.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
133 __pPanningGestureHandler = std::unique_ptr<_PanningGestureState>(new (std::nothrow) _PanningGestureState(this, __pPinchGestureHandler.get()));
134 SysTryReturnResult(NID_WEB_CTRL, __pPanningGestureHandler.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
136 __pFlickGestureHandler = std::unique_ptr<_FlickGestureState>(new (std::nothrow) _FlickGestureState(this));
137 SysTryReturnResult(NID_WEB_CTRL, __pFlickGestureHandler.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
139 __pGestureHandler = __pTapGestureHandler.get();
146 _Web::AddGestureListeners(void)
148 result r = E_SUCCESS;
150 _ITouchFlickGestureEventListener* pFlickListener = dynamic_cast< _ITouchFlickGestureEventListener* >(this);
151 SysAssertf(pFlickListener != null, "Failed to get flick gesture listener");
153 std::unique_ptr<_TouchFlickGestureDetector> pGestureFlick(new (std::nothrow) _TouchFlickGestureDetector());
154 SysTryReturnResult(NID_WEB_CTRL, pGestureFlick.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
156 r = pGestureFlick->AddGestureListener(*pFlickListener);
157 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
159 r = AddGestureDetector(*pGestureFlick.get());
160 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
162 __pGestureFlick = std::move(pGestureFlick);
164 _ITouchLongPressGestureEventListener* pLongPressListener = dynamic_cast< _ITouchLongPressGestureEventListener* >(this);
165 SysAssertf(pLongPressListener != null, "Failed to get longpress gesture listener");
167 std::unique_ptr<_TouchLongPressGestureDetector> pGestureLongPress(new (std::nothrow) _TouchLongPressGestureDetector());
168 SysTryReturnResult(NID_WEB_CTRL, pGestureLongPress.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
170 r = pGestureLongPress->AddGestureListener(*pLongPressListener);
171 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
173 r = AddGestureDetector(*pGestureLongPress.get());
174 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
176 __pGestureLongPress = std::move(pGestureLongPress);
178 _ITouchTapGestureEventListener* pDoubleTapListener = dynamic_cast< _ITouchTapGestureEventListener* >(this);
179 SysAssertf(pDoubleTapListener != null, "Failed to get tap gesture listener");
181 std::unique_ptr<_TouchTapGestureDetector> pGestureDoubleTap(new (std::nothrow) _TouchTapGestureDetector());
182 SysTryReturnResult(NID_WEB_CTRL, pGestureDoubleTap.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
184 r = pGestureDoubleTap->AddGestureListener(*pDoubleTapListener);
185 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
187 r = AddGestureDetector(*pGestureDoubleTap.get());
188 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
190 __pGestureDoubleTap = std::move(pGestureDoubleTap);
197 _Web::RemoveGestureListener(void)
199 if (__pGestureFlick.get())
201 _ITouchFlickGestureEventListener* pListener = dynamic_cast< _ITouchFlickGestureEventListener* >(this);
202 __pGestureFlick->RemoveGestureListener(*pListener);
203 RemoveGestureDetector(*__pGestureFlick);
206 if (__pGestureLongPress.get())
208 _ITouchLongPressGestureEventListener* pListener = dynamic_cast< _ITouchLongPressGestureEventListener* >(this);
209 __pGestureLongPress->RemoveGestureListener(*pListener);
210 RemoveGestureDetector(*__pGestureLongPress);
213 if (__pGestureDoubleTap.get())
215 _ITouchTapGestureEventListener* pListener = dynamic_cast< _ITouchTapGestureEventListener* >(this);
216 __pGestureDoubleTap->RemoveGestureListener(*pListener);
217 RemoveGestureDetector(*__pGestureDoubleTap);
223 _Web::InitializeWebNativeNode(void)
225 result r = E_SUCCESS;
227 r = CreateWebkitEvasObject();
228 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
230 SetNativeObjectFocusable(false);
237 _Web::GetAbsoluteCoordinate(Point relativePoint)
239 _ICoordinateSystemTransformer* pXformer = _CoordinateSystem::GetInstance()->GetTransformer();
240 SysAssertf(pXformer, "Failed to get coordinate transformer.");
242 int absX = pXformer->TransformHorizontal(relativePoint.x + GetAbsoluteBounds().x);
243 int absY = pXformer->TransformVertical(relativePoint.y + GetAbsoluteBounds().y);
245 return Point(absX, absY);
250 _Web::GetRelativeCoordinate(Point absolutePoint)
252 _ICoordinateSystemTransformer* pXformer = _CoordinateSystem::GetInstance()->GetInverseTransformer();
253 SysAssertf(pXformer, "Failed to get coordinate transformer.");
255 Point bound(GetAbsoluteCoordinate(Point(0, 0)));
257 int absX = pXformer->TransformHorizontal(absolutePoint.x - bound.x);
258 int absY = pXformer->TransformVertical(absolutePoint.y - bound.y);
260 return Point(absX, absY);
265 _Web::GetWebNativeNode(void)
267 SysTryReturn(NID_WEB_CTRL, __pEflWebkit, null, E_INVALID_STATE, "[%s] Native node is in an invalid state.", GetErrorMessage(E_INVALID_STATE));
269 return __pEflWebkit->GetWebEvasObject();
274 _Web::SetWebSettingImpl(_WebSettingImpl* pWebSettingImpl)
276 __pWebSettingImpl = pWebSettingImpl;
281 _Web::GetWebSettingImpl(void) const
283 return __pWebSettingImpl;
288 _Web::OnAttaching(const _Control* pParent)
292 evas_object_show(__pEflWebkit->GetWebEvasObject());
293 evas_object_focus_set(__pEflWebkit->GetWebEvasObject(), EINA_TRUE);
301 _Web::OnBoundsChanging(const Rectangle& bounds)
303 Rectangle absoluteBounds = GetAbsoluteBounds();
304 Rectangle webBounds = GetBounds();
305 _ICoordinateSystemTransformer* pXformer = _CoordinateSystem::GetInstance()->GetTransformer();
306 SysTryReturnResult(NID_WEB_CTRL, pXformer, E_SYSTEM, "[%s] A system error has been occurred. Failed to get coordinate transformer.", GetErrorMessage(E_SYSTEM));
310 evas_object_move(__pEflWebkit->GetWebEvasObject(), pXformer->TransformHorizontal(absoluteBounds.x - webBounds.x + bounds.x), pXformer->TransformVertical(absoluteBounds.y - webBounds.y + bounds.y));
311 evas_object_resize(__pEflWebkit->GetWebEvasObject(), pXformer->TransformHorizontal(bounds.width), pXformer->TransformVertical(bounds.height));
319 _Web::ChangeGesture(_WebGestureType type)
323 case WEB_GESTURE_TYPE_TAP:
324 __pGestureHandler = __pTapGestureHandler.get();
327 case WEB_GESTURE_TYPE_DOUBLE_TAP:
328 __pGestureHandler = __pDoubleTapGestureHandler.get();
331 case WEB_GESTURE_TYPE_PANNING:
332 __pGestureHandler = __pPanningGestureHandler.get();
335 case WEB_GESTURE_TYPE_FLICK:
336 __pGestureHandler = __pFlickGestureHandler.get();
339 case WEB_GESTURE_TYPE_PINCH:
340 __pGestureHandler = __pPinchGestureHandler.get();
350 _Web::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
352 SendTouchEventForJavaScript(touchInfo);
354 __pGestureHandler->OnTouchPressed(source, touchInfo);
361 _Web::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
363 SendTouchEventForJavaScript(touchInfo);
365 __pGestureHandler->OnTouchMoved(source, touchInfo);
372 _Web::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
374 SendTouchEventForJavaScript(touchInfo);
376 __pGestureHandler->OnTouchReleased(source, touchInfo);
378 _WebImpl* pWebImpl = reinterpret_cast<_WebImpl*>(evas_object_data_get(GetWebNativeNode(), WEB_CTRL));
379 SysAssertf(pWebImpl, "Failed to get Impl");
381 if (pWebImpl->GetLoadingListener() && pWebImpl->GetTextFromBlock().GetLength() > 0)
383 pWebImpl->FireWebPageBlockSelectedEvent();
392 _Web::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
394 SendTouchEventForJavaScript(touchInfo);
396 __pGestureHandler->OnTouchCanceled(source, touchInfo);
403 _Web::OnFlickGestureDetected(_TouchFlickGestureDetector& gesture)
405 if (__pWebSettingImpl->IsScrollEnabled())
407 ChangeGesture(WEB_GESTURE_TYPE_FLICK);
408 static_cast< _FlickGestureState* >(__pGestureHandler)->OnFlickGestureDetected(gesture);
416 _Web::OnFlickGestureCanceled(_TouchFlickGestureDetector& gesture)
423 _Web::OnLongPressGestureDetected(_TouchLongPressGestureDetector& gesture)
425 _TapGestureState* pTapGestureHandler = dynamic_cast< _TapGestureState* >(__pGestureHandler);
426 if (pTapGestureHandler)
428 pTapGestureHandler->OnLongPressGestureDetected(gesture);
436 _Web::OnLongPressGestureCanceled(_TouchLongPressGestureDetector& gesture)
443 _Web::OnTapGestureDetected(_TouchTapGestureDetector& gesture)
445 ChangeGesture(WEB_GESTURE_TYPE_DOUBLE_TAP);
452 _Web::OnTapGestureCanceled(_TouchTapGestureDetector& gesture)
459 _Web::OnCanvasRequestedN(const Dimension& size)
461 result r = E_SUCCESS;
463 Evas_Object* pWebFrame = GetWebNativeNode();
465 BufferInfo bufferInfo;
467 Point absSize = GetAbsoluteCoordinate(Point(size.width, size.height));
469 EINA_RECTANGLE_SET(&rect, 0, 0, absSize.x, absSize.y);
471 Evas_Object* pScreenShot = ewk_view_screenshot_contents_get(pWebFrame, rect, 1.0f, evas_object_evas_get(pWebFrame));
472 SysTryReturn(NID_WEB_CTRL, pScreenShot, null, E_SYSTEM, "[%s] A system error has been occurred. Failed to get snapshot of Web control", GetErrorMessage(E_SYSTEM));
474 r = _Utility::GetPixelBufferFromEvasObject(pScreenShot, bufferInfo);
475 evas_object_del(pScreenShot);
476 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
478 std::unique_ptr<Canvas> pCanvas(new (std::nothrow) Canvas());
479 SysTryReturn(NID_WEB_CTRL, pCanvas.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
481 r = pCanvas->Construct(bufferInfo);
482 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
484 return pCanvas.release();
489 _Web::OnCapturedBitmapRequestedN(void)
491 result r = E_SUCCESS;
493 Evas_Object* pWebFrame = GetWebNativeNode();
496 BufferInfo bufferInfo;
498 Dimension size = GetSize();
499 Point absSize = GetAbsoluteCoordinate(Point(size.width, size.height));
501 EINA_RECTANGLE_SET(&rect, 0, 0, absSize.x, absSize.y);
503 Evas_Object* pScreenShot = ewk_view_screenshot_contents_get(pWebFrame, rect, 1.0f, evas_object_evas_get(pWebFrame));
504 SysTryReturn(NID_WEB_CTRL, pScreenShot, null, E_SYSTEM, "[%s] A system error has been occurred. Failed to get snapshot of Web control", GetErrorMessage(E_SYSTEM));
506 r = _Utility::GetPixelBufferFromEvasObject(pScreenShot, bufferInfo);
507 evas_object_del(pScreenShot);
508 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
510 int bufferSize = bufferInfo.bitsPerPixel * bufferInfo.width * bufferInfo.height;
511 r = buffer.Construct(reinterpret_cast < byte* >(bufferInfo.pPixels), 0, bufferSize, bufferSize);
512 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
514 std::unique_ptr<Bitmap> pBitmap(new (std::nothrow) Bitmap());
515 SysTryReturn(NID_WEB_CTRL, pBitmap.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
517 r = pBitmap->Construct(buffer, Dimension(bufferInfo.width, bufferInfo.height), BITMAP_PIXEL_FORMAT_ARGB8888);
518 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
520 return pBitmap.release();
525 _Web::DumpPointList(void* pData)
527 Eina_List* pList = reinterpret_cast< Eina_List* >(pData);
529 for(; pList; pList = eina_list_next(pList))
531 Ewk_Touch_Point* pPointDump = static_cast<Ewk_Touch_Point*>(eina_list_data_get(pList));
532 SysLog(NID_WEB_CTRL, "The current value of id is %lu, x is %d, y is %d, state is %d", pPointDump->id, pPointDump->x, pPointDump->y, pPointDump->state);
538 _Web::SendTouchEventForJavaScript(const _TouchInfo& touchInfo)
540 result r = E_SUCCESS;
542 Eina_List* pPointList = null;
543 Ewk_Touch_Point* pPoint = null;
545 _TouchManager* pTouchManager = _TouchManager::GetInstance();
546 SysAssertf(pTouchManager, "Failed to get touch manager.");
548 std::unique_ptr<IListT<_FingerInfo*> > pTouchList(pTouchManager->GetMultiFingerInfoListN());
549 SysTryReturnVoidResult(NID_WEB_CTRL, pTouchList.get(), GetLastResult(), "[%s] Failed to get touch list.", GetErrorMessage(GetLastResult()));
551 std::unique_ptr<IBidirectionalEnumeratorT<_FingerInfo*> > pTouchListEnum(pTouchList->GetBidirectionalEnumeratorN());
552 SysAssertf(pTouchListEnum.get() != null, "Failed to get enumerator of touch list.");
555 _FingerInfo* pFingerInfo = null;
556 while(pTouchListEnum->MoveNext() == E_SUCCESS)
558 r = pTouchListEnum->GetCurrent(pFingerInfo);
559 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
561 _TouchStatus state = pFingerInfo->GetStatus();
562 if(state == _TOUCH_PRESSED || state == _TOUCH_MOVED || state == _TOUCH_RELEASED || state == _TOUCH_CANCELED)
564 currentPoint = GetAbsoluteCoordinate(pFingerInfo->GetPoint());
566 pPoint = static_cast<Ewk_Touch_Point*>(calloc(1, sizeof(Ewk_Touch_Point)));
568 pPoint->id = pFingerInfo->GetPointId();
569 pPoint->x = currentPoint.x;
570 pPoint->y = currentPoint.y;
571 pPoint->state = GetEvasTouchState((TouchStatus)pFingerInfo->GetStatus());
573 pPointList = eina_list_append(pPointList, pPoint);
576 DumpPointList(pPointList);
578 Eina_Bool ret = ewk_view_feed_touch_event(__pEflWebkit->GetWebEvasObject(), GetEwkTouchEvent(touchInfo.GetTouchStatus()), pPointList, null);
579 SysTryReturnVoidResult(NID_WEB_CTRL, ret == EINA_TRUE, E_SYSTEM, "[%s] A system error has been occurred. Failed to deliver touch event to javascript.", GetErrorMessage(E_SYSTEM));
583 EINA_LIST_FREE(pPointList, pData)
589 _Web::GetEwkTouchEvent(_TouchStatus touchStatus)
591 Ewk_Touch_Event_Type ewkTouchEvent = EWK_TOUCH_CANCEL;
595 case _TOUCH_PRESSED :
596 ewkTouchEvent = EWK_TOUCH_START;
599 ewkTouchEvent = EWK_TOUCH_MOVE;
601 case _TOUCH_RELEASED :
602 ewkTouchEvent = EWK_TOUCH_END;
604 case _TOUCH_CANCELED :
607 ewkTouchEvent = EWK_TOUCH_CANCEL;
611 return ewkTouchEvent;
615 Evas_Touch_Point_State
616 _Web::GetEvasTouchState(TouchStatus touchStatus)
618 Evas_Touch_Point_State evasTouchState = EVAS_TOUCH_POINT_CANCEL;
623 evasTouchState = EVAS_TOUCH_POINT_DOWN;
626 evasTouchState = EVAS_TOUCH_POINT_MOVE;
628 case TOUCH_RELEASED :
629 evasTouchState = EVAS_TOUCH_POINT_UP;
631 case TOUCH_CANCELED :
634 evasTouchState = EVAS_TOUCH_POINT_CANCEL;
635 //todo : mapping EVAS_TOUCH_POINT_STILL, /**< Touch point is not moved af
639 return evasTouchState;
643 }}} // Tizen::Web::Controls