1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/extensions/path_util.h" 6 7#include "base/path_service.h" 8#include "base/strings/sys_string_conversions.h" 9 10#if defined(OS_MACOSX) 11#include <CoreFoundation/CoreFoundation.h> 12#include "base/mac/foundation_util.h" 13#endif 14 15#if defined(OS_CHROMEOS) 16#include "chrome/browser/chromeos/file_manager/filesystem_api_util.h" 17#endif 18 19namespace extensions { 20namespace path_util { 21 22namespace { 23#if defined(OS_MACOSX) 24 25// Retrieves the localized display name for the base name of the given path. 26// If the path is not localized, this will just return the base name. 27std::string GetDisplayBaseName(const base::FilePath& path) { 28 base::ScopedCFTypeRef<CFURLRef> url(CFURLCreateFromFileSystemRepresentation( 29 NULL, (const UInt8*)path.value().c_str(), path.value().length(), true)); 30 if (!url) 31 return path.BaseName().value(); 32 33 CFStringRef str; 34 if (LSCopyDisplayNameForURL(url, &str) != noErr) 35 return path.BaseName().value(); 36 37 std::string result(base::SysCFStringRefToUTF8(str)); 38 CFRelease(str); 39 return result; 40} 41 42#endif // defined(OS_MACOSX) 43 44const base::FilePath::CharType kHomeShortcut[] = FILE_PATH_LITERAL("~"); 45 46} // namespace 47 48base::FilePath PrettifyPath(const base::FilePath& source_path) { 49 base::FilePath home_path; 50 if (source_path.empty() || !PathService::Get(base::DIR_HOME, &home_path)) 51 return source_path; 52 53 base::FilePath display_path = base::FilePath(kHomeShortcut); 54 if (source_path == home_path) 55 return display_path; 56 57#if defined(OS_MACOSX) 58 DCHECK(source_path.IsAbsolute()); 59 60 // Break down the incoming path into components, and grab the display name 61 // for every component. This will match app bundles, ".localized" folders, 62 // and localized subfolders of the user's home directory. 63 // Don't grab the display name of the first component, i.e., "/", as it'll 64 // show up as the HDD name. 65 std::vector<base::FilePath::StringType> components; 66 source_path.GetComponents(&components); 67 display_path = base::FilePath(components[0]); 68 base::FilePath actual_path = display_path; 69 for (std::vector<base::FilePath::StringType>::iterator i = 70 components.begin() + 1; i != components.end(); ++i) { 71 actual_path = actual_path.Append(*i); 72 if (actual_path == home_path) { 73 display_path = base::FilePath(kHomeShortcut); 74 home_path = base::FilePath(); 75 continue; 76 } 77 std::string display = GetDisplayBaseName(actual_path); 78 display_path = display_path.Append(display); 79 } 80 DCHECK_EQ(actual_path.value(), source_path.value()); 81 return display_path; 82#else // defined(OS_MACOSX) 83 if (home_path.AppendRelativePath(source_path, &display_path)) 84 return display_path; 85 return source_path; 86#endif // defined(OS_MACOSX) 87} 88 89} // namespace path_util 90} // namespace extensions 91