Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Unified Diff: chrome/browser/android/chrome_web_contents_delegate_android.cc

Issue 10905058: Upstream the Android port find-in-page feature. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/chrome_web_contents_delegate_android.cc
diff --git a/chrome/browser/android/chrome_web_contents_delegate_android.cc b/chrome/browser/android/chrome_web_contents_delegate_android.cc
index 56163c408ff7c4d41117ee0ba4eda1190e25b525..11d78af271a0558dddae7613baf67b93d5f34255 100644
--- a/chrome/browser/android/chrome_web_contents_delegate_android.cc
+++ b/chrome/browser/android/chrome_web_contents_delegate_android.cc
@@ -6,8 +6,18 @@
#include "base/android/jni_android.h"
#include "chrome/browser/file_select_helper.h"
+#include "chrome/browser/ui/find_bar/find_match_rects_details.h"
+#include "chrome/browser/ui/find_bar/find_notification_details.h"
+#include "chrome/browser/ui/find_bar/find_tab_helper.h"
+#include "chrome/browser/ui/tab_contents/tab_contents.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/file_chooser_params.h"
+#include "jni/ChromeWebContentsDelegateAndroid_jni.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/rect_f.h"
using base::android::AttachCurrentThread;
using base::android::GetClass;
@@ -15,6 +25,32 @@ using base::android::ScopedJavaLocalRef;
using content::FileChooserParams;
using content::WebContents;
+namespace {
+
+// Convenience method to create Android rects.
+// RectType should be either gfx::Rect or gfx::RectF.
+template <typename RectType>
+ScopedJavaLocalRef<jobject> CreateAndroidRect(
+ JNIEnv* env,
+ const ScopedJavaLocalRef<jclass>& clazz,
+ const jmethodID& constructor,
+ const RectType& rect) {
+
+ ScopedJavaLocalRef<jobject> rect_object(
+ env,
+ env->NewObject(clazz.obj(),
+ constructor,
+ rect.x(),
+ rect.y(),
+ rect.right(),
+ rect.bottom()));
+
+ DCHECK(!rect_object.is_null());
+ return rect_object;
+}
+
+} // anonymous namespace
+
namespace chrome {
namespace android {
@@ -24,6 +60,12 @@ ChromeWebContentsDelegateAndroid::ChromeWebContentsDelegateAndroid(JNIEnv* env,
}
ChromeWebContentsDelegateAndroid::~ChromeWebContentsDelegateAndroid() {
+ notification_registrar_.RemoveAll();
+}
+
+// Register native methods.
+bool RegisterChromeWebContentsDelegateAndroid(JNIEnv* env) {
+ return RegisterNativesImpl(env);
}
void ChromeWebContentsDelegateAndroid::RunFileChooser(
@@ -32,5 +74,192 @@ void ChromeWebContentsDelegateAndroid::RunFileChooser(
FileSelectHelper::RunFileChooser(web_contents, params);
}
+void ChromeWebContentsDelegateAndroid::CloseContents(
+ WebContents* web_contents) {
+ // Prevent dangling registrations assigned to closed web contents.
+ if (notification_registrar_.IsRegistered(this,
+ chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
+ content::Source<WebContents>(web_contents))) {
+ notification_registrar_.Remove(this,
+ chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
+ content::Source<WebContents>(web_contents));
+ }
+
+ if (notification_registrar_.IsRegistered(this,
+ chrome::NOTIFICATION_FIND_MATCH_RECTS_AVAILABLE,
+ content::Source<WebContents>(web_contents))) {
+ notification_registrar_.Remove(this,
+ chrome::NOTIFICATION_FIND_MATCH_RECTS_AVAILABLE,
+ content::Source<WebContents>(web_contents));
+ }
+
+ WebContentsDelegateAndroid::CloseContents(web_contents);
+}
+
+void ChromeWebContentsDelegateAndroid::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ case chrome::NOTIFICATION_FIND_RESULT_AVAILABLE:
+ OnFindResultAvailable(content::Source<WebContents>(source).ptr(),
jam 2012/09/04 16:39:09 nit: this indentation isn't according to style gui
Leandro Graciá Gil 2012/09/04 18:25:50 Done.
+ content::Details<FindNotificationDetails>(details).ptr());
+ break;
+ case chrome::NOTIFICATION_FIND_MATCH_RECTS_AVAILABLE:
+ OnFindMatchRectsAvailable(content::Source<WebContents>(source).ptr(),
+ content::Details<FindMatchRectsDetails>(details).ptr());
+ break;
+ default:
+ NOTREACHED() << "Unexpected notification: " << type;
+ break;
+ }
+}
+
+void ChromeWebContentsDelegateAndroid::FindReply(
+ WebContents* web_contents,
+ int request_id,
+ int number_of_matches,
+ const gfx::Rect& selection_rect,
+ int active_match_ordinal,
+ bool final_update) {
+ TabContents* tab_contents = TabContents::FromWebContents(web_contents);
+ if (!tab_contents || !tab_contents->find_tab_helper())
jam 2012/09/04 16:39:09 will this condition really happen?
Leandro Graciá Gil 2012/09/04 18:25:50 Good catch. We actually removed some of these chec
+ return;
+
+ if (!notification_registrar_.IsRegistered(this,
+ chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
+ content::Source<WebContents>(web_contents))) {
+ notification_registrar_.Add(this,
+ chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
+ content::Source<WebContents>(web_contents));
+ }
+
+ tab_contents->find_tab_helper()->HandleFindReply(request_id,
+ number_of_matches,
+ selection_rect,
+ active_match_ordinal,
+ final_update);
+}
+
+void ChromeWebContentsDelegateAndroid::OnFindResultAvailable(
+ WebContents* web_contents,
+ const FindNotificationDetails* find_result) {
+ DCHECK(web_contents);
jam 2012/09/04 16:39:09 please get rid of these dchecks. if they're null,
Leandro Graciá Gil 2012/09/04 18:25:50 Done.
+ DCHECK(find_result);
+
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
+ if (obj.is_null())
+ return;
+
+ // Create the selection rect.
+ ScopedJavaLocalRef<jclass> rect_clazz =
+ GetClass(env, "android/graphics/Rect");
+
+ jmethodID rect_constructor =
+ GetMethodID(env, rect_clazz, "<init>", "(IIII)V");
+
+ ScopedJavaLocalRef<jobject> selection_rect = CreateAndroidRect(
+ env, rect_clazz, rect_constructor, find_result->selection_rect());
+
+ // Create the details object.
+ ScopedJavaLocalRef<jclass> details_clazz =
+ GetClass(env, "org/chromium/chrome/browser/FindNotificationDetails");
+
+ jmethodID details_constructor = GetMethodID(env, details_clazz, "<init>",
+ "(ILandroid/graphics/Rect;IZ)V");
+
+ ScopedJavaLocalRef<jobject> details_object(
+ env,
+ env->NewObject(details_clazz.obj(),
+ details_constructor,
+ find_result->number_of_matches(),
+ selection_rect.obj(),
+ find_result->active_match_ordinal(),
+ find_result->final_update()));
+ DCHECK(!details_object.is_null());
+
+ Java_ChromeWebContentsDelegateAndroid_onFindResultAvailable(
+ env,
+ obj.obj(),
+ details_object.obj());
+}
+
+void ChromeWebContentsDelegateAndroid::GetFindMatchRectsReply(
+ WebContents* web_contents,
+ int version,
+ const std::vector<gfx::RectF>& rects,
+ const gfx::RectF& active_rect) {
+ TabContents* tab_contents = TabContents::FromWebContents(web_contents);
+ if (!tab_contents || !tab_contents->find_tab_helper())
+ return;
+
+ if (!notification_registrar_.IsRegistered(this,
+ chrome::NOTIFICATION_FIND_MATCH_RECTS_AVAILABLE,
+ content::Source<WebContents>(web_contents))) {
+ notification_registrar_.Add(this,
+ chrome::NOTIFICATION_FIND_MATCH_RECTS_AVAILABLE,
+ content::Source<WebContents>(web_contents));
+ }
+
+ tab_contents->find_tab_helper()->HandleGetFindMatchRectsReply(
+ version, rects, active_rect);
+}
+
+void ChromeWebContentsDelegateAndroid::OnFindMatchRectsAvailable(
+ WebContents* web_contents,
+ const FindMatchRectsDetails* match_rects) {
+ DCHECK(web_contents);
+ DCHECK(match_rects);
+
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
+ if (obj.is_null())
+ return;
+
+ // Create the rects.
+ ScopedJavaLocalRef<jclass> rect_clazz =
+ GetClass(env, "android/graphics/RectF");
+
+ jmethodID rect_constructor =
+ GetMethodID(env, rect_clazz, "<init>", "(FFFF)V");
+
+ ScopedJavaLocalRef<jobjectArray> rects(env, env->NewObjectArray(
+ match_rects->rects().size(), rect_clazz.obj(), NULL));
+
+ for (size_t i = 0; i < match_rects->rects().size(); ++i) {
+ env->SetObjectArrayElement(
+ rects.obj(), i,
+ CreateAndroidRect(env,
+ rect_clazz,
+ rect_constructor,
+ match_rects->rects()[i]).obj());
+ }
+
+ ScopedJavaLocalRef<jobject> active_rect = CreateAndroidRect(
+ env, rect_clazz, rect_constructor, match_rects->active_rect());
+
+ // Create the details object.
+ ScopedJavaLocalRef<jclass> details_clazz =
+ GetClass(env, "org/chromium/chrome/browser/FindMatchRectsDetails");
+
+ jmethodID details_constructor = GetMethodID(env, details_clazz, "<init>",
+ "(I[Landroid/graphics/RectF;Landroid/graphics/RectF;)V");
+
+ ScopedJavaLocalRef<jobject> details_object(
+ env,
+ env->NewObject(details_clazz.obj(),
+ details_constructor,
+ match_rects->version(),
+ rects.obj(),
+ active_rect.obj()));
+ DCHECK(!details_object.is_null());
+
+ Java_ChromeWebContentsDelegateAndroid_onFindMatchRectsAvailable(
+ env,
+ obj.obj(),
+ details_object.obj());
+}
+
} // namespace android
} // namespace chrome

Powered by Google App Engine
This is Rietveld 408576698