зеркало из https://github.com/mozilla/gecko-dev.git
initial version of CLIENT_INFO support
This commit is contained in:
Родитель
913dcd68e8
Коммит
01c4e12a0a
|
@ -47,27 +47,6 @@ const nsID IPCM_TARGET =
|
|||
{0xb1, 0x15, 0x8c, 0x29, 0x44, 0xda, 0x11, 0x50}
|
||||
};
|
||||
|
||||
//
|
||||
// +--------------------+
|
||||
// | DWORD : MSG_TYPE |
|
||||
// +--------------------+
|
||||
// | (variable) |
|
||||
// +--------------------+
|
||||
//
|
||||
|
||||
int
|
||||
IPCM_GetMsgType(const ipcMessage *msg)
|
||||
{
|
||||
// make sure message topic matches
|
||||
if (msg->Target().Equals(IPCM_TARGET)) {
|
||||
// the type is encoded as the first byte
|
||||
PRUint32 type = * (PRUint32 *) msg->Data();
|
||||
if (type < IPCM_MSG_TYPE_UNKNOWN)
|
||||
return type;
|
||||
}
|
||||
return IPCM_MSG_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
//
|
||||
// MSG_TYPE values
|
||||
//
|
||||
|
@ -75,80 +54,169 @@ const PRUint32 ipcmMessagePing::MSG_TYPE = IPCM_MSG_TYPE_PING;
|
|||
const PRUint32 ipcmMessageError::MSG_TYPE = IPCM_MSG_TYPE_ERROR;
|
||||
const PRUint32 ipcmMessageClientHello::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_HELLO;
|
||||
const PRUint32 ipcmMessageClientID::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ID;
|
||||
//const PRUint32 ipcmMessageClientInfo::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_INFO;
|
||||
const PRUint32 ipcmMessageClientInfo::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_INFO;
|
||||
const PRUint32 ipcmMessageClientAddName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_NAME;
|
||||
const PRUint32 ipcmMessageClientDelName::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_NAME;
|
||||
const PRUint32 ipcmMessageClientAddTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_ADD_TARGET;
|
||||
const PRUint32 ipcmMessageClientDelTarget::MSG_TYPE = IPCM_MSG_TYPE_CLIENT_DEL_TARGET;
|
||||
const PRUint32 ipcmMessageQueryClientByName::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME;
|
||||
const PRUint32 ipcmMessageQueryClientInfo::MSG_TYPE = IPCM_MSG_TYPE_QUERY_CLIENT_INFO;
|
||||
const PRUint32 ipcmMessageForward::MSG_TYPE = IPCM_MSG_TYPE_FORWARD;
|
||||
|
||||
#if 0
|
||||
//
|
||||
// CLIST message
|
||||
// CLIENT_INFO message
|
||||
//
|
||||
// +-----------------------+
|
||||
// | BYTE - IPCM_MSG_CLIST |
|
||||
// +-----------------------+
|
||||
// | cname[0] |
|
||||
// +-----------------------+
|
||||
// | null |
|
||||
// +-----------------------+
|
||||
// . .
|
||||
// . .
|
||||
// +-----------------------+
|
||||
// | cname[num - 1] |
|
||||
// +-----------------------+
|
||||
// | null |
|
||||
// +-----------------------+
|
||||
// +-----------------------------------------+
|
||||
// | DWORD : MSG_TYPE |
|
||||
// +--------------------+--------------------+
|
||||
// | DWORD : clientID |
|
||||
// +--------------------+--------------------+
|
||||
// | WORD : nameStart | WORD : nameCount |
|
||||
// +--------------------+--------------------+
|
||||
// | WORD : targetStart | WORD : targetCount |
|
||||
// +--------------------+--------------------+
|
||||
// | name[0] | (null byte) |
|
||||
// +--------------------+--------------------+
|
||||
// . . .
|
||||
// . . .
|
||||
// +--------------------+--------------------+
|
||||
// | name[count - 1] | (null byte) |
|
||||
// +--------------------+--------------------+
|
||||
// | target[0] |
|
||||
// +-----------------------------------------+
|
||||
// . . .
|
||||
// . . .
|
||||
// +-----------------------------------------+
|
||||
// | target[count - 1] |
|
||||
// +-----------------------------------------+
|
||||
//
|
||||
|
||||
const char ipcmMessageCLIST::MSG_TYPE = (char) IPCM_MSG_CLIST;
|
||||
|
||||
ipcmMessageCLIST::ipcmMessageCLIST(const char *cNames[], PRUint32 num)
|
||||
struct ipcmClientInfoHeader
|
||||
{
|
||||
PRUint32 i, dataLen = 1;
|
||||
PRUint32 mType;
|
||||
PRUint32 mID;
|
||||
PRUint16 mNameStart;
|
||||
PRUint16 mNameCount;
|
||||
PRUint16 mTargetStart;
|
||||
PRUint16 mTargetCount;
|
||||
};
|
||||
|
||||
for (i = 0; i < num; ++i) {
|
||||
dataLen += strlen(cNames[i]);
|
||||
dataLen ++;
|
||||
ipcmMessageClientInfo::ipcmMessageClientInfo(PRUint32 cID, const char *names[], const nsID *targets[])
|
||||
{
|
||||
ipcmClientInfoHeader hdr = {0};
|
||||
|
||||
hdr.mType = MSG_TYPE;
|
||||
hdr.mID = cID;
|
||||
hdr.mNameStart = sizeof(hdr);
|
||||
|
||||
PRUint32 i, namesLen = 0;
|
||||
|
||||
i = 0;
|
||||
while (names[i]) {
|
||||
namesLen += (strlen(names[i]) + 1);
|
||||
++hdr.mNameCount;
|
||||
++i;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (targets[i]) {
|
||||
++hdr.mTargetCount;
|
||||
++i;
|
||||
}
|
||||
|
||||
//
|
||||
// compute target array starting offset
|
||||
//
|
||||
hdr.mTargetStart = hdr.mNameStart + namesLen;
|
||||
|
||||
//
|
||||
// compute message length
|
||||
//
|
||||
PRUint32 dataLen = sizeof(hdr) + namesLen + hdr.mTargetCount * sizeof(nsID);
|
||||
|
||||
Init(IPCM_TARGET, NULL, dataLen);
|
||||
|
||||
PRUint32 offset = 1;
|
||||
for (i = 0; i < num; ++i) {
|
||||
PRUint32 len = strlen(cNames[i]);
|
||||
SetData(offset, cNames[i], len + 1);
|
||||
offset += len + 1;
|
||||
//
|
||||
// write message data
|
||||
//
|
||||
SetData(0, (const char *) &hdr, sizeof(hdr));
|
||||
|
||||
PRUint32 offset = sizeof(hdr);
|
||||
|
||||
for (i = 0; names[i]; ++i) {
|
||||
PRUint32 len = strlen(names[i]) + 1;
|
||||
SetData(offset, names[i], len);
|
||||
offset += len;
|
||||
}
|
||||
|
||||
for (i = 0; targets[i]; ++i) {
|
||||
PRUint32 len = sizeof(nsID);
|
||||
SetData(offset, (const char *) targets[i], len);
|
||||
offset += len;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
ipcmMessageCLIST::NextClientName(const char *cName) const
|
||||
PRUint32
|
||||
ipcmMessageClientInfo::ClientID() const
|
||||
{
|
||||
if (!cName)
|
||||
return Data() + 1;
|
||||
|
||||
cName += strlen(cName) + 1;
|
||||
if (cName == MsgBuf() + MsgLen())
|
||||
cName = NULL;
|
||||
return cName;
|
||||
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
|
||||
return hdr->mID;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
ipcmMessageClientInfo::NameCount() const
|
||||
{
|
||||
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
|
||||
return hdr->mNameCount;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
ipcmMessageClientInfo::TargetCount() const
|
||||
{
|
||||
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
|
||||
return hdr->mTargetCount;
|
||||
}
|
||||
|
||||
const char *
|
||||
ipcmMessageClientInfo::NextName(const char *name) const
|
||||
{
|
||||
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
|
||||
|
||||
if (!name)
|
||||
return (const char *) hdr + hdr->mNameStart;
|
||||
|
||||
name += strlen(name) + 1;
|
||||
if (name == (const char *) hdr + hdr->mTargetStart)
|
||||
name = NULL;
|
||||
return name;
|
||||
}
|
||||
|
||||
const nsID *
|
||||
ipcmMessageClientInfo::NextTarget(const nsID *target) const
|
||||
{
|
||||
ipcmClientInfoHeader *hdr = (ipcmClientInfoHeader *) Data();
|
||||
|
||||
if (!target)
|
||||
return (const nsID *) hdr + hdr->mTargetStart;
|
||||
|
||||
target += sizeof(nsID);
|
||||
if (target == (const nsID *) MsgBuf() + MsgLen())
|
||||
target = NULL;
|
||||
return target;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// FWD message
|
||||
// FORWARD message
|
||||
//
|
||||
// +-------------------------------+
|
||||
// | DWORD : IPCM_MSG_TYPE_FORWARD |
|
||||
// +-------------------------------+
|
||||
// +-------------------------+
|
||||
// | DWORD : MSG_TYPE |
|
||||
// +-------------------------+
|
||||
// | clientID |
|
||||
// +-------------------------------+
|
||||
// +-------------------------+
|
||||
// | innerMsgHeader |
|
||||
// +-------------------------------+
|
||||
// +-------------------------+
|
||||
// | innerMsgData |
|
||||
// +-------------------------------+
|
||||
// +-------------------------+
|
||||
//
|
||||
|
||||
ipcmMessageForward::ipcmMessageForward(PRUint32 cID,
|
||||
|
|
|
@ -67,7 +67,11 @@ enum {
|
|||
//
|
||||
// returns IPCM message type.
|
||||
//
|
||||
int IPCM_GetMsgType(const ipcMessage *msg);
|
||||
static inline int
|
||||
IPCM_GetMsgType(const ipcMessage *msg)
|
||||
{
|
||||
return ((const ipcMessage_DWORD *) msg)->First();
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE: this file declares some helper classes that simplify construction
|
||||
|
@ -170,6 +174,23 @@ public:
|
|||
//
|
||||
// IPCM_MSG_TYPE_CLIENT_INFO
|
||||
//
|
||||
// this message is sent from the daemon to provide the list of names
|
||||
// and targets for a particular client.
|
||||
//
|
||||
class ipcmMessageClientInfo : public ipcMessage
|
||||
{
|
||||
public:
|
||||
static const PRUint32 MSG_TYPE;
|
||||
|
||||
ipcmMessageClientInfo(PRUint32 clientID, const char **names, const nsID **targets);
|
||||
|
||||
PRUint32 ClientID() const;
|
||||
PRUint32 NameCount() const;
|
||||
PRUint32 TargetCount() const;
|
||||
|
||||
const char *NextName(const char *name) const;
|
||||
const nsID *NextTarget(const nsID *target) const;
|
||||
};
|
||||
|
||||
//
|
||||
// IPCM_MSG_TYPE_CLIENT_ADD_NAME
|
||||
|
@ -231,8 +252,8 @@ public:
|
|||
// IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME
|
||||
//
|
||||
// this message is sent from a client to the daemon to request the ID of the
|
||||
// client corresponding to the given name or alias. in response the daemon
|
||||
// will either send a CLIENT_ID or ERROR message.
|
||||
// client corresponding to the given name. in response the daemon will either
|
||||
// send a CLIENT_ID or ERROR message.
|
||||
//
|
||||
class ipcmMessageQueryClientByName : public ipcMessage_DWORD_STR
|
||||
{
|
||||
|
@ -245,6 +266,24 @@ public:
|
|||
const char *Name() const { return Second(); }
|
||||
};
|
||||
|
||||
//
|
||||
// IPCM_MSG_TYPE_QUERY_CLIENT_INFO
|
||||
//
|
||||
// thie message is sent from a client to the daemon to request complete
|
||||
// information about the client corresponding to the given client ID. in
|
||||
// response the daemon will either send a CLIENT_INFO or ERROR message.
|
||||
//
|
||||
class ipcmMessageQueryClientInfo : public ipcMessage_DWORD_DWORD
|
||||
{
|
||||
public:
|
||||
static const PRUint32 MSG_TYPE;
|
||||
|
||||
ipcmMessageQueryClientInfo(PRUint32 clientID)
|
||||
: ipcMessage_DWORD_DWORD(IPCM_TARGET, MSG_TYPE, clientID) {}
|
||||
|
||||
PRUint32 ClientID() const { return Second(); }
|
||||
};
|
||||
|
||||
//
|
||||
// IPCM_MSG_TYPE_FORWARD
|
||||
//
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ipcLog.h"
|
||||
#include "ipcCommandModule.h"
|
||||
|
@ -47,6 +48,52 @@
|
|||
|
||||
typedef void (* ipcmMsgHandler)(ipcClient *, const ipcMessage *);
|
||||
|
||||
//
|
||||
// helpers
|
||||
//
|
||||
|
||||
static char **
|
||||
ipcm_BuildStringArray(const ipcStringNode *nodes)
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
const ipcStringNode *node;
|
||||
|
||||
for (node = nodes; node; node = node->mNext)
|
||||
count++;
|
||||
|
||||
char **strs = (char **) calloc(count + 1, sizeof(char *));
|
||||
if (!strs)
|
||||
return NULL;
|
||||
|
||||
count = 0;
|
||||
for (node = nodes; node; node = node->mNext, ++count)
|
||||
strs[count] = (char *) node->Value();
|
||||
|
||||
return strs;
|
||||
}
|
||||
|
||||
static nsID **
|
||||
ipcm_BuildIDArray(const ipcIDNode *nodes)
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
const ipcIDNode *node;
|
||||
|
||||
for (node = nodes; node; node = node->mNext)
|
||||
count++;
|
||||
|
||||
nsID **ids = (nsID **) calloc(count + 1, sizeof(nsID *));
|
||||
if (!ids)
|
||||
return NULL;
|
||||
|
||||
count = 0;
|
||||
for (node = nodes; node; node = node->mNext, ++count)
|
||||
ids[count] = (nsID *) &node->Value();
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
//
|
||||
// message handlers
|
||||
//
|
||||
|
@ -129,6 +176,28 @@ ipcm_OnQueryClientByName(ipcClient *client, const ipcMessage *rawMsg)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipcm_OnQueryClientInfo(ipcClient *client, const ipcMessage *rawMsg)
|
||||
{
|
||||
LOG(("got QUERY_CLIENT_INFO\n"));
|
||||
|
||||
ipcMessageCast<ipcmMessageQueryClientInfo> msg(rawMsg);
|
||||
ipcClient *result = IPC_GetClientByID(msg->ClientID());
|
||||
if (result) {
|
||||
char **names = ipcm_BuildStringArray(result->Names());
|
||||
nsID **targets = ipcm_BuildIDArray(result->Targets());
|
||||
IPC_SendMsg(client, new ipcmMessageClientInfo(result->ID(),
|
||||
(const char **) names,
|
||||
(const nsID **)targets));
|
||||
free(names);
|
||||
free(targets);
|
||||
}
|
||||
else {
|
||||
LOG((" client does not exist\n"));
|
||||
IPC_SendMsg(client, new ipcmMessageError(IPCM_ERROR_CLIENT_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipcm_OnForward(ipcClient *client, const ipcMessage *rawMsg)
|
||||
{
|
||||
|
@ -162,7 +231,7 @@ IPCM_HandleMsg(ipcClient *client, const ipcMessage *rawMsg)
|
|||
ipcm_OnClientAddTarget,
|
||||
ipcm_OnClientDelTarget,
|
||||
ipcm_OnQueryClientByName,
|
||||
NULL, // QUERY_CLIENT_INFO
|
||||
ipcm_OnQueryClientInfo,
|
||||
ipcm_OnForward,
|
||||
};
|
||||
|
||||
|
|
|
@ -100,18 +100,24 @@ interface ipcIService : nsISupports
|
|||
void removeClientName(in ACString aName);
|
||||
|
||||
/**
|
||||
* query info about a particular client given its client name.
|
||||
* query info about a particular client given its client name. the
|
||||
* observer's onClientInfo method is called with the result of the lookup,
|
||||
* or if there is no client matching the given name, the observer's
|
||||
* onClientDown method will be called instead.
|
||||
*
|
||||
* @param aNameOrAlias name or alias of the client being queried.
|
||||
* @param aName name or alias of the client being queried.
|
||||
* @param aObserver client observer to be notified.
|
||||
*
|
||||
* @return integer token identifying this request.
|
||||
*/
|
||||
unsigned long queryClientByName(in ACString aNameOrAlias,
|
||||
unsigned long queryClientByName(in ACString aName,
|
||||
in ipcIClientObserver aObserver);
|
||||
|
||||
/**
|
||||
* query info about a particular client given its client ID.
|
||||
* query info about a particular client given its client ID. the observer's
|
||||
* onClientInfo method is called with the result of the lookup, or if there
|
||||
* is no client matching the given name, the observer's onClientDown method
|
||||
* will be called instead.
|
||||
*
|
||||
* @return integer token identifying this request.
|
||||
*/
|
||||
|
@ -119,14 +125,13 @@ interface ipcIService : nsISupports
|
|||
in ipcIClientObserver aObserver);
|
||||
|
||||
/**
|
||||
* set client observer. observer is notified whenever the status of
|
||||
* a client changes.
|
||||
* set client observer. observer's onClientUp method is called whenever
|
||||
* a new client comes online, and the observer's onClientDown method is
|
||||
* called whenever a client goes offline.
|
||||
*
|
||||
* @param aClientID the ID of the client to observe.
|
||||
* @param aObserver the client observer.
|
||||
*/
|
||||
void setClientObserver(in unsigned long aClientID,
|
||||
in ipcIClientObserver aObserver);
|
||||
void setClientObserver(in ipcIClientObserver aObserver);
|
||||
|
||||
/**
|
||||
* set a message observer for a particular message target.
|
||||
|
@ -176,38 +181,23 @@ interface ipcIMessageObserver : nsISupports
|
|||
in unsigned long aDataLen);
|
||||
};
|
||||
|
||||
[scriptable, uuid(e858d450-62b2-482d-99bb-3b5425aa28cc)]
|
||||
interface ipcIClientInfo : nsISupports
|
||||
{
|
||||
readonly attribute unsigned long ID;
|
||||
readonly attribute ACString name;
|
||||
readonly attribute nsISimpleEnumerator aliases;
|
||||
readonly attribute nsISimpleEnumerator targets;
|
||||
};
|
||||
|
||||
[scriptable, uuid(42283079-030c-4b13-b069-a08b7ad5eab2)]
|
||||
interface ipcIClientObserver : nsISupports
|
||||
{
|
||||
/**
|
||||
* client status values
|
||||
*/
|
||||
const unsigned long CLIENT_UP = 1;
|
||||
const unsigned long CLIENT_DOWN = 2;
|
||||
void onClientUp (in unsigned long aReqToken,
|
||||
in unsigned long aClientID);
|
||||
|
||||
/**
|
||||
* @param aRequestToken the request token returned from the call that
|
||||
* initiated this observation. 0 if initiated
|
||||
* from a setClientObserver call.
|
||||
* @param aClientInfo client info.
|
||||
* @param aStatus client status (e.g. CLIENT_UP).
|
||||
*/
|
||||
void onClientStatus(in unsigned long aRequestToken,
|
||||
in unsigned long aClientStatus,
|
||||
void onClientDown (in unsigned long aReqToken,
|
||||
in unsigned long aClientID);
|
||||
|
||||
void onClientInfo (in unsigned long aReqToken,
|
||||
in unsigned long aClientID,
|
||||
in ipcIClientInfo aClientInfo);
|
||||
|
||||
// XXX do we care about changes to the aliases and targets supported
|
||||
// by a client? if so, how should we pass this information up?
|
||||
[array, size_is(aNameCount)]
|
||||
in string aClientNames,
|
||||
in unsigned long aNameCount,
|
||||
[array, const, size_is(aTargetCount)]
|
||||
in nsIDPtr aClientTargets,
|
||||
in unsigned long aTargetCount);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "plstr.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
|
@ -62,38 +64,6 @@ ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcClientInfo
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ipcClientInfo, ipcIClientInfo)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcClientInfo::GetID(PRUint32 *aID)
|
||||
{
|
||||
*aID = mID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcClientInfo::GetName(nsACString &aName)
|
||||
{
|
||||
aName = mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcClientInfo::GetAliases(nsISimpleEnumerator **aliases)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcClientInfo::GetTargets(nsISimpleEnumerator **targets)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcService
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -153,44 +123,85 @@ ipcService::Init()
|
|||
}
|
||||
|
||||
void
|
||||
ipcService::HandleQueryResult(const ipcMessage *rawMsg, PRBool succeeded)
|
||||
ipcService::OnIPCMClientID(const ipcmMessageClientID *msg)
|
||||
{
|
||||
LOG(("ipcService::OnIPCMClientID\n"));
|
||||
|
||||
ipcClientQuery *query = mQueryQ.First();
|
||||
if (!query) {
|
||||
NS_ERROR("no pending query; ignoring message.");
|
||||
NS_WARNING("no pending query; ignoring message.");
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 cStatus;
|
||||
PRUint32 cID;
|
||||
ipcClientInfo *info;
|
||||
//
|
||||
// (1) store client ID in query
|
||||
// (2) move query to end of queue
|
||||
// (3) issue CLIENT_INFO request
|
||||
//
|
||||
query->mID = msg->ClientID();
|
||||
|
||||
if (succeeded) {
|
||||
cStatus = ipcIClientObserver::CLIENT_UP;
|
||||
mQueryQ.RemoveFirst();
|
||||
mQueryQ.Append(query);
|
||||
|
||||
ipcMessageCast<ipcmMessageClientID> msg(rawMsg);
|
||||
info = new ipcClientInfo();
|
||||
if (info) {
|
||||
NS_ADDREF(info);
|
||||
info->Init(msg->ClientID(), query->mName);
|
||||
}
|
||||
cID = msg->ClientID();
|
||||
}
|
||||
else {
|
||||
cStatus = ipcIClientObserver::CLIENT_DOWN;
|
||||
cID = 0;
|
||||
info = nsnull;
|
||||
}
|
||||
|
||||
query->mObserver->OnClientStatus(query->mReqToken,
|
||||
cStatus,
|
||||
cID,
|
||||
info);
|
||||
|
||||
NS_IF_RELEASE(info);
|
||||
mQueryQ.DeleteFirst();
|
||||
mTransport->SendMsg(new ipcmMessageQueryClientInfo(query->mID));
|
||||
}
|
||||
|
||||
void
|
||||
ipcService::OnIPCMClientInfo(const ipcmMessageClientInfo *msg)
|
||||
{
|
||||
LOG(("ipcService::OnIPCMClientInfo\n"));
|
||||
|
||||
ipcClientQuery *query = mQueryQ.First();
|
||||
if (!query) {
|
||||
NS_WARNING("no pending query; ignoring message.");
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 nameCount = msg->NameCount();
|
||||
PRUint32 targetCount = msg->TargetCount();
|
||||
PRUint32 i;
|
||||
|
||||
const char **names = (const char **) calloc(nameCount + 1, sizeof(const char *));
|
||||
const char *lastName = NULL;
|
||||
for (i = 0; i < nameCount; ++i) {
|
||||
lastName = msg->NextName(lastName);
|
||||
names[i] = lastName;
|
||||
}
|
||||
|
||||
const nsID **targets = (const nsID **) calloc(targetCount + 1, sizeof(const nsID *));
|
||||
const nsID *lastTarget = NULL;
|
||||
for (i = 0; i < targetCount; ++i) {
|
||||
lastTarget = msg->NextTarget(lastTarget);
|
||||
targets[i] = lastTarget;
|
||||
}
|
||||
|
||||
query->mObserver->OnClientInfo(query->mReqToken,
|
||||
query->mID,
|
||||
names, nameCount,
|
||||
targets, targetCount);
|
||||
|
||||
mQueryQ.DeleteFirst();
|
||||
|
||||
free(names);
|
||||
free(targets);
|
||||
}
|
||||
|
||||
void
|
||||
ipcService::OnIPCMError(const ipcmMessageError *msg)
|
||||
{
|
||||
LOG(("ipcService::OnIPCMError\n"));
|
||||
|
||||
ipcClientQuery *query = mQueryQ.First();
|
||||
if (!query) {
|
||||
NS_WARNING("no pending query; ignoring message.");
|
||||
return;
|
||||
}
|
||||
|
||||
query->mObserver->OnClientDown(query->mReqToken,
|
||||
query->mID);
|
||||
|
||||
mQueryQ.DeleteFirst();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// interface impl
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -277,8 +288,7 @@ ipcService::QueryClientByID(PRUint32 clientID,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcService::SetClientObserver(PRUint32 clientID,
|
||||
ipcIClientObserver *observer)
|
||||
ipcService::SetClientObserver(ipcIClientObserver *observer)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -369,9 +379,7 @@ ipcService::OnConnectionLost()
|
|||
//
|
||||
while (mQueryQ.First()) {
|
||||
ipcClientQuery *query = mQueryQ.First();
|
||||
query->mObserver->OnClientStatus(query->mReqToken,
|
||||
ipcIClientObserver::CLIENT_DOWN,
|
||||
query->mID, nsnull);
|
||||
query->mObserver->OnClientDown(query->mReqToken, query->mID);
|
||||
mQueryQ.DeleteFirst();
|
||||
}
|
||||
|
||||
|
@ -392,12 +400,16 @@ ipcService::OnMessageAvailable(const ipcMessage *msg)
|
|||
//
|
||||
// all IPCM messages stop here.
|
||||
//
|
||||
switch (IPCM_GetMsgType(msg)) {
|
||||
PRUint32 type = IPCM_GetMsgType(msg);
|
||||
switch (type) {
|
||||
case IPCM_MSG_TYPE_CLIENT_ID:
|
||||
HandleQueryResult(msg, PR_TRUE);
|
||||
OnIPCMClientID((const ipcmMessageClientID *) msg);
|
||||
break;
|
||||
case IPCM_MSG_TYPE_CLIENT_INFO:
|
||||
OnIPCMClientInfo((const ipcmMessageClientInfo *) msg);
|
||||
break;
|
||||
case IPCM_MSG_TYPE_ERROR:
|
||||
HandleQueryResult(msg, PR_FALSE);
|
||||
OnIPCMError((const ipcmMessageError *) msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,40 +38,18 @@
|
|||
#ifndef ipcService_h__
|
||||
#define ipcService_h__
|
||||
|
||||
#include "ipcIService.h"
|
||||
#include "ipcTransport.h"
|
||||
#include "ipcList.h"
|
||||
#include "ipcMessage.h"
|
||||
#include "ipcMessageQ.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ipcClientInfo
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class ipcClientInfo : public ipcIClientInfo
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IPCICLIENTINFO
|
||||
|
||||
ipcClientInfo() : mID(0) { NS_INIT_ISUPPORTS(); }
|
||||
virtual ~ipcClientInfo() {}
|
||||
|
||||
void Init(PRUint32 cID, const nsACString &cName)
|
||||
{
|
||||
mID = cID;
|
||||
mName = cName;
|
||||
}
|
||||
|
||||
private:
|
||||
PRUint32 mID;
|
||||
nsCString mName;
|
||||
};
|
||||
#include "ipcIService.h"
|
||||
#include "ipcTransport.h"
|
||||
#include "ipcList.h"
|
||||
#include "ipcMessage.h"
|
||||
#include "ipcMessageQ.h"
|
||||
#include "ipcm.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ipcClientQuery
|
||||
|
@ -113,7 +91,9 @@ public:
|
|||
|
||||
private:
|
||||
nsresult ErrorAccordingToIPCM(PRUint32 err);
|
||||
void HandleQueryResult(const ipcMessage *, PRBool succeeded);
|
||||
void OnIPCMClientID(const ipcmMessageClientID *);
|
||||
void OnIPCMClientInfo(const ipcmMessageClientInfo *);
|
||||
void OnIPCMError(const ipcmMessageError *);
|
||||
|
||||
// ipcTransportObserver:
|
||||
void OnConnectionEstablished(PRUint32 clientID);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "nsIComponentRegistrar.h"
|
||||
#include "nsString.h"
|
||||
#include "prmem.h"
|
||||
|
||||
static const nsID kTestTargetID =
|
||||
{ /* e628fc6e-a6a7-48c7-adba-f241d1128fb8 */
|
||||
|
@ -112,20 +113,43 @@ public:
|
|||
NS_IMPL_ISUPPORTS1(myIpcClientObserver, ipcIClientObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
myIpcClientObserver::OnClientStatus(PRUint32 aReqToken,
|
||||
PRUint32 aStatus,
|
||||
PRUint32 aClientID,
|
||||
ipcIClientInfo *aClientInfo)
|
||||
myIpcClientObserver::OnClientUp(PRUint32 aReqToken,
|
||||
PRUint32 aClientID)
|
||||
{
|
||||
printf("*** got client status [token=%u status=%u info=%p]\n",
|
||||
aReqToken, aStatus, (void *) aClientInfo);
|
||||
printf("*** got client up [token=%u clientID=%u]\n", aReqToken, aClientID);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
myIpcClientObserver::OnClientDown(PRUint32 aReqToken,
|
||||
PRUint32 aClientID)
|
||||
{
|
||||
printf("*** got client down [token=%u clientID=%u]\n", aReqToken, aClientID);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
myIpcClientObserver::OnClientInfo(PRUint32 aReqToken,
|
||||
PRUint32 aClientID,
|
||||
const char **aNames,
|
||||
PRUint32 aNameCount,
|
||||
const nsID **aTargets,
|
||||
PRUint32 aTargetCount)
|
||||
{
|
||||
printf("*** got client info [token=%u clientID=%u]\n", aReqToken, aClientID);
|
||||
|
||||
PRUint32 i;
|
||||
printf("*** names:\n");
|
||||
for (i = 0; i < aNameCount; ++i)
|
||||
printf("*** %d={%s}\n", i, aNames[i]);
|
||||
printf("*** targets:\n");
|
||||
for (i = 0; i < aTargetCount; ++i) {
|
||||
char *str = aTargets[i]->ToString();
|
||||
printf("*** %d=%s\n", i, str);
|
||||
PR_Free(str);
|
||||
}
|
||||
|
||||
if (aClientID != 0) {
|
||||
if (aClientInfo) {
|
||||
nsCAutoString cName;
|
||||
if (NS_SUCCEEDED(aClientInfo->GetName(cName)))
|
||||
printf("*** name:%s --> ID:%u\n", cName.get(), aClientID);
|
||||
}
|
||||
const char hello[] = "hello friend!";
|
||||
SendMsg(gIpcServ, aClientID, kTestTargetID, hello, sizeof(hello));
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче