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

Side by Side Diff: remoting/host/setup/daemon_controller_delegate_mac.mm

Issue 1272833002: Pass error messages from native messaging to web-app. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed unit tests. Created 5 years, 4 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #include <CoreFoundation/CoreFoundation.h> 5 #include <CoreFoundation/CoreFoundation.h>
6 6
7 #include "remoting/host/setup/daemon_controller_delegate_mac.h" 7 #include "remoting/host/setup/daemon_controller_delegate_mac.h"
8 8
9 #include <launch.h> 9 #include <launch.h>
10 #include <stdio.h> 10 #include <stdio.h>
11 #include <sys/types.h> 11 #include <sys/types.h>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/callback_helpers.h" 15 #include "base/callback_helpers.h"
16 #include "base/compiler_specific.h" 16 #include "base/compiler_specific.h"
17 #include "base/files/file_path.h" 17 #include "base/files/file_path.h"
18 #include "base/files/file_util.h" 18 #include "base/files/file_util.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/mac/foundation_util.h" 20 #include "base/mac/foundation_util.h"
21 #include "base/mac/launchd.h" 21 #include "base/mac/launchd.h"
22 #include "base/mac/mac_logging.h" 22 #include "base/mac/mac_logging.h"
23 #include "base/mac/mac_util.h" 23 #include "base/mac/mac_util.h"
24 #include "base/mac/scoped_launch_data.h" 24 #include "base/mac/scoped_launch_data.h"
25 #include "base/time/time.h" 25 #include "base/time/time.h"
26 #include "base/tracked_objects.h"
26 #include "base/values.h" 27 #include "base/values.h"
27 #include "remoting/host/constants_mac.h" 28 #include "remoting/host/constants_mac.h"
28 #include "remoting/host/host_config.h" 29 #include "remoting/host/host_config.h"
29 #include "remoting/host/usage_stats_consent.h" 30 #include "remoting/host/usage_stats_consent.h"
30 31
31 namespace remoting { 32 namespace remoting {
32 33
33 DaemonControllerDelegateMac::DaemonControllerDelegateMac() { 34 DaemonControllerDelegateMac::DaemonControllerDelegateMac() {
34 } 35 }
35 36
(...skipping 25 matching lines...) Expand all
61 if (host_config->GetString(kHostIdConfigPath, &value)) 62 if (host_config->GetString(kHostIdConfigPath, &value))
62 config->SetString(kHostIdConfigPath, value); 63 config->SetString(kHostIdConfigPath, value);
63 if (host_config->GetString(kXmppLoginConfigPath, &value)) 64 if (host_config->GetString(kXmppLoginConfigPath, &value))
64 config->SetString(kXmppLoginConfigPath, value); 65 config->SetString(kXmppLoginConfigPath, value);
65 return config.Pass(); 66 return config.Pass();
66 } 67 }
67 68
68 void DaemonControllerDelegateMac::SetConfigAndStart( 69 void DaemonControllerDelegateMac::SetConfigAndStart(
69 scoped_ptr<base::DictionaryValue> config, 70 scoped_ptr<base::DictionaryValue> config,
70 bool consent, 71 bool consent,
71 const DaemonController::CompletionCallback& done) { 72 const base::Closure& on_done,
73 const DaemonController::ErrorCallback& on_error) {
72 config->SetBoolean(kUsageStatsConsentConfigPath, consent); 74 config->SetBoolean(kUsageStatsConsentConfigPath, consent);
73 ShowPreferencePane(HostConfigToJson(*config), done); 75 ShowPreferencePane(HostConfigToJson(*config), on_done, on_error);
74 } 76 }
75 77
76 void DaemonControllerDelegateMac::UpdateConfig( 78 void DaemonControllerDelegateMac::UpdateConfig(
77 scoped_ptr<base::DictionaryValue> config, 79 scoped_ptr<base::DictionaryValue> config,
78 const DaemonController::CompletionCallback& done) { 80 const base::Closure& on_done,
81 const DaemonController::ErrorCallback& on_error) {
79 base::FilePath config_file_path(kHostConfigFilePath); 82 base::FilePath config_file_path(kHostConfigFilePath);
80 scoped_ptr<base::DictionaryValue> host_config( 83 scoped_ptr<base::DictionaryValue> host_config(
81 HostConfigFromJsonFile(config_file_path)); 84 HostConfigFromJsonFile(config_file_path));
82 if (!host_config) { 85 if (!host_config) {
83 done.Run(DaemonController::RESULT_FAILED); 86 std::string error_message =
87 "Reading config from " + config_file_path.value() + " failed";
88 LOG(ERROR) << error_message;
89 on_error.Run(error_message, FROM_HERE);
84 return; 90 return;
85 } 91 }
86 92
87 host_config->MergeDictionary(config.get()); 93 host_config->MergeDictionary(config.get());
88 ShowPreferencePane(HostConfigToJson(*host_config), done); 94 ShowPreferencePane(HostConfigToJson(*host_config), on_done, on_error);
89 } 95 }
90 96
91 void DaemonControllerDelegateMac::Stop( 97 void DaemonControllerDelegateMac::Stop(
92 const DaemonController::CompletionCallback& done) { 98 const base::Closure& on_done,
93 ShowPreferencePane("", done); 99 const DaemonController::ErrorCallback& on_error) {
100 ShowPreferencePane("", on_done, on_error);
94 } 101 }
95 102
96 DaemonController::UsageStatsConsent 103 DaemonController::UsageStatsConsent
97 DaemonControllerDelegateMac::GetUsageStatsConsent() { 104 DaemonControllerDelegateMac::GetUsageStatsConsent() {
98 DaemonController::UsageStatsConsent consent; 105 DaemonController::UsageStatsConsent consent;
99 consent.supported = true; 106 consent.supported = true;
100 consent.allowed = false; 107 consent.allowed = false;
101 // set_by_policy is not yet supported. 108 // set_by_policy is not yet supported.
102 consent.set_by_policy = false; 109 consent.set_by_policy = false;
103 110
104 base::FilePath config_file_path(kHostConfigFilePath); 111 base::FilePath config_file_path(kHostConfigFilePath);
105 scoped_ptr<base::DictionaryValue> host_config( 112 scoped_ptr<base::DictionaryValue> host_config(
106 HostConfigFromJsonFile(config_file_path)); 113 HostConfigFromJsonFile(config_file_path));
107 if (host_config) { 114 if (host_config) {
108 host_config->GetBoolean(kUsageStatsConsentConfigPath, &consent.allowed); 115 host_config->GetBoolean(kUsageStatsConsentConfigPath, &consent.allowed);
109 } 116 }
110 117
111 return consent; 118 return consent;
112 } 119 }
113 120
114 void DaemonControllerDelegateMac::ShowPreferencePane( 121 void DaemonControllerDelegateMac::ShowPreferencePane(
115 const std::string& config_data, 122 const std::string& config_data,
116 const DaemonController::CompletionCallback& done) { 123 const base::Closure& on_done,
117 if (DoShowPreferencePane(config_data)) { 124 const DaemonController::ErrorCallback& on_error) {
118 RegisterForPreferencePaneNotifications(done); 125 if (DoShowPreferencePane(config_data, on_error)) {
119 } else { 126 RegisterForPreferencePaneNotifications(on_done, on_error);
120 done.Run(DaemonController::RESULT_FAILED);
121 } 127 }
122 } 128 }
123 129
124 // CFNotificationCenterAddObserver ties the thread on which distributed 130 // CFNotificationCenterAddObserver ties the thread on which distributed
125 // notifications are received to the one on which it is first called. 131 // notifications are received to the one on which it is first called.
126 // This is safe because HostNPScriptObject::InvokeAsyncResultCallback 132 // This is safe because HostNPScriptObject::InvokeAsyncResultCallback
127 // bounces the invocation to the correct thread, so it doesn't matter 133 // bounces the invocation to the correct thread, so it doesn't matter
128 // which thread CompletionCallbacks are called on. 134 // which thread CompletionCallbacks are called on.
129 void DaemonControllerDelegateMac::RegisterForPreferencePaneNotifications( 135 void DaemonControllerDelegateMac::RegisterForPreferencePaneNotifications(
130 const DaemonController::CompletionCallback& done) { 136 const base::Closure& on_done,
137 const DaemonController::ErrorCallback& on_error) {
131 // We can only have one callback registered at a time. This is enforced by the 138 // We can only have one callback registered at a time. This is enforced by the
132 // UX flow of the web-app. 139 // UX flow of the web-app.
133 DCHECK(current_callback_.is_null()); 140 DCHECK(on_done_.is_null());
134 current_callback_ = done; 141 DCHECK(on_error_.is_null());
142 on_done_ = on_done;
143 on_error_ = on_error;
135 144
136 CFNotificationCenterAddObserver( 145 CFNotificationCenterAddObserver(
137 CFNotificationCenterGetDistributedCenter(), 146 CFNotificationCenterGetDistributedCenter(),
138 this, 147 this,
139 &DaemonControllerDelegateMac::PreferencePaneCallback, 148 &DaemonControllerDelegateMac::PreferencePaneCallback,
140 CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME), 149 CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME),
141 nullptr, 150 nullptr,
142 CFNotificationSuspensionBehaviorDeliverImmediately); 151 CFNotificationSuspensionBehaviorDeliverImmediately);
143 CFNotificationCenterAddObserver( 152 CFNotificationCenterAddObserver(
144 CFNotificationCenterGetDistributedCenter(), 153 CFNotificationCenterGetDistributedCenter(),
(...skipping 12 matching lines...) Expand all
157 nullptr); 166 nullptr);
158 CFNotificationCenterRemoveObserver( 167 CFNotificationCenterRemoveObserver(
159 CFNotificationCenterGetDistributedCenter(), 168 CFNotificationCenterGetDistributedCenter(),
160 this, 169 this,
161 CFSTR(UPDATE_FAILED_NOTIFICATION_NAME), 170 CFSTR(UPDATE_FAILED_NOTIFICATION_NAME),
162 nullptr); 171 nullptr);
163 } 172 }
164 173
165 void DaemonControllerDelegateMac::PreferencePaneCallbackDelegate( 174 void DaemonControllerDelegateMac::PreferencePaneCallbackDelegate(
166 CFStringRef name) { 175 CFStringRef name) {
167 DaemonController::AsyncResult result = DaemonController::RESULT_FAILED; 176 bool success =
168 if (CFStringCompare(name, CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME), 0) == 177 CFStringCompare(name, CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME), 0) ==
169 kCFCompareEqualTo) { 178 kCFCompareEqualTo;
170 result = DaemonController::RESULT_OK; 179 bool failure =
171 } else if (CFStringCompare(name, CFSTR(UPDATE_FAILED_NOTIFICATION_NAME), 0) == 180 CFStringCompare(name, CFSTR(UPDATE_FAILED_NOTIFICATION_NAME), 0) ==
172 kCFCompareEqualTo) { 181 kCFCompareEqualTo;
173 result = DaemonController::RESULT_FAILED; 182 if (success) {
183 on_error_.Reset();
184 base::ResetAndReturn(&on_done_).Run();
185 } else if (failure) {
186 on_done_.Reset();
187 std::string error_message =
188 "Received failure notification from Preference Pane";
189 LOG(ERROR) << error_message;
190 base::ResetAndReturn(&on_error_).Run(error_message, FROM_HERE);
174 } else { 191 } else {
175 LOG(WARNING) << "Ignoring unexpected notification: " << name; 192 LOG(WARNING) << "Ignoring unexpected notification: " << name;
176 return; 193 return;
177 } 194 }
178 195
179 DeregisterForPreferencePaneNotifications(); 196 DeregisterForPreferencePaneNotifications();
180
181 DCHECK(!current_callback_.is_null());
182 base::ResetAndReturn(&current_callback_).Run(result);
183 } 197 }
184 198
185 // static 199 // static
186 bool DaemonControllerDelegateMac::DoShowPreferencePane( 200 bool DaemonControllerDelegateMac::DoShowPreferencePane(
187 const std::string& config_data) { 201 const std::string& config_data,
202 const DaemonController::ErrorCallback& on_error) {
188 if (!config_data.empty()) { 203 if (!config_data.empty()) {
189 base::FilePath config_path; 204 base::FilePath config_path;
190 if (!base::GetTempDir(&config_path)) { 205 if (!base::GetTempDir(&config_path)) {
191 LOG(ERROR) << "Failed to get filename for saving configuration data."; 206 std::string error_message =
207 "Failed to get filename for saving configuration data.";
208 LOG(ERROR) << error_message;
209 on_error.Run(error_message, FROM_HERE);
192 return false; 210 return false;
193 } 211 }
212
194 config_path = config_path.Append(kHostConfigFileName); 213 config_path = config_path.Append(kHostConfigFileName);
195
196 int written = base::WriteFile(config_path, config_data.data(), 214 int written = base::WriteFile(config_path, config_data.data(),
197 config_data.size()); 215 config_data.size());
198 if (written != static_cast<int>(config_data.size())) { 216 if (written != static_cast<int>(config_data.size())) {
199 LOG(ERROR) << "Failed to save configuration data to: " 217 std::string error_message =
200 << config_path.value(); 218 "Failed to save configuration data to: " + config_path.value();
219 LOG(ERROR) << error_message;
220 on_error.Run(error_message, FROM_HERE);
201 return false; 221 return false;
202 } 222 }
203 } 223 }
204 224
205 base::FilePath pane_path; 225 base::FilePath pane_path;
206 // TODO(lambroslambrou): Use NSPreferencePanesDirectory once we start 226 // TODO(lambroslambrou): Use NSPreferencePanesDirectory once we start
207 // building against SDK 10.6. 227 // building against SDK 10.6.
208 if (!base::mac::GetLocalDirectory(NSLibraryDirectory, &pane_path)) { 228 if (!base::mac::GetLocalDirectory(NSLibraryDirectory, &pane_path)) {
209 LOG(ERROR) << "Failed to get directory for local preference panes."; 229 std::string error_message =
210 return false; 230 "Failed to get directory for local preference panes.";
211 } 231 LOG(ERROR) << error_message;
212 pane_path = pane_path.Append("PreferencePanes").Append(kPrefPaneFileName); 232 on_error.Run(error_message, FROM_HERE);
213
214 FSRef pane_path_ref;
215 if (!base::mac::FSRefFromPath(pane_path.value(), &pane_path_ref)) {
216 LOG(ERROR) << "Failed to create FSRef";
217 return false;
218 }
219 OSStatus status = LSOpenFSRef(&pane_path_ref, nullptr);
220 if (status != noErr) {
221 OSSTATUS_LOG(ERROR, status) << "LSOpenFSRef failed for path: "
222 << pane_path.value();
223 return false; 233 return false;
224 } 234 }
225 235
236 pane_path = pane_path.Append("PreferencePanes").Append(kPrefPaneFileName);
237 FSRef pane_path_ref;
238 if (!base::mac::FSRefFromPath(pane_path.value(), &pane_path_ref)) {
239 std::string error_message = "Failed to create FSRef";
240 LOG(ERROR) << error_message;
241 on_error.Run(error_message, FROM_HERE);
242 return false;
243 }
244
245 OSStatus status = LSOpenFSRef(&pane_path_ref, nullptr);
246 if (status != noErr) {
247 std::string error_message =
248 "LSOpenFSRef failed for path: " + pane_path.value() + ": " +
249 GetMacOSStatusErrorString(status);
250 LOG(ERROR) << error_message;
251 on_error.Run(error_message, FROM_HERE);
252 return false;
253 }
254
226 CFNotificationCenterRef center = 255 CFNotificationCenterRef center =
227 CFNotificationCenterGetDistributedCenter(); 256 CFNotificationCenterGetDistributedCenter();
228 base::ScopedCFTypeRef<CFStringRef> service_name(CFStringCreateWithCString( 257 base::ScopedCFTypeRef<CFStringRef> service_name(CFStringCreateWithCString(
229 kCFAllocatorDefault, remoting::kServiceName, kCFStringEncodingUTF8)); 258 kCFAllocatorDefault, remoting::kServiceName, kCFStringEncodingUTF8));
230 CFNotificationCenterPostNotification(center, service_name, nullptr, nullptr, 259 CFNotificationCenterPostNotification(center, service_name, nullptr, nullptr,
231 TRUE); 260 TRUE);
232 return true; 261 return true;
233 } 262 }
234 263
235 // static 264 // static
(...skipping 13 matching lines...) Expand all
249 self->PreferencePaneCallbackDelegate(name); 278 self->PreferencePaneCallbackDelegate(name);
250 } 279 }
251 280
252 scoped_refptr<DaemonController> DaemonController::Create() { 281 scoped_refptr<DaemonController> DaemonController::Create() {
253 scoped_ptr<DaemonController::Delegate> delegate( 282 scoped_ptr<DaemonController::Delegate> delegate(
254 new DaemonControllerDelegateMac()); 283 new DaemonControllerDelegateMac());
255 return new DaemonController(delegate.Pass()); 284 return new DaemonController(delegate.Pass());
256 } 285 }
257 286
258 } // namespace remoting 287 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698