Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: chrome/browser/chromeos/file_manager/open_util.cc

Issue 352393002: Be explicit about target type in platform_util::OpenItem() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Catch up with changes to JSONStringValueSerializer and address CrOS comment Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/chromeos/file_manager/open_util.h" 5 #include "chrome/browser/chromeos/file_manager/open_util.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/chromeos/drive/file_system_util.h" 11 #include "chrome/browser/chromeos/drive/file_system_util.h"
12 #include "chrome/browser/chromeos/file_manager/app_id.h" 12 #include "chrome/browser/chromeos/file_manager/app_id.h"
13 #include "chrome/browser/chromeos/file_manager/file_tasks.h" 13 #include "chrome/browser/chromeos/file_manager/file_tasks.h"
14 #include "chrome/browser/chromeos/file_manager/fileapi_util.h" 14 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
15 #include "chrome/browser/chromeos/file_manager/path_util.h" 15 #include "chrome/browser/chromeos/file_manager/path_util.h"
16 #include "chrome/browser/chromeos/file_manager/url_util.h" 16 #include "chrome/browser/chromeos/file_manager/url_util.h"
17 #include "chrome/browser/extensions/api/file_handlers/mime_util.h" 17 #include "chrome/browser/extensions/api/file_handlers/mime_util.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_finder.h"
20 #include "chrome/browser/ui/browser_window.h"
21 #include "chrome/browser/ui/simple_message_box.h"
22 #include "chrome/grit/generated_resources.h"
23 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/user_metrics.h" 19 #include "content/public/browser/user_metrics.h"
25 #include "storage/browser/fileapi/file_system_backend.h" 20 #include "storage/browser/fileapi/file_system_backend.h"
26 #include "storage/browser/fileapi/file_system_context.h" 21 #include "storage/browser/fileapi/file_system_context.h"
27 #include "storage/browser/fileapi/file_system_operation_runner.h" 22 #include "storage/browser/fileapi/file_system_operation_runner.h"
28 #include "storage/browser/fileapi/file_system_url.h" 23 #include "storage/browser/fileapi/file_system_url.h"
29 #include "ui/base/l10n/l10n_util.h"
30 24
31 using content::BrowserThread; 25 using content::BrowserThread;
32 using storage::FileSystemURL; 26 using storage::FileSystemURL;
33 27
34 namespace file_manager { 28 namespace file_manager {
35 namespace util { 29 namespace util {
36 namespace { 30 namespace {
37 31
38 // Shows a warning message box saying that the file could not be opened. 32 bool shell_operations_allowed = true;
39 void ShowWarningMessageBox(Profile* profile,
40 const base::FilePath& file_path,
41 int message_id) {
42 Browser* browser = chrome::FindTabbedBrowser(
43 profile, false, chrome::HOST_DESKTOP_TYPE_ASH);
44 chrome::ShowMessageBox(
45 browser ? browser->window()->GetNativeWindow() : NULL,
46 l10n_util::GetStringFUTF16(
47 IDS_FILE_BROWSER_ERROR_VIEWING_FILE_TITLE,
48 base::UTF8ToUTF16(file_path.BaseName().AsUTF8Unsafe())),
49 l10n_util::GetStringUTF16(message_id),
50 chrome::MESSAGE_BOX_TYPE_WARNING);
51 }
52 33
53 // Executes the |task| for the file specified by |url|. 34 // Executes the |task| for the file specified by |url|.
54 void ExecuteFileTaskForUrl(Profile* profile, 35 void ExecuteFileTaskForUrl(Profile* profile,
55 const file_tasks::TaskDescriptor& task, 36 const file_tasks::TaskDescriptor& task,
56 const GURL& url) { 37 const GURL& url) {
38 if (!shell_operations_allowed)
39 return;
57 storage::FileSystemContext* file_system_context = 40 storage::FileSystemContext* file_system_context =
58 GetFileSystemContextForExtensionId(profile, kFileManagerAppId); 41 GetFileSystemContextForExtensionId(profile, kFileManagerAppId);
59 42
60 file_tasks::ExecuteFileTask( 43 file_tasks::ExecuteFileTask(
61 profile, 44 profile,
62 GetFileManagerMainPageUrl(), // Executing the task on behalf of Files.app. 45 GetFileManagerMainPageUrl(), // Executing the task on behalf of Files.app.
63 task, 46 task,
64 std::vector<FileSystemURL>(1, file_system_context->CrackURL(url)), 47 std::vector<FileSystemURL>(1, file_system_context->CrackURL(url)),
65 file_tasks::FileTaskFinishedCallback()); 48 file_tasks::FileTaskFinishedCallback());
66 } 49 }
67 50
68 // Opens the file manager for the specified |url|. Used to implement 51 // Opens the file manager for the specified |url|. Used to implement
69 // internal handlers of special action IDs: 52 // internal handlers of special action IDs:
70 // 53 //
71 // "open" - Open the file manager for the given folder. 54 // "open" - Open the file manager for the given folder.
72 // "select" - Open the file manager for the given file. The folder containing 55 // "select" - Open the file manager for the given file. The folder containing
73 // the file will be opened with the file selected. 56 // the file will be opened with the file selected.
74 void OpenFileManagerWithInternalActionId(Profile* profile, 57 void OpenFileManagerWithInternalActionId(Profile* profile,
75 const GURL& url, 58 const GURL& url,
76 const std::string& action_id) { 59 const std::string& action_id) {
77 DCHECK(action_id == "open" || action_id == "select"); 60 DCHECK(action_id == "open" || action_id == "select");
61 if (!shell_operations_allowed)
62 return;
78 content::RecordAction(base::UserMetricsAction("ShowFileBrowserFullTab")); 63 content::RecordAction(base::UserMetricsAction("ShowFileBrowserFullTab"));
79 64
80 file_tasks::TaskDescriptor task(kFileManagerAppId, 65 file_tasks::TaskDescriptor task(kFileManagerAppId,
81 file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER, 66 file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER,
82 action_id); 67 action_id);
83 ExecuteFileTaskForUrl(profile, task, url); 68 ExecuteFileTaskForUrl(profile, task, url);
84 } 69 }
85 70
86 // Opens the file with fetched MIME type and calls the callback. 71 // Opens the file with fetched MIME type and calls the callback.
87 void OpenFileWithMimeType(Profile* profile, 72 void OpenFileWithMimeType(Profile* profile,
88 const base::FilePath& path, 73 const base::FilePath& path,
89 const GURL& url, 74 const GURL& url,
90 const base::Callback<void(bool)>& callback, 75 const platform_util::OpenOperationCallback& callback,
91 const std::string& mime_type) { 76 const std::string& mime_type) {
92 extensions::app_file_handler_util::PathAndMimeTypeSet path_mime_set; 77 extensions::app_file_handler_util::PathAndMimeTypeSet path_mime_set;
93 path_mime_set.insert(std::make_pair(path, mime_type)); 78 path_mime_set.insert(std::make_pair(path, mime_type));
94 79
95 std::vector<GURL> file_urls; 80 std::vector<GURL> file_urls;
96 file_urls.push_back(url); 81 file_urls.push_back(url);
97 82
98 std::vector<file_tasks::FullTaskDescriptor> tasks; 83 std::vector<file_tasks::FullTaskDescriptor> tasks;
99 file_tasks::FindAllTypesOfTasks( 84 file_tasks::FindAllTypesOfTasks(
100 profile, 85 profile,
101 drive::util::GetDriveAppRegistryByProfile(profile), 86 drive::util::GetDriveAppRegistryByProfile(profile),
102 path_mime_set, 87 path_mime_set,
103 file_urls, 88 file_urls,
104 &tasks); 89 &tasks);
105 90
106 // Select a default handler. If a default handler is not available, select 91 // Select a default handler. If a default handler is not available, select
107 // a non-generic file handler. 92 // a non-generic file handler.
108 const file_tasks::FullTaskDescriptor* chosen_task = nullptr; 93 const file_tasks::FullTaskDescriptor* chosen_task = nullptr;
109 for (const auto& task : tasks) { 94 for (const auto& task : tasks) {
110 if (!task.is_generic_file_handler()) { 95 if (!task.is_generic_file_handler()) {
111 chosen_task = &task; 96 chosen_task = &task;
112 if (task.is_default()) 97 if (task.is_default())
113 break; 98 break;
114 } 99 }
115 } 100 }
116 101
117 if (chosen_task != nullptr) { 102 if (chosen_task != nullptr) {
118 ExecuteFileTaskForUrl(profile, chosen_task->task_descriptor(), url); 103 if (shell_operations_allowed)
119 callback.Run(true); 104 ExecuteFileTaskForUrl(profile, chosen_task->task_descriptor(), url);
105 callback.Run(platform_util::OPEN_SUCCEEDED);
120 } else { 106 } else {
121 callback.Run(false); 107 callback.Run(platform_util::OPEN_FAILED_NO_HANLDER_FOR_FILE_TYPE);
122 } 108 }
123 } 109 }
124 110
125 // Opens the file specified by |url| by finding and executing a file task for 111 // Opens the file specified by |url| by finding and executing a file task for
126 // the file. In case of success, calls |callback| with true. Otherwise the 112 // the file. Calls |callback| with the result.
127 // returned value is false.
128 void OpenFile(Profile* profile, 113 void OpenFile(Profile* profile,
129 const base::FilePath& path, 114 const base::FilePath& path,
130 const GURL& url, 115 const GURL& url,
131 const base::Callback<void(bool)>& callback) { 116 const platform_util::OpenOperationCallback& callback) {
132 extensions::app_file_handler_util::GetMimeTypeForLocalPath( 117 extensions::app_file_handler_util::GetMimeTypeForLocalPath(
133 profile, 118 profile, path,
134 path,
135 base::Bind(&OpenFileWithMimeType, profile, path, url, callback)); 119 base::Bind(&OpenFileWithMimeType, profile, path, url, callback));
136 } 120 }
137 121
138 // Called when execution of ContinueOpenItem() is completed. 122 void OpenItemWithMetadata(Profile* profile,
139 void OnContinueOpenItemCompleted(Profile* profile, 123 const base::FilePath& file_path,
140 const base::FilePath& file_path, 124 const GURL& url,
141 bool result) { 125 platform_util::OpenItemType expected_type,
142 if (!result) { 126 const platform_util::OpenOperationCallback& callback,
143 int message; 127 base::File::Error error,
144 if (file_path.Extension() == FILE_PATH_LITERAL(".dmg")) 128 const base::File::Info& file_info) {
145 message = IDS_FILE_BROWSER_ERROR_VIEWING_FILE_FOR_DMG; 129 DCHECK_CURRENTLY_ON(BrowserThread::UI);
146 else if (file_path.Extension() == FILE_PATH_LITERAL(".exe") || 130 if (error != base::File::FILE_OK) {
147 file_path.Extension() == FILE_PATH_LITERAL(".msi")) 131 callback.Run(error == base::File::FILE_ERROR_NOT_FOUND
148 message = IDS_FILE_BROWSER_ERROR_VIEWING_FILE_FOR_EXECUTABLE; 132 ? platform_util::OPEN_FAILED_PATH_NOT_FOUND
149 else 133 : platform_util::OPEN_FAILED_FILE_ERROR);
150 message = IDS_FILE_BROWSER_ERROR_VIEWING_FILE; 134 return;
151 ShowWarningMessageBox(profile, file_path, message);
152 } 135 }
153 }
154 136
155 // Used to implement OpenItem(). 137 // Note that there exists a TOCTOU race between the time the metadata for
156 void ContinueOpenItem(Profile* profile, 138 // |file_path| was determined and when it is opened based on the metadata.
157 const base::FilePath& file_path, 139 if (expected_type == platform_util::OPEN_FOLDER && file_info.is_directory) {
158 const GURL& url, 140 OpenFileManagerWithInternalActionId(profile, url, "open");
159 base::File::Error error) { 141 callback.Run(platform_util::OPEN_SUCCEEDED);
160 DCHECK_CURRENTLY_ON(BrowserThread::UI); 142 return;
143 }
161 144
162 if (error == base::File::FILE_OK) { 145 if (expected_type == platform_util::OPEN_FILE && !file_info.is_directory) {
163 // A directory exists at |url|. Open it with the file manager. 146 OpenFile(profile, file_path, url, callback);
164 OpenFileManagerWithInternalActionId(profile, url, "open"); 147 return;
165 } else {
166 // |url| should be a file. Open it.
167 OpenFile(profile,
168 file_path,
169 url,
170 base::Bind(&OnContinueOpenItemCompleted, profile, file_path));
171 } 148 }
172 }
173 149
174 // Converts the |path| passed from external callers to the filesystem URL 150 callback.Run(platform_util::OPEN_FAILED_INVALID_TYPE);
175 // that the file manager can correctly handle.
176 //
177 // When conversion fails, it shows a warning dialog UI and returns false.
178 bool ConvertPath(Profile* profile, const base::FilePath& path, GURL* url) {
179 if (!ConvertAbsoluteFilePathToFileSystemUrl(
180 profile, path, kFileManagerAppId, url)) {
181 ShowWarningMessageBox(profile, path,
182 IDS_FILE_BROWSER_ERROR_UNRESOLVABLE_FILE);
183 return false;
184 }
185 return true;
186 } 151 }
187 152
188 } // namespace 153 } // namespace
189 154
190 void OpenItem(Profile* profile, const base::FilePath& file_path) { 155 void OpenItem(Profile* profile,
156 const base::FilePath& file_path,
157 platform_util::OpenItemType expected_type,
158 const platform_util::OpenOperationCallback& callback) {
191 DCHECK_CURRENTLY_ON(BrowserThread::UI); 159 DCHECK_CURRENTLY_ON(BrowserThread::UI);
192 160
193 GURL url; 161 GURL url;
194 if (!ConvertPath(profile, file_path, &url)) 162 if (!ConvertAbsoluteFilePathToFileSystemUrl(profile, file_path,
163 kFileManagerAppId, &url)) {
164 callback.Run(platform_util::OPEN_FAILED_PATH_NOT_FOUND);
195 return; 165 return;
166 }
196 167
197 CheckIfDirectoryExists( 168 GetMetadataForPath(
198 GetFileSystemContextForExtensionId(profile, kFileManagerAppId), 169 GetFileSystemContextForExtensionId(profile, kFileManagerAppId), url,
199 url, 170 base::Bind(&OpenItemWithMetadata, profile, file_path, url, expected_type,
200 base::Bind(&ContinueOpenItem, profile, file_path, url)); 171 callback));
201 } 172 }
202 173
203 void ShowItemInFolder(Profile* profile, const base::FilePath& file_path) { 174 void ShowItemInFolder(Profile* profile,
175 const base::FilePath& file_path,
176 const platform_util::OpenOperationCallback& callback) {
204 DCHECK_CURRENTLY_ON(BrowserThread::UI); 177 DCHECK_CURRENTLY_ON(BrowserThread::UI);
205 178
206 GURL url; 179 GURL url;
207 if (!ConvertPath(profile, file_path, &url)) 180 if (!ConvertAbsoluteFilePathToFileSystemUrl(profile, file_path,
181 kFileManagerAppId, &url)) {
182 callback.Run(platform_util::OPEN_FAILED_PATH_NOT_FOUND);
208 return; 183 return;
184 }
209 185
210 // This action changes the selection so we do not reuse existing tabs. 186 // This action changes the selection so we do not reuse existing tabs.
211 OpenFileManagerWithInternalActionId(profile, url, "select"); 187 OpenFileManagerWithInternalActionId(profile, url, "select");
188 callback.Run(platform_util::OPEN_SUCCEEDED);
189 }
190
191 void DisableShellOperationsForTesting() {
192 shell_operations_allowed = false;
212 } 193 }
213 194
214 } // namespace util 195 } // namespace util
215 } // namespace file_manager 196 } // namespace file_manager
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/file_manager/open_util.h ('k') | chrome/browser/download/chrome_download_manager_delegate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698