xref: /haiku/src/tests/kits/app/broster/testapps/RosterLaunchTestApp1.cpp (revision 1214ef1b2100f2b3299fc9d8d6142e46f70a4c3f)
1 // RosterLaunchTestApp1.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-launch-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 		unitTesterMessenger.SendMessage(&message);
117 	}
118 
119 	virtual bool QuitRequested()
120 	{
121 		unitTesterMessenger.SendMessage(MSG_QUIT_REQUESTED);
122 		return true;
123 	}
124 
125 	virtual void ReadyToRun()
126 	{
127 		unitTesterMessenger.SendMessage(MSG_READY_TO_RUN);
128 	}
129 };
130 
131 // main
132 int
133 main(int argc, char **argv)
134 {
135 	// find app file and get signature from resources
136 	char path[B_PATH_NAME_LENGTH];
137 	status_t error = get_app_path(path);
138 	char signature[B_MIME_TYPE_LENGTH];
139 	if (error == B_OK) {
140 		// init app file
141 		BFile file;
142 		error = file.SetTo(path, B_READ_ONLY);
143 		// get signature
144 		BString signatureString;
145 		if (error == B_OK) {
146 			if (file.ReadAttrString("signature", &signatureString) == B_OK
147 				&& signatureString.Length() > 0) {
148 				strcpy(signature, signatureString.String());
149 			} else
150 				strcpy(signature, kDefaultTestAppSignature);
151 		} else
152 			printf("ERROR: Couldn't init app file: %s\n", strerror(error));
153 	} else
154 		printf("ERROR: Couldn't get app ref: %s\n", strerror(error));
155 	// create the app
156 	TestApp *app = NULL;
157 	if (error == B_OK) {
158 		app = new TestApp(signature);
159 //		unitTesterMessenger = BMessenger(kUnitTesterSignature);
160 		error = init_unit_tester_messenger();
161 		if (error != B_OK)
162 			printf("ERROR: Couldn't init messenger: %s\n", strerror(error));
163 		// send started message
164 		BMessage message(MSG_STARTED);
165 		message.AddString("path", path);
166 		unitTesterMessenger.SendMessage(&message);
167 		// send main() args message
168 		BMessage argsMessage(MSG_MAIN_ARGS);
169 		argsMessage.AddInt32("argc", argc);
170 		for (int i = 0; i < argc; i++)
171 			argsMessage.AddString("argv", argv[i]);
172 		unitTesterMessenger.SendMessage(&argsMessage);
173 		// run the app
174 		app->Run();
175 		delete app;
176 		// send terminated message
177 		unitTesterMessenger.SendMessage(MSG_TERMINATED);
178 	}
179 	return 0;
180 }
181 
182