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

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: Rename variable and move check out of readNewConfig 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
« no previous file with comments | « remoting/host/me2me_preference_pane.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « remoting/host/me2me_preference_pane.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698