!104 支持hdi gpu混合合成

Change-Id: I3685730a57a8785eeee60fb967bb0abefd50232b
Signed-off-by: lizheng <lizheng2@huawei.com>
This commit is contained in:
lizheng 2021-12-06 10:25:21 +08:00
parent 438fc3aa62
commit a62570f4c8
88 changed files with 5467 additions and 205 deletions

View File

@ -69,3 +69,7 @@ group("libgl") {
] ]
public_deps += libgl public_deps += libgl
} }
group("libgraphic_dumper_client") {
public_deps = [ "frameworks/dumper:libgraphic_dumper_client" ]
}

178
frameworks/dumper/BUILD.gn Executable file
View File

@ -0,0 +1,178 @@
# 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.
import("//build/ohos.gni")
## Build libgraphic_dumper_client.so {{{
config("graphic_dumper_client_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"//utils/system/safwk/native/include",
]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
config("graphic_dumper_client_public_config") {
include_dirs = [
"//foundation/graphic/standard/interfaces/innerkits/dumper",
"//foundation/graphic/standard/interfaces/innerkits/common",
"//utils/native/base/include",
]
}
ohos_shared_library("libgraphic_dumper_client") {
sources = [
"src/graphic_dumper_helper.cpp",
"src/graphic_dumper_helper_impl.cpp",
"src/ipc/graphic_dumper_client_listener_stub.cpp",
"src/ipc/graphic_dumper_service_proxy.cpp",
]
configs = [ ":graphic_dumper_client_config" ]
public_configs = [ ":graphic_dumper_client_public_config" ]
deps = [
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
]
external_deps = [ "ipc:ipc_core" ]
public_deps = [ "//utils/native/base:utils" ]
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Build libgraphic_dumper_client.so }}}
## Build graphic_dumper_server {{{
config("graphic_dumper_server_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"//utils/system/safwk/native/include",
]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
ohos_executable("graphic_dumper_server") {
install_enable = true
sources = [
"src/graphic_dumper_server.cpp",
"src/graphic_dumper_server_main.cpp",
"src/graphic_dumper_tree.cpp",
"src/graphic_dumper_util.cpp",
"src/ipc/graphic_dumper_client_listener_death_recipient.cpp",
"src/ipc/graphic_dumper_client_listener_proxy.cpp",
"src/ipc/graphic_dumper_command_stub.cpp",
"src/ipc/graphic_dumper_info_listener_death_recipient.cpp",
"src/ipc/graphic_dumper_info_listener_proxy.cpp",
"src/ipc/graphic_dumper_service_stub.cpp",
]
configs = [
":graphic_dumper_server_config",
":graphic_dumper_client_public_config",
]
deps = [
"//third_party/zlib:libz",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_standard:samgr_proxy",
]
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Build graphic_dumper_server }}}
## Build gdumper {{{
config("gdumper_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"//utils/system/safwk/native/include",
]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
ohos_executable("gdumper") {
install_enable = true
sources = [
"src/graphic_dumper_command_line.cpp",
"src/graphic_dumper_command_line_main.cpp",
"src/graphic_dumper_util.cpp",
"src/ipc/graphic_dumper_command_stub.cpp",
"src/ipc/graphic_dumper_info_listener_stub.cpp",
"src/ipc/graphic_dumper_service_stub.cpp",
]
configs = [
":gdumper_config",
":graphic_dumper_client_public_config",
]
deps = [
"//foundation/graphic/standard/utils:promise",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_standard:samgr_proxy",
]
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Build gdumper }}}
## Install gdumper.ini to /system/etc/./gdumper.ini {{{
ohos_prebuilt_etc("gdumper.ini") {
source = "gdumper.ini"
relative_install_dir = "."
part_name = "graphic_standard"
subsystem_name = "graphic"
}
## Install gdumper.ini to /system/etc/./gdumper.ini }}}

View File

@ -0,0 +1,15 @@
# 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.
# [dumper]
# A.B=true

View File

@ -0,0 +1,63 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_LINE_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_LINE_H
#include <promise.h>
#include <string>
#include "ipc/graphic_dumper_info_listener_stub.h"
#include "ipc/igraphic_dumper_command.h"
namespace OHOS {
using DumperArgs = struct {
bool wait = false;
std::string dumpTag = {};
std::string logTag = {};
std::string getCfgKey = {};
std::string setCfgKey = {};
std::string setCfgValue = {};
};
class GraphicDumperCommandLine : public GraphicDumperInfoListenerStub {
public:
static sptr<GraphicDumperCommandLine> GetInstance();
virtual void OnInfoComing(const std::string &info) override;
GSError Main(int32_t argc, char *argv[]);
private:
GraphicDumperCommandLine() = default;
~GraphicDumperCommandLine() = default;
static inline sptr<GraphicDumperCommandLine> instance_;
void HandlerOfArgs();
GSError OptionParse(const char option);
GSError Parse(int32_t argc, char *argv[]);
GSError InitSA(int32_t systemAbilityId);
sptr<IGraphicDumperCommand> service_;
DumperArgs dumperArgs_ = {};
};
class GDumperCommandDeathRecipient : public IRemoteObject::DeathRecipient {
public:
GDumperCommandDeathRecipient() = default;
virtual ~GDumperCommandDeathRecipient() = default;
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_LINE_H

View File

@ -0,0 +1,133 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_HELPER_IMPL_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_HELPER_IMPL_H
#include <atomic>
#include <mutex>
#include <string>
#include <map>
#include <memory>
#include <graphic_dumper_helper.h>
#include "ipc/graphic_dumper_service_proxy.h"
#include "ipc/graphic_dumper_client_listener_stub.h"
namespace OHOS {
namespace {
class GraphicDumperClientListener;
}
using ConfigFuncMapPtr = std::unique_ptr<std::map<int32_t, OnConfigChangeFunc>>;
using DumpFuncMapPtr = std::unique_ptr<std::map<int32_t, OnDumpFunc>>;
class GraphicDumperHelperImpl : public GraphicDumperHelper {
friend class GraphicDumperClientListener;
public:
static sptr<GraphicDumperHelper> GetInstance();
virtual GSError SendInfo(const std::string &tag, const char *fmt, ...) override;
virtual int32_t AddConfigChangeListener(const std::string &tag, OnConfigChangeFunc func) override;
virtual GSError RemoveConfigChangeListener(const int32_t listenerId) override;
virtual int32_t AddDumpListener(const std::string &tag, OnDumpFunc func) override;
virtual GSError RemoveDumpListener(const int32_t listenerId) override;
void SetConnectState(bool state);
private:
GraphicDumperHelperImpl();
virtual ~GraphicDumperHelperImpl() = default;
static inline sptr<GraphicDumperHelper> currentHelper = nullptr;
static void SetNoopInstance();
GSError Init();
GSError InitSA(int32_t systemAbilityId);
GSError AddClientListener(const std::string &tag);
void DispenseOnConfigChange(const std::string &tag, const std::string &val);
void DispenseOnDump(const std::string &tag);
std::mutex initMutex_;
std::atomic_int64_t requestConnectTime = 0;
std::atomic_bool serverConnected = false;
sptr<IGraphicDumperService> service_ = nullptr;
std::mutex clientListenerMutex_;
sptr<IGraphicDumperClientListener> listener_ = nullptr;
int32_t onConfigChangeFuncId_ = 0;
std::mutex onConfigChangeMutex_;
std::map<std::string, ConfigFuncMapPtr> onConfigChangeMap_;
int32_t onDumperFuncId_ = 0;
std::mutex onDumperFuncsMutex_;
std::map<std::string, DumpFuncMapPtr> onDumpFuncsMap_;
struct InfoStruct {
std::string tag;
std::string info;
};
std::mutex cacheInfoMutex_;
std::vector<InfoStruct> cacheInfo_;
};
class GDumperServiceDeathRecipient : public IRemoteObject::DeathRecipient {
public:
GDumperServiceDeathRecipient() = default;
virtual ~GDumperServiceDeathRecipient() = default;
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
};
class GraphicDumperHelperNoop : public GraphicDumperHelper {
public:
virtual GSError SendInfo(const std::string &tag, const char *fmt, ...)
{
return GSERROR_CONNOT_CONNECT_SERVER;
}
virtual int32_t AddConfigChangeListener(const std::string &tag, OnConfigChangeFunc func)
{
return 0;
}
virtual GSError RemoveConfigChangeListener(const int32_t listenerId)
{
return GSERROR_CONNOT_CONNECT_SERVER;
}
virtual int32_t AddDumpListener(const std::string &tag, OnDumpFunc func)
{
return 0;
}
virtual GSError RemoveDumpListener(const int32_t listenerId)
{
return GSERROR_CONNOT_CONNECT_SERVER;
}
};
namespace {
class GraphicDumperClientListener : public GraphicDumperClientListenerStub {
public:
GraphicDumperClientListener(sptr<GraphicDumperHelperImpl>& helper);
virtual ~GraphicDumperClientListener() = default;
void OnConfigChange(const std::string &tag, const std::string &val) override;
void OnDump(const std::string &tag) override;
private:
sptr<GraphicDumperHelperImpl> helperImpl_ = nullptr;
};
} // namespace
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_HELPER_IMPL_H

View File

@ -0,0 +1,50 @@
/*
* 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 FRAMEWORKS_DUMPER_INCLUDE_GRAPHIC_DUMPER_HILOG_H
#define FRAMEWORKS_DUMPER_INCLUDE_GRAPHIC_DUMPER_HILOG_H
#include "hilog/log.h"
namespace OHOS {
#define GD_CPRINTF(func, fmt, ...) func(LABEL, "<%{public}d>" fmt, __LINE__, ##__VA_ARGS__)
#define GDLOGD(fmt, ...) GD_CPRINTF(HiviewDFX::HiLog::Debug, fmt, ##__VA_ARGS__)
#define GDLOGI(fmt, ...) GD_CPRINTF(HiviewDFX::HiLog::Info, fmt, ##__VA_ARGS__)
#define GDLOGW(fmt, ...) GD_CPRINTF(HiviewDFX::HiLog::Warn, fmt, ##__VA_ARGS__)
#define GDLOGE(fmt, ...) GD_CPRINTF(HiviewDFX::HiLog::Error, fmt, ##__VA_ARGS__)
#define GDLOGFD(fmt, ...) GDLOGD("%{public}s: " fmt, __func__, ##__VA_ARGS__)
#define GDLOGFI(fmt, ...) GDLOGI("%{public}s: " fmt, __func__, ##__VA_ARGS__)
#define GDLOGFW(fmt, ...) GDLOGW("%{public}s: " fmt, __func__, ##__VA_ARGS__)
#define GDLOGFE(fmt, ...) GDLOGE("%{public}s: " fmt, __func__, ##__VA_ARGS__)
#define GDLOG_SUCCESS(fmt, ...) GDLOGI("Success, Way: " fmt, ##__VA_ARGS__)
#define GDLOG_FAILURE(fmt, ...) GDLOGE("Failure, Reason: " fmt, ##__VA_ARGS__)
#define GDLOG_FAILURE_NO(gs_error) GDLOG_FAILURE("%{public}s", GSErrorStr(gs_error).c_str())
#define GDLOG_FAILURE_RET(gs_error) \
do { \
GDLOG_FAILURE_NO(gs_error); \
return gs_error; \
} while (0)
#define GDLOG_FAILURE_API(api, ret) GDLOG_FAILURE(#api " failed with %{public}s", GSErrorStr(ret).c_str())
#define GDLOG_ERROR(errno, fmt, ...) \
GDLOGE(fmt ", means %{public}s", ##__VA_ARGS__, strerror(errno))
#define GDLOG_ERROR_API(ret, api) \
GDLOG_ERROR(ret, #api " failed with %{public}d", ret)
} // namespace OHOS
#endif // FRAMEWORKS_DUMPER_INCLUDE_GRAPHIC_DUMPER_HILOG_H

View File

@ -0,0 +1,116 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVER_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVER_H
#include <any>
#include <map>
#include <memory>
#include <mutex>
#include <vector>
#include <string>
#include <thread>
#include <ipc_skeleton.h>
#include <refbase.h>
#include "graphic_dumper_tree.h"
#include "ipc/igraphic_dumper_client_listener.h"
#include "ipc/igraphic_dumper_command.h"
#include "ipc/igraphic_dumper_info_listener.h"
#include "ipc/igraphic_dumper_service.h"
namespace OHOS {
struct LogBuffer {
bool canSave = false;
bool needSave = false;
bool sync = false;
uint32_t index = 0;
uint32_t size[2] = {0};
std::mutex mutex[2];
std::vector<std::unique_ptr<std::vector<std::string>>> vec;
std::string mask = {};
};
struct LogBlock {
uint32_t size;
uint32_t length;
uint8_t data[0];
};
struct ConfigTags {
uint32_t id = 0;
sptr<IGraphicDumperClientListener> listener = nullptr;
std::vector<std::string> tags = {};
};
class GraphicDumperServer : public RefBase {
public:
static sptr<GraphicDumperServer> GetInstance();
int32_t Init();
GSError AddConfigListener(const std::string &tag, sptr<IGraphicDumperClientListener> &listener);
GSError RemoveConfigListener(sptr<IRemoteObject> object);
GSError GetConfig(const std::string &k, std::string &v);
GSError SetConfig(const std::string &k, const std::string &v);
GSError Dump(const std::string &tag);
GSError AddInfoListener(sptr<IGraphicDumperInfoListener> &listener);
GSError RemoveInfoListener(const wptr<IRemoteObject> &object);
GSError InfoHandle(const std::string &tag, const std::string &info);
GSError GetLog(const std::string &tag, const std::string &info);
private:
GraphicDumperServer() = default;
virtual ~GraphicDumperServer() = default;
static inline sptr<GraphicDumperServer> instance_;
int32_t StartServer(int32_t systemAbility, sptr<IRemoteObject> obj);
int32_t ReadDefaultConfig();
void AddConfigDeathRecipient(sptr<IRemoteObject> &object);
bool HaveConfigDeathRecipient(sptr<IRemoteObject> &object);
bool HaveObject(const sptr<IRemoteObject> &obj);
void VisitEach(const TreeNodePtr &node, std::function<void(const TreeNodePtr&)> func);
void RemoveNode(std::vector<std::string> &vec, TreeNodePtr &sub, uint32_t &listenerId);
void DispenseConfig(const TreeNodePtr &node, const std::string &k, const std::string &v);
void DispenseDump(const TreeNodePtr &node, const std::string &tag);
void AddInfoDeathRecipient(sptr<IRemoteObject> &object);
bool HaveInfoDeathRecipient(sptr<IRemoteObject> &object);
void SendToInfoListener(const std::string &info);
static void SaveLog(std::any server);
GSError LogHandle(const std::string &tag, const std::string &info);
private:
std::mutex infoListenersMutex_;
std::map<sptr<IRemoteObject>, sptr<IGraphicDumperInfoListener>> infoListeners_;
std::map<sptr<IRemoteObject>, sptr<IRemoteObject::DeathRecipient>> infoListenerDeathRecipientMap_;
uint32_t objectId_ = 0;
std::map<uint32_t, ConfigTags> configTagsMap_;
std::map<sptr<IRemoteObject>, uint32_t> objectIdMap_;
std::mutex treeMutex_;
const TreeNodePtr root = std::make_shared<GraphicDumperTree>();
LogBuffer logBuf_;
uint32_t logBlockSize_ = 0;
std::mutex logBlockVectorMutex_;
std::vector<std::unique_ptr<uint8_t[]>> logBlockVector_;
std::unique_ptr<std::thread> thread_ = nullptr;
std::map<sptr<IRemoteObject>, sptr<IRemoteObject::DeathRecipient>> configListenerDeathRecipientMap_;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVER_H

View File

@ -0,0 +1,56 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_TREE_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_TREE_H
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <refbase.h>
#include "ipc/igraphic_dumper_client_listener.h"
namespace OHOS {
class GraphicDumperTree;
using TreeNodePtr = std::shared_ptr<GraphicDumperTree>;
using TreeNodeVisitFunc = std::function<void(const TreeNodePtr &v)>;
using TreeNodeMap = std::map<const std::string, TreeNodePtr>;
class GraphicDumperTree {
public:
TreeNodePtr GetSetNode(const std::string str);
bool HasNode(const std::string str);
bool IsEmptyNode();
void EraseNode(const std::string &tag);
std::string GetTag();
void SetValue(const std::string str);
std::string GetValue();
void AddListenerId(uint32_t &listenerId);
void RemoveListenerId(uint32_t &listenerId);
std::vector<uint32_t> GetListenerIds() const;
void Foreach(TreeNodeVisitFunc func) const;
private:
std::string tag_ = "";
std::string value_ = "";
std::unique_ptr<TreeNodeMap> nodeMap_ = nullptr;
std::vector<uint32_t> listenerIds_ = {};
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_TREE_H

View File

@ -0,0 +1,28 @@
/*
* 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 FRAMEWORKS_DUMPER_INCLUDE_GRAPHIC_DUMPER_UTIL_H
#define FRAMEWORKS_DUMPER_INCLUDE_GRAPHIC_DUMPER_UTIL_H
#include <string>
#include <vector>
namespace OHOS {
constexpr int32_t CFGTERMSIZE = 2;
std::vector<std::string> Split(std::string src, const std::string &splitStr);
} // namespace OHOS
#endif // FRAMEWORKS_DUMPER_INCLUDE_GRAPHIC_DUMPER_UTIL_H

View File

@ -0,0 +1,37 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_CLIENT_LISTENER_DEATH_RECIPIENT_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_CLIENT_LISTENER_DEATH_RECIPIENT_H
#include <vector>
#include <iremote_stub.h>
#include <iremote_proxy.h>
#include <message_parcel.h>
#include <message_option.h>
#include "ipc/igraphic_dumper_service.h"
namespace OHOS {
class GraphicDumperClientListenerDeathRecipient : public IRemoteObject::DeathRecipient {
public:
GraphicDumperClientListenerDeathRecipient() = default;
virtual ~GraphicDumperClientListenerDeathRecipient() = default;
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVICE_H

View File

@ -0,0 +1,38 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_CLIENT_LISTENER_PROXY_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_CLIENT_LISTENER_PROXY_H
#include <iremote_object.h>
#include <iremote_proxy.h>
#include "ipc/igraphic_dumper_client_listener.h"
namespace OHOS {
class GraphicDumperClientListenerProxy : public IRemoteProxy<IGraphicDumperClientListener> {
public:
GraphicDumperClientListenerProxy(const sptr<IRemoteObject>& impl);
virtual ~GraphicDumperClientListenerProxy() = default;
void OnConfigChange(const std::string &tag, const std::string &val) override;
void OnDump(const std::string &tag) override;
private:
static inline BrokerDelegator<GraphicDumperClientListenerProxy> delegator_;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_CLIENT_LISTENER_STUB_H

View File

@ -0,0 +1,33 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_CLIENT_LISTENER_STUB_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_CLIENT_LISTENER_STUB_H
#include <iremote_stub.h>
#include <message_parcel.h>
#include <message_option.h>
#include "ipc/igraphic_dumper_client_listener.h"
namespace OHOS {
class GraphicDumperClientListenerStub : public IRemoteStub<IGraphicDumperClientListener> {
public:
virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option) override;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_CLIENT_LISTENER_STUB_H

View File

@ -0,0 +1,41 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_PROXY_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_PROXY_H
#include <iremote_object.h>
#include <iremote_proxy.h>
#include "ipc/igraphic_dumper_command.h"
namespace OHOS {
class GraphicDumperCommandProxy : public IRemoteProxy<IGraphicDumperCommand> {
public:
GraphicDumperCommandProxy(const sptr<IRemoteObject>& impl);
virtual ~GraphicDumperCommandProxy() = default;
GSError GetConfig(const std::string &k, std::string &v) override;
GSError SetConfig(const std::string &k, const std::string &v) override;
GSError Dump(const std::string &key) override;
GSError GetLog(const std::string &tag, std::string &log) override;
GSError AddInfoListener(const std::string &tag, sptr<IGraphicDumperInfoListener> &listener) override;
private:
static inline BrokerDelegator<GraphicDumperCommandProxy> delegator_;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_STUB_H

View File

@ -0,0 +1,40 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_STUB_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_STUB_H
#include <iremote_stub.h>
#include <message_parcel.h>
#include <message_option.h>
#include "ipc/igraphic_dumper_command.h"
namespace OHOS {
class GraphicDumperCommandStub : public IRemoteStub<IGraphicDumperCommand> {
public:
virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option) override;
virtual GSError GetConfig(const std::string &k, std::string &v) override;
virtual GSError SetConfig(const std::string &k, const std::string &v) override;
using IPCObjectStub::Dump;
virtual GSError Dump(const std::string &tag) override;
virtual GSError GetLog(const std::string &tag, std::string &log) override;
virtual GSError AddInfoListener(const std::string &tag, sptr<IGraphicDumperInfoListener> &listener) override;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_H

View File

@ -0,0 +1,34 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_INFO_LISTENER_DEATH_RECIPIENT_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_INFO_LISTENER_DEATH_RECIPIENT_H
#include <iremote_stub.h>
#include <message_parcel.h>
#include <message_option.h>
#include "ipc/igraphic_dumper_command.h"
namespace OHOS {
class GraphicDumperInfoListenerDeathRecipient : public IRemoteObject::DeathRecipient {
public:
GraphicDumperInfoListenerDeathRecipient() = default;
virtual ~GraphicDumperInfoListenerDeathRecipient() = default;
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_COMMAND_H

View File

@ -0,0 +1,36 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_INFO_LISTENER_PROXY_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_INFO_LISTENER_PROXY_H
#include <iremote_object.h>
#include <iremote_proxy.h>
#include "ipc/igraphic_dumper_info_listener.h"
namespace OHOS {
class GraphicDumperInfoListenerProxy : public IRemoteProxy<IGraphicDumperInfoListener> {
public:
GraphicDumperInfoListenerProxy(const sptr<IRemoteObject>& impl);
virtual ~GraphicDumperInfoListenerProxy() = default;
void OnInfoComing(const std::string &info) override;
private:
static inline BrokerDelegator<GraphicDumperInfoListenerProxy> delegator_;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_INFO_LISTENER_STUB_H

View File

@ -0,0 +1,33 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_INFO_LISTENER_STUB_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_INFO_LISTENER_STUB_H
#include <iremote_stub.h>
#include <message_parcel.h>
#include <message_option.h>
#include "ipc/igraphic_dumper_info_listener.h"
namespace OHOS {
class GraphicDumperInfoListenerStub : public IRemoteStub<IGraphicDumperInfoListener> {
public:
virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option) override;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_INFO_LISTENER_STUB_H

View File

@ -0,0 +1,37 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVICE_PROXY_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVICE_PROXY_H
#include <iremote_object.h>
#include <iremote_proxy.h>
#include "ipc/igraphic_dumper_service.h"
namespace OHOS {
class GraphicDumperServiceProxy : public IRemoteProxy<IGraphicDumperService> {
public:
GraphicDumperServiceProxy(const sptr<IRemoteObject>& impl);
virtual ~GraphicDumperServiceProxy() = default;
GSError AddClientListener(const std::string &tag, sptr<IGraphicDumperClientListener> &listener) override;
GSError SendInfo(const std::string &tag, const std::string &info) override;
private:
static inline BrokerDelegator<GraphicDumperServiceProxy> delegator_;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVICE_PROXY_H

View File

@ -0,0 +1,38 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVICE_STUB_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVICE_STUB_H
#include <vector>
#include <iremote_stub.h>
#include <iremote_proxy.h>
#include <message_parcel.h>
#include <message_option.h>
#include "ipc/igraphic_dumper_service.h"
namespace OHOS {
class GraphicDumperServiceStub : public IRemoteStub<IGraphicDumperService> {
public:
virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option) override;
GSError AddClientListener(const std::string &tag, sptr<IGraphicDumperClientListener> &listener) override;
GSError SendInfo(const std::string &tag, const std::string &info) override;
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_SERVICE_H

View File

@ -0,0 +1,38 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_CLIENT_LISTENER_H
#define FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_CLIENT_LISTENER_H
#include <string>
#include <iremote_broker.h>
namespace OHOS {
class IGraphicDumperClientListener : public IRemoteBroker {
public:
virtual void OnConfigChange(const std::string &tag, const std::string &val) = 0;
virtual void OnDump(const std::string &key) = 0;
DECLARE_INTERFACE_DESCRIPTOR(u"IGraphicDumperClientListener");
protected:
enum {
IGRAPHIC_DUMPER_CLIENT_LISTENER_ON_CONFIG_CHANGE,
IGRAPHIC_DUMPER_CLIENT_LISTENER_ON_DUMP,
};
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_CLIENT_LISTENER_H

View 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 FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_COMMAND_H
#define FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_COMMAND_H
#include <string>
#include <iremote_broker.h>
#include "graphic_common.h"
#include "ipc/igraphic_dumper_info_listener.h"
namespace OHOS {
class IGraphicDumperCommand : public IRemoteBroker {
public:
virtual GSError GetConfig(const std::string &k, std::string &v) = 0;
virtual GSError SetConfig(const std::string &k, const std::string &v) = 0;
virtual GSError Dump(const std::string &tag) = 0;
virtual GSError GetLog(const std::string &tag, std::string &log) = 0;
virtual GSError AddInfoListener(const std::string &tag, sptr<IGraphicDumperInfoListener> &listener) = 0;
DECLARE_INTERFACE_DESCRIPTOR(u"IGraphicDumperCommand");
protected:
enum {
IGRAPHIC_DUMPER_COMMAND_GET_CONFIG,
IGRAPHIC_DUMPER_COMMAND_SET_CONFIG,
IGRAPHIC_DUMPER_COMMAND_DUMP,
IGRAPHIC_DUMPER_COMMAND_GET_LOG,
IGRAPHIC_DUMPER_COMMAND_ADD_INFO_LISTENER,
};
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_COMMAND_H

View File

@ -0,0 +1,36 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_INFO_LISTENER_H
#define FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_INFO_LISTENER_H
#include <string>
#include <iremote_broker.h>
namespace OHOS {
class IGraphicDumperInfoListener : public IRemoteBroker {
public:
virtual void OnInfoComing(const std::string &info) = 0;
DECLARE_INTERFACE_DESCRIPTOR(u"IGraphicDumperInfoListener");
protected:
enum {
IGRAPHIC_DUMPER_INFO_LISTENER_ON_INFO_COMING,
};
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_INFO_LISTENER_H

View File

@ -0,0 +1,41 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_SERVICE_H
#define FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_SERVICE_H
#include <string>
#include <iremote_broker.h>
#include "graphic_common.h"
#include "ipc/igraphic_dumper_client_listener.h"
namespace OHOS {
class IGraphicDumperService : public IRemoteBroker {
public:
virtual GSError AddClientListener(const std::string &tag, sptr<IGraphicDumperClientListener> &listener) = 0;
virtual GSError SendInfo(const std::string &tag, const std::string &info) = 0;
DECLARE_INTERFACE_DESCRIPTOR(u"IGraphicDumperService");
protected:
enum {
IGRAPHIC_DUMPER_SERVICE_ADD_CLIENT_LISTENER,
IGRAPHIC_DUMPER_SERVICE_SEND_INFO,
};
};
} // namespace OHOS
#endif // FRAMEWORKS_DUMPRE_INCLUDE_IGRAPHIC_DUMPER_SERVICE_H

View File

@ -0,0 +1,268 @@
/*
* 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 "graphic_dumper_command_line.h"
#include <condition_variable>
#include <csignal>
#include <iostream>
#include <mutex>
#include <vector>
#include <getopt.h>
#include <ipc_skeleton.h>
#include <iservice_registry.h>
#include <system_ability_definition.h>
#include <unistd.h>
#include "graphic_dumper_hilog.h"
#include "graphic_dumper_util.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperCommandLine" };
constexpr int SLEEP_TIME = 5 * 1000;
Promise<int> signalPromise;
static void Helper()
{
std::cerr <<
"Usage: [options]\n"
"options include:\n"
" -h --help show this message.\n"
" -w --wait wait mode; listen for new prints.\n"
" -g <key>, --get <key>\n"
" get config with key.\n"
" -s <key>=<value>, --set <key>=<value>\n"
" set config of key is equal to value.\n"
" -l <tag> --log <tag>\n"
" read log with tag.\n"
" -d <tag> --dump <tag>\n"
" read dump info with tag.\n"
" read all dump info with --all.\n"
<< std::endl;
}
} // namespace
sptr<GraphicDumperCommandLine> GraphicDumperCommandLine::GetInstance()
{
if (instance_ == nullptr) {
static std::mutex mutex;
std::lock_guard<std::mutex> guard(mutex);
if (instance_ == nullptr) {
instance_ = new GraphicDumperCommandLine();
}
}
return instance_;
}
void GraphicDumperCommandLine::OnInfoComing(const std::string &info)
{
std::cerr << info.c_str() << std::endl;
}
void Handler(int signal)
{
switch (signal) {
case SIGINT:
case SIGTERM:
case SIGTSTP:
case SIGQUIT:
case SIGHUP: {
signalPromise.Resolve(signal);
break;
}
default:
break;
}
}
void SignalInit()
{
std::signal(SIGINT, Handler);
std::signal(SIGKILL, Handler);
std::signal(SIGTERM, Handler);
std::signal(SIGTSTP, Handler);
std::signal(SIGQUIT, Handler);
std::signal(SIGHUP, Handler);
}
GSError GraphicDumperCommandLine::Main(int32_t argc, char *argv[])
{
GSError iRet = GSERROR_OK;
if (argc <= 1) {
Helper();
return iRet;
}
iRet = Parse(argc, argv);
if (iRet != GSERROR_OK) {
return iRet;
}
SignalInit();
iRet = InitSA(GRAPHIC_DUMPER_COMMAND_SA_ID);
if (iRet != GSERROR_OK) {
std::cerr << "Init SA failed: " << iRet << std::endl;
return iRet;
}
sptr<IGraphicDumperInfoListener> listener = this;
iRet = service_->AddInfoListener("", listener);
if (iRet != GSERROR_OK) {
std::cerr << "Add info listener failed: " << iRet << std::endl;
return iRet;
}
HandlerOfArgs();
usleep(SLEEP_TIME);
return GSERROR_OK;
}
void GraphicDumperCommandLine::HandlerOfArgs()
{
if (!dumperArgs_.dumpTag.empty()) {
service_->Dump("*#dp#*." + dumperArgs_.dumpTag);
std::cerr << "get dump with tag:" << dumperArgs_.dumpTag.c_str() << std::endl;
}
if (!dumperArgs_.logTag.empty()) {
std::string getLog = {};
std::cerr << "get log with tag:" << dumperArgs_.logTag.c_str() << std::endl;
service_->GetLog(dumperArgs_.logTag, getLog);
std::cerr << "log is" << getLog.c_str() << std::endl;
}
if (!dumperArgs_.getCfgKey.empty()) {
std::string getCfgValue = {};
service_->GetConfig(dumperArgs_.getCfgKey, getCfgValue);
std::cerr << "get cfg with key:" << dumperArgs_.getCfgKey.c_str() << "value is:"
<< getCfgValue.c_str() << std::endl;
}
if ((!dumperArgs_.setCfgKey.empty()) && (!dumperArgs_.setCfgKey.empty())) {
service_->SetConfig(dumperArgs_.setCfgKey, dumperArgs_.setCfgValue);
std::cerr << "set cfg with key:" << dumperArgs_.setCfgKey.c_str() << "value is:"
<< dumperArgs_.setCfgValue.c_str() << std::endl;
}
if (dumperArgs_.wait) {
signalPromise.Await();
}
}
GSError GraphicDumperCommandLine::OptionParse(const char option)
{
switch (option) {
case 'h': {
Helper();
return GSERROR_OK;
break;
}
case 'w': {
dumperArgs_.wait = true;
break;
}
case 'g': {
dumperArgs_.getCfgKey = optarg;
break;
}
case 's': {
auto ret = Split(optarg, "=");
if (ret.size() != CFGTERMSIZE) {
std::cerr << "Parameter format error." << std::endl;
return GSERROR_INVALID_OPERATING;
}
dumperArgs_.setCfgKey = ret[0];
dumperArgs_.setCfgValue = ret[1];
break;
}
case 'l': {
dumperArgs_.logTag = optarg;
break;
}
case 'd': {
dumperArgs_.dumpTag = optarg;
break;
}
default: {
std::cerr << "Command not found." << std::endl;
return GSERROR_INVALID_OPERATING;
break;
}
} // switch
return GSERROR_OK;
}
GSError GraphicDumperCommandLine::Parse(int32_t argc, char *argv[])
{
int optIndex = 0;
static const struct option longOptions[] = {
{ "help", no_argument, nullptr, 'h' },
{ "wait", no_argument, nullptr, 'w' },
{ "log", required_argument, nullptr, 'l' },
{ "dump", required_argument, nullptr, 'd' },
{ "get", required_argument, nullptr, 'g' },
{ "set", required_argument, nullptr, 's' },
{nullptr, 0, nullptr, 0}
};
while (true) {
int opt = getopt_long(argc, argv, "hwg:s:l:d:", longOptions, &optIndex);
if (opt == -1) {
break;
}
auto ret = OptionParse(opt);
if (ret != GSERROR_OK) {
return ret;
}
} // while
return GSERROR_OK;
}
GSError GraphicDumperCommandLine::InitSA(int32_t systemAbilityId)
{
if (service_ != nullptr) {
GDLOG_SUCCESS("_instance != nullptr");
return GSERROR_OK;
}
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (sm == nullptr) {
GDLOG_FAILURE_RET(GSERROR_CONNOT_CONNECT_SAMGR);
}
auto remoteObject = sm->GetSystemAbility(systemAbilityId);
if (remoteObject == nullptr) {
GDLOG_FAILURE_RET(GSERROR_CONNOT_CONNECT_SERVER);
}
sptr<IRemoteObject::DeathRecipient> deathRecipient = new GDumperCommandDeathRecipient();
if ((remoteObject->IsProxyObject()) && (!remoteObject->AddDeathRecipient(deathRecipient))) {
GDLOGFE("Failed to add death recipient");
}
service_ = iface_cast<IGraphicDumperCommand>(remoteObject);
if (service_ == nullptr) {
GDLOG_FAILURE_RET(GSERROR_PROXY_NOT_INCLUDE);
}
GDLOG_SUCCESS("service_ = iface_cast");
return GSERROR_OK;
}
void GDumperCommandDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
GDLOGFE("Command server Died!");
std::raise(SIGQUIT);
}
} // namespace OHOS

View File

@ -0,0 +1,23 @@
/*
* 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 "graphic_dumper_command_line.h"
using namespace OHOS;
int32_t main(int32_t argc, char *argv[])
{
return GraphicDumperCommandLine::GetInstance()->Main(argc, argv);
}

View File

@ -0,0 +1,66 @@
/*
* 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 <graphic_dumper_helper.h>
#include <cstdarg>
#include <securec.h>
#include "graphic_dumper_helper_impl.h"
namespace OHOS {
sptr<GraphicDumperHelper> GraphicDumperHelper::GetInstance()
{
return GraphicDumperHelperImpl::GetInstance();
}
} // namespace OHOS
int SendInfo(const char* tag, const char *fmt, ...)
{
constexpr int infoSize = 4096;
char info[infoSize];
va_list args;
va_start(args, fmt);
int ret = vsnprintf_s(info, sizeof(info), (sizeof(info) - 1), fmt, args);
if (ret < 0) {
return 0;
}
va_end(args);
return OHOS::GraphicDumperHelperImpl::GetInstance()->SendInfo(std::string(tag), "%s", info);
}
int AddConfigChangeListener(const char* tag, OnConfigChangeFuncPtr func)
{
auto cfunc = [func](const std::string &a, const std::string &b) {
func(a.c_str(), b.c_str());
};
return OHOS::GraphicDumperHelperImpl::GetInstance()->AddConfigChangeListener(std::string(tag), cfunc);
}
int RemoveConfigChangeListener(int listenerId)
{
return OHOS::GraphicDumperHelperImpl::GetInstance()->RemoveConfigChangeListener(listenerId);
}
int AddDumpListener(const char* tag, OnDumpFuncPtr func)
{
return OHOS::GraphicDumperHelperImpl::GetInstance()->AddDumpListener(std::string(tag), func);
}
int RemoveDumpListener(int listenerId)
{
return OHOS::GraphicDumperHelperImpl::GetInstance()->RemoveDumpListener(listenerId);
}

View File

@ -0,0 +1,329 @@
/*
* 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 "graphic_dumper_helper_impl.h"
#include <chrono>
#include <cstdarg>
#include <vector>
#include <iservice_registry.h>
#include <securec.h>
#include <system_ability_definition.h>
#include <unistd.h>
#include "graphic_dumper_hilog.h"
#include "ipc/igraphic_dumper_command.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperHelperImpl" };
constexpr int INFO_SIZE_MAX = 4096;
}
GraphicDumperClientListener::GraphicDumperClientListener(sptr<GraphicDumperHelperImpl>& helper)
: helperImpl_(helper)
{
}
void GraphicDumperClientListener::OnConfigChange(const std::string &tag, const std::string &val)
{
GDLOGI("%{public}s -> %{public}s", tag.c_str(), val.c_str());
if (helperImpl_) {
helperImpl_->DispenseOnConfigChange(tag, val);
}
}
void GraphicDumperClientListener::OnDump(const std::string &tag)
{
if (helperImpl_) {
std::string flag = "*#dp#*.";
if (tag.find(flag) == 0) {
std::string sTag = tag.substr(flag.length());
helperImpl_->DispenseOnDump(sTag);
}
}
}
sptr<GraphicDumperHelper> GraphicDumperHelperImpl::GetInstance()
{
if (currentHelper == nullptr) {
static std::mutex mutex;
std::lock_guard<std::mutex> guard(mutex);
if (currentHelper == nullptr) {
currentHelper = new GraphicDumperHelperImpl();
}
}
return currentHelper;
}
GraphicDumperHelperImpl::GraphicDumperHelperImpl()
{
}
void GraphicDumperHelperImpl::SetNoopInstance()
{
static std::mutex mutex;
std::lock_guard<std::mutex> guard(mutex);
currentHelper = new GraphicDumperHelperNoop();
}
GSError GraphicDumperHelperImpl::Init()
{
std::lock_guard<std::mutex> lock(initMutex_);
if (serverConnected) {
return GSERROR_OK;
}
if (access("/data/gdumper_enable", F_OK) != 0) {
SetNoopInstance();
return GSERROR_NOT_SUPPORT;
}
auto now = std::chrono::steady_clock::now().time_since_epoch();
auto nowTime = (int64_t)std::chrono::duration_cast<std::chrono::milliseconds>(now).count();
constexpr int64_t reconnectTime = 1000;
if ((nowTime - requestConnectTime) < reconnectTime) {
return GSERROR_OUT_OF_RANGE;
}
requestConnectTime = nowTime;
GSError ret = InitSA(GRAPHIC_DUMPER_SERVICE_SA_ID);
if (ret != GSERROR_OK) {
return ret;
}
{
std::lock_guard<std::mutex> guard(onConfigChangeMutex_);
for (const auto& iter : onConfigChangeMap_) {
ret = AddClientListener(iter.first);
if (ret != GSERROR_OK) {
return ret;
}
}
}
{
std::lock_guard<std::mutex> guard(onDumperFuncsMutex_);
for (const auto& iter : onDumpFuncsMap_) {
ret = AddClientListener(iter.first);
if (ret != GSERROR_OK) {
return ret;
}
}
}
{
std::lock_guard<std::mutex> guard(cacheInfoMutex_);
for (const auto& infoStruct : cacheInfo_) {
ret = service_->SendInfo(infoStruct.tag, infoStruct.info);
GDLOG_SUCCESS("SendInfo is %{public}d", ret);
}
cacheInfo_.clear();
cacheInfo_.shrink_to_fit();
}
return ret;
}
GSError GraphicDumperHelperImpl::InitSA(int32_t systemAbilityId)
{
if (serverConnected) {
return GSERROR_OK;
}
auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (sam == nullptr) {
GDLOG_FAILURE_RET(GSERROR_CONNOT_CONNECT_SAMGR);
}
auto remoteObject = sam->GetSystemAbility(systemAbilityId);
if (remoteObject == nullptr) {
GDLOG_FAILURE_RET(GSERROR_CONNOT_CONNECT_SERVER);
}
sptr<IRemoteObject::DeathRecipient> deathRecipient = new GDumperServiceDeathRecipient();
if ((remoteObject->IsProxyObject()) && (!remoteObject->AddDeathRecipient(deathRecipient))) {
GDLOGFE("Failed to add death recipient");
}
service_ = iface_cast<IGraphicDumperService>(remoteObject);
if (service_ == nullptr) {
GDLOG_FAILURE_RET(GSERROR_PROXY_NOT_INCLUDE);
}
serverConnected = true;
GDLOG_SUCCESS("service_ = iface_cast");
return GSERROR_OK;
}
GSError GraphicDumperHelperImpl::AddClientListener(const std::string &tag)
{
if (Init() != GSERROR_OK) {
return GSERROR_CONNOT_CONNECT_SERVER;
}
if (listener_ == nullptr) {
std::lock_guard<std::mutex> guard(clientListenerMutex_);
if (listener_ == nullptr) {
sptr<GraphicDumperHelperImpl> helper = this;
listener_ = new GraphicDumperClientListener(helper);
}
}
return service_->AddClientListener(tag, listener_);
}
GSError GraphicDumperHelperImpl::SendInfo(const std::string &tag, const char *fmt, ...)
{
char info[INFO_SIZE_MAX]; // clear by vsnprintf
{
static std::mutex sprintfMutex_;
std::lock_guard<std::mutex> lock(sprintfMutex_);
va_list args;
va_start(args, fmt);
int ret = vsnprintf_s(info, sizeof(info), (sizeof(info) - 1), fmt, args);
if (ret < 0) {
return GSERROR_INVALID_ARGUMENTS;
}
va_end(args);
}
GSError retInit = Init();
if (retInit == GSERROR_OK) {
return service_->SendInfo(tag, std::string(info));
GDLOGFE("SendInfo is ok");
} else if (retInit == GSERROR_NOT_SUPPORT) {
return retInit;
} else {
struct InfoStruct infoStruct = {
.tag = tag,
.info = info,
};
std::lock_guard<std::mutex> guard(cacheInfoMutex_);
cacheInfo_.push_back(infoStruct);
return GSERROR_OK;
}
}
int32_t GraphicDumperHelperImpl::AddConfigChangeListener(const std::string &tag, OnConfigChangeFunc func)
{
{
std::lock_guard<std::mutex> guard(onConfigChangeMutex_);
if (onConfigChangeMap_.find(tag) != onConfigChangeMap_.end()) {
(*onConfigChangeMap_[tag])[++onConfigChangeFuncId_] = func;
return onConfigChangeFuncId_;
}
}
int ret = AddClientListener(tag);
if (ret != GSERROR_OK) {
return 0;
}
auto onConfigChangeFuncs = std::make_unique<std::map<int32_t, OnConfigChangeFunc>>();
(*onConfigChangeFuncs)[++onConfigChangeFuncId_] = func;
onConfigChangeMap_[tag] = std::move(onConfigChangeFuncs);
return onConfigChangeFuncId_;
}
GSError GraphicDumperHelperImpl::RemoveConfigChangeListener(const int32_t listenerId)
{
std::lock_guard<std::mutex> guard(onConfigChangeMutex_);
for (auto& [k, v] : onConfigChangeMap_) {
if (v->find(listenerId) != v->end()) {
v->erase(listenerId);
return GSERROR_OK;
}
}
return GSERROR_INVALID_ARGUMENTS;
}
int32_t GraphicDumperHelperImpl::AddDumpListener(const std::string &tag, OnDumpFunc func)
{
std::lock_guard<std::mutex> guard(onDumperFuncsMutex_);
if (onDumpFuncsMap_.find(tag) != onDumpFuncsMap_.end()) {
(*onDumpFuncsMap_[tag])[++onDumperFuncId_] = func;
return onDumperFuncId_;
}
auto dumpTag = "*#dp#*." + tag;
int ret = AddClientListener(dumpTag);
if (ret != GSERROR_OK) {
return 0;
}
auto onDumpFuncs = std::make_unique<std::map<int32_t, OnDumpFunc>>();
(*onDumpFuncs)[++onDumperFuncId_] = func;
onDumpFuncsMap_[tag] = std::move(onDumpFuncs);
return onDumperFuncId_;
}
GSError GraphicDumperHelperImpl::RemoveDumpListener(const int32_t listenerId)
{
std::lock_guard<std::mutex> guard(onDumperFuncsMutex_);
for (auto& [k, v] : onDumpFuncsMap_) {
if (v->find(listenerId) != v->end()) {
v->erase(listenerId);
return GSERROR_OK;
}
}
return GSERROR_INVALID_ARGUMENTS;
}
void GraphicDumperHelperImpl::SetConnectState(bool state)
{
GDLOGFI("");
serverConnected = state;
}
void GraphicDumperHelperImpl::DispenseOnConfigChange(const std::string &tag, const std::string &val)
{
GDLOGI("%{public}s -> %{public}s", tag.c_str(), val.c_str());
std::lock_guard<std::mutex> guard(onConfigChangeMutex_);
if (onConfigChangeMap_.empty()) {
return;
}
if (!onConfigChangeMap_[tag]->empty()) {
for (const auto &[id, func] : *onConfigChangeMap_[tag]) {
func(tag, val);
}
}
}
void GraphicDumperHelperImpl::DispenseOnDump(const std::string &tag)
{
std::lock_guard<std::mutex> guard(onDumperFuncsMutex_);
if (onDumpFuncsMap_.empty()) {
return;
}
if (tag == "--all") {
for (const auto& [t, mapPtr] : onDumpFuncsMap_) {
if (mapPtr != nullptr) {
for (const auto &[id, func] : *mapPtr) {
func();
}
}
}
return;
}
if (onDumpFuncsMap_.find(tag) != onDumpFuncsMap_.end()) {
if (onDumpFuncsMap_[tag] != nullptr) {
for (const auto &[id, func] : *onDumpFuncsMap_[tag]) {
func();
}
}
}
}
void GDumperServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
auto helper = GraphicDumperHelperImpl::GetInstance();
auto helperImpl = reinterpret_cast<GraphicDumperHelperImpl *>(helper.GetRefPtr());
helperImpl->SetConnectState(false);
}
} // namespace OHOS

View File

@ -0,0 +1,567 @@
/*
* 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 "graphic_dumper_server.h"
#include <fstream>
#include <iostream>
#include <regex>
#include <iremote_object.h>
#include <iservice_registry.h>
#include <securec.h>
#include <system_ability_definition.h>
#include <unistd.h>
#include <zlib.h>
#include "ipc/graphic_dumper_info_listener_death_recipient.h"
#include "ipc/graphic_dumper_client_listener_death_recipient.h"
#include "ipc/graphic_dumper_service_stub.h"
#include "ipc/graphic_dumper_command_stub.h"
#include "graphic_dumper_hilog.h"
#include "graphic_dumper_util.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperServer" };
constexpr int SLEEP_TIME = 500 * 1000;
constexpr uint32_t LOG_BUF_SIZE_MAX = 192 * 1024;
constexpr uint32_t LOG_BLOCK_SIZE_MAX = 4 * 1000 * 1024;
constexpr uint32_t LOG_VEC_SIZE = 2;
constexpr const char *GDUMPER_INI_PATH = "/system/etc/gdumper.ini";
std::string& Trim (std::string &s)
{
std::regex fmt("\\s");
s = std::regex_replace(s, fmt, "");
return s;
}
void StrLogRomveTag(bool getAll, const std::string &tag,
const std::string &strIn, std::string &strOut)
{
auto pos = strIn.find_first_of("| [");
constexpr int offset = 2;
if (pos == std::string::npos) {
pos = 0;
} else {
pos += offset;
}
if (getAll) {
strOut += strIn.substr(pos);
} else if (strIn.compare(0, tag.size(), tag) == 0) {
strOut += strIn.substr(pos);
}
}
} // namespace
sptr<GraphicDumperServer> GraphicDumperServer::GetInstance()
{
if (instance_ == nullptr) {
static std::mutex mutex;
std::lock_guard<std::mutex> guard(mutex);
if (instance_ == nullptr) {
instance_ = new GraphicDumperServer();
}
}
return instance_;
}
int32_t GraphicDumperServer::Init()
{
int32_t ret = 0;
ret = ReadDefaultConfig();
if (ret) {
GDLOGI("Read default config error with %d.\n", ret);
}
for (auto& s : logBuf_.size) {
s = 0;
logBuf_.vec.push_back(std::make_unique<std::vector<std::string>>());
}
sptr<IRemoteObject> service = new GraphicDumperServiceStub();
ret = StartServer(GRAPHIC_DUMPER_SERVICE_SA_ID, service);
if (ret) {
GDLOGI("Start graphic dumper service failed: %d\n", ret);
return ret;
}
sptr<IRemoteObject> command = new GraphicDumperCommandStub();
ret = StartServer(GRAPHIC_DUMPER_COMMAND_SA_ID, command);
if (ret) {
GDLOGI("Start graphic dumper command failed: %d\n", ret);
return ret;
}
return ret;
}
GSError GraphicDumperServer::AddConfigListener(const std::string &tag,
sptr<IGraphicDumperClientListener> &listener)
{
if (listener == nullptr) {
return GSERROR_INVALID_ARGUMENTS;
}
GDLOGFE("%{public}s", tag.c_str());
auto object = listener->AsObject();
AddConfigDeathRecipient(object);
if (HaveObject(object) == false) {
objectIdMap_[object] = ++objectId_;
configTagsMap_[objectId_].id = objectId_;
configTagsMap_[objectId_].listener = listener;
}
auto &objectId = objectIdMap_[object];
auto &configTags = configTagsMap_[objectId];
for (const auto &iter : configTags.tags) {
if (iter == tag) {
return GSERROR_OK;
}
}
configTags.tags.push_back(tag);
for (auto &tag__ : configTags.tags) {
GDLOGFE("configTagsMap %{public}s", tag__.c_str());
}
std::lock_guard<std::mutex> lock(treeMutex_);
std::vector<std::string> nodes = Split(tag, ".");
TreeNodePtr sub = root;
for (const auto& iter : nodes) {
sub = sub->GetSetNode(iter);
}
sub->AddListenerId(configTags.id);
return GSERROR_OK;
}
GSError GraphicDumperServer::RemoveConfigListener(sptr<IRemoteObject> object)
{
if (object == nullptr) {
return GSERROR_INVALID_ARGUMENTS;
}
auto &deathRecipient = configListenerDeathRecipientMap_[object];
if (deathRecipient != nullptr) {
object->RemoveDeathRecipient(deathRecipient);
}
configListenerDeathRecipientMap_.erase(object);
auto &objectId = objectIdMap_[object];
auto &configTags = configTagsMap_[objectId];
for (auto &tag : configTags.tags) {
GDLOGFE("configTagsMap %{public}s", tag.c_str());
std::lock_guard<std::mutex> lock(treeMutex_);
std::vector<std::string> nodes = Split(tag, ".");
TreeNodePtr sub = root;
RemoveNode(nodes, sub, configTags.id);
}
object = nullptr;
return GSERROR_OK;
}
GSError GraphicDumperServer::GetConfig(const std::string &k, std::string &v)
{
GDLOGI("%{public}s -> %{public}s", k.c_str(), v.c_str());
std::lock_guard<std::mutex> lock(treeMutex_);
std::vector<std::string> nodes = Split(k, ".");
TreeNodePtr sub = root;
for (const auto& iter : nodes) {
if (sub->HasNode(iter)) {
sub = sub->GetSetNode(iter);
} else {
return GSERROR_INVALID_ARGUMENTS;
}
}
v = sub->GetValue();
GDLOGI("%{public}s -> %{public}s", k.c_str(), v.c_str());
return GSERROR_OK;
}
GSError GraphicDumperServer::SetConfig(const std::string &k, const std::string &v)
{
GDLOGI("%{public}s -> %{public}s", k.c_str(), v.c_str());
std::lock_guard<std::mutex> lock(treeMutex_);
std::vector<std::string> nodes = Split(k, ".");
TreeNodePtr sub = root;
for (const auto& iter : nodes) {
sub = sub->GetSetNode(iter);
}
if (sub->GetValue().compare(v)) {
sub->SetValue(v);
DispenseConfig(sub, k, v);
}
GDLOGI("%{public}s -> %{public}s", k.c_str(), v.c_str());
return GSERROR_OK;
}
GSError GraphicDumperServer::Dump(const std::string &tag)
{
std::lock_guard<std::mutex> lock(treeMutex_);
std::vector<std::string> nodes = Split(tag, ".");
TreeNodePtr sub = root;
for (const auto& iter : nodes) {
if (iter.compare("--all") == 0) {
break;
}
GDLOGFE("%{public}s", iter.c_str());
sub = sub->GetSetNode(iter);
}
DispenseDump(sub, tag);
GDLOGFE("%{public}s", tag.c_str());
return GSERROR_OK;
}
GSError GraphicDumperServer::AddInfoListener(sptr<IGraphicDumperInfoListener> &listener)
{
if (listener == nullptr) {
return GSERROR_INVALID_ARGUMENTS;
}
std::lock_guard<std::mutex> guard(infoListenersMutex_);
auto object = listener->AsObject();
AddInfoDeathRecipient(object);
infoListeners_[object] = listener;
return GSERROR_OK;
}
GSError GraphicDumperServer::RemoveInfoListener(const wptr<IRemoteObject> &object)
{
std::lock_guard<std::mutex> guard(infoListenersMutex_);
auto sObject = object.promote();
if (infoListeners_.find(sObject) != infoListeners_.end()) {
infoListeners_.erase(sObject);
}
if (infoListeners_.empty()) {
logBuf_.sync = false;
logBuf_.mask.clear();
}
return GSERROR_OK;
}
GSError GraphicDumperServer::InfoHandle(const std::string &tag, const std::string &info)
{
GDLOGFE("GraphicDumperServer::InfoHandle --start!!!!!!!!!");
std::string logFlag = {"log."};
GDLOGFE("%{public}s -> %{public}s", tag.c_str(), info.c_str());
if (tag.compare(0, logFlag.size(), logFlag) == 0) {
GDLOGFE("InfoHandle to LogHandle");
return LogHandle(tag.substr(logFlag.size()), info);
}
GDLOGFE("InfoHandle to SendToInfoListener");
SendToInfoListener(tag + " : " + info);
return GSERROR_OK;
}
GSError GraphicDumperServer::GetLog(const std::string &tag, const std::string &info)
{
GDLOGFE("%{public}s -> %{public}s", tag.c_str(), info.c_str());
bool getAll = false;
if (tag.compare("--all") == 0) {
getAll = true;
logBuf_.mask.clear();
} else {
logBuf_.mask = tag;
}
{
std::lock_guard<std::mutex> lock(logBlockVectorMutex_);
for (const auto& array : logBlockVector_) {
auto logBlock = reinterpret_cast<LogBlock *>(array.get());
std::string toSendStr = {};
uint32_t offset = 0;
GDLOGFE("logBlock->size = %{public}d", logBlock->size);
while (offset < logBlock->size) {
std::string str(reinterpret_cast<const char*>(logBlock->data + offset));
GDLOGFE("logBlock = %{public}s", str.c_str());
StrLogRomveTag(getAll, tag, str, toSendStr);
offset += (str.size() + 1);
}
SendToInfoListener(toSendStr);
}
}
std::string logStr = {};
if (logBuf_.canSave || logBuf_.needSave) {
uint32_t index = (logBuf_.index + 1) % LOG_VEC_SIZE;
std::lock_guard<std::mutex> guard(logBuf_.mutex[index]);
for (const auto& str : *logBuf_.vec[index]) {
GDLOGFE("logBuf_cansave = %{public}s", str.c_str());
StrLogRomveTag(getAll, tag, str, logStr);
}
}
SendToInfoListener(logStr);
logStr.clear();
{
uint32_t index = logBuf_.index;
std::lock_guard<std::mutex> guard(logBuf_.mutex[index]);
for (const auto& str : *logBuf_.vec[index]) {
GDLOGFE("logBuf_ = %{public}s", str.c_str());
StrLogRomveTag(getAll, tag, str, logStr);
}
}
SendToInfoListener(logStr);
logBuf_.sync = true;
return GSERROR_OK;
}
int32_t GraphicDumperServer::StartServer(int32_t systemAbility, sptr<IRemoteObject> obj)
{
if (systemAbility == 0 || obj == nullptr) {
GDLOGI("graphic dumper start_server parameter error");
return 1;
}
int result = 0;
while (1) {
auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (sm != nullptr) {
result = sm->AddSystemAbility(systemAbility, obj);
break;
}
GDLOGI("graphic dumper start_server SystemAbilityManager is nullptr");
usleep(SLEEP_TIME);
}
return result;
}
int32_t GraphicDumperServer::ReadDefaultConfig()
{
int32_t successConst = 0;
int32_t failConst = 0;
std::string getLineStr = {};
std::vector<std::string> cfgStrs = {};
std::ifstream input(GDUMPER_INI_PATH);
if (!input.is_open()) {
GDLOGE("failed to open: %{public}s", GDUMPER_INI_PATH);
} else {
while (!input.eof()) {
getline(input, getLineStr);
Trim(getLineStr);
std::string first = getLineStr.substr(0, 1);
if (first != "#" && first != "") {
cfgStrs.push_back(getLineStr);
}
}
input.clear();
input.close();
}
std::lock_guard<std::mutex> lock(treeMutex_);
for (auto iter : cfgStrs) {
if (!iter.empty()) {
std::vector<std::string> cfg = Split(iter, "=");
if (cfg.size() != CFGTERMSIZE) {
failConst++;
GDLOGE("fail cfg(%{public}d): %{public}s", failConst, iter.c_str());
}
std::vector<std::string> nodes = Split(cfg[0], ".");
TreeNodePtr sub = root;
for (const auto& iter : nodes) {
sub = sub->GetSetNode(iter);
}
sub->SetValue(cfg[1]);
successConst++;
}
}
GDLOGI("There are %{public}d items successfully configured", successConst);
return failConst;
}
void GraphicDumperServer::AddConfigDeathRecipient(sptr<IRemoteObject> &object)
{
if (!HaveConfigDeathRecipient(object)) {
sptr<IRemoteObject::DeathRecipient> deathRecipient = new GraphicDumperClientListenerDeathRecipient();
if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient))) {
GDLOGFE("Failed to add death recipient");
}
configListenerDeathRecipientMap_[object] = deathRecipient;
}
}
bool GraphicDumperServer::HaveConfigDeathRecipient(sptr<IRemoteObject> &object)
{
auto &map = configListenerDeathRecipientMap_;
return map.find(object) != map.end();
}
bool GraphicDumperServer::HaveObject(const sptr<IRemoteObject> &obj)
{
return objectIdMap_.find(obj) != objectIdMap_.end();
}
void GraphicDumperServer::VisitEach(const TreeNodePtr &node, TreeNodeVisitFunc func)
{
GDLOGFI("");
TreeNodeVisitFunc getV = [&](const TreeNodePtr &v) {
GDLOGFI("");
func(v);
v->Foreach(getV);
};
node->Foreach(getV);
}
void GraphicDumperServer::RemoveNode(std::vector<std::string> &vec,
TreeNodePtr &sub,
uint32_t &listenerId)
{
GDLOGFE("listener: %{public}u", listenerId);
if (vec.empty() || sub == nullptr || listenerId == 0) {
return;
}
std::string tag = *vec.begin();
GDLOGFE("tag: %{public}s", tag.c_str());
vec.erase(vec.begin());
if (sub->HasNode(tag)) {
TreeNodePtr subNd = sub->GetSetNode(tag);
if (vec.empty()) {
subNd->RemoveListenerId(listenerId);
return;
}
RemoveNode(vec, subNd, listenerId);
if (subNd->IsEmptyNode()) {
sub->EraseNode(subNd->GetTag());
}
}
}
void GraphicDumperServer::DispenseConfig(const TreeNodePtr &node, const std::string &k, const std::string &v)
{
GDLOGFI("%{public}s -> %{public}s", k.c_str(), v.c_str());
auto dispenseConfig = [&](const TreeNodePtr &nd) {
GDLOGFI("%{public}s -> %{public}s", k.c_str(), v.c_str());
auto ls = nd->GetListenerIds();
for (const auto& id : ls) {
configTagsMap_[id].listener->OnConfigChange(k, v);
}
};
dispenseConfig(node);
VisitEach(node, dispenseConfig);
}
void GraphicDumperServer::DispenseDump(const TreeNodePtr &node, const std::string &tag)
{
GDLOGFI("%{public}s", tag.c_str());
auto dispenseDump = [&](const TreeNodePtr &nd) {
GDLOGFI("%{public}s", tag.c_str());
auto ls = nd->GetListenerIds();
for (const auto& id : ls) {
configTagsMap_[id].listener->OnDump(tag);
}
};
dispenseDump(node);
VisitEach(node, dispenseDump);
}
void GraphicDumperServer::AddInfoDeathRecipient(sptr<IRemoteObject> &object)
{
if (!HaveInfoDeathRecipient(object)) {
sptr<IRemoteObject::DeathRecipient> deathRecipient = new GraphicDumperInfoListenerDeathRecipient();
if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient))) {
GDLOGFE("Failed to add death recipient");
}
infoListenerDeathRecipientMap_[object] = deathRecipient;
}
}
bool GraphicDumperServer::HaveInfoDeathRecipient(sptr<IRemoteObject> &object)
{
auto &map = infoListenerDeathRecipientMap_;
return map.find(object) != map.end();
}
void GraphicDumperServer::SendToInfoListener(const std::string &info)
{
std::lock_guard<std::mutex> guard(infoListenersMutex_);
for (const auto& [k, v] : infoListeners_) {
v->OnInfoComing(info);
}
}
void GraphicDumperServer::SaveLog(std::any server)
{
auto serverPtr = std::any_cast<GraphicDumperServer *>(server);
uint32_t index = (serverPtr->logBuf_.index + 1) % LOG_VEC_SIZE;
std::lock_guard<std::mutex> guard(serverPtr->logBuf_.mutex[index]);
uint32_t size = sizeof(LogBlock) + serverPtr->logBuf_.size[index] + 1;
auto logArray = std::make_unique<uint8_t[]>(size);
auto logBlock = reinterpret_cast<LogBlock *>(logArray.get());
logBlock->size = serverPtr->logBuf_.size[index];
logBlock->length = serverPtr->logBuf_.size[index];
uint32_t offset = 0;
for (const auto& str : *serverPtr->logBuf_.vec[index]) {
int ret = memcpy_s(logBlock->data + offset,
serverPtr->logBuf_.size[index] - offset,
str.c_str(), str.size() + 1);
if (ret < 0) {
return;
}
offset += str.size() + 1;
}
std::lock_guard<std::mutex> lock(serverPtr->logBlockVectorMutex_);
if ((serverPtr->logBlockSize_ + serverPtr->logBuf_.size[index]) > LOG_BLOCK_SIZE_MAX) {
auto logFirstBlock = reinterpret_cast<LogBlock *>(serverPtr->logBlockVector_.begin()->get());
serverPtr->logBlockSize_ -= logFirstBlock->size;
serverPtr->logBlockVector_.erase(serverPtr->logBlockVector_.begin());
}
serverPtr->logBlockVector_.push_back(std::move(logArray));
serverPtr->logBlockSize_ += serverPtr->logBuf_.size[index];
serverPtr->logBuf_.vec[index]->clear();
serverPtr->logBuf_.size[index] = 0;
}
GSError GraphicDumperServer::LogHandle(const std::string &tag, const std::string &info)
{
std::string log = tag + " | " + info;
GDLOGFI("%{public}s -> %{public}s", tag.c_str(), info.c_str());
{
std::lock_guard<std::mutex> guard(logBuf_.mutex[logBuf_.index]);
logBuf_.size[logBuf_.index] += log.size() + 1;
logBuf_.vec[logBuf_.index]->push_back(log);
if (logBuf_.canSave && (logBuf_.size[logBuf_.index] > (LOG_BUF_SIZE_MAX / LOG_VEC_SIZE))) {
thread_ = std::make_unique<std::thread>(&GraphicDumperServer::SaveLog, this);
logBuf_.needSave = true;
logBuf_.canSave = false;
}
if (logBuf_.size[logBuf_.index] >= LOG_BUF_SIZE_MAX) {
logBuf_.vec[logBuf_.index]->shrink_to_fit();
if (logBuf_.needSave) {
thread_->join();
logBuf_.needSave = false;
}
logBuf_.index = (logBuf_.index + 1) % LOG_VEC_SIZE;
logBuf_.canSave = true;
}
}
if (logBuf_.sync) {
if ((!logBuf_.mask.empty()) && (log.compare(0, logBuf_.mask.size(), logBuf_.mask) != 0)) {
return GSERROR_OK;
}
auto pos = log.find_first_of("| [");
constexpr int offset = 2;
if (pos == std::string::npos) {
pos = 0;
} else {
pos += offset;
}
SendToInfoListener(log.substr(pos));
}
return GSERROR_OK;
}
} // namespace OHOS

View File

@ -0,0 +1,29 @@
/*
* 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 <ipc_skeleton.h>
#include "graphic_dumper_server.h"
using namespace OHOS;
int main()
{
int ret = GraphicDumperServer::GetInstance()->Init();
if (ret == 0) {
IPCSkeleton::JoinWorkThread();
}
return ret;
}

View File

@ -0,0 +1,106 @@
/*
* 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 "graphic_dumper_tree.h"
#include "graphic_dumper_hilog.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperTree" };
} // namespace
TreeNodePtr GraphicDumperTree::GetSetNode(const std::string s)
{
if (nodeMap_ == nullptr) {
nodeMap_ = std::make_unique<TreeNodeMap>();
}
if (!HasNode(s)) {
(*nodeMap_)[s] = std::make_shared<GraphicDumperTree>();
(*nodeMap_)[s]->tag_ = s;
}
return (*nodeMap_)[s];
}
bool GraphicDumperTree::HasNode(const std::string s)
{
return nodeMap_->find(s) != nodeMap_->end();
}
bool GraphicDumperTree::IsEmptyNode()
{
if (nodeMap_->empty() && listenerIds_.empty()) {
return true;
}
return false;
}
void GraphicDumperTree::EraseNode(const std::string &s)
{
(*nodeMap_)[s] = nullptr;
nodeMap_->erase(s);
}
std::string GraphicDumperTree::GetTag()
{
return tag_;
}
void GraphicDumperTree::SetValue(const std::string s)
{
value_ = s;
}
std::string GraphicDumperTree::GetValue()
{
return value_;
}
void GraphicDumperTree::AddListenerId(uint32_t &listenerId)
{
GDLOGFI("");
listenerIds_.push_back(listenerId);
}
void GraphicDumperTree::RemoveListenerId(uint32_t &listenerId)
{
GDLOGFI("%{public}u", listenerId);
for (auto iter = listenerIds_.begin(); iter != listenerIds_.end(); ++iter) {
GDLOGFI("%{public}u <==> %{public}u", (*iter), listenerId);
if (*iter == listenerId) {
GDLOGFI("");
listenerIds_.erase(iter--);
}
}
}
std::vector<uint32_t> GraphicDumperTree::GetListenerIds() const
{
GDLOGFI("");
return listenerIds_;
}
void GraphicDumperTree::Foreach(TreeNodeVisitFunc func) const
{
GDLOGFI("");
if (nodeMap_ == nullptr) {
return;
}
for (const auto& [k, v] : (*nodeMap_)) {
GDLOGFI("%{public}s", k.c_str());
func(v);
}
}
} // namespace OHOS

View File

@ -0,0 +1,38 @@
/*
* 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 "graphic_dumper_util.h"
namespace OHOS {
std::vector<std::string> Split(std::string src, const std::string &splitStr)
{
std::vector<std::string> ret;
std::string::size_type pos = 0;
while (pos != std::string::npos) {
pos = src.find(splitStr);
if (pos == std::string::npos) {
if (!src.empty()) {
ret.push_back(src);
}
} else {
if (!src.empty()) {
ret.push_back(src.substr(0, pos));
}
src = src.substr(pos + splitStr.size());
}
}
return ret;
}
} // namespace OHOS

View File

@ -0,0 +1,28 @@
/*
* 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 "ipc/graphic_dumper_client_listener_death_recipient.h"
#include "graphic_dumper_server.h"
namespace OHOS {
void GraphicDumperClientListenerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
if (object == nullptr) {
return;
}
GraphicDumperServer::GetInstance()->RemoveConfigListener(object.promote());
}
} // namespace OHOS

View File

@ -0,0 +1,74 @@
/*
* 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 "ipc/graphic_dumper_client_listener_proxy.h"
#include <message_option.h>
#include <message_parcel.h>
#include "graphic_dumper_hilog.h"
#include "graphic_common.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperClientListenerProxy" };
}
GraphicDumperClientListenerProxy::GraphicDumperClientListenerProxy(const sptr<IRemoteObject>& impl)
: IRemoteProxy<IGraphicDumperClientListener>(impl)
{
}
void GraphicDumperClientListenerProxy::OnConfigChange(const std::string &tag, const std::string &val)
{
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
GDLOGFI("%{public}s -> %{public}s", tag.c_str(), val.c_str());
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(tag);
arg.WriteString(val);
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_CLIENT_LISTENER_ON_CONFIG_CHANGE, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return;
}
return;
}
void GraphicDumperClientListenerProxy::OnDump(const std::string &tag)
{
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
GDLOGFI("%{public}s", tag.c_str());
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(tag);
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_CLIENT_LISTENER_ON_DUMP, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return;
}
return;
}
} // namespace OHOS

View File

@ -0,0 +1,56 @@
/*
* 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 "ipc/graphic_dumper_client_listener_stub.h"
#include "graphic_dumper_hilog.h"
#include "graphic_common.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperClientListenerStub" };
}
int32_t GraphicDumperClientListenerStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option)
{
auto remoteDescriptor = data.ReadInterfaceToken();
if (GetDescriptor() != remoteDescriptor) {
return 1;
}
switch (code) {
case IGRAPHIC_DUMPER_CLIENT_LISTENER_ON_CONFIG_CHANGE: {
std::string tag = data.ReadString();
std::string val = data.ReadString();
GDLOGI("%{public}s -> %{public}s", tag.c_str(), val.c_str());
OnConfigChange(tag, val);
reply.WriteInt32(GSERROR_OK);
}
break;
case IGRAPHIC_DUMPER_CLIENT_LISTENER_ON_DUMP: {
std::string val = data.ReadString();
OnDump(val);
reply.WriteInt32(GSERROR_OK);
}
break;
default:
GDLOGFE("code %{public}d cannot process", code);
return 1;
break;
}
return 0;
}
} // namespace OHOS

View File

@ -0,0 +1,148 @@
/*
* 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 "ipc/graphic_dumper_command_proxy.h"
#include <message_option.h>
#include <message_parcel.h>
#include "graphic_dumper_hilog.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperCommandProxy" };
}
GraphicDumperCommandProxy::GraphicDumperCommandProxy(const sptr<IRemoteObject>& impl)
: IRemoteProxy<IGraphicDumperCommand>(impl)
{
}
GSError GraphicDumperCommandProxy::GetConfig(const std::string &k, std::string &v)
{
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
GDLOGFE("%{public}s -> %{public}s", k.c_str(), v.c_str());
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(k);
arg.WriteString(v);
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_COMMAND_GET_CONFIG, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return GSERROR_API_FAILED;
}
GSError retCode = static_cast<GSError>(ret.ReadInt32());
if (retCode == GSERROR_OK) {
v = ret.ReadString();
GDLOGFE("%{public}s -> %{public}s", k.c_str(), v.c_str());
}
return retCode;
}
GSError GraphicDumperCommandProxy::SetConfig(const std::string &k, const std::string &v)
{
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
GDLOGFE("%{public}s -> %{public}s", k.c_str(), v.c_str());
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(k);
arg.WriteString(v);
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_COMMAND_SET_CONFIG, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return GSERROR_API_FAILED;
}
return GSERROR_OK;
}
GSError GraphicDumperCommandProxy::Dump(const std::string &tag)
{
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
GDLOGFE("%{public}s", tag.c_str());
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(tag);
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_COMMAND_DUMP, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return GSERROR_API_FAILED;
}
return GSERROR_OK;
}
GSError GraphicDumperCommandProxy::GetLog(const std::string &tag, std::string &log)
{
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
GDLOGFE("%{public}s -> %{public}s", tag.c_str(), log.c_str());
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(tag);
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_COMMAND_GET_LOG, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return GSERROR_API_FAILED;
}
return GSERROR_OK;
}
GSError GraphicDumperCommandProxy::AddInfoListener(const std::string &tag, sptr<IGraphicDumperInfoListener> &listener)
{
if (listener == nullptr) {
GDLOG_FAILURE_NO(GSERROR_INVALID_ARGUMENTS);
return GSERROR_INVALID_ARGUMENTS;
}
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(tag);
arg.WriteRemoteObject(listener->AsObject());
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_COMMAND_ADD_INFO_LISTENER, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return GSERROR_BINDER;
}
GSError err = (GSError)ret.ReadInt32();
if (err != GSERROR_OK) {
GDLOG_FAILURE_NO(err);
}
return err;
}
} // namespace OHOS

View File

@ -0,0 +1,128 @@
/*
* 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 "ipc/graphic_dumper_command_stub.h"
#include "graphic_dumper_hilog.h"
#include "graphic_dumper_server.h"
#include "ipc/igraphic_dumper_command.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperCommandStub" };
}
int32_t GraphicDumperCommandStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option)
{
auto remoteDescriptor = data.ReadInterfaceToken();
if (GetDescriptor() != remoteDescriptor) {
return 1;
}
switch (code) {
case IGRAPHIC_DUMPER_COMMAND_GET_CONFIG: {
std::string k = data.ReadString();
std::string v = data.ReadString();
GSError ret = GetConfig(k, v);
reply.WriteInt32(ret);
reply.WriteString(v);
break;
}
case IGRAPHIC_DUMPER_COMMAND_SET_CONFIG: {
std::string k = data.ReadString();
std::string v = data.ReadString();
GSError ret = SetConfig(k, v);
reply.WriteInt32(ret);
break;
}
case IGRAPHIC_DUMPER_COMMAND_DUMP: {
std::string v = data.ReadString();
GSError ret = Dump(v);
reply.WriteInt32(ret);
break;
}
case IGRAPHIC_DUMPER_COMMAND_GET_LOG: {
std::string tag = data.ReadString();
std::string log = "";
GSError ret = GetLog(tag, log);
reply.WriteInt32(ret);
break;
}
case IGRAPHIC_DUMPER_COMMAND_ADD_INFO_LISTENER: {
auto tag = data.ReadString();
auto remoteObject = data.ReadRemoteObject();
if (remoteObject == nullptr) {
reply.WriteInt32(GSERROR_INVALID_ARGUMENTS);
GDLOG_FAILURE_NO(GSERROR_INVALID_ARGUMENTS);
break;
}
auto l = iface_cast<IGraphicDumperInfoListener>(remoteObject);
GSError ret = AddInfoListener(tag, l);
reply.WriteInt32(ret);
if (ret != GSERROR_OK) {
GDLOG_FAILURE_NO(ret);
}
break;
}
default: {
return 1;
break;
}
}
return 0;
}
GSError GraphicDumperCommandStub::GetConfig(const std::string &k, std::string &v)
{
GDLOGFE("%{public}s -> %{public}s", k.c_str(), v.c_str());
GraphicDumperServer::GetInstance()->GetConfig(k, v);
GDLOGFE("%{public}s -> %{public}s", k.c_str(), v.c_str());
return GSERROR_OK;
}
GSError GraphicDumperCommandStub::SetConfig(const std::string &k, const std::string &v)
{
GDLOGFE("%{public}s -> %{public}s", k.c_str(), v.c_str());
GraphicDumperServer::GetInstance()->SetConfig(k, v);
return GSERROR_OK;
}
GSError GraphicDumperCommandStub::Dump(const std::string &tag)
{
GDLOGFE("%{public}s", tag.c_str());
GraphicDumperServer::GetInstance()->Dump(tag);
return GSERROR_OK;
}
GSError GraphicDumperCommandStub::GetLog(const std::string &tag, std::string &log)
{
GDLOGFE("%{public}s -> %{public}s", tag.c_str(), log.c_str());
GraphicDumperServer::GetInstance()->GetLog(tag, log);
return GSERROR_OK;
}
GSError GraphicDumperCommandStub::AddInfoListener(const std::string &tag, sptr<IGraphicDumperInfoListener> &listener)
{
GDLOGFE("");
if (listener == nullptr) {
return GSERROR_INVALID_ARGUMENTS;
}
return GraphicDumperServer::GetInstance()->AddInfoListener(listener);
}
} // namespace OHOS

View File

@ -0,0 +1,29 @@
/*
* 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 "ipc/graphic_dumper_info_listener_death_recipient.h"
#include "graphic_dumper_server.h"
#include "ipc/igraphic_dumper_command.h"
#include "graphic_common.h"
#include "graphic_dumper_hilog.h"
namespace OHOS {
void GraphicDumperInfoListenerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
if (object == nullptr) {
return;
}
GraphicDumperServer::GetInstance()->RemoveInfoListener(object);
}
} // namespace OHOS

View File

@ -0,0 +1,50 @@
/*
* 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 "ipc/graphic_dumper_info_listener_proxy.h"
#include <message_option.h>
#include <message_parcel.h>
#include "graphic_dumper_hilog.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperInfoListenerProxy" };
}
GraphicDumperInfoListenerProxy::GraphicDumperInfoListenerProxy(const sptr<IRemoteObject>& impl)
: IRemoteProxy<IGraphicDumperInfoListener>(impl)
{
}
void GraphicDumperInfoListenerProxy::OnInfoComing(const std::string &info)
{
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(info);
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_INFO_LISTENER_ON_INFO_COMING, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return;
}
return;
}
} // namespace OHOS

View File

@ -0,0 +1,50 @@
/*
* 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 "ipc/graphic_dumper_info_listener_stub.h"
#include "graphic_dumper_hilog.h"
#include "graphic_common.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperInfoListenerStub" };
}
int32_t GraphicDumperInfoListenerStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
MessageParcel& reply, MessageOption& option)
{
auto remoteDescriptor = data.ReadInterfaceToken();
if (GetDescriptor() != remoteDescriptor) {
return 1;
}
switch (code) {
case IGRAPHIC_DUMPER_INFO_LISTENER_ON_INFO_COMING: {
std::string info = data.ReadString();
OnInfoComing(info);
reply.WriteInt32(GSERROR_OK);
break;
}
default: {
GDLOGFE("code %{public}d cannot process", code);
return 1;
break;
}
}
return 0;
}
} // namespace OHOS

View File

@ -0,0 +1,84 @@
/*
* 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 "ipc/graphic_dumper_service_proxy.h"
#include <message_option.h>
#include <message_parcel.h>
#include "graphic_dumper_hilog.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperServiceProxy" };
}
GraphicDumperServiceProxy::GraphicDumperServiceProxy(const sptr<IRemoteObject>& impl)
: IRemoteProxy<IGraphicDumperService>(impl)
{
}
GSError GraphicDumperServiceProxy::AddClientListener(const std::string &tag,
sptr<IGraphicDumperClientListener> &listener)
{
if (listener == nullptr) {
GDLOG_FAILURE_NO(GSERROR_INVALID_ARGUMENTS);
return GSERROR_INVALID_ARGUMENTS;
}
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(tag);
arg.WriteRemoteObject(listener->AsObject());
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_SERVICE_ADD_CLIENT_LISTENER, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return GSERROR_BINDER;
}
GSError err = (GSError)ret.ReadInt32();
if (err != GSERROR_OK) {
GDLOG_FAILURE_NO(err);
}
return err;
}
GSError GraphicDumperServiceProxy::SendInfo(const std::string &tag, const std::string &info)
{
MessageOption opt;
MessageParcel arg;
MessageParcel ret;
if (!arg.WriteInterfaceToken(GetDescriptor())) {
GDLOGE("write interface token failed");
}
arg.WriteString(tag);
arg.WriteString(info);
GDLOGE("SendInfo SendRequest !!!!!");
int result = Remote()->SendRequest(IGRAPHIC_DUMPER_SERVICE_SEND_INFO, arg, ret, opt);
if (result) {
GDLOG_ERROR_API(result, SendRequest);
return GSERROR_BINDER;
}
return GSERROR_OK;
}
} // namespace OHOS

View File

@ -0,0 +1,91 @@
/*
* 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 "ipc/graphic_dumper_service_stub.h"
#include "graphic_dumper_hilog.h"
#include "graphic_dumper_server.h"
#define REMOTE_RETURN(reply, gs_error) \
do { \
(reply).WriteInt32(gs_error); \
if ((gs_error) != GSERROR_OK) { \
GDLOG_FAILURE_NO(gs_error); \
} \
} while (0); \
break
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "GraphicDumperServiceStub" };
}
int32_t GraphicDumperServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option)
{
auto remoteDescriptor = data.ReadInterfaceToken();
if (GetDescriptor() != remoteDescriptor) {
return 1;
}
switch (code) {
case IGRAPHIC_DUMPER_SERVICE_ADD_CLIENT_LISTENER: {
auto tag = data.ReadString();
GDLOGFE("%{public}s", tag.c_str());
auto remoteObject = data.ReadRemoteObject();
if (remoteObject == nullptr) {
reply.WriteInt32(GSERROR_INVALID_ARGUMENTS);
GDLOG_FAILURE_NO(GSERROR_INVALID_ARGUMENTS);
break;
}
auto l = iface_cast<IGraphicDumperClientListener>(remoteObject);
GSError ret = AddClientListener(tag, l);
reply.WriteInt32(ret);
if (ret != GSERROR_OK) {
GDLOG_FAILURE_NO(ret);
}
break;
}
case IGRAPHIC_DUMPER_SERVICE_SEND_INFO: {
std::string tag = data.ReadString();
std::string info = data.ReadString();
GSError ret = SendInfo(tag, info);
reply.WriteInt32(ret);
if (ret != GSERROR_OK) {
GDLOG_FAILURE_NO(ret);
}
break;
}
default: {
GDLOGFE("code %{public}d cannot process", code);
return 1;
break;
}
}
return 0;
}
GSError GraphicDumperServiceStub::AddClientListener(const std::string &tag,
sptr<IGraphicDumperClientListener> &listener)
{
if (listener == nullptr) {
return GSERROR_INVALID_ARGUMENTS;
}
return GraphicDumperServer::GetInstance()->AddConfigListener(tag, listener);
}
GSError GraphicDumperServiceStub::SendInfo(const std::string &tag, const std::string &info)
{
return GraphicDumperServer::GetInstance()->InfoHandle(tag, info);
}
} // namespace OHOS

View File

@ -148,6 +148,8 @@ ohos_shared_library("libwmclient") {
"src/subwindow_option_impl.cpp", "src/subwindow_option_impl.cpp",
"src/subwindow_video_impl.cpp", "src/subwindow_video_impl.cpp",
"src/tester.cpp", "src/tester.cpp",
"src/virtual_display_option.cpp",
"src/virtual_display_option_impl.cpp",
"src/wayland_service.cpp", "src/wayland_service.cpp",
"src/window_attribute.cpp", "src/window_attribute.cpp",
"src/window_impl.cpp", "src/window_impl.cpp",

View File

@ -68,6 +68,13 @@ private:
void *window; void *window;
}; };
struct Seat {
struct wl_seat *seat;
struct wl_pointer *pointer;
struct wl_keyboard *keyboard;
struct wl_touch *touch;
};
using InputListeners = std::vector<sptr<InputListener>>; using InputListeners = std::vector<sptr<InputListener>>;
class InputListenerManager : public RefBase { class InputListenerManager : public RefBase {
@ -95,16 +102,13 @@ private:
static inline SingletonDelegator<InputListenerManager> delegator; static inline SingletonDelegator<InputListenerManager> delegator;
static void OnAppear(const GetServiceFunc get, const std::string &iname, uint32_t ver); static void OnAppear(const GetServiceFunc get, const std::string &iname, uint32_t ver);
static inline struct wl_seat *seat = nullptr; static inline std::vector<Seat> seats;
static uint32_t FindSeatNum(struct wl_seat *seat);
static void SeatHandleCapabilities(void *, struct wl_seat *, uint32_t caps); static inline void SeatHandleCapabilities(void *, struct wl_seat *, uint32_t caps);
static void RegisterPointerListener(uint32_t caps); static inline void RegisterPointerListener(uint32_t caps, struct wl_seat *seat);
static void RegisterKeyboardListener(uint32_t caps); static inline void RegisterKeyboardListener(uint32_t caps, struct wl_seat *seat);
static void RegisterTouchListener(uint32_t caps); static inline void RegisterTouchListener(uint32_t caps, struct wl_seat *seat);
static inline struct wl_pointer *pointer = nullptr;
static inline struct wl_keyboard *keyboard = nullptr;
static inline struct wl_touch *touch = nullptr;
}; };
} // namespace OHOS } // namespace OHOS

View File

@ -0,0 +1,55 @@
/*
* 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 FRAMEWORKS_WM_INCLUDE_VIRTUAL_DISPLAY_OPTION_IMPL_H
#define FRAMEWORKS_WM_INCLUDE_VIRTUAL_DISPLAY_OPTION_IMPL_H
#include <virtual_display_option.h>
namespace OHOS {
class VirtualDisplayOptionImpl : public VirtualDisplayOption {
public:
VirtualDisplayOptionImpl() = default;
virtual ~VirtualDisplayOptionImpl() = default;
virtual WMError SetX(int32_t x) override;
virtual WMError SetY(int32_t y) override;
virtual WMError SetWidth(uint32_t width) override;
virtual WMError SetHeight(uint32_t height) override;
virtual int32_t GetX() const override;
virtual int32_t GetY() const override;
virtual uint32_t GetWidth() const override;
virtual uint32_t GetHeight() const override;
virtual bool IsSettingX() const override;
virtual bool IsSettingY() const override;
virtual bool IsSettingWidth() const override;
virtual bool IsSettingHeight() const override;
private:
bool settingX = false;
bool settingY = false;
bool settingWidth = false;
bool settingHeight = false;
int32_t x = 0;
int32_t y = 0;
uint32_t width = 1;
uint32_t height = 1;
};
} // namespace OHOS
#endif // FRAMEWORKS_WM_INCLUDE_VIRTUAL_DISPLAY_OPTION_IMPL_H

View File

@ -52,6 +52,10 @@ public:
virtual WMError ListenNextScreenShot(int32_t id, IScreenShotCallback *cb) override; virtual WMError ListenNextScreenShot(int32_t id, IScreenShotCallback *cb) override;
virtual WMError ListenNextWindowShot(const sptr<Window> &window, IWindowShotCallback *cb) override; virtual WMError ListenNextWindowShot(const sptr<Window> &window, IWindowShotCallback *cb) override;
virtual WMError CreateVirtualDisplay(const sptr<VirtualDisplayOption> &option) override;
virtual WMError DestroyVirtualDisplay(uint32_t did) override;
virtual WMError SetDisplayMode(WMSDisplayMode mode) override;
private: private:
WindowManagerImpl(); WindowManagerImpl();
virtual ~WindowManagerImpl() override; virtual ~WindowManagerImpl() override;

View File

@ -42,24 +42,27 @@ void InputListenerManager::Init()
void InputListenerManager::Deinit() void InputListenerManager::Deinit()
{ {
if (seat != nullptr) { while (!seats.empty()) {
wl_seat_destroy(seat); if (seats.back().seat != nullptr) {
seat = nullptr; wl_seat_destroy(seats.back().seat);
} seats.back().seat = nullptr;
}
if (pointer != nullptr) { if (seats.back().pointer != nullptr) {
wl_pointer_destroy(pointer); wl_pointer_destroy(seats.back().pointer);
pointer = nullptr; seats.back().pointer = nullptr;
} }
if (keyboard != nullptr) { if (seats.back().keyboard != nullptr) {
wl_keyboard_destroy(keyboard); wl_keyboard_destroy(seats.back().keyboard);
keyboard = nullptr; seats.back().keyboard = nullptr;
} }
if (touch != nullptr) { if (seats.back().touch != nullptr) {
wl_touch_destroy(touch); wl_touch_destroy(seats.back().touch);
touch = nullptr; seats.back().touch = nullptr;
}
seats.pop_back();
} }
g_getFocus = []() { return InputListeners(); }; g_getFocus = []() { return InputListeners(); };
@ -138,21 +141,25 @@ void InputListenerManager::OnAppear(const GetServiceFunc get, const std::string
{ {
if (iname == "wl_seat") { if (iname == "wl_seat") {
constexpr uint32_t wlSeatVersion = 1; constexpr uint32_t wlSeatVersion = 1;
seat = static_cast<struct wl_seat *>(get(&wl_seat_interface, wlSeatVersion)); struct wl_seat *s = static_cast<struct wl_seat *>(get(&wl_seat_interface, wlSeatVersion));
if (seat == nullptr) { if (s == nullptr) {
return; return;
} }
Seat seat = {
.seat = s,
};
seats.push_back(seat);
static struct wl_seat_listener listener = { SeatHandleCapabilities }; static struct wl_seat_listener listener = { SeatHandleCapabilities };
wl_seat_add_listener(seat, &listener, nullptr); wl_seat_add_listener(s, &listener, nullptr);
} }
} }
void InputListenerManager::SeatHandleCapabilities(void *, struct wl_seat *, uint32_t caps) void InputListenerManager::SeatHandleCapabilities(void *, struct wl_seat * seat, uint32_t caps)
{ {
InputListenerManager::RegisterPointerListener(caps); InputListenerManager::RegisterPointerListener(caps, seat);
InputListenerManager::RegisterKeyboardListener(caps); InputListenerManager::RegisterKeyboardListener(caps, seat);
InputListenerManager::RegisterTouchListener(caps); InputListenerManager::RegisterTouchListener(caps, seat);
} }
namespace { namespace {
@ -448,8 +455,23 @@ void OnTouchOrientation(void *, struct wl_touch *,
} }
} // namespace } // namespace
void InputListenerManager::RegisterPointerListener(uint32_t caps) uint32_t InputListenerManager::FindSeatNum(struct wl_seat *seat)
{ {
uint32_t num = 1;
for (uint32_t i = 0; i < seats.size(); i++) {
if (seat == seats[i].seat) {
num = i;
break;
}
}
return num;
}
void InputListenerManager::RegisterPointerListener(uint32_t caps, struct wl_seat *seat)
{
struct wl_pointer *pointer = nullptr;
uint32_t num = FindSeatNum(seat);
pointer = seats[num].pointer;
bool havePointerCapability = !!(caps & WL_SEAT_CAPABILITY_POINTER); bool havePointerCapability = !!(caps & WL_SEAT_CAPABILITY_POINTER);
if (havePointerCapability == true && pointer == nullptr) { if (havePointerCapability == true && pointer == nullptr) {
static struct wl_pointer_listener listener = { static struct wl_pointer_listener listener = {
@ -474,10 +496,14 @@ void InputListenerManager::RegisterPointerListener(uint32_t caps)
wl_pointer_destroy(pointer); wl_pointer_destroy(pointer);
pointer = nullptr; pointer = nullptr;
} }
seats[num].pointer = pointer;
} }
void InputListenerManager::RegisterKeyboardListener(uint32_t caps) void InputListenerManager::RegisterKeyboardListener(uint32_t caps, struct wl_seat *seat)
{ {
struct wl_keyboard *keyboard = nullptr;
uint32_t num = FindSeatNum(seat);
keyboard = seats[num].keyboard;
bool haveKeyboardCapability = !!(caps & WL_SEAT_CAPABILITY_KEYBOARD); bool haveKeyboardCapability = !!(caps & WL_SEAT_CAPABILITY_KEYBOARD);
if (haveKeyboardCapability == true && keyboard == nullptr) { if (haveKeyboardCapability == true && keyboard == nullptr) {
static struct wl_keyboard_listener listener = { static struct wl_keyboard_listener listener = {
@ -499,10 +525,14 @@ void InputListenerManager::RegisterKeyboardListener(uint32_t caps)
wl_keyboard_destroy(keyboard); wl_keyboard_destroy(keyboard);
keyboard = nullptr; keyboard = nullptr;
} }
seats[num].keyboard = keyboard;
} }
void InputListenerManager::RegisterTouchListener(uint32_t caps) void InputListenerManager::RegisterTouchListener(uint32_t caps, struct wl_seat *seat)
{ {
struct wl_touch *touch = nullptr;
uint32_t num = FindSeatNum(seat);
touch = seats[num].touch;
bool haveTouchCapability = !!(caps & WL_SEAT_CAPABILITY_TOUCH); bool haveTouchCapability = !!(caps & WL_SEAT_CAPABILITY_TOUCH);
if (haveTouchCapability == true && touch == nullptr) { if (haveTouchCapability == true && touch == nullptr) {
static const struct wl_touch_listener listener = { static const struct wl_touch_listener listener = {
@ -525,5 +555,6 @@ void InputListenerManager::RegisterTouchListener(uint32_t caps)
wl_touch_destroy(touch); wl_touch_destroy(touch);
touch = nullptr; touch = nullptr;
} }
seats[num].touch = touch;
} }
} // namespace OHOS } // namespace OHOS

View File

@ -0,0 +1,25 @@
/*
* 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 <virtual_display_option.h>
#include "virtual_display_option_impl.h"
namespace OHOS {
sptr<VirtualDisplayOption> VirtualDisplayOption::Get()
{
return new VirtualDisplayOptionImpl;
}
} // namespace OHOS

View File

@ -0,0 +1,102 @@
/*
* 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 "virtual_display_option_impl.h"
#include "window_manager_hilog.h"
namespace OHOS {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "WMVirtualDisplayOptionImpl"};
}
WMError VirtualDisplayOptionImpl::SetX(int32_t x)
{
this->x = x;
this->settingX = true;
return WM_OK;
}
WMError VirtualDisplayOptionImpl::SetY(int32_t y)
{
this->y = y;
this->settingY = true;
return WM_OK;
}
WMError VirtualDisplayOptionImpl::SetWidth(uint32_t width)
{
if (!(width > 0)) {
WMLOGFE("width is invalid, should > 0");
return WM_ERROR_INVALID_PARAM;
}
this->width = width;
this->settingWidth = true;
return WM_OK;
}
WMError VirtualDisplayOptionImpl::SetHeight(uint32_t height)
{
if (!(height > 0)) {
WMLOGFE("height is invalid, should > 0");
return WM_ERROR_INVALID_PARAM;
}
this->height = height;
this->settingHeight = true;
return WM_OK;
}
int32_t VirtualDisplayOptionImpl::GetX() const
{
return x;
}
int32_t VirtualDisplayOptionImpl::GetY() const
{
return y;
}
uint32_t VirtualDisplayOptionImpl::GetWidth() const
{
return width;
}
uint32_t VirtualDisplayOptionImpl::GetHeight() const
{
return height;
}
bool VirtualDisplayOptionImpl::IsSettingX() const
{
return settingX;
}
bool VirtualDisplayOptionImpl::IsSettingY() const
{
return settingY;
}
bool VirtualDisplayOptionImpl::IsSettingWidth() const
{
return settingWidth;
}
bool VirtualDisplayOptionImpl::IsSettingHeight() const
{
return settingHeight;
}
} // namespace OHOS

View File

@ -76,7 +76,8 @@ WMError WindowImpl::CreateRemoteWindow(sptr<WindowImpl> &wi,
} }
auto windowManagerServer = SingletonContainer::Get<WindowManagerServer>(); auto windowManagerServer = SingletonContainer::Get<WindowManagerServer>();
auto promise = windowManagerServer->CreateWindow(wi->wlSurface, 0, option->GetWindowType()); auto promise = windowManagerServer->CreateWindow(wi->wlSurface,
option->GetDisplay(), option->GetWindowType());
if (promise == nullptr) { if (promise == nullptr) {
WMLOGFE("CreateWindow return nullptr promise"); WMLOGFE("CreateWindow return nullptr promise");
return WM_ERROR_NEW; return WM_ERROR_NEW;

View File

@ -192,6 +192,70 @@ sptr<Window> WindowManagerImpl::GetWindowByID(int32_t wid)
return ret; return ret;
} }
WMError WindowManagerImpl::CreateVirtualDisplay(const sptr<VirtualDisplayOption> &option)
{
if (wmservice == nullptr) {
return WM_ERROR_NOT_INIT;
}
auto promise = wmservice->CreateVirtualDisplay(option->GetX(), option->GetY(),
option->GetWidth(), option->GetHeight());
if (promise == nullptr) {
WMLOGFE("CreateVirtualDisplay return nullptr promise");
return WM_ERROR_NEW;
}
auto wret = promise->Await();
if (wret != WM_OK) {
WMLOGFE("wms->CreateVirtualDisplay failed %{public}s", WMErrorStr(wret).c_str());
return wret;
}
return WM_OK;
}
WMError WindowManagerImpl::DestroyVirtualDisplay(uint32_t did)
{
if (wmservice == nullptr) {
return WM_ERROR_NOT_INIT;
}
auto promise = wmservice->DestroyVirtualDisplay(did);
if (promise == nullptr) {
WMLOGFE("DestroyVirtualDisplay return nullptr promise");
return WM_ERROR_NEW;
}
auto wret = promise->Await();
if (wret != WM_OK) {
WMLOGFE("wms->DestroyVirtualDisplay failed %{public}s", WMErrorStr(wret).c_str());
return wret;
}
return WM_OK;
}
WMError WindowManagerImpl::SetDisplayMode(WMSDisplayMode mode)
{
if (wmservice == nullptr) {
return WM_ERROR_NOT_INIT;
}
auto promise = wmservice->SetDisplayMode(mode);
if (promise == nullptr) {
WMLOGFE("SetDisplayMode return nullptr promise");
return WM_ERROR_NEW;
}
auto wret = promise->Await();
if (wret != WM_OK) {
WMLOGFE("wms->SetDisplayMode failed %{public}s", WMErrorStr(wret).c_str());
return wret;
}
return WM_OK;
}
WMError WindowManagerImpl::CreateWindow(sptr<Window> &window, const sptr<WindowOption> &option) WMError WindowManagerImpl::CreateWindow(sptr<Window> &window, const sptr<WindowOption> &option)
{ {
if (option == nullptr) { if (option == nullptr) {

View File

@ -134,7 +134,7 @@ bool PixelFormatToDrmFormat(int32_t pixelFormat, uint32_t &drmFormat)
{PIXEL_FMT_RGBX_5551, DRM_FORMAT_RGBX5551}, {PIXEL_FMT_RGBX_5551, DRM_FORMAT_RGBX5551},
{PIXEL_FMT_RGBA_5551, DRM_FORMAT_RGBA5551}, {PIXEL_FMT_RGBA_5551, DRM_FORMAT_RGBA5551},
{PIXEL_FMT_RGBX_8888, DRM_FORMAT_RGBX8888}, {PIXEL_FMT_RGBX_8888, DRM_FORMAT_RGBX8888},
{PIXEL_FMT_RGBA_8888, DRM_FORMAT_ABGR8888}, {PIXEL_FMT_RGBA_8888, DRM_FORMAT_RGBA8888},
{PIXEL_FMT_RGB_888, DRM_FORMAT_RGB888}, {PIXEL_FMT_RGB_888, DRM_FORMAT_RGB888},
{PIXEL_FMT_BGR_565, DRM_FORMAT_BGR565}, {PIXEL_FMT_BGR_565, DRM_FORMAT_BGR565},
{PIXEL_FMT_BGRX_4444, DRM_FORMAT_BGRX4444}, {PIXEL_FMT_BGRX_4444, DRM_FORMAT_BGRX4444},

View File

@ -47,6 +47,8 @@ public:
MOCK_METHOD3(ScaleTo, sptr<PromiseWMError>(int32_t wid, uint32_t width, uint32_t height)); MOCK_METHOD3(ScaleTo, sptr<PromiseWMError>(int32_t wid, uint32_t width, uint32_t height));
MOCK_METHOD2(SetWindowType, sptr<PromiseWMError>(int32_t wid, WindowType type)); MOCK_METHOD2(SetWindowType, sptr<PromiseWMError>(int32_t wid, WindowType type));
MOCK_METHOD2(SetWindowMode, sptr<PromiseWMError>(int32_t wid, WindowMode mode)); MOCK_METHOD2(SetWindowMode, sptr<PromiseWMError>(int32_t wid, WindowMode mode));
MOCK_METHOD4(CreateVirtualDisplay, sptr<PromiseWMError>(int32_t x, int32_t y, int32_t width, int32_t height));
MOCK_METHOD1(DestroyVirtualDisplay, sptr<PromiseWMError>(uint32_t did));
}; };
} // namespace OHOS } // namespace OHOS

View File

@ -63,7 +63,6 @@ ohos_shared_library("wmserver") {
"//drivers/peripheral/display/hal:hdi_display_device", "//drivers/peripheral/display/hal:hdi_display_device",
"//foundation/multimodalinput/input/patch/diff_libinput_mmi:libinput-third-mmi", "//foundation/multimodalinput/input/patch/diff_libinput_mmi:libinput-third-mmi",
"//third_party/wayland_standard:wayland_core_protocol", "//third_party/wayland_standard:wayland_core_protocol",
"//third_party/weston:drm-backend",
"//third_party/weston:libexec_weston", "//third_party/weston:libexec_weston",
"//utils/native/base:utils", "//utils/native/base:utils",
] ]

View File

@ -44,6 +44,12 @@
<entry name="remove" value="1"/> <entry name="remove" value="1"/>
</enum> </enum>
<enum name="screen_type">
<description summary="screen type"/>
<entry name="physical" value="0"/>
<entry name="virtual" value="1"/>
</enum>
<event name="screen_status"> <event name="screen_status">
<description summary="screen info update"/> <description summary="screen info update"/>
<arg name="screen_id" type="uint"/> <arg name="screen_id" type="uint"/>
@ -51,6 +57,7 @@
<arg name="status" type="uint" enum="screen_status"/> <arg name="status" type="uint" enum="screen_status"/>
<arg name="width" type="int"/> <arg name="width" type="int"/>
<arg name="height" type="int"/> <arg name="height" type="int"/>
<arg name="screen_type" type="uint" enum="screen_type"/>
</event> </event>
<!-- Screen Event }}} --> <!-- Screen Event }}} -->
@ -275,6 +282,22 @@
<arg name="id" type="uint" summary="window id"/> <arg name="id" type="uint" summary="window id"/>
</event> </event>
<!-- Windowshot }}} --> <!-- Windowshot }}} -->
<!-- Virtual Display {{{ -->
<request name="create_virtual_display">
<description summary="create a virtual display"/>
<arg name="x" type="int"/>
<arg name="y" type="int"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
</request>
<request name="destroy_virtual_display">
<description summary="destroy virtual display"/>
<arg name="screen_id" type="uint"/>
</request>
<!-- Virtual Display }}}-->
</interface> </interface>
<interface name="screen_info" version="1"> <interface name="screen_info" version="1">

View File

@ -74,6 +74,7 @@ struct WindowSurface {
int32_t height; int32_t height;
int32_t lastSurfaceWidth; int32_t lastSurfaceWidth;
int32_t lastSurfaceHeight; int32_t lastSurfaceHeight;
int32_t firstCommit;
struct wl_list link; struct wl_list link;
}; };
@ -101,6 +102,11 @@ static struct WmsContext g_wmsCtx = {0};
static ScreenInfoChangeListener g_screenInfoChangeListener = NULL; static ScreenInfoChangeListener g_screenInfoChangeListener = NULL;
static SeatInfoChangeListener g_seatInfoChangeListener = NULL; static SeatInfoChangeListener g_seatInfoChangeListener = NULL;
static int32_t CreateScreen(struct WmsContext *pCtx,
struct weston_output *pOutput,
uint32_t screenType);
static void DestroyScreen(struct WmsScreen *pScreen);
static void SendGlobalWindowStatus(const struct WmsController *pController, uint32_t window_id, uint32_t status) static void SendGlobalWindowStatus(const struct WmsController *pController, uint32_t window_id, uint32_t status)
{ {
LOGD("start."); LOGD("start.");
@ -174,6 +180,12 @@ static inline int GetLayerId(uint32_t screenId, uint32_t type, uint32_t mode)
return z + screenId * LAYER_ID_SCREEN_BASE; return z + screenId * LAYER_ID_SCREEN_BASE;
} }
static inline int ChangeLayerId(uint32_t layerIdOld, uint32_t screenIdOld, uint32_t screenIdNew)
{
uint32_t z = layerIdOld - screenIdOld * LAYER_ID_SCREEN_BASE;
return z + screenIdNew * LAYER_ID_SCREEN_BASE;
}
static void WindowSurfaceCommitted(struct weston_surface *surface, int32_t sx, int32_t sy); static void WindowSurfaceCommitted(struct weston_surface *surface, int32_t sx, int32_t sy);
static struct WindowSurface *GetWindowSurface(const struct weston_surface *surface) static struct WindowSurface *GetWindowSurface(const struct weston_surface *surface)
@ -218,15 +230,21 @@ static void SetSourceRectangle(const struct WindowSurface *windowSurface,
(uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height); (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
} }
static void SetDestinationRectangle(const struct WindowSurface *windowSurface, static void SetDestinationRectangle(struct WindowSurface *windowSurface,
int32_t x, int32_t y, int32_t width, int32_t height) int32_t x, int32_t y, int32_t width, int32_t height)
{ {
const struct ivi_layout_interface_for_wms *layoutInterface = windowSurface->controller->pWmsCtx->pLayoutInterface; const struct ivi_layout_interface_for_wms *layoutInterface = windowSurface->controller->pWmsCtx->pLayoutInterface;
struct ivi_layout_surface *layoutSurface = windowSurface->layoutSurface; struct ivi_layout_surface *layoutSurface = windowSurface->layoutSurface;
const struct ivi_layout_surface_properties *prop = layoutInterface->get_properties_of_surface(layoutSurface); const struct ivi_layout_surface_properties *prop = layoutInterface->get_properties_of_surface(layoutSurface);
layoutInterface->surface_set_transition(layoutSurface, if (windowSurface->firstCommit == 1) {
IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, TIMER_INTERVAL_MS); // ms layoutInterface->surface_set_transition(layoutSurface,
IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, TIMER_INTERVAL_MS); // ms
} else {
layoutInterface->surface_set_transition(layoutSurface,
IVI_LAYOUT_TRANSITION_NONE, TIMER_INTERVAL_MS); // ms
windowSurface->firstCommit = 1;
}
if (width < 0) { if (width < 0) {
width = prop->dest_width; width = prop->dest_width;
@ -364,7 +382,7 @@ static uint32_t GetWindowId(struct WmsController *pController)
static struct ivi_layout_layer *GetLayer(struct weston_output *westonOutput, static struct ivi_layout_layer *GetLayer(struct weston_output *westonOutput,
struct ivi_layout_interface_for_wms *pLayoutInterface, struct ivi_layout_interface_for_wms *pLayoutInterface,
uint32_t layerId) uint32_t layerId, bool *isNewLayer)
{ {
LOGD("start."); LOGD("start.");
struct ivi_layout_layer *layoutLayer = pLayoutInterface->get_layer_from_id(layerId); struct ivi_layout_layer *layoutLayer = pLayoutInterface->get_layer_from_id(layerId);
@ -378,6 +396,8 @@ static struct ivi_layout_layer *GetLayer(struct weston_output *westonOutput,
pLayoutInterface->screen_add_layer(westonOutput, layoutLayer); pLayoutInterface->screen_add_layer(westonOutput, layoutLayer);
pLayoutInterface->layer_set_visibility(layoutLayer, true); pLayoutInterface->layer_set_visibility(layoutLayer, true);
if (isNewLayer != NULL)
*isNewLayer = true;
} }
LOGD("end."); LOGD("end.");
@ -410,18 +430,23 @@ static struct WmsScreen *GetScreen(const struct WindowSurface *windowSurface)
static void CalcWindowInfo(struct WindowSurface *surface) static void CalcWindowInfo(struct WindowSurface *surface)
{ {
#ifdef USE_DUMMY_SCREEN struct WmsContext *ctx = surface->controller->pWmsCtx;
int maxWidth = DUMMY_SCREEN_WIDTH;
int maxHeight = DUMMY_SCREEN_HEIGHT;
#else
struct WmsScreen *screen = GetScreen(surface); struct WmsScreen *screen = GetScreen(surface);
int maxWidth = 0;
int maxHeight = 0;
if (!screen) { if (!screen) {
LOGE("GetScreen error."); LOGE("GetScreen error.");
return; return;
} }
int maxWidth = screen->westonOutput->width; if (ctx->displayMode == WM_DISPLAY_MODE_EXPAND) {
int maxHeight = screen->westonOutput->height; wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
#endif /* USE_DUMMY_SCREEN */ maxWidth += screen->westonOutput->width;
}
maxHeight = ctx->pMainScreen->westonOutput->height;
} else {
maxWidth = screen->westonOutput->width;
maxHeight = screen->westonOutput->height;
}
LayoutControllerInit(maxWidth, maxHeight); LayoutControllerInit(maxWidth, maxHeight);
struct layout layout = {}; struct layout layout = {};
@ -432,6 +457,78 @@ static void CalcWindowInfo(struct WindowSurface *surface)
surface->height = layout.h; surface->height = layout.h;
} }
static bool AddSurface(struct WindowSurface *windowSurface,
uint32_t windowType, uint32_t windowMode)
{
struct WmsContext *ctx = windowSurface->controller->pWmsCtx;
struct ivi_layout_interface_for_wms *layoutInterface = ctx->pLayoutInterface;
struct weston_output *mainWestonOutput = ctx->pMainScreen->westonOutput;
struct WmsScreen *screen = NULL;
int32_t x = mainWestonOutput->width;
LOGD("start.");
wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
if (screen->screenId == windowSurface->screenId
|| ctx->displayMode == WMS_DISPLAY_MODE_CLONE
|| ctx->displayMode == WMS_DISPLAY_MODE_EXPAND) {
bool isNewLayer = false;
struct weston_output *westonOutput = screen->westonOutput;
uint32_t layerId = GetLayerId(screen->screenId, windowType, windowMode);
struct ivi_layout_layer *layoutLayer = GetLayer(screen->westonOutput,
layoutInterface, layerId, &isNewLayer);
if (!layoutLayer) {
LOGE("GetLayer failed.");
return false;
}
if (screen->screenId != mainWestonOutput->id && isNewLayer) {
if (ctx->displayMode == WMS_DISPLAY_MODE_CLONE) {
layoutInterface->layer_set_source_rectangle(layoutLayer, 0, 0,
mainWestonOutput->width, mainWestonOutput->height);
} else if (ctx->displayMode == WMS_DISPLAY_MODE_EXPAND) {
layoutInterface->layer_set_source_rectangle(layoutLayer, x, 0,
westonOutput->width, mainWestonOutput->height);
x += westonOutput->width;
}
}
layoutInterface->layer_add_surface(layoutLayer, windowSurface->layoutSurface);
}
}
layoutInterface->surface_set_visibility(windowSurface->layoutSurface, true);
LOGD("end.");
return true;
}
static bool RemoveSurface(struct WindowSurface *windowSurface)
{
struct WmsContext *ctx = windowSurface->controller->pWmsCtx;
struct ivi_layout_interface_for_wms *layoutInterface = ctx->pLayoutInterface;
struct WmsScreen *screen = NULL;
LOGD("start.");
wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
if (screen->screenId == windowSurface->screenId
|| ctx->displayMode == WMS_DISPLAY_MODE_CLONE
|| ctx->displayMode == WMS_DISPLAY_MODE_EXPAND) {
uint32_t layerId = GetLayerId(screen->screenId, windowSurface->type, windowSurface->mode);
struct ivi_layout_layer *layoutLayer = layoutInterface->get_layer_from_id(layerId);
if (!layoutLayer && screen->screenId == windowSurface->screenId) {
LOGE("get_layer_from_id failed. layerId=%{public}d", layerId);
continue;
}
layoutInterface->layer_remove_surface(layoutLayer, windowSurface->layoutSurface);
}
}
LOGD("end.");
return true;
}
static bool AddWindow(struct WindowSurface *windowSurface) static bool AddWindow(struct WindowSurface *windowSurface)
{ {
struct ivi_layout_layer *layoutLayer = NULL; struct ivi_layout_layer *layoutLayer = NULL;
@ -440,20 +537,9 @@ static bool AddWindow(struct WindowSurface *windowSurface)
LOGD("start."); LOGD("start.");
wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) { if (!AddSurface(windowSurface, windowSurface->type, windowSurface->mode)) {
if (screen->screenId == windowSurface->screenId LOGE("AddSurface failed.");
|| ctx->displayMode == WMS_DISPLAY_MODE_CLONE) { return false;
uint32_t layerId = GetLayerId(screen->screenId, windowSurface->type, windowSurface->mode);
layoutLayer = GetLayer(screen->westonOutput, ctx->pLayoutInterface, layerId);
if (!layoutLayer) {
LOGE("GetLayer failed.");
return false;
}
ctx->pLayoutInterface->layer_add_surface(layoutLayer,
windowSurface->layoutSurface);
ctx->pLayoutInterface->surface_set_visibility(
windowSurface->layoutSurface, true);
}
} }
// window position,size calc. // window position,size calc.
@ -557,6 +643,230 @@ static void ControllerCommitChanges(struct wl_client *client,
LOGD("end."); LOGD("end.");
} }
static bool LayerCopySurfaces(struct WmsContext *ctx, struct ivi_layout_layer *layerFrom,
struct ivi_layout_layer *layerTo)
{
LOGD("start.");
struct ivi_layout_surface **surfaces = NULL;
int32_t surfacesCount = 0;
uint32_t surfaceId = 0;
int32_t ret;
ret = ctx->pLayoutInterface->get_surfaces_on_layer(layerFrom, &surfacesCount, &surfaces);
if (ret != IVI_SUCCEEDED) {
LOGE("ivi_layout_get_surfaces_on_layer failed.");
return false;
}
for (int32_t surf_i = 0; surf_i < surfacesCount; surf_i++) {
ctx->pLayoutInterface->layer_add_surface(layerTo, surfaces[surf_i]);
}
if (surfaces != NULL) {
free(surfaces);
}
LOGD("end.");
return true;
}
static bool ScreenCopyLayers(struct WmsContext *ctx, struct WmsScreen *screenFrom,
struct WmsScreen *screenTo)
{
LOGD("start.");
struct ivi_layout_layer **layers = NULL;
int32_t layersCount = 0;
int32_t ret;
ret = ctx->pLayoutInterface->get_layers_on_screen(screenFrom->westonOutput, &layersCount, &layers);
if (ret != IVI_SUCCEEDED) {
LOGE("ivi_layout_get_layers_on_screen failed.");
return false;
}
for (int32_t layer_i = 0; layer_i < layersCount; layer_i++) {
uint32_t layerIdOld = ctx->pLayoutInterface->get_id_of_layer(layers[layer_i]);
uint32_t layerIdNew = ChangeLayerId(layerIdOld, screenFrom->screenId, screenTo->screenId);
struct ivi_layout_layer *layerNew = GetLayer(screenTo->westonOutput,
ctx->pLayoutInterface, layerIdNew, NULL);
if (!layerNew) {
LOGE("GetLayer failed.");
free(layers);
return false;
}
if (!LayerCopySurfaces(ctx, layers[layer_i], layerNew)) {
LOGE("LayerCopySurfaces failed.");
free(layers);
return false;
}
}
if (layers != NULL) {
free(layers);
}
ctx->pLayoutInterface->commit_changes();
LOGD("end.");
return true;
}
static bool ScreenSetLayersSourceRect(struct WmsScreen *screen,
int32_t x, int32_t y, int32_t w, int32_t h)
{
LOGD("start.");
struct WmsContext *ctx = screen->pWmsCtx;
struct ivi_layout_layer **layers = NULL;
int32_t layersCount = 0;
int32_t ret;
ret = ctx->pLayoutInterface->get_layers_on_screen(screen->westonOutput, &layersCount, &layers);
if (ret != IVI_SUCCEEDED) {
LOGE("ivi_layout_get_layers_on_screen failed.");
return false;
}
for (int32_t layer_i = 0; layer_i < layersCount; layer_i++) {
ret = ctx->pLayoutInterface->layer_set_source_rectangle(layers[layer_i], x, y, w, h);
if (ret != IVI_SUCCEEDED) {
free(layers);
return false;
}
}
if (layers != NULL) {
free(layers);
}
LOGD("end.");
return true;
}
static bool ScreenClone(struct WmsScreen *screenFrom, struct WmsScreen *screenTo)
{
LOGD("start.");
struct WmsContext *ctx = screenFrom->pWmsCtx;
bool ret;
ret = ScreenCopyLayers(ctx, screenFrom, screenTo);
if (!ret) {
LOGE("ScreenCopyLayers failed.");
return ret;
}
ret = ScreenSetLayersSourceRect(screenTo, 0, 0,
screenFrom->westonOutput->width, screenFrom->westonOutput->height);
if (!ret) {
LOGE("ScreenSetLayersSourceRect failed.");
return ret;
}
LOGD("end.");
return true;
}
static bool ScreenExpand(struct WmsScreen *screenMain, struct WmsScreen *screenExpand,
int32_t expandX, int32_t expandY)
{
LOGD("start.");
struct WmsContext *ctx = screenMain->pWmsCtx;
bool ret;
ret = ScreenCopyLayers(ctx, screenMain, screenExpand);
if (!ret) {
LOGE("ScreenCopyLayers failed.");
return ret;
}
ret = ScreenSetLayersSourceRect(screenExpand, expandX, expandY,
screenExpand->westonOutput->width, screenMain->westonOutput->height);
if (!ret) {
LOGE("ScreenSetLayersSourceRect failed.");
return ret;
}
LOGD("end.");
return true;
}
static bool ScreenClear(struct WmsScreen *screen)
{
LOGD("start.");
struct WmsContext *ctx = screen->pWmsCtx;
struct ivi_layout_layer **layers = NULL;
int32_t layersCount = 0;
int32_t ret;
ret = ctx->pLayoutInterface->get_layers_on_screen(screen->westonOutput, &layersCount, &layers);
if (ret != IVI_SUCCEEDED) {
LOGE("ivi_layout_get_layers_on_screen failed.");
return false;
}
for (int32_t layer_i = 0; layer_i < layersCount; layer_i++) {
struct ivi_layout_surface **surfaces = NULL;
int32_t surfacesCount = 0;
ret = ctx->pLayoutInterface->get_surfaces_on_layer(layers[layer_i], &surfacesCount, &surfaces);
if (ret != IVI_SUCCEEDED) {
LOGE("ivi_layout_get_surfaces_on_layer failed.");
return false;
}
for (int32_t surf_i = 0; surf_i < surfacesCount; surf_i++) {
ctx->pLayoutInterface->layer_remove_surface(layers[layer_i], surfaces[surf_i]);
}
if (surfaces != NULL) {
free(surfaces);
}
ctx->pLayoutInterface->layer_set_source_rectangle(layers[layer_i], 0, 0,
screen->westonOutput->width, screen->westonOutput->height);
}
if (layers != NULL) {
free(layers);
}
LOGD("end.");
return true;
}
static bool SetDisplayMode(struct WmsContext *ctx, uint32_t displayMode)
{
struct WmsScreen *screen = NULL;
bool ret = true;
ctx->pLayoutInterface->commit_changes();
if (ctx->displayMode != WMS_DISPLAY_MODE_SINGLE) {
wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
if (screen->screenId == ctx->pMainScreen->screenId) {
continue;
}
ret = ScreenClear(screen);
LOGI("screen_clear, id: %{public}d, ret = %{public}d", screen->screenId, ret);
}
}
int32_t x = ctx->pMainScreen->westonOutput->width;
if (displayMode == WMS_DISPLAY_MODE_CLONE
|| displayMode == WMS_DISPLAY_MODE_EXPAND) {
wl_list_for_each(screen, &ctx->wlListScreen, wlListLink) {
if (screen->screenId == ctx->pMainScreen->screenId) {
continue;
}
if (displayMode == WMS_DISPLAY_MODE_CLONE) {
ret = ScreenClone(ctx->pMainScreen, screen);
LOGI("screen_clone from %{public}d to %{public}d, ret = %{public}d",
ctx->pMainScreen->screenId, screen->screenId, ret);
} else {
ret = ScreenExpand(ctx->pMainScreen, screen, x, 0);
x += screen->westonOutput->width;
LOGI("screen_expand from %{public}d to %{public}d, ret = %{public}d",
ctx->pMainScreen->screenId, screen->screenId, ret);
}
}
}
ctx->pLayoutInterface->commit_changes();
return ret;
}
static void ControllerSetDisplayMode(struct wl_client *client, static void ControllerSetDisplayMode(struct wl_client *client,
struct wl_resource *resource, struct wl_resource *resource,
uint32_t displayMode) uint32_t displayMode)
@ -564,6 +874,7 @@ static void ControllerSetDisplayMode(struct wl_client *client,
LOGD("start. displayMode %{public}d", displayMode); LOGD("start. displayMode %{public}d", displayMode);
struct WmsController *controller = wl_resource_get_user_data(resource); struct WmsController *controller = wl_resource_get_user_data(resource);
struct WmsContext *ctx = controller->pWmsCtx; struct WmsContext *ctx = controller->pWmsCtx;
bool ret = true;
if (displayMode != WMS_DISPLAY_MODE_SINGLE && if (displayMode != WMS_DISPLAY_MODE_SINGLE &&
displayMode != WMS_DISPLAY_MODE_CLONE && displayMode != WMS_DISPLAY_MODE_CLONE &&
@ -577,23 +888,13 @@ static void ControllerSetDisplayMode(struct wl_client *client,
if (ctx->displayMode == displayMode) { if (ctx->displayMode == displayMode) {
LOGE("current displayMode is the same."); LOGE("current displayMode is the same.");
wms_send_reply_error(resource, WMS_ERROR_INVALID_PARAM); wms_send_reply_error(resource, WMS_ERROR_OK);
wl_client_flush(wl_resource_get_client(resource)); wl_client_flush(wl_resource_get_client(resource));
return; return;
} }
int32_t ret; ret = SetDisplayMode(ctx, displayMode);
if (displayMode == WMS_DISPLAY_MODE_CLONE) { if (ret == true) {
ctx->pLayoutInterface->commit_changes();
ret = ctx->pLayoutInterface->screen_clone(0, 1);
LOGE("screen_clone ret = %{public}d", ret);
} else {
ctx->pLayoutInterface->commit_changes();
ret = ctx->pLayoutInterface->screen_clear(1);
LOGE("screen_clear ret = %{public}d", ret);
}
if (ret == IVI_SUCCEEDED) {
ctx->displayMode = displayMode; ctx->displayMode = displayMode;
wms_send_reply_error(resource, WMS_ERROR_OK); wms_send_reply_error(resource, WMS_ERROR_OK);
wl_client_flush(wl_resource_get_client(resource)); wl_client_flush(wl_resource_get_client(resource));
@ -606,44 +907,78 @@ static void ControllerSetDisplayMode(struct wl_client *client,
LOGD("end. displayMode %{public}d", ctx->displayMode); LOGD("end. displayMode %{public}d", ctx->displayMode);
} }
static void MoveWindowToLayerId(const struct WmsContext *wc, static void ControllerCreateVirtualDisplay(struct wl_client *pWlClient,
const struct WindowSurface *ws, struct wl_resource *pWlResource, int32_t x, int32_t y, int32_t width, int32_t height)
struct wl_resource *wr,
uint32_t layerIdNew)
{ {
struct ivi_layout_layer *pLayoutLayerOld = NULL; LOGD("start. CreateVirtualDisplay, x:%{public}d, y:%{public}d, "
struct ivi_layout_layer *pLayoutLayerNew = NULL; "w:%{public}d, h:%{public}d", x, y, width, height);
struct ivi_layout_interface_for_wms *pLayoutInterface = wc->pLayoutInterface; struct WmsController *pWmsController = wl_resource_get_user_data(pWlResource);
struct WmsScreen *screen = NULL; struct WmsContext *pWmsCtx = pWmsController->pWmsCtx;
struct ivi_layout_interface_for_wms *pLayoutInterface = pWmsCtx->pLayoutInterface;
struct weston_output *pOutput = NULL;
struct WmsScreen *pScreen = NULL;
wl_list_for_each(screen, &wc->wlListScreen, wlListLink) { wl_list_for_each(pScreen, &pWmsCtx->wlListScreen, wlListLink) {
if (screen->screenId == ws->screenId if (pScreen->screenType == WMS_SCREEN_TYPE_VIRTUAL) {
|| wc->displayMode == WMS_DISPLAY_MODE_CLONE) { LOGE("virtual display already exists.");
uint32_t layerIdOld = GetLayerId(screen->screenId, ws->type, ws->mode); wms_send_reply_error(pWlResource, WMS_ERROR_OK);
pLayoutLayerOld = pLayoutInterface->get_layer_from_id(layerIdOld); return;
if (!pLayoutLayerOld) {
if (screen->screenId == ws->screenId) {
LOGE("get_layer_from_id failed. layerId=%{public}d", layerIdOld);
wms_send_reply_error(wr, WMS_ERROR_INNER_ERROR);
wl_client_flush(wl_resource_get_client(wr));
return;
} else {
continue;
}
}
pLayoutLayerNew = GetLayer(screen->westonOutput, pLayoutInterface, layerIdNew);
if (!pLayoutLayerNew) {
LOGE("GetLayer failed.");
wms_send_reply_error(wr, WMS_ERROR_INNER_ERROR);
wl_client_flush(wl_resource_get_client(wr));
return;
}
pLayoutInterface->layer_remove_surface(pLayoutLayerOld, ws->layoutSurface);
pLayoutInterface->layer_add_surface(pLayoutLayerNew, ws->layoutSurface);
} }
} }
pOutput = pLayoutInterface->create_virtual_screen(x, y, width, height);
if (pOutput == NULL) {
LOGE("layout create_virtual_screen failed.");
wms_send_reply_error(pWlResource, WMS_ERROR_NO_MEMORY);
return;
}
if (CreateScreen(pWmsCtx, pOutput, WMS_SCREEN_TYPE_VIRTUAL) < 0) {
pLayoutInterface->destroy_virtual_screen(pOutput->id);
wms_send_reply_error(pWlResource, WMS_ERROR_NO_MEMORY);
return;
}
wms_send_screen_status(pWlResource, pOutput->id, pOutput->name, WMS_SCREEN_STATUS_ADD,
pOutput->width, pOutput->height, WMS_SCREEN_TYPE_VIRTUAL);
wms_send_reply_error(pWlResource, WMS_ERROR_OK);
wl_list_for_each(pWmsController, &pWmsCtx->wlListController, wlListLink) {
wms_send_screen_status(pWmsController->pWlResource, pOutput->id, pOutput->name,
WMS_SCREEN_STATUS_ADD, pOutput->width, pOutput->height, WMS_SCREEN_TYPE_VIRTUAL);
}
LOGD("end. CreateVirtualDisplay");
}
static void ControllerDestroyVirtualDisplay(struct wl_client *pWlClient,
struct wl_resource *pWlResource,
uint32_t screenID)
{
LOGD("start. DestroyVirtualDisplay, screen id:%{public}d", screenID);
struct WmsController *pWmsController = wl_resource_get_user_data(pWlResource);
struct WmsContext *pWmsCtx = pWmsController->pWmsCtx;
struct ivi_layout_interface_for_wms *pLayoutInterface = pWmsCtx->pLayoutInterface;
struct WmsScreen *pScreen = NULL;
pScreen = GetScreenFromId(pWmsCtx, screenID);
if (!pScreen || pScreen->screenType != WMS_SCREEN_TYPE_VIRTUAL) {
LOGE("screen is not found[%{public}d].", screenID);
wms_send_reply_error(pWlResource, WMS_ERROR_INVALID_PARAM);
return;
}
pLayoutInterface->destroy_virtual_screen(screenID);
DestroyScreen(pScreen);
wms_send_screen_status(pWlResource, screenID, "", WMS_SCREEN_STATUS_REMOVE,
0, 0, 0);
wms_send_reply_error(pWlResource, WMS_ERROR_OK);
wl_list_for_each(pWmsController, &pWmsCtx->wlListController, wlListLink) {
wms_send_screen_status(pWmsController->pWlResource, screenID, "",
WMS_SCREEN_STATUS_REMOVE, 0, 0, 0);
}
LOGD("end. DestroyVirtualDisplay");
} }
static void SetWindowPosition(struct WindowSurface *ws, static void SetWindowPosition(struct WindowSurface *ws,
@ -663,20 +998,18 @@ static void SetWindowSize(struct WindowSurface *ws,
ws->height = height; ws->height = height;
} }
static void SetWindowType(const struct WmsContext *wc, static void SetWindowType(struct WindowSurface *ws,
const struct WindowSurface *ws,
struct wl_resource *wr,
uint32_t windowType) uint32_t windowType)
{ {
MoveWindowToLayerId(wc, ws, wr, GetLayerId(ws->screenId, windowType, ws->mode)); RemoveSurface(ws);
AddSurface(ws, windowType, ws->mode);
} }
static void SetWindowMode(const struct WmsContext *wc, static void SetWindowMode(struct WindowSurface *ws,
struct WindowSurface *ws,
struct wl_resource *wr,
uint32_t windowMode) uint32_t windowMode)
{ {
MoveWindowToLayerId(wc, ws, wr, GetLayerId(ws->screenId, ws->type, windowMode)); RemoveSurface(ws);
AddSurface(ws, ws->type, windowMode);
} }
static void ControllerSetWindowType(struct wl_client *pWlClient, static void ControllerSetWindowType(struct wl_client *pWlClient,
@ -717,7 +1050,7 @@ static void ControllerSetWindowType(struct wl_client *pWlClient,
return; return;
} }
SetWindowType(pWmsCtx, pWindowSurface, pWlResource, windowType); SetWindowType(pWindowSurface, windowType);
pWindowSurface->type = windowType; pWindowSurface->type = windowType;
@ -764,7 +1097,7 @@ static void ControllerSetWindowMode(struct wl_client *pWlClient,
return; return;
} }
SetWindowMode(pWmsCtx, pWindowSurface, pWlResource, windowMode); SetWindowMode(pWindowSurface, windowMode);
pWindowSurface->mode = windowMode; pWindowSurface->mode = windowMode;
wms_send_reply_error(pWlResource, WMS_ERROR_OK); wms_send_reply_error(pWlResource, WMS_ERROR_OK);
wl_client_flush(wl_resource_get_client(pWlResource)); wl_client_flush(wl_resource_get_client(pWlResource));
@ -1346,7 +1679,7 @@ static void ControllerCreateWindow(struct wl_client *pWlClient,
return; return;
} }
if (screenId > 0 && pWmsCtx->displayMode != WMS_DISPLAY_MODE_EXPAND) { if (screenId > 0 && pWmsCtx->displayMode != WMS_DISPLAY_MODE_EXTEND) {
LOGE("screenId %{public}d error.", screenId); LOGE("screenId %{public}d error.", screenId);
wms_send_window_status(pWlResource, WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0); wms_send_window_status(pWlResource, WMS_WINDOW_STATUS_FAILED, WINDOW_ID_INVALID, 0, 0, 0, 0);
wl_client_flush(wl_resource_get_client(pWlResource)); wl_client_flush(wl_resource_get_client(pWlResource));
@ -1671,6 +2004,8 @@ static const struct wms_interface g_controllerImplementation = {
ControllerCommitChanges, ControllerCommitChanges,
ControllerScreenshot, ControllerScreenshot,
ControllerWindowshot, ControllerWindowshot,
ControllerCreateVirtualDisplay,
ControllerDestroyVirtualDisplay,
}; };
static void UnbindWmsController(struct wl_resource *pResource) static void UnbindWmsController(struct wl_resource *pResource)
@ -1730,24 +2065,14 @@ static void BindWmsController(struct wl_client *pClient,
wl_list_init(&pController->stListener.frameListener.link); wl_list_init(&pController->stListener.frameListener.link);
wl_list_init(&pController->stListener.outputDestroyed.link); wl_list_init(&pController->stListener.outputDestroyed.link);
struct WmsScreen *pScreen = NULL;
struct weston_output *pOutput = NULL; struct weston_output *pOutput = NULL;
wl_list_for_each(pOutput, &pCtx->pCompositor->output_list, link) { wl_list_for_each(pScreen, &pCtx->wlListScreen, wlListLink) {
pOutput = pScreen->westonOutput;
wms_send_screen_status(pController->pWlResource, pOutput->id, pOutput->name, WMS_SCREEN_STATUS_ADD, wms_send_screen_status(pController->pWlResource, pOutput->id, pOutput->name, WMS_SCREEN_STATUS_ADD,
#ifdef USE_DUMMY_SCREEN pOutput->width, pOutput->height, pScreen->screenType);
DUMMY_SCREEN_WIDTH, DUMMY_SCREEN_HEIGHT);
#else
pOutput->width, pOutput->height);
#endif /* USE_DUMMY_SCREEN */
wl_client_flush(wl_resource_get_client(pController->pWlResource));
} }
#ifdef USE_DUMMY_SCREEN
pOutput = pCtx->pLayoutInterface->get_dummy_output();
wms_send_screen_status(pController->pWlResource, pOutput->id, pOutput->name, WMS_SCREEN_STATUS_ADD,
pOutput->width, pOutput->height);
wl_client_flush(wl_resource_get_client(pController->pWlResource));
#endif /* USE_DUMMY_SCREEN */
uint32_t flag = GetDisplayModeFlag(pController->pWmsCtx); uint32_t flag = GetDisplayModeFlag(pController->pWmsCtx);
wms_send_display_mode(pController->pWlResource, flag); wms_send_display_mode(pController->pWlResource, flag);
wl_client_flush(wl_resource_get_client(pController->pWlResource)); wl_client_flush(wl_resource_get_client(pController->pWlResource));
@ -1822,7 +2147,8 @@ static void WmsControllerDestroy(struct wl_listener *listener, void *data)
} }
static int32_t CreateScreen(struct WmsContext *pCtx, static int32_t CreateScreen(struct WmsContext *pCtx,
struct weston_output *pOutput) struct weston_output *pOutput,
uint32_t screenType)
{ {
struct WmsScreen *pScreen = NULL; struct WmsScreen *pScreen = NULL;
@ -1834,8 +2160,13 @@ static int32_t CreateScreen(struct WmsContext *pCtx,
pScreen->pWmsCtx = pCtx; pScreen->pWmsCtx = pCtx;
pScreen->westonOutput = pOutput; pScreen->westonOutput = pOutput;
pScreen->screenId = pOutput->id; pScreen->screenId = pOutput->id;
pScreen->screenType = screenType;
wl_list_insert(&pCtx->wlListScreen, &pScreen->wlListLink); if (pScreen->screenId == 0) {
pCtx->pMainScreen = pScreen;
}
wl_list_insert(pCtx->wlListScreen.prev, &pScreen->wlListLink);
return 0; return 0;
} }
@ -1868,10 +2199,12 @@ static void OutputCreatedEvent(struct wl_listener *listener, void *data)
struct WmsContext *ctx = wl_container_of(listener, ctx, wlListenerOutputCreated); struct WmsContext *ctx = wl_container_of(listener, ctx, wlListenerOutputCreated);
struct weston_output *createdOutput = (struct weston_output*)data; struct weston_output *createdOutput = (struct weston_output*)data;
CreateScreen(ctx, createdOutput); CreateScreen(ctx, createdOutput, WMS_SCREEN_TYPE_PHYSICAL);
DisplayModeUpdate(ctx); DisplayModeUpdate(ctx);
SetDisplayMode(ctx, ctx->displayMode);
ScreenInfoChangerNotify(); ScreenInfoChangerNotify();
LOGD("end."); LOGD("end.");
@ -1953,11 +2286,9 @@ static int WmsContextInit(struct WmsContext *ctx, struct weston_compositor *comp
} }
ctx->wlListenerDestroy.notify = WmsControllerDestroy; ctx->wlListenerDestroy.notify = WmsControllerDestroy;
#ifdef USE_DUMMY_SCREEN
ctx->displayMode = WMS_DISPLAY_MODE_CLONE; ctx->displayMode = WMS_DISPLAY_MODE_EXTEND;
#else
ctx->displayMode = WMS_DISPLAY_MODE_SINGLE;
#endif
wl_signal_add(&compositor->destroy_signal, &ctx->wlListenerDestroy); wl_signal_add(&compositor->destroy_signal, &ctx->wlListenerDestroy);
LayoutControllerInit(0, 0); LayoutControllerInit(0, 0);
@ -1977,22 +2308,13 @@ WL_EXPORT int wet_module_init(struct weston_compositor *compositor,
} }
wl_list_for_each(output, &compositor->output_list, link) { wl_list_for_each(output, &compositor->output_list, link) {
if (CreateScreen(ctx, output) < 0) { if (CreateScreen(ctx, output, WMS_SCREEN_TYPE_PHYSICAL) < 0) {
WmsScreenDestroy(ctx); WmsScreenDestroy(ctx);
free(ctx); free(ctx);
return -1; return -1;
} }
} }
#ifdef USE_DUMMY_SCREEN
output = ctx->pLayoutInterface->get_dummy_output();
if (CreateScreen(ctx, output) < 0) {
WmsScreenDestroy(ctx);
free(ctx);
return -1;
}
#endif /* USE_DUMMY_SCREEN */
ScreenInfoInit(compositor); ScreenInfoInit(compositor);
LOGD("end."); LOGD("end.");

View File

@ -44,6 +44,7 @@ struct WmsContext {
struct wl_listener wlListenerOutputDestroyed; struct wl_listener wlListenerOutputDestroyed;
struct wl_listener wlListenerSeatCreated; struct wl_listener wlListenerSeatCreated;
uint32_t displayMode; uint32_t displayMode;
struct WmsScreen *pMainScreen;
#ifdef USE_IVI_INPUT_FOCUS #ifdef USE_IVI_INPUT_FOCUS
const struct ivi_input_interface_for_wms *pInputInterface; const struct ivi_input_interface_for_wms *pInputInterface;
#endif #endif
@ -63,6 +64,7 @@ struct WmsScreen {
struct wl_list wlListLink; struct wl_list wlListLink;
struct WmsContext *pWmsCtx; struct WmsContext *pWmsCtx;
uint32_t screenId; uint32_t screenId;
uint32_t screenType;
struct weston_output *westonOutput; struct weston_output *westonOutput;
}; };

View File

@ -57,9 +57,11 @@ public:
virtual sptr<PromiseWMError> ScaleTo(int32_t wid, uint32_t width, uint32_t height) override; virtual sptr<PromiseWMError> ScaleTo(int32_t wid, uint32_t width, uint32_t height) override;
virtual sptr<PromiseWMError> SetWindowType(int32_t wid, WindowType type) override; virtual sptr<PromiseWMError> SetWindowType(int32_t wid, WindowType type) override;
virtual sptr<PromiseWMError> SetWindowMode(int32_t wid, WindowMode mode) override; virtual sptr<PromiseWMError> SetWindowMode(int32_t wid, WindowMode mode) override;
virtual sptr<PromiseWMError> CreateVirtualDisplay(int32_t x, int32_t y, int32_t width, int32_t height) override;
virtual sptr<PromiseWMError> DestroyVirtualDisplay(uint32_t did) override;
static void OnReply(wms_error); static void OnReply(wms_error);
static void OnDisplayChange(uint32_t, const char *, wms_screen_status, int32_t, int32_t); static void OnDisplayChange(uint32_t, const char *, wms_screen_status, int32_t, int32_t, wms_screen_type type);
static void OnDisplayPower(uint32_t, int32_t); static void OnDisplayPower(uint32_t, int32_t);
static void OnDisplayBacklight(uint32_t, uint32_t); static void OnDisplayBacklight(uint32_t, uint32_t);
static void OnDisplayModeChange(uint32_t); static void OnDisplayModeChange(uint32_t);

View File

@ -48,9 +48,10 @@ void OnReply(void *, struct wms *, uint32_t a)
} }
void OnDisplayChange(void *, struct wms *, void OnDisplayChange(void *, struct wms *,
uint32_t a, const char *b, uint32_t c, int32_t d, int32_t e) uint32_t a, const char *b, uint32_t c, int32_t d, int32_t e, uint32_t f)
{ {
WindowManagerServiceProxy::OnDisplayChange(a, b, static_cast<wms_screen_status>(c), d, e); WindowManagerServiceProxy::OnDisplayChange(a, b, static_cast<wms_screen_status>(c), d, e,
static_cast<wms_screen_type>(f));
} }
void OnDisplayPower(void *, struct wms *, uint32_t a, int32_t b) void OnDisplayPower(void *, struct wms *, uint32_t a, int32_t b)

View File

@ -66,7 +66,7 @@ void WindowManagerServiceProxy::OnReply(wms_error error)
} }
void WindowManagerServiceProxy::OnDisplayChange(uint32_t did, void WindowManagerServiceProxy::OnDisplayChange(uint32_t did,
const char *name, wms_screen_status state, int32_t width, int32_t height) const char *name, wms_screen_status state, int32_t width, int32_t height, wms_screen_type type)
{ {
WMLOGFI("state: %{public}d, did: %{public}d, %{public}s(%{public}dx%{public}d)", WMLOGFI("state: %{public}d, did: %{public}d, %{public}s(%{public}dx%{public}d)",
state, did, name, width, height); state, did, name, width, height);
@ -84,6 +84,7 @@ void WindowManagerServiceProxy::OnDisplayChange(uint32_t did,
.phyWidth = width, .phyWidth = width,
.phyHeight = height, .phyHeight = height,
.vsync = tmpVsyncFreq, .vsync = tmpVsyncFreq,
.type = static_cast<enum DisplayType>(type),
}; };
displays.push_back(info); displays.push_back(info);
} }
@ -475,4 +476,27 @@ sptr<PromiseWMError> WindowManagerServiceProxy::SetWindowMode(int32_t wid, Windo
wl_display_flush(display); wl_display_flush(display);
return ret; return ret;
} }
sptr<PromiseWMError> WindowManagerServiceProxy::CreateVirtualDisplay(
int32_t x, int32_t y, int32_t width, int32_t height)
{
sptr<PromiseWMError> ret = new PromiseWMError();
std::lock_guard<std::mutex> lock(promiseQueueMutex);
promiseQueue.push(ret);
wms_create_virtual_display(wms, x, y, width, height);
wms_commit_changes(wms);
wl_display_flush(display);
return ret;
}
sptr<PromiseWMError> WindowManagerServiceProxy::DestroyVirtualDisplay(uint32_t did)
{
sptr<PromiseWMError> ret = new PromiseWMError();
std::lock_guard<std::mutex> lock(promiseQueueMutex);
promiseQueue.push(ret);
wms_destroy_virtual_display(wms, did);
wms_commit_changes(wms);
wl_display_flush(display);
return ret;
}
} // namespace OHOS } // namespace OHOS

View File

@ -33,10 +33,15 @@ ohos_executable("wmtest") {
sources = [ sources = [
"frameworks/inative_test.cpp", "frameworks/inative_test.cpp",
"frameworks/main.cpp", "frameworks/main.cpp",
"frameworks/main_option.cpp",
"frameworks/native_test_class.cpp", "frameworks/native_test_class.cpp",
"frameworks/util.cpp", "frameworks/util.cpp",
]
sources += [
"test/crash_native_test_1.cpp", "test/crash_native_test_1.cpp",
"test/crash_native_test_2.cpp", "test/crash_native_test_2.cpp",
"test/dumper_test_1.cpp",
"test/other_native_test_1.cpp", "test/other_native_test_1.cpp",
"test/pref_native_test_1.cpp", "test/pref_native_test_1.cpp",
"test/vsync_native_test_1.cpp", "test/vsync_native_test_1.cpp",
@ -58,6 +63,9 @@ ohos_executable("wmtest") {
"test/wmclient_native_test_29.cpp", "test/wmclient_native_test_29.cpp",
"test/wmclient_native_test_30.cpp", "test/wmclient_native_test_30.cpp",
"test/wmclient_native_test_32.cpp", "test/wmclient_native_test_32.cpp",
"test/wmclient_native_test_33.cpp",
"test/wmclient_native_test_34.cpp",
"test/wmclient_native_test_35.cpp",
"test/wmclient_native_test_4.cpp", "test/wmclient_native_test_4.cpp",
"test/wmclient_native_test_5.cpp", "test/wmclient_native_test_5.cpp",
"test/wmclient_native_test_6.cpp", "test/wmclient_native_test_6.cpp",
@ -80,9 +88,11 @@ ohos_executable("wmtest") {
deps = [ deps = [
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core", "//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//foundation/graphic/standard:libgraphic_dumper_client",
"//foundation/graphic/standard:libvsync_client", "//foundation/graphic/standard:libvsync_client",
"//foundation/graphic/standard:libwmclient", "//foundation/graphic/standard:libwmclient",
"//foundation/graphic/standard:libwmservice", "//foundation/graphic/standard:libwmservice",
"//foundation/graphic/standard/utils:option_parser",
"//foundation/multimodalinput/input/frameworks/proxy:libmmi-client", "//foundation/multimodalinput/input/frameworks/proxy:libmmi-client",
"//third_party/zlib:libz", "//third_party/zlib:libz",
] ]

View File

@ -24,13 +24,16 @@
#include <window_manager.h> #include <window_manager.h>
#include "inative_test.h" #include "inative_test.h"
#include "main_option.h"
#include "native_test_class.h"
using namespace OHOS; using namespace OHOS;
namespace { namespace {
void Usage(const char *argv0) void Usage(const char *argv0)
{ {
printf("Usage: %s type id\n", argv0); std::cerr << "Usage: " << argv0 << " [option] type id" << std::endl;
std::cerr << "-d, --display[=0] Created Window's Display ID" << std::endl;
auto visitFunc = [](const INativeTest *test) { auto visitFunc = [](const INativeTest *test) {
std::stringstream ss; std::stringstream ss;
ss << test->GetDomain() << ", id="; ss << test->GetDomain() << ", id=";
@ -48,37 +51,34 @@ void Usage(const char *argv0)
int32_t main(int32_t argc, const char **argv) int32_t main(int32_t argc, const char **argv)
{ {
constexpr int32_t argNumber = 2; // parse option
if (argc <= argNumber) { MainOption option;
Usage(argv[0]); if (option.Parse(argc, argv)) {
return 0; std::cerr << option.GetErrorString() << std::endl;
}
int32_t testcase = -1;
constexpr int32_t domainIndex = 1;
constexpr int32_t idIndex = 2;
std::stringstream ss(argv[idIndex]);
ss >> testcase;
if (!ss || testcase == -1) {
Usage(argv[0]); Usage(argv[0]);
return 1; return 1;
} }
// find test
INativeTest *found = nullptr; INativeTest *found = nullptr;
auto visitFunc = [argv, testcase, &found](INativeTest *test) { auto visitFunc = [&option, &found](INativeTest *test) {
if (test->GetDomain() == argv[domainIndex] && test->GetID() == testcase) { if (test->GetDomain() == option.domain && test->GetID() == option.testcase) {
found = test; found = test;
} }
}; };
INativeTest::VisitTests(visitFunc); INativeTest::VisitTests(visitFunc);
if (found == nullptr) { if (found == nullptr) {
printf("not found test %d\n", testcase); printf("not found test %d\n", option.testcase);
return 1; return 1;
} }
// default value assign
NativeTestFactory::defaultDisplayID = option.displayID;
// run test
auto runner = AppExecFwk::EventRunner::Create(false); auto runner = AppExecFwk::EventRunner::Create(false);
auto handler = std::make_shared<AppExecFwk::EventHandler>(runner); auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
handler->PostTask(std::bind(&INativeTest::Run, found, argc - argNumber, argv + argNumber)); handler->PostTask(std::bind(&INativeTest::Run, found, option.GetSkippedArgc(), option.GetSkippedArgv()));
if (found->GetLastTime() != INativeTest::LAST_TIME_FOREVER) { if (found->GetLastTime() != INativeTest::LAST_TIME_FOREVER) {
handler->PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner), found->GetLastTime()); handler->PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner), found->GetLastTime());
} }

View File

@ -0,0 +1,29 @@
/*
* 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 "main_option.h"
MainOption::MainOption()
{
AddArguments(domain);
AddArguments(testcase);
AddOption("d", "display", displayID);
}
int32_t MainOption::Parse(int32_t argc, const char **argv)
{
// ignore wmtest(argv0)
return OptionParser::Parse(argc - 1, argv + 1);
}

View File

@ -0,0 +1,32 @@
/*
* 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 FRAMEWORKS_WMTEST_FRAMEWORKS_MAIN_OPTION_H
#define FRAMEWORKS_WMTEST_FRAMEWORKS_MAIN_OPTION_H
#include <option_parser.h>
class MainOption : public OptionParser {
public:
MainOption();
int32_t Parse(int32_t argc, const char **argv);
// attr
std::string domain = "";
int32_t testcase = -1;
int32_t displayID = 0;
};
#endif // FRAMEWORKS_WMTEST_FRAMEWORKS_MAIN_OPTION_H

View File

@ -33,7 +33,9 @@
#define NUMBER_VERTICES 4 #define NUMBER_VERTICES 4
namespace OHOS { namespace OHOS {
sptr<Window> NativeTestFactory::CreateWindow(WindowType type, sptr<Surface> csurface) sptr<Window> NativeTestFactory::CreateWindow(WindowType type,
sptr<Surface> csurface,
std::optional<uint32_t> did)
{ {
auto wm = WindowManager::GetInstance(); auto wm = WindowManager::GetInstance();
if (wm == nullptr) { if (wm == nullptr) {
@ -48,6 +50,7 @@ sptr<Window> NativeTestFactory::CreateWindow(WindowType type, sptr<Surface> csur
sptr<Window> window; sptr<Window> window;
option->SetWindowType(type); option->SetWindowType(type);
option->SetConsumerSurface(csurface); option->SetConsumerSurface(csurface);
option->SetDisplay(did.value_or(defaultDisplayID));
wm->CreateWindow(window, option); wm->CreateWindow(window, option);
if (window == nullptr) { if (window == nullptr) {
printf("NativeTestFactory::CreateWindow return nullptr\n"); printf("NativeTestFactory::CreateWindow return nullptr\n");

View File

@ -18,6 +18,7 @@
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <optional>
#include <refbase.h> #include <refbase.h>
#include <window_manager.h> #include <window_manager.h>
@ -40,7 +41,10 @@ typedef struct {
class NativeTestFactory { class NativeTestFactory {
public: public:
static sptr<Window> CreateWindow(WindowType, sptr<Surface> csurface = nullptr); static sptr<Window> CreateWindow(WindowType type,
sptr<Surface> csurface = nullptr,
std::optional<uint32_t> did = std::nullopt);
static inline int32_t defaultDisplayID = 0;
}; };
using DrawFunc = std::function<void(void *, uint32_t, uint32_t, uint32_t)>; using DrawFunc = std::function<void(void *, uint32_t, uint32_t, uint32_t)>;

View File

@ -0,0 +1,155 @@
/*
* 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 "other_native_test_1.h"
#include <csignal>
#include <string>
#include <unistd.h>
#include <graphic_dumper_helper.h>
#include <option_parser.h>
#include "inative_test.h"
#include "native_test_class.h"
#include "util.h"
using namespace OHOS;
namespace {
class DumperTest1 : public INativeTest {
public:
std::string GetDescription() const override
{
constexpr const char *desc = "dumper native test";
return desc;
}
std::string GetDomain() const override
{
constexpr const char *domain = "!dumper";
return domain;
}
int32_t GetID() const override
{
constexpr int32_t id = 1;
return id;
}
uint32_t GetLastTime() const override
{
constexpr uint32_t lastTime = LAST_TIME_FOREVER;
return lastTime;
}
static void Handler(int32_t signal)
{
int32_t signals[] = {SIGINT, SIGKILL, SIGTERM, SIGTSTP, SIGQUIT, SIGHUP};
for (uint32_t i = 0; i < sizeof(signals) / sizeof(*signals); i++) {
if (signals[i] == signal) {
ExitTest();
break;
}
}
}
void Run(int32_t argc, const char **argv) override
{
handler = AppExecFwk::EventHandler::Current();
printf("graphic dumper test start!\n");
std::signal(SIGINT, Handler);
std::signal(SIGKILL, Handler);
std::signal(SIGTERM, Handler);
std::signal(SIGTSTP, Handler);
std::signal(SIGQUIT, Handler);
std::signal(SIGHUP, Handler);
OptionParser parser;
parser.AddArguments(tagInfo);
parser.Parse(argc, argv);
dumper = GraphicDumperHelper::GetInstance();
configListener = dumper->AddConfigChangeListener(tagInfo + ".info",
std::bind(&DumperTest1::OnConfigChange, this, std::placeholders::_1, std::placeholders::_2));
dumpListener = dumper->AddDumpListener(tagInfo + ".info", std::bind(&DumperTest1::OnDump, this));
AfterRun();
}
void AfterRun()
{
auto str = "ABCEDFGHIG0123456789ABCEDFGHIG0123456789ABCEDFGHIG0123456789";
int32_t ret = dumper->SendInfo("log." + tagInfo, "[%d]%s just for test log %d!!!\n", getpid(), str, count++);
if (ret != 0) {
printf("graphic dumper service died!\n");
ExitDump();
return;
}
ret = dumper->SendInfo("log." + tagInfo + ".1", "[%d]%s\njust for test2 log %d!!!\n", getpid(), str, count++);
if (ret != 0) {
printf("graphic dumper service died!\n");
ExitDump();
}
constexpr int32_t delayTime = 10;
PostTask(std::bind(&DumperTest1::AfterRun, this), delayTime);
}
void ExitDump()
{
if (configListener != 0) {
dumper->RemoveConfigChangeListener(configListener);
}
if (dumpListener != 0) {
dumper->RemoveDumpListener(dumpListener);
}
ExitTest();
}
void OnConfigChange(const std::string &key, const std::string &val)
{
auto func = [this]() {
auto str = "********** !!! just for test send info !!! **********\n";
int32_t ret = dumper->SendInfo(tagInfo, str);
printf("graphic dumper ret = %d\n", ret);
if (ret != 0) {
printf("graphic dumper service died!\n");
handler->PostTask(std::bind(&DumperTest1::ExitDump, this));
}
};
printf("%s -> %s\n", key.c_str(), val.c_str());
if (key.find("info") != std::string::npos && val.compare("true") == 0) {
handler->PostTask(func);
}
}
void OnDump()
{
printf("OnDump\n");
dumper->SendInfo(tagInfo, "pid[%d] send dump info \n", getpid());
}
private:
static inline std::shared_ptr<AppExecFwk::EventHandler> handler = nullptr;
std::string tagInfo = "A.B.info";
sptr<GraphicDumperHelper> dumper = nullptr;
int32_t configListener = 0;
int32_t dumpListener = 0;
int32_t count = 0;
} g_autoload;
} // namespace

View File

@ -0,0 +1,19 @@
/*
* 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 FRAMEWORKS_WMTEST_TEST_DUMPER_TEST_1
#define FRAMEWORKS_WMTEST_TEST_DUMPER_TEST_1
#endif // FRAMEWORKS_WMTEST_TEST_DUMPER_TEST_1

View File

@ -17,8 +17,9 @@
#include <cinttypes> #include <cinttypes>
#include <cstdio> #include <cstdio>
#include <securec.h> #include <iostream>
#include <option_parser.h>
#include <zlib.h> #include <zlib.h>
#include "inative_test.h" #include "inative_test.h"
@ -56,16 +57,11 @@ public:
void Run(int32_t argc, const char **argv) override void Run(int32_t argc, const char **argv) override
{ {
if (argc <= 1) { OptionParser parser;
printf("need a compress size\n"); int32_t size = -1;
ExitTest(); parser.AddArguments(size);
return; if (parser.Parse(argc, argv)) {
} std::cerr << parser.GetErrorString() << std::endl;
uint32_t size = -1;
int ret = sscanf_s(argv[1], "%u", &size);
if (ret == 0) {
printf("%s parse argv[2] failed\n", __func__);
ExitTest(); ExitTest();
return; return;
} }

View File

@ -21,6 +21,7 @@
#include <sstream> #include <sstream>
#include <display_type.h> #include <display_type.h>
#include <option_parser.h>
#include <window_manager.h> #include <window_manager.h>
#include "inative_test.h" #include "inative_test.h"
@ -76,15 +77,8 @@ public:
} }
} }
bool CheckArguments(const char *argv1, int &typeId) bool CheckArguments(int32_t typeId)
{ {
std::stringstream ss(argv1);
ss >> typeId;
if (!ss.eof() || !ss) {
printf("input error\n");
return false;
}
if (typeId < 0 || typeId > WINDOW_TYPE_MAX) { if (typeId < 0 || typeId > WINDOW_TYPE_MAX) {
printf ("input id is %d, not with rules!!!\n", typeId); printf ("input id is %d, not with rules!!!\n", typeId);
return false; return false;
@ -95,8 +89,17 @@ public:
void Run(int32_t argc, const char **argv) override void Run(int32_t argc, const char **argv) override
{ {
int type = -1; OptionParser parser;
if (argc == 1 || (!CheckArguments(argv[1], type))) { int32_t type = -1;
parser.AddArguments(type);
if (parser.Parse(argc, argv)) {
std::cerr << parser.GetErrorString() << std::endl;
Usage();
ExitTest();
return;
}
if (!CheckArguments(type)) {
Usage(); Usage();
ExitTest(); ExitTest();
return; return;
@ -112,13 +115,14 @@ public:
window = NativeTestFactory::CreateWindow(static_cast<WindowType>(type)); window = NativeTestFactory::CreateWindow(static_cast<WindowType>(type));
if (window == nullptr) { if (window == nullptr) {
printf("NativeTestFactory::CreateWindow return nullptr\n"); printf("NativeTestFactory::CreateWindow return nullptr\n");
ExitTest();
return; return;
} }
window->SwitchTop(); window->SwitchTop();
auto surface = window->GetSurface(); auto surface = window->GetSurface();
windowSync = NativeTestSync::CreateSync(NativeTestDraw::FlushDraw, surface); windowSync = NativeTestSync::CreateSync(NativeTestDraw::FlushDraw, surface);
} }
private: private:
sptr<Window> window = nullptr; sptr<Window> window = nullptr;

View File

@ -0,0 +1,127 @@
/*
* 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 "wmclient_native_test_33.h"
#include <cstdio>
#include <securec.h>
#include <display_type.h>
#include <window_manager.h>
#include "inative_test.h"
#include "native_test_class.h"
#include "util.h"
using namespace OHOS;
namespace {
constexpr int32_t VIRTUAL_DISPLAY_X = 100;
constexpr int32_t VIRTUAL_DISPLAY_Y = 10;
constexpr int32_t VIRTUAL_DISPLAY_W = 500;
constexpr int32_t VIRTUAL_DISPLAY_H = 500;
class WMClientNativeTest33 : public INativeTest {
public:
std::string GetDescription() const override
{
constexpr const char *desc = "virtual display create";
return desc;
}
std::string GetDomain() const override
{
constexpr const char *domain = "wmclient";
return domain;
}
int32_t GetID() const override
{
constexpr int32_t id = 33;
return id;
}
uint32_t GetLastTime() const override
{
constexpr uint32_t lastTime = 5000;
return lastTime;
}
void Run(int32_t argc, const char **argv) override
{
auto wm = WindowManager::GetInstance();
if (wm == nullptr) {
printf("WindowManager::GetInstance failed.\n");
return;
}
auto wmRet = wm->Init();
if (wmRet) {
printf("init failed with %s\n", WMErrorStr(wmRet).c_str());
ExitTest();
return;
}
wm->GetDisplays(displays);
for (display = displays.begin(); display != displays.end(); display++) {
if (display->type == DISPLAY_TYPE_VIRTUAL)
break;
}
if (display != displays.end()) {
printf("virtual display already extsis.\n");
} else {
auto virtualDisplayOption = VirtualDisplayOption::Get();
if (virtualDisplayOption == nullptr) {
printf("VirtualDisplayOption::Get failed.\n");
return;
}
virtualDisplayOption->SetX(VIRTUAL_DISPLAY_X);
virtualDisplayOption->SetY(VIRTUAL_DISPLAY_Y);
virtualDisplayOption->SetWidth(VIRTUAL_DISPLAY_W);
virtualDisplayOption->SetHeight(VIRTUAL_DISPLAY_H);
auto ret = wm->CreateVirtualDisplay(virtualDisplayOption);
if (ret != WM_OK) {
printf("create virtual display failed.\n");
return;
}
printf("create virtual display succeed.\n");
}
wm->GetDisplays(displays);
for (display = displays.begin(); display != displays.end(); display++) {
if (display->type == DISPLAY_TYPE_VIRTUAL)
break;
}
window = NativeTestFactory::CreateWindow(WINDOW_TYPE_NORMAL, nullptr, display->id);
if (window == nullptr) {
printf("NativeTestFactory::CreateWindow return nullptr\n");
return;
}
window->SwitchTop();
auto surface = window->GetSurface();
windowSync = NativeTestSync::CreateSync(NativeTestDraw::FlushDraw, surface);
}
private:
std::vector<struct WMDisplayInfo> displays;
std::vector<struct WMDisplayInfo>::iterator display;
sptr<Window> window = nullptr;
sptr<NativeTestSync> windowSync = nullptr;
} g_autoload;
}

View File

@ -0,0 +1,19 @@
/*
* 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 FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_33_H
#define FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_33_H
#endif // FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_33_H

View File

@ -0,0 +1,96 @@
/*
* 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 "wmclient_native_test_34.h"
#include <cstdio>
#include <securec.h>
#include <display_type.h>
#include <window_manager.h>
#include "inative_test.h"
#include "native_test_class.h"
#include "util.h"
using namespace OHOS;
namespace {
class WMClientNativeTest34 : public INativeTest {
public:
std::string GetDescription() const override
{
constexpr const char *desc = "virtual display destory";
return desc;
}
std::string GetDomain() const override
{
constexpr const char *domain = "wmclient";
return domain;
}
int32_t GetID() const override
{
constexpr int32_t id = 34;
return id;
}
uint32_t GetLastTime() const override
{
constexpr uint32_t lastTime = 1000;
return lastTime;
}
void Run(int32_t argc, const char **argv) override
{
auto wm = WindowManager::GetInstance();
if (wm == nullptr) {
printf("WindowManager::GetInstance failed.\n");
return;
}
auto wmRet = wm->Init();
if (wmRet) {
printf("init failed with %s\n", WMErrorStr(wmRet).c_str());
ExitTest();
return;
}
wm->GetDisplays(displays);
for (display = displays.begin(); display != displays.end(); display++) {
if (display->type == DISPLAY_TYPE_VIRTUAL)
break;
}
if (display == displays.end()) {
printf("virtual display non-existent.\n");
} else {
auto ret = wm->DestroyVirtualDisplay(display->id);
if (ret != WM_OK) {
printf("destroy virtual display failed.\n");
return;
}
printf("virtual display destroy succeed.\n");
}
}
private:
std::vector<struct WMDisplayInfo> displays;
std::vector<struct WMDisplayInfo>::iterator display;
sptr<Window> window;
sptr<NativeTestSync> windowSync;
} g_autoload;
}

View File

@ -0,0 +1,19 @@
/*
* 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 FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_34_H
#define FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_34_H
#endif // FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_34_H

View File

@ -0,0 +1,128 @@
/*
* 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 "wmclient_native_test_35.h"
#include <cstdio>
#include <iostream>
#include <sstream>
#include <display_type.h>
#include <option_parser.h>
#include <window_manager.h>
#include "inative_test.h"
#include "native_test_class.h"
#include "util.h"
using namespace OHOS;
namespace {
constexpr int32_t DISPLAY_MODE_SINGLE = 1;
constexpr int32_t DISPLAY_MODE_CLONE = 2;
constexpr int32_t DISPLAY_MODE_EXTEND = 3;
constexpr int32_t DISPLAY_MODE_EXPAND = 4;
class WMClientNativeTest35 : public INativeTest {
public:
std::string GetDescription() const
{
constexpr const char *desc = "set display mode";
return desc;
}
std::string GetDomain() const
{
constexpr const char *desc = "wmclient";
return desc;
}
int32_t GetID() const
{
constexpr int32_t id = 35;
return id;
}
uint32_t GetLastTime() const
{
constexpr uint32_t lastTime = 1000;
return lastTime;
}
void inputExplain()
{
printf("please input set display mode: wmtest wmclient 35 [parameter] \n");
printf("[parameter] : 1 , 2 , 3 , 4 \n");
printf("1 : set display mode to SINGLE \n");
printf("2 : set display mode to CLONE\n");
printf("3 : set display mode to EXTEND\n");
printf("4 : set display mode to EXPAND\n");
}
void Run(int32_t argc, const char **argv)
{
OptionParser parser;
int32_t displayMode = 0;
parser.AddArguments(displayMode);
if (parser.Parse(argc, argv)) {
std::cerr << parser.GetErrorString() << std::endl;
inputExplain();
ExitTest();
return;
}
auto wm = WindowManager::GetInstance();
auto wmRet = wm->Init();
if (wmRet) {
printf("init failed with %s\n", WMErrorStr(wmRet).c_str());
ExitTest();
return;
}
switch (displayMode) {
case DISPLAY_MODE_SINGLE:
wmRet = wm->SetDisplayMode(WM_DISPLAY_MODE_SINGLE);
printf("1 : set display mode to SINGLE \n");
break;
case DISPLAY_MODE_CLONE:
wmRet = wm->SetDisplayMode(WM_DISPLAY_MODE_CLONE);
printf("2 : set display mode to CLONE\n");
break;
case DISPLAY_MODE_EXTEND:
wmRet = wm->SetDisplayMode(WM_DISPLAY_MODE_EXTEND);
printf("3 : set display mode to EXTEND\n");
break;
case DISPLAY_MODE_EXPAND:
wmRet = wm->SetDisplayMode(WM_DISPLAY_MODE_EXPAND);
printf("4 : set display mode to EXPAND\n");
break;
default:
inputExplain();
return;
break;
}
if (wmRet != WM_OK) {
printf("set display mode failed with %s.\n", WMErrorStr(wmRet).c_str());
ExitTest();
return;
}
printf("set display mode succeed.\n");
}
private:
sptr<Window> window;
sptr<NativeTestSync> windowSync;
} g_autoload;
} // namespace

View File

@ -0,0 +1,19 @@
/*
* 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 FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_35_H
#define FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_35_H
#endif // FRAMEWORKS_WMTEST_TEST_WMCLIENT_WMCLIENT_NATIVE_TEST_35_H

View File

@ -2,11 +2,16 @@
"jobs" : [{ "jobs" : [{
"name" : "weston_start", "name" : "weston_start",
"cmds" : [ "cmds" : [
"start graphic_dumper_server",
"start bootanimation" "start bootanimation"
] ]
} }
], ],
"services" : [{ "services" : [{
"name" : "graphic_dumper_server",
"path" : ["/system/bin/graphic_dumper_server"],
"disabled" : 1
}, {
"name" : "vsync_server", "name" : "vsync_server",
"path" : ["/system/bin/vsync_server"], "path" : ["/system/bin/vsync_server"],
"disabled" : 1 "disabled" : 1

View File

@ -16,10 +16,16 @@ service vsync_server /system/bin/vsync_server
disabled disabled
seclabel u:r:wms_service:s0 seclabel u:r:wms_service:s0
service graphic_dumper_server /system/bin/graphic_dumper_server
class weston
disabled
seclabel u:r:wms_service:s0
service bootanimation /system/bin/bootanimation service bootanimation /system/bin/bootanimation
class weston class weston
disabled disabled
oneshot oneshot
on weston_start on weston_start
start graphic_dumper_server
start bootanimation start bootanimation

View File

@ -0,0 +1,55 @@
/*
* 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 FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_HELPER_H
#define FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_HELPER_H
#include "graphic_common.h"
#ifdef __cplusplus
#include <refbase.h>
namespace OHOS {
using OnConfigChangeFunc = std::function<void(const std::string &, const std::string &)>;
using OnDumpFunc = std::function<void()>;
class GraphicDumperHelper : public RefBase {
public:
static sptr<GraphicDumperHelper> GetInstance();
virtual GSError SendInfo(const std::string &tag, const char *fmt, ...) = 0;
virtual int32_t AddConfigChangeListener(const std::string &tag, OnConfigChangeFunc func) = 0;
virtual GSError RemoveConfigChangeListener(const int32_t listenerId) = 0;
virtual int32_t AddDumpListener(const std::string &tag, OnDumpFunc func) = 0;
virtual GSError RemoveDumpListener(const int32_t listenerId) = 0;
};
} // namespace OHOS
extern "C" {
#endif
typedef void(*OnDumpFuncPtr)(void);
typedef void(*OnConfigChangeFuncPtr)(const char *, const char *);
int SendInfo(const char* tag, const char *fmt, ...);
int AddConfigChangeListener(const char* tag, OnConfigChangeFuncPtr func);
int RemoveConfigChangeListener(int listenerId);
int AddDumpListener(const char* tag, OnDumpFuncPtr func);
int RemoveDumpListener(int listenerId);
#ifdef __cplusplus
}
#endif
#endif // FRAMEWORKS_DUMPRE_INCLUDE_GRAPHIC_DUMPER_HELPER_H

View File

@ -0,0 +1,46 @@
/*
* 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 INTERFACES_INNERKITS_WMCLIENT_VIRTUAL_DISPLAY_OPTION_H
#define INTERFACES_INNERKITS_WMCLIENT_VIRTUAL_DISPLAY_OPTION_H
#include <refbase.h>
#include <surface.h>
#include "window_manager_type.h"
namespace OHOS {
class VirtualDisplayOption : public RefBase {
public:
static sptr<VirtualDisplayOption> Get();
virtual WMError SetX(int32_t x) = 0;
virtual WMError SetY(int32_t y) = 0;
virtual WMError SetWidth(uint32_t width) = 0;
virtual WMError SetHeight(uint32_t height) = 0;
virtual int32_t GetX() const = 0;
virtual int32_t GetY() const = 0;
virtual uint32_t GetWidth() const = 0;
virtual uint32_t GetHeight() const = 0;
virtual bool IsSettingX() const = 0;
virtual bool IsSettingY() const = 0;
virtual bool IsSettingWidth() const = 0;
virtual bool IsSettingHeight() const = 0;
};
} // namespace OHOS
#endif // INTERFACES_INNERKITS_WMCLIENT_VIRTUAL_DISPLAY_OPTION_H

View File

@ -27,6 +27,7 @@
#include "window.h" #include "window.h"
#include "window_manager_type.h" #include "window_manager_type.h"
#include "window_option.h" #include "window_option.h"
#include "virtual_display_option.h"
namespace OHOS { namespace OHOS {
class WindowManager : public RefBase { class WindowManager : public RefBase {
@ -45,6 +46,10 @@ public:
virtual WMError ListenNextScreenShot(int32_t id, IScreenShotCallback *cb) = 0; virtual WMError ListenNextScreenShot(int32_t id, IScreenShotCallback *cb) = 0;
virtual WMError ListenNextWindowShot(const sptr<Window> &window, IWindowShotCallback *cb) = 0; virtual WMError ListenNextWindowShot(const sptr<Window> &window, IWindowShotCallback *cb) = 0;
virtual WMError CreateVirtualDisplay(const sptr<VirtualDisplayOption> &option) = 0;
virtual WMError DestroyVirtualDisplay(uint32_t did) = 0;
virtual WMError SetDisplayMode(WMSDisplayMode mode) = 0;
}; };
} // namespace OHOS } // namespace OHOS

View File

@ -54,6 +54,19 @@ enum WindowMode {
WINDOW_MODE_MAX, WINDOW_MODE_MAX,
}; };
// bitmask
enum WMSDisplayMode {
WM_DISPLAY_MODE_SINGLE = 1,
WM_DISPLAY_MODE_CLONE = 2,
WM_DISPLAY_MODE_EXTEND = 4,
WM_DISPLAY_MODE_EXPAND = 8,
};
enum DisplayType {
DISPLAY_TYPE_PHYSICAL = 0,
DISPLAY_TYPE_VIRTUAL,
DISPLAY_TYPE_MAX,
};
struct WMDisplayInfo { struct WMDisplayInfo {
int32_t id; int32_t id;
uint32_t width; uint32_t width;
@ -61,6 +74,7 @@ struct WMDisplayInfo {
uint32_t phyWidth; uint32_t phyWidth;
uint32_t phyHeight; uint32_t phyHeight;
uint32_t vsync; uint32_t vsync;
enum DisplayType type;
}; };
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -60,6 +60,9 @@ public:
virtual sptr<PromiseWMError> ScaleTo(int32_t wid, uint32_t width, uint32_t height) = 0; virtual sptr<PromiseWMError> ScaleTo(int32_t wid, uint32_t width, uint32_t height) = 0;
virtual sptr<PromiseWMError> SetWindowType(int32_t wid, WindowType type) = 0; virtual sptr<PromiseWMError> SetWindowType(int32_t wid, WindowType type) = 0;
virtual sptr<PromiseWMError> SetWindowMode(int32_t wid, WindowMode mode) = 0; virtual sptr<PromiseWMError> SetWindowMode(int32_t wid, WindowMode mode) = 0;
virtual sptr<PromiseWMError> CreateVirtualDisplay(int32_t x, int32_t y, int32_t width, int32_t height) = 0;
virtual sptr<PromiseWMError> DestroyVirtualDisplay(uint32_t did) = 0;
}; };
} // namespace OHOS } // namespace OHOS

View File

@ -23,14 +23,6 @@
#include <window_manager_type.h> #include <window_manager_type.h>
namespace OHOS { namespace OHOS {
// bitmask
enum WMSDisplayMode {
WM_DISPLAY_MODE_SINGLE = 1,
WM_DISPLAY_MODE_CLONE = 2,
WM_DISPLAY_MODE_EXTEND = 4,
WM_DISPLAY_MODE_EXPAND = 8,
};
enum WMSDisplayDirection { enum WMSDisplayDirection {
WMS_DISPLAY_DIRECTION_DOWN = 0, WMS_DISPLAY_DIRECTION_DOWN = 0,
WMS_DISPLAY_DIRECTION_LEFT = 1, WMS_DISPLAY_DIRECTION_LEFT = 1,

View File

@ -6,6 +6,10 @@
"//foundation/graphic/standard/interfaces/kits/js/declaration:window", "//foundation/graphic/standard/interfaces/kits/js/declaration:window",
"//foundation/graphic/standard/interfaces/kits/napi:napi_packages", "//foundation/graphic/standard/interfaces/kits/napi:napi_packages",
"//foundation/graphic/standard/frameworks/dumper:gdumper.ini",
"//foundation/graphic/standard/frameworks/dumper:graphic_dumper_server",
"//foundation/graphic/standard/frameworks/dumper:gdumper",
"//third_party/wayland-ivi-extension:ivi-controller", "//third_party/wayland-ivi-extension:ivi-controller",
"//third_party/wayland-ivi-extension:ivi-input-controller", "//third_party/wayland-ivi-extension:ivi-input-controller",
"//third_party/wayland-ivi-extension:libscreen-info-module", "//third_party/wayland-ivi-extension:libscreen-info-module",

View File

@ -26,3 +26,7 @@ group("semaphore") {
group("test_header") { group("test_header") {
public_deps = [ "test_header:test_header" ] public_deps = [ "test_header:test_header" ]
} }
group("option_parser") {
public_deps = [ "option_parser:option_parser" ]
}

View File

@ -0,0 +1,41 @@
# 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.
import("//build/ohos.gni")
## Build option_parser.so {{{
config("option_parser_config") {
visibility = [ ":*" ]
cflags = [
"-Wall",
"-Werror",
"-g3",
]
}
config("option_parser_public_config") {
include_dirs = [ "export" ]
}
ohos_shared_library("option_parser") {
sources = [ "src/option_parser.cpp" ]
configs = [ ":option_parser_config" ]
public_configs = [ ":option_parser_public_config" ]
subsystem_name = "graphic"
part_name = "graphic_standard"
}
## Build option_parser.so }}}

View File

@ -0,0 +1,153 @@
/*
* 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 UTILS_OPTION_PARSER_EXPORT_OPTION_PARSER_H
#define UTILS_OPTION_PARSER_EXPORT_OPTION_PARSER_H
#include <cassert>
#include <list>
#include <string>
#include <vector>
class OptionParser {
public:
int32_t Parse(int32_t argc, const char **argv);
std::string GetErrorString();
template<typename T>
int32_t AddOption(const std::string &shortOpt, const std::string &longOpt, T &result)
{
assert(!"not support");
return 0;
}
template<>
int32_t AddOption<int32_t>(const std::string &shortOpt, const std::string &longOpt, int32_t &result)
{
return AddOption(shortOpt, longOpt, &result, Option::ValueType::i32);
}
template<>
int32_t AddOption<int64_t>(const std::string &shortOpt, const std::string &longOpt, int64_t &result)
{
return AddOption(shortOpt, longOpt, &result, Option::ValueType::i64);
}
template<>
int32_t AddOption<double>(const std::string &shortOpt, const std::string &longOpt, double &result)
{
return AddOption(shortOpt, longOpt, &result, Option::ValueType::f64);
}
template<>
int32_t AddOption<std::string>(const std::string &shortOpt, const std::string &longOpt, std::string &result)
{
return AddOption(shortOpt, longOpt, &result, Option::ValueType::str);
}
template<>
int32_t AddOption<bool>(const std::string &shortOpt, const std::string &longOpt, bool &result)
{
return AddOption(shortOpt, longOpt, &result, Option::ValueType::bol);
}
template<typename T>
int32_t AddArguments(T &result)
{
assert(!"not support");
return 0;
}
template<>
int32_t AddArguments<int32_t>(int32_t &result)
{
return AddArguments(&result, Argument::ValueType::i32);
}
template<>
int32_t AddArguments<int64_t>(int64_t &result)
{
return AddArguments(&result, Argument::ValueType::i64);
}
template<>
int32_t AddArguments<double>(double &result)
{
return AddArguments(&result, Argument::ValueType::f64);
}
template<>
int32_t AddArguments<std::string>(std::string &result)
{
return AddArguments(&result, Argument::ValueType::str);
}
int32_t GetSkippedArgc();
const char **GetSkippedArgv();
private:
int32_t ParseArgument(const char *arg, const char *arg2);
int32_t ParseArgc(const char *arg, const char *arg2);
int32_t ParseShortOption(const char *arg1, const char *arg2);
int32_t ParseLongEqualOption(const char *arg, const char *arg2);
int32_t ParseLongOption(const char *arg1, const char *arg2);
int32_t AddSkipped(const char *arg, const char *arg2);
struct Option {
const std::string so;
const std::string lo;
union Value {
int32_t i32;
int64_t i64;
double f64;
std::string str;
bool bl;
} *result;
enum class ValueType {
i32,
i64,
f64,
str,
bol,
} type;
};
int32_t AddOption(const std::string &shortOpt,
const std::string &longOpt, void *result, Option::ValueType type);
struct Argument {
union Value {
int32_t i32;
int64_t i64;
double f64;
std::string str;
} *result;
enum class ValueType {
i32,
i64,
f64,
str,
} type;
};
int32_t AddArguments(void *result, Argument::ValueType type);
std::list<struct Argument> arguments;
std::vector<struct Option> options;
std::vector<const char *> skipped;
std::string error = "";
};
#endif // UTILS_OPTION_PARSER_EXPORT_OPTION_PARSER_H

View File

@ -0,0 +1,274 @@
/*
* 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 <option_parser.h>
#include <sstream>
enum {
PARSER_NEXT = 0,
PARSER_ERROR = 1,
PARSER_PARSED = 2,
PARSER_PARSED_MORE = 3,
};
int32_t OptionParser::ParseArgument(const char *arg, const char *arg2)
{
if (arguments.empty()) {
return PARSER_NEXT;
}
std::stringstream ss(arg);
switch (arguments.front().type) {
case Argument::ValueType::i32:
ss >> arguments.front().result->i32;
break;
case Argument::ValueType::i64:
ss >> arguments.front().result->i64;
break;
case Argument::ValueType::f64:
ss >> arguments.front().result->f64;
break;
case Argument::ValueType::str:
ss >> arguments.front().result->str;
break;
}
if (!ss.eof() || !ss) {
error = "parse ";
error = error + arg + " error";
return PARSER_ERROR;
}
arguments.pop_front();
return PARSER_PARSED;
}
int32_t OptionParser::ParseArgc(const char *arg, const char *arg2)
{
if (arg[0] == 0) {
return PARSER_ERROR;
}
if (arg[0] != '-') {
skipped.push_back(arg);
return PARSER_PARSED;
}
if (arg[1] == 0) {
return PARSER_ERROR;
}
return PARSER_NEXT;
}
int32_t OptionParser::ParseShortOption(const char *arg1, const char *arg2)
{
if (arg1[1] == '-') {
// long option
return PARSER_NEXT;
}
for (const auto &option : options) {
if (option.so == &arg1[1]) {
if (option.type == Option::ValueType::bol) {
option.result->bl = !option.result->bl;
return PARSER_PARSED;
} else if (arg2 == nullptr) {
error = option.so + " need argument";
return PARSER_ERROR;
}
std::stringstream ss(arg2);
switch (option.type) {
case Option::ValueType::i32:
ss >> option.result->i32;
break;
case Option::ValueType::i64:
ss >> option.result->i64;
break;
case Option::ValueType::f64:
ss >> option.result->f64;
break;
case Option::ValueType::str:
ss >> option.result->str;
break;
default:
assert(!"no way");
break;
}
if (!ss.eof() || !ss) {
error = "parse ";
error = error + arg1 + " error, " + arg2;
return PARSER_ERROR;
}
return PARSER_PARSED_MORE;
}
}
return PARSER_NEXT;
}
int32_t OptionParser::ParseLongEqualOption(const char *arg, const char *arg2)
{
if (arg[1] != '-') {
return PARSER_NEXT;
}
int32_t ret = 0;
bool parsed = false;
for (const char *c = arg; *c; c++) {
if (*c == '=') {
std::string arg1(arg, c - arg);
std::string arg2(c + 1);
ret = ParseLongOption(arg1.c_str(), arg2.c_str());
parsed = true;
break;
}
}
if (ret == PARSER_ERROR || ret == PARSER_NEXT) {
return ret;
}
if (parsed) {
return PARSER_PARSED;
}
return PARSER_NEXT;
}
int32_t OptionParser::ParseLongOption(const char *arg1, const char *arg2)
{
if (arg1[1] != '-') {
return PARSER_NEXT;
}
for (const auto &option : options) {
if (option.lo == &arg1[0x2]) {
if (option.type == Option::ValueType::bol) {
option.result->bl = !option.result->bl;
return PARSER_PARSED;
} else if (arg2 == nullptr) {
error = option.lo + " need argument";
return PARSER_ERROR;
}
std::stringstream ss(arg2);
switch (option.type) {
case Option::ValueType::i32:
ss >> option.result->i32;
break;
case Option::ValueType::i64:
ss >> option.result->i64;
break;
case Option::ValueType::f64:
ss >> option.result->f64;
break;
case Option::ValueType::str:
ss >> option.result->str;
break;
default:
assert(!"no way");
break;
}
if (!ss.eof() || !ss) {
error = "parse ";
error = error + arg1 + " error, " + arg2;
return PARSER_ERROR;
}
return PARSER_PARSED_MORE;
}
}
return PARSER_NEXT;
}
int32_t OptionParser::AddSkipped(const char *arg, const char *arg2)
{
skipped.push_back(arg);
return PARSER_PARSED;
}
int32_t OptionParser::Parse(int32_t argc, const char **argv)
{
int32_t (OptionParser:: *parsers[])(const char *, const char *) = {
&OptionParser::ParseArgument,
&OptionParser::ParseArgc,
&OptionParser::ParseShortOption,
&OptionParser::ParseLongEqualOption,
&OptionParser::ParseLongOption,
&OptionParser::AddSkipped,
};
for (int32_t i = 0; i < argc; i++) {
for (auto &parser : parsers) {
auto ret = (this->*parser)(argv[i], argv[i + 1]);
if (ret == PARSER_ERROR) {
return ret;
} else if (ret == PARSER_PARSED_MORE) {
i++;
break;
} else if (ret == PARSER_PARSED) {
break;
}
}
}
if (!arguments.empty()) {
error = "need more arguments";
return 1;
} else {
skipped.push_back(nullptr);
}
return 0;
}
int32_t OptionParser::AddOption(const std::string &shortOpt,
const std::string &longOpt, void *result, Option::ValueType type)
{
struct Option option = {
.so = shortOpt,
.lo = longOpt,
.result = reinterpret_cast<union Option::Value *>(result),
.type = type,
};
options.emplace_back(std::move(option));
return 0;
}
int32_t OptionParser::AddArguments(void *result, Argument::ValueType type)
{
struct Argument argument = {
.result = reinterpret_cast<union Argument::Value *>(result),
.type = type,
};
arguments.emplace_back(std::move(argument));
return 0;
}
std::string OptionParser::GetErrorString()
{
return error;
}
int32_t OptionParser::GetSkippedArgc()
{
return skipped.size() - 1;
}
const char **OptionParser::GetSkippedArgv()
{
return skipped.data();
}