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