| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/web_contents/web_contents_android.h" | 5 #include "content/browser/web_contents/web_contents_android.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
| 10 #include "base/android/jni_array.h" | 10 #include "base/android/jni_array.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 const base::Value* result) { | 62 const base::Value* result) { |
| 63 JNIEnv* env = base::android::AttachCurrentThread(); | 63 JNIEnv* env = base::android::AttachCurrentThread(); |
| 64 std::string json; | 64 std::string json; |
| 65 base::JSONWriter::Write(*result, &json); | 65 base::JSONWriter::Write(*result, &json); |
| 66 ScopedJavaLocalRef<jstring> j_json = ConvertUTF8ToJavaString(env, json); | 66 ScopedJavaLocalRef<jstring> j_json = ConvertUTF8ToJavaString(env, json); |
| 67 Java_WebContentsImpl_onEvaluateJavaScriptResult( | 67 Java_WebContentsImpl_onEvaluateJavaScriptResult( |
| 68 env, j_json.obj(), callback.obj()); | 68 env, j_json.obj(), callback.obj()); |
| 69 } | 69 } |
| 70 | 70 |
| 71 struct AccessibilitySnapshotParams { | 71 struct AccessibilitySnapshotParams { |
| 72 AccessibilitySnapshotParams(float scale, | 72 AccessibilitySnapshotParams() |
| 73 float vertical_offset, | 73 : has_tree_data(false), should_select_leaf_nodes(false) {} |
| 74 float horizontal_scroll) | |
| 75 : scale_factor(scale), | |
| 76 y_offset(vertical_offset), | |
| 77 x_scroll(horizontal_scroll), | |
| 78 has_tree_data(false), | |
| 79 should_select_leaf_nodes(false) {} | |
| 80 | 74 |
| 81 float scale_factor; | |
| 82 float y_offset; | |
| 83 float x_scroll; | |
| 84 bool has_tree_data; | 75 bool has_tree_data; |
| 85 // The current text selection within this tree, if any, expressed as the | 76 // The current text selection within this tree, if any, expressed as the |
| 86 // node ID and character offset of the anchor (selection start) and focus | 77 // node ID and character offset of the anchor (selection start) and focus |
| 87 // (selection end). | 78 // (selection end). |
| 88 int32_t sel_anchor_object_id; | 79 int32_t sel_anchor_object_id; |
| 89 int32_t sel_anchor_offset; | 80 int32_t sel_anchor_offset; |
| 90 int32_t sel_focus_object_id; | 81 int32_t sel_focus_object_id; |
| 91 int32_t sel_focus_offset; | 82 int32_t sel_focus_offset; |
| 92 // if the flag is true, mark the leaf node as selected. | 83 // if the flag is true, mark the leaf node as selected. |
| 93 bool should_select_leaf_nodes; | 84 bool should_select_leaf_nodes; |
| 94 }; | 85 }; |
| 95 | 86 |
| 96 ScopedJavaLocalRef<jobject> WalkAXTreeDepthFirst( | 87 ScopedJavaLocalRef<jobject> WalkAXTreeDepthFirst( |
| 97 JNIEnv* env, | 88 JNIEnv* env, |
| 98 BrowserAccessibilityAndroid* node, | 89 BrowserAccessibilityAndroid* node, |
| 90 const gfx::Rect& parent_rect, |
| 99 AccessibilitySnapshotParams* params) { | 91 AccessibilitySnapshotParams* params) { |
| 100 ScopedJavaLocalRef<jstring> j_text = | 92 ScopedJavaLocalRef<jstring> j_text = |
| 101 ConvertUTF16ToJavaString(env, node->GetText()); | 93 ConvertUTF16ToJavaString(env, node->GetText()); |
| 102 ScopedJavaLocalRef<jstring> j_class = | 94 ScopedJavaLocalRef<jstring> j_class = |
| 103 ConvertUTF8ToJavaString(env, node->GetClassName()); | 95 ConvertUTF8ToJavaString(env, node->GetClassName()); |
| 104 const gfx::Rect& location = node->GetLocalBoundsRect(); | |
| 105 // The style attributes exists and valid if size attribute exists. Otherwise, | 96 // The style attributes exists and valid if size attribute exists. Otherwise, |
| 106 // they are not. Use a negative size information to indicate the existence | 97 // they are not. Use a negative size information to indicate the existence |
| 107 // of style information. | 98 // of style information. |
| 108 float size = -1.0; | 99 float size = -1.0; |
| 109 int color = 0; | 100 int color = 0; |
| 110 int bgcolor = 0; | 101 int bgcolor = 0; |
| 111 int text_style = 0; | 102 int text_style = 0; |
| 112 | 103 |
| 113 if (node->HasFloatAttribute(ui::AX_ATTR_FONT_SIZE)) { | 104 if (node->HasFloatAttribute(ui::AX_ATTR_FONT_SIZE)) { |
| 114 color = node->GetIntAttribute(ui::AX_ATTR_COLOR); | 105 color = node->GetIntAttribute(ui::AX_ATTR_COLOR); |
| 115 bgcolor = node->GetIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR); | 106 bgcolor = node->GetIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR); |
| 116 size = node->GetFloatAttribute(ui::AX_ATTR_FONT_SIZE); | 107 size = node->GetFloatAttribute(ui::AX_ATTR_FONT_SIZE); |
| 117 text_style = node->GetIntAttribute(ui::AX_ATTR_TEXT_STYLE); | 108 text_style = node->GetIntAttribute(ui::AX_ATTR_TEXT_STYLE); |
| 118 } | 109 } |
| 119 float scale_factor = params->scale_factor; | 110 |
| 111 const gfx::Rect& absolute_rect = node->GetLocalBoundsRect(); |
| 112 gfx::Rect parent_relative_rect = absolute_rect; |
| 113 bool is_root = node->GetParent() == nullptr; |
| 114 if (!is_root) { |
| 115 parent_relative_rect.Offset(-parent_rect.OffsetFromOrigin()); |
| 116 } |
| 120 ScopedJavaLocalRef<jobject> j_node = | 117 ScopedJavaLocalRef<jobject> j_node = |
| 121 Java_WebContentsImpl_createAccessibilitySnapshotNode( | 118 Java_WebContentsImpl_createAccessibilitySnapshotNode( |
| 122 env, scale_factor * location.x() - params->x_scroll, | 119 env, parent_relative_rect.x(), parent_relative_rect.y(), |
| 123 scale_factor * location.y() + params->y_offset, | 120 absolute_rect.width(), absolute_rect.height(), is_root, j_text.obj(), |
| 124 scale_factor * node->GetScrollX(), scale_factor * node->GetScrollY(), | 121 color, bgcolor, size, text_style, j_class.obj()); |
| 125 scale_factor * location.width(), scale_factor * location.height(), | |
| 126 j_text.obj(), color, bgcolor, scale_factor * size, text_style, | |
| 127 j_class.obj()); | |
| 128 | 122 |
| 129 if (params->has_tree_data && node->PlatformIsLeaf()) { | 123 if (params->has_tree_data && node->PlatformIsLeaf()) { |
| 130 int start_selection = 0; | 124 int start_selection = 0; |
| 131 int end_selection = 0; | 125 int end_selection = 0; |
| 132 if (params->sel_anchor_object_id == node->GetId()) { | 126 if (params->sel_anchor_object_id == node->GetId()) { |
| 133 start_selection = params->sel_anchor_offset; | 127 start_selection = params->sel_anchor_offset; |
| 134 params->should_select_leaf_nodes = true; | 128 params->should_select_leaf_nodes = true; |
| 135 } | 129 } |
| 136 if (params->should_select_leaf_nodes) | 130 if (params->should_select_leaf_nodes) |
| 137 end_selection = node->GetText().length(); | 131 end_selection = node->GetText().length(); |
| 138 | 132 |
| 139 if (params->sel_focus_object_id == node->GetId()) { | 133 if (params->sel_focus_object_id == node->GetId()) { |
| 140 end_selection = params->sel_focus_offset; | 134 end_selection = params->sel_focus_offset; |
| 141 params->should_select_leaf_nodes = false; | 135 params->should_select_leaf_nodes = false; |
| 142 } | 136 } |
| 143 if (end_selection > 0) | 137 if (end_selection > 0) |
| 144 Java_WebContentsImpl_setAccessibilitySnapshotSelection( | 138 Java_WebContentsImpl_setAccessibilitySnapshotSelection( |
| 145 env, j_node.obj(), start_selection, end_selection); | 139 env, j_node.obj(), start_selection, end_selection); |
| 146 } | 140 } |
| 147 | 141 |
| 148 for (uint32_t i = 0; i < node->PlatformChildCount(); i++) { | 142 for (uint32_t i = 0; i < node->PlatformChildCount(); i++) { |
| 149 BrowserAccessibilityAndroid* child = | 143 BrowserAccessibilityAndroid* child = |
| 150 static_cast<BrowserAccessibilityAndroid*>( | 144 static_cast<BrowserAccessibilityAndroid*>( |
| 151 node->PlatformGetChild(i)); | 145 node->PlatformGetChild(i)); |
| 152 Java_WebContentsImpl_addAccessibilityNodeAsChild( | 146 Java_WebContentsImpl_addAccessibilityNodeAsChild( |
| 153 env, j_node.obj(), WalkAXTreeDepthFirst(env, child, params).obj()); | 147 env, j_node.obj(), |
| 148 WalkAXTreeDepthFirst(env, child, absolute_rect, params).obj()); |
| 154 } | 149 } |
| 155 return j_node; | 150 return j_node; |
| 156 } | 151 } |
| 157 | 152 |
| 158 // Walks over the AXTreeUpdate and creates a light weight snapshot. | 153 // Walks over the AXTreeUpdate and creates a light weight snapshot. |
| 159 void AXTreeSnapshotCallback(const ScopedJavaGlobalRef<jobject>& callback, | 154 void AXTreeSnapshotCallback(const ScopedJavaGlobalRef<jobject>& callback, |
| 160 AccessibilitySnapshotParams* params, | |
| 161 const ui::AXTreeUpdate& result) { | 155 const ui::AXTreeUpdate& result) { |
| 162 JNIEnv* env = base::android::AttachCurrentThread(); | 156 JNIEnv* env = base::android::AttachCurrentThread(); |
| 163 if (result.nodes.empty()) { | 157 if (result.nodes.empty()) { |
| 164 Java_WebContentsImpl_onAccessibilitySnapshot(env, nullptr, callback.obj()); | 158 Java_WebContentsImpl_onAccessibilitySnapshot(env, nullptr, callback.obj()); |
| 165 return; | 159 return; |
| 166 } | 160 } |
| 167 scoped_ptr<BrowserAccessibilityManagerAndroid> manager( | 161 scoped_ptr<BrowserAccessibilityManagerAndroid> manager( |
| 168 static_cast<BrowserAccessibilityManagerAndroid*>( | 162 static_cast<BrowserAccessibilityManagerAndroid*>( |
| 169 BrowserAccessibilityManager::Create(result, nullptr))); | 163 BrowserAccessibilityManager::Create(result, nullptr))); |
| 170 manager->set_prune_tree_for_screen_reader(false); | 164 manager->set_prune_tree_for_screen_reader(false); |
| 171 BrowserAccessibilityAndroid* root = | 165 BrowserAccessibilityAndroid* root = |
| 172 static_cast<BrowserAccessibilityAndroid*>(manager->GetRoot()); | 166 static_cast<BrowserAccessibilityAndroid*>(manager->GetRoot()); |
| 167 AccessibilitySnapshotParams params; |
| 173 if (result.has_tree_data) { | 168 if (result.has_tree_data) { |
| 174 params->has_tree_data = true; | 169 params.has_tree_data = true; |
| 175 params->sel_anchor_object_id = result.tree_data.sel_anchor_object_id; | 170 params.sel_anchor_object_id = result.tree_data.sel_anchor_object_id; |
| 176 params->sel_anchor_offset = result.tree_data.sel_anchor_offset; | 171 params.sel_anchor_offset = result.tree_data.sel_anchor_offset; |
| 177 params->sel_focus_object_id = result.tree_data.sel_focus_object_id; | 172 params.sel_focus_object_id = result.tree_data.sel_focus_object_id; |
| 178 params->sel_focus_offset = result.tree_data.sel_focus_offset; | 173 params.sel_focus_offset = result.tree_data.sel_focus_offset; |
| 179 } | 174 } |
| 180 ScopedJavaLocalRef<jobject> j_root = WalkAXTreeDepthFirst(env, root, params); | 175 gfx::Rect parent_rect; |
| 176 ScopedJavaLocalRef<jobject> j_root = |
| 177 WalkAXTreeDepthFirst(env, root, parent_rect, ¶ms); |
| 181 Java_WebContentsImpl_onAccessibilitySnapshot( | 178 Java_WebContentsImpl_onAccessibilitySnapshot( |
| 182 env, j_root.obj(), callback.obj()); | 179 env, j_root.obj(), callback.obj()); |
| 183 } | 180 } |
| 184 | 181 |
| 185 } // namespace | 182 } // namespace |
| 186 | 183 |
| 187 // static | 184 // static |
| 188 WebContents* WebContents::FromJavaWebContents( | 185 WebContents* WebContents::FromJavaWebContents( |
| 189 jobject jweb_contents_android) { | 186 jobject jweb_contents_android) { |
| 190 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 187 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 } | 589 } |
| 593 | 590 |
| 594 jint WebContentsAndroid::GetThemeColor(JNIEnv* env, | 591 jint WebContentsAndroid::GetThemeColor(JNIEnv* env, |
| 595 const JavaParamRef<jobject>& obj) { | 592 const JavaParamRef<jobject>& obj) { |
| 596 return web_contents_->GetThemeColor(); | 593 return web_contents_->GetThemeColor(); |
| 597 } | 594 } |
| 598 | 595 |
| 599 void WebContentsAndroid::RequestAccessibilitySnapshot( | 596 void WebContentsAndroid::RequestAccessibilitySnapshot( |
| 600 JNIEnv* env, | 597 JNIEnv* env, |
| 601 const JavaParamRef<jobject>& obj, | 598 const JavaParamRef<jobject>& obj, |
| 602 const JavaParamRef<jobject>& callback, | 599 const JavaParamRef<jobject>& callback) { |
| 603 jfloat y_offset, | |
| 604 jfloat x_scroll) { | |
| 605 // Secure the Java callback in a scoped object and give ownership of it to the | 600 // Secure the Java callback in a scoped object and give ownership of it to the |
| 606 // base::Callback. | 601 // base::Callback. |
| 607 ScopedJavaGlobalRef<jobject> j_callback; | 602 ScopedJavaGlobalRef<jobject> j_callback; |
| 608 j_callback.Reset(env, callback); | 603 j_callback.Reset(env, callback); |
| 609 gfx::DeviceDisplayInfo device_info; | 604 gfx::DeviceDisplayInfo device_info; |
| 610 ContentViewCoreImpl* contentViewCore = | |
| 611 ContentViewCoreImpl::FromWebContents(web_contents_); | |
| 612 | 605 |
| 613 AccessibilitySnapshotParams* params = new AccessibilitySnapshotParams( | |
| 614 contentViewCore->GetScaleFactor(), y_offset, x_scroll); | |
| 615 WebContentsImpl::AXTreeSnapshotCallback snapshot_callback = | 606 WebContentsImpl::AXTreeSnapshotCallback snapshot_callback = |
| 616 base::Bind(&AXTreeSnapshotCallback, j_callback, base::Owned(params)); | 607 base::Bind(&AXTreeSnapshotCallback, j_callback); |
| 617 static_cast<WebContentsImpl*>(web_contents_)->RequestAXTreeSnapshot( | 608 static_cast<WebContentsImpl*>(web_contents_)->RequestAXTreeSnapshot( |
| 618 snapshot_callback); | 609 snapshot_callback); |
| 619 } | 610 } |
| 620 | 611 |
| 621 void WebContentsAndroid::ResumeMediaSession(JNIEnv* env, | 612 void WebContentsAndroid::ResumeMediaSession(JNIEnv* env, |
| 622 const JavaParamRef<jobject>& obj) { | 613 const JavaParamRef<jobject>& obj) { |
| 623 web_contents_->ResumeMediaSession(); | 614 web_contents_->ResumeMediaSession(); |
| 624 } | 615 } |
| 625 | 616 |
| 626 void WebContentsAndroid::SuspendMediaSession(JNIEnv* env, | 617 void WebContentsAndroid::SuspendMediaSession(JNIEnv* env, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 if (response == READBACK_SUCCESS) | 683 if (response == READBACK_SUCCESS) |
| 693 java_bitmap = gfx::ConvertToJavaBitmap(&bitmap); | 684 java_bitmap = gfx::ConvertToJavaBitmap(&bitmap); |
| 694 Java_WebContentsImpl_onGetContentBitmapFinished(env, | 685 Java_WebContentsImpl_onGetContentBitmapFinished(env, |
| 695 obj->obj(), | 686 obj->obj(), |
| 696 callback->obj(), | 687 callback->obj(), |
| 697 java_bitmap.obj(), | 688 java_bitmap.obj(), |
| 698 response); | 689 response); |
| 699 } | 690 } |
| 700 | 691 |
| 701 } // namespace content | 692 } // namespace content |
| OLD | NEW |