OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/cros/mount_library.h" | 5 #include "chrome/browser/chromeos/cros/mount_library.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "chrome/browser/chrome_thread.h" | 9 #include "chrome/browser/chrome_thread.h" |
10 #include "chrome/browser/chromeos/cros/cros_library.h" | 10 #include "chrome/browser/chromeos/cros/cros_library.h" |
11 | 11 |
| 12 namespace chromeos { |
| 13 |
| 14 class 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(ChromeThread::CurrentlyOn(ChromeThread::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 |
| 117 class 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 |
| 136 MountLibrary* MountLibrary::GetImpl(bool stub) { |
| 137 if (stub) |
| 138 return new MountLibraryStubImpl(); |
| 139 else |
| 140 return new MountLibraryImpl(); |
| 141 } |
| 142 |
| 143 } // namespace chromeos |
| 144 |
12 // Allows InvokeLater without adding refcounting. This class is a Singleton and | 145 // Allows InvokeLater without adding refcounting. This class is a Singleton and |
13 // won't be deleted until it's last InvokeLater is run. | 146 // won't be deleted until it's last InvokeLater is run. |
14 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::MountLibraryImpl); | 147 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::MountLibraryImpl); |
15 | 148 |
16 namespace chromeos { | |
17 | |
18 void MountLibraryImpl::AddObserver(Observer* observer) { | |
19 observers_.AddObserver(observer); | |
20 } | |
21 | |
22 void MountLibraryImpl::RemoveObserver(Observer* observer) { | |
23 observers_.RemoveObserver(observer); | |
24 } | |
25 | |
26 bool MountLibraryImpl::MountPath(const char* device_path) { | |
27 return MountDevicePath(device_path); | |
28 } | |
29 | |
30 void MountLibraryImpl::ParseDisks(const MountStatus& status) { | |
31 disks_.clear(); | |
32 for (int i = 0; i < status.size; i++) { | |
33 std::string path; | |
34 std::string mountpath; | |
35 std::string systempath; | |
36 bool parent; | |
37 bool hasmedia; | |
38 if (status.disks[i].path != NULL) { | |
39 path = status.disks[i].path; | |
40 } | |
41 if (status.disks[i].mountpath != NULL) { | |
42 mountpath = status.disks[i].mountpath; | |
43 } | |
44 if (status.disks[i].systempath != NULL) { | |
45 systempath = status.disks[i].systempath; | |
46 } | |
47 parent = status.disks[i].isparent; | |
48 hasmedia = status.disks[i].hasmedia; | |
49 disks_.push_back(Disk(path, | |
50 mountpath, | |
51 systempath, | |
52 parent, | |
53 hasmedia)); | |
54 } | |
55 } | |
56 | |
57 MountLibraryImpl::MountLibraryImpl() : mount_status_connection_(NULL) { | |
58 if (CrosLibrary::Get()->EnsureLoaded()) { | |
59 Init(); | |
60 } else { | |
61 LOG(ERROR) << "Cros Library has not been loaded"; | |
62 } | |
63 } | |
64 | |
65 MountLibraryImpl::~MountLibraryImpl() { | |
66 if (mount_status_connection_) { | |
67 DisconnectMountStatus(mount_status_connection_); | |
68 } | |
69 } | |
70 | |
71 // static | |
72 void MountLibraryImpl::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 MountLibraryImpl::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 MountLibraryImpl::UpdateMountStatus(const MountStatus& status, | |
97 MountEventType evt, | |
98 const std::string& path) { | |
99 // Make sure we run on UI thread. | |
100 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | |
101 | |
102 FOR_EACH_OBSERVER(Observer, observers_, MountChanged(this, evt, path)); | |
103 } | |
104 | |
105 } // namespace chromeos | |
OLD | NEW |