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

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: Rebased. 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 // Returns true if the task should be used as a fallback. Such tasks are
102 // Files.app's internal handlers as well as quick office extensions.
103 bool IsFallbackTask(const FileBrowserHandler* task) {
104 return (task->extension_id() == kFileBrowserDomain || 104 return (task->extension_id() == kFileBrowserDomain ||
105 task->extension_id() == 105 task->extension_id() ==
106 extension_misc::kQuickOfficeComponentExtensionId || 106 extension_misc::kQuickOfficeComponentExtensionId ||
107 task->extension_id() == extension_misc::kQuickOfficeDevExtensionId || 107 task->extension_id() == extension_misc::kQuickOfficeDevExtensionId ||
108 task->extension_id() == extension_misc::kQuickOfficeExtensionId); 108 task->extension_id() == extension_misc::kQuickOfficeExtensionId);
109 } 109 }
110 110
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, 111 const FileBrowserHandler* FindFileBrowserHandler(const Extension* extension,
124 const std::string& action_id) { 112 const std::string& action_id) {
125 FileBrowserHandler::List* handler_list = 113 FileBrowserHandler::List* handler_list =
126 FileBrowserHandler::GetHandlers(extension); 114 FileBrowserHandler::GetHandlers(extension);
127 for (FileBrowserHandler::List::const_iterator action_iter = 115 for (FileBrowserHandler::List::const_iterator action_iter =
128 handler_list->begin(); 116 handler_list->begin();
129 action_iter != handler_list->end(); 117 action_iter != handler_list->end();
130 ++action_iter) { 118 ++action_iter) {
131 if (action_iter->get()->id() == action_id) 119 if (action_iter->get()->id() == action_id)
132 return action_iter->get(); 120 return action_iter->get();
(...skipping 20 matching lines...) Expand all
153 std::string EscapedUtf8ToLower(const std::string& str) { 141 std::string EscapedUtf8ToLower(const std::string& str) {
154 string16 utf16 = UTF8ToUTF16( 142 string16 utf16 = UTF8ToUTF16(
155 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL)); 143 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL));
156 return net::EscapeUrlEncodedData( 144 return net::EscapeUrlEncodedData(
157 UTF16ToUTF8(base::i18n::ToLower(utf16)), 145 UTF16ToUTF8(base::i18n::ToLower(utf16)),
158 false /* do not replace space with plus */); 146 false /* do not replace space with plus */);
159 } 147 }
160 148
161 bool GetFileBrowserHandlers(Profile* profile, 149 bool GetFileBrowserHandlers(Profile* profile,
162 const GURL& selected_file_url, 150 const GURL& selected_file_url,
163 FileBrowserHandlerSet* results) { 151 FileBrowserHandlerList* results) {
164 ExtensionService* service = 152 ExtensionService* service =
165 extensions::ExtensionSystem::Get(profile)->extension_service(); 153 extensions::ExtensionSystem::Get(profile)->extension_service();
166 if (!service) 154 if (!service)
167 return false; // In unit-tests, we may not have an ExtensionService. 155 return false; // In unit-tests, we may not have an ExtensionService.
168 156
169 // We need case-insensitive matching, and pattern in the handler is already 157 // We need case-insensitive matching, and pattern in the handler is already
170 // in lower case. 158 // in lower case.
171 const GURL lowercase_url(EscapedUtf8ToLower(selected_file_url.spec())); 159 const GURL lowercase_url(EscapedUtf8ToLower(selected_file_url.spec()));
172 160
173 for (ExtensionSet::const_iterator iter = service->extensions()->begin(); 161 for (ExtensionSet::const_iterator iter = service->extensions()->begin();
174 iter != service->extensions()->end(); 162 iter != service->extensions()->end();
175 ++iter) { 163 ++iter) {
176 const Extension* extension = *iter; 164 const Extension* extension = *iter;
177 if (profile->IsOffTheRecord() && 165 if (profile->IsOffTheRecord() &&
178 !service->IsIncognitoEnabled(extension->id())) 166 !service->IsIncognitoEnabled(extension->id()))
179 continue; 167 continue;
180 168
181 FileBrowserHandler::List* handler_list = 169 FileBrowserHandler::List* handler_list =
182 FileBrowserHandler::GetHandlers(extension); 170 FileBrowserHandler::GetHandlers(extension);
183 if (!handler_list) 171 if (!handler_list)
184 continue; 172 continue;
185 for (FileBrowserHandler::List::const_iterator action_iter = 173 for (FileBrowserHandler::List::const_iterator action_iter =
186 handler_list->begin(); 174 handler_list->begin();
187 action_iter != handler_list->end(); 175 action_iter != handler_list->end();
188 ++action_iter) { 176 ++action_iter) {
189 const FileBrowserHandler* action = action_iter->get(); 177 const FileBrowserHandler* action = action_iter->get();
190 if (!action->MatchesURL(lowercase_url)) 178 if (!action->MatchesURL(lowercase_url))
191 continue; 179 continue;
192 180
193 results->insert(action_iter->get()); 181 results->push_back(action_iter->get());
194 } 182 }
195 } 183 }
196 return true; 184 return true;
197 } 185 }
198 186
199 } // namespace 187 } // namespace
200 188
201 void UpdateDefaultTask(Profile* profile, 189 void UpdateDefaultTask(Profile* profile,
202 const std::string& task_id, 190 const std::string& task_id,
203 const std::set<std::string>& suffixes, 191 const std::set<std::string>& suffixes,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 *task_type == kTaskApp); 311 *task_type == kTaskApp);
324 } 312 }
325 313
326 if (action_id) 314 if (action_id)
327 *action_id = result[2]; 315 *action_id = result[2];
328 316
329 return true; 317 return true;
330 } 318 }
331 319
332 // Find a specific handler in the handler list. 320 // Find a specific handler in the handler list.
333 FileBrowserHandlerSet::iterator FindHandler( 321 FileBrowserHandlerList::iterator FindHandler(
334 FileBrowserHandlerSet* handler_set, 322 FileBrowserHandlerList* handler_list,
335 const std::string& extension_id, 323 const std::string& extension_id,
336 const std::string& id) { 324 const std::string& id) {
337 FileBrowserHandlerSet::iterator iter = handler_set->begin(); 325 FileBrowserHandlerList::iterator iter = handler_list->begin();
338 while (iter != handler_set->end() && 326 while (iter != handler_list->end() &&
339 !((*iter)->extension_id() == extension_id && 327 !((*iter)->extension_id() == extension_id &&
340 (*iter)->id() == id)) { 328 (*iter)->id() == id)) {
341 iter++; 329 ++iter;
342 } 330 }
343 return iter; 331 return iter;
344 } 332 }
345 333
346 // Given the list of selected files, returns array of file action tasks 334 // Given the list of selected files, returns array of file action tasks
347 // that are shared between them. 335 // that are shared between them.
348 void FindDefaultTasks(Profile* profile, 336 void FindDefaultTasks(Profile* profile,
349 const std::vector<base::FilePath>& files_list, 337 const std::vector<base::FilePath>& files_list,
350 const FileBrowserHandlerSet& common_tasks, 338 const FileBrowserHandlerList& common_tasks,
351 FileBrowserHandlerSet* default_tasks) { 339 FileBrowserHandlerList* default_tasks) {
352 DCHECK(default_tasks); 340 DCHECK(default_tasks);
353 default_tasks->clear(); 341 default_tasks->clear();
354 342
355 std::set<std::string> default_ids; 343 std::set<std::string> default_ids;
356 for (std::vector<base::FilePath>::const_iterator it = files_list.begin(); 344 for (std::vector<base::FilePath>::const_iterator it = files_list.begin();
357 it != files_list.end(); ++it) { 345 it != files_list.end(); ++it) {
358 std::string task_id = file_handler_util::GetDefaultTaskIdFromPrefs( 346 std::string task_id = file_handler_util::GetDefaultTaskIdFromPrefs(
359 profile, "", it->Extension()); 347 profile, "", it->Extension());
360 if (!task_id.empty()) 348 if (!task_id.empty())
361 default_ids.insert(task_id); 349 default_ids.insert(task_id);
362 } 350 }
363 351
364 const FileBrowserHandler* builtin_task = NULL; 352 const FileBrowserHandler* fallback_task = NULL;
365 // Convert the default task IDs collected above to one of the handler pointers 353 // Convert the default task IDs collected above to one of the handler pointers
366 // from common_tasks. 354 // from common_tasks.
367 for (FileBrowserHandlerSet::const_iterator task_iter = common_tasks.begin(); 355 for (FileBrowserHandlerList::const_iterator task_iter = common_tasks.begin();
368 task_iter != common_tasks.end(); ++task_iter) { 356 task_iter != common_tasks.end(); ++task_iter) {
369 std::string task_id = MakeTaskID((*task_iter)->extension_id(), kTaskFile, 357 std::string task_id = MakeTaskID((*task_iter)->extension_id(), kTaskFile,
370 (*task_iter)->id()); 358 (*task_iter)->id());
371 std::set<std::string>::iterator default_iter = default_ids.find(task_id); 359 std::set<std::string>::iterator default_iter = default_ids.find(task_id);
372 if (default_iter != default_ids.end()) { 360 if (default_iter != default_ids.end()) {
373 default_tasks->insert(*task_iter); 361 default_tasks->push_back(*task_iter);
374 continue; 362 continue;
375 } 363 }
376 364
377 // If it's a built in task, remember it. If there are no default tasks among 365 // Remember the first fallback task.
378 // common tasks, builtin task will be used as a fallback. 366 if (!fallback_task && IsFallbackTask(*task_iter))
379 // Note that builtin tasks are not overlapping, so there can be at most one 367 fallback_task = *task_iter;
380 // builtin tasks for each set of files.
381 if (IsBuiltinTask(*task_iter))
382 builtin_task = *task_iter;
383 } 368 }
384 369
385 // If there are no default tasks found, use builtin task (if found) as a 370 // If there are no default tasks found, use fallback as default.
386 // default. 371 if (fallback_task && default_tasks->empty())
387 if (builtin_task && default_tasks->empty()) 372 default_tasks->push_back(fallback_task);
388 default_tasks->insert(builtin_task);
389 } 373 }
390 374
391 // Given the list of selected files, returns array of context menu tasks 375 // Given the list of selected files, returns array of context menu tasks
392 // that are shared 376 // that are shared
393 bool FindCommonTasks(Profile* profile, 377 bool FindCommonTasks(Profile* profile,
394 const std::vector<GURL>& files_list, 378 const std::vector<GURL>& files_list,
395 FileBrowserHandlerSet* common_tasks) { 379 FileBrowserHandlerList* common_tasks) {
396 DCHECK(common_tasks); 380 DCHECK(common_tasks);
397 common_tasks->clear(); 381 common_tasks->clear();
398 382
399 FileBrowserHandlerSet common_task_set; 383 FileBrowserHandlerList common_task_list;
400 std::set<std::string> default_task_ids; 384 std::set<std::string> default_task_ids;
401 for (std::vector<GURL>::const_iterator it = files_list.begin(); 385 for (std::vector<GURL>::const_iterator it = files_list.begin();
402 it != files_list.end(); ++it) { 386 it != files_list.end(); ++it) {
403 FileBrowserHandlerSet file_actions; 387 FileBrowserHandlerList file_actions;
404 if (!GetFileBrowserHandlers(profile, *it, &file_actions)) 388 if (!GetFileBrowserHandlers(profile, *it, &file_actions))
405 return false; 389 return false;
406 // If there is nothing to do for one file, the intersection of tasks for all 390 // 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. 391 // files will be empty at the end, and so will the default tasks.
408 if (file_actions.empty()) 392 if (file_actions.empty())
409 return true; 393 return true;
410 394
411 // For the very first file, just copy all the elements. 395 // For the very first file, just copy all the elements.
412 if (it == files_list.begin()) { 396 if (it == files_list.begin()) {
413 common_task_set = file_actions; 397 common_task_list = file_actions;
414 } else { 398 } else {
415 // For all additional files, find intersection between the accumulated and 399 // For all additional files, find intersection between the accumulated and
416 // file specific set. 400 // file specific set.
417 FileBrowserHandlerSet intersection; 401 FileBrowserHandlerList intersection;
418 std::set_intersection(common_task_set.begin(), common_task_set.end(), 402 std::set_intersection(common_task_list.begin(), common_task_list.end(),
419 file_actions.begin(), file_actions.end(), 403 file_actions.begin(), file_actions.end(),
420 std::inserter(intersection, 404 std::back_inserter(intersection));
421 intersection.begin())); 405 common_task_list = intersection;
422 common_task_set = intersection; 406 if (common_task_list.empty())
423 if (common_task_set.empty())
424 return true; 407 return true;
425 } 408 }
426 } 409 }
427 410
428 FileBrowserHandlerSet::iterator watch_iter = FindHandler( 411 FileBrowserHandlerList::iterator watch_iter = FindHandler(
429 &common_task_set, kFileBrowserDomain, kFileBrowserWatchTaskId); 412 &common_task_list, kFileBrowserDomain, kFileBrowserWatchTaskId);
430 FileBrowserHandlerSet::iterator gallery_iter = FindHandler( 413 FileBrowserHandlerList::iterator gallery_iter = FindHandler(
431 &common_task_set, kFileBrowserDomain, kFileBrowserGalleryTaskId); 414 &common_task_list, kFileBrowserDomain, kFileBrowserGalleryTaskId);
432 if (watch_iter != common_task_set.end() && 415 if (watch_iter != common_task_list.end() &&
433 gallery_iter != common_task_set.end()) { 416 gallery_iter != common_task_list.end()) {
434 // Both "watch" and "gallery" actions are applicable which means that the 417 // 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 418 // 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" 419 // the one that makes more sense ("watch" for single selection, "gallery"
437 // for multiple selection). 420 // for multiple selection).
438 if (files_list.size() == 1) 421 if (files_list.size() == 1)
439 common_task_set.erase(gallery_iter); 422 common_task_list.erase(gallery_iter);
440 else 423 else
441 common_task_set.erase(watch_iter); 424 common_task_list.erase(watch_iter);
442 } 425 }
443 426
444 common_tasks->swap(common_task_set); 427 common_tasks->swap(common_task_list);
445 return true; 428 return true;
446 } 429 }
447 430
448 bool GetTaskForURLAndPath(Profile* profile, 431 bool GetTaskForURLAndPath(Profile* profile,
449 const GURL& url, 432 const GURL& url,
450 const base::FilePath& file_path, 433 const base::FilePath& file_path,
451 const FileBrowserHandler** handler) { 434 const FileBrowserHandler** handler) {
452 std::vector<GURL> file_urls; 435 std::vector<GURL> file_urls;
453 file_urls.push_back(url); 436 file_urls.push_back(url);
454 437
455 FileBrowserHandlerSet default_tasks; 438 FileBrowserHandlerList default_tasks;
456 FileBrowserHandlerSet common_tasks; 439 FileBrowserHandlerList common_tasks;
457 if (!FindCommonTasks(profile, file_urls, &common_tasks)) 440 if (!FindCommonTasks(profile, file_urls, &common_tasks))
458 return false; 441 return false;
459 442
460 if (common_tasks.empty()) 443 if (common_tasks.empty())
461 return false; 444 return false;
462 445
463 std::vector<base::FilePath> file_paths; 446 std::vector<base::FilePath> file_paths;
464 file_paths.push_back(file_path); 447 file_paths.push_back(file_path);
465 448
466 FindDefaultTasks(profile, file_paths, common_tasks, &default_tasks); 449 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(), 971 extensions::LaunchPlatformAppWithFileHandler(profile(), GetExtension(),
989 action_id_, file_urls[i].path()); 972 action_id_, file_urls[i].path());
990 } 973 }
991 974
992 if (!done.is_null()) 975 if (!done.is_null())
993 done.Run(true); 976 done.Run(true);
994 return true; 977 return true;
995 } 978 }
996 979
997 } // namespace file_handler_util 980 } // namespace file_handler_util
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698