1 /* 2 * Copyright 2008, François Revol, revol@free.fr. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "SystemInfoHandler.h" 8 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 13 #include <Clipboard.h> 14 #include <Handler.h> 15 #include <Input.h> 16 #include <List.h> 17 #include <MediaRoster.h> 18 #include <Messenger.h> 19 #include <Roster.h> 20 21 22 SystemInfoHandler::SystemInfoHandler() 23 : BHandler("SystemInfoHandler") 24 { 25 fRunningApps = 0; 26 fClipboardSize = 0; 27 fClipboardTextSize = 0; 28 fMediaNodes = 0; 29 fMediaConnections = 0; 30 fMediaBuffers = 0; 31 } 32 33 34 SystemInfoHandler::~SystemInfoHandler() 35 { 36 } 37 38 39 status_t 40 SystemInfoHandler::Archive(BMessage* data, bool deep) const 41 { 42 // we don't want ourselves to be archived at all... 43 // return BHandler::Archive(data, deep); 44 return B_OK; 45 } 46 47 48 void 49 SystemInfoHandler::StartWatching() 50 { 51 status_t status; 52 fRunningApps = 0; 53 fClipboardSize = 0; 54 fClipboardTextSize = 0; 55 fMediaNodes = 0; 56 fMediaConnections = 0; 57 fMediaBuffers = 0; 58 59 // running applications count 60 BList teamList; 61 if (be_roster) { 62 be_roster->StartWatching(BMessenger(this), 63 B_REQUEST_LAUNCHED | B_REQUEST_QUIT); 64 be_roster->GetAppList(&teamList); 65 fRunningApps = teamList.CountItems(); 66 teamList.MakeEmpty(); 67 } 68 69 // useless clipboard size 70 if (be_clipboard) { 71 be_clipboard->StartWatching(BMessenger(this)); 72 _UpdateClipboardData(); 73 } 74 75 if (BMediaRoster::Roster(&status) && (status >= B_OK)) { 76 BMediaRoster::Roster()->StartWatching(BMessenger(this), B_MEDIA_NODE_CREATED); 77 BMediaRoster::Roster()->StartWatching(BMessenger(this), B_MEDIA_NODE_DELETED); 78 BMediaRoster::Roster()->StartWatching(BMessenger(this), B_MEDIA_CONNECTION_MADE); 79 BMediaRoster::Roster()->StartWatching(BMessenger(this), B_MEDIA_CONNECTION_BROKEN); 80 BMediaRoster::Roster()->StartWatching(BMessenger(this), B_MEDIA_BUFFER_CREATED); 81 BMediaRoster::Roster()->StartWatching(BMessenger(this), B_MEDIA_BUFFER_DELETED); 82 // XXX: this won't survive a media_server restart... 83 84 live_node_info nodeInfo; // I just need one 85 int32 nodeCount = 1; 86 if (BMediaRoster::Roster()->GetLiveNodes(&nodeInfo, &nodeCount)) { 87 if (nodeCount > 0) 88 fMediaNodes = (uint32)nodeCount; 89 // TODO: retry with an array, and use GetNodeInput/Output 90 // to find initial connection count 91 } 92 // TODO: get initial buffer count 93 94 } 95 96 // doesn't work on R5 97 watch_input_devices(BMessenger(this), true); 98 } 99 100 101 void 102 SystemInfoHandler::StopWatching() 103 { 104 status_t status; 105 watch_input_devices(BMessenger(this), false); 106 if (BMediaRoster::Roster(&status) && (status >= B_OK)) { 107 BMediaRoster::Roster()->StopWatching(BMessenger(this), B_MEDIA_NODE_CREATED); 108 BMediaRoster::Roster()->StopWatching(BMessenger(this), B_MEDIA_NODE_DELETED); 109 BMediaRoster::Roster()->StopWatching(BMessenger(this), B_MEDIA_CONNECTION_MADE); 110 BMediaRoster::Roster()->StopWatching(BMessenger(this), B_MEDIA_CONNECTION_BROKEN); 111 BMediaRoster::Roster()->StopWatching(BMessenger(this), B_MEDIA_BUFFER_CREATED); 112 BMediaRoster::Roster()->StopWatching(BMessenger(this), B_MEDIA_BUFFER_DELETED); 113 } 114 if (be_clipboard) 115 be_clipboard->StopWatching(BMessenger(this)); 116 if (be_roster) 117 be_roster->StopWatching(BMessenger(this)); 118 } 119 120 121 void 122 SystemInfoHandler::MessageReceived(BMessage* message) 123 { 124 switch (message->what) { 125 case B_SOME_APP_LAUNCHED: 126 fRunningApps++; 127 // TODO: maybe resync periodically in case we miss one 128 break; 129 case B_SOME_APP_QUIT: 130 fRunningApps--; 131 // TODO: maybe resync periodically in case we miss one 132 break; 133 case B_CLIPBOARD_CHANGED: 134 _UpdateClipboardData(); 135 break; 136 case B_MEDIA_NODE_CREATED: 137 fMediaNodes++; 138 break; 139 case B_MEDIA_NODE_DELETED: 140 fMediaNodes--; 141 break; 142 case B_MEDIA_CONNECTION_MADE: 143 fMediaConnections++; 144 break; 145 case B_MEDIA_CONNECTION_BROKEN: 146 fMediaConnections--; 147 break; 148 case B_MEDIA_BUFFER_CREATED: 149 fMediaBuffers++; 150 break; 151 case B_MEDIA_BUFFER_DELETED: 152 fMediaBuffers--; 153 break; 154 default: 155 message->PrintToStream(); 156 BHandler::MessageReceived(message); 157 } 158 } 159 160 161 uint32 162 SystemInfoHandler::RunningApps() const 163 { 164 return fRunningApps; 165 } 166 167 168 uint32 169 SystemInfoHandler::ClipboardSize() const 170 { 171 return fClipboardSize; 172 } 173 174 175 uint32 176 SystemInfoHandler::ClipboardTextSize() const 177 { 178 return fClipboardTextSize; 179 } 180 181 182 uint32 183 SystemInfoHandler::MediaNodes() const 184 { 185 return fMediaNodes; 186 } 187 188 189 uint32 190 SystemInfoHandler::MediaConnections() const 191 { 192 return fMediaConnections; 193 } 194 195 196 uint32 197 SystemInfoHandler::MediaBuffers() const 198 { 199 return fMediaBuffers; 200 } 201 202 203 void 204 SystemInfoHandler::_UpdateClipboardData() 205 { 206 fClipboardSize = 0; 207 fClipboardTextSize = 0; 208 209 if (be_clipboard == NULL || !be_clipboard->Lock()) 210 return; 211 212 BMessage* data = be_clipboard->Data(); 213 if (data) { 214 ssize_t size = data->FlattenedSize(); 215 fClipboardSize = size < 0 ? 0 : (uint32)size; 216 217 const void* text; 218 ssize_t textSize; 219 if (data->FindData("text/plain", B_MIME_TYPE, &text, &textSize) >= B_OK) 220 fClipboardTextSize = textSize; 221 } 222 223 be_clipboard->Unlock(); 224 } 225 226