1 // RosterWatchingTestApp1.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-watching-test";
22
23 // init_unit_tester_messenger
24 static
25 status_t
init_unit_tester_messenger()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
get_app_path(char * buffer)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:
TestApp(const char * signature)91 TestApp(const char *signature) : BApplication(signature)
92 {
93 }
94
ArgvReceived(int32 argc,char ** argv)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
RefsReceived(BMessage * _message)104 virtual void RefsReceived(BMessage *_message)
105 {
106 BMessage message(*_message);
107 message.what = MSG_REFS_RECEIVED;
108 unitTesterMessenger.SendMessage(&message);
109 }
110
MessageReceived(BMessage * _message)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 switch (_message->what) {
117 case B_SOME_APP_LAUNCHED:
118 case B_SOME_APP_QUIT:
119 case B_SOME_APP_ACTIVATED:
120 message.AddBool("don't ignore", true);
121 break;
122 }
123 unitTesterMessenger.SendMessage(&message);
124 }
125
QuitRequested()126 virtual bool QuitRequested()
127 {
128 unitTesterMessenger.SendMessage(MSG_QUIT_REQUESTED);
129 return true;
130 }
131
ReadyToRun()132 virtual void ReadyToRun()
133 {
134 unitTesterMessenger.SendMessage(MSG_READY_TO_RUN);
135 }
136 };
137
138 // main
139 int
main(int argc,char ** argv)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