1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <map>
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/bind.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/callback.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/format_macros.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/i18n/i18n_constants.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/i18n/icu_string_conversions.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/location.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/stl_util.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/string_util.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/file_path_watcher_util.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/common/media_galleries/itunes_library.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/native_file_util.h"
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "third_party/icu/source/common/unicode/locid.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace itunes {
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Colon and slash are not allowed in filenames, replace them with underscore.
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstd::string SanitizeName(const std::string& input) {
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string result;
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::ConvertToUtf8AndNormalize(input, base::kCodepageUTF8, &result);
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::ReplaceChars(result, ":/", "_", &result);
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return result;
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochITunesDataProvider::Album MakeUniqueTrackNames(const parser::Album& album) {
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // TODO(vandebo): It would be nice to ensure that names returned from here
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // are stable, but aside from persisting every name returned, it's not
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // obvious how to do that (without including the track id in every name).
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  typedef std::set<const parser::Track*> TrackRefs;
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  typedef std::map<ITunesDataProvider::TrackName, TrackRefs> AlbumInfo;
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ITunesDataProvider::Album result;
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AlbumInfo duped_tracks;
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  parser::Album::const_iterator album_it;
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (album_it = album.begin(); album_it != album.end(); ++album_it) {
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const parser::Track& track = *album_it;
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    std::string name = SanitizeName(track.location.BaseName().AsUTF8Unsafe());
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    duped_tracks[name].insert(&track);
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (AlbumInfo::const_iterator name_it = duped_tracks.begin();
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       name_it != duped_tracks.end();
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++name_it) {
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const TrackRefs& track_refs = name_it->second;
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (track_refs.size() == 1) {
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      result[name_it->first] = (*track_refs.begin())->location;
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else {
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      for (TrackRefs::const_iterator track_it = track_refs.begin();
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           track_it != track_refs.end();
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           ++track_it) {
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::FilePath track_file_name = (*track_it)->location.BaseName();
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        std::string id =
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            base::StringPrintf(" (%" PRId64 ")", (*track_it)->id);
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        std::string uniquified_track_name =
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            track_file_name.InsertBeforeExtensionASCII(id).AsUTF8Unsafe();
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        std::string escaped_track_name = SanitizeName(uniquified_track_name);
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        result[escaped_track_name] = (*track_it)->location;
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return result;
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// |result_path| is set if |locale_string| maps to a localized directory name
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// and it exists in the filesystem.
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool CheckLocaleStringAutoAddPath(
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::FilePath& media_path,
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::map<std::string, std::string>& localized_dir_names,
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& locale_string,
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::FilePath* result_path) {
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!media_path.empty());
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!localized_dir_names.empty());
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!locale_string.empty());
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(result_path);
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::map<std::string, std::string>::const_iterator it =
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      localized_dir_names.find(locale_string);
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (it == localized_dir_names.end())
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::FilePath localized_auto_add_path =
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      media_path.Append(base::FilePath::FromUTF8Unsafe(it->second));
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!storage::NativeFileUtil::DirectoryExists(localized_auto_add_path))
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  *result_path = localized_auto_add_path;
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return true;
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// This method is complex because Apple localizes the directory name in versions
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// of iTunes before 10.6.
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::FilePath GetAutoAddPath(const base::FilePath& library_path) {
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char kiTunesMediaDir[] = "iTunes Media";
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::FilePath media_path =
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      library_path.DirName().AppendASCII(kiTunesMediaDir);
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Test 'universal' path first.
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::FilePath universal_auto_add_path =
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      media_path.AppendASCII("Automatically Add to iTunes.localized");
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (storage::NativeFileUtil::DirectoryExists(universal_auto_add_path))
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return universal_auto_add_path;
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Test user locale. Localized directory names encoded in UTF-8.
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::map<std::string, std::string> localized_dir_names;
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["nl"] = "Voeg automatisch toe aan iTunes";
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["en"] = "Automatically Add to iTunes";
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["fr"] = "Ajouter automatiquement \xC3\xA0 iTunes";
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["de"] = "Automatisch zu iTunes hinzuf\xC3\xBCgen";
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["it"] = "Aggiungi automaticamente a iTunes";
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["ja"] = "iTunes \xE3\x81\xAB\xE8\x87\xAA\xE5\x8B\x95\xE7"
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              "\x9A\x84\xE3\x81\xAB\xE8\xBF\xBD\xE5\x8A\xA0";
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["es"] = "A\xC3\xB1""adir autom\xC3\xA1ticamente a iTunes";
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["da"] = "F\xC3\xB8j automatisk til iTunes";
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["en-GB"] = "Automatically Add to iTunes";
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["fi"] = "Lis\xC3\xA4\xC3\xA4 automaattisesti iTunesiin";
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["ko"] = "iTunes\xEC\x97\x90 \xEC\x9E\x90\xEB\x8F\x99\xEC"
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              "\x9C\xBC\xEB\xA1\x9C \xEC\xB6\x94\xEA\xB0\x80";
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["no"] = "Legg til automatisk i iTunes";
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["pl"] = "Automatycznie dodaj do iTunes";
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["pt"] = "Adicionar Automaticamente ao iTunes";
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["pt-PT"] = "Adicionar ao iTunes automaticamente";
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["ru"] = "\xD0\x90\xD0\xB2\xD1\x82\xD0\xBE\xD0\xBC\xD0\xB0"
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              "\xD1\x82\xD0\xB8\xD1\x87\xD0\xB5\xD1\x81\xD0\xBA"
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              "\xD0\xB8 \xD0\xB4\xD0\xBE\xD0\xB1\xD0\xB0\xD0"
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              "\xB2\xD0\xBB\xD1\x8F\xD1\x82\xD1\x8C \xD0\xB2"
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              "iTunes";
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["sv"] = "L\xC3\xA4gg automatiskt till i iTunes";
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["zh-CN"] = "\xE8\x87\xAA\xE5\x8A\xA8\xE6\xB7\xBB\xE5\x8A"
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 "\xA0\xE5\x88\xB0 iTunes";
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  localized_dir_names["zh-TW"] = "\xE8\x87\xAA\xE5\x8B\x95\xE5\x8A\xA0\xE5\x85"
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 "\xA5 iTunes";
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const icu::Locale locale = icu::Locale::getDefault();
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char* language = locale.getLanguage();
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char* country = locale.getCountry();
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::FilePath result_path;
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (language != NULL && *language != '\0') {
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (country != NULL && *country != '\0' &&
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CheckLocaleStringAutoAddPath(media_path, localized_dir_names,
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     std::string(language) + "-" + country,
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     &result_path)) {
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return result_path;
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (CheckLocaleStringAutoAddPath(media_path, localized_dir_names,
1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     language, &result_path)) {
1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return result_path;
1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Fallback to trying English.
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (CheckLocaleStringAutoAddPath(media_path, localized_dir_names,
1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                   "en", &result_path)) {
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return result_path;
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return base::FilePath();
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ITunesDataProvider::ITunesDataProvider(const base::FilePath& library_path)
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : iapps::IAppsDataProvider(library_path),
1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      auto_add_path_(GetAutoAddPath(library_path)),
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_(this) {}
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ITunesDataProvider::~ITunesDataProvider() {}
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ITunesDataProvider::DoParseLibrary(
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const base::FilePath& library_path,
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const ReadyCallback& ready_callback) {
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  xml_parser_ = new iapps::SafeIAppsLibraryParser;
1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  xml_parser_->ParseITunesLibrary(
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      library_path,
1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      base::Bind(&ITunesDataProvider::OnLibraryParsed,
1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                 ready_callback));
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const base::FilePath& ITunesDataProvider::auto_add_path() const {
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return auto_add_path_;
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ITunesDataProvider::KnownArtist(const ArtistName& artist) const {
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(valid());
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ContainsKey(library_, artist);
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ITunesDataProvider::KnownAlbum(const ArtistName& artist,
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                    const AlbumName& album) const {
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(valid());
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Library::const_iterator library_it = library_.find(artist);
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (library_it == library_.end())
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ContainsKey(library_it->second, album);
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::FilePath ITunesDataProvider::GetTrackLocation(
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const ArtistName& artist, const AlbumName& album,
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const TrackName& track) const {
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(valid());
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Library::const_iterator library_it = library_.find(artist);
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (library_it == library_.end())
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return base::FilePath();
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Artist::const_iterator artist_it = library_it->second.find(album);
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (artist_it == library_it->second.end())
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return base::FilePath();
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Album::const_iterator album_it = artist_it->second.find(track);
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (album_it == artist_it->second.end())
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return base::FilePath();
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return album_it->second;
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::set<ITunesDataProvider::ArtistName>
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ITunesDataProvider::GetArtistNames() const {
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(valid());
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::set<ArtistName> result;
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Library::const_iterator it;
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (it = library_.begin(); it != library_.end(); ++it) {
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    result.insert(it->first);
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return result;
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::set<ITunesDataProvider::AlbumName> ITunesDataProvider::GetAlbumNames(
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const ArtistName& artist) const {
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(valid());
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::set<AlbumName> result;
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Library::const_iterator artist_lookup = library_.find(artist);
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (artist_lookup == library_.end())
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return result;
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const Artist& artist_entry = artist_lookup->second;
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Artist::const_iterator it;
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (it = artist_entry.begin(); it != artist_entry.end(); ++it) {
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    result.insert(it->first);
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return result;
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ITunesDataProvider::Album ITunesDataProvider::GetAlbum(
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const ArtistName& artist, const AlbumName& album) const {
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(valid());
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Album result;
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Library::const_iterator artist_lookup = library_.find(artist);
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (artist_lookup != library_.end()) {
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Artist::const_iterator album_lookup = artist_lookup->second.find(album);
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (album_lookup != artist_lookup->second.end())
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      result = album_lookup->second;
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return result;
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ITunesDataProvider::OnLibraryParsed(const ReadyCallback& ready_callback,
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                         bool result,
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                         const parser::Library& library) {
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  set_valid(result);
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (valid()) {
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    library_.clear();
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    for (parser::Library::const_iterator artist_it = library.begin();
287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         artist_it != library.end();
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         ++artist_it) {
289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      std::string artist_name = SanitizeName(artist_it->first);
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      for (parser::Albums::const_iterator album_it = artist_it->second.begin();
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           album_it != artist_it->second.end();
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           ++album_it) {
293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        std::string album_name = SanitizeName(album_it->first);
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        library_[artist_name][album_name] =
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            MakeUniqueTrackNames(album_it->second);
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ready_callback.Run(valid());
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace itunes
303