sbBaseFileSystemWatcher.cpp
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2009 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25 */
26 
28 
29 #include <nsIUUIDGenerator.h>
30 #include <nsComponentManagerUtils.h>
31 #include <nsServiceManagerUtils.h>
32 
33 #include <sbDebugUtils.h>
34 
41 
43 {
44  SB_PRLOG_SETUP(sbBaseFSWatcher);
45 
46  mIsRecursive = PR_TRUE;
47  mIsWatching = PR_FALSE;
48  mIsSupported = PR_TRUE;
49  mShouldLoadSession = PR_FALSE;
50  mTree = nsnull;
51 }
52 
54 {
55  if (mTree) {
56  nsresult SB_UNUSED_IN_RELEASE(rv) = mTree->ClearListener();
57  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Error could not clear tree listener!");
58  }
59 }
60 
61 //------------------------------------------------------------------------------
62 // sbIFileSystemWatcher
63 
64 NS_IMETHODIMP
66  const nsAString & aRootPath,
67  PRBool aIsRecursive)
68 {
69  NS_ENSURE_ARG_POINTER(aListener);
70 
71  TRACE("%s: initing, will watch [%s]",
72  __FUNCTION__,
73  NS_ConvertUTF16toUTF8(aRootPath).get());
74 
75  mListener = aListener;
76  mWatchPath.Assign(aRootPath);
77  mIsRecursive = PR_TRUE;
78  mIsWatching = PR_FALSE;
79  mShouldLoadSession = PR_FALSE;
80 
81  // Generate a session GUID.
82  nsresult rv;
83  nsCOMPtr<nsIUUIDGenerator> uuidGen =
84  do_GetService("@mozilla.org/uuid-generator;1", &rv);
85  NS_ENSURE_SUCCESS(rv, rv);
86 
87  rv = uuidGen->GenerateUUIDInPlace(&mSessionID);
88  NS_ENSURE_SUCCESS(rv, rv);
89 
90  return NS_OK;
91 }
92 
93 NS_IMETHODIMP
94 sbBaseFileSystemWatcher::InitWithSession(const nsACString & aSessionGuid,
95  sbIFileSystemListener *aListener)
96 {
97  NS_ENSURE_ARG_POINTER(aListener);
98 
99  mIsWatching = PR_FALSE;
100  mListener = aListener;
101 
102  if (!mSessionID.Parse(nsCString(aSessionGuid).get())) {
103  return NS_ERROR_FAILURE;
104  }
105 
106  mShouldLoadSession = PR_TRUE;
107 
108  return NS_OK;
109 }
110 
111 NS_IMETHODIMP
112 sbBaseFileSystemWatcher::StartWatching()
113 {
114  if (!mIsSupported) {
115  return NS_ERROR_NOT_IMPLEMENTED;
116  }
117 
118  if (mIsWatching) {
119  return NS_OK;
120  }
121 
122  TRACE("%s: starting to watch [%s]",
123  __FUNCTION__,
124  NS_ConvertUTF16toUTF8(mWatchPath).get());
125 
126  // Init the tree
127  mTree = new sbFileSystemTree();
128  NS_ENSURE_TRUE(mTree, NS_ERROR_OUT_OF_MEMORY);
129 
130  // Add ourselves as a tree listener
131  nsresult rv = mTree->SetListener(this);
132  NS_ENSURE_SUCCESS(rv, rv);
133 
134  // Build the tree snapshot now, the native file system hooks will be setup
135  // once the tree has been built.
136  if (mShouldLoadSession) {
137  rv = mTree->InitWithTreeSession(mSessionID);
138  NS_ENSURE_SUCCESS(rv, rv);
139  }
140  else {
141  rv = mTree->Init(mWatchPath, mIsRecursive);
142  NS_ENSURE_SUCCESS(rv, rv);
143  }
144 
145  return NS_OK;
146 }
147 
148 NS_IMETHODIMP
149 sbBaseFileSystemWatcher::StopWatching(PRBool aShouldSaveSession)
150 {
151  nsRefPtr<sbBaseFileSystemWatcher> kungFuDeathGrip(this);
152  mIsWatching = PR_FALSE;
153 
154  // Don't worry about checking the result from the listener.
155  mListener->OnWatcherStopped();
156 
157  if (aShouldSaveSession) {
158  nsresult rv = mTree->SaveTreeSession(mSessionID);
159  NS_ENSURE_SUCCESS(rv, rv);
160  }
161 
162  return NS_OK;
163 }
164 
165 NS_IMETHODIMP
166 sbBaseFileSystemWatcher::DeleteSession(const nsACString & aSessionGuid)
167 {
168  nsID sessionID;
169  if (!sessionID.Parse(nsCString(aSessionGuid).get())) {
170  return NS_ERROR_FAILURE;
171  }
172 
173  nsresult rv = sbFileSystemTreeState::DeleteSavedTreeState(sessionID);
174  NS_ENSURE_SUCCESS(rv, rv);
175 
176  return NS_OK;
177 }
178 
179 NS_IMETHODIMP
180 sbBaseFileSystemWatcher::GetIsWatching(PRBool *aIsWatching)
181 {
182  NS_ENSURE_ARG_POINTER(aIsWatching);
183  *aIsWatching = mIsWatching;
184  return NS_OK;
185 }
186 
187 NS_IMETHODIMP
188 sbBaseFileSystemWatcher::GetWatchPath(nsAString & aWatchPath)
189 {
190  aWatchPath.Assign(mWatchPath);
191  return NS_OK;
192 }
193 
194 NS_IMETHODIMP
195 sbBaseFileSystemWatcher::GetSessionGuid(nsACString & aSessionGuid)
196 {
197  char idChars[NSID_LENGTH];
198  mSessionID.ToProvidedString(idChars);
199  aSessionGuid.Assign(idChars);
200  return NS_OK;
201 }
202 
203 NS_IMETHODIMP
204 sbBaseFileSystemWatcher::GetIsSupported(PRBool *aIsSupported)
205 {
206  NS_ENSURE_ARG_POINTER(aIsSupported);
207  *aIsSupported = mIsSupported;
208  return NS_OK;
209 }
210 
211 //------------------------------------------------------------------------------
212 // sbFileSystemTreeListener
213 
214 NS_IMETHODIMP
215 sbBaseFileSystemWatcher::OnChangeFound(const nsAString & aChangePath,
216  EChangeType aChangeType)
217 {
218  nsresult rv;
219 
220  TRACE("%s: Found change in %s of type %s",
221  __FUNCTION__,
222  NS_ConvertUTF16toUTF8(aChangePath).get(),
223  (aChangeType == eChanged) ? "change" :
224  (aChangeType == eAdded) ? "add" :
225  (aChangeType == eRemoved) ? "removed" :
226  "unknown");
227  switch (aChangeType) {
228  case eChanged:
229  rv = mListener->OnFileSystemChanged(aChangePath);
230  break;
231  case eAdded:
232  rv = mListener->OnFileSystemAdded(aChangePath);
233  break;
234  case eRemoved:
235  rv = mListener->OnFileSystemRemoved(aChangePath);
236  break;
237  default:
238  rv = NS_ERROR_UNEXPECTED;
239  }
240 
241  return rv;
242 }
243 
244 NS_IMETHODIMP
245 sbBaseFileSystemWatcher::OnTreeReady(const nsAString & aTreeRootPath,
246  sbStringArray & aDirPathArray)
247 {
248  // Return fail here - since the implementor needs to implement this to start
249  // its native file-system event system.
250  return NS_ERROR_NOT_IMPLEMENTED;
251 }
252 
253 NS_IMETHODIMP
255 {
256  // This callback will be notified before the tree is ready if the event
257  // occurs. When this event is received, notify the listener of the error
258  // and stop the tree (as per documentation in sbIFileSystemListener.idl).
259  nsresult rv;
261  mWatchPath);
262  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
263  "Could not notify listener of OnWatcherError()!");
264 
265  return StopWatching(PR_FALSE); // do not save the session.
266 }
267 
268 NS_IMETHODIMP
270 {
271  char idChars[NSID_LENGTH];
272  mSessionID.ToProvidedString(idChars);
273  nsString sessionString;
274  sessionString.Append(NS_ConvertASCIItoUTF16(idChars));
276  sessionString);
277 }
278 
nsCOMPtr< sbIFileSystemListener > mListener
#define SB_PRLOG_SETUP(x)
Definition: sbDebugUtils.h:115
return NS_OK
nsTArray< nsString > sbStringArray
NS_DECL_ISUPPORTS NS_DECL_SBIFILESYSTEMWATCHER NS_IMETHOD OnChangeFound(const nsAString &aChangePath, EChangeType aChangeType)
static nsresult DeleteSavedTreeState(const nsID &aSessionID)
nsRefPtr< sbFileSystemTree > mTree
NS_IMPL_THREADSAFE_ISUPPORTS1(sbDeviceCapsCompatibility, sbIDeviceCapsCompatibility) sbDeviceCapsCompatibility
function TRACE(s)
function Init()
const unsigned long ROOT_PATH_MISSING
NS_IMETHOD OnTreeReady(const nsAString &aTreeRootPath, sbStringArray &aDirPathArray)
const unsigned long SESSION_LOAD_ERROR
#define SB_UNUSED_IN_RELEASE(decl)
Definition: sbDebugUtils.h:55