接着分析CommandListener,FrameworkListener是它的直接父类。
FrameworkListener类的代码:
FrameworkCommand即是执行的命令。实际上在CommandListener的构造函数中即注册了多个命令:
FrameworkListener类的代码:
class FrameworkListener : public SocketListener {
public:
static const int CMD_ARGS_MAX = 26;
/* 1 out of errorRate will be dropped */
int errorRate;
private:
int mCommandCount;
bool mWithSeq;
FrameworkCommandCollection *mCommands;
public:
FrameworkListener(const char *socketName);
FrameworkListener(const char *socketName, bool withSeq);
virtual ~FrameworkListener() {}
protected:
void registerCmd(FrameworkCommand *cmd);
virtual bool onDataAvailable(SocketClient *c);
private:
void dispatchCommand(SocketClient *c, char *data);
void init(const char *socketName, bool withSeq);
};
前面分析过了,当有数据到来时会调用onDataAvailalbe()方法:
bool FrameworkListener::onDataAvailable(SocketClient *c) {
char buffer[CMD_BUF_SIZE];
int len;
len = TEMP_FAILURE_RETRY(read(c->getSocket(), buffer, sizeof(buffer)));
if (len < 0) {
SLOGE("read() failed (%s)", strerror(errno));
return false;
} else if (!len)
return false;
if(buffer[len-1] != '\0')
SLOGW("String is not zero-terminated");
int offset = 0;
int i;
for (i = 0; i < len; i++) {
if (buffer[i] == '\0') { //可以有多条命令,它们之间使用\0分隔。
/* IMPORTANT: dispatchCommand() expects a zero-terminated string */
dispatchCommand(c, buffer + offset);
offset = i + 1;
}
}
return true;
}
调用dispatchCommand:
void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
分析命令的代码略,最终得到argv
for (i = mCommands->begin(); i != mCommands->end(); ++i) {
FrameworkCommand *c = *i;
if (!strcmp(argv[0], c->getCommand())) {
if (c->runCommand(cli, argc, argv)) {
SLOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno));
}
goto out;
}
}
cli->sendMsg(500, "Command not recognized", false);
FrameworkCommand即是执行的命令。实际上在CommandListener的构造函数中即注册了多个命令:
CommandListener::CommandListener() :
FrameworkListener("vold", true) {
registerCmd(new DumpCmd());
registerCmd(new VolumeCmd());
registerCmd(new AsecCmd());
registerCmd(new ObbCmd());
registerCmd(new StorageCmd());
registerCmd(new XwarpCmd());
registerCmd(new CryptfsCmd());
registerCmd(new FstrimCmd());
}