Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(846)

Side by Side Diff: remoting/host/me2me_preference_pane.mm

Issue 10446091: Prompt user before restarting System Preferences. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Send notification if user cancels the "restart" alert Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 }
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)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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.
Jamie 2012/06/01 18:53:26 Please clarify that it is only the check that is s
Lambros 2012/06/05 17:57:39 Done.
535 NSString* this_version = [this_plist objectForKey:@"CFBundleVersion"]; 545 if (!is_pane_disabled_) {
546 NSBundle* this_bundle = [NSBundle bundleForClass:[self class]];
547 NSDictionary* this_plist = [this_bundle infoDictionary];
548 NSString* this_version = [this_plist objectForKey:@"CFBundleVersion"];
536 549
537 NSString* bundle_path = [this_bundle bundlePath]; 550 NSString* bundle_path = [this_bundle bundlePath];
538 NSString* plist_path = 551 NSString* plist_path =
539 [bundle_path stringByAppendingString:@"/Contents/Info.plist"]; 552 [bundle_path stringByAppendingString:@"/Contents/Info.plist"];
540 NSDictionary* disk_plist = 553 NSDictionary* disk_plist =
541 [NSDictionary dictionaryWithContentsOfFile:plist_path]; 554 [NSDictionary dictionaryWithContentsOfFile:plist_path];
542 NSString* disk_version = [disk_plist objectForKey:@"CFBundleVersion"]; 555 NSString* disk_version = [disk_plist objectForKey:@"CFBundleVersion"];
543 556
544 if (disk_version == nil) { 557 if (disk_version == nil) {
545 LOG(ERROR) << "Failed to get installed version information"; 558 LOG(ERROR) << "Failed to get installed version information";
546 [self showError]; 559 [self showError];
547 return NO; 560 return;
561 }
562
563 if ([this_version isEqualToString:disk_version]) {
564 return;
565 }
566
567 is_pane_disabled_ = YES;
Jamie 2012/06/01 18:53:26 This is a bit confusing. I guess the pane is disab
Lambros 2012/06/05 17:57:39 It indicates that the pane is disabled because ver
568 [self updateUI];
548 } 569 }
549 570
550 if ([this_version isEqualToString:disk_version]) { 571 NSWindow* window = [[self mainView] window];
551 return NO; 572 if (window == nil) {
573 // Defer the alert until |didSelect| is called, which happens just after
574 // the window is created.
Jamie 2012/06/01 18:53:26 Under what circumstances can this happen? Presumab
Lambros 2012/06/05 17:57:39 Open the pref-pane, close it (leaving System Prefe
575 return;
576 }
577
578 // This alert appears as a sheet over the top of the Chromoting pref-pane,
579 // underneath the title, so it's OK to refer to "this preference pane" rather
580 // than repeat the title "Chromoting" here.
581 NSAlert* alert = [[NSAlert alloc] init];
582 [alert setMessageText:@"System update detected"];
583 [alert setInformativeText:@"To use this preference pane, System Preferences "
584 "needs to be restarted"];
585 [alert addButtonWithTitle:@"OK"];
586 NSButton* cancel_button = [alert addButtonWithTitle:@"Cancel"];
587 [cancel_button setKeyEquivalent:@"\e"];
Jamie 2012/06/01 18:53:26 No key equivalent for OK?
Lambros 2012/06/05 17:57:39 I think the first button already becomes the defau
588 [alert setAlertStyle:NSWarningAlertStyle];
589 [alert beginSheetModalForWindow:window
590 modalDelegate:self
591 didEndSelector:@selector(
592 mismatchAlertDidEnd:returnCode:contextInfo:)
593 contextInfo:nil];
594 [alert release];
595 }
596
597 - (void)mismatchAlertDidEnd:(NSAlert*)alert
598 returnCode:(NSInteger)returnCode
599 contextInfo:(void*)contextInfo {
600 if (returnCode == NSAlertFirstButtonReturn) {
601 // OK was pressed.
602
603 // Dismiss the alert window here, so that the application will respond to
604 // the NSApp terminate: message.
605 [[alert window] orderOut:nil];
606 [self restartSystemPreferences];
552 } else { 607 } else {
553 // Terminate and relaunch System Preferences. 608 // Cancel was pressed.
554 609
555 // TODO(lambroslambrou): Improve this when System Preferences supports 610 // If there is a new config file, delete it and notify the web-app of
556 // dynamic reloading of pref-panes. 611 // failure to apply the config. Otherwise, the web-app will remain in a
557 NSTask* task = [[NSTask alloc] init]; 612 // spinning state until System Preferences eventually gets restarted and
558 NSArray* arguments = [NSArray arrayWithObjects:@"--relaunch-prefpane", nil]; 613 // the user visits this pane again.
559 [task setLaunchPath:[NSString stringWithUTF8String:kHelperTool]]; 614 std::string file;
560 [task setArguments:arguments]; 615 if (!GetTemporaryConfigFilePath(&file)) {
561 [task setStandardInput:[NSPipe pipe]]; 616 // There's no point in alerting the user here. The same error would
562 [task launch]; 617 // happen when the pane is eventually restarted, so the user would be
563 [task release]; 618 // alerted at that time.
564 [NSApp terminate:nil]; 619 LOG(ERROR) << "Failed to get path of configuration data.";
565 return YES; 620 return;
621 }
622 if (access(file.c_str(), F_OK) != 0)
Jamie 2012/06/01 18:53:26 Is this check needed? Can't we just let remove fai
Lambros 2012/06/05 17:57:39 I don't think we want to send an UpdateFailed noti
623 return;
624
625 remove(file.c_str());
626 [self notifyPlugin:kUpdateFailedNotificationName];
Jamie 2012/06/01 18:53:26 I think this needs to be moved above the early ret
Lambros 2012/06/05 17:57:39 Same as above.
566 } 627 }
567 } 628 }
568 629
630 - (void)restartSystemPreferences {
631 // TODO(lambroslambrou): Improve this when System Preferences supports
632 // dynamic reloading of pref-panes.
Jamie 2012/06/01 18:53:26 Is there any reason to expect that this will happe
Lambros 2012/06/05 17:57:39 No :) Done.
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
OLDNEW
« remoting/host/me2me_preference_pane.h ('K') | « remoting/host/me2me_preference_pane.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698