Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / sync_file_system / local / local_file_sync_status.cc
blob990baf709b6a0d34cf008ccf57b1887f5363c42b
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.
5 #include "chrome/browser/sync_file_system/local/local_file_sync_status.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "storage/common/fileapi/file_system_util.h"
11 using storage::FileSystemURL;
12 using storage::FileSystemURLSet;
14 namespace sync_file_system {
16 namespace {
18 typedef LocalFileSyncStatus::OriginAndType OriginAndType;
20 OriginAndType GetOriginAndType(const storage::FileSystemURL& url) {
21 return std::make_pair(url.origin(), url.type());
24 base::FilePath NormalizePath(const base::FilePath& path) {
25 // Ensure |path| has single trailing path-separator, so that we can use
26 // prefix-match to find descendants of |path| in an ordered container.
27 return base::FilePath(path.StripTrailingSeparators().value() +
28 storage::VirtualPath::kSeparator);
31 struct SetKeyHelper {
32 template <typename Iterator>
33 static const base::FilePath& GetKey(Iterator itr) {
34 return *itr;
38 struct MapKeyHelper {
39 template <typename Iterator>
40 static const base::FilePath& GetKey(Iterator itr) {
41 return itr->first;
45 template <typename Container, typename GetKeyHelper>
46 bool ContainsChildOrParent(const Container& paths,
47 const base::FilePath& path,
48 const GetKeyHelper& get_key_helper) {
49 base::FilePath normalized_path = NormalizePath(path);
51 // Check if |paths| has a child of |normalized_path|.
52 // Note that descendants of |normalized_path| are stored right after
53 // |normalized_path| since |normalized_path| has trailing path separator.
54 typename Container::const_iterator upper =
55 paths.upper_bound(normalized_path);
57 if (upper != paths.end() &&
58 normalized_path.IsParent(get_key_helper.GetKey(upper)))
59 return true;
61 // Check if any ancestor of |normalized_path| is in |writing_|.
62 while (true) {
63 if (ContainsKey(paths, normalized_path))
64 return true;
66 if (storage::VirtualPath::IsRootPath(normalized_path))
67 return false;
69 normalized_path =
70 NormalizePath(storage::VirtualPath::DirName(normalized_path));
74 } // namespace
76 LocalFileSyncStatus::LocalFileSyncStatus() {}
78 LocalFileSyncStatus::~LocalFileSyncStatus() {}
80 void LocalFileSyncStatus::StartWriting(const FileSystemURL& url) {
81 DCHECK(CalledOnValidThread());
82 DCHECK(!IsChildOrParentSyncing(url));
83 writing_[GetOriginAndType(url)][NormalizePath(url.path())]++;
86 void LocalFileSyncStatus::EndWriting(const FileSystemURL& url) {
87 DCHECK(CalledOnValidThread());
88 base::FilePath normalized_path = NormalizePath(url.path());
89 OriginAndType origin_and_type = GetOriginAndType(url);
91 int count = --writing_[origin_and_type][normalized_path];
92 if (count == 0) {
93 writing_[origin_and_type].erase(normalized_path);
94 if (writing_[origin_and_type].empty())
95 writing_.erase(origin_and_type);
96 FOR_EACH_OBSERVER(Observer, observer_list_, OnSyncEnabled(url));
100 void LocalFileSyncStatus::StartSyncing(const FileSystemURL& url) {
101 DCHECK(CalledOnValidThread());
102 DCHECK(!IsChildOrParentWriting(url));
103 DCHECK(!IsChildOrParentSyncing(url));
104 syncing_[GetOriginAndType(url)].insert(NormalizePath(url.path()));
107 void LocalFileSyncStatus::EndSyncing(const FileSystemURL& url) {
108 DCHECK(CalledOnValidThread());
109 base::FilePath normalized_path = NormalizePath(url.path());
110 OriginAndType origin_and_type = GetOriginAndType(url);
112 syncing_[origin_and_type].erase(normalized_path);
113 if (syncing_[origin_and_type].empty())
114 syncing_.erase(origin_and_type);
115 FOR_EACH_OBSERVER(Observer, observer_list_, OnSyncEnabled(url));
116 FOR_EACH_OBSERVER(Observer, observer_list_, OnWriteEnabled(url));
119 bool LocalFileSyncStatus::IsWriting(const FileSystemURL& url) const {
120 DCHECK(CalledOnValidThread());
121 return IsChildOrParentWriting(url);
124 bool LocalFileSyncStatus::IsWritable(const FileSystemURL& url) const {
125 DCHECK(CalledOnValidThread());
126 return !IsChildOrParentSyncing(url);
129 bool LocalFileSyncStatus::IsSyncable(const FileSystemURL& url) const {
130 DCHECK(CalledOnValidThread());
131 return !IsChildOrParentSyncing(url) && !IsChildOrParentWriting(url);
134 void LocalFileSyncStatus::AddObserver(Observer* observer) {
135 DCHECK(CalledOnValidThread());
136 observer_list_.AddObserver(observer);
139 void LocalFileSyncStatus::RemoveObserver(Observer* observer) {
140 DCHECK(CalledOnValidThread());
141 observer_list_.RemoveObserver(observer);
144 bool LocalFileSyncStatus::IsChildOrParentWriting(
145 const FileSystemURL& url) const {
146 DCHECK(CalledOnValidThread());
148 URLBucket::const_iterator found = writing_.find(GetOriginAndType(url));
149 if (found == writing_.end())
150 return false;
151 return ContainsChildOrParent(found->second, url.path(),
152 MapKeyHelper());
155 bool LocalFileSyncStatus::IsChildOrParentSyncing(
156 const FileSystemURL& url) const {
157 DCHECK(CalledOnValidThread());
158 URLSet::const_iterator found = syncing_.find(GetOriginAndType(url));
159 if (found == syncing_.end())
160 return false;
161 return ContainsChildOrParent(found->second, url.path(),
162 SetKeyHelper());
165 } // namespace sync_file_system