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

Side by Side Diff: chrome/browser/chromeos/extensions/file_manager/file_handler_util.cc

Issue 15975004: Replace sets with vectors when storing file handlers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Solved problems with the virtual handlers. Created 7 years, 7 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/extensions/file_manager/file_handler_util.h" 5 #include "chrome/browser/chromeos/extensions/file_manager/file_handler_util.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/i18n/case_conversion.h" 9 #include "base/i18n/case_conversion.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 const char kTaskDrive[] = "drive"; 58 const char kTaskDrive[] = "drive";
59 const char kTaskApp[] = "app"; 59 const char kTaskApp[] = "app";
60 60
61 namespace { 61 namespace {
62 62
63 // Legacy Drive task extension prefix, used by CrackTaskID. 63 // Legacy Drive task extension prefix, used by CrackTaskID.
64 const char kDriveTaskExtensionPrefix[] = "drive-app:"; 64 const char kDriveTaskExtensionPrefix[] = "drive-app:";
65 const size_t kDriveTaskExtensionPrefixLength = 65 const size_t kDriveTaskExtensionPrefixLength =
66 arraysize(kDriveTaskExtensionPrefix) - 1; 66 arraysize(kDriveTaskExtensionPrefix) - 1;
67 67
68 typedef std::set<const FileBrowserHandler*> FileBrowserHandlerSet;
69
70 const int kReadWriteFilePermissions = base::PLATFORM_FILE_OPEN | 68 const int kReadWriteFilePermissions = base::PLATFORM_FILE_OPEN |
71 base::PLATFORM_FILE_CREATE | 69 base::PLATFORM_FILE_CREATE |
72 base::PLATFORM_FILE_OPEN_ALWAYS | 70 base::PLATFORM_FILE_OPEN_ALWAYS |
73 base::PLATFORM_FILE_CREATE_ALWAYS | 71 base::PLATFORM_FILE_CREATE_ALWAYS |
74 base::PLATFORM_FILE_OPEN_TRUNCATED | 72 base::PLATFORM_FILE_OPEN_TRUNCATED |
75 base::PLATFORM_FILE_READ | 73 base::PLATFORM_FILE_READ |
76 base::PLATFORM_FILE_WRITE | 74 base::PLATFORM_FILE_WRITE |
77 base::PLATFORM_FILE_EXCLUSIVE_READ | 75 base::PLATFORM_FILE_EXCLUSIVE_READ |
78 base::PLATFORM_FILE_EXCLUSIVE_WRITE | 76 base::PLATFORM_FILE_EXCLUSIVE_WRITE |
79 base::PLATFORM_FILE_ASYNC | 77 base::PLATFORM_FILE_ASYNC |
(...skipping 13 matching lines...) Expand all
93 extensions::ExtensionSystem::Get(profile)->process_manager(); 91 extensions::ExtensionSystem::Get(profile)->process_manager();
94 92
95 SiteInstance* site_instance = manager->GetSiteInstanceForURL(extension_url); 93 SiteInstance* site_instance = manager->GetSiteInstanceForURL(extension_url);
96 if (!site_instance || !site_instance->HasProcess()) 94 if (!site_instance || !site_instance->HasProcess())
97 return -1; 95 return -1;
98 content::RenderProcessHost* process = site_instance->GetProcess(); 96 content::RenderProcessHost* process = site_instance->GetProcess();
99 97
100 return process->GetID(); 98 return process->GetID();
101 } 99 }
102 100
103 bool IsBuiltinTask(const FileBrowserHandler* task) { 101 bool IsFallbackTask(const FileBrowserHandler* task) {
hashimoto 2013/05/24 11:15:51 Please add a function comment. It's not clear from
mtomasz 2013/05/27 01:20:20 I didn't change anything in this class but set ->
104 return (task->extension_id() == kFileBrowserDomain || 102 return (task->extension_id() == kFileBrowserDomain ||
105 task->extension_id() == 103 task->extension_id() ==
106 extension_misc::kQuickOfficeComponentExtensionId || 104 extension_misc::kQuickOfficeComponentExtensionId ||
107 task->extension_id() == extension_misc::kQuickOfficeDevExtensionId || 105 task->extension_id() == extension_misc::kQuickOfficeDevExtensionId ||
108 task->extension_id() == extension_misc::kQuickOfficeExtensionId); 106 task->extension_id() == extension_misc::kQuickOfficeExtensionId);
109 } 107 }
110 108
111 bool MatchesAllURLs(const FileBrowserHandler* handler) {
112 const std::set<URLPattern>& patterns =
113 handler->file_url_patterns().patterns();
114 for (std::set<URLPattern>::const_iterator it = patterns.begin();
115 it != patterns.end();
116 ++it) {
117 if (it->match_all_urls())
118 return true;
119 }
120 return false;
121 }
122
123 const FileBrowserHandler* FindFileBrowserHandler(const Extension* extension, 109 const FileBrowserHandler* FindFileBrowserHandler(const Extension* extension,
124 const std::string& action_id) { 110 const std::string& action_id) {
125 FileBrowserHandler::List* handler_list = 111 FileBrowserHandler::List* handler_list =
126 FileBrowserHandler::GetHandlers(extension); 112 FileBrowserHandler::GetHandlers(extension);
127 for (FileBrowserHandler::List::const_iterator action_iter = 113 for (FileBrowserHandler::List::const_iterator action_iter =
128 handler_list->begin(); 114 handler_list->begin();
129 action_iter != handler_list->end(); 115 action_iter != handler_list->end();
130 ++action_iter) { 116 ++action_iter) {
131 if (action_iter->get()->id() == action_id) 117 if (action_iter->get()->id() == action_id)
132 return action_iter->get(); 118 return action_iter->get();
(...skipping 20 matching lines...) Expand all
153 std::string EscapedUtf8ToLower(const std::string& str) { 139 std::string EscapedUtf8ToLower(const std::string& str) {
154 string16 utf16 = UTF8ToUTF16( 140 string16 utf16 = UTF8ToUTF16(
155 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL)); 141 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL));
156 return net::EscapeUrlEncodedData( 142 return net::EscapeUrlEncodedData(
157 UTF16ToUTF8(base::i18n::ToLower(utf16)), 143 UTF16ToUTF8(base::i18n::ToLower(utf16)),
158 false /* do not replace space with plus */); 144 false /* do not replace space with plus */);
159 } 145 }
160 146
161 bool GetFileBrowserHandlers(Profile* profile, 147 bool GetFileBrowserHandlers(Profile* profile,
162 const GURL& selected_file_url, 148 const GURL& selected_file_url,
163 FileBrowserHandlerSet* results) { 149 FileBrowserHandlerList* results) {
164 ExtensionService* service = 150 ExtensionService* service =
165 extensions::ExtensionSystem::Get(profile)->extension_service(); 151 extensions::ExtensionSystem::Get(profile)->extension_service();
166 if (!service) 152 if (!service)
167 return false; // In unit-tests, we may not have an ExtensionService. 153 return false; // In unit-tests, we may not have an ExtensionService.
168 154
169 // We need case-insensitive matching, and pattern in the handler is already 155 // We need case-insensitive matching, and pattern in the handler is already
170 // in lower case. 156 // in lower case.
171 const GURL lowercase_url(EscapedUtf8ToLower(selected_file_url.spec())); 157 const GURL lowercase_url(EscapedUtf8ToLower(selected_file_url.spec()));
172 158
173 for (ExtensionSet::const_iterator iter = service->extensions()->begin(); 159 for (ExtensionSet::const_iterator iter = service->extensions()->begin();
174 iter != service->extensions()->end(); 160 iter != service->extensions()->end();
175 ++iter) { 161 ++iter) {
176 const Extension* extension = *iter; 162 const Extension* extension = *iter;
177 if (profile->IsOffTheRecord() && 163 if (profile->IsOffTheRecord() &&
178 !service->IsIncognitoEnabled(extension->id())) 164 !service->IsIncognitoEnabled(extension->id()))
179 continue; 165 continue;
180 166
181 FileBrowserHandler::List* handler_list = 167 FileBrowserHandler::List* handler_list =
182 FileBrowserHandler::GetHandlers(extension); 168 FileBrowserHandler::GetHandlers(extension);
183 if (!handler_list) 169 if (!handler_list)
184 continue; 170 continue;
185 for (FileBrowserHandler::List::const_iterator action_iter = 171 for (FileBrowserHandler::List::const_iterator action_iter =
186 handler_list->begin(); 172 handler_list->begin();
187 action_iter != handler_list->end(); 173 action_iter != handler_list->end();
188 ++action_iter) { 174 ++action_iter) {
189 const FileBrowserHandler* action = action_iter->get(); 175 const FileBrowserHandler* action = action_iter->get();
190 if (!action->MatchesURL(lowercase_url)) 176 if (!action->MatchesURL(lowercase_url))
191 continue; 177 continue;
192 178
193 results->insert(action_iter->get()); 179 results->push_back(action_iter->get());
194 } 180 }
195 } 181 }
196 return true; 182 return true;
197 } 183 }
198 184
199 } // namespace 185 } // namespace
200 186
201 void UpdateDefaultTask(Profile* profile, 187 void UpdateDefaultTask(Profile* profile,
202 const std::string& task_id, 188 const std::string& task_id,
203 const std::set<std::string>& suffixes, 189 const std::set<std::string>& suffixes,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 *task_type == kTaskApp); 309 *task_type == kTaskApp);
324 } 310 }
325 311
326 if (action_id) 312 if (action_id)
327 *action_id = result[2]; 313 *action_id = result[2];
328 314
329 return true; 315 return true;
330 } 316 }
331 317
332 // Find a specific handler in the handler list. 318 // Find a specific handler in the handler list.
333 FileBrowserHandlerSet::iterator FindHandler( 319 FileBrowserHandlerList::iterator FindHandler(
334 FileBrowserHandlerSet* handler_set, 320 FileBrowserHandlerList* handler_list,
335 const std::string& extension_id, 321 const std::string& extension_id,
336 const std::string& id) { 322 const std::string& id) {
337 FileBrowserHandlerSet::iterator iter = handler_set->begin(); 323 FileBrowserHandlerList::iterator iter = handler_list->begin();
338 while (iter != handler_set->end() && 324 while (iter != handler_list->end() &&
339 !((*iter)->extension_id() == extension_id && 325 !((*iter)->extension_id() == extension_id &&
340 (*iter)->id() == id)) { 326 (*iter)->id() == id)) {
341 iter++; 327 iter++;
342 } 328 }
343 return iter; 329 return iter;
344 } 330 }
345 331
346 // Given the list of selected files, returns array of file action tasks 332 // Given the list of selected files, returns array of file action tasks
347 // that are shared between them. 333 // that are shared between them.
348 void FindDefaultTasks(Profile* profile, 334 void FindDefaultTasks(Profile* profile,
349 const std::vector<base::FilePath>& files_list, 335 const std::vector<base::FilePath>& files_list,
350 const FileBrowserHandlerSet& common_tasks, 336 const FileBrowserHandlerList& common_tasks,
351 FileBrowserHandlerSet* default_tasks) { 337 FileBrowserHandlerList* default_tasks) {
352 DCHECK(default_tasks); 338 DCHECK(default_tasks);
353 default_tasks->clear(); 339 default_tasks->clear();
354 340
355 std::set<std::string> default_ids; 341 std::set<std::string> default_ids;
356 for (std::vector<base::FilePath>::const_iterator it = files_list.begin(); 342 for (std::vector<base::FilePath>::const_iterator it = files_list.begin();
357 it != files_list.end(); ++it) { 343 it != files_list.end(); ++it) {
358 std::string task_id = file_handler_util::GetDefaultTaskIdFromPrefs( 344 std::string task_id = file_handler_util::GetDefaultTaskIdFromPrefs(
359 profile, "", it->Extension()); 345 profile, "", it->Extension());
360 if (!task_id.empty()) 346 if (!task_id.empty())
361 default_ids.insert(task_id); 347 default_ids.insert(task_id);
362 } 348 }
363 349
364 const FileBrowserHandler* builtin_task = NULL; 350 const FileBrowserHandler* fallback_task = NULL;
365 // Convert the default task IDs collected above to one of the handler pointers 351 // Convert the default task IDs collected above to one of the handler pointers
366 // from common_tasks. 352 // from common_tasks.
367 for (FileBrowserHandlerSet::const_iterator task_iter = common_tasks.begin(); 353 for (FileBrowserHandlerList::const_iterator task_iter = common_tasks.begin();
368 task_iter != common_tasks.end(); ++task_iter) { 354 task_iter != common_tasks.end(); ++task_iter) {
369 std::string task_id = MakeTaskID((*task_iter)->extension_id(), kTaskFile, 355 std::string task_id = MakeTaskID((*task_iter)->extension_id(), kTaskFile,
370 (*task_iter)->id()); 356 (*task_iter)->id());
371 std::set<std::string>::iterator default_iter = default_ids.find(task_id); 357 std::set<std::string>::iterator default_iter = default_ids.find(task_id);
372 if (default_iter != default_ids.end()) { 358 if (default_iter != default_ids.end()) {
373 default_tasks->insert(*task_iter); 359 default_tasks->push_back(*task_iter);
374 continue; 360 continue;
375 } 361 }
376 362
377 // If it's a built in task, remember it. If there are no default tasks among 363 // Remember the first fallback task.
378 // common tasks, builtin task will be used as a fallback. 364 if (!fallback_task && IsFallbackTask(*task_iter))
379 // Note that builtin tasks are not overlapping, so there can be at most one 365 fallback_task = *task_iter;
380 // builtin tasks for each set of files.
381 if (IsBuiltinTask(*task_iter))
382 builtin_task = *task_iter;
383 } 366 }
384 367
385 // If there are no default tasks found, use builtin task (if found) as a 368 // If there are no default tasks found, use fallback as default.
386 // default. 369 if (fallback_task && default_tasks->empty())
387 if (builtin_task && default_tasks->empty()) 370 default_tasks->push_back(fallback_task);
388 default_tasks->insert(builtin_task);
389 } 371 }
390 372
391 // Given the list of selected files, returns array of context menu tasks 373 // Given the list of selected files, returns array of context menu tasks
392 // that are shared 374 // that are shared
393 bool FindCommonTasks(Profile* profile, 375 bool FindCommonTasks(Profile* profile,
394 const std::vector<GURL>& files_list, 376 const std::vector<GURL>& files_list,
395 FileBrowserHandlerSet* common_tasks) { 377 FileBrowserHandlerList* common_tasks) {
396 DCHECK(common_tasks); 378 DCHECK(common_tasks);
397 common_tasks->clear(); 379 common_tasks->clear();
398 380
399 FileBrowserHandlerSet common_task_set; 381 FileBrowserHandlerList common_task_list;
400 std::set<std::string> default_task_ids; 382 std::set<std::string> default_task_ids;
401 for (std::vector<GURL>::const_iterator it = files_list.begin(); 383 for (std::vector<GURL>::const_iterator it = files_list.begin();
402 it != files_list.end(); ++it) { 384 it != files_list.end(); ++it) {
403 FileBrowserHandlerSet file_actions; 385 FileBrowserHandlerList file_actions;
404 if (!GetFileBrowserHandlers(profile, *it, &file_actions)) 386 if (!GetFileBrowserHandlers(profile, *it, &file_actions))
405 return false; 387 return false;
406 // If there is nothing to do for one file, the intersection of tasks for all 388 // If there is nothing to do for one file, the intersection of tasks for all
407 // files will be empty at the end, and so will the default tasks. 389 // files will be empty at the end, and so will the default tasks.
408 if (file_actions.empty()) 390 if (file_actions.empty())
409 return true; 391 return true;
410 392
411 // For the very first file, just copy all the elements. 393 // For the very first file, just copy all the elements.
412 if (it == files_list.begin()) { 394 if (it == files_list.begin()) {
413 common_task_set = file_actions; 395 common_task_list = file_actions;
414 } else { 396 } else {
415 // For all additional files, find intersection between the accumulated and 397 // For all additional files, find intersection between the accumulated and
416 // file specific set. 398 // file specific set.
417 FileBrowserHandlerSet intersection; 399 FileBrowserHandlerList intersection;
418 std::set_intersection(common_task_set.begin(), common_task_set.end(), 400 std::set_intersection(common_task_list.begin(), common_task_list.end(),
419 file_actions.begin(), file_actions.end(), 401 file_actions.begin(), file_actions.end(),
420 std::inserter(intersection, 402 std::back_inserter(intersection));
421 intersection.begin())); 403 common_task_list = intersection;
422 common_task_set = intersection; 404 if (common_task_list.empty())
423 if (common_task_set.empty())
424 return true; 405 return true;
425 } 406 }
426 } 407 }
427 408
428 FileBrowserHandlerSet::iterator watch_iter = FindHandler( 409 FileBrowserHandlerList::iterator watch_iter = FindHandler(
429 &common_task_set, kFileBrowserDomain, kFileBrowserWatchTaskId); 410 &common_task_list, kFileBrowserDomain, kFileBrowserWatchTaskId);
430 FileBrowserHandlerSet::iterator gallery_iter = FindHandler( 411 FileBrowserHandlerList::iterator gallery_iter = FindHandler(
431 &common_task_set, kFileBrowserDomain, kFileBrowserGalleryTaskId); 412 &common_task_list, kFileBrowserDomain, kFileBrowserGalleryTaskId);
432 if (watch_iter != common_task_set.end() && 413 if (watch_iter != common_task_list.end() &&
433 gallery_iter != common_task_set.end()) { 414 gallery_iter != common_task_list.end()) {
434 // Both "watch" and "gallery" actions are applicable which means that the 415 // Both "watch" and "gallery" actions are applicable which means that the
435 // selection is all videos. Showing them both is confusing, so we only keep 416 // selection is all videos. Showing them both is confusing, so we only keep
436 // the one that makes more sense ("watch" for single selection, "gallery" 417 // the one that makes more sense ("watch" for single selection, "gallery"
437 // for multiple selection). 418 // for multiple selection).
438 if (files_list.size() == 1) 419 if (files_list.size() == 1)
439 common_task_set.erase(gallery_iter); 420 common_task_list.erase(gallery_iter);
440 else 421 else
441 common_task_set.erase(watch_iter); 422 common_task_list.erase(watch_iter);
442 } 423 }
443 424
444 common_tasks->swap(common_task_set); 425 common_tasks->swap(common_task_list);
445 return true; 426 return true;
446 } 427 }
447 428
448 bool GetTaskForURLAndPath(Profile* profile, 429 bool GetTaskForURLAndPath(Profile* profile,
449 const GURL& url, 430 const GURL& url,
450 const base::FilePath& file_path, 431 const base::FilePath& file_path,
451 const FileBrowserHandler** handler) { 432 const FileBrowserHandler** handler) {
452 std::vector<GURL> file_urls; 433 std::vector<GURL> file_urls;
453 file_urls.push_back(url); 434 file_urls.push_back(url);
454 435
455 FileBrowserHandlerSet default_tasks; 436 FileBrowserHandlerList default_tasks;
456 FileBrowserHandlerSet common_tasks; 437 FileBrowserHandlerList common_tasks;
457 if (!FindCommonTasks(profile, file_urls, &common_tasks)) 438 if (!FindCommonTasks(profile, file_urls, &common_tasks))
458 return false; 439 return false;
459 440
460 if (common_tasks.empty()) 441 if (common_tasks.empty())
461 return false; 442 return false;
462 443
463 std::vector<base::FilePath> file_paths; 444 std::vector<base::FilePath> file_paths;
464 file_paths.push_back(file_path); 445 file_paths.push_back(file_path);
465 446
466 FindDefaultTasks(profile, file_paths, common_tasks, &default_tasks); 447 FindDefaultTasks(profile, file_paths, common_tasks, &default_tasks);
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 extensions::LaunchPlatformAppWithFileHandler(profile(), GetExtension(), 969 extensions::LaunchPlatformAppWithFileHandler(profile(), GetExtension(),
989 action_id_, file_urls[i].path()); 970 action_id_, file_urls[i].path());
990 } 971 }
991 972
992 if (!done.is_null()) 973 if (!done.is_null())
993 done.Run(true); 974 done.Run(true);
994 return true; 975 return true;
995 } 976 }
996 977
997 } // namespace file_handler_util 978 } // namespace file_handler_util
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698