1// Copyright 2014 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_MEDIA_SCAN_MANAGER_H_
6#define CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_SCAN_MANAGER_H_
7
8#include <map>
9#include <set>
10#include <string>
11
12#include "base/basictypes.h"
13#include "base/compiler_specific.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "base/scoped_observer.h"
17#include "base/time/time.h"
18#include "chrome/browser/media_galleries/media_folder_finder.h"
19#include "chrome/browser/media_galleries/media_scan_types.h"
20#include "extensions/browser/extension_registry_observer.h"
21
22class MediaScanManagerObserver;
23class Profile;
24
25namespace extensions {
26class Extension;
27class ExtensionRegistry;
28}
29
30// The MediaScanManager is owned by MediaFileSystemRegistry, which is global.
31// This class manages multiple 'virtual' media scans, up to one per extension
32// per profile, and also manages the one physical scan backing them.
33// This class lives and is called on the UI thread.
34class MediaScanManager : public extensions::ExtensionRegistryObserver {
35 public:
36  MediaScanManager();
37  virtual ~MediaScanManager();
38
39  // There can only be ever one observer registered per profile. Does not take
40  // ownership of |observer|. An observer must be registered before scanning.
41  void AddObserver(Profile* profile, MediaScanManagerObserver* observer);
42  void RemoveObserver(Profile* profile);
43
44  // Must be called when |profile| is shut down.
45  void CancelScansForProfile(Profile* profile);
46
47  // The results of the scan are reported to the registered
48  // MediaScanManagerObserver via OnScanFinished. There must be an observer
49  // registered for |profile| before the scan starts.
50  void StartScan(Profile* profile, const extensions::Extension* extension,
51                 bool user_gesture);
52  void CancelScan(Profile* profile, const extensions::Extension* extension);
53
54 protected:
55  friend class MediaGalleriesPlatformAppBrowserTest;
56  friend class MediaScanManagerTest;
57
58  typedef base::Callback<MediaFolderFinder*(
59      const MediaFolderFinder::MediaFolderFinderResultsCallback&)>
60          MediaFolderFinderFactory;
61
62  void SetMediaFolderFinderFactory(const MediaFolderFinderFactory& factory);
63
64  // Here so that friend MediaScanManagerTest can access it.
65  static MediaFolderFinder::MediaFolderFinderResults FindContainerScanResults(
66      const MediaFolderFinder::MediaFolderFinderResults& found_folders,
67      const std::vector<base::FilePath>& sensitive_locations);
68
69 private:
70  struct ScanObservers {
71    ScanObservers();
72    ~ScanObservers();
73    MediaScanManagerObserver* observer;
74    std::set<std::string /*extension id*/> scanning_extensions;
75  };
76  typedef std::map<Profile*, ScanObservers> ScanObserverMap;
77
78  // extensions::ExtensionRegistryObserver implementation.
79  virtual void OnExtensionUnloaded(
80      content::BrowserContext* browser_context,
81      const extensions::Extension* extension,
82      extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE;
83
84  bool ScanInProgress() const;
85
86  void OnScanCompleted(
87      bool success,
88      const MediaFolderFinder::MediaFolderFinderResults& found_folders);
89
90  void OnFoundContainerDirectories(
91      const MediaFolderFinder::MediaFolderFinderResults& found_folders,
92      const MediaFolderFinder::MediaFolderFinderResults& container_folders);
93
94  scoped_ptr<MediaFolderFinder> folder_finder_;
95
96  base::Time scan_start_time_;
97
98  // If not NULL, used to create |folder_finder_|. Used for testing.
99  MediaFolderFinderFactory testing_folder_finder_factory_;
100
101  // Set of extensions (on all profiles) that have an in-progress scan.
102  ScanObserverMap observers_;
103
104  ScopedObserver<extensions::ExtensionRegistry,
105                 extensions::ExtensionRegistryObserver>
106      scoped_extension_registry_observer_;
107
108  base::WeakPtrFactory<MediaScanManager> weak_factory_;
109
110  DISALLOW_COPY_AND_ASSIGN(MediaScanManager);
111};
112
113#endif  // CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_SCAN_MANAGER_H_
114