Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ jobs:
channel: stable
- name: Install clang-format
run: |
sudo apt-get update
sudo apt-get install clang-format-11
pip install clang-format==16.0.6
- name: Check format
run: |
./tools/tools_runner.sh format --fail-on-change --no-kotlin --no-java --no-swift --clang-format-path=clang-format-11 \
Expand Down
54 changes: 54 additions & 0 deletions packages/in_app_purchase/tizen/inc/ftpw_in_app_purchase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2026 Samsung Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_TIZEN_PLUGINS_WRAPPER_IN_APP_PURCHASE_H_
#define FLUTTER_TIZEN_PLUGINS_WRAPPER_IN_APP_PURCHASE_H_

#include <stdbool.h>
#include <stdint.h>

typedef void (*billing_payment_api_cb)(const char *detail_result,
void *user_data);
typedef bool (*billing_buyitem_cb)(const char *pay_result,
const char *detail_info, void *user_data);

typedef struct sso_login_info {
char login_id[128];
char login_pwd[128];
char login_guid[128];
char uid[128];
char user_icon[128 * 8];
} sso_login_info_s;

#ifdef __cplusplus
extern "C" {
#endif

// Native libraries remain loaded for the process lifetime (callbacks may
// outlive calls).

bool ftpw_in_app_purchase_service_billing_get_products_list(
const char *app_id, const char *country_code, int page_size,
int page_number, const char *check_value, billing_payment_api_cb callback,
void *user_data);
bool ftpw_in_app_purchase_service_billing_get_purchase_list(
const char *app_id, const char *custom_id, const char *country_code,
int page_number, const char *check_value, billing_payment_api_cb callback,
void *user_data);
bool ftpw_in_app_purchase_service_billing_is_service_available(
billing_payment_api_cb callback, void *user_data);
bool ftpw_in_app_purchase_service_billing_buyitem(const char *app_id,
const char *detail_info);
void ftpw_in_app_purchase_service_billing_set_buyitem_cb(
billing_buyitem_cb callback, void *user_data);
bool ftpw_in_app_purchase_service_billing_verify_invoice(
const char *app_id, const char *custom_id, const char *invoice_id,
const char *country_code, billing_payment_api_cb callback, void *user_data);
bool ftpw_in_app_purchase_sso_get_login_info(sso_login_info_s *login_info);
char *ftpw_in_app_purchase_get_county_code();

#ifdef __cplusplus
}
#endif

#endif
4 changes: 2 additions & 2 deletions packages/in_app_purchase/tizen/inc/rapidjson/rapidjson.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,8 @@ RAPIDJSON_NAMESPACE_END
#define RAPIDJSON_STATIC_ASSERT(x) \
typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest<sizeof( \
::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x)>)> \
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) \
RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) \
RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
#endif // RAPIDJSON_STATIC_ASSERT

///////////////////////////////////////////////////////////////////////////////
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3 changes: 3 additions & 0 deletions packages/in_app_purchase/tizen/project_def.prop
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ USER_CPP_UNDEFS =
USER_INC_DIRS = inc src
USER_INC_FILES =
USER_CPP_INC_FILES =

USER_LIB_DIRS += lib/${BUILD_ARCH}
USER_LIBS += ftpw_in_app_purchase
129 changes: 17 additions & 112 deletions packages/in_app_purchase/tizen/src/billing_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "billing_manager.h"

#include <dlfcn.h>
#include <flutter/encodable_value.h>
#include <flutter/standard_method_codec.h>

Expand All @@ -14,27 +13,13 @@
#include <string>
#include <variant>

#include "billing_service_proxy.h"
#include "ftpw_in_app_purchase.h"
#include "log.h"
#include "messages.h"
#include "rapidjson/document.h"

namespace in_app_purchase_tizen {

static std::string ServerTypeToString(billing_server_type server_type) {
switch (server_type) {
case SERVERTYPE_OPERATE:
return "PRD";
break;
case SERVERTYPE_DEV:
return "DEV";
break;
default:
return "NONE";
break;
}
}

static flutter::EncodableValue ConvertVariantToEncodable(
std::variant<int, double> var) {
if (std::holds_alternative<int>(var)) {
Expand All @@ -45,120 +30,46 @@ static flutter::EncodableValue ConvertVariantToEncodable(
return flutter::EncodableValue();
}

bool BillingManager::Init() {
LOG_INFO("[BillingManager] Init billing api.");

if (!BillingWrapper::GetInstance().Initialize()) {
LOG_ERROR("[BillingManager] Fail to initialize billing APIs.");
return false;
}
return true;
}

std::optional<std::string> BillingManager::GetCustomId() {
void *handle = dlopen("libsso_api.so", RTLD_LAZY);
if (!handle) {
LOG_ERROR("[BillingManager] Fail to open sso APIs.");
return std::nullopt;
}
FuncSsoGetLoginInfo sso_get_login_info =
reinterpret_cast<FuncSsoGetLoginInfo>(
dlsym(handle, "sso_get_login_info"));
if (!sso_get_login_info) {
LOG_ERROR("[BillingManager] Fail to find the sso_get_login_info symbol.");
dlclose(handle);
return std::nullopt;
}

std::optional<std::string> custom_id;
sso_login_info_s login_info = {};
int ret = sso_get_login_info(&login_info);
if (ret == SSO_SUCCESS) {
if (!ftpw_in_app_purchase_sso_get_login_info(&login_info)) {
custom_id = login_info.uid;
} else {
LOG_ERROR("[BillingManager] Fail to get the login info. (%d)", ret);
LOG_ERROR("[BillingManager] Fail to get the login info.");
}
// NOTE: written through volatile because a plain memset on a struct that
// is dead afterwards is dropped by the optimizer.
auto *bytes = reinterpret_cast<volatile unsigned char *>(&login_info);
for (std::size_t i = 0; i < sizeof(login_info); ++i) {
bytes[i] = 0;
}
dlclose(handle);
return custom_id;
}

std::optional<std::string> BillingManager::GetCountryCode() {
void *handle = dlopen("libvconf.so.0", RTLD_LAZY);
if (!handle) {
LOG_ERROR("[BillingManager] Fail to open vconf APIs.");
return std::nullopt;
}
FuncVconfGetStr vconf_get_str =
reinterpret_cast<FuncVconfGetStr>(dlsym(handle, "vconf_get_str"));
if (!vconf_get_str) {
LOG_ERROR("[BillingManager] Fail to find the vconf_get_str symbol.");
dlclose(handle);
return std::nullopt;
}

std::optional<std::string> country_code;
char *value = vconf_get_str("db/comss/countrycode");
char *value = ftpw_in_app_purchase_get_county_code();
if (value) {
country_code = value;
free(value);
} else {
LOG_ERROR("[BillingManager] Fail to read db/comss/countrycode.");
LOG_ERROR("[BillingManager] Fail to get country code.");
}
dlclose(handle);
return country_code;
}

bool BillingManager::IsAvailable(FunctionResult<bool> result) {
LOG_INFO("[BillingManager] Check billing server is available.");

void *handle = dlopen("libcapi-system-info.so.0", RTLD_LAZY);
if (!handle) {
LOG_ERROR("[BillingManager] Fail to open system APIs.");
} else {
FuncSystemInfGetValueInt system_info_get_value_int =
reinterpret_cast<FuncSystemInfGetValueInt>(
dlsym(handle, "system_info_get_value_int"));
if (system_info_get_value_int) {
int tv_server_type = 0;
int ret = system_info_get_value_int(SYSTEM_INFO_KEY_INFO_LINK_SERVER_TYPE,
&tv_server_type);
if (ret == SYSTEM_INFO_ERROR_NONE) {
switch (tv_server_type) {
case PRD:
billing_server_type_ = SERVERTYPE_OPERATE;
break;
case DEV:
billing_server_type_ = SERVERTYPE_DEV;
break;
default:
billing_server_type_ = SERVERTYPE_NONE;
break;
}
LOG_INFO("[BillingManager] Billing Server Type is %d",
billing_server_type_);
} else {
LOG_ERROR("[BillingManager] Fail to get TV server type.");
dlclose(handle);
return false;
}
}
dlclose(handle);
}

if (is_available_callback_) {
LOG_ERROR("[BillingManager] IsAvailable is already called.");
return false;
}

is_available_callback_ = std::move(result);
bool ret = BillingWrapper::GetInstance().service_billing_is_service_available(
billing_server_type_, OnAvailable, this);
bool ret = ftpw_in_app_purchase_service_billing_is_service_available(
OnAvailable, this);
if (!ret) {
is_available_callback_ = nullptr;
LOG_ERROR("[BillingManager] service_billing_is_service_available failed.");
Expand All @@ -179,9 +90,9 @@ bool BillingManager::GetProductList(
}

get_product_list_callback_ = std::move(result);
bool ret = BillingWrapper::GetInstance().service_billing_get_products_list(
app_id, country_code, page_size, page_number, check_value,
billing_server_type_, OnProducts, this);
bool ret = ftpw_in_app_purchase_service_billing_get_products_list(
app_id, country_code, page_size, page_number, check_value, OnProducts,
this);
if (!ret) {
get_product_list_callback_ = nullptr;
LOG_ERROR("[BillingManager] service_billing_get_products_list failed.");
Expand All @@ -202,9 +113,9 @@ bool BillingManager::GetPurchaseList(
}

get_purchase_list_callback_ = std::move(result);
bool ret = BillingWrapper::GetInstance().service_billing_get_purchase_list(
app_id, custom_id, country_code, page_number, check_value,
billing_server_type_, OnPurchase, this);
bool ret = ftpw_in_app_purchase_service_billing_get_purchase_list(
app_id, custom_id, country_code, page_number, check_value, OnPurchase,
this);
if (!ret) {
get_purchase_list_callback_ = nullptr;
LOG_ERROR("[BillingManager] service_billing_get_purchase_list failed.");
Expand All @@ -224,9 +135,8 @@ bool BillingManager::BuyItem(const char *app_id, const char *detail_info,
}

buy_item_callback_ = std::move(result);
bool ret = BillingWrapper::GetInstance().service_billing_buyitem(
app_id, ServerTypeToString(billing_server_type_).c_str(), detail_info);
BillingWrapper::GetInstance().service_billing_set_buyitem_cb(OnBuyItem, this);
bool ret = ftpw_in_app_purchase_service_billing_buyitem(app_id, detail_info);
ftpw_in_app_purchase_service_billing_set_buyitem_cb(OnBuyItem, this);
if (!ret) {
buy_item_callback_ = nullptr;
LOG_ERROR("[BillingManager] service_billing_buyitem failed.");
Expand All @@ -246,9 +156,8 @@ bool BillingManager::VerifyInvoice(
}

verify_invoice_callback_ = std::move(result);
bool ret = BillingWrapper::GetInstance().service_billing_verify_invoice(
app_id, custom_id, invoice_id, country_code, billing_server_type_,
OnVerify, this);
bool ret = ftpw_in_app_purchase_service_billing_verify_invoice(
app_id, custom_id, invoice_id, country_code, OnVerify, this);
if (!ret) {
verify_invoice_callback_ = nullptr;
LOG_ERROR("[BillingManager] service_billing_verify_invoice failed.");
Expand Down Expand Up @@ -530,8 +439,4 @@ void BillingManager::OnVerify(const char *detail_result, void *user_data) {
self->verify_invoice_callback_ = nullptr;
}

void BillingManager::Dispose() {
LOG_INFO("[BillingManager] Dispose billing.");
}

} // namespace in_app_purchase_tizen
46 changes: 0 additions & 46 deletions packages/in_app_purchase/tizen/src/billing_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,18 @@
#ifndef FLUTTER_PLUGIN_BILLING_MANAGER_H
#define FLUTTER_PLUGIN_BILLING_MANAGER_H

#include <tizen_error.h>

#include <cassert>
#include <iostream>
#include <mutex>
#include <optional>
#include <string>
#include <variant>

#include "billing_service_proxy.h"
#include "messages.h"
#include "rapidjson/document.h"

#define SSO_API_MAX_STRING_LEN 128
#define SSO_SUCCESS 0

namespace in_app_purchase_tizen {

typedef struct sso_login_info {
char login_id[SSO_API_MAX_STRING_LEN];
char login_pwd[SSO_API_MAX_STRING_LEN];
char login_guid[SSO_API_MAX_STRING_LEN];
char uid[SSO_API_MAX_STRING_LEN];
char user_icon[SSO_API_MAX_STRING_LEN * 8];
} sso_login_info_s;

typedef enum {
PRD = 0,
DEV,
} tv_server_type;

typedef enum {
SYSTEM_INFO_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
SYSTEM_INFO_ERROR_INVALID_PARAMETER =
TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
SYSTEM_INFO_ERROR_OUT_OF_MEMORY =
TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
SYSTEM_INFO_ERROR_IO_ERROR =
TIZEN_ERROR_IO_ERROR, /**< An input/output error occurred when reading
value from system */
SYSTEM_INFO_ERROR_PERMISSION_DENIED =
TIZEN_ERROR_PERMISSION_DENIED, /**< No permission to use the API */
SYSTEM_INFO_ERROR_NOT_SUPPORTED =
TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported parameter (Since 3.0) */
} system_info_error_e;

typedef enum {
SYSTEM_INFO_KEY_INFO_LINK_SERVER_TYPE = 126,
} system_info_key_e;

typedef int (*FuncSsoGetLoginInfo)(sso_login_info_s *login_info);
typedef char *(*FuncVconfGetStr)(const char *in_key);
typedef int (*FuncSystemInfGetValueInt)(system_info_key_e key, int *value);

template <typename T>
using FunctionResult = std::function<void(ErrorOr<T>)>;

Expand Down Expand Up @@ -102,8 +60,6 @@ class BillingManager {
explicit BillingManager() {}
~BillingManager(){};

bool Init();
void Dispose();
bool IsAvailable(FunctionResult<bool> result);
bool BuyItem(const char *app_id, const char *detail_info,
FunctionResult<BillingBuyData> result);
Expand All @@ -128,8 +84,6 @@ class BillingManager {
static void OnAvailable(const char *detail_result, void *user_data);
static void OnVerify(const char *detail_result, void *user_data);

billing_server_type billing_server_type_;

FunctionResult<bool> is_available_callback_;
FunctionResult<BillingBuyData> buy_item_callback_;
FunctionResult<ProductsListApiResult> get_product_list_callback_;
Expand Down
Loading
Loading