OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/android/content_view_core_impl.h" | 5 #include "content/browser/android/content_view_core_impl.h" |
6 | 6 |
7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
8 #include "base/android/jni_array.h" | 8 #include "base/android/jni_array.h" |
9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
10 #include "base/android/scoped_java_ref.h" | 10 #include "base/android/scoped_java_ref.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 POPUP_ITEM_TYPE_ENABLED | 49 POPUP_ITEM_TYPE_ENABLED |
50 }; | 50 }; |
51 | 51 |
52 namespace { | 52 namespace { |
53 jfieldID g_native_content_view; | 53 jfieldID g_native_content_view; |
54 } // namespace | 54 } // namespace |
55 | 55 |
56 namespace content { | 56 namespace content { |
57 | 57 |
58 struct ContentViewCoreImpl::JavaObject { | 58 struct ContentViewCoreImpl::JavaObject { |
59 jweak obj; | |
60 | 59 |
61 ScopedJavaLocalRef<jobject> View(JNIEnv* env) { | |
62 return GetRealObject(env, obj); | |
63 } | |
64 }; | 60 }; |
65 | 61 |
66 // ---------------------------------------------------------------------------- | 62 // ---------------------------------------------------------------------------- |
67 // Implementation of static ContentViewCore public interfaces | 63 // Implementation of static ContentViewCore public interfaces |
68 | 64 |
69 ContentViewCore* ContentViewCore::Create(JNIEnv* env, jobject obj, | 65 ContentViewCore* ContentViewCore::Create(JNIEnv* env, jobject obj, |
70 WebContents* web_contents) { | 66 WebContents* web_contents) { |
71 return new ContentViewCoreImpl(env, obj, web_contents); | 67 return new ContentViewCoreImpl(env, obj, web_contents); |
72 } | 68 } |
73 | 69 |
74 ContentViewCore* ContentViewCore::GetNativeContentViewCore(JNIEnv* env, | 70 ContentViewCore* ContentViewCore::GetNativeContentViewCore(JNIEnv* env, |
75 jobject obj) { | 71 jobject obj) { |
76 return reinterpret_cast<ContentViewCore*>( | 72 return reinterpret_cast<ContentViewCore*>( |
77 env->GetIntField(obj, g_native_content_view)); | 73 env->GetIntField(obj, g_native_content_view)); |
78 } | 74 } |
79 | 75 |
80 // ---------------------------------------------------------------------------- | 76 // ---------------------------------------------------------------------------- |
81 | 77 |
82 ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, | 78 ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, |
83 WebContents* web_contents) | 79 WebContents* web_contents) |
84 : web_contents_(static_cast<WebContentsImpl*>(web_contents)), | 80 : java_ref_(env, obj), |
| 81 web_contents_(static_cast<WebContentsImpl*>(web_contents)), |
85 tab_crashed_(false) { | 82 tab_crashed_(false) { |
86 DCHECK(web_contents) << | 83 DCHECK(web_contents) << |
87 "A ContentViewCoreImpl should be created with a valid WebContents."; | 84 "A ContentViewCoreImpl should be created with a valid WebContents."; |
88 | 85 |
89 InitJNI(env, obj); | 86 InitJNI(env, obj); |
90 | 87 |
91 notification_registrar_.Add(this, | 88 notification_registrar_.Add(this, |
92 NOTIFICATION_EXECUTE_JAVASCRIPT_RESULT, | 89 NOTIFICATION_EXECUTE_JAVASCRIPT_RESULT, |
93 NotificationService::AllSources()); | 90 NotificationService::AllSources()); |
94 } | 91 } |
95 | 92 |
96 ContentViewCoreImpl::~ContentViewCoreImpl() { | 93 ContentViewCoreImpl::~ContentViewCoreImpl() { |
97 // Make sure nobody calls back into this object while we are tearing things | 94 // Make sure nobody calls back into this object while we are tearing things |
98 // down. | 95 // down. |
99 notification_registrar_.RemoveAll(); | 96 notification_registrar_.RemoveAll(); |
100 | 97 |
101 if (java_object_) { | 98 delete java_object_; |
102 JNIEnv* env = AttachCurrentThread(); | 99 java_object_ = NULL; |
103 env->DeleteWeakGlobalRef(java_object_->obj); | 100 java_ref_.reset(); |
104 delete java_object_; | |
105 java_object_ = 0; | |
106 } | |
107 } | 101 } |
108 | 102 |
109 void ContentViewCoreImpl::Destroy(JNIEnv* env, jobject obj) { | 103 void ContentViewCoreImpl::Destroy(JNIEnv* env, jobject obj) { |
110 delete this; | 104 delete this; |
111 } | 105 } |
112 | 106 |
113 void ContentViewCoreImpl::Observe(int type, | 107 void ContentViewCoreImpl::Observe(int type, |
114 const NotificationSource& source, | 108 const NotificationSource& source, |
115 const NotificationDetails& details) { | 109 const NotificationDetails& details) { |
116 switch (type) { | 110 switch (type) { |
117 case NOTIFICATION_EXECUTE_JAVASCRIPT_RESULT: { | 111 case NOTIFICATION_EXECUTE_JAVASCRIPT_RESULT: { |
118 if (!web_contents_ || Source<RenderViewHost>(source).ptr() != | 112 if (!web_contents_ || Source<RenderViewHost>(source).ptr() != |
119 web_contents_->GetRenderViewHost()) { | 113 web_contents_->GetRenderViewHost()) { |
120 return; | 114 return; |
121 } | 115 } |
122 | 116 |
123 JNIEnv* env = base::android::AttachCurrentThread(); | 117 JNIEnv* env = base::android::AttachCurrentThread(); |
124 std::pair<int, Value*>* result_pair = | 118 std::pair<int, Value*>* result_pair = |
125 Details<std::pair<int, Value*> >(details).ptr(); | 119 Details<std::pair<int, Value*> >(details).ptr(); |
126 std::string json; | 120 std::string json; |
127 base::JSONWriter::Write(result_pair->second, &json); | 121 base::JSONWriter::Write(result_pair->second, &json); |
128 ScopedJavaLocalRef<jstring> j_json = ConvertUTF8ToJavaString(env, | 122 ScopedJavaLocalRef<jstring> j_json = ConvertUTF8ToJavaString(env, json); |
129 json); | 123 ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); |
130 Java_ContentViewCore_onEvaluateJavaScriptResult(env, | 124 if (!j_obj.is_null()) { |
131 java_object_->View(env).obj(), | 125 Java_ContentViewCore_onEvaluateJavaScriptResult(env, j_obj.obj(), |
132 static_cast<jint>(result_pair->first), j_json.obj()); | 126 static_cast<jint>(result_pair->first), j_json.obj()); |
| 127 } |
133 break; | 128 break; |
134 } | 129 } |
135 } | 130 } |
136 | 131 |
137 // TODO(jrg) | 132 // TODO(jrg) |
138 } | 133 } |
139 | 134 |
140 void ContentViewCoreImpl::InitJNI(JNIEnv* env, jobject obj) { | 135 void ContentViewCoreImpl::InitJNI(JNIEnv* env, jobject obj) { |
141 java_object_ = new JavaObject; | 136 java_object_ = new JavaObject; |
142 java_object_->obj = env->NewWeakGlobalRef(obj); | |
143 } | 137 } |
144 | 138 |
145 RenderWidgetHostViewAndroid* | 139 RenderWidgetHostViewAndroid* |
146 ContentViewCoreImpl::GetRenderWidgetHostViewAndroid() { | 140 ContentViewCoreImpl::GetRenderWidgetHostViewAndroid() { |
147 RenderWidgetHostView* rwhv = NULL; | 141 RenderWidgetHostView* rwhv = NULL; |
148 if (web_contents_) | 142 if (web_contents_) |
149 rwhv = web_contents_->GetRenderWidgetHostView(); | 143 rwhv = web_contents_->GetRenderWidgetHostView(); |
150 return static_cast<RenderWidgetHostViewAndroid*>(rwhv); | 144 return static_cast<RenderWidgetHostViewAndroid*>(rwhv); |
151 } | 145 } |
152 | 146 |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 NOTIMPLEMENTED() << "not upstreamed yet"; | 453 NOTIMPLEMENTED() << "not upstreamed yet"; |
460 } | 454 } |
461 | 455 |
462 void ContentViewCoreImpl::SetTitle(const string16& title) { | 456 void ContentViewCoreImpl::SetTitle(const string16& title) { |
463 NOTIMPLEMENTED() << "not upstreamed yet"; | 457 NOTIMPLEMENTED() << "not upstreamed yet"; |
464 } | 458 } |
465 | 459 |
466 void ContentViewCoreImpl::ShowSelectPopupMenu( | 460 void ContentViewCoreImpl::ShowSelectPopupMenu( |
467 const std::vector<WebMenuItem>& items, int selected_item, bool multiple) { | 461 const std::vector<WebMenuItem>& items, int selected_item, bool multiple) { |
468 JNIEnv* env = AttachCurrentThread(); | 462 JNIEnv* env = AttachCurrentThread(); |
| 463 ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); |
| 464 if (j_obj.is_null()) |
| 465 return; |
469 | 466 |
470 // For multi-select list popups we find the list of previous selections by | 467 // For multi-select list popups we find the list of previous selections by |
471 // iterating through the items. But for single selection popups we take the | 468 // iterating through the items. But for single selection popups we take the |
472 // given |selected_item| as is. | 469 // given |selected_item| as is. |
473 ScopedJavaLocalRef<jintArray> selected_array; | 470 ScopedJavaLocalRef<jintArray> selected_array; |
474 if (multiple) { | 471 if (multiple) { |
475 scoped_array<jint> native_selected_array(new jint[items.size()]); | 472 scoped_array<jint> native_selected_array(new jint[items.size()]); |
476 size_t selected_count = 0; | 473 size_t selected_count = 0; |
477 for (size_t i = 0; i < items.size(); ++i) { | 474 for (size_t i = 0; i < items.size(); ++i) { |
478 if (items[i].checked) | 475 if (items[i].checked) |
(...skipping 16 matching lines...) Expand all Loading... |
495 for (size_t i = 0; i < items.size(); ++i) { | 492 for (size_t i = 0; i < items.size(); ++i) { |
496 labels.push_back(items[i].label); | 493 labels.push_back(items[i].label); |
497 jint enabled = | 494 jint enabled = |
498 (items[i].type == WebMenuItem::GROUP ? POPUP_ITEM_TYPE_GROUP : | 495 (items[i].type == WebMenuItem::GROUP ? POPUP_ITEM_TYPE_GROUP : |
499 (items[i].enabled ? POPUP_ITEM_TYPE_ENABLED : | 496 (items[i].enabled ? POPUP_ITEM_TYPE_ENABLED : |
500 POPUP_ITEM_TYPE_DISABLED)); | 497 POPUP_ITEM_TYPE_DISABLED)); |
501 env->SetIntArrayRegion(enabled_array.obj(), i, 1, &enabled); | 498 env->SetIntArrayRegion(enabled_array.obj(), i, 1, &enabled); |
502 } | 499 } |
503 ScopedJavaLocalRef<jobjectArray> items_array( | 500 ScopedJavaLocalRef<jobjectArray> items_array( |
504 base::android::ToJavaArrayOfStrings(env, labels)); | 501 base::android::ToJavaArrayOfStrings(env, labels)); |
505 Java_ContentViewCore_showSelectPopup(env, java_object_->View(env).obj(), | 502 Java_ContentViewCore_showSelectPopup(env, j_obj.obj(), |
506 items_array.obj(), enabled_array.obj(), | 503 items_array.obj(), enabled_array.obj(), |
507 multiple, selected_array.obj()); | 504 multiple, selected_array.obj()); |
508 } | 505 } |
509 | 506 |
510 void ContentViewCoreImpl::ConfirmTouchEvent(bool handled) { | 507 void ContentViewCoreImpl::ConfirmTouchEvent(bool handled) { |
511 // TODO(yusufo): Upstream changes for http://crbug/139386 to match upstream | |
512 // to downstream. | |
513 JNIEnv* env = AttachCurrentThread(); | 508 JNIEnv* env = AttachCurrentThread(); |
514 Java_ContentViewCore_confirmTouchEvent(env, | 509 ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); |
515 java_object_->View(env).obj(), | 510 if (j_obj.is_null()) |
516 handled); | 511 return; |
| 512 Java_ContentViewCore_confirmTouchEvent(env, j_obj.obj(), handled); |
517 } | 513 } |
518 | 514 |
519 void ContentViewCoreImpl::DidSetNeedTouchEvents(bool need_touch_events) { | 515 void ContentViewCoreImpl::DidSetNeedTouchEvents(bool need_touch_events) { |
520 JNIEnv* env = AttachCurrentThread(); | 516 JNIEnv* env = AttachCurrentThread(); |
| 517 ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); |
| 518 if (j_obj.is_null()) |
| 519 return; |
521 Java_ContentViewCore_didSetNeedTouchEvents(env, | 520 Java_ContentViewCore_didSetNeedTouchEvents(env, |
522 java_object_->View(env).obj(), | 521 j_obj.obj(), |
523 need_touch_events); | 522 need_touch_events); |
524 } | 523 } |
525 | 524 |
526 bool ContentViewCoreImpl::HasFocus() { | 525 bool ContentViewCoreImpl::HasFocus() { |
527 NOTIMPLEMENTED() << "not upstreamed yet"; | 526 NOTIMPLEMENTED() << "not upstreamed yet"; |
528 return false; | 527 return false; |
529 } | 528 } |
530 | 529 |
531 void ContentViewCoreImpl::OnSelectionChanged(const std::string& text) { | 530 void ContentViewCoreImpl::OnSelectionChanged(const std::string& text) { |
532 NOTIMPLEMENTED() << "not upstreamed yet"; | 531 NOTIMPLEMENTED() << "not upstreamed yet"; |
533 } | 532 } |
534 | 533 |
535 void ContentViewCoreImpl::OnSelectionBoundsChanged( | 534 void ContentViewCoreImpl::OnSelectionBoundsChanged( |
536 int startx, | 535 int startx, |
537 int starty, | 536 int starty, |
538 base::i18n::TextDirection start_dir, | 537 base::i18n::TextDirection start_dir, |
539 int endx, | 538 int endx, |
540 int endy, | 539 int endy, |
541 base::i18n::TextDirection end_dir) { | 540 base::i18n::TextDirection end_dir) { |
542 NOTIMPLEMENTED() << "not upstreamed yet"; | 541 NOTIMPLEMENTED() << "not upstreamed yet"; |
543 } | 542 } |
544 | 543 |
545 void ContentViewCoreImpl::DidStartLoading() { | 544 void ContentViewCoreImpl::DidStartLoading() { |
546 JNIEnv* env = AttachCurrentThread(); | 545 JNIEnv* env = AttachCurrentThread(); |
547 Java_ContentViewCore_didStartLoading(env, java_object_->View(env).obj()); | 546 ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); |
| 547 if (j_obj.is_null()) |
| 548 return; |
| 549 Java_ContentViewCore_didStartLoading(env, j_obj.obj()); |
548 } | 550 } |
549 | 551 |
550 void ContentViewCoreImpl::OnAcceleratedCompositingStateChange( | 552 void ContentViewCoreImpl::OnAcceleratedCompositingStateChange( |
551 RenderWidgetHostViewAndroid* rwhva, bool activated, bool force) { | 553 RenderWidgetHostViewAndroid* rwhva, bool activated, bool force) { |
552 NOTIMPLEMENTED() << "not upstreamed yet"; | 554 NOTIMPLEMENTED() << "not upstreamed yet"; |
553 } | 555 } |
554 | 556 |
555 void ContentViewCoreImpl::StartContentIntent(const GURL& content_url) { | 557 void ContentViewCoreImpl::StartContentIntent(const GURL& content_url) { |
556 JNIEnv* env = AttachCurrentThread(); | 558 JNIEnv* env = AttachCurrentThread(); |
| 559 ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); |
| 560 if (j_obj.is_null()) |
| 561 return; |
557 ScopedJavaLocalRef<jstring> jcontent_url = | 562 ScopedJavaLocalRef<jstring> jcontent_url = |
558 ConvertUTF8ToJavaString(env, content_url.spec()); | 563 ConvertUTF8ToJavaString(env, content_url.spec()); |
559 Java_ContentViewCore_startContentIntent(env, | 564 Java_ContentViewCore_startContentIntent(env, |
560 java_object_->View(env).obj(), | 565 j_obj.obj(), |
561 jcontent_url.obj()); | 566 jcontent_url.obj()); |
562 } | 567 } |
563 | 568 |
564 // -------------------------------------------------------------------------- | 569 // -------------------------------------------------------------------------- |
565 // Methods called from native code | 570 // Methods called from native code |
566 // -------------------------------------------------------------------------- | 571 // -------------------------------------------------------------------------- |
567 | 572 |
568 gfx::Rect ContentViewCoreImpl::GetBounds() const { | 573 gfx::Rect ContentViewCoreImpl::GetBounds() const { |
569 NOTIMPLEMENTED() << "not upstreamed yet"; | 574 NOTIMPLEMENTED() << "not upstreamed yet"; |
570 return gfx::Rect(); | 575 return gfx::Rect(); |
(...skipping 10 matching lines...) Expand all Loading... |
581 if (!HasField(env, clazz, "mNativeContentViewCore", "I")) { | 586 if (!HasField(env, clazz, "mNativeContentViewCore", "I")) { |
582 DLOG(ERROR) << "Unable to find ContentView.mNativeContentViewCore!"; | 587 DLOG(ERROR) << "Unable to find ContentView.mNativeContentViewCore!"; |
583 return false; | 588 return false; |
584 } | 589 } |
585 g_native_content_view = GetFieldID(env, clazz, "mNativeContentViewCore", "I"); | 590 g_native_content_view = GetFieldID(env, clazz, "mNativeContentViewCore", "I"); |
586 | 591 |
587 return RegisterNativesImpl(env) >= 0; | 592 return RegisterNativesImpl(env) >= 0; |
588 } | 593 } |
589 | 594 |
590 } // namespace content | 595 } // namespace content |
OLD | NEW |