--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics 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 <aul.h>
+#include <aul_cmd.h>
+#include <aul_comp_info.h>
+#include <aul_sock.h>
+#include <gtest/gtest.h>
+#include <stdlib.h>
+
+#include <bundle_cpp.h>
+
+#include <iostream>
+#include <memory>
+
+#include "mock/mock_hook.h"
+#include "mock/socket_mock.h"
+#include "mock/test_fixture.h"
+#include "mock/vconf_mock.h"
+#include "src/launch.h"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::Invoke;
+using ::testing::SaveArg;
+
+namespace {
+
+constexpr const char kAppId[] = "org.tizen.component-based-app";
+constexpr const char kComponentId[] = "org.tizen.frame-component";
+constexpr const char kComponentType[] = "frame";
+constexpr const char kLaunchMode[] = "caller";
+constexpr const char kMainComponent[] = "true";
+constexpr const char kIconDisplay[] = "true";
+constexpr const char kTaskManage[] = "true";
+constexpr const char kLocale[] = "en-us";
+constexpr const char kIcon[] = "/home/owner/apps_rw/org.tizen.component-based-app/shared/res/frame-component.png";
+constexpr const char kLabel[] = "Frame-Component";
+
+class Mocks : virtual public ::testing::NiceMock<SocketMock>,
+ virtual public ::testing::NiceMock<VconfMock> {};
+
+} // namespace
+
+class CompInfoTest : public TestFixture {
+ public:
+ CompInfoTest() : TestFixture(std::make_unique<::Mocks>()) {}
+
+ virtual void SetUp() {
+ int times = 2;
+ if (aul_is_initialized())
+ times--;
+
+ EXPECT_CALL(GetMock<SocketMock>(), send(_, _, _, _))
+ .Times(times)
+ .WillOnce(Invoke([&](int fd, const void* buf, size_t n, int flags)
+ -> ssize_t {
+ return n;
+ }));
+
+ if (!aul_is_initialized())
+ aul_launch_init(nullptr, nullptr);
+
+ auto pkt = MakePacket(std::move(MakeCompInfoBundle()));
+ EXPECT_NE(pkt, nullptr);
+
+ EXPECT_CALL(GetMock<SocketMock>(), recv(_, _, _, _))
+ .Times(2)
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ pkt->cmd = APP_GET_INFO_OK;
+ memcpy(buf, pkt.get(), n);
+ return n;
+ }))
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ memcpy(buf, pkt->data, n);
+ return n;
+ }));
+
+ int ret = aul_comp_info_create(kComponentId, &handle_);
+ EXPECT_EQ(ret, AUL_R_OK);
+ }
+
+ virtual void TearDown() {
+ if (handle_ != nullptr) {
+ aul_comp_info_destroy(handle_);
+ handle_ = nullptr;
+ }
+
+ if (aul_is_initialized())
+ aul_launch_fini();
+ }
+
+ tizen_base::Bundle MakeLocalizedInfoBundle() {
+ return {
+ { AUL_K_LOCALE, kLocale },
+ { AUL_K_ICON, kIcon },
+ { AUL_K_LABEL, kLabel }
+ };
+ }
+
+ tizen_base::Bundle MakeCompInfoBundle() {
+ tizen_base::Bundle b {
+ { AUL_K_APPID, kAppId },
+ { AUL_K_COMPONENT_ID, kComponentId },
+ { AUL_K_COMPONENT_TYPE, kComponentType },
+ { AUL_K_LAUNCH_MODE, kLaunchMode },
+ { AUL_K_MAIN_COMP, kMainComponent },
+ { AUL_K_ICON_DISPLAY, kIconDisplay },
+ { AUL_K_TASK_MANAGE, kTaskManage }
+ };
+
+ auto raw = MakeLocalizedInfoBundle().ToRaw();
+ std::vector<std::string> localized_info_size {
+ std::to_string(raw.second)
+ };
+ std::vector<std::string> localized_info {
+ reinterpret_cast<char*>(raw.first.get())
+ };
+
+ b.Add(AUL_K_LOCALIZED_INFO, localized_info);
+ b.Add(AUL_K_LOCALIZED_INFO_SIZE, localized_info_size);
+ return b;
+ }
+
+ std::shared_ptr<app_pkt_t> MakePacket(tizen_base::Bundle b) {
+ auto raw = b.ToRaw();
+ app_pkt_t* pkt =
+ static_cast<app_pkt_t*>(calloc(1, sizeof(app_pkt_t) + raw.second));
+ if (pkt == nullptr)
+ return nullptr;
+
+ pkt->opt = AUL_SOCK_BUNDLE;
+ pkt->cmd = APP_GET_INFO_OK;
+ pkt->len = raw.second;
+ memcpy(pkt->data, raw.first.get(), raw.second);
+
+ return std::shared_ptr<app_pkt_t>(pkt, free);
+ }
+
+ bool touched_ = false;
+ aul_comp_info_h handle_ = nullptr;
+};
+
+TEST_F(CompInfoTest, aul_comp_info_create_P) {
+ int cmd = -1;
+ int opt = -1;
+ bundle* kb = nullptr;
+ auto pkt = MakePacket(std::move(MakeCompInfoBundle()));
+ EXPECT_NE(pkt, nullptr);
+
+ EXPECT_CALL(GetMock<SocketMock>(), send(_, _, _, _))
+ .Times(1)
+ .WillOnce(Invoke([&](int fd, const void* buf, size_t n, int flags)
+ -> ssize_t {
+ const app_pkt_t* pkt = reinterpret_cast<const app_pkt_t*>(buf);
+ cmd = pkt->cmd;
+ opt = pkt->opt;
+ kb = bundle_decode(pkt->data, pkt->len);
+ return n;
+ }));
+ EXPECT_CALL(GetMock<SocketMock>(), recv(_, _, _, _))
+ .Times(2)
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ memcpy(buf, pkt.get(), n);
+ return n;
+ }))
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ memcpy(buf, pkt->data, n);
+ return n;
+ }));
+
+ aul_comp_info_h handle = nullptr;
+ int ret = aul_comp_info_create(kComponentId, &handle);
+ EXPECT_NE(kb, nullptr);
+ tizen_base::Bundle b(kb, false, true);
+
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_NE(handle, nullptr);
+ auto handle_auto = std::unique_ptr<std::remove_pointer<aul_comp_info_h>::type,
+ decltype(aul_comp_info_destroy)*>(handle, aul_comp_info_destroy);
+
+ EXPECT_EQ(cmd, COMP_INFO_GET);
+ EXPECT_EQ(opt, (AUL_SOCK_BUNDLE | AUL_SOCK_ASYNC));
+ EXPECT_EQ(b.GetString(AUL_K_COMPONENT_ID), kComponentId);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_create_N) {
+ int ret = aul_comp_info_create(kComponentId, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ aul_comp_info_h handle = nullptr;
+ ret = aul_comp_info_create(nullptr, &handle);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_destroy_P) {
+ int ret = aul_comp_info_destroy(handle_);
+ EXPECT_EQ(ret, AUL_R_OK);
+ handle_ = nullptr;
+}
+
+TEST_F(CompInfoTest, aul_comp_info_destroy_N) {
+ int ret = aul_comp_info_destroy(nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_clone_P) {
+ aul_comp_info_h cloned_info = nullptr;
+ int ret = aul_comp_info_clone(handle_, &cloned_info);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_NE(cloned_info, nullptr);
+ auto cloned_info_auto =
+ std::unique_ptr<std::remove_pointer<aul_comp_info_h>::type,
+ decltype(aul_comp_info_destroy)*>(cloned_info, aul_comp_info_destroy);
+
+ const char* comp_id = nullptr;
+ ret = aul_comp_info_get_comp_id(cloned_info, &comp_id);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(std::string(comp_id), kComponentId);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_clone_N) {
+ int ret = aul_comp_info_clone(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ aul_comp_info_h cloned_info = nullptr;
+ ret = aul_comp_info_clone(nullptr, &cloned_info);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_app_id_P) {
+ const char* app_id = nullptr;
+ int ret = aul_comp_info_get_app_id(handle_, &app_id);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(std::string(app_id), kAppId);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_app_id_N) {
+ int ret = aul_comp_info_get_app_id(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ const char* app_id = nullptr;
+ ret = aul_comp_info_get_app_id(nullptr, &app_id);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_comp_id_P) {
+ const char* comp_id = nullptr;
+ int ret = aul_comp_info_get_comp_id(handle_, &comp_id);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(std::string(comp_id), kComponentId);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_comp_id_N) {
+ int ret = aul_comp_info_get_comp_id(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ const char* comp_id = nullptr;
+ ret = aul_comp_info_get_comp_id(nullptr, &comp_id);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_type_P) {
+ const char* type = nullptr;
+ int ret = aul_comp_info_get_type(handle_, &type);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(std::string(type), kComponentType);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_type_N) {
+ int ret = aul_comp_info_get_type(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ const char* type = nullptr;
+ ret = aul_comp_info_get_type(nullptr, &type);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_launch_mode_P) {
+ const char* launch_mode = nullptr;
+ int ret = aul_comp_info_get_launch_mode(handle_, &launch_mode);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(std::string(launch_mode), kLaunchMode);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_launch_mode_N) {
+ int ret = aul_comp_info_get_launch_mode(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ const char* launch_mode = nullptr;
+ ret = aul_comp_info_get_launch_mode(nullptr, &launch_mode);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_is_main_comp_P) {
+ bool main_comp = false;
+ int ret = aul_comp_info_is_main_comp(handle_, &main_comp);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(main_comp, true);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_is_main_comp_N) {
+ int ret = aul_comp_info_is_main_comp(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ bool main_comp = false;
+ ret = aul_comp_info_is_main_comp(nullptr, &main_comp);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_is_icon_display_P) {
+ bool icon_display = false;
+ int ret = aul_comp_info_is_icon_display(handle_, &icon_display);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(icon_display, true);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_is_icon_display_N) {
+ int ret = aul_comp_info_is_icon_display(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ bool icon_display = false;
+ ret = aul_comp_info_is_icon_display(nullptr, &icon_display);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_is_taskmanage_P) {
+ bool taskmanage = false;
+ int ret = aul_comp_info_is_taskmanage(handle_, &taskmanage);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(taskmanage, true);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_is_taskmanage_N) {
+ int ret = aul_comp_info_is_taskmanage(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ bool taskmanage = false;
+ ret = aul_comp_info_is_taskmanage(nullptr, &taskmanage);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_icon_P) {
+ std::string key;
+
+ EXPECT_CALL(GetMock<VconfMock>(), vconf_get_str(_))
+ .Times(1)
+ .WillOnce(Invoke([&](const char* in_key) -> char* {
+ key = std::string(in_key);
+ return strdup("en_US.UTF-8");
+ }));
+
+ const char* icon = nullptr;
+ int ret = aul_comp_info_get_icon(handle_, &icon);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(std::string(icon), kIcon);
+ EXPECT_EQ(key, VCONFKEY_LANGSET);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_icon_N) {
+ int ret = aul_comp_info_get_icon(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ const char* icon = nullptr;
+ ret = aul_comp_info_get_icon(nullptr, &icon);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_label_P) {
+ std::string key;
+
+ EXPECT_CALL(GetMock<VconfMock>(), vconf_get_str(_))
+ .Times(1)
+ .WillOnce(Invoke([&](const char* in_key) -> char* {
+ key = std::string(in_key);
+ return strdup("en_US.UTF-8");
+ }));
+
+ const char* label = nullptr;
+ int ret = aul_comp_info_get_label(handle_, &label);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(std::string(label), kLabel);
+ EXPECT_EQ(key, VCONFKEY_LANGSET);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_label_N) {
+ int ret = aul_comp_info_get_label(handle_, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ const char* label = nullptr;
+ ret = aul_comp_info_get_label(nullptr, &label);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_localed_label_P) {
+ const char* label = nullptr;
+ int ret = aul_comp_info_get_localed_label(handle_, kLocale, &label);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(std::string(label), kLabel);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_get_localed_label_N) {
+ int ret = aul_comp_info_get_localed_label(handle_, kLocale, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ const char* label = nullptr;
+ ret = aul_comp_info_get_localed_label(handle_, nullptr, &label);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ ret = aul_comp_info_get_localed_label(nullptr, kLocale, &label);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_foreach_comp_info_from_app_P) {
+ int cmd = -1;
+ int opt = -1;
+ auto pkt = MakePacket(std::move(MakeCompInfoBundle()));
+ EXPECT_NE(pkt, nullptr);
+
+ EXPECT_CALL(GetMock<SocketMock>(), send(_, _, _, _))
+ .Times(1)
+ .WillOnce(Invoke([&](int fd, const void* buf, size_t n, int flags)
+ -> ssize_t {
+ const app_pkt_t* pkt = reinterpret_cast<const app_pkt_t*>(buf);
+ cmd = pkt->cmd;
+ opt = pkt->opt;
+ return n;
+ }));
+ EXPECT_CALL(GetMock<SocketMock>(), recv(_, _, _, _))
+ .Times(3)
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ int count = 1;
+ memcpy(buf, &count, sizeof(int));
+ return n;
+ }))
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ memcpy(buf, pkt.get(), n);
+ return n;
+ }))
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ memcpy(buf, pkt->data, n);
+ return n;
+ }));
+
+ touched_ = false;
+ int ret = aul_comp_info_foreach_comp_info_from_app(kAppId,
+ [](aul_comp_info_h handle, void* user_data) {
+ const char* comp_id = nullptr;
+ aul_comp_info_get_comp_id(handle, &comp_id);
+ if (comp_id && !strcmp(comp_id, kComponentId)) {
+ auto* test = static_cast<CompInfoTest*>(user_data);
+ test->touched_ = true;
+ return false;
+ }
+
+ return true;
+ }, this);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(cmd, COMP_INFO_FOREACH);
+ EXPECT_EQ(opt, (AUL_SOCK_BUNDLE | AUL_SOCK_ASYNC));
+ EXPECT_EQ(touched_, true);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_foreach_comp_info_from_app_N) {
+ int ret = aul_comp_info_foreach_comp_info_from_app(kAppId, nullptr, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+
+ ret = aul_comp_info_foreach_comp_info_from_app(nullptr,
+ [](aul_comp_info_h handle, void* user_data) {
+ return true;
+ }, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_foreach_comp_info_P) {
+ int cmd = -1;
+ int opt = -1;
+ auto pkt = MakePacket(std::move(MakeCompInfoBundle()));
+ EXPECT_NE(pkt, nullptr);
+
+ EXPECT_CALL(GetMock<SocketMock>(), send(_, _, _, _))
+ .Times(1)
+ .WillOnce(Invoke([&](int fd, const void* buf, size_t n, int flags)
+ -> ssize_t {
+ const app_pkt_t* pkt = reinterpret_cast<const app_pkt_t*>(buf);
+ cmd = pkt->cmd;
+ opt = pkt->opt;
+ return n;
+ }));
+ EXPECT_CALL(GetMock<SocketMock>(), recv(_, _, _, _))
+ .Times(3)
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ int count = 1;
+ memcpy(buf, &count, sizeof(int));
+ return n;
+ }))
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ memcpy(buf, pkt.get(), n);
+ return n;
+ }))
+ .WillOnce(Invoke([&](int fd, void* buf, size_t n, int flags) -> ssize_t {
+ memcpy(buf, pkt->data, n);
+ return n;
+ }));
+
+ touched_ = false;
+ int ret = aul_comp_info_foreach_comp_info(
+ [](aul_comp_info_h handle, void* user_data) {
+ const char* app_id = nullptr;
+ aul_comp_info_get_app_id(handle, &app_id);
+ const char* comp_id = nullptr;
+ aul_comp_info_get_comp_id(handle, &comp_id);
+ if (comp_id && !strcmp(comp_id, kComponentId) &&
+ app_id && !strcmp(app_id, kAppId)) {
+ auto* test = static_cast<CompInfoTest*>(user_data);
+ test->touched_ = true;
+ return false;
+ }
+
+ return true;
+ }, this);
+ EXPECT_EQ(ret, AUL_R_OK);
+ EXPECT_EQ(cmd, COMP_INFO_FOREACH);
+ EXPECT_EQ(opt, (AUL_SOCK_BUNDLE | AUL_SOCK_ASYNC));
+ EXPECT_EQ(touched_, true);
+}
+
+TEST_F(CompInfoTest, aul_comp_info_foreach_comp_info_N) {
+ int ret = aul_comp_info_foreach_comp_info(nullptr, nullptr);
+ EXPECT_EQ(ret, AUL_R_EINVAL);
+}