• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/browser/sync/syncable/directory_manager.h"
6 
7 #include <map>
8 #include <set>
9 #include <iterator>
10 
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/port.h"
14 #include "base/string_util.h"
15 #include "chrome/browser/sync/syncable/syncable.h"
16 #include "chrome/common/deprecated/event_sys-inl.h"
17 
18 using browser_sync::Cryptographer;
19 
20 namespace syncable {
21 
22 static const FilePath::CharType kSyncDataDatabaseFilename[] =
23     FILE_PATH_LITERAL("SyncData.sqlite3");
24 
DirectoryManagerShutdownEvent()25 DirectoryManagerEvent DirectoryManagerShutdownEvent() {
26   DirectoryManagerEvent event;
27   event.what_happened = DirectoryManagerEvent::SHUTDOWN;
28   return event;
29 }
30 
31 // static
GetSyncDataDatabaseFilename()32 const FilePath DirectoryManager::GetSyncDataDatabaseFilename() {
33   return FilePath(kSyncDataDatabaseFilename);
34 }
35 
GetSyncDataDatabasePath() const36 const FilePath DirectoryManager::GetSyncDataDatabasePath() const {
37   return root_path_.Append(GetSyncDataDatabaseFilename());
38 }
39 
DirectoryManager(const FilePath & path)40 DirectoryManager::DirectoryManager(const FilePath& path)
41     : root_path_(path),
42       managed_directory_(NULL),
43       channel_(new Channel(DirectoryManagerShutdownEvent())),
44       cryptographer_(new Cryptographer) {
45 }
46 
~DirectoryManager()47 DirectoryManager::~DirectoryManager() {
48   base::AutoLock lock(lock_);
49   DCHECK_EQ(managed_directory_, static_cast<Directory*>(NULL))
50       << "Dir " << managed_directory_->name() << " not closed!";
51   delete channel_;
52 }
53 
Open(const std::string & name)54 bool DirectoryManager::Open(const std::string& name) {
55   bool was_open = false;
56   const DirOpenResult result = OpenImpl(name,
57       GetSyncDataDatabasePath(), &was_open);
58   return syncable::OPENED == result;
59 }
60 
61 // Opens a directory.  Returns false on error.
OpenImpl(const std::string & name,const FilePath & path,bool * was_open)62 DirOpenResult DirectoryManager::OpenImpl(const std::string& name,
63                                          const FilePath& path,
64                                          bool* was_open) {
65   bool opened = false;
66   {
67     base::AutoLock lock(lock_);
68     // Check to see if it's already open.
69     if (managed_directory_) {
70       DCHECK_EQ(base::strcasecmp(name.c_str(),
71                                  managed_directory_->name().c_str()), 0)
72           << "Can't open more than one directory.";
73       opened = *was_open = true;
74     }
75   }
76 
77   if (opened)
78     return syncable::OPENED;
79   // Otherwise, open it.
80 
81   scoped_ptr<Directory> dir(new Directory);
82   const DirOpenResult result = dir->Open(path, name);
83   if (syncable::OPENED == result) {
84     base::AutoLock lock(lock_);
85     managed_directory_ = dir.release();
86   }
87   return result;
88 }
89 
90 // Marks a directory as closed.  It might take a while until all the file
91 // handles and resources are freed by other threads.
Close(const std::string & name)92 void DirectoryManager::Close(const std::string& name) {
93   // Erase from mounted and opened directory lists.
94   {
95     base::AutoLock lock(lock_);
96     if (!managed_directory_ ||
97         base::strcasecmp(name.c_str(),
98                          managed_directory_->name().c_str()) != 0) {
99       // It wasn't open.
100       return;
101     }
102   }
103 
104   // TODO(timsteele): No lock?!
105   // Notify listeners.
106   managed_directory_->channel()->NotifyListeners(DIRECTORY_CLOSED);
107   DirectoryManagerEvent event = { DirectoryManagerEvent::CLOSED, name };
108   channel_->NotifyListeners(event);
109 
110   delete managed_directory_;
111   managed_directory_ = NULL;
112 }
113 
FinalSaveChangesForAll()114 void DirectoryManager::FinalSaveChangesForAll() {
115   base::AutoLock lock(lock_);
116   if (managed_directory_)
117     managed_directory_->SaveChanges();
118 }
119 
GetOpenDirectories(DirNames * result)120 void DirectoryManager::GetOpenDirectories(DirNames* result) {
121   result->clear();
122   base::AutoLock lock(lock_);
123   if (managed_directory_)
124     result->push_back(managed_directory_->name());
125 }
126 
ScopedDirLookup(DirectoryManager * dirman,const std::string & name)127 ScopedDirLookup::ScopedDirLookup(DirectoryManager* dirman,
128                                  const std::string& name) : dirman_(dirman) {
129   dir_ = dirman->managed_directory_ &&
130          (base::strcasecmp(name.c_str(),
131                            dirman->managed_directory_->name().c_str()) == 0) ?
132          dirman->managed_directory_ : NULL;
133   good_ = dir_ != NULL;
134   good_checked_ = false;
135 }
136 
~ScopedDirLookup()137 ScopedDirLookup::~ScopedDirLookup() { }
138 
operator ->() const139 Directory* ScopedDirLookup::operator -> () const {
140   CHECK(good_checked_);
141   DCHECK(good_);
142   return dir_;
143 }
144 
operator Directory*() const145 ScopedDirLookup::operator Directory* () const {
146   CHECK(good_checked_);
147   DCHECK(good_);
148   return dir_;
149 }
150 
151 }  // namespace syncable
152