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