mount_library.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2009 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/chromeos/cros/mount_library.h"
6
7#include "base/message_loop.h"
8#include "base/string_util.h"
9#include "chrome/browser/chromeos/cros/cros_library.h"
10#include "content/browser/browser_thread.h"
11
12namespace chromeos {
13
14class MountLibraryImpl : public MountLibrary {
15 public:
16  MountLibraryImpl() : mount_status_connection_(NULL) {
17    if (CrosLibrary::Get()->EnsureLoaded()) {
18      Init();
19    } else {
20      LOG(ERROR) << "Cros Library has not been loaded";
21    }
22  }
23
24  ~MountLibraryImpl() {
25    if (mount_status_connection_) {
26      DisconnectMountStatus(mount_status_connection_);
27    }
28  }
29
30  void AddObserver(Observer* observer) {
31    observers_.AddObserver(observer);
32  }
33
34  void RemoveObserver(Observer* observer) {
35    observers_.RemoveObserver(observer);
36  }
37
38  bool MountPath(const char* device_path) {
39    return MountDevicePath(device_path);
40  }
41
42  bool IsBootPath(const char* device_path) {
43    return IsBootDevicePath(device_path);
44  }
45
46  const DiskVector& disks() const { return disks_; }
47
48 private:
49  void ParseDisks(const MountStatus& status) {
50    disks_.clear();
51    for (int i = 0; i < status.size; i++) {
52      std::string path;
53      std::string mountpath;
54      std::string systempath;
55      bool parent;
56      bool hasmedia;
57      if (status.disks[i].path != NULL) {
58        path = status.disks[i].path;
59      }
60      if (status.disks[i].mountpath != NULL) {
61        mountpath = status.disks[i].mountpath;
62      }
63      if (status.disks[i].systempath != NULL) {
64        systempath = status.disks[i].systempath;
65      }
66      parent = status.disks[i].isparent;
67      hasmedia = status.disks[i].hasmedia;
68      disks_.push_back(Disk(path,
69                            mountpath,
70                            systempath,
71                            parent,
72                            hasmedia));
73    }
74  }
75
76  static void MountStatusChangedHandler(void* object,
77                                        const MountStatus& status,
78                                        MountEventType evt,
79                                        const  char* path) {
80    MountLibraryImpl* mount = static_cast<MountLibraryImpl*>(object);
81    std::string devicepath = path;
82    mount->ParseDisks(status);
83    mount->UpdateMountStatus(status, evt, devicepath);
84  }
85
86  void Init() {
87    // Getting the monitor status so that the daemon starts up.
88    MountStatus* mount = RetrieveMountInformation();
89    if (!mount) {
90      LOG(ERROR) << "Failed to retrieve mount information";
91      return;
92    }
93    ParseDisks(*mount);
94    FreeMountStatus(mount);
95
96    mount_status_connection_ = MonitorMountStatus(
97        &MountStatusChangedHandler, this);
98  }
99
100  void UpdateMountStatus(const MountStatus& status,
101                                       MountEventType evt,
102                                       const std::string& path) {
103    // Make sure we run on UI thread.
104    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
105
106    FOR_EACH_OBSERVER(
107        Observer, observers_, MountChanged(this, evt, path));
108  }
109  ObserverList<Observer> observers_;
110
111  // A reference to the  mount api, to allow callbacks when the mount
112  // status changes.
113  MountStatusConnection mount_status_connection_;
114
115  // The list of disks found.
116  DiskVector disks_;
117
118  DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl);
119};
120
121class MountLibraryStubImpl : public MountLibrary {
122 public:
123  MountLibraryStubImpl() {}
124  virtual ~MountLibraryStubImpl() {}
125
126  // MountLibrary overrides.
127  virtual void AddObserver(Observer* observer) {}
128  virtual void RemoveObserver(Observer* observer) {}
129  virtual const DiskVector& disks() const { return disks_; }
130  virtual bool MountPath(const char* device_path) { return false; }
131  virtual bool IsBootPath(const char* device_path) { return true; }
132
133 private:
134  // The list of disks found.
135  DiskVector disks_;
136
137  DISALLOW_COPY_AND_ASSIGN(MountLibraryStubImpl);
138};
139
140// static
141MountLibrary* MountLibrary::GetImpl(bool stub) {
142  if (stub)
143    return new MountLibraryStubImpl();
144  else
145    return new MountLibraryImpl();
146}
147
148}  // namespace chromeos
149
150// Allows InvokeLater without adding refcounting. This class is a Singleton and
151// won't be deleted until it's last InvokeLater is run.
152DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::MountLibraryImpl);
153
154