The new implementation is based on actual upstream android
implementation of the feature. We no longer need to do hit tests from UI
to renderer process after each tap event. The engine content detection
logic resides in the renderer process itself. We only need to react to
ViewHostMsg_StartContentIntent message in UI which is sent after renderer
has found an URI it wishes us to handle.
Since the feature is generic enough I've also taken my liberty to have
it supported on desktop. Desktop implementation uses gio library to launch
applications handling selected URIs.
Simple TC:
<html><body>
<p>mailto:anonymous@example.com</p>
<p>tel:+
48721421421</p>
</body></html>
To test the feature on desktop please use ubrowser app and make sure
touch events are enabled. When clicking on the mailto link default email
application should be launch. Clicking on tel: will probably produce a
warning saying there is no registered client to handle the URI. Tel links
will probably only work on mobile targets. Still the warning tells us
that the content is recognized and the appropriate message makes it's
way to our handler.
Change-Id: Iec394f97d99ccb97e84c94f948804d500d44fc46
Signed-off-by: Piotr Tworek <p.tworek@samsung.com>
--- /dev/null
+# copyright (c) 2015 samsung electronics. all rights reserved.
+# use of this source code is governed by a bsd-style license that can be
+# found in the license file.
+
+{
+ 'target_defaults': {
+ 'include_dirs': [
+ '<(DEPTH)',
+ ],
+ },
+ 'targets': [
+ {
+ 'target_name': 'android_content_detection',
+ 'type': 'static_library',
+ 'dependencies' : [
+ '<(DEPTH)/third_party/libphonenumber/libphonenumber.gyp:libphonenumber',
+ '<(DEPTH)/third_party/icu/icu.gyp:icui18n',
+ '<(DEPTH)/third_party/WebKit/public//blink.gyp:blink',
+ ],
+ 'sources': [
+ '<(DEPTH)/content/renderer/android/content_detector.h',
+ '<(DEPTH)/content/renderer/android/content_detector.cc',
+ '<(DEPTH)/content/renderer/android/email_detector.h',
+ '<(DEPTH)/content/renderer/android/email_detector.cc',
+ '<(DEPTH)/content/renderer/android/phone_number_detector.h',
+ '<(DEPTH)/content/renderer/android/phone_number_detector.cc',
+ ],
+ },
+ ],
+}
],
'external_content_renderer_deps': [
'<(DEPTH)/tizen_src/build/system.gyp:tts',
+ '<(DEPTH)/tizen_src/chromium_impl/content/content_efl.gyp:android_content_detection',
],
'external_content_gpu_deps': [
'<(DEPTH)/tizen_src/build/system.gyp:evas',
using content::WebContents;
using namespace web_contents_utils;
+namespace {
+static const uint32 kFilteredMessageClasses[] = { EwkMsgStart, ViewMsgStart };
+}
+
class WebViewBrowserMessageFilterPrivate
: public content::NotificationObserver {
public:
web_view_->GetScrollDetector()->OnChangeScrollOffset(gfx::Vector2d(scrollX, scrollY));
}
- void OnGetTextAtPositionReply(const std::string& text) {
-#ifdef TIZEN_CONTENTS_DETECTION
- if (web_view_) {
- base::string16 content = base::UTF8ToUTF16(text);
-
- std::string message;
- if (autofill::IsValidEmailAddress(content))
- message = std::string("mailto:").append(text);
- else if (autofill::IsValidPhoneNumber(content))
- message = std::string("tel:").append(text);
- else
- return;
-
- web_view_->ShowContentsDetectedPopup(message.c_str());
- }
-#endif
+ void OnStartContentIntent(const GURL& content_url) {
+ DCHECK(!content_url.is_empty());
+ web_view_->ShowContentsDetectedPopup(content_url.spec().c_str());
}
void Observe(int type, const content::NotificationSource& source,
const content::NotificationDetails& details) override {
DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type);
-
web_view_ = NULL;
}
WebViewBrowserMessageFilter::WebViewBrowserMessageFilter(
content::WebContents* web_contents)
- : BrowserMessageFilter(EwkMsgStart),
+ : BrowserMessageFilter(kFilteredMessageClasses,
+ arraysize(kFilteredMessageClasses)),
private_(new WebViewBrowserMessageFilterPrivate(web_contents)) {
}
WebViewBrowserMessageFilterPrivate::OnDidChangeMaxScrollOffset)
IPC_MESSAGE_FORWARD(EwkHostMsg_DidChangeScrollOffset, private_,
WebViewBrowserMessageFilterPrivate::OnDidChangeScrollOffset)
+ IPC_MESSAGE_FORWARD(ViewHostMsg_StartContentIntent, private_,
+ WebViewBrowserMessageFilterPrivate::OnStartContentIntent)
#if defined(OS_TIZEN)
IPC_MESSAGE_FORWARD(ViewHostMsg_SnapshotDataReceived, private_,
WebViewBrowserMessageFilterPrivate::OnSnapshot)
#endif
-#if defined(TIZEN_CONTENTS_DETECTION)
- IPC_MESSAGE_FORWARD(ViewHostMsg_GetTextAtPositionReply, private_,
- WebViewBrowserMessageFilterPrivate::OnGetTextAtPositionReply)
-#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
[ 'exclude', 'browser/sound_effect\\.(cc|h)$' ],
],
}, {
+ 'dependencies': [
+ '<(DEPTH)/build/linux/system.gyp:gio',
+ ],
'sources/': [
[ 'exclude', 'browser/sound_effect_tizen\\.(cc|h)$' ],
[ 'exclude', 'browser/geolocation/location_provider_efl\\.(cc|h)$'],
context_menu_->SetPopupSize(width, height);
if (inputPicker_)
inputPicker_->SetPopupSize(width, height);
-#ifdef TIZEN_CONTENTS_DETECTION
if (popup_controller_)
popup_controller_->SetPopupSize(width, height);
-#endif
if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
dialogMG->SetPopupSize(width, height);
#if defined(OS_TIZEN)
return context_menu_position_;
}
-#ifdef TIZEN_CONTENTS_DETECTION
void EWebView::ShowContentsDetectedPopup(const char* message) {
popup_controller_.reset(new PopupControllerEfl(this));
popup_controller_->openPopup(message);
}
-#endif
void EWebView::RequestColorPicker(int r, int g, int b, int a) {
inputPicker_.reset(new InputPicker(*this));
#include "ui/gfx/size.h"
#include "browser/inputpicker/InputPicker.h"
#include "tizen_webview/public/tw_hit_test.h"
-
-#ifdef TIZEN_CONTENTS_DETECTION
#include "popup_controller_efl.h"
-#endif
#if defined(OS_TIZEN)
#include "browser/selectpicker/popup_picker.h"
class ContextMenuControllerEfl;
class DevToolsDelegateEfl;
class WebContentsViewEfl;
-#ifdef TIZEN_CONTENTS_DETECTION
class PopupControllerEfl;
-#endif
}
namespace ui {
const char* body);
content::SelectionControllerEfl* GetSelectionController() const { return selection_controller_.get(); }
-#ifdef TIZEN_CONTENTS_DETECTION
content::PopupControllerEfl* GetPopupController() const { return popup_controller_.get(); }
-#endif
ScrollDetector* GetScrollDetector() const { return scroll_detector_.get(); }
void SelectRange(const gfx::Point& start, const gfx::Point& end);
void MoveCaret(const gfx::Point& point);
#endif
void OnSnapshot(const std::vector<unsigned char>& pixData, int width, int height, int snapshotId);
-#ifdef TIZEN_CONTENTS_DETECTION
void ShowContentsDetectedPopup(const char*);
-#endif
bool IsIMEShow();
gfx::Rect GetIMERect();
formNavigation formNavigation_;
scoped_ptr<content::ContextMenuControllerEfl> context_menu_;
scoped_ptr<content::FileChooserControllerEfl> file_chooser_;
-#ifdef TIZEN_CONTENTS_DETECTION
scoped_ptr<content::PopupControllerEfl> popup_controller_;
-#endif
scoped_ptr<content::SelectionControllerEfl> selection_controller_;
base::string16 previous_text_;
int current_find_request_id_;
#include "popup_controller_efl.h"
#include "ui/base/clipboard/clipboard_helper_efl.h"
-#ifdef TIZEN_CONTENTS_DETECTION
+#if defined(OS_TIZEN)
#include <ui-gadget.h>
#include <app_control.h>
+#else
+#include <gio/gio.h>
+#endif // OS_TIZEN
#ifdef OS_TIZEN_MOBILE
#include <efl_assist.h>
return;
}
+#if defined(OS_TIZEN)
app_control_h svcHandle = 0;
if (app_control_create(&svcHandle) < 0 || !svcHandle) {
LOG(ERROR) << __PRETTY_FUNCTION__ << " : " << "could not create service.";
<< "could not launch application.";
app_control_destroy(svcHandle);
+#endif
}
PopupControllerEfl::PopupControllerEfl(EWebView* webView)
full_content_ = std::string(message);
content_ = std::string(message);
-
+#if defined(OS_TIZEN)
if (content_.find("mailto:") != std::string::npos) {
content_.erase(0, 7);
content_type_ = EMAIL;
appendItems();
addCallbacks();
showPopup();
+#else
+ GError* error = NULL;
+ gboolean ret = g_app_info_launch_default_for_uri(
+ full_content_.c_str(), NULL, &error);
+ if (!ret) {
+ LOG(WARNING) << "Failed to launch default application for: "
+ << full_content_ << ", " << error->message;
+ }
+#endif
}
void PopupControllerEfl::addOptions() {
}
} //namespace
-#endif //TIZEN_CONTENTS_DETECTION
#define popup_controller_efl_h
#include <Evas.h>
+
#include "eweb_view.h"
-#ifdef TIZEN_CONTENTS_DETECTION
namespace content {
class PopupControllerEfl {
};
} // namespace
-#endif // TIZEN_CONTENTS_DETECTION
#endif // popup_controller_efl_h