#include "api/theme.h"
+#include <pkgmgr-info.h>
+
#include <memory>
#include <string>
return THEME_MANAGER_ERROR_NONE;
}
+extern "C" EXPORT_API int theme_get_path(theme_h handle,
+ const char* key, char** val) {
+ if (handle == nullptr || key == nullptr || val == nullptr) {
+ LOG(ERROR) << "Invalid parameter";
+ return THEME_MANAGER_ERROR_INVALID_PARAMETER;
+ }
+
+ auto p = *static_cast<std::shared_ptr<ThemeInfo>*>(handle);
+ auto value = p->GetPath(std::string(key));
+ if (value.empty()) {
+ LOG(ERROR) << "Failed to get path with given key";
+ return THEME_MANAGER_ERROR_IO_ERROR;
+ }
+ char* value_raw = strdup(value.c_str());
+ if (value_raw == nullptr) {
+ LOG(ERROR) << "Out of memory";
+ return THEME_MANAGER_ERROR_OUT_OF_MEMORY;
+ }
+
+ *val = value_raw;
+ return THEME_MANAGER_ERROR_NONE;
+}
+
extern "C" EXPORT_API int theme_get_string_array(theme_h handle,
const char* key, char*** val, int* cnt) {
if (handle == nullptr || key == nullptr ||
return THEME_MANAGER_ERROR_NONE;
}
+extern "C" EXPORT_API int theme_get_path_array(theme_h handle,
+ const char* key, char*** val, int* cnt) {
+ if (handle == nullptr || key == nullptr ||
+ val == nullptr || cnt == nullptr) {
+ LOG(ERROR) << "Invalid parameter";
+ return THEME_MANAGER_ERROR_INVALID_PARAMETER;
+ }
+
+ auto p = *static_cast<std::shared_ptr<ThemeInfo>*>(handle);
+ auto values = p->GetPathArray(std::string(key));
+
+ if (values.size() == 0) {
+ *cnt = 0;
+ return THEME_MANAGER_ERROR_NONE;
+ }
+
+ char** values_raw = static_cast<char**>(
+ calloc(values.size(), sizeof(*values_raw)));
+ if (values_raw == nullptr) {
+ LOG(ERROR) << "Out of memory";
+ return THEME_MANAGER_ERROR_OUT_OF_MEMORY;
+ }
+
+ int idx = 0;
+ for (auto& value : values) {
+ char *val_char = strdup(value.c_str());
+ if (val_char == nullptr) {
+ LOG(ERROR) << "Out of memory";
+ for (int i = 0; i < idx; i++)
+ free(values_raw[i]);
+ free(values_raw);
+ return THEME_MANAGER_ERROR_OUT_OF_MEMORY;
+ }
+ values_raw[idx] = val_char;
+ idx++;
+ }
+ *val = values_raw;
+ *cnt = idx;
+
+ return THEME_MANAGER_ERROR_NONE;
+}
+
extern "C" EXPORT_API int theme_get_int(theme_h handle, const char* key,
int* val) {
if (handle == nullptr || key == nullptr || val == nullptr) {
int theme_get_string(theme_h handle, const char *key, char **val);
/**
+ * @brief Gets the path corresponding to given key.
+ * @since_tizen 6.0
+ * @remarks You must release @a val using free().
+ * @param[in] handle The theme information
+ * @param[in] key String key to find information
+ * @param[out] val Value corresponding to given key
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #THEME_MANAGER_ERROR_NONE Successful
+ * @retval #THEME_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #THEME_MANAGER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #THEME_MANAGER_ERROR_IO_ERROR I/O error
+ */
+int theme_get_path(theme_h handle, const char *key, char **val);
+
+/**
* @brief Gets the bundle of strings corresponding with given key.
* @since_tizen 6.0
* @remarks You must release @a val using free().
char ***val, int *cnt);
/**
+ * @brief Gets the bundle of paths corresponding to given key.
+ * @since_tizen 6.0
+ * @remarks You must release @a val using free().
+ * @param[in] handle The theme information
+ * @param[in] key String key to find information
+ * @param[out] val Values corresponding to given key
+ * @param[out] cnt Number of returned strings
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #THEME_MANAGER_ERROR_NONE Successful
+ * @retval #THEME_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #THEME_MANAGER_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int theme_get_path_array(theme_h handle, const char *key,
+ char ***val, int *cnt);
+
+/**
* @brief Gets the integer corresponding with given key.
* @since_tizen 6.0
* @param[in] handle The theme information
BUNDLE_DEPS
DLOG_DEPS
GLIB_DEPS
+ PKGMGR_INFO_DEPS
)
INSTALL(TARGETS ${TARGET_TIZEN_THEME} DESTINATION ${LIB_INSTALL_DIR})
#include "theme/loader/theme_info.h"
+#include <pkgmgr-info.h>
+
#include <algorithm>
#include <string>
#include <vector>
#include "theme/utils/logging.h"
+namespace {
+
+std::string GetPkgRootPath(const std::string& pkgid, uid_t uid) {
+ pkgmgrinfo_pkginfo_h handle;
+ int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid.c_str(), uid, &handle);
+ if (ret != PMINFO_R_OK)
+ return {};
+
+ char *root_path;
+ ret = pkgmgrinfo_pkginfo_get_root_path(handle, &root_path);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return {};
+ }
+ std::string path(root_path);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+
+ return path;
+}
+
+} // namespace
+
namespace ttm {
namespace loader {
return bundle_.GetString(key);
}
+std::string ThemeInfo::GetPath(const std::string& key) const {
+ bool is_overlayed = false;
+ std::vector<std::string> selected_keys =
+ bundle_.GetStringArray("selected_keys");
+ auto it = std::find(selected_keys.begin(), selected_keys.end(), key);
+ if (it != selected_keys.end())
+ is_overlayed = true;
+
+ std::string pkgid;
+ uid_t uid;
+ if (is_overlayed) {
+ pkgid = GetPkgid();
+ uid = GetUid();
+ } else {
+ pkgid = bundle_.GetString("default_pkgid");
+ uid = std::stoi(bundle_.GetString("default_uid"));
+ }
+
+ std::string root_path = GetPkgRootPath(pkgid, uid);
+ if (root_path.empty()) {
+ LOG(ERROR) << "Failed to get root path of theme";
+ return {};
+ }
+
+ std::string val = bundle_.GetString(key);
+ return root_path + "/" + val;
+}
+
std::vector<std::string> ThemeInfo::GetStringArray(
const std::string& key) const {
std::vector<std::string> v = bundle_.GetStringArray(key);
return v;
}
+std::vector< std::string> ThemeInfo::GetPathArray(
+ const std::string& key) const {
+ std::string root_path = GetPkgRootPath(GetPkgid(), GetUid());
+ if (root_path.empty()) {
+ LOG(ERROR) << "Failed to get root path of theme";
+ return {};
+ }
+
+ std::vector<std::string> val_arr = bundle_.GetStringArray(key);
+ std::vector<std::string> path_arr;
+ for (const std::string& val : val_arr)
+ path_arr.emplace_back(root_path + "/" + val);
+
+ return path_arr;
+}
+
int ThemeInfo::GetInt(const std::string& key) const {
int val = std::stoi(bundle_.GetString(key));
return val;
return bundle_;
}
-ThemeInfo& ThemeInfo::Merge(const ThemeInfo& other) {
+ThemeInfo& ThemeInfo::MergeDefault(const ThemeInfo& default_theme) {
std::vector<tizen_base::Bundle::KeyInfo> keyinfos = bundle_.GetKeys();
- std::vector<tizen_base::Bundle::KeyInfo> other_keyinfos =
- const_cast<ThemeInfo&>(other).bundle_.GetKeys();
+ std::vector<tizen_base::Bundle::KeyInfo> default_keyinfos =
+ const_cast<ThemeInfo&>(default_theme).bundle_.GetKeys();
// We need to create new vector which only has key strings, because we need to
// sort and resize vector to use set_difference(), but
std::vector<std::string> keys;
for (const auto& info : keyinfos)
keys.emplace_back(info.GetName());
- std::vector<std::string> other_keys;
- for (const auto& info : other_keyinfos)
- other_keys.emplace_back(info.GetName());
+ std::vector<std::string> default_keys;
+ for (const auto& info : default_keyinfos)
+ default_keys.emplace_back(info.GetName());
- if (keys.size() < other_keys.size())
- keys.resize(other_keys.size());
+ if (keys.size() < default_keys.size())
+ keys.resize(default_keys.size());
std::sort(keys.begin(), keys.end());
- std::sort(other_keys.begin(), other_keys.end());
+ std::sort(default_keys.begin(), default_keys.end());
std::vector<std::string> diff;
- std::set_difference(other_keys.begin(), other_keys.end(), keys.begin(),
+ std::set_difference(default_keys.begin(), default_keys.end(), keys.begin(),
keys.end(), std::back_inserter(diff));
// do not merge special key "is_default"
diff.erase(std::remove(diff.begin(), diff.end(), "is_default"), diff.end());
for (const auto& key : diff) {
- bundle_type type = other.bundle_.GetType(key);
+ bundle_type type = default_theme.bundle_.GetType(key);
switch (type) {
case BUNDLE_TYPE_STR:
- bundle_.Add(key, other.bundle_.GetString(key));
+ bundle_.Add(key, default_theme.bundle_.GetString(key));
break;
case BUNDLE_TYPE_STR_ARRAY:
- bundle_.Add(key, other.bundle_.GetStringArray(key));
+ bundle_.Add(key, default_theme.bundle_.GetStringArray(key));
break;
case BUNDLE_TYPE_BYTE:
- bundle_.Add(key, other.bundle_.GetByte(key));
+ bundle_.Add(key, default_theme.bundle_.GetByte(key));
break;
default:
LOG(WARNING) << "Unexpected bundle_type during merging bundle";
}
}
+ // Add selected(origin) keys to distinguish overlayed or not
+ bundle_.Add("selected_keys", keys);
+
+ // Add default pkgid, uid for getting path values
+ bundle_.Add("default_pkgid", default_theme.GetPkgid());
+ bundle_.Add("default_uid", std::to_string(default_theme.GetUid()));
+
return *this;
}
std::string GetPreview() const;
std::string GetDescription() const;
std::string GetString(const std::string& key) const;
+ std::string GetPath(const std::string& key) const;
std::vector<std::string> GetStringArray(const std::string& key) const;
+ std::vector<std::string> GetPathArray(const std::string& key) const;
int GetInt(const std::string& key) const;
float GetFloat(const std::string& key) const;
bool GetBool(const std::string& key) const;
tizen_base::Bundle Serialize() const;
- ThemeInfo& Merge(const ThemeInfo& other);
+ ThemeInfo& MergeDefault(const ThemeInfo& other);
private:
tizen_base::Bundle bundle_;
std::shared_ptr<loader::ThemeInfo> default_theme =
proxy_->GetDefaultTheme();
if (default_theme)
- themeinfo->Merge(*default_theme);
+ themeinfo->MergeDefault(*default_theme);
b.Add(dbus::kCmdResultKey, "ok");
b.Add(dbus::kCmdDataKey,
--- /dev/null
+/*
+ * Copyright (c) 2020 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 "unit_tests/mock/pkgmgr_info_mock.h"
+
+#include <pkgmgr-info.h>
+
+#include "unit_tests/mock/mock_hook.h"
+#include "unit_tests/mock/test_fixture.h"
+
+extern "C" int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char* pkgid, uid_t uid,
+ pkgmgrinfo_pkginfo_h* handle) {
+ return MOCK_HOOK_P3(PkgmgrInfoMock, pkgmgrinfo_pkginfo_get_usr_pkginfo, pkgid,
+ uid, handle);
+}
+
+extern "C" int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle,
+ char** root_path) {
+ return MOCK_HOOK_P2(PkgmgrInfoMock, pkgmgrinfo_pkginfo_get_root_path, handle,
+ root_path);
+}
+
+extern "C" int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h handle) {
+ return MOCK_HOOK_P1(PkgmgrInfoMock, pkgmgrinfo_pkginfo_destroy_pkginfo,
+ handle);
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#ifndef UNIT_TESTS_MOCK_PKGMGR_INFO_MOCK_H_
+#define UNIT_TESTS_MOCK_PKGMGR_INFO_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <pkgmgr-info.h>
+
+#include "mock/module_mock.h"
+
+class PkgmgrInfoMock : public virtual ModuleMock {
+ public:
+ virtual ~PkgmgrInfoMock() {}
+
+ MOCK_METHOD3(pkgmgrinfo_pkginfo_get_usr_pkginfo,
+ int(const char*, uid_t, pkgmgrinfo_pkginfo_h*));
+ MOCK_METHOD2(pkgmgrinfo_pkginfo_get_root_path,
+ int(pkgmgrinfo_pkginfo_h, char**));
+ MOCK_METHOD1(pkgmgrinfo_pkginfo_destroy_pkginfo, int(pkgmgrinfo_pkginfo_h));
+};
+
+#endif // UNIT_TESTS_MOCK_PKGMGR_INFO_MOCK_H_
#include "theme/loader/theme_info.h"
#include "unit_tests/mock/gio_mock.h"
+#include "unit_tests/mock/pkgmgr_info_mock.h"
#include "unit_tests/mock/test_fixture.h"
using ::testing::_;
}
};
-class Mocks : public ::testing::NiceMock<GioMock> {};
+class Mocks : public ::testing::NiceMock<GioMock>,
+ public ::testing::NiceMock<PkgmgrInfoMock> {};
class RequestBrokerTest : public TestFixture {
public:
#include "theme_provider/selection_request_handler.h"
#include "theme_provider/theme_info_proxy.h"
#include "unit_tests/mock/gio_mock.h"
+#include "unit_tests/mock/pkgmgr_info_mock.h"
#include "unit_tests/mock/test_fixture.h"
using ::testing::_;
} // namespace
-class Mocks : public ::testing::NiceMock<GioMock> {};
+class Mocks : public ::testing::NiceMock<GioMock>,
+ public ::testing::NiceMock<PkgmgrInfoMock> {};
class RequestHandlersTest : public TestFixture {
public:
ttm::provider::DbManager db_manager(kTestDb);
tizen_base::Bundle b;
b.Add("id", "default_id");
+ b.Add("pkgid", "default_pkgid");
+ b.Add("uid", "5001");
b.Add("version", "1.0");
b.Add("tool_version", "1.1");
b.Add("title", "Default Theme");
proxy_ = std::make_shared<ThemeInfoProxy>(kTestDb);
b_.Add("id", "testid");
+ b_.Add("pkgid", "testpkgid");
+ b_.Add("uid", "5001");
b_.Add("version", "1.0");
b_.Add("tool_version", "1.1");
b_.Add("title", "Test");
#include <stdlib.h>
#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <pkgmgr-info.h>
#include <iostream>
#include <memory>
#include "api/theme.h"
#include "api/theme_error.h"
#include "theme/loader/theme_info.h"
-
+#include "unit_tests/mock/gio_mock.h"
+#include "unit_tests/mock/pkgmgr_info_mock.h"
+#include "unit_tests/mock/test_fixture.h"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::StrEq;
using ttm::loader::ThemeInfo;
-class ThemeTest : public testing::Test {
+class Mocks : public ::testing::NiceMock<GioMock>,
+ public ::testing::NiceMock<PkgmgrInfoMock> {};
+
+class ThemeTest : public TestFixture {
public:
+ ThemeTest() : TestFixture(std::make_unique<Mocks>()) {}
virtual ~ThemeTest() {}
virtual void SetUp() {
std::vector<std::string> ar = {"str1", "str2"};
b_.Add("id", "testid");
+ b_.Add("pkgid", "testpkgid");
+ b_.Add("uid", "5001");
b_.Add("version", "1.0");
b_.Add("tool_version", "1.1");
b_.Add("title", "Test");
TEST_F(ThemeTest, Theme_Destroy_N) {
int ret = theme_destroy(nullptr);
EXPECT_EQ(ret, THEME_MANAGER_ERROR_INVALID_PARAMETER);
-}
\ No newline at end of file
+}
+
+TEST_F(ThemeTest, Theme_GetPath) {
+ tizen_base::Bundle b;
+ b.Add("id", "defaultid");
+ b.Add("pkgid", "defaultpkgid");
+ b.Add("uid", "5001");
+ b.Add("version", "1.0");
+ b.Add("tool_version", "1.1");
+ b.Add("title", "Default");
+ b.Add("resolution", "360X360");
+ b.Add("preview", "shared/res/default_preview.png");
+ b.Add("test_resource", "shared/res/default_resource.png");
+ b.Add("description", "default test");
+ b.Add("stringkey", "value");
+
+ ThemeInfo default_theme(b);
+ ThemeInfo test_theme(b_);
+ test_theme.MergeDefault(default_theme);
+
+
+ int handle1 = 1;
+ int handle2 = 2;
+ EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+ pkgmgrinfo_pkginfo_get_usr_pkginfo(StrEq("testpkgid"), _, _)).
+ WillOnce(DoAll(
+ SetArgPointee<2>(
+ reinterpret_cast<pkgmgrinfo_pkginfo_h>(handle1)),
+ Return(PMINFO_R_OK)));
+ EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+ pkgmgrinfo_pkginfo_get_usr_pkginfo(StrEq("defaultpkgid"), _, _)).
+ WillOnce(DoAll(
+ SetArgPointee<2>(
+ reinterpret_cast<pkgmgrinfo_pkginfo_h>(handle2)),
+ Return(PMINFO_R_OK)));
+ char root_path1[] = "/opt/usr/globalapps/test_pkgid";
+ char root_path2[] = "/opt/usr/globalapps/default_pkgid";
+ EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+ pkgmgrinfo_pkginfo_get_root_path(
+ reinterpret_cast<pkgmgrinfo_pkginfo_h>(handle1), _)).
+ WillOnce(DoAll(
+ SetArgPointee<1>(const_cast<char*>(root_path1)),
+ Return(PMINFO_R_OK)));
+ EXPECT_CALL(GetMock<PkgmgrInfoMock>(),
+ pkgmgrinfo_pkginfo_get_root_path(
+ reinterpret_cast<pkgmgrinfo_pkginfo_h>(handle2), _)).
+ WillOnce(DoAll(
+ SetArgPointee<1>(const_cast<char*>(root_path2)),
+ Return(PMINFO_R_OK)));
+
+ EXPECT_EQ("/opt/usr/globalapps/test_pkgid/shared/res/preview.png",
+ test_theme.GetPath("preview"));
+ EXPECT_EQ("/opt/usr/globalapps/default_pkgid/shared/res/default_resource.png",
+ test_theme.GetPath("test_resource"));
+}
#include "loader/theme_info_loader.h"
#include "unit_tests/mock/gio_mock.h"
+#include "unit_tests/mock/pkgmgr_info_mock.h"
#include "unit_tests/mock/test_fixture.h"
using namespace ttm::loader;
}
};
-class Mocks : public ::testing::NiceMock<GioMock> {};
+class Mocks : public ::testing::NiceMock<GioMock>,
+ public ::testing::NiceMock<PkgmgrInfoMock> {};
class ThemeLoaderTest : public TestFixture {
public: