OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/chromeos/login/base_login_display_host.h" | 5 #include "chrome/browser/chromeos/login/login_display_host_impl.h" |
6 | 6 |
7 #include "ash/desktop_background/desktop_background_controller.h" | 7 #include "ash/desktop_background/desktop_background_controller.h" |
8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
9 #include "ash/shell_window_ids.h" | 9 #include "ash/shell_window_ids.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/prefs/pref_service.h" | 15 #include "base/prefs/pref_service.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 103 |
104 ui::Layer* GetLayer(views::Widget* widget) { | 104 ui::Layer* GetLayer(views::Widget* widget) { |
105 return widget->GetNativeView()->layer(); | 105 return widget->GetNativeView()->layer(); |
106 } | 106 } |
107 | 107 |
108 } // namespace | 108 } // namespace |
109 | 109 |
110 namespace chromeos { | 110 namespace chromeos { |
111 | 111 |
112 // static | 112 // static |
113 LoginDisplayHost* BaseLoginDisplayHost::default_host_ = NULL; | 113 LoginDisplayHost* LoginDisplayHostImpl::default_host_ = NULL; |
114 | 114 |
115 //////////////////////////////////////////////////////////////////////////////// | 115 //////////////////////////////////////////////////////////////////////////////// |
116 // BaseLoginDisplayHost, public | 116 // LoginDisplayHostImpl, public |
117 | 117 |
118 BaseLoginDisplayHost::BaseLoginDisplayHost(const gfx::Rect& background_bounds) | 118 LoginDisplayHostImpl::LoginDisplayHostImpl(const gfx::Rect& background_bounds) |
119 : background_bounds_(background_bounds), | 119 : background_bounds_(background_bounds), |
120 ALLOW_THIS_IN_INITIALIZER_LIST(pointer_factory_(this)), | 120 ALLOW_THIS_IN_INITIALIZER_LIST(pointer_factory_(this)), |
121 shutting_down_(false), | 121 shutting_down_(false), |
122 oobe_progress_bar_visible_(false), | 122 oobe_progress_bar_visible_(false), |
123 session_starting_(false) { | 123 session_starting_(false) { |
124 // We need to listen to CLOSE_ALL_BROWSERS_REQUEST but not APP_TERMINATIN | 124 // We need to listen to CLOSE_ALL_BROWSERS_REQUEST but not APP_TERMINATIN |
125 // because/ APP_TERMINATING will never be fired as long as this keeps | 125 // because/ APP_TERMINATING will never be fired as long as this keeps |
126 // ref-count. CLOSE_ALL_BROWSERS_REQUEST is safe here because there will be no | 126 // ref-count. CLOSE_ALL_BROWSERS_REQUEST is safe here because there will be no |
127 // browser instance that will block the shutdown. | 127 // browser instance that will block the shutdown. |
128 registrar_.Add(this, | 128 registrar_.Add(this, |
(...skipping 12 matching lines...) Expand all Loading... |
141 chrome::NOTIFICATION_LOGIN_USER_CHANGED, | 141 chrome::NOTIFICATION_LOGIN_USER_CHANGED, |
142 content::NotificationService::AllSources()); | 142 content::NotificationService::AllSources()); |
143 | 143 |
144 DCHECK(default_host_ == NULL); | 144 DCHECK(default_host_ == NULL); |
145 default_host_ = this; | 145 default_host_ = this; |
146 | 146 |
147 // Make sure chrome won't exit while we are at login/oobe screen. | 147 // Make sure chrome won't exit while we are at login/oobe screen. |
148 chrome::StartKeepAlive(); | 148 chrome::StartKeepAlive(); |
149 } | 149 } |
150 | 150 |
151 BaseLoginDisplayHost::~BaseLoginDisplayHost() { | 151 LoginDisplayHostImpl::~LoginDisplayHostImpl() { |
152 // Let chrome process exit after login/oobe screen if needed. | 152 // Let chrome process exit after login/oobe screen if needed. |
153 chrome::EndKeepAlive(); | 153 chrome::EndKeepAlive(); |
154 | 154 |
155 default_host_ = NULL; | 155 default_host_ = NULL; |
156 } | 156 } |
157 | 157 |
158 //////////////////////////////////////////////////////////////////////////////// | 158 //////////////////////////////////////////////////////////////////////////////// |
159 // BaseLoginDisplayHost, LoginDisplayHost implementation: | 159 // LoginDisplayHostImpl, LoginDisplayHost implementation: |
160 | 160 |
161 void BaseLoginDisplayHost::BeforeSessionStart() { | 161 void LoginDisplayHostImpl::BeforeSessionStart() { |
162 session_starting_ = true; | 162 session_starting_ = true; |
163 } | 163 } |
164 | 164 |
165 void BaseLoginDisplayHost::OnSessionStart() { | 165 void LoginDisplayHostImpl::OnSessionStart() { |
166 DVLOG(1) << "Session starting"; | 166 DVLOG(1) << "Session starting"; |
167 ash::Shell::GetInstance()-> | 167 ash::Shell::GetInstance()-> |
168 desktop_background_controller()->MoveDesktopToUnlockedContainer(); | 168 desktop_background_controller()->MoveDesktopToUnlockedContainer(); |
169 if (wizard_controller_.get()) | 169 if (wizard_controller_.get()) |
170 wizard_controller_->OnSessionStart(); | 170 wizard_controller_->OnSessionStart(); |
171 // Display host is deleted once animation is completed | 171 // Display host is deleted once animation is completed |
172 // since sign in screen widget has to stay alive. | 172 // since sign in screen widget has to stay alive. |
173 StartAnimation(); | 173 StartAnimation(); |
174 ShutdownDisplayHost(false); | 174 ShutdownDisplayHost(false); |
175 } | 175 } |
176 | 176 |
177 void BaseLoginDisplayHost::OnCompleteLogin() { | 177 void LoginDisplayHostImpl::OnCompleteLogin() { |
178 // Cancelling the |auto_enrollment_client_| now allows it to determine whether | 178 // Cancelling the |auto_enrollment_client_| now allows it to determine whether |
179 // its protocol finished before login was complete. | 179 // its protocol finished before login was complete. |
180 if (auto_enrollment_client_.get()) | 180 if (auto_enrollment_client_.get()) |
181 auto_enrollment_client_.release()->CancelAndDeleteSoon(); | 181 auto_enrollment_client_.release()->CancelAndDeleteSoon(); |
182 } | 182 } |
183 | 183 |
184 void BaseLoginDisplayHost::StartWizard( | 184 void LoginDisplayHostImpl::StartWizard( |
185 const std::string& first_screen_name, | 185 const std::string& first_screen_name, |
186 DictionaryValue* screen_parameters) { | 186 DictionaryValue* screen_parameters) { |
187 DVLOG(1) << "Starting wizard, first_screen_name: " << first_screen_name; | 187 DVLOG(1) << "Starting wizard, first_screen_name: " << first_screen_name; |
188 // Create and show the wizard. | 188 // Create and show the wizard. |
189 // Note, dtor of the old WizardController should be called before ctor of the | 189 // Note, dtor of the old WizardController should be called before ctor of the |
190 // new one, because "default_controller()" is updated there. So pure "reset()" | 190 // new one, because "default_controller()" is updated there. So pure "reset()" |
191 // is done before new controller creation. | 191 // is done before new controller creation. |
192 wizard_controller_.reset(); | 192 wizard_controller_.reset(); |
193 wizard_controller_.reset(CreateWizardController()); | 193 wizard_controller_.reset(CreateWizardController()); |
194 | 194 |
195 oobe_progress_bar_visible_ = !WizardController::IsDeviceRegistered(); | 195 oobe_progress_bar_visible_ = !WizardController::IsDeviceRegistered(); |
196 SetOobeProgressBarVisible(oobe_progress_bar_visible_); | 196 SetOobeProgressBarVisible(oobe_progress_bar_visible_); |
197 wizard_controller_->Init(first_screen_name, screen_parameters); | 197 wizard_controller_->Init(first_screen_name, screen_parameters); |
198 } | 198 } |
199 | 199 |
200 void BaseLoginDisplayHost::StartSignInScreen() { | 200 void LoginDisplayHostImpl::StartSignInScreen() { |
201 DVLOG(1) << "Starting sign in screen"; | 201 DVLOG(1) << "Starting sign in screen"; |
202 const chromeos::UserList& users = chromeos::UserManager::Get()->GetUsers(); | 202 const chromeos::UserList& users = chromeos::UserManager::Get()->GetUsers(); |
203 | 203 |
204 // Fix for users who updated device and thus never passed register screen. | 204 // Fix for users who updated device and thus never passed register screen. |
205 // If we already have users, we assume that it is not a second part of | 205 // If we already have users, we assume that it is not a second part of |
206 // OOBE. See http://crosbug.com/6289 | 206 // OOBE. See http://crosbug.com/6289 |
207 if (!WizardController::IsDeviceRegistered() && !users.empty()) { | 207 if (!WizardController::IsDeviceRegistered() && !users.empty()) { |
208 VLOG(1) << "Mark device registered because there are remembered users: " | 208 VLOG(1) << "Mark device registered because there are remembered users: " |
209 << users.size(); | 209 << users.size(); |
210 WizardController::MarkDeviceRegistered(); | 210 WizardController::MarkDeviceRegistered(); |
(...skipping 16 matching lines...) Expand all Loading... |
227 ServicesCustomizationDocument::GetInstance()->StartFetching(); | 227 ServicesCustomizationDocument::GetInstance()->StartFetching(); |
228 | 228 |
229 // Initiate mobile config load. | 229 // Initiate mobile config load. |
230 MobileConfig::GetInstance(); | 230 MobileConfig::GetInstance(); |
231 | 231 |
232 // Initiate device policy fetching. | 232 // Initiate device policy fetching. |
233 g_browser_process->browser_policy_connector()->ScheduleServiceInitialization( | 233 g_browser_process->browser_policy_connector()->ScheduleServiceInitialization( |
234 kPolicyServiceInitializationDelayMilliseconds); | 234 kPolicyServiceInitializationDelayMilliseconds); |
235 } | 235 } |
236 | 236 |
237 WizardController* BaseLoginDisplayHost::GetWizardController() { | 237 WizardController* LoginDisplayHostImpl::GetWizardController() { |
238 return wizard_controller_.get(); | 238 return wizard_controller_.get(); |
239 } | 239 } |
240 | 240 |
241 void BaseLoginDisplayHost::ResumeSignInScreen() { | 241 void LoginDisplayHostImpl::ResumeSignInScreen() { |
242 // We only get here after a previous call the StartSignInScreen. That sign-in | 242 // We only get here after a previous call the StartSignInScreen. That sign-in |
243 // was successful but was interrupted by an auto-enrollment execution; once | 243 // was successful but was interrupted by an auto-enrollment execution; once |
244 // auto-enrollment is complete we resume the normal login flow from here. | 244 // auto-enrollment is complete we resume the normal login flow from here. |
245 DVLOG(1) << "Resuming sign in screen"; | 245 DVLOG(1) << "Resuming sign in screen"; |
246 CHECK(sign_in_controller_.get()); | 246 CHECK(sign_in_controller_.get()); |
247 SetOobeProgressBarVisible(oobe_progress_bar_visible_); | 247 SetOobeProgressBarVisible(oobe_progress_bar_visible_); |
248 SetStatusAreaVisible(true); | 248 SetStatusAreaVisible(true); |
249 SetShutdownButtonEnabled(true); | 249 SetShutdownButtonEnabled(true); |
250 sign_in_controller_->ResumeLogin(); | 250 sign_in_controller_->ResumeLogin(); |
251 } | 251 } |
252 | 252 |
253 void BaseLoginDisplayHost::CheckForAutoEnrollment() { | 253 void LoginDisplayHostImpl::CheckForAutoEnrollment() { |
254 // This method is called when the controller determines that the | 254 // This method is called when the controller determines that the |
255 // auto-enrollment check can start. This happens either after the EULA is | 255 // auto-enrollment check can start. This happens either after the EULA is |
256 // accepted, or right after a reboot if the EULA has already been accepted. | 256 // accepted, or right after a reboot if the EULA has already been accepted. |
257 | 257 |
258 if (policy::AutoEnrollmentClient::IsDisabled()) { | 258 if (policy::AutoEnrollmentClient::IsDisabled()) { |
259 VLOG(1) << "CheckForAutoEnrollment: auto-enrollment disabled"; | 259 VLOG(1) << "CheckForAutoEnrollment: auto-enrollment disabled"; |
260 return; | 260 return; |
261 } | 261 } |
262 | 262 |
263 // Start by checking if the device has already been owned. | 263 // Start by checking if the device has already been owned. |
264 pointer_factory_.InvalidateWeakPtrs(); | 264 pointer_factory_.InvalidateWeakPtrs(); |
265 DeviceSettingsService::Get()->GetOwnershipStatusAsync( | 265 DeviceSettingsService::Get()->GetOwnershipStatusAsync( |
266 base::Bind(&BaseLoginDisplayHost::OnOwnershipStatusCheckDone, | 266 base::Bind(&LoginDisplayHostImpl::OnOwnershipStatusCheckDone, |
267 pointer_factory_.GetWeakPtr())); | 267 pointer_factory_.GetWeakPtr())); |
268 } | 268 } |
269 | 269 |
270 //////////////////////////////////////////////////////////////////////////////// | 270 //////////////////////////////////////////////////////////////////////////////// |
271 // BaseLoginDisplayHost, content:NotificationObserver implementation: | 271 // LoginDisplayHostImpl, content:NotificationObserver implementation: |
272 | 272 |
273 void BaseLoginDisplayHost::Observe( | 273 void LoginDisplayHostImpl::Observe( |
274 int type, | 274 int type, |
275 const content::NotificationSource& source, | 275 const content::NotificationSource& source, |
276 const content::NotificationDetails& details) { | 276 const content::NotificationDetails& details) { |
277 if (type == chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST) { | 277 if (type == chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST) { |
278 ShutdownDisplayHost(true); | 278 ShutdownDisplayHost(true); |
279 } else if (type == chrome::NOTIFICATION_BROWSER_OPENED && session_starting_) { | 279 } else if (type == chrome::NOTIFICATION_BROWSER_OPENED && session_starting_) { |
280 // Browsers created before session start (windows opened by extensions, for | 280 // Browsers created before session start (windows opened by extensions, for |
281 // example) are ignored. | 281 // example) are ignored. |
282 OnBrowserCreated(); | 282 OnBrowserCreated(); |
283 registrar_.Remove(this, | 283 registrar_.Remove(this, |
284 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST, | 284 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST, |
285 content::NotificationService::AllSources()); | 285 content::NotificationService::AllSources()); |
286 registrar_.Remove(this, | 286 registrar_.Remove(this, |
287 chrome::NOTIFICATION_BROWSER_OPENED, | 287 chrome::NOTIFICATION_BROWSER_OPENED, |
288 content::NotificationService::AllSources()); | 288 content::NotificationService::AllSources()); |
289 } else if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED && | 289 } else if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED && |
290 chromeos::UserManager::Get()->IsCurrentUserNew()) { | 290 chromeos::UserManager::Get()->IsCurrentUserNew()) { |
291 // For new user, move desktop to locker container so that windows created | 291 // For new user, move desktop to locker container so that windows created |
292 // during the user image picker step are below it. | 292 // during the user image picker step are below it. |
293 ash::Shell::GetInstance()-> | 293 ash::Shell::GetInstance()-> |
294 desktop_background_controller()->MoveDesktopToLockedContainer(); | 294 desktop_background_controller()->MoveDesktopToLockedContainer(); |
295 registrar_.Remove(this, | 295 registrar_.Remove(this, |
296 chrome::NOTIFICATION_LOGIN_USER_CHANGED, | 296 chrome::NOTIFICATION_LOGIN_USER_CHANGED, |
297 content::NotificationService::AllSources()); | 297 content::NotificationService::AllSources()); |
298 } | 298 } |
299 } | 299 } |
300 | 300 |
301 void BaseLoginDisplayHost::ShutdownDisplayHost(bool post_quit_task) { | 301 void LoginDisplayHostImpl::ShutdownDisplayHost(bool post_quit_task) { |
302 if (shutting_down_) | 302 if (shutting_down_) |
303 return; | 303 return; |
304 | 304 |
305 shutting_down_ = true; | 305 shutting_down_ = true; |
306 registrar_.RemoveAll(); | 306 registrar_.RemoveAll(); |
307 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 307 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
308 if (post_quit_task) | 308 if (post_quit_task) |
309 MessageLoop::current()->Quit(); | 309 MessageLoop::current()->Quit(); |
310 } | 310 } |
311 | 311 |
312 void BaseLoginDisplayHost::StartAnimation() { | 312 void LoginDisplayHostImpl::StartAnimation() { |
313 if (ash::Shell::GetContainer( | 313 if (ash::Shell::GetContainer( |
314 ash::Shell::GetPrimaryRootWindow(), | 314 ash::Shell::GetPrimaryRootWindow(), |
315 ash::internal::kShellWindowId_DesktopBackgroundContainer)-> | 315 ash::internal::kShellWindowId_DesktopBackgroundContainer)-> |
316 children().empty()) { | 316 children().empty()) { |
317 // If there is no background window, don't perform any animation on the | 317 // If there is no background window, don't perform any animation on the |
318 // default and background layer because there is nothing behind it. | 318 // default and background layer because there is nothing behind it. |
319 return; | 319 return; |
320 } | 320 } |
321 | 321 |
322 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 322 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
323 switches::kDisableLoginAnimations)) | 323 switches::kDisableLoginAnimations)) |
324 ash::Shell::GetInstance()->DoInitialWorkspaceAnimation(); | 324 ash::Shell::GetInstance()->DoInitialWorkspaceAnimation(); |
325 } | 325 } |
326 | 326 |
327 void BaseLoginDisplayHost::OnOwnershipStatusCheckDone( | 327 void LoginDisplayHostImpl::OnOwnershipStatusCheckDone( |
328 DeviceSettingsService::OwnershipStatus status, | 328 DeviceSettingsService::OwnershipStatus status, |
329 bool current_user_is_owner) { | 329 bool current_user_is_owner) { |
330 if (status != DeviceSettingsService::OWNERSHIP_NONE) { | 330 if (status != DeviceSettingsService::OWNERSHIP_NONE) { |
331 // The device is already owned. No need for auto-enrollment checks. | 331 // The device is already owned. No need for auto-enrollment checks. |
332 VLOG(1) << "CheckForAutoEnrollment: device already owned"; | 332 VLOG(1) << "CheckForAutoEnrollment: device already owned"; |
333 return; | 333 return; |
334 } | 334 } |
335 | 335 |
336 // Kick off the auto-enrollment client. | 336 // Kick off the auto-enrollment client. |
337 if (auto_enrollment_client_.get()) { | 337 if (auto_enrollment_client_.get()) { |
338 // They client might have been started after the EULA screen, but we made | 338 // They client might have been started after the EULA screen, but we made |
339 // it to the login screen before it finished. In that case let the current | 339 // it to the login screen before it finished. In that case let the current |
340 // client proceed. | 340 // client proceed. |
341 // | 341 // |
342 // CheckForAutoEnrollment() is also called when we reach the sign-in screen, | 342 // CheckForAutoEnrollment() is also called when we reach the sign-in screen, |
343 // because that's what happens after an auto-update. | 343 // because that's what happens after an auto-update. |
344 VLOG(1) << "CheckForAutoEnrollment: client already started"; | 344 VLOG(1) << "CheckForAutoEnrollment: client already started"; |
345 | 345 |
346 // If the client already started and already finished too, pass the decision | 346 // If the client already started and already finished too, pass the decision |
347 // to the |sign_in_controller_| now. | 347 // to the |sign_in_controller_| now. |
348 if (auto_enrollment_client_->should_auto_enroll()) | 348 if (auto_enrollment_client_->should_auto_enroll()) |
349 ForceAutoEnrollment(); | 349 ForceAutoEnrollment(); |
350 } else { | 350 } else { |
351 VLOG(1) << "CheckForAutoEnrollment: starting auto-enrollment client"; | 351 VLOG(1) << "CheckForAutoEnrollment: starting auto-enrollment client"; |
352 auto_enrollment_client_.reset(policy::AutoEnrollmentClient::Create( | 352 auto_enrollment_client_.reset(policy::AutoEnrollmentClient::Create( |
353 base::Bind(&BaseLoginDisplayHost::OnAutoEnrollmentClientDone, | 353 base::Bind(&LoginDisplayHostImpl::OnAutoEnrollmentClientDone, |
354 base::Unretained(this)))); | 354 base::Unretained(this)))); |
355 auto_enrollment_client_->Start(); | 355 auto_enrollment_client_->Start(); |
356 } | 356 } |
357 } | 357 } |
358 | 358 |
359 void BaseLoginDisplayHost::OnAutoEnrollmentClientDone() { | 359 void LoginDisplayHostImpl::OnAutoEnrollmentClientDone() { |
360 bool auto_enroll = auto_enrollment_client_->should_auto_enroll(); | 360 bool auto_enroll = auto_enrollment_client_->should_auto_enroll(); |
361 VLOG(1) << "OnAutoEnrollmentClientDone, decision is " << auto_enroll; | 361 VLOG(1) << "OnAutoEnrollmentClientDone, decision is " << auto_enroll; |
362 | 362 |
363 if (auto_enroll) | 363 if (auto_enroll) |
364 ForceAutoEnrollment(); | 364 ForceAutoEnrollment(); |
365 } | 365 } |
366 | 366 |
367 void BaseLoginDisplayHost::ForceAutoEnrollment() { | 367 void LoginDisplayHostImpl::ForceAutoEnrollment() { |
368 if (sign_in_controller_.get()) | 368 if (sign_in_controller_.get()) |
369 sign_in_controller_->DoAutoEnrollment(); | 369 sign_in_controller_->DoAutoEnrollment(); |
370 } | 370 } |
371 | 371 |
372 // Declared in login_wizard.h so that others don't need to depend on our .h. | 372 // Declared in login_wizard.h so that others don't need to depend on our .h. |
373 // TODO(nkostylev): Split this into a smaller functions. | 373 // TODO(nkostylev): Split this into a smaller functions. |
374 void ShowLoginWizard(const std::string& first_screen_name, | 374 void ShowLoginWizard(const std::string& first_screen_name, |
375 const gfx::Size& size) { | 375 const gfx::Size& size) { |
376 if (browser_shutdown::IsTryingToQuit()) | 376 if (browser_shutdown::IsTryingToQuit()) |
377 return; | 377 return; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 VLOG(1) << "Initial time zone: " << timezone_name; | 503 VLOG(1) << "Initial time zone: " << timezone_name; |
504 // Apply locale customizations only once to preserve whatever locale | 504 // Apply locale customizations only once to preserve whatever locale |
505 // user has changed to during OOBE. | 505 // user has changed to during OOBE. |
506 if (!timezone_name.empty()) { | 506 if (!timezone_name.empty()) { |
507 chromeos::system::TimezoneSettings::GetInstance()->SetTimezoneFromID( | 507 chromeos::system::TimezoneSettings::GetInstance()->SetTimezoneFromID( |
508 UTF8ToUTF16(timezone_name)); | 508 UTF8ToUTF16(timezone_name)); |
509 } | 509 } |
510 } | 510 } |
511 | 511 |
512 } // namespace chromeos | 512 } // namespace chromeos |
OLD | NEW |