OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "base/base_paths.h" | |
6 #include "base/bind.h" | |
7 #include "base/logging.h" | |
8 #include "base/path_service.h" | |
9 #include "base/strings/string16.h" | |
10 #include "content/browser/hyphenator/hyphenator_message_filter.h" | |
11 #include "content/common/hyphenator_messages.h" | |
12 #include "content/public/browser/browser_thread.h" | |
13 #include "content/public/browser/content_browser_client.h" | |
14 #include "content/public/browser/render_process_host.h" | |
15 | |
16 namespace content { | |
17 | |
18 namespace { | |
19 | |
20 // A helper function that closes the specified file in the FILE thread. This | |
21 // function may be called after the HyphenatorMessageFilter object that owns the | |
22 // specified file is deleted, i.e. this function must not depend on the object. | |
23 void CloseDictionary(base::PlatformFile file) { | |
24 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
25 base::ClosePlatformFile(file); | |
26 } | |
27 | |
28 } // namespace | |
29 | |
30 HyphenatorMessageFilter::HyphenatorMessageFilter( | |
31 RenderProcessHost* render_process_host) | |
32 : render_process_host_(render_process_host), | |
33 dictionary_file_(base::kInvalidPlatformFileValue), | |
34 weak_factory_(this) { | |
35 } | |
36 | |
37 HyphenatorMessageFilter::~HyphenatorMessageFilter() { | |
38 // Post a FILE task that deletes the dictionary file. This message filter is | |
39 // usually deleted on the IO thread, which does not allow file operations. | |
40 if (dictionary_file_ != base::kInvalidPlatformFileValue) { | |
41 BrowserThread::PostTask( | |
42 BrowserThread::FILE, | |
43 FROM_HERE, | |
44 base::Bind(&CloseDictionary, dictionary_file_)); | |
45 } | |
46 } | |
47 | |
48 void HyphenatorMessageFilter::SetDictionaryBase(const base::FilePath& base) { | |
49 dictionary_base_ = base; | |
50 } | |
51 | |
52 void HyphenatorMessageFilter::OverrideThreadForMessage( | |
53 const IPC::Message& message, | |
54 BrowserThread::ID* thread) { | |
55 if (message.type() == HyphenatorHostMsg_OpenDictionary::ID) | |
56 *thread = BrowserThread::UI; | |
57 } | |
58 | |
59 bool HyphenatorMessageFilter::OnMessageReceived( | |
60 const IPC::Message& message, | |
61 bool* message_was_ok) { | |
62 bool handled = true; | |
63 IPC_BEGIN_MESSAGE_MAP_EX(HyphenatorMessageFilter, | |
64 message, | |
65 *message_was_ok) | |
66 IPC_MESSAGE_HANDLER(HyphenatorHostMsg_OpenDictionary, OnOpenDictionary) | |
67 IPC_MESSAGE_UNHANDLED(handled = false) | |
68 IPC_END_MESSAGE_MAP_EX() | |
69 return handled; | |
70 } | |
71 | |
72 void HyphenatorMessageFilter::OnOpenDictionary(const string16& locale) { | |
73 if (dictionary_file_ != base::kInvalidPlatformFileValue) { | |
74 SendDictionary(); | |
75 return; | |
76 } | |
77 BrowserThread::PostTaskAndReply( | |
78 BrowserThread::FILE, | |
79 FROM_HERE, | |
80 base::Bind(&HyphenatorMessageFilter::OpenDictionary, this, locale), | |
81 base::Bind(&HyphenatorMessageFilter::SendDictionary, | |
82 weak_factory_.GetWeakPtr())); | |
83 } | |
84 | |
85 void HyphenatorMessageFilter::OpenDictionary(const string16& locale) { | |
86 DCHECK(dictionary_file_ == base::kInvalidPlatformFileValue); | |
87 | |
88 if (dictionary_base_.empty()) { | |
89 dictionary_base_ = | |
90 GetContentClient()->browser()->GetHyphenDictionaryDirectory(); | |
91 } | |
92 std::string rule_file = locale.empty() ? "en-US" : UTF16ToASCII(locale); | |
93 | |
94 // Currently, only en-US is hyphenated. This is a quick fix for | |
95 // http://crbug.com/167122. | |
96 // TODO(groby): The proper fix entails validating if locale is a properly | |
97 // formatted locale string, but knowledge about valid locales currently | |
98 // resides in chrome, not content. | |
99 if (rule_file != "en-US") | |
100 return; | |
101 rule_file.append("-1-0.dic"); | |
102 base::FilePath rule_path = dictionary_base_.AppendASCII(rule_file); | |
103 dictionary_file_ = base::CreatePlatformFile( | |
104 rule_path, | |
105 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN, | |
106 NULL, NULL); | |
107 } | |
108 | |
109 void HyphenatorMessageFilter::SendDictionary() { | |
110 IPC::PlatformFileForTransit file = IPC::InvalidPlatformFileForTransit(); | |
111 if (dictionary_file_ != base::kInvalidPlatformFileValue) { | |
112 file = IPC::GetFileHandleForProcess( | |
113 dictionary_file_, | |
114 render_process_host_->GetHandle(), | |
115 false); | |
116 } | |
117 Send(new HyphenatorMsg_SetDictionary(file)); | |
118 } | |
119 | |
120 } // namespace content | |
OLD | NEW |