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
3 // found in the LICENSE file.
5 #import "content/browser/renderer_host/text_input_client_mac.h"
7 #include "base/memory/singleton.h"
8 #include "base/metrics/histogram.h"
9 #include "base/threading/thread_restrictions.h"
10 #include "base/time.h"
11 #include "content/browser/renderer_host/render_widget_host_impl.h"
12 #include "content/common/text_input_client_messages.h"
16 // The amount of time in milliseconds that the browser process will wait for a
17 // response from the renderer.
18 // TODO(rsesek): Using the histogram data, find the best upper-bound for this
20 const float kWaitTimeout = 1500;
22 TextInputClientMac::TextInputClientMac()
23 : character_index_(NSNotFound),
28 TextInputClientMac::~TextInputClientMac() {
32 TextInputClientMac* TextInputClientMac::GetInstance() {
33 return Singleton<TextInputClientMac>::get();
36 NSUInteger TextInputClientMac::GetCharacterIndexAtPoint(RenderWidgetHost* rwh,
38 base::TimeTicks start = base::TimeTicks::Now();
41 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(rwh);
42 rwhi->Send(new TextInputClientMsg_CharacterIndexForPoint(rwhi->GetRoutingID(),
44 // http://crbug.com/121917
45 base::ThreadRestrictions::ScopedAllowWait allow_wait;
46 condition_.TimedWait(base::TimeDelta::FromMilliseconds(kWaitTimeout));
49 base::TimeDelta delta(base::TimeTicks::Now() - start);
50 UMA_HISTOGRAM_LONG_TIMES("TextInputClient.CharacterIndex",
51 delta * base::Time::kMicrosecondsPerMillisecond);
53 return character_index_;
56 NSRect TextInputClientMac::GetFirstRectForRange(RenderWidgetHost* rwh,
58 base::TimeTicks start = base::TimeTicks::Now();
61 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(rwh);
63 new TextInputClientMsg_FirstRectForCharacterRange(rwhi->GetRoutingID(),
65 // http://crbug.com/121917
66 base::ThreadRestrictions::ScopedAllowWait allow_wait;
67 condition_.TimedWait(base::TimeDelta::FromMilliseconds(kWaitTimeout));
70 base::TimeDelta delta(base::TimeTicks::Now() - start);
71 UMA_HISTOGRAM_LONG_TIMES("TextInputClient.FirstRect",
72 delta * base::Time::kMicrosecondsPerMillisecond);
77 NSAttributedString* TextInputClientMac::GetAttributedSubstringFromRange(
78 RenderWidgetHost* rwh,
80 base::TimeTicks start = base::TimeTicks::Now();
83 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(rwh);
84 rwhi->Send(new TextInputClientMsg_StringForRange(rwhi->GetRoutingID(),
86 // http://crbug.com/121917
87 base::ThreadRestrictions::ScopedAllowWait allow_wait;
88 condition_.TimedWait(base::TimeDelta::FromMilliseconds(kWaitTimeout));
91 base::TimeDelta delta(base::TimeTicks::Now() - start);
92 UMA_HISTOGRAM_LONG_TIMES("TextInputClient.Substring",
93 delta * base::Time::kMicrosecondsPerMillisecond);
95 // Lookup.framework calls this method repeatedly and expects that repeated
96 // calls don't deallocate previous results immediately. Returning an
97 // autoreleased string is better convention anyway.
98 return [[substring_.get() retain] autorelease];
101 void TextInputClientMac::SetCharacterIndexAndSignal(NSUInteger index) {
103 character_index_ = index;
108 void TextInputClientMac::SetFirstRectAndSignal(NSRect first_rect) {
110 first_rect_ = first_rect;
115 void TextInputClientMac::SetSubstringAndSignal(NSAttributedString* string) {
117 substring_.reset([string copy]);
122 void TextInputClientMac::BeforeRequest() {
123 base::TimeTicks start = base::TimeTicks::Now();
127 base::TimeDelta delta(base::TimeTicks::Now() - start);
128 UMA_HISTOGRAM_LONG_TIMES("TextInputClient.LockWait",
129 delta * base::Time::kMicrosecondsPerMillisecond);
131 character_index_ = NSNotFound;
132 first_rect_ = NSZeroRect;
136 void TextInputClientMac::AfterRequest() {
140 } // namespace content