1//	LaunchTesterHelper.h
2
3#ifndef LAUNCH_TESTER_HELPER_H
4#define LAUNCH_TESTER_HELPER_H
5
6#include <Application.h>
7#include <List.h>
8#include <Locker.h>
9#include <MessageQueue.h>
10#include <OS.h>
11
12// LaunchCaller
13class LaunchCaller {
14public:
15	LaunchCaller() : fNext(NULL) {}
16	virtual ~LaunchCaller() { if (fNext) delete fNext;}
17
18	virtual status_t operator()(const char *type, BList *messages, int32 argc,
19								const char **argv, team_id *team) = 0;
20	virtual int32 SupportsMessages() const { return 1; }
21	virtual bool SupportsArgv() const { return SupportsMessages() == 0; }
22	virtual bool SupportsRefs() const { return false; }
23	virtual const entry_ref *Ref() const { return NULL; }
24
25	virtual LaunchCaller &Clone()
26	{
27		LaunchCaller *newCaller = CloneInternal();
28		newCaller->fNext = fNext;
29		fNext = newCaller;
30		return *newCaller;
31	}
32
33	virtual LaunchCaller *CloneInternal() = 0;
34
35private:
36	LaunchCaller	*fNext;
37};
38
39// LaunchContext
40class LaunchContext {
41public:
42	LaunchContext();
43	~LaunchContext();
44
45	status_t operator()(LaunchCaller &caller, const char *type, team_id *team);
46	status_t operator()(LaunchCaller &caller, const char *type,
47						BList *messages, int32 argc, const char **argv,
48						team_id *team);
49
50	void HandleMessage(BMessage *message);
51
52	void Terminate();
53	void TerminateApp(team_id team, bool wait = true);
54
55	team_id TeamAt(int32 index) const;
56
57	BMessenger AppMessengerFor(team_id team) const;
58
59	BMessage *NextMessageFrom(team_id team, int32 &cookie,
60							  bigtime_t *time = NULL);
61	bool CheckNextMessage(LaunchCaller &caller, team_id team, int32 &cookie,
62						  uint32 what);
63	bool CheckMainArgsMessage(LaunchCaller &caller, team_id team,
64							  int32 &cookie, const entry_ref *appRef,
65							  bool useRef = true);
66	bool CheckMainArgsMessage(LaunchCaller &caller, team_id team,
67							  int32 &cookie, const entry_ref *appRef,
68							  int32 argc, const char **argv,
69							  bool useRef = true);
70	bool CheckArgvMessage(LaunchCaller &caller, team_id team, int32 &cookie,
71						  const entry_ref *appRef, bool useRef = true);
72	bool CheckArgvMessage(LaunchCaller &caller, team_id team, int32 &cookie,
73						  const entry_ref *appRef,
74						  int32 argc, const char **argv, bool useRef = true);
75	bool CheckArgvMessage(LaunchCaller &caller, team_id team, int32 &cookie,
76						  const entry_ref *appRef, const entry_ref *ref,
77						  int32 argc, const char **argv);
78	bool CheckArgsMessage(LaunchCaller &caller, team_id team, int32 &cookie,
79						  const entry_ref *appRef, const entry_ref *ref,
80						  int32 argc, const char **argv, uint32 messageCode);
81	bool CheckMessageMessages(LaunchCaller &caller, team_id team,
82							  int32 &cookie);
83	bool CheckMessageMessage(LaunchCaller &caller, team_id team, int32 &cookie,
84							 int32 index);
85	bool CheckMessageMessage(LaunchCaller &caller, team_id team, int32 &cookie,
86							 const BMessage *message);
87	bool CheckRefsMessage(LaunchCaller &caller, team_id team, int32 &cookie);
88	bool CheckRefsMessage(LaunchCaller &caller, team_id team, int32 &cookie,
89						  const entry_ref *refs, int32 count = 1);
90
91	bool WaitForMessage(uint32 messageCode, bool fromNow = false,
92						bigtime_t timeout = B_INFINITE_TIMEOUT);
93	bool WaitForMessage(team_id team, uint32 messageCode, bool fromNow = false,
94						bigtime_t timeout = B_INFINITE_TIMEOUT,
95						int32 startIndex = 0);
96
97	BList *StandardMessages();
98
99public:
100	static const char *kStandardArgv[];
101	static const int32 kStandardArgc;
102
103private:
104	class Message;
105	class Sleeper;
106	class AppInfo;
107
108private:
109	AppInfo *AppInfoAt(int32 index) const;
110	AppInfo *AppInfoFor(team_id team) const;
111	AppInfo *CreateAppInfo(team_id team, const BMessenger *messenger = NULL);
112	AppInfo *CreateAppInfo(BMessenger messenger);
113	void TerminateApp(AppInfo *info);
114
115	Message *FindMessage(uint32 messageCode);
116	void AddSleeper(Sleeper *sleeper);
117	void RemoveSleeper(Sleeper *sleeper);
118	void NotifySleepers(uint32 messageCode);
119
120	int32 Terminator();
121
122	static int32 AppThreadEntry(void *data);
123	static int32 TerminatorEntry(void *data);
124
125private:
126	BList			fAppInfos;
127	BList			fSleepers;
128	mutable BLocker	fLock;
129	thread_id		fAppThread;
130	thread_id		fTerminator;
131	bool			fTerminating;
132	BList			fStandardMessages;
133};
134
135// RosterLaunchApp
136class RosterLaunchApp : public BApplication {
137public:
138	RosterLaunchApp(const char *signature);
139	~RosterLaunchApp();
140
141	virtual void MessageReceived(BMessage *message);
142
143	void SetLaunchContext(LaunchContext *context);
144	LaunchContext *GetLaunchContext() const;
145
146	BHandler *Handler() { return fHandler; }
147	void SetHandler(BHandler *handler);
148
149private:
150	LaunchContext	*fLaunchContext;
151	BHandler		*fHandler;
152};
153
154// RosterBroadcastHandler
155class RosterBroadcastHandler : public BHandler {
156public:
157	RosterBroadcastHandler();
158
159	virtual void MessageReceived(BMessage *message);
160};
161
162#endif	// LAUNCH_TESTER_HELPER_H
163