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",
|
":hdc",
|
||||||
":hdcd_system",
|
":hdcd_system",
|
||||||
":hdcd_updater",
|
":hdcd_updater",
|
||||||
|
":hdc_register",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,3 +334,46 @@ action("hdc_hash_gen") {
|
|||||||
]
|
]
|
||||||
public_configs = [ ":hdc_config" ]
|
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": {
|
"build": {
|
||||||
"sub_component": [
|
"sub_component": [
|
||||||
"//developtools/hdc:hdcd_system",
|
"//developtools/hdc:hdcd_system",
|
||||||
"//developtools/hdc:hdcd_updater"
|
"//developtools/hdc:hdcd_updater",
|
||||||
|
"//developtools/hdc:hdc_register"
|
||||||
],
|
],
|
||||||
"test": [ "//developtools/hdc/test:hdc_fuzztest" ]
|
"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_jdwp_unittest",
|
||||||
":hdc_uart_unittest",
|
":hdc_uart_unittest",
|
||||||
":hdc_uart_unittest(${host_toolchain})",
|
":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 = [
|
fuzz_cflags = [
|
||||||
"-O0",
|
"-O0",
|
||||||
"-Wno-unused-variable",
|
"-Wno-unused-variable",
|
||||||
@ -348,3 +367,32 @@ group("hdc_fuzztest") {
|
|||||||
testonly = true
|
testonly = true
|
||||||
deps = [ ":JdwpReadStreamFuzzTest" ]
|
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