xref: /haiku/src/tests/kits/app/broster/testapps/RosterBroadcastTestApp1.cpp (revision 2f470aec1c92ce6917b8a903e343795dc77af41f)
1 // RosterBroadcastTestApp1.cpp
2 
3 #include <stdio.h>
4 #include <string.h>
5 
6 #include <Application.h>
7 #include <Entry.h>
8 #include <File.h>
9 #include <Message.h>
10 #include <Messenger.h>
11 #include <OS.h>
12 #include <Resources.h>
13 #include <Roster.h>
14 #include <String.h>
15 
16 #include "RosterTestAppDefs.h"
17 
18 BMessenger unitTesterMessenger;
19 
20 static const char *kUnitTesterSignature
21 	= "application/x-vnd.obos-roster-broadcast-test";
22 
23 // init_unit_tester_messenger
24 static
25 status_t
26 init_unit_tester_messenger()
27 {
28 	// Unfortunately BeOS R5 doesn't update the roster-side information about
29 	// the app looper's port ID once a BApplication has been created, and
30 	// thus we can't construct a BMessenger targeting a BApplication created
31 	// after the first one using the signature/team ID constructor.
32 	// We need to do some hacking.
33 	struct fake_messenger {
34 		port_id	fPort;
35 		int32	fHandlerToken;
36 		team_id	fTeam;
37 		int32	extra0;
38 		int32	extra1;
39 		bool	fPreferredTarget;
40 		bool	extra2;
41 		bool	extra3;
42 		bool	extra4;
43 	} &fake = *(fake_messenger*)&unitTesterMessenger;
44 	// get team
45 	status_t error = B_OK;
46 	fake.fTeam = BRoster().TeamFor(kUnitTesterSignature);
47 	if (fake.fTeam < 0)
48 		error = fake.fTeam;
49 	// find app looper port
50 	bool found = false;
51 	int32 cookie = 0;
52 	port_info info;
53 	while (error == B_OK && !found) {
54 		error = get_next_port_info(fake.fTeam, &cookie, &info);
55 		found = (error == B_OK && !strcmp("AppLooperPort", info.name));
56 	}
57 	// init messenger
58 	if (error == B_OK) {
59 		fake.fPort = info.port;
60 		fake.fHandlerToken = 0;
61 		fake.fPreferredTarget = true;
62 	}
63 	return error;
64 }
65 
66 // get_app_path
67 status_t
68 get_app_path(char *buffer)
69 {
70 	status_t error = (buffer ? B_OK : B_BAD_VALUE);
71 	image_info info;
72 	int32 cookie = 0;
73 	bool found = false;
74 	if (error == B_OK) {
75 		while (!found && get_next_image_info(0, &cookie, &info) == B_OK) {
76 			if (info.type == B_APP_IMAGE) {
77 				strncpy(buffer, info.name, B_PATH_NAME_LENGTH);
78 				buffer[B_PATH_NAME_LENGTH] = 0;
79 				found = true;
80 			}
81 		}
82 	}
83 	if (error == B_OK && !found)
84 		error = B_ENTRY_NOT_FOUND;
85 	return error;
86 }
87 
88 // TestApp
89 class TestApp : public BApplication {
90 public:
91 	TestApp(const char *signature) : BApplication(signature)
92 	{
93 	}
94 
95 	virtual void ArgvReceived(int32 argc, char **argv)
96 	{
97 		BMessage message(MSG_ARGV_RECEIVED);
98 		message.AddInt32("argc", argc);
99 		for (int32 i = 0; i < argc; i++)
100 			message.AddString("argv", argv[i]);
101 		unitTesterMessenger.SendMessage(&message);
102 	}
103 
104 	virtual void RefsReceived(BMessage *_message)
105 	{
106 		BMessage message(*_message);
107 		message.what = MSG_REFS_RECEIVED;
108 		unitTesterMessenger.SendMessage(&message);
109 	}
110 
111 	virtual void MessageReceived(BMessage *_message)
112 	{
113 		BMessage message(MSG_MESSAGE_RECEIVED);
114 		message.AddMessage("message", _message);
115 		message.AddInt32("sender", _message->ReturnAddress().Team());
116 		if (_message->what == MSG_1)
117 			message.AddBool("don't ignore", true);
118 		unitTesterMessenger.SendMessage(&message);
119 		if (_message->what == MSG_1) {
120 //			_message->SendReply(MSG_2);
121 			BMessage reply(MSG_2);
122 			_message->SendReply(&reply, be_app_messenger);
123 		}
124 	}
125 
126 	virtual bool QuitRequested()
127 	{
128 		unitTesterMessenger.SendMessage(MSG_QUIT_REQUESTED);
129 		return true;
130 	}
131 
132 	virtual void ReadyToRun()
133 	{
134 		unitTesterMessenger.SendMessage(MSG_READY_TO_RUN);
135 	}
136 };
137 
138 // main
139 int
140 main(int argc, char **argv)
141 {
142 	// find app file and get signature from resources
143 	char path[B_PATH_NAME_LENGTH];
144 	status_t error = get_app_path(path);
145 	char signature[B_MIME_TYPE_LENGTH];
146 	if (error == B_OK) {
147 		// init app file
148 		BFile file;
149 		error = file.SetTo(path, B_READ_ONLY);
150 		// get signature
151 		BString signatureString;
152 		if (error == B_OK) {
153 			if (file.ReadAttrString("signature", &signatureString) == B_OK
154 				&& signatureString.Length() > 0) {
155 				strcpy(signature, signatureString.String());
156 			} else
157 				strcpy(signature, kDefaultTestAppSignature);
158 		} else
159 			printf("ERROR: Couldn't init app file: %s\n", strerror(error));
160 	} else
161 		printf("ERROR: Couldn't get app ref: %s\n", strerror(error));
162 	// create the app
163 	TestApp *app = NULL;
164 	if (error == B_OK) {
165 		app = new TestApp(signature);
166 //		unitTesterMessenger = BMessenger(kUnitTesterSignature);
167 		error = init_unit_tester_messenger();
168 		if (error != B_OK)
169 			printf("ERROR: Couldn't init messenger: %s\n", strerror(error));
170 		// send started message
171 		BMessage message(MSG_STARTED);
172 		message.AddString("path", path);
173 		unitTesterMessenger.SendMessage(&message);
174 		// send main() args message
175 		BMessage argsMessage(MSG_MAIN_ARGS);
176 		argsMessage.AddInt32("argc", argc);
177 		for (int i = 0; i < argc; i++)
178 			argsMessage.AddString("argv", argv[i]);
179 		unitTesterMessenger.SendMessage(&argsMessage);
180 		// run the app
181 		app->Run();
182 		delete app;
183 		// send terminated message
184 		unitTesterMessenger.SendMessage(MSG_TERMINATED);
185 	}
186 	return 0;
187 }
188 
189