xref: /haiku/src/apps/activitymonitor/SystemInfoHandler.cpp (revision f2b4344867e97c3f4e742a1b4a15e6879644601a)
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