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#ifndef CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_PICASA_DATA_PROVIDER_H_
6#define CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_PICASA_DATA_PROVIDER_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/callback_forward.h"
14#include "base/files/file.h"
15#include "base/files/file_path.h"
16#include "base/files/file_path_watcher.h"
17#include "base/memory/ref_counted.h"
18#include "base/memory/scoped_ptr.h"
19#include "base/memory/weak_ptr.h"
20#include "base/time/time.h"
21#include "chrome/common/media_galleries/picasa_types.h"
22
23namespace picasa {
24
25class SafePicasaAlbumTableReader;
26class SafePicasaAlbumsIndexer;
27
28// Created and owned by ImportedMediaGalleryRegistryTaskRunnerValues
29class PicasaDataProvider {
30 public:
31  typedef base::Callback<void(bool)> ReadyCallback;
32
33  enum DataType {
34    LIST_OF_ALBUMS_AND_FOLDERS_DATA,
35    ALBUMS_IMAGES_DATA
36  };
37
38  explicit PicasaDataProvider(const base::FilePath& database_path);
39  virtual ~PicasaDataProvider();
40
41  // Ask the data provider to refresh the data if necessary. |ready_callback|
42  // will be called when the data is up to date.
43  void RefreshData(DataType needed_data, const ReadyCallback& ready_callback);
44
45  // These methods return scoped_ptrs because we want to return a copy that
46  // will not change to the caller.
47  scoped_ptr<AlbumMap> GetAlbums();
48  scoped_ptr<AlbumMap> GetFolders();
49  // |error| must be non-NULL.
50  scoped_ptr<AlbumImages> FindAlbumImages(const std::string& key,
51                                          base::File::Error* error);
52
53 protected:
54  // Notifies data provider that any currently cached data is stale.
55  virtual void InvalidateData();
56
57 private:
58  enum State {
59    STALE_DATA_STATE,
60    INVALID_DATA_STATE,
61    LIST_OF_ALBUMS_AND_FOLDERS_FRESH_STATE,
62    ALBUMS_IMAGES_FRESH_STATE
63  };
64
65  friend class PicasaFileUtilTest;
66  friend class TestPicasaDataProvider;
67
68  // Called when the FilePathWatcher for Picasa's temp directory has started.
69  virtual void OnTempDirWatchStarted(
70      scoped_ptr<base::FilePathWatcher> temp_dir_watcher);
71
72  // Called when Picasa's temp directory has changed. Virtual for testing.
73  virtual void OnTempDirChanged(const base::FilePath& temp_dir_path,
74                                bool error);
75
76  // Kicks off utility processes needed to fulfill any pending callbacks.
77  void DoRefreshIfNecessary();
78
79  void OnAlbumTableReaderDone(scoped_refptr<SafePicasaAlbumTableReader> reader,
80                              bool parse_success,
81                              const std::vector<AlbumInfo>& albums,
82                              const std::vector<AlbumInfo>& folder);
83
84  void OnAlbumsIndexerDone(scoped_refptr<SafePicasaAlbumsIndexer> indexer,
85                           bool success,
86                           const picasa::AlbumImagesMap& albums_images);
87
88  static std::string DateToPathString(const base::Time& time);
89  static void UniquifyNames(const std::vector<AlbumInfo>& info_list,
90                            AlbumMap* result_map);
91
92  AlbumMap album_map_;
93  AlbumMap folder_map_;
94  AlbumImagesMap albums_images_;
95
96  base::FilePath database_path_;
97
98  State state_;
99
100  // Callbacks that are waiting for their requested data to be ready.
101  std::vector<ReadyCallback> album_list_ready_callbacks_;
102  std::vector<ReadyCallback> albums_index_ready_callbacks_;
103
104  // Stores the "live" in-flight utility processes. Callbacks from other
105  // (older) utility processes are stale and ignored. Only one of these at a
106  // time should be non-NULL.
107  scoped_refptr<SafePicasaAlbumTableReader> album_table_reader_;
108  scoped_refptr<SafePicasaAlbumsIndexer> albums_indexer_;
109
110  // We watch the temp dir, as we can't detect database file modifications on
111  // Mac, but we are able to detect creation and deletion of temporary files.
112  scoped_ptr<base::FilePathWatcher> temp_dir_watcher_;
113
114  base::WeakPtrFactory<PicasaDataProvider> weak_factory_;
115
116  DISALLOW_COPY_AND_ASSIGN(PicasaDataProvider);
117};
118
119}  // namespace picasa
120
121#endif  // CHROME_BROWSER_MEDIA_GALLERIES_FILEAPI_PICASA_DATA_PROVIDER_H_
122