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
17static BLocker sLocker("volume watcher");
18static VolumeWatcher* sWatcher;
19
20
21VolumeListener::~VolumeListener()
22{
23}
24
25
26// #pragma mark -
27
28
29VolumeWatcher::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
42VolumeWatcher::~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
53void
54VolumeWatcher::AddListener(VolumeListener* listener)
55{
56	BAutolock lock(sLocker);
57	fListeners.AddItem(listener);
58}
59
60
61void
62VolumeWatcher::RemoveListener(VolumeListener* listener)
63{
64	BAutolock lock(sLocker);
65	fListeners.RemoveItem(listener);
66}
67
68
69int32
70VolumeWatcher::CountListeners() const
71{
72	BAutolock lock(sLocker);
73	return fListeners.CountItems();
74}
75
76
77void
78VolumeWatcher::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
108VolumeWatcher::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
119VolumeWatcher::Unregister(VolumeListener* listener)
120{
121	BAutolock lock(sLocker);
122	sWatcher->RemoveListener(listener);
123
124	if (sWatcher->CountListeners() == 0)
125		delete sWatcher;
126}
127