1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This used to do a lot of TLS-based management of multiple Directory objects.
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We now can access Directory objects from any thread for general purpose
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// operations and we only ever have one Directory, so this class isn't doing
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// anything too fancy besides keeping calling and access conventions the same
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// for now.
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(timsteele): We can probably nuke this entire class and use raw
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Directory objects everywhere.
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_SYNC_SYNCABLE_DIRECTORY_MANAGER_H_
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_SYNC_SYNCABLE_DIRECTORY_MANAGER_H_
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/synchronization/lock.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/syncable/dir_open_result.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/syncable/syncable.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/util/cryptographer.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/deprecated/event_sys.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace sync_api { class BaseTransaction; }
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace syncable { class BaseTransaction; }
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace syncable {
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct DirectoryManagerEvent {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum {
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CLOSED,
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CLOSED_ALL,
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SHUTDOWN,
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } what_happened;
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string dirname;
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef DirectoryManagerEvent EventType;
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static inline bool IsChannelShutdownEvent(const EventType& event) {
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return SHUTDOWN == event.what_happened;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDirectoryManagerEvent DirectoryManagerShutdownEvent();
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass DirectoryManager {
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef EventChannel<DirectoryManagerEvent> Channel;
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // root_path specifies where db is stored.
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit DirectoryManager(const FilePath& root_path);
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~DirectoryManager();
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const FilePath GetSyncDataDatabaseFilename();
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const FilePath GetSyncDataDatabasePath() const;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Opens a directory.  Returns false on error.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Name parameter is the the user's login,
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // MUST already have been converted to a common case.
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool Open(const std::string& name);
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Marks a directory as closed.  It might take a while until all the
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // file handles and resources are freed by other threads.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Close(const std::string& name);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Should be called at App exit.
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void FinalSaveChangesForAll();
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Gets the list of currently open directory names.
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::vector<std::string> DirNames;
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void GetOpenDirectories(DirNames* result);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Channel* channel() const { return channel_; }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Wrappers for cryptographer() that enforce holding a transaction.
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Note: the Cryptographer is NOT thread safe. It must only be accessed while
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the transaction is still active. The Cryptographer's pointer should not be
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // stored separately.
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser_sync::Cryptographer* GetCryptographer(
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const sync_api::BaseTransaction* trans) const { return cryptographer(); }
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser_sync::Cryptographer* GetCryptographer(
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const syncable::BaseTransaction* trans) const { return cryptographer(); }
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen protected:
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_sync::Cryptographer* cryptographer() const {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return cryptographer_.get();
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DirOpenResult OpenImpl(const std::string& name, const FilePath& path,
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         bool* was_open);
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helpers for friend class ScopedDirLookup:
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class ScopedDirLookup;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const FilePath root_path_;
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // protects managed_directory_
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::Lock lock_;
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Directory* managed_directory_;
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Channel* const channel_;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<browser_sync::Cryptographer> cryptographer_;
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(DirectoryManager);
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ScopedDirLookup {
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedDirLookup(DirectoryManager* dirman, const std::string& name);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~ScopedDirLookup();
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  inline bool good() {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    good_checked_ = true;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return good_;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Directory* operator -> () const;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  operator Directory* () const;
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:  // Don't allow creation on heap, except by sync API wrapper.
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class sync_api::BaseTransaction;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void* operator new(size_t size) { return (::operator new)(size); }
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Directory* dir_;
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool good_;
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Ensure that the programmer checks good before using the ScopedDirLookup.
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This member should can be removed if it ever shows up in profiling
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool good_checked_;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DirectoryManager* const dirman_;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace syncable
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_SYNC_SYNCABLE_DIRECTORY_MANAGER_H_
138