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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 [self readNewConfig]; |
| 183 [self updateUI]; | 183 [self updateUI]; |
| 184 } | 184 } |
| 185 | 185 |
| 186 - (void)didSelect { | |
| 187 [self checkInstalledVersion]; | |
| 188 } | |
| 189 | |
| 186 - (void)willUnselect { | 190 - (void)willUnselect { |
| 187 NSDistributedNotificationCenter* center = | 191 NSDistributedNotificationCenter* center = |
| 188 [NSDistributedNotificationCenter defaultCenter]; | 192 [NSDistributedNotificationCenter defaultCenter]; |
| 189 [center removeObserver:self]; | 193 [center removeObserver:self]; |
| 190 | 194 |
| 191 [service_status_timer_ invalidate]; | 195 [service_status_timer_ invalidate]; |
| 192 [service_status_timer_ release]; | 196 [service_status_timer_ release]; |
| 193 service_status_timer_ = nil; | 197 service_status_timer_ = nil; |
| 194 if (have_new_config_) { | 198 if (have_new_config_) { |
| 195 [self notifyPlugin:kUpdateFailedNotificationName]; | 199 [self notifyPlugin:kUpdateFailedNotificationName]; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 - (void)updateServiceStatus { | 278 - (void)updateServiceStatus { |
| 275 pid_t job_pid = base::mac::PIDForJob(kServiceName); | 279 pid_t job_pid = base::mac::PIDForJob(kServiceName); |
| 276 is_service_running_ = (job_pid > 0); | 280 is_service_running_ = (job_pid > 0); |
| 277 } | 281 } |
| 278 | 282 |
| 279 - (void)updateAuthorizationStatus { | 283 - (void)updateAuthorizationStatus { |
| 280 is_pane_unlocked_ = [authorization_view_ updateStatus:authorization_view_]; | 284 is_pane_unlocked_ = [authorization_view_ updateStatus:authorization_view_]; |
| 281 } | 285 } |
| 282 | 286 |
| 283 - (void)readNewConfig { | 287 - (void)readNewConfig { |
| 284 if ([self restartPanelIfDifferentVersionInstalled]) { | 288 [self checkInstalledVersion]; |
| 285 // Don't read any new config if the version is mismatched. Return control | 289 if (is_pane_disabled_) { |
| 286 // to the main run-loop instead, so the application can be terminated. | 290 // Don't read or delete any new config here if the version is mismatched. |
| 291 // When the pane restarts, it should see the new config file. | |
| 287 return; | 292 return; |
| 288 } | 293 } |
|
Jamie
2012/06/06 16:26:49
As my previous remark states, I don't think either
Lambros
2012/06/07 00:25:28
Done.
| |
| 289 | 294 |
| 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 |
| (...skipping 45 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 !is_pane_disabled_)]; |
| 361 [confirm_pin_view_ setEnabled:(is_pane_unlocked_ && !is_pane_disabled_)]; | |
| 356 [confirm_pin_view_ setEmail:base::SysUTF8ToNSString(email)]; | 362 [confirm_pin_view_ setEmail:base::SysUTF8ToNSString(email)]; |
| 357 NSString* applyButtonText = is_service_running_ ? @"Confirm" : @"Enable"; | 363 NSString* applyButtonText = is_service_running_ ? @"Confirm" : @"Enable"; |
| 358 [confirm_pin_view_ setButtonText:applyButtonText]; | 364 [confirm_pin_view_ setButtonText:applyButtonText]; |
| 365 | |
| 366 if (is_pane_disabled_) { | |
| 367 [authorization_view_ setEnabled:NO]; | |
| 368 } | |
| 359 } | 369 } |
| 360 | 370 |
| 361 - (void)showError { | 371 - (void)showError { |
| 362 NSAlert* alert = [[NSAlert alloc] init]; | 372 NSAlert* alert = [[NSAlert alloc] init]; |
| 363 [alert setMessageText:@"An unexpected error occurred."]; | 373 [alert setMessageText:@"An unexpected error occurred."]; |
| 364 [alert setInformativeText:@"Check the system log for more information."]; | 374 [alert setInformativeText:@"Check the system log for more information."]; |
| 365 [alert setAlertStyle:NSWarningAlertStyle]; | 375 [alert setAlertStyle:NSWarningAlertStyle]; |
| 366 [alert beginSheetModalForWindow:[[self mainView] window] | 376 [alert beginSheetModalForWindow:[[self mainView] window] |
| 367 modalDelegate:nil | 377 modalDelegate:nil |
| 368 didEndSelector:nil | 378 didEndSelector:nil |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 | 532 |
| 523 - (void)notifyPlugin:(const char*)message { | 533 - (void)notifyPlugin:(const char*)message { |
| 524 NSDistributedNotificationCenter* center = | 534 NSDistributedNotificationCenter* center = |
| 525 [NSDistributedNotificationCenter defaultCenter]; | 535 [NSDistributedNotificationCenter defaultCenter]; |
| 526 NSString* name = [NSString stringWithUTF8String:message]; | 536 NSString* name = [NSString stringWithUTF8String:message]; |
| 527 [center postNotificationName:name | 537 [center postNotificationName:name |
| 528 object:nil | 538 object:nil |
| 529 userInfo:nil]; | 539 userInfo:nil]; |
| 530 } | 540 } |
| 531 | 541 |
| 532 - (BOOL)restartPanelIfDifferentVersionInstalled { | 542 - (void)checkInstalledVersion { |
| 533 NSBundle* this_bundle = [NSBundle bundleForClass:[self class]]; | 543 // There's no point repeating the check if the pane has already been disabled |
| 534 NSDictionary* this_plist = [this_bundle infoDictionary]; | 544 // from a previous call to this method. The pane only gets disabled when a |
| 535 NSString* this_version = [this_plist objectForKey:@"CFBundleVersion"]; | 545 // version-mismatch has been detected here, so skip the check, but continue to |
| 546 // handle the version-mismatch case. | |
| 547 if (!is_pane_disabled_) { | |
| 548 NSBundle* this_bundle = [NSBundle bundleForClass:[self class]]; | |
| 549 NSDictionary* this_plist = [this_bundle infoDictionary]; | |
| 550 NSString* this_version = [this_plist objectForKey:@"CFBundleVersion"]; | |
| 536 | 551 |
| 537 NSString* bundle_path = [this_bundle bundlePath]; | 552 NSString* bundle_path = [this_bundle bundlePath]; |
| 538 NSString* plist_path = | 553 NSString* plist_path = |
| 539 [bundle_path stringByAppendingString:@"/Contents/Info.plist"]; | 554 [bundle_path stringByAppendingString:@"/Contents/Info.plist"]; |
| 540 NSDictionary* disk_plist = | 555 NSDictionary* disk_plist = |
| 541 [NSDictionary dictionaryWithContentsOfFile:plist_path]; | 556 [NSDictionary dictionaryWithContentsOfFile:plist_path]; |
| 542 NSString* disk_version = [disk_plist objectForKey:@"CFBundleVersion"]; | 557 NSString* disk_version = [disk_plist objectForKey:@"CFBundleVersion"]; |
| 543 | 558 |
| 544 if (disk_version == nil) { | 559 if (disk_version == nil) { |
| 545 LOG(ERROR) << "Failed to get installed version information"; | 560 LOG(ERROR) << "Failed to get installed version information"; |
| 546 [self showError]; | 561 [self showError]; |
| 547 return NO; | 562 return; |
| 563 } | |
| 564 | |
| 565 if ([this_version isEqualToString:disk_version]) { | |
| 566 return; | |
| 567 } | |
| 568 | |
| 569 is_pane_disabled_ = YES; | |
| 570 [self updateUI]; | |
| 548 } | 571 } |
| 549 | 572 |
| 550 if ([this_version isEqualToString:disk_version]) { | 573 NSWindow* window = [[self mainView] window]; |
| 551 return NO; | 574 if (window == nil) { |
| 575 // Defer the alert until |didSelect| is called, which happens just after | |
| 576 // the window is created. | |
| 577 return; | |
| 578 } | |
| 579 | |
| 580 // This alert appears as a sheet over the top of the Chromoting pref-pane, | |
| 581 // underneath the title, so it's OK to refer to "this preference pane" rather | |
| 582 // than repeat the title "Chromoting" here. | |
| 583 NSAlert* alert = [[NSAlert alloc] init]; | |
| 584 [alert setMessageText:@"System update detected"]; | |
| 585 [alert setInformativeText:@"To use this preference pane, System Preferences " | |
| 586 "needs to be restarted"]; | |
| 587 [alert addButtonWithTitle:@"OK"]; | |
| 588 NSButton* cancel_button = [alert addButtonWithTitle:@"Cancel"]; | |
| 589 [cancel_button setKeyEquivalent:@"\e"]; | |
| 590 [alert setAlertStyle:NSWarningAlertStyle]; | |
| 591 [alert beginSheetModalForWindow:window | |
| 592 modalDelegate:self | |
| 593 didEndSelector:@selector( | |
| 594 mismatchAlertDidEnd:returnCode:contextInfo:) | |
| 595 contextInfo:nil]; | |
| 596 [alert release]; | |
| 597 } | |
| 598 | |
| 599 - (void)mismatchAlertDidEnd:(NSAlert*)alert | |
| 600 returnCode:(NSInteger)returnCode | |
| 601 contextInfo:(void*)contextInfo { | |
| 602 if (returnCode == NSAlertFirstButtonReturn) { | |
| 603 // OK was pressed. | |
| 604 | |
| 605 // Dismiss the alert window here, so that the application will respond to | |
| 606 // the NSApp terminate: message. | |
| 607 [[alert window] orderOut:nil]; | |
| 608 [self restartSystemPreferences]; | |
| 552 } else { | 609 } else { |
| 553 // Terminate and relaunch System Preferences. | 610 // Cancel was pressed. |
| 554 | 611 |
| 555 // TODO(lambroslambrou): Improve this when System Preferences supports | 612 // If there is a new config file, delete it and notify the web-app of |
| 556 // dynamic reloading of pref-panes. | 613 // failure to apply the config. Otherwise, the web-app will remain in a |
| 557 NSTask* task = [[NSTask alloc] init]; | 614 // spinning state until System Preferences eventually gets restarted and |
| 558 NSArray* arguments = [NSArray arrayWithObjects:@"--relaunch-prefpane", nil]; | 615 // the user visits this pane again. |
| 559 [task setLaunchPath:[NSString stringWithUTF8String:kHelperTool]]; | 616 std::string file; |
| 560 [task setArguments:arguments]; | 617 if (!GetTemporaryConfigFilePath(&file)) { |
| 561 [task setStandardInput:[NSPipe pipe]]; | 618 // There's no point in alerting the user here. The same error would |
| 562 [task launch]; | 619 // happen when the pane is eventually restarted, so the user would be |
| 563 [task release]; | 620 // alerted at that time. |
| 564 [NSApp terminate:nil]; | 621 LOG(ERROR) << "Failed to get path of configuration data."; |
| 565 return YES; | 622 return; |
| 623 } | |
| 624 if (access(file.c_str(), F_OK) != 0) | |
| 625 return; | |
| 626 | |
| 627 remove(file.c_str()); | |
| 628 [self notifyPlugin:kUpdateFailedNotificationName]; | |
| 566 } | 629 } |
| 567 } | 630 } |
| 568 | 631 |
| 632 - (void)restartSystemPreferences { | |
| 633 NSTask* task = [[NSTask alloc] init]; | |
| 634 NSArray* arguments = [NSArray arrayWithObjects:@"--relaunch-prefpane", nil]; | |
| 635 [task setLaunchPath:[NSString stringWithUTF8String:kHelperTool]]; | |
| 636 [task setArguments:arguments]; | |
| 637 [task setStandardInput:[NSPipe pipe]]; | |
| 638 [task launch]; | |
| 639 [task release]; | |
| 640 [NSApp terminate:nil]; | |
| 641 } | |
| 642 | |
| 569 @end | 643 @end |
| OLD | NEW |