1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/utility/importer/bookmarks_file_importer.h"
6
7#include "base/bind.h"
8#include "chrome/common/importer/imported_bookmark_entry.h"
9#include "chrome/common/importer/imported_favicon_usage.h"
10#include "chrome/common/importer/importer_bridge.h"
11#include "chrome/common/importer/importer_data_types.h"
12#include "chrome/common/url_constants.h"
13#include "chrome/grit/generated_resources.h"
14#include "chrome/utility/importer/bookmark_html_reader.h"
15#include "components/url_fixer/url_fixer.h"
16#include "content/public/common/url_constants.h"
17
18namespace {
19
20bool IsImporterCancelled(BookmarksFileImporter* importer) {
21  return importer->cancelled();
22}
23
24}  // namespace
25
26namespace internal {
27
28// Returns true if |url| has a valid scheme that we allow to import. We
29// filter out the URL with a unsupported scheme.
30bool CanImportURL(const GURL& url) {
31  // The URL is not valid.
32  if (!url.is_valid())
33    return false;
34
35  // Filter out the URLs with unsupported schemes.
36  const char* const kInvalidSchemes[] = {"wyciwyg", "place"};
37  for (size_t i = 0; i < arraysize(kInvalidSchemes); ++i) {
38    if (url.SchemeIs(kInvalidSchemes[i]))
39      return false;
40  }
41
42  // Check if |url| is about:blank.
43  if (url == GURL(url::kAboutBlankURL))
44    return true;
45
46  // If |url| starts with chrome:// or about:, check if it's one of the URLs
47  // that we support.
48  if (url.SchemeIs(content::kChromeUIScheme) ||
49      url.SchemeIs(url::kAboutScheme)) {
50    if (url.host() == chrome::kChromeUIUberHost ||
51        url.host() == chrome::kChromeUIAboutHost)
52      return true;
53
54    GURL fixed_url(url_fixer::FixupURL(url.spec(), std::string()));
55    for (size_t i = 0; i < chrome::kNumberOfChromeHostURLs; ++i) {
56      if (fixed_url.DomainIs(chrome::kChromeHostURLs[i]))
57        return true;
58    }
59
60    for (int i = 0; i < chrome::kNumberOfChromeDebugURLs; ++i) {
61      if (fixed_url == GURL(chrome::kChromeDebugURLs[i]))
62        return true;
63    }
64
65    // If url has either chrome:// or about: schemes but wasn't found in the
66    // above lists, it means we don't support it, so we don't allow the user
67    // to import it.
68    return false;
69  }
70
71  // Otherwise, we assume the url has a valid (importable) scheme.
72  return true;
73}
74
75}  // namespace internal
76
77BookmarksFileImporter::BookmarksFileImporter() {}
78
79BookmarksFileImporter::~BookmarksFileImporter() {}
80
81void BookmarksFileImporter::StartImport(
82    const importer::SourceProfile& source_profile,
83    uint16 items,
84    ImporterBridge* bridge) {
85  // The only thing this importer can import is a bookmarks file, aka
86  // "favorites".
87  DCHECK_EQ(importer::FAVORITES, items);
88
89  bridge->NotifyStarted();
90  bridge->NotifyItemStarted(importer::FAVORITES);
91
92  std::vector<ImportedBookmarkEntry> bookmarks;
93  std::vector<ImportedFaviconUsage> favicons;
94
95  bookmark_html_reader::ImportBookmarksFile(
96      base::Bind(IsImporterCancelled, base::Unretained(this)),
97      base::Bind(internal::CanImportURL),
98      source_profile.source_path,
99      &bookmarks,
100      &favicons);
101
102  if (!bookmarks.empty() && !cancelled()) {
103    base::string16 first_folder_name =
104        bridge->GetLocalizedString(IDS_BOOKMARK_GROUP);
105    bridge->AddBookmarks(bookmarks, first_folder_name);
106  }
107  if (!favicons.empty())
108    bridge->SetFavicons(favicons);
109
110  bridge->NotifyItemEnded(importer::FAVORITES);
111  bridge->NotifyEnded();
112}
113