mirror of
https://gitee.com/openharmony/developtools_hdc
synced 2024-11-24 07:31:06 +00:00
Move register to hdc
Signed-off-by: zhaolihui <zhaolihui2@huawei.com>
This commit is contained in:
parent
1425ec71ef
commit
ca1a4844e1
44
BUILD.gn
44
BUILD.gn
@ -302,6 +302,7 @@ group("hdc_target") {
|
||||
":hdc",
|
||||
":hdcd_system",
|
||||
":hdcd_updater",
|
||||
":hdc_register",
|
||||
]
|
||||
}
|
||||
|
||||
@ -333,3 +334,46 @@ action("hdc_hash_gen") {
|
||||
]
|
||||
public_configs = [ ":hdc_config" ]
|
||||
}
|
||||
|
||||
config("hdc_register_config") {
|
||||
cflags_cc = [
|
||||
"-fexceptions",
|
||||
"-fno-complete-member-pointers",
|
||||
"-Wno-implicit-fallthrough",
|
||||
"-fvisibility=default",
|
||||
"-frtti",
|
||||
"-std=c++17",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_shared_library("hdc_register") {
|
||||
deps = []
|
||||
defines = [
|
||||
"JS_JDWP_CONNECT",
|
||||
"HDC_HILOG",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"hilog:libhilog",
|
||||
"c_utils:utilsbase",
|
||||
]
|
||||
|
||||
deps += [
|
||||
"//third_party/bounds_checking_function:libsec_shared",
|
||||
"//third_party/libuv:uv",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"//commonlibrary/c_utils/base/include",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"src/register/hdc_connect.cpp",
|
||||
"src/register/hdc_jdwp.cpp",
|
||||
]
|
||||
|
||||
configs = [ ":hdc_register_config" ]
|
||||
|
||||
subsystem_name = "developtools"
|
||||
part_name = "hdc"
|
||||
}
|
||||
|
@ -36,7 +36,8 @@
|
||||
"build": {
|
||||
"sub_component": [
|
||||
"//developtools/hdc:hdcd_system",
|
||||
"//developtools/hdc:hdcd_updater"
|
||||
"//developtools/hdc:hdcd_updater",
|
||||
"//developtools/hdc:hdc_register"
|
||||
],
|
||||
"test": [ "//developtools/hdc/test:hdc_fuzztest" ]
|
||||
}
|
||||
|
48
src/register/define_register.h
Normal file
48
src/register/define_register.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef HDC_REGISTER_H
|
||||
#define HDC_REGISTER_H
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <securec.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <uv.h>
|
||||
#ifdef HDC_HILOG
|
||||
#include "hilog/log.h"
|
||||
#endif
|
||||
|
||||
static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = {LOG_CORE, 0xD002D13, "HDC_LOG"};
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
enum class RetErrCode {
|
||||
SUCCESS = 0,
|
||||
ERR_GENERIC = -1,
|
||||
ERR_BUF_ALLOC = -2,
|
||||
};
|
||||
const string HANDSHAKE_MESSAGE = "OHOS HDC-HELLO";
|
||||
// str one of ark:pid@com.xxx.xxxx, ark:pid@Debugger, ark:pid@tid@Debugger
|
||||
using Callback = std::function<void(int fd, std::string str)>;
|
||||
#endif // end HDC_REGISTER_H
|
120
src/register/hdc_connect.cpp
Normal file
120
src/register/hdc_connect.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hdc_connect.h"
|
||||
#include "hdc_jdwp.h"
|
||||
|
||||
namespace Hdc {
|
||||
|
||||
std::unique_ptr<ConnectManagement> g_connectManagement = nullptr;
|
||||
static HdcJdwpSimulator *clsHdcJdwpSimulator = nullptr;
|
||||
|
||||
void ConnectManagement::SetProcessName(const std::string &processName)
|
||||
{
|
||||
processName_ = processName;
|
||||
}
|
||||
|
||||
std::string ConnectManagement::GetProcessName()
|
||||
{
|
||||
return processName_;
|
||||
}
|
||||
|
||||
void ConnectManagement::SetPkgName(const std::string &pkgName)
|
||||
{
|
||||
pkgName_ = pkgName;
|
||||
}
|
||||
|
||||
std::string ConnectManagement::GetPkgName()
|
||||
{
|
||||
return pkgName_;
|
||||
}
|
||||
|
||||
void ConnectManagement::SetDebug(bool isDebug)
|
||||
{
|
||||
isDebug_ = isDebug;
|
||||
}
|
||||
|
||||
bool ConnectManagement::GetDebug()
|
||||
{
|
||||
return isDebug_;
|
||||
}
|
||||
|
||||
void ConnectManagement::SetCallback(Callback cb)
|
||||
{
|
||||
cb_ = cb;
|
||||
}
|
||||
|
||||
Callback ConnectManagement::GetCallback()
|
||||
{
|
||||
return cb_;
|
||||
}
|
||||
|
||||
void FreeInstance()
|
||||
{
|
||||
if (clsHdcJdwpSimulator == nullptr) {
|
||||
return; // if clsHdcJdwpSimulator is nullptr, should return immediately.
|
||||
}
|
||||
clsHdcJdwpSimulator->Disconnect();
|
||||
delete clsHdcJdwpSimulator;
|
||||
clsHdcJdwpSimulator = nullptr;
|
||||
}
|
||||
|
||||
void Stop(int signo)
|
||||
{
|
||||
FreeInstance();
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
void StopConnect()
|
||||
{
|
||||
#ifdef JS_JDWP_CONNECT
|
||||
FreeInstance();
|
||||
#endif // JS_JDWP_CONNECT
|
||||
}
|
||||
|
||||
void* HdcConnectRun(void* pkgContent)
|
||||
{
|
||||
if (signal(SIGINT, Stop) == SIG_ERR) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "jdwp_process signal fail.");
|
||||
}
|
||||
std::string processName = static_cast<ConnectManagement*>(pkgContent)->GetProcessName();
|
||||
std::string pkgName = static_cast<ConnectManagement*>(pkgContent)->GetPkgName();
|
||||
bool isDebug = static_cast<ConnectManagement*>(pkgContent)->GetDebug();
|
||||
Callback cb = static_cast<ConnectManagement*>(pkgContent)->GetCallback();
|
||||
clsHdcJdwpSimulator = new (std::nothrow) HdcJdwpSimulator(processName, pkgName, isDebug, cb);
|
||||
if (!clsHdcJdwpSimulator->Connect()) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "Connect fail.");
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void StartConnect(const std::string& processName, const std::string& pkgName, bool isDebug, Callback cb)
|
||||
{
|
||||
if (clsHdcJdwpSimulator != nullptr) {
|
||||
return;
|
||||
}
|
||||
pthread_t tid;
|
||||
g_connectManagement = std::make_unique<ConnectManagement>();
|
||||
g_connectManagement->SetProcessName(processName);
|
||||
g_connectManagement->SetPkgName(pkgName);
|
||||
g_connectManagement->SetDebug(isDebug);
|
||||
g_connectManagement->SetCallback(cb);
|
||||
if (pthread_create(&tid, nullptr, &HdcConnectRun, static_cast<void*>(g_connectManagement.get())) != 0) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "pthread_create fail!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // namespace Hdc
|
56
src/register/hdc_connect.h
Normal file
56
src/register/hdc_connect.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef REGISTER_HDC_CONNECT_H
|
||||
#define REGISTER_HDC_CONNECT_H
|
||||
|
||||
#include <string>
|
||||
#include "define_register.h"
|
||||
namespace Hdc {
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
void StartConnect(const std::string& processName, const std::string& pkgName, bool isDebug, Callback cb);
|
||||
void StopConnect();
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
class ConnectManagement {
|
||||
public:
|
||||
ConnectManagement() = default;
|
||||
~ConnectManagement() {}
|
||||
void SetProcessName(const std::string& processName);
|
||||
std::string GetProcessName();
|
||||
void SetPkgName(const std::string& pkgName);
|
||||
std::string GetPkgName();
|
||||
void SetDebug(bool isDebug);
|
||||
bool GetDebug();
|
||||
void SetCallback(Callback cb);
|
||||
Callback GetCallback();
|
||||
|
||||
private:
|
||||
std::string processName_;
|
||||
std::string pkgName_;
|
||||
bool isDebug_;
|
||||
Callback cb_;
|
||||
};
|
||||
} // namespace Hdc
|
||||
|
||||
#endif // REGISTER_HDC_CONNECT_H
|
244
src/register/hdc_jdwp.cpp
Normal file
244
src/register/hdc_jdwp.cpp
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#include "hdc_jdwp.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
namespace Hdc {
|
||||
|
||||
HdcJdwpSimulator::HdcJdwpSimulator(const std::string processName, const std::string pkgName, bool isDebug, Callback cb)
|
||||
{
|
||||
processName_ = processName;
|
||||
pkgName_ = pkgName;
|
||||
isDebug_ = isDebug;
|
||||
cb_ = cb;
|
||||
cfd_ = -1;
|
||||
ctxPoint_ = (HCtxJdwpSimulator)MallocContext();
|
||||
disconnectFlag_ = false;
|
||||
}
|
||||
|
||||
void HdcJdwpSimulator::Disconnect()
|
||||
{
|
||||
if (ctxPoint_ != nullptr && ctxPoint_->cfd > -1) {
|
||||
disconnectFlag_ = true;
|
||||
shutdown(ctxPoint_->cfd, SHUT_RDWR);
|
||||
close(ctxPoint_->cfd);
|
||||
ctxPoint_->cfd = -1;
|
||||
unsigned int threadDelay = 500000;
|
||||
usleep(threadDelay);
|
||||
if (readThread_.joinable()) {
|
||||
readThread_.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HdcJdwpSimulator::~HdcJdwpSimulator()
|
||||
{
|
||||
if (ctxPoint_ != nullptr) {
|
||||
if (ctxPoint_->cfd > -1) {
|
||||
disconnectFlag_ = true;
|
||||
shutdown(ctxPoint_->cfd, SHUT_RDWR);
|
||||
close(ctxPoint_->cfd);
|
||||
ctxPoint_->cfd = -1;
|
||||
}
|
||||
delete ctxPoint_;
|
||||
ctxPoint_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool HdcJdwpSimulator::SendToJpid(int fd, const uint8_t *buf, const int bufLen)
|
||||
{
|
||||
OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "SendToJpid: %{public}s, %{public}d", buf, bufLen);
|
||||
ssize_t rc = write(fd, buf, bufLen);
|
||||
if (rc < 0) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "SendToJpid failed errno:%{public}d", errno);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HdcJdwpSimulator::ConnectJpid(void *param)
|
||||
{
|
||||
uint32_t pid_curr = static_cast<uint32_t>(getpid());
|
||||
HdcJdwpSimulator *thisClass = static_cast<HdcJdwpSimulator *>(param);
|
||||
#ifdef JS_JDWP_CONNECT
|
||||
string processName = thisClass->processName_;
|
||||
string pkgName = thisClass->pkgName_;
|
||||
bool isDebug = thisClass->isDebug_;
|
||||
string pp = pkgName;
|
||||
if (!processName.empty()) {
|
||||
pp += "/" + processName;
|
||||
}
|
||||
uint32_t ppSize = pp.size() + sizeof(JsMsgHeader);
|
||||
uint8_t* info = new (std::nothrow) uint8_t[ppSize]();
|
||||
if (info == nullptr) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "ConnectJpid new info fail.");
|
||||
return false;
|
||||
}
|
||||
if (memset_s(info, ppSize, 0, ppSize) != EOK) {
|
||||
delete[] info;
|
||||
info = nullptr;
|
||||
return false;
|
||||
}
|
||||
JsMsgHeader *jsMsg = reinterpret_cast<JsMsgHeader *>(info);
|
||||
jsMsg->msgLen = ppSize;
|
||||
jsMsg->pid = pid_curr;
|
||||
jsMsg->isDebug = isDebug;
|
||||
OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "ConnectJpid send pid:%{public}d, pp:%{public}s, isDebug:%{public}d, msglen:%{public}d",
|
||||
jsMsg->pid, pp.c_str(), isDebug, jsMsg->msgLen);
|
||||
bool ret = true;
|
||||
if (memcpy_s(info + sizeof(JsMsgHeader), pp.size(), &pp[0], pp.size()) != EOK) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "ConnectJpid memcpy_s fail :%{public}s.", pp.c_str());
|
||||
ret = false;
|
||||
} else {
|
||||
OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "ConnectJpid send JS msg:%{public}s", info);
|
||||
ret = SendToJpid(thisClass->ctxPoint_->cfd, (uint8_t*)info, ppSize);
|
||||
}
|
||||
delete[] info;
|
||||
return ret;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void *HdcJdwpSimulator::MallocContext()
|
||||
{
|
||||
HCtxJdwpSimulator ctx = nullptr;
|
||||
if ((ctx = new (std::nothrow) ContextJdwpSimulator()) == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
ctx->thisClass = this;
|
||||
ctx->cfd = -1;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
bool HdcJdwpSimulator::Connect()
|
||||
{
|
||||
const char jdwp[] = { '\0', 'o', 'h', 'j', 'p', 'i', 'd', '-', 'c', 'o', 'n', 't', 'r', 'o', 'l', 0 };
|
||||
if (ctxPoint_ == nullptr) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "MallocContext failed");
|
||||
return false;
|
||||
}
|
||||
struct sockaddr_un caddr;
|
||||
if (memset_s(&caddr, sizeof(caddr), 0, sizeof(caddr)) != EOK) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "memset_s failed");
|
||||
return false;
|
||||
}
|
||||
caddr.sun_family = AF_UNIX;
|
||||
for (size_t i = 0; i < sizeof(jdwp); i++) {
|
||||
caddr.sun_path[i] = jdwp[i];
|
||||
}
|
||||
cfd_ = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (cfd_ < 0) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "socket failed errno:%{public}d", errno);
|
||||
return false;
|
||||
}
|
||||
ctxPoint_->cfd = cfd_;
|
||||
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
setsockopt(cfd_, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
||||
size_t caddrLen = sizeof(caddr.sun_family) + sizeof(jdwp) - 1;
|
||||
int rc = connect(cfd_, reinterpret_cast<struct sockaddr *>(&caddr), caddrLen);
|
||||
if (rc != 0) {
|
||||
OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "connect failed errno:%{public}d", errno);
|
||||
close(cfd_);
|
||||
return false;
|
||||
}
|
||||
if (ConnectJpid(this)) {
|
||||
ReadStart();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t HdcJdwpSimulator::Bytes2Int(uint8_t b[])
|
||||
{
|
||||
int32_t value = 0;
|
||||
value = (b[0] & 0xFF);
|
||||
value |= ((b[1] << 8) & 0xFF00);
|
||||
value |= ((b[2] << 16) & 0xFF0000);
|
||||
value |= ((b[3] << 24) & 0xFF000000);
|
||||
return value;
|
||||
}
|
||||
|
||||
void HdcJdwpSimulator::ReadStart()
|
||||
{
|
||||
readThread_ = std::thread(ReadWork, this);
|
||||
}
|
||||
|
||||
void HdcJdwpSimulator::ReadWork(void *param)
|
||||
{
|
||||
HdcJdwpSimulator *jdwp = (HdcJdwpSimulator *)param;
|
||||
jdwp->Read();
|
||||
}
|
||||
|
||||
void HdcJdwpSimulator::Read()
|
||||
{
|
||||
constexpr size_t size = 256;
|
||||
constexpr long sec = 5;
|
||||
uint8_t buf[size] = { 0 };
|
||||
while(!disconnectFlag_) {
|
||||
ssize_t cnt = 0;
|
||||
fd_set rset;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = sec;
|
||||
timeout.tv_usec = 0;
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(cfd_, &rset);
|
||||
int rc = select(cfd_ + 1, &rset, nullptr, nullptr, &timeout);
|
||||
if (rc < 0) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "Read select fd:%{public}d error:%{public}d", cfd_, errno);
|
||||
break;
|
||||
} else if (rc == 0) {
|
||||
continue;
|
||||
}
|
||||
if (memset_s(buf, size, 0, size) != EOK) {
|
||||
continue;
|
||||
}
|
||||
struct iovec iov;
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = size - 1;
|
||||
struct msghdr msg;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
int len = CMSG_SPACE(static_cast<unsigned int>(sizeof(int)));
|
||||
char ctlBuf[len];
|
||||
msg.msg_controllen = sizeof(ctlBuf);
|
||||
msg.msg_control = ctlBuf;
|
||||
cnt = recvmsg(cfd_, &msg, 0);
|
||||
if (cnt <= 0) {
|
||||
break;
|
||||
} else if (0 < cnt && cnt < 5) {
|
||||
continue;
|
||||
}
|
||||
int32_t fd = Bytes2Int(buf);
|
||||
std::string str = (char *)(buf + 4);
|
||||
OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "Read fd:%{public}d str:%{public}s", fd, str.c_str());
|
||||
struct cmsghdr *cmsg;
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != nullptr; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_type != SCM_RIGHTS) {
|
||||
continue;
|
||||
}
|
||||
int *newfd = (int *) CMSG_DATA(cmsg);
|
||||
OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "Read fd:%{public}d newfd:%{public}d str:%{public}s", fd, *newfd, str.c_str());
|
||||
if (cb_) {
|
||||
cb_(*newfd, str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Hdc
|
64
src/register/hdc_jdwp.h
Normal file
64
src/register/hdc_jdwp.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef REGISTER_HDC_JDWP_H
|
||||
#define REGISTER_HDC_JDWP_H
|
||||
|
||||
#include "define_register.h"
|
||||
|
||||
namespace Hdc {
|
||||
class HdcJdwpSimulator;
|
||||
|
||||
class HdcJdwpSimulator {
|
||||
public:
|
||||
explicit HdcJdwpSimulator(string processName, string pkgName, bool isDebug, Callback cb);
|
||||
~HdcJdwpSimulator();
|
||||
bool Connect();
|
||||
void Disconnect();
|
||||
|
||||
protected:
|
||||
struct ContextJdwpSimulator {
|
||||
int cfd;
|
||||
HdcJdwpSimulator *thisClass;
|
||||
};
|
||||
using HCtxJdwpSimulator = struct ContextJdwpSimulator *;
|
||||
|
||||
private:
|
||||
struct JsMsgHeader {
|
||||
uint32_t msgLen;
|
||||
uint32_t pid;
|
||||
uint8_t isDebug; // 1:debug 0:release
|
||||
};
|
||||
void *MallocContext();
|
||||
static bool ConnectJpid(void *param);
|
||||
static bool SendToJpid(int fd, const uint8_t *buf, const int bufLen);
|
||||
HCtxJdwpSimulator ctxPoint_;
|
||||
string processName_;
|
||||
string pkgName_;
|
||||
bool isDebug_;
|
||||
Callback cb_;
|
||||
int cfd_;
|
||||
std::atomic<bool> disconnectFlag_;
|
||||
|
||||
static int32_t Bytes2Int(uint8_t b[]);
|
||||
std::thread readThread_;
|
||||
static void ReadWork(void *param);
|
||||
void Read();
|
||||
void ReadStart();
|
||||
void TidCallback(std::string id, int fd);
|
||||
};
|
||||
} // namespace Hdc
|
||||
#endif // REGISTER_HDC_JDWP_H
|
@ -297,6 +297,7 @@ group("hdc_unittest") {
|
||||
":hdc_jdwp_unittest",
|
||||
":hdc_uart_unittest",
|
||||
":hdc_uart_unittest(${host_toolchain})",
|
||||
":hdc_register_unittest",
|
||||
]
|
||||
}
|
||||
|
||||
@ -325,6 +326,24 @@ config("hdc_test_config") {
|
||||
]
|
||||
}
|
||||
|
||||
config("hdc_register_config") {
|
||||
cflags = code_check_flag
|
||||
ldflags = []
|
||||
defines = [ "HDC_HILOG" ]
|
||||
|
||||
if (hdc_test_coverage && is_ohos) {
|
||||
defines += [ "TEST_COVERAGE" ]
|
||||
cflags += [
|
||||
"-fprofile-arcs",
|
||||
"-ftest-coverage",
|
||||
]
|
||||
ldflags += [ "--coverage" ]
|
||||
}
|
||||
if (js_jdwp_connect) {
|
||||
defines += [ "JS_JDWP_CONNECT" ]
|
||||
}
|
||||
}
|
||||
|
||||
fuzz_cflags = [
|
||||
"-O0",
|
||||
"-Wno-unused-variable",
|
||||
@ -348,3 +367,32 @@ group("hdc_fuzztest") {
|
||||
testonly = true
|
||||
deps = [ ":JdwpReadStreamFuzzTest" ]
|
||||
}
|
||||
|
||||
ohos_unittest("hdc_register_unittest") {
|
||||
module_out_path = module_output_path
|
||||
resource_config_file = "unittest/resource/ohos_test.xml"
|
||||
|
||||
sources = [
|
||||
"${hdc_path}/src/register/hdc_connect.cpp",
|
||||
"${hdc_path}/src/register/hdc_jdwp.cpp",
|
||||
"unittest/register/register_test.cpp",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"${hdc_path}/src/register/"
|
||||
]
|
||||
|
||||
configs = [ ":hdc_register_config" ]
|
||||
|
||||
deps = [
|
||||
"//third_party/googletest:gmock_main",
|
||||
"//third_party/libuv:uv",
|
||||
]
|
||||
external_deps = [
|
||||
"c_utils:utils",
|
||||
"hilog:libhilog",
|
||||
]
|
||||
|
||||
subsystem_name = "developtools"
|
||||
part_name = "hdc"
|
||||
}
|
||||
|
241
test/unittest/register/register_test.cpp
Normal file
241
test/unittest/register/register_test.cpp
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
# Copyright (c) 2023 iSoftStone Information Technology (Group) Co.,Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define private public
|
||||
#define protected public
|
||||
#include "define_register.h"
|
||||
#include "hdc_connect.h"
|
||||
#include "hdc_jdwp.h"
|
||||
#undef private
|
||||
#undef protected
|
||||
|
||||
using namespace testing;
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace Hdc {
|
||||
extern std::unique_ptr<ConnectManagement> g_connectManagement;
|
||||
class RegisterTest : public testing::Test {};
|
||||
|
||||
/**
|
||||
* @tc.name: CastToRegisterTest001
|
||||
* @tc.desc: Test cast to register.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RegisterTest, CastToRegisterTest001, TestSize.Level1)
|
||||
{
|
||||
/**
|
||||
* @tc.steps: step1. stop connect before start.
|
||||
* @tc.expected: step1. g_connectManagement is null.
|
||||
*/
|
||||
StopConnect();
|
||||
EXPECT_EQ(g_connectManagement, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: CastToRegisterTest002
|
||||
* @tc.desc: Test cast to register.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RegisterTest, CastToRegisterTest002, TestSize.Level1)
|
||||
{
|
||||
/**
|
||||
* @tc.steps: step1. start connect.
|
||||
* @tc.expected: step1. g_connectManagement is not null and the pktName is right.
|
||||
*/
|
||||
StartConnect("", "test_pkt_name", true, nullptr);
|
||||
ASSERT_NE(g_connectManagement, nullptr);
|
||||
EXPECT_EQ(g_connectManagement->GetPkgName(), "test_pkt_name");
|
||||
|
||||
/**
|
||||
* @tc.steps: step2. sleep 3 second.
|
||||
*/
|
||||
sleep(3);
|
||||
|
||||
/**
|
||||
# @tc.steps: step3. stop connect.
|
||||
* @tc.expected: step3. g_connectManagement is not null
|
||||
*/
|
||||
StopConnect();
|
||||
ASSERT_NE(g_connectManagement, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: CastToRegisterTest003
|
||||
* @tc.desc: Test cast to register.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RegisterTest, CastToRegisterTest003, TestSize.Level1)
|
||||
{
|
||||
/**
|
||||
* @tc.steps: step1. start connect.
|
||||
* @tc.expected: step1. g_connectManagement is not null and the pktName is right.
|
||||
*/
|
||||
StartConnect("", "test_pkt_name", true, nullptr);
|
||||
ASSERT_NE(g_connectManagement, nullptr);
|
||||
EXPECT_EQ(g_connectManagement->GetPkgName(), "test_pkt_name");
|
||||
|
||||
/**
|
||||
* @tc.steps: step2. sleep 3 second.
|
||||
*/
|
||||
sleep(3);
|
||||
|
||||
/**
|
||||
# @tc.steps: step3. start connect again
|
||||
* @tc.expected: step3. start fail and g_connectManagement is not null and the pktName is same with first start.
|
||||
*/
|
||||
StartConnect("", "test_pkt_name_2", true, nullptr);
|
||||
ASSERT_NE(g_connectManagement, nullptr);
|
||||
EXPECT_EQ(g_connectManagement->GetPkgName(), "test_pkt_name");
|
||||
}
|
||||
|
||||
HdcJdwpSimulator* g_hdcJdwpSimulator = nullptr;
|
||||
bool g_threadRunning = false;
|
||||
void* HdcConnectRun_Test(void* pkgContent)
|
||||
{
|
||||
g_threadRunning = true;
|
||||
std::string pkgName = static_cast<ConnectManagement*>(pkgContent)->GetPkgName();
|
||||
std::string processName = static_cast<ConnectManagement*>(pkgContent)->GetProcessName();
|
||||
bool isDebug = static_cast<ConnectManagement*>(pkgContent)->GetDebug();
|
||||
g_hdcJdwpSimulator = new (std::nothrow) HdcJdwpSimulator(processName, pkgName, isDebug, nullptr);
|
||||
if (!g_hdcJdwpSimulator->Connect()) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "Connect fail.");
|
||||
g_threadRunning = false;
|
||||
return nullptr;
|
||||
}
|
||||
g_threadRunning = false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: CastToRegisterTest005
|
||||
* @tc.desc: Test cast to HdcJdwpSimulator.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RegisterTest, CastToRegisterTest005, TestSize.Level1)
|
||||
{
|
||||
/**
|
||||
* @tc.steps: step1. new a ConnectManagement and start the connect thread
|
||||
* @tc.expected: step1. connect ok, the thread is runed.
|
||||
*/
|
||||
pthread_t tid;
|
||||
g_connectManagement = std::make_unique<ConnectManagement>();
|
||||
g_connectManagement->SetPkgName("test_pkt_name");
|
||||
if (pthread_create(&tid, nullptr, &HdcConnectRun_Test, static_cast<void*>(g_connectManagement.get())) != 0) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "pthread_create fail!");
|
||||
return;
|
||||
}
|
||||
sleep(3);
|
||||
EXPECT_FALSE(g_threadRunning);
|
||||
|
||||
/**
|
||||
* @tc.steps: step2. Call disconnect and delete the HdcJdwpSimulator
|
||||
* @tc.expected: step2. Disconnect ok, the thread is stopped.
|
||||
*/
|
||||
g_hdcJdwpSimulator->Disconnect();
|
||||
delete g_hdcJdwpSimulator;
|
||||
g_hdcJdwpSimulator = nullptr;
|
||||
sleep(2);
|
||||
EXPECT_FALSE(g_threadRunning);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: CastToRegisterTest006
|
||||
* @tc.desc: Test cast to ConnectJpid.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RegisterTest, CastToRegisterTest006, TestSize.Level1)
|
||||
{
|
||||
/**
|
||||
* @tc.steps: step1. new a ConnectManagement and start the connect thread
|
||||
* @tc.expected: step1. connect ok, the thread is runed.
|
||||
*/
|
||||
auto hdcJdwpSimulator = std::make_unique<HdcJdwpSimulator>("", "test_pkt_name", true, nullptr);
|
||||
auto retFlag = hdcJdwpSimulator->ConnectJpid((void*)hdcJdwpSimulator.get());
|
||||
|
||||
EXPECT_FALSE(retFlag);
|
||||
}
|
||||
|
||||
bool g_isCtxPointNull = false;
|
||||
void* ConnectJpidTest(void* pkgName)
|
||||
{
|
||||
g_threadRunning = true;
|
||||
|
||||
std::string name = (char*)pkgName;
|
||||
g_hdcJdwpSimulator = new (std::nothrow) HdcJdwpSimulator(name, name, true, nullptr);
|
||||
if (g_isCtxPointNull) {
|
||||
delete g_hdcJdwpSimulator->ctxPoint_;
|
||||
g_hdcJdwpSimulator->ctxPoint_ = nullptr;
|
||||
} else {
|
||||
g_hdcJdwpSimulator->ctxPoint_->cfd = 1;
|
||||
}
|
||||
|
||||
if (!g_hdcJdwpSimulator->Connect()) {
|
||||
OHOS::HiviewDFX::HiLog::Fatal(LOG_LABEL, "Connect fail.");
|
||||
}
|
||||
g_threadRunning = false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: CastToRegisterTest006
|
||||
* @tc.desc: Test cast to Connect.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RegisterTest, CastToRegisterTest007, TestSize.Level1)
|
||||
{
|
||||
/**
|
||||
* @tc.steps: step1. new a ConnectManagement and start the connect thread
|
||||
* @tc.expected: step1. connect ok, the thread is runed.
|
||||
*/
|
||||
pthread_t tid;
|
||||
g_hdcJdwpSimulator = nullptr;
|
||||
g_threadRunning = false;
|
||||
string pkgName = "test_pkt_name";
|
||||
ASSERT_EQ(pthread_create(&tid, nullptr, &ConnectJpidTest, (void*)pkgName.c_str()), 0);
|
||||
sleep(3);
|
||||
EXPECT_FALSE(g_threadRunning);
|
||||
|
||||
/**
|
||||
* @tc.steps: step2. Call disconnect and delete the HdcJdwpSimulator
|
||||
* @tc.expected: step2. Disconnect ok, the thread is stopped.
|
||||
*/
|
||||
g_hdcJdwpSimulator->Disconnect();
|
||||
delete g_hdcJdwpSimulator;
|
||||
g_hdcJdwpSimulator = nullptr;
|
||||
sleep(2);
|
||||
EXPECT_FALSE(g_threadRunning);
|
||||
|
||||
/**
|
||||
* @tc.steps: step3. new a HdcJdwpSimulator and start the connect thread
|
||||
* @tc.expected: step3. connect failed
|
||||
*/
|
||||
pthread_t tid2;
|
||||
g_hdcJdwpSimulator = nullptr;
|
||||
g_threadRunning = false;
|
||||
g_isCtxPointNull = true;
|
||||
ASSERT_EQ(pthread_create(&tid2, nullptr, &ConnectJpidTest, (void*)pkgName.c_str()), 0);
|
||||
sleep(3);
|
||||
EXPECT_FALSE(g_threadRunning);
|
||||
|
||||
g_hdcJdwpSimulator->Disconnect();
|
||||
delete g_hdcJdwpSimulator;
|
||||
g_hdcJdwpSimulator = nullptr;
|
||||
}
|
||||
} // namespace Hdc
|
Loading…
Reference in New Issue
Block a user