Android SocketListener、FrameworkListener 分析

1. xxx.rc 中使用 /dev/socket/xxx

logd.rc 中 有 "socket logd stream 0666 logd logd" 以及 "socket logdr seqpacket 0666 logd logd"

这样的写法,实际会将logd 服务 与  "/dev/socket/logd" "dev/socket/logdr" socket节点进行绑定

​/system/core/logd/logd.rc
service logd /system/bin/logd
    socket logd stream 0666 logd logd
    socket logdr seqpacket 0666 logd logd
    socket logdw dgram+passcred 0222 logd logd
    file /proc/kmsg r
    file /dev/kmsg w
    user logd
    group logd system package_info readproc
    capabilities SYSLOG AUDIT_CONTROL
    priority 10
    task_profiles ServiceCapacityLow

2. SocketListener 分析

1) 通过继承 SocketListener 类,

SocketListener, class LogReader : public SocketListener {}"

2) 实现构造方法:

LogListener::LogListener(LogBuffer* buf, LogReader* reader)
    : SocketListener(getLogSocket(), false), logbuf(buf), reader(reader) {}

3) 通过 startListener()  以及重载的 onDataAvailable()方法 完成通信

system/core/libsysutils/include/sysutils/SocketListener.h
class SocketListener {
    bool                    mListen;
    const char              *mSocketName;
    int                     mSock;
    std::unordered_map<int, SocketClient*> mClients;
    pthread_mutex_t         mClientsLock;
    int                     mCtrlPipe[2];
    pthread_t               mThread;
    bool                    mUseCmdNum;

public:
    SocketListener(const char *socketName, bool listen);
    SocketListener(const char *socketName, bool listen, bool useCmdNum);
    SocketListener(int socketFd, bool listen);

    virtual ~SocketListener();
    int startListener();
    int startListener(int backlog);
    int stopListener();

    void sendBroadcast(int code, const char *msg, bool addErrno);

    void runOnEachSocket(SocketClientCommand *command);

    bool release(SocketClient *c) { return release(c, true); }

protected:
    virtual bool onDataAvailable(SocketClient *c) = 0;

private:
    static void *threadStart(void *obj);

    // Add all clients to a separate list, so we don't have to hold the lock
    // while processing it.
    std::vector<SocketClient*> snapshotClients();

    bool release(SocketClient *c, bool wakeup);
    void runListener();
    void init(const char *socketName, int socketFd, bool listen, bool useCmdNum);
};

natvie 代码里面通过 android_get_control_socket(xxx) 获取 "/dev/socket/xxx"

/system/core/libsysutils/src/SocketListener.cpp

SocketListener::SocketListener(const char *socketName, bool listen) {
    init(socketName, -1, listen, false)
}
SocketListener::SocketListener(int socketFd, bool listen) {
  init(nullptr, socketFd, listen, false)
}

void SocketListener::init(const char *socketName, int socketFd, bool listen, bool 
  useCmdNum) {
  mListen = listen
  mSocketName = socketName
  mSock = socketFd
  mUseCmdNum = useCmdNum
  pthread_mutex_init(&mClientsLock, nullptr)
}

int SocketListener::startListener() {
  return startListener(4)
}

int SocketListener::startListener(int backlog) {
  if (mSocketName) {
    // 重要,获取 socket 的地方,通过 mSocketName 获取socket
    mSock = android_get_control_socket(mSocketName))
    fcntl(mSock, F_SETFD, FD_CLOEXEC)
  }

  if (mListen && listen(mSock, backlog) < 0)
  else if(!mListen)
    mClients[mSock] = new SocketClient(mSock, false, mUseCmdNum)
    
  (pthread_create(&mThread, nullptr, SocketListener::threadStart, this)
}
  
void *SocketListener::threadStart(void *obj) {
  SocketListener *me = reinterpret_cast<SocketListener *>(obj)
  me->runListener()
}

// 继承于 SocketListener 的子类,通过重载 onDataAvailable()方法,基于这个模型实现通信的
void SocketListener::runListener() {
  while (true) {
    for (SocketClient* c : pending) {
      onDataAvailable(c)
    }
  }
}

3. FrameworkListener 分析

FrameworkListener 继承于 SocketListener ,也可以基于 FrameworkListener 进行通信设计

通过 registerCmd 方法注册,然后调用对应 FrameworkCommand 的runCommand()方法

system/core/libsysutils/include/sysutils/FrameworkListener.h
class FrameworkListener : public SocketListener {}

/system/core/libsysutils/src/FrameworkListener.cpp

FrameworkListener::FrameworkListener(const char *socketName, bool withSeq) :
  SocketListener(socketName, true, withSeq) {
  init(socketName, withSeq)
}

FrameworkListener::FrameworkListener(const char *socketName) :
  SocketListener(socketName, true, false) {
  init(socketName, false)
}

void FrameworkListener::init(const char* /*socketName*/, bool withSeq) {
  mWithSeq = withSeq
  mSkipToNextNullByte = false
}

bool FrameworkListener::onDataAvailable(SocketClient *c) {
  len = TEMP_FAILURE_RETRY(read(c->getSocket(), buffer, sizeof(buffer)))
  for (i = 0; i < len; i++) {
    if (buffer[i] == '\0') {
       dispatchCommand(c, buffer + offset)
       offset = i + 1
    }
  }
}

void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
  while(*p) {
    for (auto* c : mCommands) {
      if (!strcmp(argv[0], c->getCommand())) {
        if (c->runCommand(cli, argc, argv))
      }
    }
  }
}

// 通过 registerCmd 方法注册,然后调用对应 FrameworkCommand 的runCommand()方法
void FrameworkListener::registerCmd(FrameworkCommand *cmd) {
  mCommands.push_back(cmd)
}

4. 通过 SocketListener 及 FrameworkListener 实现通信例子

// 继承 SocketListener 实现通信
/system/core/logd/LogListener.cpp
  LogListener::LogListener(LogBuffer* buf, LogReader* reader)
    : SocketListener(getLogSocket(), false), logbuf(buf), reader(reader) {}
  
  int LogListener::getLogSocket() {
    static const char socketName[] = "logdw";
    int sock = android_get_control_socket(socketName);
    if (sock < 0) {
      sock = socket_local_server(
        socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM);
      setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))
    }
    return sock
  }

  bool LogListener::onDataAvailable(SocketClient* cli) {
  }

/system/core/logd/CommandListener.cpp
  int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc,char** argv) {
    if (argc < 2) {
      cli->sendMsg("Missing Argument");
      return 0;
    }
    cli->sendMsg(mBuf.clear((log_id_t)id, uid) ? "busy" : "success")
    return 0
  }

// 服务端,守护进程 logd

/system/core/logd/main.cpp
  int main(int argc, char* argv[]) {
    // 继承于 SocketListener, class LogReader : public SocketListener {}
    LogReader* reader = new LogReader(logBuf)
    reader->startListener()
    
    // 继承于 SocketListener, class LogListener : public SocketListener {}
    LogListener* swl = new LogListener(logBuf, reader)
    swl->startListener(600)
    
    // 继承于FrameworkListener, class CommandListener : public FrameworkListener {}
    CommandListener* cl = new CommandListener(logBuf, reader, swl)
    cl->startListener() 
  }

// 使用者客户端, logcat 


/system/core/logcat/logcat.cpp
int main(int argc, char** argv) {
  return logcat.Run(argc, argv)
}
int Logcat::Run(int argc, char** argv) {
  while (!max_count_ || print_count_ < max_count_) {
    int ret = android_logger_list_read(logger_list.get(), &log_msg)
  }
}

/system/core/liblog/logd_reader.cpp
int LogdRead(struct logger_list* logger_list, struct log_msg* log_msg) {
  int ret = logdOpen(logger_list)
}

static int logdOpen(struct logger_list* logger_list) {
  sock = socket_local_client("logdr", SOCK_SEQPACKET)
  ret = TEMP_FAILURE_RETRY(write(sock, buffer, cp - buffer))
}

static int socket_local_client(const std::string& name, int type) {
  std::string path = "/dev/socket/" + name;
  strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path))
  int fd = socket(AF_LOCAL, type | SOCK_CLOEXEC, 0)
  connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值