Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include "base/mac/foundation_util.h" | 5 #include "base/mac/foundation_util.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/mac/bundle_locations.h" | 12 #include "base/mac/bundle_locations.h" |
| 13 #include "base/mac/mac_logging.h" | 13 #include "base/mac/mac_logging.h" |
| 14 #include "base/strings/sys_string_conversions.h" | 14 #include "base/strings/sys_string_conversions.h" |
| 15 | 15 |
| 16 #if !defined(OS_IOS) | 16 #if !defined(OS_IOS) |
| 17 extern "C" { | 17 extern "C" { |
| 18 CFTypeID SecACLGetTypeID(); | 18 CFTypeID SecACLGetTypeID(); |
| 19 CFTypeID SecTrustedApplicationGetTypeID(); | 19 CFTypeID SecTrustedApplicationGetTypeID(); |
| 20 } // extern "C" | 20 } // extern "C" |
| 21 #endif | 21 #endif |
| 22 | 22 |
| 23 namespace base { | 23 namespace base { |
| 24 namespace mac { | 24 namespace mac { |
| 25 | 25 |
| 26 static bool g_override_am_i_bundled = false; | 26 namespace { |
| 27 static bool g_override_am_i_bundled_value = false; | |
| 28 | 27 |
| 29 // Adapted from http://developer.apple.com/carbon/tipsandtricks.html#AmIBundled | 28 bool g_override_am_i_bundled = false; |
| 30 static bool UncachedAmIBundled() { | 29 bool g_override_am_i_bundled_value = false; |
| 30 | |
| 31 NSUInteger CheapPathNormalizedCount(NSArray* path_array) { | |
|
Mark Mentovai
2013/10/28 15:57:09
Don’t use an unsigned, because count could legitim
| |
| 32 NSUInteger count = 0; | |
| 33 for (NSString* component in path_array) { | |
| 34 if ([component isEqualToString:@"."]) | |
| 35 continue; | |
| 36 else if ([component isEqualToString:@".."]) | |
| 37 --count; | |
| 38 else | |
| 39 ++count; | |
| 40 } | |
| 41 | |
| 42 return count; | |
| 43 } | |
| 44 | |
| 45 bool UncachedAmIBundled() { | |
| 31 #if defined(OS_IOS) | 46 #if defined(OS_IOS) |
| 32 // All apps are bundled on iOS. | 47 // All apps are bundled on iOS. |
| 33 return true; | 48 return true; |
| 34 #else | 49 #else |
| 35 if (g_override_am_i_bundled) | 50 if (g_override_am_i_bundled) |
| 36 return g_override_am_i_bundled_value; | 51 return g_override_am_i_bundled_value; |
| 37 | 52 |
| 38 NSBundle* bundle = base::mac::OuterBundle(); | 53 NSBundle* bundle = base::mac::OuterBundle(); |
| 39 NSArray* bundle_parts = [[bundle bundlePath] pathComponents]; | 54 NSUInteger bundle_count = |
| 40 NSArray* executable_parts = [[bundle executablePath] pathComponents]; | 55 CheapPathNormalizedCount([[bundle bundlePath] pathComponents]); |
| 56 NSUInteger executable_count = | |
| 57 CheapPathNormalizedCount([[bundle executablePath] pathComponents]); | |
| 41 | 58 |
| 42 // Bundled executables are exactly three levels deeper than their bundle. | 59 // Bundled executables are exactly three levels deeper than their bundle. |
| 43 // Non-bundled executables have a fake bundle with a bundle path of their | 60 // Non-bundled executables have a fake bundle with a bundle path of their |
| 44 // parent directory. | 61 // parent directory. |
| 45 NSUInteger depth_difference = [executable_parts count] - [bundle_parts count]; | 62 NSUInteger depth_difference = executable_count - bundle_count; |
| 46 CHECK(depth_difference == 1 || depth_difference == 3); | 63 CHECK(depth_difference == 1 || depth_difference == 3); |
| 47 return depth_difference == 3; | 64 return depth_difference == 3; |
| 48 #endif | 65 #endif |
| 49 } | 66 } |
| 50 | 67 |
| 68 } // namespace | |
| 69 | |
| 51 bool AmIBundled() { | 70 bool AmIBundled() { |
| 52 // If the return value is not cached, this function will return different | 71 // If the return value is not cached, this function will return different |
| 53 // values depending on when it's called. This confuses some client code, see | 72 // values depending on when it's called. This confuses some client code, see |
| 54 // http://crbug.com/63183 . | 73 // http://crbug.com/63183 . |
| 55 static bool result = UncachedAmIBundled(); | 74 static bool result = UncachedAmIBundled(); |
| 56 DCHECK_EQ(result, UncachedAmIBundled()) | 75 DCHECK_EQ(result, UncachedAmIBundled()) |
| 57 << "The return value of AmIBundled() changed. This will confuse tests. " | 76 << "The return value of AmIBundled() changed. This will confuse tests. " |
| 58 << "Call SetAmIBundled() override manually if your test binary " | 77 << "Call SetAmIBundled() override manually if your test binary " |
| 59 << "delay-loads the framework."; | 78 << "delay-loads the framework."; |
| 60 return result; | 79 return result; |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 CFDictionaryGetValue(user_info.get(), kCFErrorDescriptionKey)); | 402 CFDictionaryGetValue(user_info.get(), kCFErrorDescriptionKey)); |
| 384 } | 403 } |
| 385 o << "Code: " << CFErrorGetCode(err) | 404 o << "Code: " << CFErrorGetCode(err) |
| 386 << " Domain: " << CFErrorGetDomain(err) | 405 << " Domain: " << CFErrorGetDomain(err) |
| 387 << " Desc: " << desc.get(); | 406 << " Desc: " << desc.get(); |
| 388 if(errorDesc) { | 407 if(errorDesc) { |
| 389 o << "(" << errorDesc << ")"; | 408 o << "(" << errorDesc << ")"; |
| 390 } | 409 } |
| 391 return o; | 410 return o; |
| 392 } | 411 } |
| OLD | NEW |