// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/file_manager/file_tasks.h"

#include <stddef.h>

#include <map>

#include "apps/launcher.h"
#include "base/bind.h"
#include "base/macros.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/drive/file_task_executor.h"
#include "chrome/browser/chromeos/file_manager/app_id.h"
#include "chrome/browser/chromeos/file_manager/arc_file_tasks.h"
#include "chrome/browser/chromeos/file_manager/file_browser_handlers.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
#include "chrome/browser/chromeos/file_manager/open_util.h"
#include "chrome/browser/extensions/api/file_handlers/mime_util.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
#include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
#include "chrome/common/extensions/api/file_manager_private.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
#include "chromeos/chromeos_switches.h"
#include "components/drive/drive_api_util.h"
#include "components/drive/drive_app_registry.h"
#include "components/mime_util/mime_util.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "extensions/browser/entry_info.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_util.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension_set.h"
#include "storage/browser/fileapi/file_system_url.h"

using extensions::Extension;
using extensions::api::file_manager_private::Verb;
using extensions::app_file_handler_util::FindFileHandlersForEntries;
using storage::FileSystemURL;

namespace file_manager {
namespace file_tasks {

namespace {

// The values "file" and "app" are confusing, but cannot be changed easily as
// these are used in default task IDs stored in preferences.
const char kFileBrowserHandlerTaskType[] = "file";
const char kFileHandlerTaskType[] = "app";
const char kDriveAppTaskType[] = "drive";
const char kArcAppTaskType[] = "arc";

// Drive apps always use the action ID.
const char kDriveAppActionID[] = "open-with";

// Converts a TaskType to a string.
std::string TaskTypeToString(TaskType task_type) {
  switch (task_type) {
    case TASK_TYPE_FILE_BROWSER_HANDLER:
      return kFileBrowserHandlerTaskType;
    case TASK_TYPE_FILE_HANDLER:
      return kFileHandlerTaskType;
    case TASK_TYPE_DRIVE_APP:
      return kDriveAppTaskType;
    case TASK_TYPE_ARC_APP:
      return kArcAppTaskType;
    case TASK_TYPE_UNKNOWN:
      break;
  }
  NOTREACHED();
  return "";
}

// Converts a string to a TaskType. Returns TASK_TYPE_UNKNOWN on error.
TaskType StringToTaskType(const std::string& str) {
  if (str == kFileBrowserHandlerTaskType)
    return TASK_TYPE_FILE_BROWSER_HANDLER;
  if (str == kFileHandlerTaskType)
    return TASK_TYPE_FILE_HANDLER;
  if (str == kDriveAppTaskType)
    return TASK_TYPE_DRIVE_APP;
  if (str == kArcAppTaskType)
    return TASK_TYPE_ARC_APP;
  return TASK_TYPE_UNKNOWN;
}

// Legacy Drive task extension prefix, used by CrackTaskID.
const char kDriveTaskExtensionPrefix[] = "drive-app:";
const size_t kDriveTaskExtensionPrefixLength =
    arraysize(kDriveTaskExtensionPrefix) - 1;

// Returns true if path_mime_set contains a Google document.
bool ContainsGoogleDocument(const std::vector<extensions::EntryInfo>& entries) {
  for (const auto& it : entries) {
    if (drive::util::HasHostedDocumentExtension(it.path))
      return true;
  }
  return false;
}

// Leaves tasks handled by the file manger itself as is and removes all others.
void KeepOnlyFileManagerInternalTasks(std::vector<FullTaskDescriptor>* tasks) {
  std::vector<FullTaskDescriptor> filtered;
  for (size_t i = 0; i < tasks->size(); ++i) {
    if ((*tasks)[i].task_descriptor().app_id == kFileManagerAppId)
      filtered.push_back((*tasks)[i]);
  }
  tasks->swap(filtered);
}

// Returns true if the given task is a handler by built-in apps like Files.app
// itself or QuickOffice etc. They are used as the initial default app.
bool IsFallbackFileHandler(const file_tasks::TaskDescriptor& task) {
  if (task.task_type != file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER &&
      task.task_type != file_tasks::TASK_TYPE_FILE_HANDLER)
    return false;

  const char* const kBuiltInApps[] = {
    kFileManagerAppId,
    kVideoPlayerAppId,
    kGalleryAppId,
  };

  for (size_t i = 0; i < arraysize(kBuiltInApps); ++i) {
    if (task.app_id == kBuiltInApps[i])
      return true;
  }
  return false;
}

void ExecuteByArcAfterMimeTypesCollected(
    Profile* profile,
    const TaskDescriptor& task,
    const std::vector<FileSystemURL>& file_urls,
    const FileTaskFinishedCallback& done,
    extensions::app_file_handler_util::MimeTypeCollector* mime_collector,
    std::unique_ptr<std::vector<std::string>> mime_types) {
  if (ExecuteArcTask(profile, task, file_urls, *mime_types)) {
    done.Run(extensions::api::file_manager_private::TASK_RESULT_MESSAGE_SENT);
  } else {
    done.Run(extensions::api::file_manager_private::TASK_RESULT_FAILED);
  }
}

void PostProcessFoundTasks(
    Profile* profile,
    const std::vector<extensions::EntryInfo>& entries,
    const FindTasksCallback& callback,
    std::unique_ptr<std::vector<FullTaskDescriptor>> result_list) {
  // Google documents can only be handled by internal handlers.
  if (ContainsGoogleDocument(entries))
    KeepOnlyFileManagerInternalTasks(result_list.get());
  ChooseAndSetDefaultTask(*profile->GetPrefs(), entries, result_list.get());
  callback.Run(std::move(result_list));
}

}  // namespace

FullTaskDescriptor::FullTaskDescriptor(const TaskDescriptor& task_descriptor,
                                       const std::string& task_title,
                                       const Verb task_verb,
                                       const GURL& icon_url,
                                       bool is_default,
                                       bool is_generic_file_handler)
    : task_descriptor_(task_descriptor),
      task_title_(task_title),
      task_verb_(task_verb),
      icon_url_(icon_url),
      is_default_(is_default),
      is_generic_file_handler_(is_generic_file_handler) {}

FullTaskDescriptor::~FullTaskDescriptor() {}

FullTaskDescriptor::FullTaskDescriptor(const FullTaskDescriptor& other) =
    default;

void UpdateDefaultTask(PrefService* pref_service,
                       const std::string& task_id,
                       const std::set<std::string>& suffixes,
                       const std::set<std::string>& mime_types) {
  if (!pref_service)
    return;

  if (!mime_types.empty()) {
    DictionaryPrefUpdate mime_type_pref(pref_service,
                                        prefs::kDefaultTasksByMimeType);
    for (std::set<std::string>::const_iterator iter = mime_types.begin();
        iter != mime_types.end(); ++iter) {
      base::StringValue* value = new base::StringValue(task_id);
      mime_type_pref->SetWithoutPathExpansion(*iter, value);
    }
  }

  if (!suffixes.empty()) {
    DictionaryPrefUpdate mime_type_pref(pref_service,
                                        prefs::kDefaultTasksBySuffix);
    for (std::set<std::string>::const_iterator iter = suffixes.begin();
        iter != suffixes.end(); ++iter) {
      base::StringValue* value = new base::StringValue(task_id);
      // Suffixes are case insensitive.
      std::string lower_suffix = base::ToLowerASCII(*iter);
      mime_type_pref->SetWithoutPathExpansion(lower_suffix, value);
    }
  }
}

std::string GetDefaultTaskIdFromPrefs(const PrefService& pref_service,
                                      const std::string& mime_type,
                                      const std::string& suffix) {
  VLOG(1) << "Looking for default for MIME type: " << mime_type
      << " and suffix: " << suffix;
  std::string task_id;
  if (!mime_type.empty()) {
    const base::DictionaryValue* mime_task_prefs =
        pref_service.GetDictionary(prefs::kDefaultTasksByMimeType);
    DCHECK(mime_task_prefs);
    LOG_IF(ERROR, !mime_task_prefs) << "Unable to open MIME type prefs";
    if (mime_task_prefs &&
        mime_task_prefs->GetStringWithoutPathExpansion(mime_type, &task_id)) {
      VLOG(1) << "Found MIME default handler: " << task_id;
      return task_id;
    }
  }

  const base::DictionaryValue* suffix_task_prefs =
      pref_service.GetDictionary(prefs::kDefaultTasksBySuffix);
  DCHECK(suffix_task_prefs);
  LOG_IF(ERROR, !suffix_task_prefs) << "Unable to open suffix prefs";
  std::string lower_suffix = base::ToLowerASCII(suffix);
  if (suffix_task_prefs)
    suffix_task_prefs->GetStringWithoutPathExpansion(lower_suffix, &task_id);
  VLOG_IF(1, !task_id.empty()) << "Found suffix default handler: " << task_id;
  return task_id;
}

std::string MakeTaskID(const std::string& app_id,
                       TaskType task_type,
                       const std::string& action_id) {
  return base::StringPrintf("%s|%s|%s",
                            app_id.c_str(),
                            TaskTypeToString(task_type).c_str(),
                            action_id.c_str());
}

std::string TaskDescriptorToId(const TaskDescriptor& task_descriptor) {
  return MakeTaskID(task_descriptor.app_id,
                    task_descriptor.task_type,
                    task_descriptor.action_id);
}

bool ParseTaskID(const std::string& task_id, TaskDescriptor* task) {
  DCHECK(task);

  std::vector<std::string> result = base::SplitString(
      task_id, "|", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  // Parse a legacy task ID that only contain two parts. Drive tasks are
  // identified by a prefix "drive-app:" on the extension ID. The legacy task
  // IDs can be stored in preferences.
  if (result.size() == 2) {
    if (base::StartsWith(result[0], kDriveTaskExtensionPrefix,
                         base::CompareCase::SENSITIVE)) {
      task->task_type = TASK_TYPE_DRIVE_APP;
      task->app_id = result[0].substr(kDriveTaskExtensionPrefixLength);
    } else {
      task->task_type = TASK_TYPE_FILE_BROWSER_HANDLER;
      task->app_id = result[0];
    }

    task->action_id = result[1];

    return true;
  }

  if (result.size() != 3)
    return false;

  TaskType task_type = StringToTaskType(result[1]);
  if (task_type == TASK_TYPE_UNKNOWN)
    return false;

  task->app_id = result[0];
  task->task_type = task_type;
  task->action_id = result[2];

  return true;
}

bool ExecuteFileTask(Profile* profile,
                     const GURL& source_url,
                     const TaskDescriptor& task,
                     const std::vector<FileSystemURL>& file_urls,
                     const FileTaskFinishedCallback& done) {
  // ARC apps needs mime types for launching. Retrieve them first.
  if (task.task_type == TASK_TYPE_ARC_APP) {
    extensions::app_file_handler_util::MimeTypeCollector* mime_collector =
        new extensions::app_file_handler_util::MimeTypeCollector(profile);
    mime_collector->CollectForURLs(
        file_urls,
        base::Bind(&ExecuteByArcAfterMimeTypesCollected, profile, task,
                   file_urls, done, base::Owned(mime_collector)));
    return true;
  }

  // drive::FileTaskExecutor is responsible to handle drive tasks.
  if (task.task_type == TASK_TYPE_DRIVE_APP) {
    DCHECK_EQ(kDriveAppActionID, task.action_id);
    drive::FileTaskExecutor* executor =
        new drive::FileTaskExecutor(profile, task.app_id);
    executor->Execute(file_urls, done);
    return true;
  }

  // Get the extension.
  const Extension* extension = extensions::ExtensionRegistry::Get(
      profile)->enabled_extensions().GetByID(task.app_id);
  if (!extension)
    return false;

  // Execute the task.
  if (task.task_type == TASK_TYPE_FILE_BROWSER_HANDLER) {
    return file_browser_handlers::ExecuteFileBrowserHandler(
        profile,
        extension,
        task.action_id,
        file_urls,
        done);
  } else if (task.task_type == TASK_TYPE_FILE_HANDLER) {
    std::vector<base::FilePath> paths;
    for (size_t i = 0; i != file_urls.size(); ++i)
      paths.push_back(file_urls[i].path());
    apps::LaunchPlatformAppWithFileHandler(
        profile, extension, task.action_id, paths);
    if (!done.is_null())
      done.Run(extensions::api::file_manager_private::TASK_RESULT_MESSAGE_SENT);
    return true;
  }
  NOTREACHED();
  return false;
}

void FindDriveAppTasks(const drive::DriveAppRegistry& drive_app_registry,
                       const std::vector<extensions::EntryInfo>& entries,
                       std::vector<FullTaskDescriptor>* result_list) {
  DCHECK(result_list);

  bool is_first = true;
  typedef std::map<std::string, drive::DriveAppInfo> DriveAppInfoMap;
  DriveAppInfoMap drive_app_map;

  for (std::vector<extensions::EntryInfo>::const_iterator it = entries.begin();
       it != entries.end(); ++it) {
    const base::FilePath& file_path = it->path;
    const std::string& mime_type = it->mime_type;
    // Return immediately if a file not on Drive is found, as Drive app tasks
    // work only if all files are on Drive.
    if (!drive::util::IsUnderDriveMountPoint(file_path))
      return;

    std::vector<drive::DriveAppInfo> app_info_list;
    drive_app_registry.GetAppsForFile(file_path.Extension(),
                                      mime_type,
                                      &app_info_list);

    if (is_first) {
      // For the first file, we store all the info.
      for (size_t j = 0; j < app_info_list.size(); ++j)
        drive_app_map[app_info_list[j].app_id] = app_info_list[j];
    } else {
      // For remaining files, take the intersection with the current
      // result, based on the app id.
      std::set<std::string> app_id_set;
      for (size_t j = 0; j < app_info_list.size(); ++j)
        app_id_set.insert(app_info_list[j].app_id);
      for (DriveAppInfoMap::iterator iter = drive_app_map.begin();
           iter != drive_app_map.end();) {
        if (app_id_set.count(iter->first) == 0) {
          drive_app_map.erase(iter++);
        } else {
          ++iter;
        }
      }
    }

    is_first = false;
  }

  for (DriveAppInfoMap::const_iterator iter = drive_app_map.begin();
       iter != drive_app_map.end(); ++iter) {
    const drive::DriveAppInfo& app_info = iter->second;
    TaskDescriptor descriptor(app_info.app_id,
                              TASK_TYPE_DRIVE_APP,
                              kDriveAppActionID);
    GURL icon_url = drive::util::FindPreferredIcon(
        app_info.app_icons,
        drive::util::kPreferredIconSize);

    result_list->push_back(FullTaskDescriptor(
        descriptor, app_info.app_name, Verb::VERB_OPEN_WITH, icon_url,
        false /* is_default */, false /* is_generic_file_handler */));
  }
}

bool IsGoodMatchFileHandler(
    const extensions::FileHandlerInfo& file_handler_info,
    const std::vector<extensions::EntryInfo>& entries) {
  if (file_handler_info.extensions.count("*") > 0 ||
      file_handler_info.types.count("*") > 0 ||
      file_handler_info.types.count("*/*") > 0)
    return false;

  // If text/* file handler matches with unsupported text mime type, we don't
  // regard it as good match.
  if (file_handler_info.types.count("text/*")) {
    for (const auto& entry : entries) {
      if (mime_util::IsUnsupportedTextMimeType(entry.mime_type))
        return false;
    }
  }

  // We consider it a good match if no directories are selected.
  for (const auto& entry : entries) {
    if (entry.is_directory)
      return false;
  }
  return true;
}

void FindFileHandlerTasks(Profile* profile,
                          const std::vector<extensions::EntryInfo>& entries,
                          std::vector<FullTaskDescriptor>* result_list) {
  DCHECK(!entries.empty());
  DCHECK(result_list);

  const extensions::ExtensionSet& enabled_extensions =
      extensions::ExtensionRegistry::Get(profile)->enabled_extensions();

  for (extensions::ExtensionSet::const_iterator iter =
           enabled_extensions.begin();
       iter != enabled_extensions.end();
       ++iter) {
    const Extension* extension = iter->get();

    // Check that the extension can be launched via an event. This includes all
    // platform apps plus whitelisted extensions.
    if (!CanLaunchViaEvent(extension))
      continue;

    if (profile->IsOffTheRecord() &&
        !extensions::util::IsIncognitoEnabled(extension->id(), profile))
      continue;

    typedef std::vector<const extensions::FileHandlerInfo*> FileHandlerList;
    FileHandlerList file_handlers =
        FindFileHandlersForEntries(*extension, entries);
    if (file_handlers.empty())
      continue;

    // If the new ZIP unpacker is disabled, then hide its handlers, so we don't
    // show both the legacy one and the new one in Files app for ZIP files.
    if (extension->id() == extension_misc::kZIPUnpackerExtensionId &&
        base::CommandLine::ForCurrentProcess()->HasSwitch(
            chromeos::switches::kDisableNewZIPUnpacker)) {
      continue;
    }

    // A map which has as key a handler verb, and as value a pair of the
    // handler with which to open the given entries and a boolean marking
    // if the handler is a good match.
    std::map<std::string, std::pair<const extensions::FileHandlerInfo*, bool>>
        handlers_for_entries;
    // Show the first good matching handler of each verb supporting the given
    // entries that corresponds to the app. If there doesn't exist such handler,
    // show the first matching handler of the verb.
    for (const extensions::FileHandlerInfo* handler : file_handlers) {
      bool good_match = IsGoodMatchFileHandler(*handler, entries);
      auto it = handlers_for_entries.find(handler->verb);
      if (it == handlers_for_entries.end() ||
          (!it->second.second /* existing handler not a good match */ &&
           good_match)) {
        handlers_for_entries[handler->verb] =
            std::make_pair(handler, good_match);
      }
    }

    for (const auto& entry : handlers_for_entries) {
      const extensions::FileHandlerInfo* handler = entry.second.first;
      std::string task_id = file_tasks::MakeTaskID(
          extension->id(), file_tasks::TASK_TYPE_FILE_HANDLER, handler->id);

      GURL best_icon = extensions::ExtensionIconSource::GetIconURL(
          extension, drive::util::kPreferredIconSize,
          ExtensionIconSet::MATCH_BIGGER,
          false,  // grayscale
          NULL);  // exists

      // If file handler doesn't match as good match, regards it as generic file
      // handler.
      const bool is_generic_file_handler =
          !IsGoodMatchFileHandler(*handler, entries);
      Verb verb;
      if (handler->verb == extensions::file_handler_verbs::kAddTo) {
        verb = Verb::VERB_ADD_TO;
      } else if (handler->verb == extensions::file_handler_verbs::kPackWith) {
        verb = Verb::VERB_PACK_WITH;
      } else if (handler->verb == extensions::file_handler_verbs::kShareWith) {
        verb = Verb::VERB_SHARE_WITH;
      } else {
        // Only kOpenWith is a valid remaining verb. Invalid verbs should fall
        // back to it.
        DCHECK(handler->verb == extensions::file_handler_verbs::kOpenWith);
        verb = Verb::VERB_OPEN_WITH;
      }

      result_list->push_back(FullTaskDescriptor(
          TaskDescriptor(extension->id(), file_tasks::TASK_TYPE_FILE_HANDLER,
                         handler->id),
          extension->name(), verb, best_icon, false /* is_default */,
          is_generic_file_handler));
    }
  }
}

void FindFileBrowserHandlerTasks(
    Profile* profile,
    const std::vector<GURL>& file_urls,
    std::vector<FullTaskDescriptor>* result_list) {
  DCHECK(!file_urls.empty());
  DCHECK(result_list);

  file_browser_handlers::FileBrowserHandlerList common_tasks =
      file_browser_handlers::FindFileBrowserHandlers(profile, file_urls);
  if (common_tasks.empty())
    return;

  const extensions::ExtensionSet& enabled_extensions =
      extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
  for (file_browser_handlers::FileBrowserHandlerList::const_iterator iter =
           common_tasks.begin();
       iter != common_tasks.end();
       ++iter) {
    const FileBrowserHandler* handler = *iter;
    const std::string extension_id = handler->extension_id();
    const Extension* extension = enabled_extensions.GetByID(extension_id);
    DCHECK(extension);

    // TODO(zelidrag): Figure out how to expose icon URL that task defined in
    // manifest instead of the default extension icon.
    const GURL icon_url = extensions::ExtensionIconSource::GetIconURL(
        extension,
        extension_misc::EXTENSION_ICON_BITTY,
        ExtensionIconSet::MATCH_BIGGER,
        false,  // grayscale
        NULL);  // exists

    result_list->push_back(FullTaskDescriptor(
        TaskDescriptor(extension_id, file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER,
                       handler->id()),
        handler->title(), Verb::VERB_NONE /* no verb for FileBrowserHandler */,
        icon_url, false /* is_default */, false /* is_generic_file_handler */));
  }
}

void FindExtensionAndAppTasks(
    Profile* profile,
    const std::vector<extensions::EntryInfo>& entries,
    const std::vector<GURL>& file_urls,
    const FindTasksCallback& callback,
    std::unique_ptr<std::vector<FullTaskDescriptor>> result_list) {
  // 3. Continues from FindAllTypesOfTasks. Find and append file handler tasks.
  FindFileHandlerTasks(profile, entries, result_list.get());

  // 4. Find and append file browser handler tasks. We know there aren't
  // duplicates because "file_browser_handlers" and "file_handlers" shouldn't
  // be used in the same manifest.json.
  FindFileBrowserHandlerTasks(profile, file_urls, result_list.get());

  // Done. Apply post-filtering and callback.
  PostProcessFoundTasks(profile, entries, callback, std::move(result_list));
}

void FindAllTypesOfTasks(Profile* profile,
                         const drive::DriveAppRegistry* drive_app_registry,
                         const std::vector<extensions::EntryInfo>& entries,
                         const std::vector<GURL>& file_urls,
                         const FindTasksCallback& callback) {
  DCHECK(profile);
  std::unique_ptr<std::vector<FullTaskDescriptor>> result_list(
      new std::vector<FullTaskDescriptor>);

  // 1. Find Drive app tasks, if the drive app registry is present.
  if (drive_app_registry)
    FindDriveAppTasks(*drive_app_registry, entries, result_list.get());

  // 2. Find and append ARC handler tasks.
  FindArcTasks(profile, entries, std::move(result_list),
               base::Bind(&FindExtensionAndAppTasks, profile, entries,
                          file_urls, callback));
}

void ChooseAndSetDefaultTask(const PrefService& pref_service,
                             const std::vector<extensions::EntryInfo>& entries,
                             std::vector<FullTaskDescriptor>* tasks) {
  // Collect the task IDs of default tasks from the preferences into a set.
  std::set<std::string> default_task_ids;
  for (std::vector<extensions::EntryInfo>::const_iterator it = entries.begin();
       it != entries.end(); ++it) {
    const base::FilePath& file_path = it->path;
    const std::string& mime_type = it->mime_type;
    std::string task_id = file_tasks::GetDefaultTaskIdFromPrefs(
        pref_service, mime_type, file_path.Extension());
    default_task_ids.insert(task_id);
  }

  // Go through all the tasks from the beginning and see if there is any
  // default task. If found, pick and set it as default and return.
  for (size_t i = 0; i < tasks->size(); ++i) {
    FullTaskDescriptor* task = &tasks->at(i);
    DCHECK(!task->is_default());
    const std::string task_id = TaskDescriptorToId(task->task_descriptor());
    if (base::ContainsKey(default_task_ids, task_id)) {
      task->set_is_default(true);
      return;
    }
  }

  // No default tasks found. If there is any fallback file browser handler,
  // make it as default task, so it's selected by default.
  for (size_t i = 0; i < tasks->size(); ++i) {
    FullTaskDescriptor* task = &tasks->at(i);
    DCHECK(!task->is_default());
    if (IsFallbackFileHandler(task->task_descriptor())) {
      task->set_is_default(true);
      return;
    }
  }
}

}  // namespace file_tasks
}  // namespace file_manager
