OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/mac/mac_util.h" | 5 #include "base/mac/mac_util.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <sys/utsname.h> | 9 #include <sys/utsname.h> |
10 | 10 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 } | 57 } |
58 | 58 |
59 // Looks into Shared File Lists corresponding to Login Items for the item | 59 // Looks into Shared File Lists corresponding to Login Items for the item |
60 // representing the current application. If such an item is found, returns a | 60 // representing the current application. If such an item is found, returns a |
61 // retained reference to it. Caller is responsible for releasing the reference. | 61 // retained reference to it. Caller is responsible for releasing the reference. |
62 LSSharedFileListItemRef GetLoginItemForApp() { | 62 LSSharedFileListItemRef GetLoginItemForApp() { |
63 ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate( | 63 ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate( |
64 NULL, kLSSharedFileListSessionLoginItems, NULL)); | 64 NULL, kLSSharedFileListSessionLoginItems, NULL)); |
65 | 65 |
66 if (!login_items.get()) { | 66 if (!login_items.get()) { |
67 LOG(ERROR) << "Couldn't get a Login Items list."; | 67 DLOG(ERROR) << "Couldn't get a Login Items list."; |
68 return NULL; | 68 return NULL; |
69 } | 69 } |
70 | 70 |
71 scoped_nsobject<NSArray> login_items_array( | 71 scoped_nsobject<NSArray> login_items_array( |
72 CFToNSCast(LSSharedFileListCopySnapshot(login_items, NULL))); | 72 CFToNSCast(LSSharedFileListCopySnapshot(login_items, NULL))); |
73 | 73 |
74 NSURL* url = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; | 74 NSURL* url = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; |
75 | 75 |
76 for(NSUInteger i = 0; i < [login_items_array count]; ++i) { | 76 for(NSUInteger i = 0; i < [login_items_array count]; ++i) { |
77 LSSharedFileListItemRef item = reinterpret_cast<LSSharedFileListItemRef>( | 77 LSSharedFileListItemRef item = reinterpret_cast<LSSharedFileListItemRef>( |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 bool FSRefFromPath(const std::string& path, FSRef* ref) { | 119 bool FSRefFromPath(const std::string& path, FSRef* ref) { |
120 OSStatus status = FSPathMakeRef((const UInt8*)path.c_str(), | 120 OSStatus status = FSPathMakeRef((const UInt8*)path.c_str(), |
121 ref, nil); | 121 ref, nil); |
122 return status == noErr; | 122 return status == noErr; |
123 } | 123 } |
124 | 124 |
125 CGColorSpaceRef GetSRGBColorSpace() { | 125 CGColorSpaceRef GetSRGBColorSpace() { |
126 // Leaked. That's OK, it's scoped to the lifetime of the application. | 126 // Leaked. That's OK, it's scoped to the lifetime of the application. |
127 static CGColorSpaceRef g_color_space_sRGB = | 127 static CGColorSpaceRef g_color_space_sRGB = |
128 CGColorSpaceCreateWithName(kCGColorSpaceSRGB); | 128 CGColorSpaceCreateWithName(kCGColorSpaceSRGB); |
129 LOG_IF(ERROR, !g_color_space_sRGB) << "Couldn't get the sRGB color space"; | 129 DLOG_IF(ERROR, !g_color_space_sRGB) << "Couldn't get the sRGB color space"; |
130 return g_color_space_sRGB; | 130 return g_color_space_sRGB; |
131 } | 131 } |
132 | 132 |
133 CGColorSpaceRef GetSystemColorSpace() { | 133 CGColorSpaceRef GetSystemColorSpace() { |
134 // Leaked. That's OK, it's scoped to the lifetime of the application. | 134 // Leaked. That's OK, it's scoped to the lifetime of the application. |
135 // Try to get the main display's color space. | 135 // Try to get the main display's color space. |
136 static CGColorSpaceRef g_system_color_space = | 136 static CGColorSpaceRef g_system_color_space = |
137 CGDisplayCopyColorSpace(CGMainDisplayID()); | 137 CGDisplayCopyColorSpace(CGMainDisplayID()); |
138 | 138 |
139 if (!g_system_color_space) { | 139 if (!g_system_color_space) { |
140 // Use a generic RGB color space. This is better than nothing. | 140 // Use a generic RGB color space. This is better than nothing. |
141 g_system_color_space = CGColorSpaceCreateDeviceRGB(); | 141 g_system_color_space = CGColorSpaceCreateDeviceRGB(); |
142 | 142 |
143 if (g_system_color_space) { | 143 if (g_system_color_space) { |
144 LOG(WARNING) << | 144 DLOG(WARNING) << |
145 "Couldn't get the main display's color space, using generic"; | 145 "Couldn't get the main display's color space, using generic"; |
146 } else { | 146 } else { |
147 LOG(ERROR) << "Couldn't get any color space"; | 147 DLOG(ERROR) << "Couldn't get any color space"; |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 return g_system_color_space; | 151 return g_system_color_space; |
152 } | 152 } |
153 | 153 |
154 // Add a request for full screen mode. Must be called on the main thread. | 154 // Add a request for full screen mode. Must be called on the main thread. |
155 void RequestFullScreen(FullScreenMode mode) { | 155 void RequestFullScreen(FullScreenMode mode) { |
156 DCHECK_LT(mode, kNumFullScreenModes); | 156 DCHECK_LT(mode, kNumFullScreenModes); |
157 if (mode >= kNumFullScreenModes) | 157 if (mode >= kNumFullScreenModes) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 return !methodImplemented || | 209 return !methodImplemented || |
210 [NSWindow performSelector:@selector(_shouldMiniaturizeOnDoubleClick)]; | 210 [NSWindow performSelector:@selector(_shouldMiniaturizeOnDoubleClick)]; |
211 } | 211 } |
212 | 212 |
213 void ActivateProcess(pid_t pid) { | 213 void ActivateProcess(pid_t pid) { |
214 ProcessSerialNumber process; | 214 ProcessSerialNumber process; |
215 OSStatus status = GetProcessForPID(pid, &process); | 215 OSStatus status = GetProcessForPID(pid, &process); |
216 if (status == noErr) { | 216 if (status == noErr) { |
217 SetFrontProcess(&process); | 217 SetFrontProcess(&process); |
218 } else { | 218 } else { |
219 LOG(WARNING) << "Unable to get process for pid " << pid; | 219 DLOG(WARNING) << "Unable to get process for pid " << pid; |
220 } | 220 } |
221 } | 221 } |
222 | 222 |
223 bool AmIForeground() { | 223 bool AmIForeground() { |
224 ProcessSerialNumber foreground_psn = { 0 }; | 224 ProcessSerialNumber foreground_psn = { 0 }; |
225 OSErr err = GetFrontProcess(&foreground_psn); | 225 OSErr err = GetFrontProcess(&foreground_psn); |
226 if (err != noErr) { | 226 if (err != noErr) { |
227 LOG(WARNING) << "GetFrontProcess: " << err; | 227 DLOG(WARNING) << "GetFrontProcess: " << err; |
228 return false; | 228 return false; |
229 } | 229 } |
230 | 230 |
231 ProcessSerialNumber my_psn = { 0, kCurrentProcess }; | 231 ProcessSerialNumber my_psn = { 0, kCurrentProcess }; |
232 | 232 |
233 Boolean result = FALSE; | 233 Boolean result = FALSE; |
234 err = SameProcess(&foreground_psn, &my_psn, &result); | 234 err = SameProcess(&foreground_psn, &my_psn, &result); |
235 if (err != noErr) { | 235 if (err != noErr) { |
236 LOG(WARNING) << "SameProcess: " << err; | 236 DLOG(WARNING) << "SameProcess: " << err; |
237 return false; | 237 return false; |
238 } | 238 } |
239 | 239 |
240 return result; | 240 return result; |
241 } | 241 } |
242 | 242 |
243 bool SetFileBackupExclusion(const FilePath& file_path) { | 243 bool SetFileBackupExclusion(const FilePath& file_path) { |
244 NSString* file_path_ns = | 244 NSString* file_path_ns = |
245 [NSString stringWithUTF8String:file_path.value().c_str()]; | 245 [NSString stringWithUTF8String:file_path.value().c_str()]; |
246 NSURL* file_url = [NSURL fileURLWithPath:file_path_ns]; | 246 NSURL* file_url = [NSURL fileURLWithPath:file_path_ns]; |
247 | 247 |
248 // When excludeByPath is true the application must be running with root | 248 // When excludeByPath is true the application must be running with root |
249 // privileges (admin for 10.6 and earlier) but the URL does not have to | 249 // privileges (admin for 10.6 and earlier) but the URL does not have to |
250 // already exist. When excludeByPath is false the URL must already exist but | 250 // already exist. When excludeByPath is false the URL must already exist but |
251 // can be used in non-root (or admin as above) mode. We use false so that | 251 // can be used in non-root (or admin as above) mode. We use false so that |
252 // non-root (or admin) users don't get their TimeMachine drive filled up with | 252 // non-root (or admin) users don't get their TimeMachine drive filled up with |
253 // unnecessary backups. | 253 // unnecessary backups. |
254 OSStatus os_err = | 254 OSStatus os_err = |
255 CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), TRUE, FALSE); | 255 CSBackupSetItemExcluded(base::mac::NSToCFCast(file_url), TRUE, FALSE); |
256 if (os_err != noErr) { | 256 if (os_err != noErr) { |
257 LOG(WARNING) << "Failed to set backup exclusion for file '" | 257 DLOG(WARNING) << "Failed to set backup exclusion for file '" |
258 << file_path.value().c_str() << "' with error " | 258 << file_path.value().c_str() << "' with error " |
259 << os_err << " (" << GetMacOSStatusErrorString(os_err) | 259 << os_err << " (" << GetMacOSStatusErrorString(os_err) |
260 << ": " << GetMacOSStatusCommentString(os_err) | 260 << ": " << GetMacOSStatusCommentString(os_err) |
261 << "). Continuing."; | 261 << "). Continuing."; |
262 } | 262 } |
263 return os_err == noErr; | 263 return os_err == noErr; |
264 } | 264 } |
265 | 265 |
266 void SetProcessName(CFStringRef process_name) { | 266 void SetProcessName(CFStringRef process_name) { |
267 if (!process_name || CFStringGetLength(process_name) == 0) { | 267 if (!process_name || CFStringGetLength(process_name) == 0) { |
(...skipping 25 matching lines...) Expand all Loading... |
293 static LSSetApplicationInformationItemType | 293 static LSSetApplicationInformationItemType |
294 ls_set_application_information_item_func = NULL; | 294 ls_set_application_information_item_func = NULL; |
295 static CFStringRef ls_display_name_key = NULL; | 295 static CFStringRef ls_display_name_key = NULL; |
296 | 296 |
297 static bool did_symbol_lookup = false; | 297 static bool did_symbol_lookup = false; |
298 if (!did_symbol_lookup) { | 298 if (!did_symbol_lookup) { |
299 did_symbol_lookup = true; | 299 did_symbol_lookup = true; |
300 CFBundleRef launch_services_bundle = | 300 CFBundleRef launch_services_bundle = |
301 CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices")); | 301 CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices")); |
302 if (!launch_services_bundle) { | 302 if (!launch_services_bundle) { |
303 LOG(ERROR) << "Failed to look up LaunchServices bundle"; | 303 DLOG(ERROR) << "Failed to look up LaunchServices bundle"; |
304 return; | 304 return; |
305 } | 305 } |
306 | 306 |
307 ls_get_current_application_asn_func = | 307 ls_get_current_application_asn_func = |
308 reinterpret_cast<LSGetCurrentApplicationASNType>( | 308 reinterpret_cast<LSGetCurrentApplicationASNType>( |
309 CFBundleGetFunctionPointerForName( | 309 CFBundleGetFunctionPointerForName( |
310 launch_services_bundle, CFSTR("_LSGetCurrentApplicationASN"))); | 310 launch_services_bundle, CFSTR("_LSGetCurrentApplicationASN"))); |
311 if (!ls_get_current_application_asn_func) | 311 if (!ls_get_current_application_asn_func) |
312 LOG(ERROR) << "Could not find _LSGetCurrentApplicationASN"; | 312 DLOG(ERROR) << "Could not find _LSGetCurrentApplicationASN"; |
313 | 313 |
314 ls_set_application_information_item_func = | 314 ls_set_application_information_item_func = |
315 reinterpret_cast<LSSetApplicationInformationItemType>( | 315 reinterpret_cast<LSSetApplicationInformationItemType>( |
316 CFBundleGetFunctionPointerForName( | 316 CFBundleGetFunctionPointerForName( |
317 launch_services_bundle, | 317 launch_services_bundle, |
318 CFSTR("_LSSetApplicationInformationItem"))); | 318 CFSTR("_LSSetApplicationInformationItem"))); |
319 if (!ls_set_application_information_item_func) | 319 if (!ls_set_application_information_item_func) |
320 LOG(ERROR) << "Could not find _LSSetApplicationInformationItem"; | 320 DLOG(ERROR) << "Could not find _LSSetApplicationInformationItem"; |
321 | 321 |
322 CFStringRef* key_pointer = reinterpret_cast<CFStringRef*>( | 322 CFStringRef* key_pointer = reinterpret_cast<CFStringRef*>( |
323 CFBundleGetDataPointerForName(launch_services_bundle, | 323 CFBundleGetDataPointerForName(launch_services_bundle, |
324 CFSTR("_kLSDisplayNameKey"))); | 324 CFSTR("_kLSDisplayNameKey"))); |
325 ls_display_name_key = key_pointer ? *key_pointer : NULL; | 325 ls_display_name_key = key_pointer ? *key_pointer : NULL; |
326 if (!ls_display_name_key) | 326 if (!ls_display_name_key) |
327 LOG(ERROR) << "Could not find _kLSDisplayNameKey"; | 327 DLOG(ERROR) << "Could not find _kLSDisplayNameKey"; |
328 | 328 |
329 // Internally, this call relies on the Mach ports that are started up by the | 329 // Internally, this call relies on the Mach ports that are started up by the |
330 // Carbon Process Manager. In debug builds this usually happens due to how | 330 // Carbon Process Manager. In debug builds this usually happens due to how |
331 // the logging layers are started up; but in release, it isn't started in as | 331 // the logging layers are started up; but in release, it isn't started in as |
332 // much of a defined order. So if the symbols had to be loaded, go ahead | 332 // much of a defined order. So if the symbols had to be loaded, go ahead |
333 // and force a call to make sure the manager has been initialized and hence | 333 // and force a call to make sure the manager has been initialized and hence |
334 // the ports are opened. | 334 // the ports are opened. |
335 ProcessSerialNumber psn; | 335 ProcessSerialNumber psn; |
336 GetCurrentProcess(&psn); | 336 GetCurrentProcess(&psn); |
337 } | 337 } |
338 if (!ls_get_current_application_asn_func || | 338 if (!ls_get_current_application_asn_func || |
339 !ls_set_application_information_item_func || | 339 !ls_set_application_information_item_func || |
340 !ls_display_name_key) { | 340 !ls_display_name_key) { |
341 return; | 341 return; |
342 } | 342 } |
343 | 343 |
344 PrivateLSASN asn = ls_get_current_application_asn_func(); | 344 PrivateLSASN asn = ls_get_current_application_asn_func(); |
345 // Constant used by WebKit; what exactly it means is unknown. | 345 // Constant used by WebKit; what exactly it means is unknown. |
346 const int magic_session_constant = -2; | 346 const int magic_session_constant = -2; |
347 OSErr err = | 347 OSErr err = |
348 ls_set_application_information_item_func(magic_session_constant, asn, | 348 ls_set_application_information_item_func(magic_session_constant, asn, |
349 ls_display_name_key, | 349 ls_display_name_key, |
350 process_name, | 350 process_name, |
351 NULL /* optional out param */); | 351 NULL /* optional out param */); |
352 LOG_IF(ERROR, err) << "Call to set process name failed, err " << err; | 352 DLOG_IF(ERROR, err) << "Call to set process name failed, err " << err; |
353 } | 353 } |
354 | 354 |
355 // Converts a NSImage to a CGImageRef. Normally, the system frameworks can do | 355 // Converts a NSImage to a CGImageRef. Normally, the system frameworks can do |
356 // this fine, especially on 10.6. On 10.5, however, CGImage cannot handle | 356 // this fine, especially on 10.6. On 10.5, however, CGImage cannot handle |
357 // converting a PDF-backed NSImage into a CGImageRef. This function will | 357 // converting a PDF-backed NSImage into a CGImageRef. This function will |
358 // rasterize the PDF into a bitmap CGImage. The caller is responsible for | 358 // rasterize the PDF into a bitmap CGImage. The caller is responsible for |
359 // releasing the return value. | 359 // releasing the return value. |
360 CGImageRef CopyNSImageToCGImage(NSImage* image) { | 360 CGImageRef CopyNSImageToCGImage(NSImage* image) { |
361 // This is based loosely on http://www.cocoadev.com/index.pl?CGImageRef . | 361 // This is based loosely on http://www.cocoadev.com/index.pl?CGImageRef . |
362 NSSize size = [image size]; | 362 NSSize size = [image size]; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 void AddToLoginItems(bool hide_on_startup) { | 399 void AddToLoginItems(bool hide_on_startup) { |
400 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); | 400 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); |
401 if (item.get() && (IsHiddenLoginItem(item) == hide_on_startup)) { | 401 if (item.get() && (IsHiddenLoginItem(item) == hide_on_startup)) { |
402 return; // Already is a login item with required hide flag. | 402 return; // Already is a login item with required hide flag. |
403 } | 403 } |
404 | 404 |
405 ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate( | 405 ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate( |
406 NULL, kLSSharedFileListSessionLoginItems, NULL)); | 406 NULL, kLSSharedFileListSessionLoginItems, NULL)); |
407 | 407 |
408 if (!login_items.get()) { | 408 if (!login_items.get()) { |
409 LOG(ERROR) << "Couldn't get a Login Items list."; | 409 DLOG(ERROR) << "Couldn't get a Login Items list."; |
410 return; | 410 return; |
411 } | 411 } |
412 | 412 |
413 // Remove the old item, it has wrong hide flag, we'll create a new one. | 413 // Remove the old item, it has wrong hide flag, we'll create a new one. |
414 if (item.get()) { | 414 if (item.get()) { |
415 LSSharedFileListItemRemove(login_items, item); | 415 LSSharedFileListItemRemove(login_items, item); |
416 } | 416 } |
417 | 417 |
418 NSURL* url = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; | 418 NSURL* url = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; |
419 | 419 |
420 BOOL hide = hide_on_startup ? YES : NO; | 420 BOOL hide = hide_on_startup ? YES : NO; |
421 NSDictionary* properties = | 421 NSDictionary* properties = |
422 [NSDictionary | 422 [NSDictionary |
423 dictionaryWithObject:[NSNumber numberWithBool:hide] | 423 dictionaryWithObject:[NSNumber numberWithBool:hide] |
424 forKey:(NSString*)kLSSharedFileListLoginItemHidden]; | 424 forKey:(NSString*)kLSSharedFileListLoginItemHidden]; |
425 | 425 |
426 ScopedCFTypeRef<LSSharedFileListItemRef> new_item; | 426 ScopedCFTypeRef<LSSharedFileListItemRef> new_item; |
427 new_item.reset(LSSharedFileListInsertItemURL( | 427 new_item.reset(LSSharedFileListInsertItemURL( |
428 login_items, kLSSharedFileListItemLast, NULL, NULL, | 428 login_items, kLSSharedFileListItemLast, NULL, NULL, |
429 reinterpret_cast<CFURLRef>(url), | 429 reinterpret_cast<CFURLRef>(url), |
430 reinterpret_cast<CFDictionaryRef>(properties), NULL)); | 430 reinterpret_cast<CFDictionaryRef>(properties), NULL)); |
431 | 431 |
432 if (!new_item.get()) { | 432 if (!new_item.get()) { |
433 LOG(ERROR) << "Couldn't insert current app into Login Items list."; | 433 DLOG(ERROR) << "Couldn't insert current app into Login Items list."; |
434 } | 434 } |
435 } | 435 } |
436 | 436 |
437 void RemoveFromLoginItems() { | 437 void RemoveFromLoginItems() { |
438 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); | 438 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); |
439 if (!item.get()) | 439 if (!item.get()) |
440 return; | 440 return; |
441 | 441 |
442 ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate( | 442 ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate( |
443 NULL, kLSSharedFileListSessionLoginItems, NULL)); | 443 NULL, kLSSharedFileListSessionLoginItems, NULL)); |
444 | 444 |
445 if (!login_items.get()) { | 445 if (!login_items.get()) { |
446 LOG(ERROR) << "Couldn't get a Login Items list."; | 446 DLOG(ERROR) << "Couldn't get a Login Items list."; |
447 return; | 447 return; |
448 } | 448 } |
449 | 449 |
450 LSSharedFileListItemRemove(login_items, item); | 450 LSSharedFileListItemRemove(login_items, item); |
451 } | 451 } |
452 | 452 |
453 bool WasLaunchedAsLoginOrResumeItem() { | 453 bool WasLaunchedAsLoginOrResumeItem() { |
454 ProcessSerialNumber psn = { 0, kCurrentProcess }; | 454 ProcessSerialNumber psn = { 0, kCurrentProcess }; |
455 | 455 |
456 scoped_nsobject<NSDictionary> process_info( | 456 scoped_nsobject<NSDictionary> process_info( |
(...skipping 17 matching lines...) Expand all Loading... |
474 | 474 |
475 bool WasLaunchedAsHiddenLoginItem() { | 475 bool WasLaunchedAsHiddenLoginItem() { |
476 if (!WasLaunchedAsLoginOrResumeItem()) | 476 if (!WasLaunchedAsLoginOrResumeItem()) |
477 return false; | 477 return false; |
478 | 478 |
479 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); | 479 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); |
480 if (!item.get()) { | 480 if (!item.get()) { |
481 // Lion can launch items for the resume feature. So log an error only for | 481 // Lion can launch items for the resume feature. So log an error only for |
482 // Snow Leopard or earlier. | 482 // Snow Leopard or earlier. |
483 if (IsOSSnowLeopardOrEarlier()) | 483 if (IsOSSnowLeopardOrEarlier()) |
484 LOG(ERROR) << | 484 DLOG(ERROR) << |
485 "Process launched at Login but can't access Login Item List."; | 485 "Process launched at Login but can't access Login Item List."; |
486 | 486 |
487 return false; | 487 return false; |
488 } | 488 } |
489 return IsHiddenLoginItem(item); | 489 return IsHiddenLoginItem(item); |
490 } | 490 } |
491 | 491 |
492 namespace { | 492 namespace { |
493 | 493 |
494 // Returns the running system's Darwin major version. Don't call this, it's | 494 // Returns the running system's Darwin major version. Don't call this, it's |
495 // an implementation detail and its result is meant to be cached by | 495 // an implementation detail and its result is meant to be cached by |
496 // MacOSXMinorVersion. | 496 // MacOSXMinorVersion. |
497 int DarwinMajorVersionInternal() { | 497 int DarwinMajorVersionInternal() { |
498 // base::OperatingSystemVersionNumbers calls Gestalt, which is a | 498 // base::OperatingSystemVersionNumbers calls Gestalt, which is a |
499 // higher-level operation than is needed. It might perform unnecessary | 499 // higher-level operation than is needed. It might perform unnecessary |
500 // operations. On 10.6, it was observed to be able to spawn threads (see | 500 // operations. On 10.6, it was observed to be able to spawn threads (see |
501 // http://crbug.com/53200). It might also read files or perform other | 501 // http://crbug.com/53200). It might also read files or perform other |
502 // blocking operations. Actually, nobody really knows for sure just what | 502 // blocking operations. Actually, nobody really knows for sure just what |
503 // Gestalt might do, or what it might be taught to do in the future. | 503 // Gestalt might do, or what it might be taught to do in the future. |
504 // | 504 // |
505 // uname, on the other hand, is implemented as a simple series of sysctl | 505 // uname, on the other hand, is implemented as a simple series of sysctl |
506 // system calls to obtain the relevant data from the kernel. The data is | 506 // system calls to obtain the relevant data from the kernel. The data is |
507 // compiled right into the kernel, so no threads or blocking or other | 507 // compiled right into the kernel, so no threads or blocking or other |
508 // funny business is necessary. | 508 // funny business is necessary. |
509 | 509 |
510 struct utsname uname_info; | 510 struct utsname uname_info; |
511 if (uname(&uname_info) != 0) { | 511 if (uname(&uname_info) != 0) { |
512 PLOG(ERROR) << "uname"; | 512 DPLOG(ERROR) << "uname"; |
513 return 0; | 513 return 0; |
514 } | 514 } |
515 | 515 |
516 if (strcmp(uname_info.sysname, "Darwin") != 0) { | 516 if (strcmp(uname_info.sysname, "Darwin") != 0) { |
517 LOG(ERROR) << "unexpected uname sysname " << uname_info.sysname; | 517 DLOG(ERROR) << "unexpected uname sysname " << uname_info.sysname; |
518 return 0; | 518 return 0; |
519 } | 519 } |
520 | 520 |
521 int darwin_major_version = 0; | 521 int darwin_major_version = 0; |
522 char* dot = strchr(uname_info.release, '.'); | 522 char* dot = strchr(uname_info.release, '.'); |
523 if (dot) { | 523 if (dot) { |
524 if (!base::StringToInt(uname_info.release, dot, &darwin_major_version)) { | 524 if (!base::StringToInt(uname_info.release, dot, &darwin_major_version)) { |
525 dot = NULL; | 525 dot = NULL; |
526 } | 526 } |
527 } | 527 } |
528 | 528 |
529 if (!dot) { | 529 if (!dot) { |
530 LOG(ERROR) << "could not parse uname release " << uname_info.release; | 530 DLOG(ERROR) << "could not parse uname release " << uname_info.release; |
531 return 0; | 531 return 0; |
532 } | 532 } |
533 | 533 |
534 return darwin_major_version; | 534 return darwin_major_version; |
535 } | 535 } |
536 | 536 |
537 // Returns the running system's Mac OS X minor version. This is the |y| value | 537 // Returns the running system's Mac OS X minor version. This is the |y| value |
538 // in 10.y or 10.y.z. Don't call this, it's an implementation detail and the | 538 // in 10.y or 10.y.z. Don't call this, it's an implementation detail and the |
539 // result is meant to be cached by MacOSXMinorVersion. | 539 // result is meant to be cached by MacOSXMinorVersion. |
540 int MacOSXMinorVersionInternal() { | 540 int MacOSXMinorVersionInternal() { |
541 int darwin_major_version = DarwinMajorVersionInternal(); | 541 int darwin_major_version = DarwinMajorVersionInternal(); |
542 | 542 |
543 // The Darwin major version is always 4 greater than the Mac OS X minor | 543 // The Darwin major version is always 4 greater than the Mac OS X minor |
544 // version for Darwin versions beginning with 6, corresponding to Mac OS X | 544 // version for Darwin versions beginning with 6, corresponding to Mac OS X |
545 // 10.2. Since this correspondence may change in the future, warn when | 545 // 10.2. Since this correspondence may change in the future, warn when |
546 // encountering a version higher than anything seen before. Older Darwin | 546 // encountering a version higher than anything seen before. Older Darwin |
547 // versions, or versions that can't be determined, result in | 547 // versions, or versions that can't be determined, result in |
548 // immediate death. | 548 // immediate death. |
549 CHECK(darwin_major_version >= 6); | 549 CHECK(darwin_major_version >= 6); |
550 int mac_os_x_minor_version = darwin_major_version - 4; | 550 int mac_os_x_minor_version = darwin_major_version - 4; |
551 LOG_IF(WARNING, darwin_major_version > 11) << "Assuming Darwin " | 551 DLOG_IF(WARNING, darwin_major_version > 11) << "Assuming Darwin " |
552 << base::IntToString(darwin_major_version) << " is Mac OS X 10." | 552 << base::IntToString(darwin_major_version) << " is Mac OS X 10." |
553 << base::IntToString(mac_os_x_minor_version); | 553 << base::IntToString(mac_os_x_minor_version); |
554 | 554 |
555 return mac_os_x_minor_version; | 555 return mac_os_x_minor_version; |
556 } | 556 } |
557 | 557 |
558 // Returns the running system's Mac OS X minor version. This is the |y| value | 558 // Returns the running system's Mac OS X minor version. This is the |y| value |
559 // in 10.y or 10.y.z. | 559 // in 10.y or 10.y.z. |
560 int MacOSXMinorVersion() { | 560 int MacOSXMinorVersion() { |
561 static int mac_os_x_minor_version = MacOSXMinorVersionInternal(); | 561 static int mac_os_x_minor_version = MacOSXMinorVersionInternal(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 #endif | 613 #endif |
614 | 614 |
615 #if !defined(BASE_MAC_MAC_UTIL_H_INLINED_GT_10_7) | 615 #if !defined(BASE_MAC_MAC_UTIL_H_INLINED_GT_10_7) |
616 bool IsOSLaterThanLion() { | 616 bool IsOSLaterThanLion() { |
617 return MacOSXMinorVersion() > LION_MINOR_VERSION; | 617 return MacOSXMinorVersion() > LION_MINOR_VERSION; |
618 } | 618 } |
619 #endif | 619 #endif |
620 | 620 |
621 } // namespace mac | 621 } // namespace mac |
622 } // namespace base | 622 } // namespace base |
OLD | NEW |