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