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

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: Chdir on Linux, Fix memory leak in test and address Mac comment. Created 5 years, 10 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/platform_util_internal.h"
18 #include "chrome/browser/ui/browser.h" 19 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_finder.h" 20 #include "chrome/browser/ui/browser_finder.h"
20 #include "chrome/browser/ui/browser_window.h" 21 #include "chrome/browser/ui/browser_window.h"
21 #include "chrome/browser/ui/simple_message_box.h" 22 #include "chrome/browser/ui/simple_message_box.h"
22 #include "chrome/grit/generated_resources.h" 23 #include "chrome/grit/generated_resources.h"
23 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/user_metrics.h" 25 #include "content/public/browser/user_metrics.h"
25 #include "storage/browser/fileapi/file_system_backend.h" 26 #include "storage/browser/fileapi/file_system_backend.h"
26 #include "storage/browser/fileapi/file_system_context.h" 27 #include "storage/browser/fileapi/file_system_context.h"
27 #include "storage/browser/fileapi/file_system_operation_runner.h" 28 #include "storage/browser/fileapi/file_system_operation_runner.h"
28 #include "storage/browser/fileapi/file_system_url.h" 29 #include "storage/browser/fileapi/file_system_url.h"
29 #include "ui/base/l10n/l10n_util.h" 30 #include "ui/base/l10n/l10n_util.h"
30 31
31 using content::BrowserThread; 32 using content::BrowserThread;
32 using storage::FileSystemURL; 33 using storage::FileSystemURL;
33 34
34 namespace file_manager { 35 namespace file_manager {
35 namespace util { 36 namespace util {
36 namespace { 37 namespace {
37 38
38 // Shows a warning message box saying that the file could not be opened. 39 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 40
53 // Executes the |task| for the file specified by |url|. 41 // Executes the |task| for the file specified by |url|.
54 void ExecuteFileTaskForUrl(Profile* profile, 42 void ExecuteFileTaskForUrl(Profile* profile,
55 const file_tasks::TaskDescriptor& task, 43 const file_tasks::TaskDescriptor& task,
56 const GURL& url) { 44 const GURL& url) {
45 if (!shell_operations_allowed)
46 return;
57 storage::FileSystemContext* file_system_context = 47 storage::FileSystemContext* file_system_context =
58 GetFileSystemContextForExtensionId(profile, kFileManagerAppId); 48 GetFileSystemContextForExtensionId(profile, kFileManagerAppId);
59 49
60 file_tasks::ExecuteFileTask( 50 file_tasks::ExecuteFileTask(
61 profile, 51 profile,
62 GetFileManagerMainPageUrl(), // Executing the task on behalf of Files.app. 52 GetFileManagerMainPageUrl(), // Executing the task on behalf of Files.app.
63 task, 53 task,
64 std::vector<FileSystemURL>(1, file_system_context->CrackURL(url)), 54 std::vector<FileSystemURL>(1, file_system_context->CrackURL(url)),
65 file_tasks::FileTaskFinishedCallback()); 55 file_tasks::FileTaskFinishedCallback());
66 } 56 }
67 57
68 // Opens the file manager for the specified |url|. Used to implement 58 // Opens the file manager for the specified |url|. Used to implement
69 // internal handlers of special action IDs: 59 // internal handlers of special action IDs:
70 // 60 //
71 // "open" - Open the file manager for the given folder. 61 // "open" - Open the file manager for the given folder.
72 // "select" - Open the file manager for the given file. The folder containing 62 // "select" - Open the file manager for the given file. The folder containing
73 // the file will be opened with the file selected. 63 // the file will be opened with the file selected.
74 void OpenFileManagerWithInternalActionId(Profile* profile, 64 void OpenFileManagerWithInternalActionId(Profile* profile,
75 const GURL& url, 65 const GURL& url,
76 const std::string& action_id) { 66 const std::string& action_id) {
77 DCHECK(action_id == "open" || action_id == "select"); 67 DCHECK(action_id == "open" || action_id == "select");
68 if (!shell_operations_allowed)
69 return;
78 content::RecordAction(base::UserMetricsAction("ShowFileBrowserFullTab")); 70 content::RecordAction(base::UserMetricsAction("ShowFileBrowserFullTab"));
79 71
80 file_tasks::TaskDescriptor task(kFileManagerAppId, 72 file_tasks::TaskDescriptor task(kFileManagerAppId,
81 file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER, 73 file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER,
82 action_id); 74 action_id);
83 ExecuteFileTaskForUrl(profile, task, url); 75 ExecuteFileTaskForUrl(profile, task, url);
84 } 76 }
85 77
86 // Opens the file with fetched MIME type and calls the callback. 78 // Opens the file with fetched MIME type and warns the user on failure.
87 void OpenFileWithMimeType(Profile* profile, 79 void OpenFileWithMimeType(Profile* profile,
80 const platform_util::OpenOperationCallback& callback,
88 const base::FilePath& path, 81 const base::FilePath& path,
89 const GURL& url, 82 const GURL& url,
90 const base::Callback<void(bool)>& callback,
91 const std::string& mime_type) { 83 const std::string& mime_type) {
92 extensions::app_file_handler_util::PathAndMimeTypeSet path_mime_set; 84 extensions::app_file_handler_util::PathAndMimeTypeSet path_mime_set;
93 path_mime_set.insert(std::make_pair(path, mime_type)); 85 path_mime_set.insert(std::make_pair(path, mime_type));
94 86
95 std::vector<GURL> file_urls; 87 std::vector<GURL> file_urls;
96 file_urls.push_back(url); 88 file_urls.push_back(url);
97 89
98 std::vector<file_tasks::FullTaskDescriptor> tasks; 90 std::vector<file_tasks::FullTaskDescriptor> tasks;
99 file_tasks::FindAllTypesOfTasks( 91 file_tasks::FindAllTypesOfTasks(
100 profile, 92 profile,
101 drive::util::GetDriveAppRegistryByProfile(profile), 93 drive::util::GetDriveAppRegistryByProfile(profile),
102 path_mime_set, 94 path_mime_set,
103 file_urls, 95 file_urls,
104 &tasks); 96 &tasks);
105 97
106 if (tasks.empty()) { 98 if (tasks.empty()) {
107 callback.Run(false); 99 callback.Run(platform_util::OPEN_FAILED_NO_HANLDER_FOR_FILE_TYPE);
108 return; 100 return;
109 } 101 }
110 102
111 const file_tasks::FullTaskDescriptor* chosen_task = &tasks[0]; 103 const file_tasks::FullTaskDescriptor* chosen_task = &tasks[0];
112 for (size_t i = 0; i < tasks.size(); ++i) { 104 for (const auto& task : tasks) {
113 if (tasks[i].is_default()) { 105 if (task.is_default()) {
114 chosen_task = &tasks[i]; 106 chosen_task = &task;
115 break; 107 break;
116 } 108 }
117 } 109 }
118 110
119 ExecuteFileTaskForUrl(profile, chosen_task->task_descriptor(), url); 111 if (shell_operations_allowed)
120 callback.Run(true); 112 ExecuteFileTaskForUrl(profile, chosen_task->task_descriptor(), url);
113 callback.Run(platform_util::OPEN_SUCCEEDED);
121 } 114 }
122 115
123 // Opens the file specified by |url| by finding and executing a file task for
124 // the file. In case of success, calls |callback| with true. Otherwise the
125 // returned value is false.
126 void OpenFile(Profile* profile,
127 const base::FilePath& path,
128 const GURL& url,
129 const base::Callback<void(bool)>& callback) {
130 extensions::app_file_handler_util::GetMimeTypeForLocalPath(
131 profile,
132 path,
133 base::Bind(&OpenFileWithMimeType, profile, path, url, callback));
134 }
135
136 // Called when execution of ContinueOpenItem() is completed.
137 void OnContinueOpenItemCompleted(Profile* profile,
138 const base::FilePath& file_path,
139 bool result) {
140 if (!result) {
141 int message;
142 if (file_path.Extension() == FILE_PATH_LITERAL(".dmg"))
143 message = IDS_FILE_BROWSER_ERROR_VIEWING_FILE_FOR_DMG;
144 else if (file_path.Extension() == FILE_PATH_LITERAL(".exe") ||
145 file_path.Extension() == FILE_PATH_LITERAL(".msi"))
146 message = IDS_FILE_BROWSER_ERROR_VIEWING_FILE_FOR_EXECUTABLE;
147 else
148 message = IDS_FILE_BROWSER_ERROR_VIEWING_FILE;
149 ShowWarningMessageBox(profile, file_path, message);
150 }
151 }
152
153 // Used to implement OpenItem().
154 void ContinueOpenItem(Profile* profile, 116 void ContinueOpenItem(Profile* profile,
155 const base::FilePath& file_path, 117 const base::FilePath& file_path,
156 const GURL& url, 118 const GURL& url,
157 base::File::Error error) { 119 platform_util::internal::OpenItemType expected_type,
120 const platform_util::OpenOperationCallback& callback,
121 base::File::Error error,
122 const base::File::Info& file_info) {
123 DCHECK_CURRENTLY_ON(BrowserThread::UI);
124 if (error != base::File::FILE_OK) {
125 callback.Run(error == base::File::FILE_ERROR_NOT_FOUND
126 ? platform_util::OPEN_FAILED_PATH_NOT_FOUND
127 : platform_util::OPEN_FAILED_FILE_ERROR);
128 return;
129 }
130
131 if (expected_type == platform_util::internal::OPEN_FOLDER &&
132 file_info.is_directory) {
133 OpenFileManagerWithInternalActionId(profile, url, "open");
134 callback.Run(platform_util::OPEN_SUCCEEDED);
135 return;
136 }
137
138 if (expected_type == platform_util::internal::OPEN_FILE &&
139 !file_info.is_directory) {
140 extensions::app_file_handler_util::GetMimeTypeForLocalPath(
141 profile, file_path,
142 base::Bind(&OpenFileWithMimeType, profile, callback, file_path, url));
143 return;
144 }
145
146 callback.Run(platform_util::OPEN_FAILED_INVALID_TYPE);
147 }
148
149 void VerifyAndOpenItem(Profile* profile,
150 const base::FilePath& file_path,
151 platform_util::internal::OpenItemType expected_type,
152 const platform_util::OpenOperationCallback& callback) {
158 DCHECK_CURRENTLY_ON(BrowserThread::UI); 153 DCHECK_CURRENTLY_ON(BrowserThread::UI);
159 154
160 if (error == base::File::FILE_OK) { 155 GURL url;
161 // A directory exists at |url|. Open it with the file manager. 156 if (!ConvertAbsoluteFilePathToFileSystemUrl(profile, file_path,
162 OpenFileManagerWithInternalActionId(profile, url, "open"); 157 kFileManagerAppId, &url)) {
163 } else { 158 callback.Run(platform_util::OPEN_FAILED_PATH_NOT_FOUND);
164 // |url| should be a file. Open it. 159 return;
165 OpenFile(profile,
166 file_path,
167 url,
168 base::Bind(&OnContinueOpenItemCompleted, profile, file_path));
169 } 160 }
170 }
171 161
172 // Converts the |path| passed from external callers to the filesystem URL 162 GetMetadataForPath(
173 // that the file manager can correctly handle. 163 GetFileSystemContextForExtensionId(profile, kFileManagerAppId), url,
174 // 164 base::Bind(&ContinueOpenItem, profile, file_path, url, expected_type,
175 // When conversion fails, it shows a warning dialog UI and returns false. 165 callback));
176 bool ConvertPath(Profile* profile, const base::FilePath& path, GURL* url) {
177 if (!ConvertAbsoluteFilePathToFileSystemUrl(
178 profile, path, kFileManagerAppId, url)) {
179 ShowWarningMessageBox(profile, path,
180 IDS_FILE_BROWSER_ERROR_UNRESOLVABLE_FILE);
181 return false;
182 }
183 return true;
184 } 166 }
185 167
186 } // namespace 168 } // namespace
187 169
188 void OpenItem(Profile* profile, const base::FilePath& file_path) { 170 void OpenFile(Profile* profile,
171 const base::FilePath& file_path,
172 const platform_util::OpenOperationCallback& callback) {
173 VerifyAndOpenItem(profile, file_path, platform_util::internal::OPEN_FILE,
174 callback);
175 }
176
177 void OpenFolder(Profile* profile,
178 const base::FilePath& file_path,
179 const platform_util::OpenOperationCallback& callback) {
180 VerifyAndOpenItem(profile, file_path, platform_util::internal::OPEN_FOLDER,
181 callback);
182 }
183
184 void ShowItemInFolder(Profile* profile,
185 const base::FilePath& file_path,
186 const platform_util::OpenOperationCallback& callback) {
189 DCHECK_CURRENTLY_ON(BrowserThread::UI); 187 DCHECK_CURRENTLY_ON(BrowserThread::UI);
190 188
191 GURL url; 189 GURL url;
192 if (!ConvertPath(profile, file_path, &url)) 190 if (!ConvertAbsoluteFilePathToFileSystemUrl(profile, file_path,
191 kFileManagerAppId, &url)) {
192 callback.Run(platform_util::OPEN_FAILED_PATH_NOT_FOUND);
193 return; 193 return;
194 194 }
195 CheckIfDirectoryExists(
196 GetFileSystemContextForExtensionId(profile, kFileManagerAppId),
197 url,
198 base::Bind(&ContinueOpenItem, profile, file_path, url));
199 }
200
201 void ShowItemInFolder(Profile* profile, const base::FilePath& file_path) {
202 DCHECK_CURRENTLY_ON(BrowserThread::UI);
203
204 GURL url;
205 if (!ConvertPath(profile, file_path, &url))
206 return;
207 195
208 // This action changes the selection so we do not reuse existing tabs. 196 // This action changes the selection so we do not reuse existing tabs.
209 OpenFileManagerWithInternalActionId(profile, url, "select"); 197 OpenFileManagerWithInternalActionId(profile, url, "select");
198 callback.Run(platform_util::OPEN_SUCCEEDED);
199 }
200
201 void DisableShellOperationsForTesting() {
202 shell_operations_allowed = false;
210 } 203 }
211 204
212 } // namespace util 205 } // namespace util
213 } // namespace file_manager 206 } // namespace file_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698