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

Side by Side Diff: chrome/browser/android/contextualsearch/search_action.cc

Issue 2211353002: [TTS] Gather surrounding text on Tap before any UX. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplified the results for the native accessors to the context. Removed print statements. Created 4 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/android/contextualsearch/search_action.h"
6
7 #include <set>
8
9 #include "base/android/jni_string.h"
10 #include "base/bind.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/android/contextualsearch/contextual_search_context.h"
14 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "jni/SearchAction_jni.h"
17 #include "url/gurl.h"
18
19 using base::android::ConvertUTF8ToJavaString;
20 using base::android::JavaParamRef;
21 using base::android::ScopedJavaGlobalRef;
22 using content::WebContents;
23
24 namespace {
25 const int kSurroundingTextSize = 1536;
Theresa 2016/09/01 16:49:37 nit: where did 1536 come from?
Donn Denman 2016/09/02 16:40:43 Done: added the comment "Context length is set to
26 }
27
28 SearchAction::SearchAction(JNIEnv* env, jobject obj) {
29 java_object_.Reset(env, obj);
30 }
31
32 SearchAction::~SearchAction() {
33 JNIEnv* env = base::android::AttachCurrentThread();
34 Java_SearchAction_clearNativePointer(env, java_object_.obj());
35 }
36
37 void SearchAction::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
38 delete this;
39 }
40
41 void SearchAction::RequestSurroundingText(
42 JNIEnv* env,
43 const JavaParamRef<jobject>& obj,
44 const JavaParamRef<jobject>& j_web_contents) {
45 WebContents* web_contents =
46 WebContents::FromJavaWebContents(j_web_contents.obj());
47 DCHECK(web_contents);
48
49 GURL url(web_contents->GetURL());
50 std::string encoding(web_contents->GetEncoding());
51 search_context_.reset(new ContextualSearchContext(true, url, encoding));
52
53 content::RenderFrameHost* focused_frame = web_contents->GetFocusedFrame();
54 if (!focused_frame) {
55 OnSurroundingTextResponse(base::string16(), 0, 0);
56 } else {
57 focused_frame->RequestTextSurroundingSelection(
58 base::Bind(&SearchAction::OnSurroundingTextResponse, AsWeakPtr()),
59 kSurroundingTextSize);
60 }
61 }
62
63 void SearchAction::OnSurroundingTextResponse(
64 const base::string16& surrounding_text,
65 int focus_start,
66 int focus_end) {
67 // Record the context, which can be accessed later on demand.
68 search_context_->surrounding_text = surrounding_text;
69 search_context_->start_offset = focus_start;
70 search_context_->end_offset = focus_end;
71
72 // Notify Java.
73 JNIEnv* env = base::android::AttachCurrentThread();
74 Java_SearchAction_onSurroundingTextResponse(env, java_object_.obj());
75 }
76
77 std::string SearchAction::FindFocusedWord() {
78 DCHECK(search_context_);
79 // Find the focused word.
80 std::pair<int, int> focus = FindFocusedWord(search_context_->surrounding_text,
81 search_context_->start_offset,
82 search_context_->end_offset);
83 return base::UTF16ToUTF8(search_context_->surrounding_text.substr(
84 focus.first, focus.second - focus.first));
85 }
86
87 std::string SearchAction::GetSampleText(int sample_length) {
88 DCHECK(search_context_);
89 // Trim surroundings to the requested sample size.
90 std::pair<base::string16, int> sample = SampleSurroundings(
91 search_context_->surrounding_text, search_context_->start_offset,
92 search_context_->end_offset, sample_length);
93 return base::UTF16ToUTF8(sample.first);
94 }
95
96 // static
97 std::pair<int, int> SearchAction::FindFocusedWord(
pedro (no code reviews) 2016/08/31 22:38:22 Nit: Why not merge this method with the one with s
Donn Denman 2016/09/02 16:40:43 Done. It was tricky to figure out how to test non
98 const base::string16& surrounding_text,
99 int focus_start,
100 int focus_end) {
101 int surrounding_text_length = surrounding_text.length();
102
103 // First, we need to find the focused word boundaries.
104 int focused_word_start = focus_start;
105 int focused_word_end = focus_end;
106
107 if (surrounding_text_length > 0 &&
108 IsValidCharacter(surrounding_text[focused_word_start])) {
109 // Find focused word start (inclusive)
110 for (int i = focus_start; i >= 0; i--) {
111 focused_word_start = i;
112
113 wchar_t character;
114 if (i > 0) {
115 character = surrounding_text[i - 1];
116
117 if (!IsValidCharacter(character))
118 break;
119 }
120 }
121
122 // Find focused word end (non inclusive)
123 for (int i = focus_end; i < surrounding_text_length; i++) {
124 wchar_t character = surrounding_text[i];
125
126 if (IsValidCharacter(character)) {
127 focused_word_end = i + 1;
128 } else {
129 focused_word_end = i;
130 break;
131 }
132 }
133 }
134
135 return std::pair<int, int>(focused_word_start, focused_word_end);
136 }
137
138 // static
139 std::pair<base::string16, int> SearchAction::SampleSurroundings(
140 const base::string16& surrounding_text,
141 int focus_start,
142 int focus_end,
143 int surrounding_text_sample_limit) {
144 int surrounding_text_length = surrounding_text.length();
145
146 //---------------------------------------------------------------------------
147 // Cut the surrounding size so it can be sent to the Java side.
148
149 // Start equally distributing the size around the focal point.
150 int focal_point_size = focus_end - focus_start;
151 int sample_margin = (surrounding_text_sample_limit - focal_point_size) / 2;
152 int sample_start = focus_start - sample_margin;
153 int sample_end = focus_end + sample_margin;
154
155 // If the the start is out of bounds, compensate the end side.
156 if (sample_start < 0) {
157 sample_end -= sample_start;
158 sample_start = 0;
159 }
160
161 // If the the end is out of bounds, compensate the start side.
162 if (sample_end > surrounding_text_length) {
163 int diff = sample_end - surrounding_text_length;
164 sample_end = surrounding_text_length;
165 sample_start -= diff;
166 }
167
168 // Trim the start and end to make sure they are within bounds.
169 sample_start = std::max(0, sample_start);
170 sample_end = std::min(surrounding_text_length, sample_end);
171 base::string16 sample_string(
172 surrounding_text.substr(sample_start, sample_end - sample_start));
173 std::pair<base::string16, int> sample(sample_string, sample_start);
174 return sample;
175 }
176
177 // static
178 bool SearchAction::IsValidCharacter(int char_code) {
179 // See http://www.unicode.org/Public/UCD/latest/ucd/NamesList.txt
180 // See http://jrgraphix.net/research/unicode_blocks.php
181
182 // TODO(pedrosimonetti): should not include CJK characters!
pedro (no code reviews) 2016/08/31 22:38:22 Take over this TODO? This needs to be addressed or
Donn Denman 2016/09/02 16:40:43 Done. Note: With the current implementation sur
183 // TODO(donnd): consider using regular expressions.
184
185 if ((char_code >= 11264 && char_code <= 55295) || // Asian language symbols
186 (char_code >= 192 && char_code <= 8191) || // Letters in many languages
187 (char_code >= 97 && char_code <= 122) || // Lowercase letters
188 (char_code >= 65 && char_code <= 90) || // Uppercase letters
189 (char_code >= 48 && char_code <= 57)) { // Numbers
190 return true;
191 }
192
193 return false;
194 }
195
196 bool RegisterSearchAction(JNIEnv* env) {
197 return RegisterNativesImpl(env);
198 }
199
200 jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) {
201 SearchAction* content = new SearchAction(env, obj);
202 return reinterpret_cast<intptr_t>(content);
203 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698