Chromium Code Reviews| Index: remoting/host/me2me_preference_pane.mm |
| diff --git a/remoting/host/me2me_preference_pane.mm b/remoting/host/me2me_preference_pane.mm |
| index 723a28b98e56bcc2744a04d20df0811df8b10efd..d87436472f1d53067ce72f3d2932bbd6a62e652b 100644 |
| --- a/remoting/host/me2me_preference_pane.mm |
| +++ b/remoting/host/me2me_preference_pane.mm |
| @@ -183,6 +183,10 @@ std::string JsonHostConfig::GetSerializedData() const { |
| [self updateUI]; |
| } |
| +- (void)didSelect { |
| + [self checkInstalledVersion]; |
| +} |
| + |
| - (void)willUnselect { |
| NSDistributedNotificationCenter* center = |
| [NSDistributedNotificationCenter defaultCenter]; |
| @@ -281,9 +285,10 @@ std::string JsonHostConfig::GetSerializedData() const { |
| } |
| - (void)readNewConfig { |
| - if ([self restartPanelIfDifferentVersionInstalled]) { |
| - // Don't read any new config if the version is mismatched. Return control |
| - // to the main run-loop instead, so the application can be terminated. |
| + [self checkInstalledVersion]; |
| + if (is_pane_disabled_) { |
| + // Don't read or delete any new config here if the version is mismatched. |
| + // When the pane restarts, it should see the new config file. |
| return; |
| } |
| @@ -351,11 +356,16 @@ std::string JsonHostConfig::GetSerializedData() const { |
| DCHECK(result); |
| } |
| - [disable_view_ setEnabled:(is_pane_unlocked_ && is_service_running_)]; |
| - [confirm_pin_view_ setEnabled:is_pane_unlocked_]; |
| + [disable_view_ setEnabled:(is_pane_unlocked_ && is_service_running_ && |
| + !is_pane_disabled_)]; |
| + [confirm_pin_view_ setEnabled:(is_pane_unlocked_ && !is_pane_disabled_)]; |
| [confirm_pin_view_ setEmail:base::SysUTF8ToNSString(email)]; |
| NSString* applyButtonText = is_service_running_ ? @"Confirm" : @"Enable"; |
| [confirm_pin_view_ setButtonText:applyButtonText]; |
| + |
| + if (is_pane_disabled_) { |
| + [authorization_view_ setEnabled:NO]; |
| + } |
| } |
| - (void)showError { |
| @@ -529,41 +539,105 @@ std::string JsonHostConfig::GetSerializedData() const { |
| userInfo:nil]; |
| } |
| -- (BOOL)restartPanelIfDifferentVersionInstalled { |
| - NSBundle* this_bundle = [NSBundle bundleForClass:[self class]]; |
| - NSDictionary* this_plist = [this_bundle infoDictionary]; |
| - NSString* this_version = [this_plist objectForKey:@"CFBundleVersion"]; |
| +- (void)checkInstalledVersion { |
| + // There's no point repeating the check if the pane has already been disabled |
| + // 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.
|
| + if (!is_pane_disabled_) { |
| + NSBundle* this_bundle = [NSBundle bundleForClass:[self class]]; |
| + NSDictionary* this_plist = [this_bundle infoDictionary]; |
| + NSString* this_version = [this_plist objectForKey:@"CFBundleVersion"]; |
| + |
| + NSString* bundle_path = [this_bundle bundlePath]; |
| + NSString* plist_path = |
| + [bundle_path stringByAppendingString:@"/Contents/Info.plist"]; |
| + NSDictionary* disk_plist = |
| + [NSDictionary dictionaryWithContentsOfFile:plist_path]; |
| + NSString* disk_version = [disk_plist objectForKey:@"CFBundleVersion"]; |
| + |
| + if (disk_version == nil) { |
| + LOG(ERROR) << "Failed to get installed version information"; |
| + [self showError]; |
| + return; |
| + } |
| + |
| + if ([this_version isEqualToString:disk_version]) { |
| + return; |
| + } |
| - NSString* bundle_path = [this_bundle bundlePath]; |
| - NSString* plist_path = |
| - [bundle_path stringByAppendingString:@"/Contents/Info.plist"]; |
| - NSDictionary* disk_plist = |
| - [NSDictionary dictionaryWithContentsOfFile:plist_path]; |
| - NSString* disk_version = [disk_plist objectForKey:@"CFBundleVersion"]; |
| + 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
|
| + [self updateUI]; |
| + } |
| - if (disk_version == nil) { |
| - LOG(ERROR) << "Failed to get installed version information"; |
| - [self showError]; |
| - return NO; |
| + NSWindow* window = [[self mainView] window]; |
| + if (window == nil) { |
| + // Defer the alert until |didSelect| is called, which happens just after |
| + // 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
|
| + return; |
| } |
| - if ([this_version isEqualToString:disk_version]) { |
| - return NO; |
| + // This alert appears as a sheet over the top of the Chromoting pref-pane, |
| + // underneath the title, so it's OK to refer to "this preference pane" rather |
| + // than repeat the title "Chromoting" here. |
| + NSAlert* alert = [[NSAlert alloc] init]; |
| + [alert setMessageText:@"System update detected"]; |
| + [alert setInformativeText:@"To use this preference pane, System Preferences " |
| + "needs to be restarted"]; |
| + [alert addButtonWithTitle:@"OK"]; |
| + NSButton* cancel_button = [alert addButtonWithTitle:@"Cancel"]; |
| + [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
|
| + [alert setAlertStyle:NSWarningAlertStyle]; |
| + [alert beginSheetModalForWindow:window |
| + modalDelegate:self |
| + didEndSelector:@selector( |
| + mismatchAlertDidEnd:returnCode:contextInfo:) |
| + contextInfo:nil]; |
| + [alert release]; |
| +} |
| + |
| +- (void)mismatchAlertDidEnd:(NSAlert*)alert |
| + returnCode:(NSInteger)returnCode |
| + contextInfo:(void*)contextInfo { |
| + if (returnCode == NSAlertFirstButtonReturn) { |
| + // OK was pressed. |
| + |
| + // Dismiss the alert window here, so that the application will respond to |
| + // the NSApp terminate: message. |
| + [[alert window] orderOut:nil]; |
| + [self restartSystemPreferences]; |
| } else { |
| - // Terminate and relaunch System Preferences. |
| - |
| - // TODO(lambroslambrou): Improve this when System Preferences supports |
| - // dynamic reloading of pref-panes. |
| - NSTask* task = [[NSTask alloc] init]; |
| - NSArray* arguments = [NSArray arrayWithObjects:@"--relaunch-prefpane", nil]; |
| - [task setLaunchPath:[NSString stringWithUTF8String:kHelperTool]]; |
| - [task setArguments:arguments]; |
| - [task setStandardInput:[NSPipe pipe]]; |
| - [task launch]; |
| - [task release]; |
| - [NSApp terminate:nil]; |
| - return YES; |
| + // Cancel was pressed. |
| + |
| + // If there is a new config file, delete it and notify the web-app of |
| + // failure to apply the config. Otherwise, the web-app will remain in a |
| + // spinning state until System Preferences eventually gets restarted and |
| + // the user visits this pane again. |
| + std::string file; |
| + if (!GetTemporaryConfigFilePath(&file)) { |
| + // There's no point in alerting the user here. The same error would |
| + // happen when the pane is eventually restarted, so the user would be |
| + // alerted at that time. |
| + LOG(ERROR) << "Failed to get path of configuration data."; |
| + return; |
| + } |
| + 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
|
| + return; |
| + |
| + remove(file.c_str()); |
| + [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.
|
| } |
| } |
| +- (void)restartSystemPreferences { |
| + // TODO(lambroslambrou): Improve this when System Preferences supports |
| + // 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.
|
| + NSTask* task = [[NSTask alloc] init]; |
| + NSArray* arguments = [NSArray arrayWithObjects:@"--relaunch-prefpane", nil]; |
| + [task setLaunchPath:[NSString stringWithUTF8String:kHelperTool]]; |
| + [task setArguments:arguments]; |
| + [task setStandardInput:[NSPipe pipe]]; |
| + [task launch]; |
| + [task release]; |
| + [NSApp terminate:nil]; |
| +} |
| + |
| @end |