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

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: Addressed comments. 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 std::string EscapedUtf8ToLower(const std::string& str) { 151 std::string EscapedUtf8ToLower(const std::string& str) {
154 string16 utf16 = UTF8ToUTF16( 152 string16 utf16 = UTF8ToUTF16(
155 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL)); 153 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL));
156 return net::EscapeUrlEncodedData( 154 return net::EscapeUrlEncodedData(
157 UTF16ToUTF8(base::i18n::ToLower(utf16)), 155 UTF16ToUTF8(base::i18n::ToLower(utf16)),
158 false /* do not replace space with plus */); 156 false /* do not replace space with plus */);
159 } 157 }
160 158
161 bool GetFileBrowserHandlers(Profile* profile, 159 bool GetFileBrowserHandlers(Profile* profile,
162 const GURL& selected_file_url, 160 const GURL& selected_file_url,
163 FileBrowserHandlerSet* results) { 161 FileBrowserHandlerList* results) {
164 ExtensionService* service = 162 ExtensionService* service =
165 extensions::ExtensionSystem::Get(profile)->extension_service(); 163 extensions::ExtensionSystem::Get(profile)->extension_service();
166 if (!service) 164 if (!service)
167 return false; // In unit-tests, we may not have an ExtensionService. 165 return false; // In unit-tests, we may not have an ExtensionService.
168 166
169 // We need case-insensitive matching, and pattern in the handler is already 167 // We need case-insensitive matching, and pattern in the handler is already
170 // in lower case. 168 // in lower case.
171 const GURL lowercase_url(EscapedUtf8ToLower(selected_file_url.spec())); 169 const GURL lowercase_url(EscapedUtf8ToLower(selected_file_url.spec()));
172 170
173 for (ExtensionSet::const_iterator iter = service->extensions()->begin(); 171 for (ExtensionSet::const_iterator iter = service->extensions()->begin();
174 iter != service->extensions()->end(); 172 iter != service->extensions()->end();
175 ++iter) { 173 ++iter) {
176 const Extension* extension = *iter; 174 const Extension* extension = *iter;
177 if (profile->IsOffTheRecord() && 175 if (profile->IsOffTheRecord() &&
178 !service->IsIncognitoEnabled(extension->id())) 176 !service->IsIncognitoEnabled(extension->id()))
179 continue; 177 continue;
180 178
181 FileBrowserHandler::List* handler_list = 179 FileBrowserHandler::List* handler_list =
182 FileBrowserHandler::GetHandlers(extension); 180 FileBrowserHandler::GetHandlers(extension);
183 if (!handler_list) 181 if (!handler_list)
184 continue; 182 continue;
185 for (FileBrowserHandler::List::const_iterator action_iter = 183 for (FileBrowserHandler::List::const_iterator action_iter =
186 handler_list->begin(); 184 handler_list->begin();
187 action_iter != handler_list->end(); 185 action_iter != handler_list->end();
188 ++action_iter) { 186 ++action_iter) {
189 const FileBrowserHandler* action = action_iter->get(); 187 const FileBrowserHandler* action = action_iter->get();
190 if (!action->MatchesURL(lowercase_url)) 188 if (!action->MatchesURL(lowercase_url))
191 continue; 189 continue;
192 190
193 results->insert(action_iter->get()); 191 results->push_back(action_iter->get());
194 } 192 }
195 } 193 }
196 return true; 194 return true;
197 } 195 }
198 196
199 } // namespace 197 } // namespace
200 198
201 void UpdateDefaultTask(Profile* profile, 199 void UpdateDefaultTask(Profile* profile,
202 const std::string& task_id, 200 const std::string& task_id,
203 const std::set<std::string>& suffixes, 201 const std::set<std::string>& suffixes,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 *task_type == kTaskApp); 321 *task_type == kTaskApp);
324 } 322 }
325 323
326 if (action_id) 324 if (action_id)
327 *action_id = result[2]; 325 *action_id = result[2];
328 326
329 return true; 327 return true;
330 } 328 }
331 329
332 // Find a specific handler in the handler list. 330 // Find a specific handler in the handler list.
333 FileBrowserHandlerSet::iterator FindHandler( 331 FileBrowserHandlerList::iterator FindHandler(
334 FileBrowserHandlerSet* handler_set, 332 FileBrowserHandlerList* handler_list,
hashimoto 2013/05/24 08:38:57 nit: Could you add const while you are here?
mtomasz 2013/05/24 10:37:59 If I do that, then I have to return a const_iterat
hashimoto 2013/05/24 11:15:51 Oops, I was too careless to forget to look at how
335 const std::string& extension_id, 333 const std::string& extension_id,
336 const std::string& id) { 334 const std::string& id) {
337 FileBrowserHandlerSet::iterator iter = handler_set->begin(); 335 FileBrowserHandlerList::iterator iter = handler_list->begin();
338 while (iter != handler_set->end() && 336 while (iter != handler_list->end() &&
339 !((*iter)->extension_id() == extension_id && 337 !((*iter)->extension_id() == extension_id &&
340 (*iter)->id() == id)) { 338 (*iter)->id() == id)) {
341 iter++; 339 iter++;
hashimoto 2013/05/24 08:38:57 nit: Could you fix this to ++iter while you are he
mtomasz 2013/05/24 10:37:59 If I do that then it makes lots of stuff complicat
hashimoto 2013/05/24 11:15:51 I just wanted you to use preincrement (++iter) ins
mtomasz 2013/05/27 01:20:20 Done.
342 } 340 }
343 return iter; 341 return iter;
344 } 342 }
345 343
346 // Given the list of selected files, returns array of file action tasks 344 // Given the list of selected files, returns array of file action tasks
347 // that are shared between them. 345 // that are shared between them.
348 void FindDefaultTasks(Profile* profile, 346 void FindDefaultTasks(Profile* profile,
349 const std::vector<base::FilePath>& files_list, 347 const std::vector<base::FilePath>& files_list,
350 const FileBrowserHandlerSet& common_tasks, 348 const FileBrowserHandlerList& common_tasks,
351 FileBrowserHandlerSet* default_tasks) { 349 FileBrowserHandlerList* default_tasks) {
352 DCHECK(default_tasks); 350 DCHECK(default_tasks);
353 default_tasks->clear(); 351 default_tasks->clear();
354 352
355 std::set<std::string> default_ids; 353 std::set<std::string> default_ids;
356 for (std::vector<base::FilePath>::const_iterator it = files_list.begin(); 354 for (std::vector<base::FilePath>::const_iterator it = files_list.begin();
357 it != files_list.end(); ++it) { 355 it != files_list.end(); ++it) {
358 std::string task_id = file_handler_util::GetDefaultTaskIdFromPrefs( 356 std::string task_id = file_handler_util::GetDefaultTaskIdFromPrefs(
359 profile, "", it->Extension()); 357 profile, "", it->Extension());
360 if (!task_id.empty()) 358 if (!task_id.empty())
361 default_ids.insert(task_id); 359 default_ids.insert(task_id);
362 } 360 }
363 361
364 const FileBrowserHandler* builtin_task = NULL; 362 const FileBrowserHandler* builtin_task = NULL;
365 // Convert the default task IDs collected above to one of the handler pointers 363 // Convert the default task IDs collected above to one of the handler pointers
366 // from common_tasks. 364 // from common_tasks.
367 for (FileBrowserHandlerSet::const_iterator task_iter = common_tasks.begin(); 365 for (FileBrowserHandlerList::const_iterator task_iter = common_tasks.begin();
hashimoto 2013/05/24 08:38:57 nit: Use size_t to iterate over a vector.
mtomasz 2013/05/24 10:37:59 Why is it better? We work extensively on iterators
hashimoto 2013/05/24 11:15:51 Fair enough.
368 task_iter != common_tasks.end(); ++task_iter) { 366 task_iter != common_tasks.end(); ++task_iter) {
369 std::string task_id = MakeTaskID((*task_iter)->extension_id(), kTaskFile, 367 std::string task_id = MakeTaskID((*task_iter)->extension_id(), kTaskFile,
370 (*task_iter)->id()); 368 (*task_iter)->id());
371 std::set<std::string>::iterator default_iter = default_ids.find(task_id); 369 std::set<std::string>::iterator default_iter = default_ids.find(task_id);
372 if (default_iter != default_ids.end()) { 370 if (default_iter != default_ids.end()) {
373 default_tasks->insert(*task_iter); 371 default_tasks->push_back(*task_iter);
374 continue; 372 continue;
375 } 373 }
376 374
377 // If it's a built in task, remember it. If there are no default tasks among 375 // If it's a built in task, remember it. If there are no default tasks among
378 // common tasks, builtin task will be used as a fallback. 376 // common tasks, builtin task will be used as a fallback.
379 // Note that builtin tasks are not overlapping, so there can be at most one 377 // Note that builtin tasks are not overlapping, so there can be at most one
380 // builtin tasks for each set of files. 378 // builtin tasks for each set of files.
381 if (IsBuiltinTask(*task_iter)) 379 if (IsBuiltinTask(*task_iter))
382 builtin_task = *task_iter; 380 builtin_task = *task_iter;
383 } 381 }
384 382
385 // If there are no default tasks found, use builtin task (if found) as a 383 // If there are no default tasks found, use builtin task (if found) as a
386 // default. 384 // default.
387 if (builtin_task && default_tasks->empty()) 385 if (builtin_task && default_tasks->empty())
388 default_tasks->insert(builtin_task); 386 default_tasks->push_back(builtin_task);
389 } 387 }
390 388
391 // Given the list of selected files, returns array of context menu tasks 389 // Given the list of selected files, returns array of context menu tasks
392 // that are shared 390 // that are shared
393 bool FindCommonTasks(Profile* profile, 391 bool FindCommonTasks(Profile* profile,
394 const std::vector<GURL>& files_list, 392 const std::vector<GURL>& files_list,
395 FileBrowserHandlerSet* common_tasks) { 393 FileBrowserHandlerList* common_tasks) {
396 DCHECK(common_tasks); 394 DCHECK(common_tasks);
397 common_tasks->clear(); 395 common_tasks->clear();
398 396
399 FileBrowserHandlerSet common_task_set; 397 FileBrowserHandlerList common_task_list;
400 std::set<std::string> default_task_ids; 398 std::set<std::string> default_task_ids;
401 for (std::vector<GURL>::const_iterator it = files_list.begin(); 399 for (std::vector<GURL>::const_iterator it = files_list.begin();
402 it != files_list.end(); ++it) { 400 it != files_list.end(); ++it) {
403 FileBrowserHandlerSet file_actions; 401 FileBrowserHandlerList file_actions;
404 if (!GetFileBrowserHandlers(profile, *it, &file_actions)) 402 if (!GetFileBrowserHandlers(profile, *it, &file_actions))
405 return false; 403 return false;
406 // If there is nothing to do for one file, the intersection of tasks for all 404 // 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. 405 // files will be empty at the end, and so will the default tasks.
408 if (file_actions.empty()) 406 if (file_actions.empty())
409 return true; 407 return true;
410 408
411 // For the very first file, just copy all the elements. 409 // For the very first file, just copy all the elements.
412 if (it == files_list.begin()) { 410 if (it == files_list.begin()) {
413 common_task_set = file_actions; 411 common_task_list = file_actions;
414 } else { 412 } else {
415 // For all additional files, find intersection between the accumulated and 413 // For all additional files, find intersection between the accumulated and
416 // file specific set. 414 // file specific set.
417 FileBrowserHandlerSet intersection; 415 FileBrowserHandlerList intersection;
418 std::set_intersection(common_task_set.begin(), common_task_set.end(), 416 std::set_intersection(common_task_list.begin(), common_task_list.end(),
419 file_actions.begin(), file_actions.end(), 417 file_actions.begin(), file_actions.end(),
420 std::inserter(intersection, 418 std::back_inserter(intersection));
421 intersection.begin())); 419 common_task_list = intersection;
422 common_task_set = intersection; 420 if (common_task_list.empty())
423 if (common_task_set.empty())
424 return true; 421 return true;
425 } 422 }
426 } 423 }
427 424
428 FileBrowserHandlerSet::iterator watch_iter = FindHandler( 425 FileBrowserHandlerList::iterator watch_iter = FindHandler(
429 &common_task_set, kFileBrowserDomain, kFileBrowserWatchTaskId); 426 &common_task_list, kFileBrowserDomain, kFileBrowserWatchTaskId);
430 FileBrowserHandlerSet::iterator gallery_iter = FindHandler( 427 FileBrowserHandlerList::iterator gallery_iter = FindHandler(
431 &common_task_set, kFileBrowserDomain, kFileBrowserGalleryTaskId); 428 &common_task_list, kFileBrowserDomain, kFileBrowserGalleryTaskId);
432 if (watch_iter != common_task_set.end() && 429 if (watch_iter != common_task_list.end() &&
433 gallery_iter != common_task_set.end()) { 430 gallery_iter != common_task_list.end()) {
434 // Both "watch" and "gallery" actions are applicable which means that the 431 // 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 432 // 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" 433 // the one that makes more sense ("watch" for single selection, "gallery"
437 // for multiple selection). 434 // for multiple selection).
438 if (files_list.size() == 1) 435 if (files_list.size() == 1)
439 common_task_set.erase(gallery_iter); 436 common_task_list.erase(gallery_iter);
440 else 437 else
441 common_task_set.erase(watch_iter); 438 common_task_list.erase(watch_iter);
442 } 439 }
443 440
444 common_tasks->swap(common_task_set); 441 common_tasks->swap(common_task_list);
445 return true; 442 return true;
446 } 443 }
447 444
448 bool GetTaskForURLAndPath(Profile* profile, 445 bool GetTaskForURLAndPath(Profile* profile,
449 const GURL& url, 446 const GURL& url,
450 const base::FilePath& file_path, 447 const base::FilePath& file_path,
451 const FileBrowserHandler** handler) { 448 const FileBrowserHandler** handler) {
452 std::vector<GURL> file_urls; 449 std::vector<GURL> file_urls;
453 file_urls.push_back(url); 450 file_urls.push_back(url);
454 451
455 FileBrowserHandlerSet default_tasks; 452 FileBrowserHandlerList default_tasks;
456 FileBrowserHandlerSet common_tasks; 453 FileBrowserHandlerList common_tasks;
457 if (!FindCommonTasks(profile, file_urls, &common_tasks)) 454 if (!FindCommonTasks(profile, file_urls, &common_tasks))
458 return false; 455 return false;
459 456
460 if (common_tasks.empty()) 457 if (common_tasks.empty())
461 return false; 458 return false;
462 459
463 std::vector<base::FilePath> file_paths; 460 std::vector<base::FilePath> file_paths;
464 file_paths.push_back(file_path); 461 file_paths.push_back(file_path);
465 462
466 FindDefaultTasks(profile, file_paths, common_tasks, &default_tasks); 463 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(), 985 extensions::LaunchPlatformAppWithFileHandler(profile(), GetExtension(),
989 action_id_, file_urls[i].path()); 986 action_id_, file_urls[i].path());
990 } 987 }
991 988
992 if (!done.is_null()) 989 if (!done.is_null())
993 done.Run(true); 990 done.Run(true);
994 return true; 991 return true;
995 } 992 }
996 993
997 } // namespace file_handler_util 994 } // namespace file_handler_util
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698