OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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/service/remoting/chromoting_host_manager.h" | |
6 | |
7 #include "base/path_service.h" | |
8 #include "chrome/common/chrome_paths.h" | |
9 #include "chrome/common/guid.h" | |
10 #include "chrome/common/remoting/chromoting_host_info.h" | |
11 #include "net/base/net_util.h" | |
12 #include "remoting/base/constants.h" | |
13 #include "remoting/host/chromoting_host_context.h" | |
14 #include "remoting/host/heartbeat_sender.h" | |
15 #include "remoting/host/host_key_pair.h" | |
16 #include "remoting/host/json_host_config.h" | |
17 | |
18 namespace remoting { | |
19 | |
20 ChromotingHostManager::ChromotingHostManager(Observer* observer) | |
21 : observer_(observer), | |
22 main_message_loop_(NULL) { | |
23 } | |
24 | |
25 void ChromotingHostManager::Initialize( | |
26 MessageLoopForUI* main_message_loop, | |
27 base::MessageLoopProxy* file_message_loop) { | |
28 FilePath user_data_dir; | |
29 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); | |
30 FilePath chromoting_config_path = | |
31 user_data_dir.Append(FILE_PATH_LITERAL(".ChromotingConfig.json")); | |
32 remoting::JsonHostConfig* config = new remoting::JsonHostConfig( | |
33 chromoting_config_path, file_message_loop); | |
34 if (!config->Read()) { | |
35 VLOG(1) << "Failed to read chromoting config file."; | |
36 } | |
37 | |
38 main_message_loop_ = main_message_loop; | |
39 chromoting_config_ = config; | |
40 | |
41 if (!IsConfigInitialized()) { | |
42 InitializeConfig(); | |
43 } | |
44 | |
45 if (IsEnabled()) { | |
46 // TODO(wez): Need to callback the Observer so that ServiceProcess | |
47 // knows to stay alive to service Chromoting requests. | |
48 // This will go away once we have a more consistent model for the | |
49 // service process internals. | |
50 observer_->OnChromotingHostEnabled(); | |
51 Start(); | |
52 } | |
53 } | |
54 | |
55 void ChromotingHostManager::Teardown(Task* done_task) { | |
56 Stop(done_task); | |
57 } | |
58 | |
59 ChromotingHostManager::~ChromotingHostManager() { | |
60 DCHECK(!chromoting_host_); | |
61 DCHECK(!chromoting_context_.get()); | |
62 } | |
63 | |
64 bool ChromotingHostManager::IsConfigInitialized() { | |
65 std::string host_id; | |
66 if (!chromoting_config_->GetString(remoting::kHostIdConfigPath, &host_id)) | |
67 return false; | |
68 | |
69 return guid::IsValidGUID(host_id); | |
70 } | |
71 | |
72 void ChromotingHostManager::InitializeConfig() { | |
73 VLOG(1) << "Initializing static chromoting host parameters."; | |
74 | |
75 // TODO(hclam): This is a time consuming operation so we should run it on | |
76 // a separate thread. | |
77 remoting::HostKeyPair host_key_pair; | |
78 host_key_pair.Generate(); | |
79 std::string host_id(guid::GenerateGUID()); | |
80 std::string hostname(net::GetHostName()); | |
81 | |
82 chromoting_config_->SetBoolean(remoting::kHostEnabledConfigPath, false); | |
83 chromoting_config_->SetString(remoting::kHostIdConfigPath, host_id); | |
84 chromoting_config_->SetString(remoting::kHostNameConfigPath, hostname); | |
85 host_key_pair.Save(chromoting_config_); | |
86 | |
87 // Save updated values on the disk. | |
88 chromoting_config_->Save(); | |
89 } | |
90 | |
91 void ChromotingHostManager::SetCredentials(const std::string& login, | |
92 const std::string& token) { | |
93 chromoting_config_->SetString(remoting::kXmppLoginConfigPath, login); | |
94 chromoting_config_->SetString(remoting::kXmppAuthTokenConfigPath, token); | |
95 | |
96 // Save updated values on the disk. | |
97 chromoting_config_->Save(); | |
98 } | |
99 | |
100 void ChromotingHostManager::Enable() { | |
101 // We have already started. | |
102 if (IsEnabled()) | |
103 return; | |
104 | |
105 SetEnabled(true); | |
106 observer_->OnChromotingHostEnabled(); | |
107 | |
108 Start(); | |
109 } | |
110 | |
111 void ChromotingHostManager::Disable() { | |
112 if (!IsEnabled()) | |
113 return; | |
114 | |
115 SetEnabled(false); | |
116 | |
117 // TODO(hclam): Immediately reporting will cause threading problems | |
118 // ServiceProcess thinks we can shutdown safely. | |
119 observer_->OnChromotingHostDisabled(); | |
120 | |
121 Stop(NULL); | |
122 } | |
123 | |
124 void ChromotingHostManager::GetHostInfo(ChromotingHostInfo* host_info) { | |
125 chromoting_config_->GetString(remoting::kHostIdConfigPath, | |
126 &host_info->host_id); | |
127 chromoting_config_->GetString(remoting::kHostNameConfigPath, | |
128 &host_info->hostname); | |
129 HostKeyPair key_pair; | |
130 if (key_pair.Load(chromoting_config_)) { | |
131 host_info->public_key = key_pair.GetPublicKey(); | |
132 } | |
133 | |
134 host_info->enabled = IsEnabled(); | |
135 | |
136 chromoting_config_->GetString(remoting::kXmppLoginConfigPath, | |
137 &host_info->login); | |
138 } | |
139 | |
140 void ChromotingHostManager::Stop(Task* done_task) { | |
141 // Stop the host if it is started. | |
142 if (chromoting_host_) { | |
143 // Save the shutdown task, it will be executed when chromoting host | |
144 // is stopped. | |
145 shutdown_task_.reset(done_task); | |
146 | |
147 // Shutdown the chromoting host asynchronously. | |
148 chromoting_host_->Shutdown(); | |
149 } else if (done_task) { | |
150 done_task->Run(); | |
151 delete done_task; | |
152 } | |
153 } | |
154 | |
155 bool ChromotingHostManager::IsEnabled() { | |
156 bool enabled; | |
157 if (!chromoting_config_->GetBoolean(remoting::kHostEnabledConfigPath, | |
158 &enabled)) { | |
159 enabled = false; | |
160 } | |
161 return enabled; | |
162 } | |
163 | |
164 void ChromotingHostManager::SetEnabled(bool enabled) { | |
165 chromoting_config_->SetBoolean(remoting::kHostEnabledConfigPath, | |
166 enabled); | |
167 chromoting_config_->Save(); | |
168 } | |
169 | |
170 void ChromotingHostManager::Start() { | |
171 // Don't do anything if we already started. | |
172 if (chromoting_host_.get()) | |
173 return; | |
174 | |
175 // Start the chromoting context first. | |
176 chromoting_context_.reset( | |
177 new remoting::ChromotingHostContext(main_message_loop_)); | |
178 chromoting_context_->Start(); | |
179 | |
180 // Create a chromoting host object. | |
181 chromoting_host_ = remoting::ChromotingHost::Create(chromoting_context_.get(), | |
182 chromoting_config_); | |
183 | |
184 // Initialize HeartbeatSender. | |
185 scoped_refptr<remoting::HeartbeatSender> heartbeat_sender = | |
186 new remoting::HeartbeatSender(chromoting_context_->network_message_loop(), | |
187 chromoting_config_); | |
188 if (!heartbeat_sender->Init()) | |
189 LOG(ERROR) << "Failed to initialize heartbeat sender."; | |
190 chromoting_host_->AddStatusObserver(heartbeat_sender); | |
191 | |
192 | |
193 // Then start the chromoting host. | |
194 // When ChromotingHost is shutdown because of failure or a request that | |
195 // we made OnChromotingShutdown() is calls. | |
196 chromoting_host_->Start( | |
197 NewRunnableMethod(this, &ChromotingHostManager::OnShutdown)); | |
198 } | |
199 | |
200 void ChromotingHostManager::OnShutdown() { | |
201 if (MessageLoop::current() != main_message_loop_) { | |
202 main_message_loop_->PostTask(FROM_HERE, | |
203 NewRunnableMethod(this, &ChromotingHostManager::OnShutdown)); | |
204 return; | |
205 } | |
206 chromoting_context_->Stop(); | |
207 chromoting_context_.reset(); | |
208 chromoting_host_ = NULL; | |
209 | |
210 if (shutdown_task_.get()) { | |
211 shutdown_task_->Run(); | |
212 shutdown_task_.reset(); | |
213 } | |
214 } | |
215 | |
216 } // namespace remoting | |
OLD | NEW |