xref: /haiku/src/servers/launch/VolumeWatcher.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
1 /*
2  * Copyright 2015, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 //!	The backbone of the VolumeMountedEvent.
8 
9 
10 #include "VolumeWatcher.h"
11 
12 #include <Application.h>
13 #include <Autolock.h>
14 #include <NodeMonitor.h>
15 
16 
17 static BLocker sLocker("volume watcher");
18 static VolumeWatcher* sWatcher;
19 
20 
21 VolumeListener::~VolumeListener()
22 {
23 }
24 
25 
26 // #pragma mark -
27 
28 
29 VolumeWatcher::VolumeWatcher()
30 	:
31 	BHandler("volume watcher")
32 {
33 	if (be_app->Lock()) {
34 		be_app->AddHandler(this);
35 
36 		watch_node(NULL, B_WATCH_MOUNT, this);
37 		be_app->Unlock();
38 	}
39 }
40 
41 
42 VolumeWatcher::~VolumeWatcher()
43 {
44 	if (be_app->Lock()) {
45 		stop_watching(this);
46 
47 		be_app->RemoveHandler(this);
48 		be_app->Unlock();
49 	}
50 }
51 
52 
53 void
54 VolumeWatcher::AddListener(VolumeListener* listener)
55 {
56 	BAutolock lock(sLocker);
57 	fListeners.AddItem(listener);
58 }
59 
60 
61 void
62 VolumeWatcher::RemoveListener(VolumeListener* listener)
63 {
64 	BAutolock lock(sLocker);
65 	fListeners.RemoveItem(listener);
66 }
67 
68 
69 int32
70 VolumeWatcher::CountListeners() const
71 {
72 	BAutolock lock(sLocker);
73 	return fListeners.CountItems();
74 }
75 
76 
77 void
78 VolumeWatcher::MessageReceived(BMessage* message)
79 {
80 	switch (message->what) {
81 		case B_NODE_MONITOR:
82 		{
83 			int32 opcode = message->GetInt32("opcode", -1);
84 			if (opcode == B_DEVICE_MOUNTED) {
85 				dev_t device;
86 				if (message->FindInt32("new device", &device) == B_OK) {
87 					BAutolock lock(sLocker);
88 					for (int32 i = 0; i < fListeners.CountItems(); i++) {
89 						fListeners.ItemAt(i)->VolumeMounted(device);
90 					}
91 				}
92 			} else if (opcode == B_DEVICE_UNMOUNTED) {
93 				dev_t device;
94 				if (message->FindInt32("device", &device) == B_OK) {
95 					BAutolock lock(sLocker);
96 					for (int32 i = 0; i < fListeners.CountItems(); i++) {
97 						fListeners.ItemAt(i)->VolumeUnmounted(device);
98 					}
99 				}
100 			}
101 			break;
102 		}
103 	}
104 }
105 
106 
107 /*static*/ void
108 VolumeWatcher::Register(VolumeListener* listener)
109 {
110 	BAutolock lock(sLocker);
111 	if (sWatcher == NULL)
112 		sWatcher = new VolumeWatcher();
113 
114 	sWatcher->AddListener(listener);
115 }
116 
117 
118 /*static*/ void
119 VolumeWatcher::Unregister(VolumeListener* listener)
120 {
121 	BAutolock lock(sLocker);
122 	sWatcher->RemoveListener(listener);
123 
124 	if (sWatcher->CountListeners() == 0)
125 		delete sWatcher;
126 }
127