15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/foundation_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/bundle_locations.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_logging.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/sys_string_conversions.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_IOS) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFTypeID SecACLGetTypeID(); 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFTypeID SecTrustedApplicationGetTypeID(); 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)Boolean _CFIsObjC(CFTypeID typeID, CFTypeRef obj); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // extern "C" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace mac { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool g_override_am_i_bundled = false; 301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool g_override_am_i_bundled_value = false; 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool UncachedAmIBundled() { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // All apps are bundled on iOS. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_override_am_i_bundled) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_override_am_i_bundled_value; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Yes, this is cheap. 411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return [[base::mac::OuterBundle() bundlePath] hasSuffix:@".app"]; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} // namespace 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AmIBundled() { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the return value is not cached, this function will return different 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // values depending on when it's called. This confuses some client code, see 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/63183 . 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool result = UncachedAmIBundled(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(result, UncachedAmIBundled()) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "The return value of AmIBundled() changed. This will confuse tests. " 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Call SetAmIBundled() override manually if your test binary " 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "delay-loads the framework."; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetOverrideAmIBundled(bool value) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It doesn't make sense not to be bundled on iOS. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_override_am_i_bundled = true; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_override_am_i_bundled_value = value; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsBackgroundOnlyProcess() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function really does want to examine NSBundle's idea of the main 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bundle dictionary. It needs to look at the actual running .app's 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Info.plist to access its LSUIElement property. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSDictionary* info_dictionary = [base::mac::MainBundle() infoDictionary]; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [[info_dictionary objectForKey:@"LSUIElement"] boolValue] != NO; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath PathForFrameworkBundleResource(CFStringRef resourceName) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSBundle* bundle = base::mac::FrameworkBundle(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* resourcePath = [bundle pathForResource:(NSString*)resourceName 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ofType:nil]; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NSStringToFilePath(resourcePath); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OSType CreatorCodeForCFBundleRef(CFBundleRef bundle) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OSType creator = kUnknownType; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFBundleGetPackageInfo(bundle, NULL, &creator); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return creator; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OSType CreatorCodeForApplication() { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFBundleRef bundle = CFBundleGetMainBundle(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bundle) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kUnknownType; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreatorCodeForCFBundleRef(bundle); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetSearchPathDirectory(NSSearchPathDirectory directory, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSSearchPathDomainMask domain_mask, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath* result) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(result); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSArray* dirs = 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSSearchPathForDirectoriesInDomains(directory, domain_mask, YES); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ([dirs count] < 1) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = NSStringToFilePath([dirs objectAtIndex:0]); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetLocalDirectory(NSSearchPathDirectory directory, FilePath* result) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetSearchPathDirectory(directory, NSLocalDomainMask, result); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetUserDirectory(NSSearchPathDirectory directory, FilePath* result) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetSearchPathDirectory(directory, NSUserDomainMask, result); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath GetUserLibraryPath() { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath user_library_path; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetUserDirectory(NSLibraryDirectory, &user_library_path)) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "Could not get user library path"; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return user_library_path; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Takes a path to an (executable) binary and tries to provide the path to an 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// application bundle containing it. It takes the outermost bundle that it can 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// find (so for "/Foo/Bar.app/.../Baz.app/..." it produces "/Foo/Bar.app"). 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |exec_name| - path to the binary 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returns - path to the application bundle, or empty on error 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath GetAppBundlePath(const FilePath& exec_name) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kExt[] = ".app"; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kExtLength = arraysize(kExt) - 1; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Split the path into components. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> components; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exec_name.GetComponents(&components); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's an error if we don't get any components. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!components.size()) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilePath(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't prepend '/' to the first component. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>::const_iterator it = components.begin(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string bundle_name = *it; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(it->length(), 0U); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the first component ends in ".app", we're already done. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->length() > kExtLength && 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !it->compare(it->length() - kExtLength, kExtLength, kExt, kExtLength)) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilePath(bundle_name); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first component may be "/" or "//", etc. Only append '/' if it doesn't 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already end in '/'. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bundle_name[bundle_name.length() - 1] != '/') 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bundle_name += '/'; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Go through the remaining components. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (++it; it != components.end(); ++it) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(it->length(), 0U); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bundle_name += *it; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the current component ends in ".app", we're done. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->length() > kExtLength && 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !it->compare(it->length() - kExtLength, kExtLength, kExt, kExtLength)) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilePath(bundle_name); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Separate this component from the next one. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bundle_name += '/'; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilePath(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TYPE_NAME_FOR_CF_TYPE_DEFN(TypeCF) \ 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TypeNameForCFType(TypeCF##Ref) { \ 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return #TypeCF; \ 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFArray); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFBag); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFBoolean); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFData); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFDate); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFDictionary); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFNull); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFNumber); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFSet); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFString); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFURL); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CFUUID); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CGColor); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CTFont); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TYPE_NAME_FOR_CF_TYPE_DEFN(CTRun); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef TYPE_NAME_FOR_CF_TYPE_DEFN 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NSObjectRetain(void* obj) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id<NSObject> nsobj = static_cast<id<NSObject> >(obj); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [nsobj retain]; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NSObjectRelease(void* obj) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id<NSObject> nsobj = static_cast<id<NSObject> >(obj); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [nsobj release]; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* CFTypeRefToNSObjectAutorelease(CFTypeRef cf_object) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When GC is on, NSMakeCollectable marks cf_object for GC and autorelease 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is a no-op. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In the traditional GC-less environment, NSMakeCollectable is a no-op, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and cf_object is autoreleased, balancing out the caller's ownership claim. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NSMakeCollectable returns nil when used on a NULL object. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [NSMakeCollectable(cf_object) autorelease]; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* base_bundle_id; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* BaseBundleID() { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base_bundle_id) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_bundle_id; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "com.google.Chrome"; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "org.chromium.Chromium"; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetBaseBundleID(const char* new_base_bundle_id) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_base_bundle_id != base_bundle_id) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free((void*)base_bundle_id); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_bundle_id = new_base_bundle_id ? strdup(new_base_bundle_id) : NULL; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Definitions for the corresponding CF_TO_NS_CAST_DECL macros in 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// foundation_util.h. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CF_TO_NS_CAST_DEFN(TypeCF, TypeNS) \ 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)\ 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TypeNS* CFToNSCast(TypeCF##Ref cf_val) { \ 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TypeNS* ns_val = \ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<TypeNS*>(reinterpret_cast<const TypeNS*>(cf_val)); \ 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ns_val; \ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} \ 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)\ 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TypeCF##Ref NSToCFCast(TypeNS* ns_val) { \ 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TypeCF##Ref cf_val = reinterpret_cast<TypeCF##Ref>(ns_val); \ 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \ 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cf_val; \ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CF_TO_NS_MUTABLE_CAST_DEFN(name) \ 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CF##name, NS##name) \ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)\ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSMutable##name* CFToNSCast(CFMutable##name##Ref cf_val) { \ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \ 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSMutable##name* ns_val = reinterpret_cast<NSMutable##name*>(cf_val); \ 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ns_val; \ 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} \ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)\ 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFMutable##name##Ref NSToCFCast(NSMutable##name* ns_val) { \ 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFMutable##name##Ref cf_val = \ 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<CFMutable##name##Ref>(ns_val); \ 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \ 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cf_val; \ 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_MUTABLE_CAST_DEFN(Array); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_MUTABLE_CAST_DEFN(AttributedString); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFCalendar, NSCalendar); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_MUTABLE_CAST_DEFN(CharacterSet); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_MUTABLE_CAST_DEFN(Data); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFDate, NSDate); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_MUTABLE_CAST_DEFN(Dictionary); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFError, NSError); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFLocale, NSLocale); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFNumber, NSNumber); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFRunLoopTimer, NSTimer); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFTimeZone, NSTimeZone); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_MUTABLE_CAST_DEFN(Set); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFReadStream, NSInputStream); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFWriteStream, NSOutputStream); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_MUTABLE_CAST_DEFN(String); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CFURL, NSURL); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_IOS) 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)CF_TO_NS_CAST_DEFN(CTFont, UIFont); 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#else 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// The NSFont/CTFont toll-free bridging is broken when it comes to type 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// checking, so do some special-casing. 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// http://www.openradar.me/15341349 rdar://15341349 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)NSFont* CFToNSCast(CTFontRef cf_val) { 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NSFont* ns_val = 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const_cast<NSFont*>(reinterpret_cast<const NSFont*>(cf_val)); 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!cf_val || 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CTFontGetTypeID() == CFGetTypeID(cf_val) || 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) (_CFIsObjC(CTFontGetTypeID(), cf_val) && 3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) [ns_val isKindOfClass:NSClassFromString(@"NSFont")])); 3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return ns_val; 3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)CTFontRef NSToCFCast(NSFont* ns_val) { 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CTFontRef cf_val = reinterpret_cast<CTFontRef>(ns_val); 3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!cf_val || 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CTFontGetTypeID() == CFGetTypeID(cf_val) || 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) [ns_val isKindOfClass:NSClassFromString(@"NSFont")]); 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return cf_val; 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CF_TO_NS_CAST_DEFN 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CF_TO_NS_MUTABLE_CAST_DEFN 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CF_CAST_DEFN(TypeCF) \ 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<> TypeCF##Ref \ 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFCast<TypeCF##Ref>(const CFTypeRef& cf_val) { \ 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cf_val == NULL) { \ 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; \ 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CFGetTypeID(cf_val) == TypeCF##GetTypeID()) { \ 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (TypeCF##Ref)(cf_val); \ 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; \ 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} \ 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)\ 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<> TypeCF##Ref \ 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFCastStrict<TypeCF##Ref>(const CFTypeRef& cf_val) { \ 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TypeCF##Ref rv = CFCast<TypeCF##Ref>(cf_val); \ 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(cf_val == NULL || rv); \ 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; \ 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFArray); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFBag); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFBoolean); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFData); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFDate); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFDictionary); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFNull); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFNumber); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFSet); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFString); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFURL); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CFUUID); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CGColor); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(CTRun); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_IOS) 3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)CF_CAST_DEFN(CTFont); 3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#else 3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// The NSFont/CTFont toll-free bridging is broken when it comes to type 3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// checking, so do some special-casing. 3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// http://www.openradar.me/15341349 rdar://15341349 3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template<> CTFontRef 3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)CFCast<CTFontRef>(const CFTypeRef& cf_val) { 3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (cf_val == NULL) { 3671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (CFGetTypeID(cf_val) == CTFontGetTypeID()) { 3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return (CTFontRef)(cf_val); 3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!_CFIsObjC(CTFontGetTypeID(), cf_val)) 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) id<NSObject> ns_val = reinterpret_cast<id>(const_cast<void*>(cf_val)); 3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if ([ns_val isKindOfClass:NSClassFromString(@"NSFont")]) { 3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return (CTFontRef)(cf_val); 3791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 3811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template<> CTFontRef 3841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)CFCastStrict<CTFontRef>(const CFTypeRef& cf_val) { 3851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CTFontRef rv = CFCast<CTFontRef>(cf_val); 3861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(cf_val == NULL || rv); 3871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return rv; 3881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 3901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_IOS) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(SecACL); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CF_CAST_DEFN(SecTrustedApplication); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CF_CAST_DEFN 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetValueFromDictionaryErrorMessage( 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef key, const std::string& expected_type, CFTypeRef value) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedCFTypeRef<CFStringRef> actual_type_ref( 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFCopyTypeIDDescription(CFGetTypeID(value))); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Expected value for key " + 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SysCFStringRefToUTF8(key) + 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " to be " + 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_type + 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " but it was " + 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SysCFStringRefToUTF8(actual_type_ref) + 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " instead"; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSString* FilePathToNSString(const FilePath& path) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (path.empty()) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return nil; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [NSString stringWithUTF8String:path.value().c_str()]; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath NSStringToFilePath(NSString* str) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (![str length]) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilePath(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilePath([str fileSystemRepresentation]); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace mac 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::ostream& operator<<(std::ostream& o, const CFStringRef string) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return o << base::SysCFStringRefToUTF8(string); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::ostream& operator<<(std::ostream& o, const CFErrorRef err) { 431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFStringRef> desc(CFErrorCopyDescription(err)); 432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFDictionaryRef> user_info(CFErrorCopyUserInfo(err)); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef errorDesc = NULL; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (user_info.get()) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errorDesc = reinterpret_cast<CFStringRef>( 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFDictionaryGetValue(user_info.get(), kCFErrorDescriptionKey)); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) o << "Code: " << CFErrorGetCode(err) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Domain: " << CFErrorGetDomain(err) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " Desc: " << desc.get(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(errorDesc) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) o << "(" << errorDesc << ")"; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return o; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 446