Chromium Code Reviews| 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 #import "remoting/host/me2me_preference_pane.h" | 5 #import "remoting/host/me2me_preference_pane.h" |
| 6 | 6 |
| 7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 #include <CommonCrypto/CommonHMAC.h> | 8 #include <CommonCrypto/CommonHMAC.h> |
| 9 #include <launch.h> | 9 #include <launch.h> |
| 10 #import <PreferencePanes/PreferencePanes.h> | 10 #import <PreferencePanes/PreferencePanes.h> |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 object:nil]; | 172 object:nil]; |
| 173 | 173 |
| 174 service_status_timer_ = | 174 service_status_timer_ = |
| 175 [[NSTimer scheduledTimerWithTimeInterval:2.0 | 175 [[NSTimer scheduledTimerWithTimeInterval:2.0 |
| 176 target:self | 176 target:self |
| 177 selector:@selector(refreshServiceStatus:) | 177 selector:@selector(refreshServiceStatus:) |
| 178 userInfo:nil | 178 userInfo:nil |
| 179 repeats:YES] retain]; | 179 repeats:YES] retain]; |
| 180 [self updateServiceStatus]; | 180 [self updateServiceStatus]; |
| 181 [self updateAuthorizationStatus]; | 181 [self updateAuthorizationStatus]; |
| 182 [self readNewConfig]; | 182 |
| 183 [self checkInstalledVersion]; | |
| 184 if (!restart_pending_or_canceled_) | |
|
Jamie
2012/06/07 20:41:35
Nit: You've used a mix of braced and unbraced one-
Lambros
2012/06/14 00:36:34
Done.
| |
| 185 [self readNewConfig]; | |
| 186 | |
| 183 [self updateUI]; | 187 [self updateUI]; |
| 184 } | 188 } |
| 185 | 189 |
| 190 - (void)didSelect { | |
| 191 [self checkInstalledVersion]; | |
| 192 } | |
| 193 | |
| 186 - (void)willUnselect { | 194 - (void)willUnselect { |
| 187 NSDistributedNotificationCenter* center = | 195 NSDistributedNotificationCenter* center = |
| 188 [NSDistributedNotificationCenter defaultCenter]; | 196 [NSDistributedNotificationCenter defaultCenter]; |
| 189 [center removeObserver:self]; | 197 [center removeObserver:self]; |
| 190 | 198 |
| 191 [service_status_timer_ invalidate]; | 199 [service_status_timer_ invalidate]; |
| 192 [service_status_timer_ release]; | 200 [service_status_timer_ release]; |
| 193 service_status_timer_ = nil; | 201 service_status_timer_ = nil; |
| 194 if (have_new_config_) { | 202 if (have_new_config_) { |
| 195 [self notifyPlugin:kUpdateFailedNotificationName]; | 203 [self notifyPlugin:kUpdateFailedNotificationName]; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 return; | 246 return; |
| 239 } | 247 } |
| 240 | 248 |
| 241 // Stop the launchd job. This cannot easily be done by the helper tool, | 249 // Stop the launchd job. This cannot easily be done by the helper tool, |
| 242 // since the launchd job runs in the current user's context. | 250 // since the launchd job runs in the current user's context. |
| 243 [self sendJobControlMessage:LAUNCH_KEY_STOPJOB]; | 251 [self sendJobControlMessage:LAUNCH_KEY_STOPJOB]; |
| 244 awaiting_service_stop_ = YES; | 252 awaiting_service_stop_ = YES; |
| 245 } | 253 } |
| 246 | 254 |
| 247 - (void)onNewConfigFile:(NSNotification*)notification { | 255 - (void)onNewConfigFile:(NSNotification*)notification { |
| 248 [self readNewConfig]; | 256 [self checkInstalledVersion]; |
| 257 if (!restart_pending_or_canceled_) | |
| 258 [self readNewConfig]; | |
| 259 | |
| 249 [self updateUI]; | 260 [self updateUI]; |
| 250 } | 261 } |
| 251 | 262 |
| 252 - (void)refreshServiceStatus:(NSTimer*)timer { | 263 - (void)refreshServiceStatus:(NSTimer*)timer { |
| 253 BOOL was_running = is_service_running_; | 264 BOOL was_running = is_service_running_; |
| 254 [self updateServiceStatus]; | 265 [self updateServiceStatus]; |
| 255 if (awaiting_service_stop_ && !is_service_running_) { | 266 if (awaiting_service_stop_ && !is_service_running_) { |
| 256 awaiting_service_stop_ = NO; | 267 awaiting_service_stop_ = NO; |
| 257 [self notifyPlugin:kUpdateSucceededNotificationName]; | 268 [self notifyPlugin:kUpdateSucceededNotificationName]; |
| 258 } | 269 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 274 - (void)updateServiceStatus { | 285 - (void)updateServiceStatus { |
| 275 pid_t job_pid = base::mac::PIDForJob(kServiceName); | 286 pid_t job_pid = base::mac::PIDForJob(kServiceName); |
| 276 is_service_running_ = (job_pid > 0); | 287 is_service_running_ = (job_pid > 0); |
| 277 } | 288 } |
| 278 | 289 |
| 279 - (void)updateAuthorizationStatus { | 290 - (void)updateAuthorizationStatus { |
| 280 is_pane_unlocked_ = [authorization_view_ updateStatus:authorization_view_]; | 291 is_pane_unlocked_ = [authorization_view_ updateStatus:authorization_view_]; |
| 281 } | 292 } |
| 282 | 293 |
| 283 - (void)readNewConfig { | 294 - (void)readNewConfig { |
| 284 if ([self restartPanelIfDifferentVersionInstalled]) { | |
| 285 // Don't read any new config if the version is mismatched. Return control | |
| 286 // to the main run-loop instead, so the application can be terminated. | |
| 287 return; | |
| 288 } | |
| 289 | |
| 290 std::string file; | 295 std::string file; |
| 291 if (!GetTemporaryConfigFilePath(&file)) { | 296 if (!GetTemporaryConfigFilePath(&file)) { |
| 292 LOG(ERROR) << "Failed to get path of configuration data."; | 297 LOG(ERROR) << "Failed to get path of configuration data."; |
| 293 [self showError]; | 298 [self showError]; |
| 294 return; | 299 return; |
| 295 } | 300 } |
| 296 if (access(file.c_str(), F_OK) != 0) | 301 if (access(file.c_str(), F_OK) != 0) |
| 297 return; | 302 return; |
| 298 | 303 |
| 299 scoped_ptr<remoting::JsonHostConfig> new_config_( | 304 scoped_ptr<remoting::JsonHostConfig> new_config_( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 [status_message_ setStringValue:message]; | 349 [status_message_ setStringValue:message]; |
| 345 | 350 |
| 346 std::string email; | 351 std::string email; |
| 347 if (config_.get()) { | 352 if (config_.get()) { |
| 348 bool result = config_->GetString(remoting::kXmppLoginConfigPath, &email); | 353 bool result = config_->GetString(remoting::kXmppLoginConfigPath, &email); |
| 349 | 354 |
| 350 // The config has already been checked by |IsConfigValid|. | 355 // The config has already been checked by |IsConfigValid|. |
| 351 DCHECK(result); | 356 DCHECK(result); |
| 352 } | 357 } |
| 353 | 358 |
| 354 [disable_view_ setEnabled:(is_pane_unlocked_ && is_service_running_)]; | 359 [disable_view_ setEnabled:(is_pane_unlocked_ && is_service_running_ && |
| 355 [confirm_pin_view_ setEnabled:is_pane_unlocked_]; | 360 !restart_pending_or_canceled_)]; |
| 361 [confirm_pin_view_ setEnabled:(is_pane_unlocked_ && | |
| 362 !restart_pending_or_canceled_)]; | |
| 356 [confirm_pin_view_ setEmail:base::SysUTF8ToNSString(email)]; | 363 [confirm_pin_view_ setEmail:base::SysUTF8ToNSString(email)]; |
| 357 NSString* applyButtonText = is_service_running_ ? @"Confirm" : @"Enable"; | 364 NSString* applyButtonText = is_service_running_ ? @"Confirm" : @"Enable"; |
| 358 [confirm_pin_view_ setButtonText:applyButtonText]; | 365 [confirm_pin_view_ setButtonText:applyButtonText]; |
| 366 | |
| 367 if (restart_pending_or_canceled_) { | |
| 368 [authorization_view_ setEnabled:NO]; | |
| 369 } | |
| 359 } | 370 } |
| 360 | 371 |
| 361 - (void)showError { | 372 - (void)showError { |
| 362 NSAlert* alert = [[NSAlert alloc] init]; | 373 NSAlert* alert = [[NSAlert alloc] init]; |
| 363 [alert setMessageText:@"An unexpected error occurred."]; | 374 [alert setMessageText:@"An unexpected error occurred."]; |
| 364 [alert setInformativeText:@"Check the system log for more information."]; | 375 [alert setInformativeText:@"Check the system log for more information."]; |
| 365 [alert setAlertStyle:NSWarningAlertStyle]; | 376 [alert setAlertStyle:NSWarningAlertStyle]; |
| 366 [alert beginSheetModalForWindow:[[self mainView] window] | 377 [alert beginSheetModalForWindow:[[self mainView] window] |
| 367 modalDelegate:nil | 378 modalDelegate:nil |
| 368 didEndSelector:nil | 379 didEndSelector:nil |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 | 533 |
| 523 - (void)notifyPlugin:(const char*)message { | 534 - (void)notifyPlugin:(const char*)message { |
| 524 NSDistributedNotificationCenter* center = | 535 NSDistributedNotificationCenter* center = |
| 525 [NSDistributedNotificationCenter defaultCenter]; | 536 [NSDistributedNotificationCenter defaultCenter]; |
| 526 NSString* name = [NSString stringWithUTF8String:message]; | 537 NSString* name = [NSString stringWithUTF8String:message]; |
| 527 [center postNotificationName:name | 538 [center postNotificationName:name |
| 528 object:nil | 539 object:nil |
| 529 userInfo:nil]; | 540 userInfo:nil]; |
| 530 } | 541 } |
| 531 | 542 |
| 532 - (BOOL)restartPanelIfDifferentVersionInstalled { | 543 - (void)checkInstalledVersion { |
| 533 NSBundle* this_bundle = [NSBundle bundleForClass:[self class]]; | 544 // There's no point repeating the check if the pane has already been disabled |
| 534 NSDictionary* this_plist = [this_bundle infoDictionary]; | 545 // from a previous call to this method. The pane only gets disabled when a |
| 535 NSString* this_version = [this_plist objectForKey:@"CFBundleVersion"]; | 546 // version-mismatch has been detected here, so skip the check, but continue to |
| 547 // handle the version-mismatch case. | |
| 548 if (!restart_pending_or_canceled_) { | |
| 549 NSBundle* this_bundle = [NSBundle bundleForClass:[self class]]; | |
| 550 NSDictionary* this_plist = [this_bundle infoDictionary]; | |
| 551 NSString* this_version = [this_plist objectForKey:@"CFBundleVersion"]; | |
| 536 | 552 |
| 537 NSString* bundle_path = [this_bundle bundlePath]; | 553 NSString* bundle_path = [this_bundle bundlePath]; |
| 538 NSString* plist_path = | 554 NSString* plist_path = |
| 539 [bundle_path stringByAppendingString:@"/Contents/Info.plist"]; | 555 [bundle_path stringByAppendingString:@"/Contents/Info.plist"]; |
| 540 NSDictionary* disk_plist = | 556 NSDictionary* disk_plist = |
| 541 [NSDictionary dictionaryWithContentsOfFile:plist_path]; | 557 [NSDictionary dictionaryWithContentsOfFile:plist_path]; |
| 542 NSString* disk_version = [disk_plist objectForKey:@"CFBundleVersion"]; | 558 NSString* disk_version = [disk_plist objectForKey:@"CFBundleVersion"]; |
| 543 | 559 |
| 544 if (disk_version == nil) { | 560 if (disk_version == nil) { |
| 545 LOG(ERROR) << "Failed to get installed version information"; | 561 LOG(ERROR) << "Failed to get installed version information"; |
| 546 [self showError]; | 562 [self showError]; |
| 547 return NO; | 563 return; |
| 564 } | |
| 565 | |
| 566 if ([this_version isEqualToString:disk_version]) { | |
| 567 return; | |
| 568 } | |
| 569 | |
| 570 restart_pending_or_canceled_ = YES; | |
| 571 [self updateUI]; | |
| 548 } | 572 } |
| 549 | 573 |
| 550 if ([this_version isEqualToString:disk_version]) { | 574 NSWindow* window = [[self mainView] window]; |
| 551 return NO; | 575 if (window == nil) { |
| 576 // Defer the alert until |didSelect| is called, which happens just after | |
| 577 // the window is created. | |
| 578 return; | |
| 579 } | |
| 580 | |
| 581 // This alert appears as a sheet over the top of the Chromoting pref-pane, | |
| 582 // underneath the title, so it's OK to refer to "this preference pane" rather | |
| 583 // than repeat the title "Chromoting" here. | |
| 584 NSAlert* alert = [[NSAlert alloc] init]; | |
| 585 [alert setMessageText:@"System update detected"]; | |
| 586 [alert setInformativeText:@"To use this preference pane, System Preferences " | |
| 587 "needs to be restarted"]; | |
| 588 [alert addButtonWithTitle:@"OK"]; | |
| 589 NSButton* cancel_button = [alert addButtonWithTitle:@"Cancel"]; | |
| 590 [cancel_button setKeyEquivalent:@"\e"]; | |
| 591 [alert setAlertStyle:NSWarningAlertStyle]; | |
| 592 [alert beginSheetModalForWindow:window | |
| 593 modalDelegate:self | |
| 594 didEndSelector:@selector( | |
| 595 mismatchAlertDidEnd:returnCode:contextInfo:) | |
| 596 contextInfo:nil]; | |
| 597 [alert release]; | |
| 598 } | |
| 599 | |
| 600 - (void)mismatchAlertDidEnd:(NSAlert*)alert | |
| 601 returnCode:(NSInteger)returnCode | |
| 602 contextInfo:(void*)contextInfo { | |
| 603 if (returnCode == NSAlertFirstButtonReturn) { | |
| 604 // OK was pressed. | |
| 605 | |
| 606 // Dismiss the alert window here, so that the application will respond to | |
| 607 // the NSApp terminate: message. | |
| 608 [[alert window] orderOut:nil]; | |
| 609 [self restartSystemPreferences]; | |
| 552 } else { | 610 } else { |
| 553 // Terminate and relaunch System Preferences. | 611 // Cancel was pressed. |
| 554 | 612 |
| 555 // TODO(lambroslambrou): Improve this when System Preferences supports | 613 // If there is a new config file, delete it and notify the web-app of |
| 556 // dynamic reloading of pref-panes. | 614 // failure to apply the config. Otherwise, the web-app will remain in a |
| 557 NSTask* task = [[NSTask alloc] init]; | 615 // spinning state until System Preferences eventually gets restarted and |
| 558 NSArray* arguments = [NSArray arrayWithObjects:@"--relaunch-prefpane", nil]; | 616 // the user visits this pane again. |
| 559 [task setLaunchPath:[NSString stringWithUTF8String:kHelperTool]]; | 617 std::string file; |
| 560 [task setArguments:arguments]; | 618 if (!GetTemporaryConfigFilePath(&file)) { |
| 561 [task setStandardInput:[NSPipe pipe]]; | 619 // There's no point in alerting the user here. The same error would |
| 562 [task launch]; | 620 // happen when the pane is eventually restarted, so the user would be |
| 563 [task release]; | 621 // alerted at that time. |
| 564 [NSApp terminate:nil]; | 622 LOG(ERROR) << "Failed to get path of configuration data."; |
| 565 return YES; | 623 return; |
| 624 } | |
| 625 if (access(file.c_str(), F_OK) != 0) | |
| 626 return; | |
| 627 | |
| 628 remove(file.c_str()); | |
| 629 [self notifyPlugin:kUpdateFailedNotificationName]; | |
| 566 } | 630 } |
| 567 } | 631 } |
| 568 | 632 |
| 633 - (void)restartSystemPreferences { | |
| 634 NSTask* task = [[NSTask alloc] init]; | |
| 635 NSArray* arguments = [NSArray arrayWithObjects:@"--relaunch-prefpane", nil]; | |
| 636 [task setLaunchPath:[NSString stringWithUTF8String:kHelperTool]]; | |
| 637 [task setArguments:arguments]; | |
| 638 [task setStandardInput:[NSPipe pipe]]; | |
| 639 [task launch]; | |
| 640 [task release]; | |
| 641 [NSApp terminate:nil]; | |
| 642 } | |
| 643 | |
| 569 @end | 644 @end |
| OLD | NEW |