Extended the Launch() helpers.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1300 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -4,9 +4,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
|
#include <Entry.h>
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
#include "LaunchTesterHelper.h"
|
#include "LaunchTesterHelper.h"
|
||||||
#include "RosterTestAppDefs.h"
|
#include "RosterTestAppDefs.h"
|
||||||
@@ -14,12 +16,20 @@
|
|||||||
/////////////////
|
/////////////////
|
||||||
// LaunchContext
|
// LaunchContext
|
||||||
|
|
||||||
|
const char *LaunchContext::kStandardArgv[] = {
|
||||||
|
"Some", "nice", "arguments"
|
||||||
|
};
|
||||||
|
const int32 LaunchContext::kStandardArgc
|
||||||
|
= sizeof(kStandardArgv) / sizeof(const char*);
|
||||||
|
|
||||||
|
// Message
|
||||||
class LaunchContext::Message {
|
class LaunchContext::Message {
|
||||||
public:
|
public:
|
||||||
BMessage message;
|
BMessage message;
|
||||||
bigtime_t when;
|
bigtime_t when;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// AppInfo
|
||||||
class LaunchContext::AppInfo {
|
class LaunchContext::AppInfo {
|
||||||
public:
|
public:
|
||||||
AppInfo(team_id team)
|
AppInfo(team_id team)
|
||||||
@@ -68,6 +78,11 @@ public:
|
|||||||
fMessages.AddItem(message);
|
fMessages.AddItem(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchContext::Message *RemoveMessage(int32 index)
|
||||||
|
{
|
||||||
|
return (LaunchContext::Message*)fMessages.RemoveItem(index);
|
||||||
|
}
|
||||||
|
|
||||||
LaunchContext::Message *MessageAt(int32 index) const
|
LaunchContext::Message *MessageAt(int32 index) const
|
||||||
{
|
{
|
||||||
return (LaunchContext::Message*)fMessages.ItemAt(index);
|
return (LaunchContext::Message*)fMessages.ItemAt(index);
|
||||||
@@ -109,14 +124,34 @@ LaunchContext::~LaunchContext()
|
|||||||
// cleanup
|
// cleanup
|
||||||
for (int32 i = 0; AppInfo *info = AppInfoAt(i); i++)
|
for (int32 i = 0; AppInfo *info = AppInfoAt(i); i++)
|
||||||
delete info;
|
delete info;
|
||||||
|
for (int32 i = 0;
|
||||||
|
BMessage *message = (BMessage*)fStandardMessages.ItemAt(i);
|
||||||
|
i++) {
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ()
|
// ()
|
||||||
status_t
|
status_t
|
||||||
LaunchContext::operator()(const char *type, team_id *team)
|
LaunchContext::operator()(const char *type, team_id *team)
|
||||||
|
{
|
||||||
|
BMessage message1(MSG_1);
|
||||||
|
BMessage message2(MSG_2);
|
||||||
|
BMessage message3(MSG_3);
|
||||||
|
BList messages;
|
||||||
|
messages.AddItem(&message1);
|
||||||
|
messages.AddItem(&message2);
|
||||||
|
messages.AddItem(&message3);
|
||||||
|
return (*this)(type, &messages, kStandardArgc, kStandardArgv, team);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ()
|
||||||
|
status_t
|
||||||
|
LaunchContext::operator()(const char *type, BList *messages, int32 argc,
|
||||||
|
const char **argv, team_id *team)
|
||||||
{
|
{
|
||||||
BAutolock _lock(fLock);
|
BAutolock _lock(fLock);
|
||||||
status_t result = fCaller(type, team);
|
status_t result = fCaller(type, messages, argc, argv, team);
|
||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
if (team)
|
if (team)
|
||||||
CreateAppInfo(*team);
|
CreateAppInfo(*team);
|
||||||
@@ -136,6 +171,8 @@ LaunchContext::operator()(const char *type, team_id *team)
|
|||||||
void
|
void
|
||||||
LaunchContext::HandleMessage(BMessage *message)
|
LaunchContext::HandleMessage(BMessage *message)
|
||||||
{
|
{
|
||||||
|
//printf("LaunchContext::HandleMessage(%6ld: %.4s)\n",
|
||||||
|
//message->ReturnAddress().Team(), (char*)&message->what);
|
||||||
BAutolock _lock(fLock);
|
BAutolock _lock(fLock);
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case MSG_STARTED:
|
case MSG_STARTED:
|
||||||
@@ -207,10 +244,8 @@ LaunchContext::NextMessageFrom(team_id team, int32 &cookie, bigtime_t *time)
|
|||||||
BAutolock _lock(fLock);
|
BAutolock _lock(fLock);
|
||||||
BMessage *message = NULL;
|
BMessage *message = NULL;
|
||||||
if (AppInfo *info = AppInfoFor(team)) {
|
if (AppInfo *info = AppInfoFor(team)) {
|
||||||
if (Message *contextMessage = info->MessageAt(cookie++)) {
|
if (Message *contextMessage = info->MessageAt(cookie++))
|
||||||
message = new BMessage(contextMessage->message);
|
message = &contextMessage->message;
|
||||||
delete contextMessage;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
@@ -223,6 +258,206 @@ LaunchContext::CheckNextMessage(team_id team, int32 &cookie, uint32 what)
|
|||||||
return (message && message->what == what);
|
return (message && message->what == what);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckArgvMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::CheckArgvMessage(team_id team, int32 &cookie,
|
||||||
|
const entry_ref *appRef, bool useRef)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
if (fCaller.SupportsArgv()) {
|
||||||
|
result = CheckArgvMessage(team, cookie, appRef, kStandardArgc,
|
||||||
|
kStandardArgv, useRef);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckArgvMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::CheckArgvMessage(team_id team, int32 &cookie,
|
||||||
|
const entry_ref *appRef, int32 argc,
|
||||||
|
const char **argv, bool useRef)
|
||||||
|
{
|
||||||
|
const entry_ref *ref = (useRef ? fCaller.Ref() : NULL);
|
||||||
|
return CheckArgvMessage(team, cookie, appRef, ref , argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckArgvMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::CheckArgvMessage(team_id team, int32 &cookie,
|
||||||
|
const entry_ref *appRef,
|
||||||
|
const entry_ref *ref , int32 argc,
|
||||||
|
const char **argv)
|
||||||
|
{
|
||||||
|
BMessage *message = NextMessageFrom(team, cookie);
|
||||||
|
bool result = (message && message->what == MSG_ARGV_RECEIVED);
|
||||||
|
int32 additionalRef = (ref ? 1 : 0);
|
||||||
|
// check argc
|
||||||
|
int32 foundArgc = -1;
|
||||||
|
if (result) {
|
||||||
|
result = (message->FindInt32("argc", &foundArgc) == B_OK
|
||||||
|
&& foundArgc == argc + 1 + additionalRef);
|
||||||
|
if (!result)
|
||||||
|
printf("argc differ: %ld vs %ld + 1 + %ld\n", foundArgc, argc, additionalRef);
|
||||||
|
}
|
||||||
|
// check argv[0] (the app file name)
|
||||||
|
if (result) {
|
||||||
|
BPath path;
|
||||||
|
const char *arg = NULL;
|
||||||
|
result = (path.SetTo(appRef) == B_OK
|
||||||
|
&& message->FindString("argv", 0, &arg) == B_OK
|
||||||
|
&& path == arg);
|
||||||
|
if (!result)
|
||||||
|
printf("app paths differ: `%s' vs `%s'\n", arg, path.Path());
|
||||||
|
}
|
||||||
|
// check remaining argv
|
||||||
|
for (int32 i = 1; result && i < argc; i++) {
|
||||||
|
const char *arg = NULL;
|
||||||
|
result = (message->FindString("argv", i, &arg) == B_OK
|
||||||
|
&& !strcmp(arg, argv[i - 1]));
|
||||||
|
if (!result)
|
||||||
|
printf("arg[%ld] differ: `%s' vs `%s'\n", i, arg, argv[i - 1]);
|
||||||
|
}
|
||||||
|
// check additional ref
|
||||||
|
if (result && additionalRef) {
|
||||||
|
BPath path;
|
||||||
|
const char *arg = NULL;
|
||||||
|
result = (path.SetTo(ref) == B_OK
|
||||||
|
&& message->FindString("argv", argc + 1, &arg) == B_OK
|
||||||
|
&& path == arg);
|
||||||
|
if (!result)
|
||||||
|
printf("app paths differ: `%s' vs `%s'\n", arg, path.Path());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveStandardArgvMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::RemoveStandardArgvMessage(team_id team, const entry_ref *appRef)
|
||||||
|
{
|
||||||
|
return RemoveArgvMessage(team, appRef, kStandardArgc, kStandardArgv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveArgvMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::RemoveArgvMessage(team_id team, const entry_ref *appRef,
|
||||||
|
int32 argc, const char **argv)
|
||||||
|
{
|
||||||
|
BAutolock _lock(fLock);
|
||||||
|
bool result = true;
|
||||||
|
if (fCaller.SupportsArgv()) {
|
||||||
|
result = false;
|
||||||
|
int32 cookie = 0;
|
||||||
|
while (BMessage *message = NextMessageFrom(team, cookie)) {
|
||||||
|
if (message->what == MSG_ARGV_RECEIVED) {
|
||||||
|
int32 index = --cookie;
|
||||||
|
result = CheckArgvMessage(team, cookie, appRef, argc, argv);
|
||||||
|
delete AppInfoFor(team)->RemoveMessage(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckMessageMessages
|
||||||
|
bool
|
||||||
|
LaunchContext::CheckMessageMessages(team_id team, int32 &cookie)
|
||||||
|
{
|
||||||
|
BAutolock _lock(fLock);
|
||||||
|
bool result = true;
|
||||||
|
for (int32 i = 0; i < 3; i++)
|
||||||
|
result &= CheckMessageMessage(team, cookie, i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckMessageMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::CheckMessageMessage(team_id team, int32 &cookie, int32 index)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
if (fCaller.SupportsMessages() > index && index < 3) {
|
||||||
|
uint32 commands[] = { MSG_1, MSG_2, MSG_3 };
|
||||||
|
BMessage message(commands[index]);
|
||||||
|
result = CheckMessageMessage(team, cookie, &message);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckMessageMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::CheckMessageMessage(team_id team, int32 &cookie,
|
||||||
|
const BMessage *expectedMessage)
|
||||||
|
{
|
||||||
|
BMessage *message = NextMessageFrom(team, cookie);
|
||||||
|
bool result = (message && message->what == MSG_MESSAGE_RECEIVED);
|
||||||
|
if (result) {
|
||||||
|
BMessage sentMessage;
|
||||||
|
result = (message->FindMessage("message", &sentMessage) == B_OK
|
||||||
|
&& sentMessage.what == expectedMessage->what);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckRefsMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::CheckRefsMessage(team_id team, int32 &cookie)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
if (fCaller.SupportsRefs())
|
||||||
|
result = CheckRefsMessage(team, cookie, fCaller.Ref());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckRefsMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::CheckRefsMessage(team_id team, int32 &cookie,
|
||||||
|
const entry_ref *refs, int32 count)
|
||||||
|
{
|
||||||
|
BMessage *message = NextMessageFrom(team, cookie);
|
||||||
|
bool result = (message && message->what == MSG_REFS_RECEIVED);
|
||||||
|
if (result) {
|
||||||
|
entry_ref ref;
|
||||||
|
for (int32 i = 0; result && i < count; i++) {
|
||||||
|
result = (message->FindRef("refs", i, &ref) == B_OK
|
||||||
|
&& ref == refs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveRefsMessage
|
||||||
|
bool
|
||||||
|
LaunchContext::RemoveRefsMessage(team_id team)
|
||||||
|
{
|
||||||
|
BAutolock _lock(fLock);
|
||||||
|
bool result = true;
|
||||||
|
if (fCaller.SupportsRefs()) {
|
||||||
|
result = false;
|
||||||
|
int32 cookie = 0;
|
||||||
|
while (BMessage *message = NextMessageFrom(team, cookie)) {
|
||||||
|
if (message->what == MSG_REFS_RECEIVED) {
|
||||||
|
int32 index = --cookie;
|
||||||
|
result = CheckRefsMessage(team, cookie);
|
||||||
|
delete AppInfoFor(team)->RemoveMessage(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// StandardMessages
|
||||||
|
BList*
|
||||||
|
LaunchContext::StandardMessages()
|
||||||
|
{
|
||||||
|
if (fStandardMessages.IsEmpty()) {
|
||||||
|
fStandardMessages.AddItem(new BMessage(MSG_1));
|
||||||
|
fStandardMessages.AddItem(new BMessage(MSG_2));
|
||||||
|
fStandardMessages.AddItem(new BMessage(MSG_3));
|
||||||
|
}
|
||||||
|
return &fStandardMessages;
|
||||||
|
}
|
||||||
|
|
||||||
// AppInfoAt
|
// AppInfoAt
|
||||||
LaunchContext::AppInfo*
|
LaunchContext::AppInfo*
|
||||||
LaunchContext::AppInfoAt(int32 index) const
|
LaunchContext::AppInfoAt(int32 index) const
|
||||||
|
|||||||
@@ -4,14 +4,26 @@
|
|||||||
#define LAUNCH_TESTER_HELPER_H
|
#define LAUNCH_TESTER_HELPER_H
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
|
#include <List.h>
|
||||||
#include <Locker.h>
|
#include <Locker.h>
|
||||||
#include <MessageQueue.h>
|
#include <MessageQueue.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MSG_1 = 'msg1',
|
||||||
|
MSG_2 = 'msg2',
|
||||||
|
MSG_3 = 'msg3',
|
||||||
|
};
|
||||||
|
|
||||||
// LaunchCaller
|
// LaunchCaller
|
||||||
class LaunchCaller {
|
class LaunchCaller {
|
||||||
public:
|
public:
|
||||||
virtual status_t operator()(const char *type, team_id *team) = 0;
|
virtual status_t operator()(const char *type, BList *messages, int32 argc,
|
||||||
|
const char **argv, team_id *team) = 0;
|
||||||
|
virtual int32 SupportsMessages() const { return 1; }
|
||||||
|
virtual bool SupportsArgv() const { return SupportsMessages() == 0; }
|
||||||
|
virtual bool SupportsRefs() const { return false; }
|
||||||
|
virtual const entry_ref *Ref() const { return NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// LaunchContext
|
// LaunchContext
|
||||||
@@ -21,6 +33,8 @@ public:
|
|||||||
~LaunchContext();
|
~LaunchContext();
|
||||||
|
|
||||||
status_t operator()(const char *type, team_id *team);
|
status_t operator()(const char *type, team_id *team);
|
||||||
|
status_t operator()(const char *type, BList *messages, int32 argc,
|
||||||
|
const char **argv, team_id *team);
|
||||||
|
|
||||||
void HandleMessage(BMessage *message);
|
void HandleMessage(BMessage *message);
|
||||||
|
|
||||||
@@ -31,6 +45,29 @@ public:
|
|||||||
BMessage *NextMessageFrom(team_id team, int32 &cookie,
|
BMessage *NextMessageFrom(team_id team, int32 &cookie,
|
||||||
bigtime_t *time = NULL);
|
bigtime_t *time = NULL);
|
||||||
bool CheckNextMessage(team_id team, int32 &cookie, uint32 what);
|
bool CheckNextMessage(team_id team, int32 &cookie, uint32 what);
|
||||||
|
bool CheckArgvMessage(team_id team, int32 &cookie,
|
||||||
|
const entry_ref *appRef, bool useRef = true);
|
||||||
|
bool CheckArgvMessage(team_id team, int32 &cookie, const entry_ref *appRef,
|
||||||
|
int32 argc, const char **argv, bool useRef = true);
|
||||||
|
bool CheckArgvMessage(team_id team, int32 &cookie, const entry_ref *appRef,
|
||||||
|
const entry_ref *ref, int32 argc, const char **argv);
|
||||||
|
bool RemoveStandardArgvMessage(team_id team, const entry_ref *appRef);
|
||||||
|
bool RemoveArgvMessage(team_id team, const entry_ref *appRef, int32 argc,
|
||||||
|
const char **argv);
|
||||||
|
bool CheckMessageMessages(team_id team, int32 &cookie);
|
||||||
|
bool CheckMessageMessage(team_id team, int32 &cookie, int32 index);
|
||||||
|
bool CheckMessageMessage(team_id team, int32 &cookie,
|
||||||
|
const BMessage *message);
|
||||||
|
bool CheckRefsMessage(team_id team, int32 &cookie);
|
||||||
|
bool CheckRefsMessage(team_id team, int32 &cookie, const entry_ref *refs,
|
||||||
|
int32 count = 1);
|
||||||
|
bool RemoveRefsMessage(team_id team);
|
||||||
|
|
||||||
|
BList *StandardMessages();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const char *kStandardArgv[];
|
||||||
|
static const int32 kStandardArgc;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Message;
|
class Message;
|
||||||
@@ -55,6 +92,7 @@ private:
|
|||||||
thread_id fAppThread;
|
thread_id fAppThread;
|
||||||
thread_id fTerminator;
|
thread_id fTerminator;
|
||||||
bool fTerminating;
|
bool fTerminating;
|
||||||
|
BList fStandardMessages;
|
||||||
};
|
};
|
||||||
|
|
||||||
// RosterLaunchApp
|
// RosterLaunchApp
|
||||||
|
|||||||
Reference in New Issue
Block a user