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 "chrome/browser/platform_util.h" | 5 #include "chrome/browser/platform_util.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | |
| 8 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 9 #include "base/process/kill.h" | 10 #include "base/process/kill.h" |
| 10 #include "base/process/launch.h" | 11 #include "base/process/launch.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "base/version.h" | |
| 12 #include "chrome/browser/platform_util_internal.h" | 14 #include "chrome/browser/platform_util_internal.h" |
| 13 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 14 #include "url/gurl.h" | 16 #include "url/gurl.h" |
| 15 | 17 |
| 16 using content::BrowserThread; | 18 using content::BrowserThread; |
| 17 | 19 |
| 18 namespace platform_util { | 20 namespace platform_util { |
| 19 | 21 |
| 20 namespace { | 22 namespace { |
| 21 | 23 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 49 } | 51 } |
| 50 | 52 |
| 51 void XDGOpen(const base::FilePath& working_directory, const std::string& path) { | 53 void XDGOpen(const base::FilePath& working_directory, const std::string& path) { |
| 52 XDGUtil("xdg-open", working_directory, path); | 54 XDGUtil("xdg-open", working_directory, path); |
| 53 } | 55 } |
| 54 | 56 |
| 55 void XDGEmail(const std::string& email) { | 57 void XDGEmail(const std::string& email) { |
| 56 XDGUtil("xdg-email", base::FilePath(), email); | 58 XDGUtil("xdg-email", base::FilePath(), email); |
| 57 } | 59 } |
| 58 | 60 |
| 61 const char kNautilusKey[] = "nautilus.desktop"; | |
| 62 const char kNautilusCmd[] = "nautilus"; | |
| 63 const char kSupportedNautilusVersion[] = "3.0.2"; | |
| 64 | |
| 65 void ShowFileInNautilus(const base::FilePath& working_directory, | |
| 66 const std::string& path) { | |
| 67 XDGUtil(kNautilusCmd, working_directory, path); | |
|
Lei Zhang
2016/04/20 20:45:57
XDGUtil() should be renamed since it's not just la
| |
| 68 } | |
| 69 | |
| 70 std::string GetNautilusVersion() { | |
| 71 std::string output; | |
| 72 std::string found_version; | |
| 73 | |
| 74 base::CommandLine nautilus_cl((base::FilePath(kNautilusCmd))); | |
| 75 nautilus_cl.AppendArg("--version"); | |
|
Lei Zhang
2016/04/20 20:45:57
nit: indentation
| |
| 76 | |
| 77 if (base::GetAppOutputAndError(nautilus_cl, &output)) { | |
| 78 const std::size_t version_position = output.find(kNautilusCmd) + | |
|
Lei Zhang
2016/04/20 20:45:57
Shouldn't you check the output.find() result befor
| |
| 79 std::strlen(kNautilusCmd) + 1; | |
| 80 found_version = output.substr(version_position); | |
| 81 | |
| 82 if (!found_version.empty() && | |
| 83 (found_version[found_version.length() - 1]) == '\n') { | |
|
Lei Zhang
2016/04/20 20:45:57
Why do you need the parenthesis around foo[bar] ?
| |
| 84 found_version.erase(found_version.length()-1); | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 return found_version; | |
| 89 } | |
| 90 | |
| 91 std::string CheckNautilusIsDefault() { | |
|
Lei Zhang
2016/04/20 20:45:57
Why not just return a bool?
| |
| 92 const base::Version supported_version(kSupportedNautilusVersion); | |
| 93 std::string file_browser; | |
| 94 | |
| 95 base::CommandLine xdg_mime(base::FilePath("xdg-mime")); | |
| 96 xdg_mime.AppendArg("query"); | |
|
Lei Zhang
2016/04/20 20:45:57
Also indentation. If you are not familiar with Chr
| |
| 97 xdg_mime.AppendArg("default"); | |
| 98 xdg_mime.AppendArg("inode/directory"); | |
| 99 | |
| 100 if (base::GetAppOutputAndError(xdg_mime, &file_browser)) { | |
| 101 if (file_browser.find(kNautilusKey) != std::string::npos) { | |
| 102 base::Version current_version(GetNautilusVersion()); | |
| 103 if ((current_version.IsValid() && supported_version.IsValid()) && | |
| 104 (current_version >= supported_version)) { | |
| 105 file_browser = kNautilusKey; | |
| 106 return file_browser; | |
| 107 } | |
| 108 } | |
| 109 } | |
| 110 return file_browser; | |
| 111 } | |
| 112 | |
| 113 void ShowItem(Profile* profile, const base::FilePath& full_path, | |
| 114 const std::string& file_browser) { | |
| 115 if (file_browser == kNautilusKey) { | |
| 116 OpenItem(profile, full_path, SHOW_ITEM_IN_FOLDER, OpenOperationCallback()); | |
| 117 } else { | |
| 118 OpenItem(profile, full_path.DirName(), OPEN_FOLDER, | |
|
Lei Zhang
2016/04/20 20:45:57
The TODO from estade still applies, for non-Nautil
| |
| 119 OpenOperationCallback()); | |
| 120 } | |
| 121 } | |
| 122 | |
| 59 } // namespace | 123 } // namespace |
| 60 | 124 |
| 61 namespace internal { | 125 namespace internal { |
| 62 | 126 |
| 63 void PlatformOpenVerifiedItem(const base::FilePath& path, OpenItemType type) { | 127 void PlatformOpenVerifiedItem(const base::FilePath& path, OpenItemType type) { |
| 64 switch (type) { | 128 switch (type) { |
| 65 case OPEN_FILE: | 129 case OPEN_FILE: |
| 66 XDGOpen(path.DirName(), path.value()); | 130 XDGOpen(path.DirName(), path.value()); |
| 67 break; | 131 break; |
| 68 case OPEN_FOLDER: | 132 case OPEN_FOLDER: |
| 69 // The utility process checks the working directory prior to the | 133 // The utility process checks the working directory prior to the |
| 70 // invocation of xdg-open by changing the current directory into it. This | 134 // invocation of xdg-open by changing the current directory into it. This |
| 71 // operation only succeeds if |path| is a directory. Opening "." from | 135 // operation only succeeds if |path| is a directory. Opening "." from |
| 72 // there ensures that the target of the operation is a directory. Note | 136 // there ensures that the target of the operation is a directory. Note |
| 73 // that there remains a TOCTOU race where the directory could be unlinked | 137 // that there remains a TOCTOU race where the directory could be unlinked |
| 74 // between the time the utility process changes into the directory and the | 138 // between the time the utility process changes into the directory and the |
| 75 // time the application invoked by xdg-open inspects the path by name. | 139 // time the application invoked by xdg-open inspects the path by name. |
| 76 XDGOpen(path, "."); | 140 XDGOpen(path, "."); |
| 77 break; | 141 break; |
| 142 case SHOW_ITEM_IN_FOLDER: | |
| 143 ShowFileInNautilus(path.DirName(), path.value()); | |
| 144 break; | |
| 78 } | 145 } |
| 79 } | 146 } |
| 147 | |
| 80 } // namespace internal | 148 } // namespace internal |
| 81 | 149 |
| 82 void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) { | 150 void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) { |
| 83 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 151 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 84 // TODO(estade): It would be nice to be able to select the file in the file | 152 base::PostTaskAndReplyWithResult( |
| 85 // manager, but that probably requires extending xdg-open. For now just show | 153 content::BrowserThread::GetBlockingPool(), |
| 86 // the folder. | 154 FROM_HERE, |
| 87 OpenItem(profile, full_path.DirName(), OPEN_FOLDER, OpenOperationCallback()); | 155 base::Bind(&CheckNautilusIsDefault), |
| 156 base::Bind(&ShowItem, profile, full_path)); | |
| 88 } | 157 } |
| 89 | 158 |
| 90 void OpenExternal(Profile* profile, const GURL& url) { | 159 void OpenExternal(Profile* profile, const GURL& url) { |
| 91 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 160 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 92 if (url.SchemeIs("mailto")) | 161 if (url.SchemeIs("mailto")) |
| 93 XDGEmail(url.spec()); | 162 XDGEmail(url.spec()); |
| 94 else | 163 else |
| 95 XDGOpen(base::FilePath(), url.spec()); | 164 XDGOpen(base::FilePath(), url.spec()); |
| 96 } | 165 } |
| 97 | 166 |
| 98 } // namespace platform_util | 167 } // namespace platform_util |
| OLD | NEW |