Commit 3114e51a authored by garykac@chromium.org's avatar garykac@chromium.org

[Chromoting] Update uninstaller to facilitate testing automation.

With this change, if launched from shell as root, the uninstaller will:
* Not show any confirmation UX
* Not prompt for admin elevation

Also in this cl, cleanup some of the shared Mac constants by pushing
more into into constants_mac and fixing up the naming style. This
required minor updates to the prefpane and daemon controller.

BUG=None
TEST=None
Review URL: https://chromiumcodereview.appspot.com/10807061

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148442 0039d316-1c4b-4281-b951-d872f2087c98
parent 0812b714
...@@ -6,6 +6,34 @@ ...@@ -6,6 +6,34 @@
namespace remoting { namespace remoting {
const char kHostHelperTool[] = kHostConfigDir kServiceName ".me2me.sh"; #define SERVICE_NAME "org.chromium.chromoting"
#define APPLICATIONS_DIR "/Applications/"
#define HELPER_TOOLS_DIR "/Library/PrivilegedHelperTools/"
#define LAUNCH_AGENTS_DIR "/Library/LaunchAgents/"
#define PREFERENCE_PANES_DIR "/Library/PreferencePanes/"
const char kServiceName[] = SERVICE_NAME;
const char kUpdateSucceededNotificationName[] =
SERVICE_NAME ".update_succeeded";
const char kUpdateFailedNotificationName[] = SERVICE_NAME ".update_failed";
const char kPrefPaneFileName[] = SERVICE_NAME ".prefPane";
const char kPrefPaneFilePath[] = PREFERENCE_PANES_DIR SERVICE_NAME ".prefPane";
const char kHostConfigFileName[] = SERVICE_NAME ".json";
const char kHostConfigFilePath[] = HELPER_TOOLS_DIR SERVICE_NAME ".json";
const char kHostHelperScriptPath[] = HELPER_TOOLS_DIR SERVICE_NAME ".me2me.sh";
const char kHostBinaryPath[] = HELPER_TOOLS_DIR SERVICE_NAME ".me2me_host.app";
const char kHostEnabledPath[] = HELPER_TOOLS_DIR SERVICE_NAME ".me2me_enabled";
const char kServicePlistPath[] = LAUNCH_AGENTS_DIR SERVICE_NAME ".plist";
const char kBrandedUninstallerPath[] = APPLICATIONS_DIR
"Chrome Remote Desktop Host Uninstaller.app";
const char kUnbrandedUninstallerPath[] = APPLICATIONS_DIR
"Chromoting Host Uninstaller.app";
} // namespace remoting } // namespace remoting
...@@ -8,21 +8,49 @@ ...@@ -8,21 +8,49 @@
namespace remoting { namespace remoting {
// The name of the Remoting Host service that is registered with launchd. // The name of the Remoting Host service that is registered with launchd.
#define kServiceName "org.chromium.chromoting" extern const char kServiceName[];
// Use separate named notifications for success and failure because sandboxed // Use separate named notifications for success and failure because sandboxed
// components can't include a dictionary when sending distributed notifications. // components can't include a dictionary when sending distributed notifications.
// The preferences panel is not yet sandboxed, but err on the side of caution. // The preferences panel is not yet sandboxed, but err on the side of caution.
#define kUpdateSucceededNotificationName kServiceName ".update_succeeded" // These are #defines because they are used with CFSTR macro, which requires
#define kUpdateFailedNotificationName kServiceName ".update_failed" // string literals.
#define UPDATE_SUCCEEDED_NOTIFICATION_NAME \
"org.chromium.chromoting.update_succeeded"
#define UPDATE_FAILED_NOTIFICATION_NAME "org.chromium.chromoting.update_failed"
#define kHostConfigDir "/Library/PrivilegedHelperTools/"
// This helper tool is executed as root to enable/disable/configure the host // Chromoting's preference pane file.
extern const char kPrefPaneFileName[];
extern const char kPrefPaneFilePath[];
// Use a single configuration file, instead of separate "auth" and "host" files.
// This is because the SetConfigAndStart() API only provides a single
// dictionary, and splitting this into two dictionaries would require
// knowledge of which keys belong in which files.
extern const char kHostConfigFileName[];
extern const char kHostConfigFilePath[];
// This helper script is executed as root to enable/disable/configure the host
// service. // service.
// It is also used (as non-root) to provide version information for the // It is also used (as non-root) to provide version information for the
// installed host components. // installed host components.
extern const char kHostHelperTool[]; extern const char kHostHelperScriptPath[];
// Path to the service binary (.app).
extern const char kHostBinaryPath[];
// If this file exists, it means that the host is enabled for sharing.
extern const char kHostEnabledPath[];
// The .plist file for the Chromoting service.
extern const char kServicePlistPath[];
// The branded and unbranded names for the uninstaller.
// This is the only file that changes names based on branding. We define both
// because we want local dev builds to be able to clean up both files.
extern const char kBrandedUninstallerPath[];
extern const char kUnbrandedUninstallerPath[];
} // namespace remoting } // namespace remoting
......
...@@ -4,11 +4,9 @@ ...@@ -4,11 +4,9 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
@interface RemotingUninstallerAppDelegate : NSObject { @interface RemotingUninstaller : NSObject {
} }
- (IBAction)uninstall:(id)sender; - (OSStatus)remotingUninstall;
- (IBAction)cancel:(id)sender;
- (IBAction)handleMenuClose:(NSMenuItem*)sender;
@end @end
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <Cocoa/Cocoa.h>
@interface RemotingUninstallerAppDelegate : NSObject {
}
- (IBAction)uninstall:(id)sender;
- (IBAction)cancel:(id)sender;
- (IBAction)handleMenuClose:(NSMenuItem*)sender;
@end
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.h"
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_cftyperef.h"
#include "remoting/host/installer/mac/uninstaller/remoting_uninstaller.h"
@implementation RemotingUninstallerAppDelegate
- (void)dealloc {
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
}
- (void)showSuccess:(bool)success withMessage:(NSString*) message {
NSString* summary = success ? @"Uninstall succeeded" : @"Uninstall failed";
NSAlert* alert = [NSAlert alertWithMessageText:summary
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
informativeTextWithFormat:message];
[alert runModal];
}
- (IBAction)uninstall:(NSButton*)sender {
@try {
NSLog(@"Chrome Remote Desktop uninstall starting.");
RemotingUninstaller* uninstaller =
[[[RemotingUninstaller alloc] init] autorelease];
OSStatus status = [uninstaller remotingUninstall];
NSLog(@"Chrome Remote Desktop Host uninstall complete.");
bool success = false;
NSString* message = NULL;
if (status == errAuthorizationSuccess) {
success = true;
message = @"Chrome Remote Desktop Host successfully uninstalled.";
} else if (status == errAuthorizationCanceled) {
message = @"Chrome Remote Desktop Host uninstall canceled.";
} else if (status == errAuthorizationDenied) {
message = @"Chrome Remote Desktop Host uninstall authorization denied.";
} else {
[NSException raise:@"AuthorizationCopyRights Failure"
format:@"Error during AuthorizationCopyRights status=%ld", status];
}
if (message != NULL) {
NSLog(@"Uninstall %s: %@", success ? "succeeded" : "failed", message);
[self showSuccess:success withMessage:message];
}
}
@catch (NSException* exception) {
NSLog(@"Exception %@ %@", [exception name], [exception reason]);
NSString* message =
@"Error! Unable to uninstall Chrome Remote Desktop Host.";
[self showSuccess:false withMessage:message];
}
[NSApp terminate:self];
}
- (IBAction)cancel:(id)sender {
[NSApp terminate:self];
}
- (IBAction)handleMenuClose:(NSMenuItem*)sender {
[NSApp terminate:self];
}
@end
int main(int argc, char* argv[])
{
// The no-ui option skips the UI confirmation dialogs. This is provided as
// a convenience for our automated testing.
// There will still be an elevation prompt unless the command is run as root.
if (argc == 2 && !strcmp(argv[1], "--no-ui")) {
@autoreleasepool {
NSLog(@"Chrome Remote Desktop uninstall starting.");
NSLog(@"--no-ui : Suppressing UI");
RemotingUninstaller* uninstaller =
[[[RemotingUninstaller alloc] init] autorelease];
OSStatus status = [uninstaller remotingUninstall];
NSLog(@"Chrome Remote Desktop Host uninstall complete.");
NSLog(@"Status = %ld", status);
return status != errAuthorizationSuccess;
}
} else {
return NSApplicationMain(argc, (const char**)argv);
}
}
...@@ -33,8 +33,8 @@ bool GetTemporaryConfigFilePath(std::string* path) { ...@@ -33,8 +33,8 @@ bool GetTemporaryConfigFilePath(std::string* path) {
if (filename == nil) if (filename == nil)
return false; return false;
filename = [filename stringByAppendingString:@"/" kServiceName ".json"]; *path = [[NSString stringWithFormat:@"%@/%s",
*path = [filename UTF8String]; filename, remoting::kHostConfigFileName] UTF8String];
return true; return true;
} }
...@@ -226,6 +226,7 @@ OSStatus ExecuteWithPrivilegesAndGetPID(AuthorizationRef authorization, ...@@ -226,6 +226,7 @@ OSStatus ExecuteWithPrivilegesAndGetPID(AuthorizationRef authorization,
} // namespace base } // namespace base
namespace remoting { namespace remoting {
JsonHostConfig::JsonHostConfig(const std::string& filename) JsonHostConfig::JsonHostConfig(const std::string& filename)
: filename_(filename) { : filename_(filename) {
} }
...@@ -282,7 +283,7 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -282,7 +283,7 @@ std::string JsonHostConfig::GetSerializedData() const {
[NSDistributedNotificationCenter defaultCenter]; [NSDistributedNotificationCenter defaultCenter];
[center addObserver:self [center addObserver:self
selector:@selector(onNewConfigFile:) selector:@selector(onNewConfigFile:)
name:@kServiceName name:[NSString stringWithUTF8String:remoting::kServiceName]
object:nil]; object:nil];
service_status_timer_ = service_status_timer_ =
...@@ -314,7 +315,7 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -314,7 +315,7 @@ std::string JsonHostConfig::GetSerializedData() const {
[service_status_timer_ release]; [service_status_timer_ release];
service_status_timer_ = nil; service_status_timer_ = nil;
[self notifyPlugin:kUpdateFailedNotificationName]; [self notifyPlugin:UPDATE_FAILED_NOTIFICATION_NAME];
} }
- (void)applyConfiguration:(id)sender - (void)applyConfiguration:(id)sender
...@@ -358,7 +359,7 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -358,7 +359,7 @@ std::string JsonHostConfig::GetSerializedData() const {
inputData:""]) { inputData:""]) {
NSLog(@"Failed to run the helper tool"); NSLog(@"Failed to run the helper tool");
[self showError]; [self showError];
[self notifyPlugin: kUpdateFailedNotificationName]; [self notifyPlugin:UPDATE_FAILED_NOTIFICATION_NAME];
return; return;
} }
...@@ -381,7 +382,7 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -381,7 +382,7 @@ std::string JsonHostConfig::GetSerializedData() const {
[self updateServiceStatus]; [self updateServiceStatus];
if (awaiting_service_stop_ && !is_service_running_) { if (awaiting_service_stop_ && !is_service_running_) {
awaiting_service_stop_ = NO; awaiting_service_stop_ = NO;
[self notifyPlugin:kUpdateSucceededNotificationName]; [self notifyPlugin:UPDATE_SUCCEEDED_NOTIFICATION_NAME];
} }
if (was_running != is_service_running_) if (was_running != is_service_running_)
...@@ -399,7 +400,7 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -399,7 +400,7 @@ std::string JsonHostConfig::GetSerializedData() const {
} }
- (void)updateServiceStatus { - (void)updateServiceStatus {
pid_t job_pid = base::mac::PIDForJob(kServiceName); pid_t job_pid = base::mac::PIDForJob(remoting::kServiceName);
is_service_running_ = (job_pid > 0); is_service_running_ = (job_pid > 0);
} }
...@@ -525,11 +526,11 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -525,11 +526,11 @@ std::string JsonHostConfig::GetSerializedData() const {
// If the service is running, send a signal to cause it to reload its // If the service is running, send a signal to cause it to reload its
// configuration, otherwise start the service. // configuration, otherwise start the service.
if (is_service_running_) { if (is_service_running_) {
pid_t job_pid = base::mac::PIDForJob(kServiceName); pid_t job_pid = base::mac::PIDForJob(remoting::kServiceName);
if (job_pid > 0) { if (job_pid > 0) {
kill(job_pid, SIGHUP); kill(job_pid, SIGHUP);
} else { } else {
NSLog(@"Failed to obtain PID of service " kServiceName); NSLog(@"Failed to obtain PID of service %s", remoting::kServiceName);
[self showError]; [self showError];
} }
} else { } else {
...@@ -538,7 +539,7 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -538,7 +539,7 @@ std::string JsonHostConfig::GetSerializedData() const {
// Broadcast a distributed notification to inform the plugin that the // Broadcast a distributed notification to inform the plugin that the
// configuration has been applied. // configuration has been applied.
[self notifyPlugin: kUpdateSucceededNotificationName]; [self notifyPlugin:UPDATE_SUCCEEDED_NOTIFICATION_NAME];
} }
- (BOOL)runHelperAsRootWithCommand:(const char*)command - (BOOL)runHelperAsRootWithCommand:(const char*)command
...@@ -558,7 +559,7 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -558,7 +559,7 @@ std::string JsonHostConfig::GetSerializedData() const {
pid_t pid; pid_t pid;
OSStatus status = base::mac::ExecuteWithPrivilegesAndGetPID( OSStatus status = base::mac::ExecuteWithPrivilegesAndGetPID(
authorization, authorization,
remoting::kHostHelperTool, remoting::kHostHelperScriptPath,
kAuthorizationFlagDefaults, kAuthorizationFlagDefaults,
arguments, arguments,
&pipe, &pipe,
...@@ -618,7 +619,7 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -618,7 +619,7 @@ std::string JsonHostConfig::GetSerializedData() const {
if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == 0) { if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == 0) {
return YES; return YES;
} else { } else {
NSLog(@"%s failed with exit status %d", remoting::kHostHelperTool, NSLog(@"%s failed with exit status %d", remoting::kHostHelperScriptPath,
exit_status); exit_status);
return NO; return NO;
} }
...@@ -626,7 +627,7 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -626,7 +627,7 @@ std::string JsonHostConfig::GetSerializedData() const {
- (BOOL)sendJobControlMessage:(const char*)launch_key { - (BOOL)sendJobControlMessage:(const char*)launch_key {
base::mac::ScopedLaunchData response( base::mac::ScopedLaunchData response(
base::mac::MessageForJob(kServiceName, launch_key)); base::mac::MessageForJob(remoting::kServiceName, launch_key));
if (!response) { if (!response) {
NSLog(@"Failed to send message to launchd"); NSLog(@"Failed to send message to launchd");
[self showError]; [self showError];
...@@ -742,14 +743,14 @@ std::string JsonHostConfig::GetSerializedData() const { ...@@ -742,14 +743,14 @@ std::string JsonHostConfig::GetSerializedData() const {
} }
remove(file.c_str()); remove(file.c_str());
[self notifyPlugin:kUpdateFailedNotificationName]; [self notifyPlugin:UPDATE_FAILED_NOTIFICATION_NAME];
} }
} }
- (void)restartSystemPreferences { - (void)restartSystemPreferences {
NSTask* task = [[NSTask alloc] init]; NSTask* task = [[NSTask alloc] init];
NSString* command = NSString* command =
[NSString stringWithUTF8String:remoting::kHostHelperTool]; [NSString stringWithUTF8String:remoting::kHostHelperScriptPath];
NSArray* arguments = [NSArray arrayWithObjects:@"--relaunch-prefpane", nil]; NSArray* arguments = [NSArray arrayWithObjects:@"--relaunch-prefpane", nil];
[task setLaunchPath:command]; [task setLaunchPath:command];
[task setArguments:arguments]; [task setArguments:arguments];
......
...@@ -37,12 +37,6 @@ namespace { ...@@ -37,12 +37,6 @@ namespace {
// Therefore, we define the needed constants here. // Therefore, we define the needed constants here.
const int NSLibraryDirectory = 5; const int NSLibraryDirectory = 5;
// Use a single configuration file, instead of separate "auth" and "host" files.
// This is because the SetConfigAndStart() API only provides a single
// dictionary, and splitting this into two dictionaries would require
// knowledge of which keys belong in which files.
const char kHostConfigFile[] = kHostConfigDir kServiceName ".json";
class DaemonControllerMac : public remoting::DaemonController { class DaemonControllerMac : public remoting::DaemonController {
public: public:
DaemonControllerMac(); DaemonControllerMac();
...@@ -104,12 +98,12 @@ void DaemonControllerMac::DeregisterForPreferencePaneNotifications() { ...@@ -104,12 +98,12 @@ void DaemonControllerMac::DeregisterForPreferencePaneNotifications() {
CFNotificationCenterRemoveObserver( CFNotificationCenterRemoveObserver(
CFNotificationCenterGetDistributedCenter(), CFNotificationCenterGetDistributedCenter(),
this, this,
CFSTR(kUpdateSucceededNotificationName), CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME),
NULL); NULL);
CFNotificationCenterRemoveObserver( CFNotificationCenterRemoveObserver(
CFNotificationCenterGetDistributedCenter(), CFNotificationCenterGetDistributedCenter(),
this, this,
CFSTR(kUpdateFailedNotificationName), CFSTR(UPDATE_FAILED_NOTIFICATION_NAME),
NULL); NULL);
} }
...@@ -180,7 +174,7 @@ void DaemonControllerMac::GetUsageStatsConsent( ...@@ -180,7 +174,7 @@ void DaemonControllerMac::GetUsageStatsConsent(
} }
void DaemonControllerMac::DoGetConfig(const GetConfigCallback& callback) { void DaemonControllerMac::DoGetConfig(const GetConfigCallback& callback) {
FilePath config_path(kHostConfigFile); FilePath config_path(kHostConfigFilePath);
JsonHostConfig host_config(config_path); JsonHostConfig host_config(config_path);
scoped_ptr<base::DictionaryValue> config; scoped_ptr<base::DictionaryValue> config;
...@@ -198,7 +192,7 @@ void DaemonControllerMac::DoGetConfig(const GetConfigCallback& callback) { ...@@ -198,7 +192,7 @@ void DaemonControllerMac::DoGetConfig(const GetConfigCallback& callback) {
void DaemonControllerMac::DoGetVersion(const GetVersionCallback& callback) { void DaemonControllerMac::DoGetVersion(const GetVersionCallback& callback) {
std::string version = ""; std::string version = "";
std::string command_line = remoting::kHostHelperTool; std::string command_line = remoting::kHostHelperScriptPath;
command_line += " --host-version"; command_line += " --host-version";
FILE* script_output = popen(command_line.c_str(), "r"); FILE* script_output = popen(command_line.c_str(), "r");
if (script_output) { if (script_output) {
...@@ -231,7 +225,7 @@ void DaemonControllerMac::DoSetConfigAndStart( ...@@ -231,7 +225,7 @@ void DaemonControllerMac::DoSetConfigAndStart(
void DaemonControllerMac::DoUpdateConfig( void DaemonControllerMac::DoUpdateConfig(
scoped_ptr<base::DictionaryValue> config, scoped_ptr<base::DictionaryValue> config,
const CompletionCallback& done_callback) { const CompletionCallback& done_callback) {
FilePath config_file_path(kHostConfigFile); FilePath config_file_path(kHostConfigFilePath);
JsonHostConfig config_file(config_file_path); JsonHostConfig config_file(config_file_path);
if (!config_file.Read()) { if (!config_file.Read()) {
done_callback.Run(RESULT_FAILED); done_callback.Run(RESULT_FAILED);
...@@ -268,7 +262,7 @@ bool DaemonControllerMac::DoShowPreferencePane(const std::string& config_data) { ...@@ -268,7 +262,7 @@ bool DaemonControllerMac::DoShowPreferencePane(const std::string& config_data) {
LOG(ERROR) << "Failed to get filename for saving configuration data."; LOG(ERROR) << "Failed to get filename for saving configuration data.";
return false; return false;
} }
config_path = config_path.Append(kServiceName ".json"); config_path = config_path.Append(kHostConfigFileName);
int written = file_util::WriteFile(config_path, config_data.data(), int written = file_util::WriteFile(config_path, config_data.data(),
config_data.size()); config_data.size());
...@@ -286,8 +280,7 @@ bool DaemonControllerMac::DoShowPreferencePane(const std::string& config_data) { ...@@ -286,8 +280,7 @@ bool DaemonControllerMac::DoShowPreferencePane(const std::string& config_data) {
LOG(ERROR) << "Failed to get directory for local preference panes."; LOG(ERROR) << "Failed to get directory for local preference panes.";
return false; return false;
} }
pane_path = pane_path.Append("PreferencePanes") pane_path = pane_path.Append("PreferencePanes").Append(kPrefPaneFileName);
.Append(kServiceName ".prefPane");
FSRef pane_path_ref; FSRef pane_path_ref;
if (!base::mac::FSRefFromPath(pane_path.value(), &pane_path_ref)) { if (!base::mac::FSRefFromPath(pane_path.value(), &pane_path_ref)) {
...@@ -303,7 +296,10 @@ bool DaemonControllerMac::DoShowPreferencePane(const std::string& config_data) { ...@@ -303,7 +296,10 @@ bool DaemonControllerMac::DoShowPreferencePane(const std::string& config_data) {
CFNotificationCenterRef center = CFNotificationCenterRef center =
CFNotificationCenterGetDistributedCenter(); CFNotificationCenterGetDistributedCenter();
CFNotificationCenterPostNotification(center, CFSTR(kServiceName), NULL, NULL, base::mac::ScopedCFTypeRef<CFStringRef> service_name(
CFStringCreateWithCString(kCFAllocatorDefault, remoting::kServiceName,
kCFStringEncodingUTF8));
CFNotificationCenterPostNotification(center, service_name, NULL, NULL,
TRUE); TRUE);
return true; return true;
} }
...@@ -328,24 +324,24 @@ void DaemonControllerMac::RegisterForPreferencePaneNotifications( ...@@ -328,24 +324,24 @@ void DaemonControllerMac::RegisterForPreferencePaneNotifications(
CFNotificationCenterGetDistributedCenter(), CFNotificationCenterGetDistributedCenter(),
this, this,
&DaemonControllerMac::PreferencePaneCallback, &DaemonControllerMac::PreferencePaneCallback,
CFSTR(kUpdateSucceededNotificationName), CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME),
NULL, NULL,
CFNotificationSuspensionBehaviorDeliverImmediately); CFNotificationSuspensionBehaviorDeliverImmediately);
CFNotificationCenterAddObserver( CFNotificationCenterAddObserver(
CFNotificationCenterGetDistributedCenter(), CFNotificationCenterGetDistributedCenter(),
this, this,
&DaemonControllerMac::PreferencePaneCallback, &DaemonControllerMac::PreferencePaneCallback,
CFSTR(kUpdateFailedNotificationName), CFSTR(UPDATE_FAILED_NOTIFICATION_NAME),
NULL, NULL,
CFNotificationSuspensionBehaviorDeliverImmediately); CFNotificationSuspensionBehaviorDeliverImmediately);
} }
void DaemonControllerMac::PreferencePaneCallbackDelegate(CFStringRef name) { void DaemonControllerMac::PreferencePaneCallbackDelegate(CFStringRef name) {
AsyncResult result = RESULT_FAILED; AsyncResult result = RESULT_FAILED;
if (CFStringCompare(name, CFSTR(kUpdateSucceededNotificationName), 0) == if (CFStringCompare(name, CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME), 0) ==
kCFCompareEqualTo) { kCFCompareEqualTo) {
result = RESULT_OK; result = RESULT_OK;
} else if (CFStringCompare(name, CFSTR(kUpdateFailedNotificationName), 0) == } else if (CFStringCompare(name, CFSTR(UPDATE_FAILED_NOTIFICATION_NAME), 0) ==
kCFCompareEqualTo) { kCFCompareEqualTo) {
result = RESULT_FAILED; result = RESULT_FAILED;
} else { } else {
......
...@@ -272,8 +272,12 @@ ...@@ -272,8 +272,12 @@
'<(DEPTH)/base/base.gyp:base', '<(DEPTH)/base/base.gyp:base',
], ],
'sources': [ 'sources': [
'host/constants_mac.cc',
'host/constants_mac.h',
'host/installer/mac/uninstaller/remoting_uninstaller.h', 'host/installer/mac/uninstaller/remoting_uninstaller.h',
'host/installer/mac/uninstaller/remoting_uninstaller.mm', 'host/installer/mac/uninstaller/remoting_uninstaller.mm',
'host/installer/mac/uninstaller/remoting_uninstaller_app.h',
'host/installer/mac/uninstaller/remoting_uninstaller_app.mm',
], ],
'xcode_settings': { 'xcode_settings': {
'INFOPLIST_FILE': 'host/installer/mac/uninstaller/remoting_uninstaller-Info.plist', 'INFOPLIST_FILE': 'host/installer/mac/uninstaller/remoting_uninstaller-Info.plist',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment