Skip to content

Commit

Permalink
Add extended IFA support to H5vccSystem (#3292)
Browse files Browse the repository at this point in the history
b/334143349

(cherry picked from commit 6653e2f)
  • Loading branch information
gbournou authored and anonymous1-me committed May 18, 2024
1 parent f7bd764 commit f32fc3c
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 26 deletions.
3 changes: 3 additions & 0 deletions cobalt/h5vcc/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ config("h5vcc_internal_config") {

config("h5vcc_external_config") {
defines = []
if (enable_extended_ifa_in_h5vcc) {
defines += [ "COBALT_ENABLE_EXTENDED_IFA" ]
}
}

static_library("h5vcc") {
Expand Down
126 changes: 103 additions & 23 deletions cobalt/h5vcc/h5vcc_system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,54 @@

#include "cobalt/h5vcc/h5vcc_system.h"

#include <utility>

#include "base/strings/stringprintf.h"
#include "cobalt/configuration/configuration.h"
#include "cobalt/version.h"
#include "cobalt/web/environment_settings_helper.h"
#include "cobalt_build_id.h" // NOLINT(build/include_subdir)
#include "starboard/common/system_property.h"
#include "starboard/system.h"

#if SB_API_VERSION < 14
#include "starboard/extension/ifa.h"
#endif // SB_API_VERSION < 14
#include "starboard/system.h"

using starboard::kSystemPropertyMaxLength;

namespace cobalt {
namespace h5vcc {

H5vccSystem::H5vccSystem(
#if SB_IS(EVERGREEN)
H5vccSystem::H5vccSystem(H5vccUpdater* updater) : updater_(updater) {}
H5vccUpdater* updater)
: updater_(updater),
#else
H5vccSystem::H5vccSystem() {}
)
:
#endif
task_runner_(base::SequencedTaskRunner::GetCurrentDefault()),
ifa_extension_(static_cast<const StarboardExtensionIfaApi*>(
SbSystemGetExtension(kStarboardExtensionIfaName))) {
#if defined(COBALT_ENABLE_EXTENDED_IFA)
if (ifa_extension_ && ifa_extension_->version >= 2) {
ifa_extension_->RegisterTrackingAuthorizationCallback(
this, [](void* context) {
DCHECK(context) << "Callback called with NULL context";
if (context) {
static_cast<H5vccSystem*>(context)
->ReceiveTrackingAuthorizationComplete();
}
});
}
#endif // defined(COBALT_ENABLE_EXTENDED_IFA)
}

H5vccSystem::~H5vccSystem() {
#if defined(COBALT_ENABLE_EXTENDED_IFA)
if (ifa_extension_ && ifa_extension_->version >= 2) {
ifa_extension_->UnregisterTrackingAuthorizationCallback();
}
#endif // defined(COBALT_ENABLE_EXTENDED_IFA)
}

bool H5vccSystem::are_keys_reversed() const {
return SbSystemHasCapability(kSbSystemCapabilityReversedEnterAndBack);
Expand Down Expand Up @@ -70,14 +97,9 @@ std::string H5vccSystem::advertising_id() const {
result = property;
}
#else
static auto const* ifa_extension =
static_cast<const StarboardExtensionIfaApi*>(
SbSystemGetExtension(kStarboardExtensionIfaName));
if (ifa_extension &&
strcmp(ifa_extension->name, kStarboardExtensionIfaName) == 0 &&
ifa_extension->version >= 1) {
if (!ifa_extension->GetAdvertisingId(property,
SB_ARRAY_SIZE_INT(property))) {
if (ifa_extension_ && ifa_extension_->version >= 1) {
if (!ifa_extension_->GetAdvertisingId(property,
SB_ARRAY_SIZE_INT(property))) {
DLOG(FATAL) << "Failed to get AdvertisingId from IFA extension.";
} else {
result = property;
Expand All @@ -97,15 +119,9 @@ bool H5vccSystem::limit_ad_tracking() const {
result = std::atoi(property);
}
#else
static auto const* ifa_extension =
static_cast<const StarboardExtensionIfaApi*>(
SbSystemGetExtension(kStarboardExtensionIfaName));

if (ifa_extension &&
strcmp(ifa_extension->name, kStarboardExtensionIfaName) == 0 &&
ifa_extension->version >= 1) {
if (!ifa_extension->GetLimitAdTracking(property,
SB_ARRAY_SIZE_INT(property))) {
if (ifa_extension_ && ifa_extension_->version >= 1) {
if (!ifa_extension_->GetLimitAdTracking(property,
SB_ARRAY_SIZE_INT(property))) {
DLOG(FATAL) << "Failed to get LimitAdTracking from IFA extension.";
} else {
result = std::atoi(property);
Expand All @@ -115,6 +131,70 @@ bool H5vccSystem::limit_ad_tracking() const {
return result;
}

#if defined(COBALT_ENABLE_EXTENDED_IFA)

std::string H5vccSystem::tracking_authorization_status() const {
std::string result = "UNKNOWN";
char property[kSystemPropertyMaxLength] = {0};
if (ifa_extension_ && ifa_extension_->version >= 2) {
if (!ifa_extension_->GetTrackingAuthorizationStatus(
property, SB_ARRAY_SIZE_INT(property))) {
DLOG(FATAL)
<< "Failed to get TrackingAuthorizationStatus from IFA extension.";
} else {
result = property;
}
}
return result;
}

void H5vccSystem::ReceiveTrackingAuthorizationComplete() {
// May be called by another thread.
if (!task_runner_->RunsTasksInCurrentSequence()) {
task_runner_->PostTask(
FROM_HERE,
base::Bind(&H5vccSystem::ReceiveTrackingAuthorizationComplete,
base::Unretained(this)));
return;
}
DCHECK(task_runner_->RunsTasksInCurrentSequence());

// Mark all promises complete and release the references.
for (auto& promise : request_tracking_authorization_promises_) {
promise->value().Resolve();
}
request_tracking_authorization_promises_.clear();
}

script::HandlePromiseVoid H5vccSystem::RequestTrackingAuthorization(
script::EnvironmentSettings* environment_settings) {
auto* global_wrappable = web::get_global_wrappable(environment_settings);
script::HandlePromiseVoid promise =
web::get_script_value_factory(environment_settings)
->CreateBasicPromise<void>();

auto promise_reference =
std::make_unique<script::ValuePromiseVoid::Reference>(global_wrappable,
promise);
if (ifa_extension_ && ifa_extension_->version >= 2) {
request_tracking_authorization_promises_.emplace_back(
std::move(promise_reference));
ifa_extension_->RequestTrackingAuthorization();
} else {
// Reject the promise since the API isn't available.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
[](std::unique_ptr<script::ValuePromiseVoid::Reference>
promise_reference) { promise_reference->value().Reject(); },
std::move(promise_reference)));
}

return promise;
}

#endif // defined(COBALT_ENABLE_EXTENDED_IFA)

std::string H5vccSystem::region() const {
// No region information.
return "";
Expand Down
23 changes: 21 additions & 2 deletions cobalt/h5vcc/h5vcc_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@
#ifndef COBALT_H5VCC_H5VCC_SYSTEM_H_
#define COBALT_H5VCC_H5VCC_SYSTEM_H_

#include <memory>
#include <string>
#include <vector>

#include "starboard/configuration.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/sequenced_task_runner.h"
#if SB_IS(EVERGREEN)
#include "cobalt/h5vcc/h5vcc_updater.h"
#endif
#include "cobalt/script/environment_settings.h"
#include "cobalt/script/script_value_factory.h"
#include "cobalt/script/wrappable.h"
#include "starboard/configuration.h"
#include "starboard/extension/ifa.h"

namespace cobalt {
namespace h5vcc {
Expand All @@ -33,6 +40,7 @@ class H5vccSystem : public script::Wrappable {
#else
H5vccSystem();
#endif
~H5vccSystem();

bool are_keys_reversed() const;
std::string build_id() const;
Expand All @@ -41,6 +49,11 @@ class H5vccSystem : public script::Wrappable {
std::string version() const;
std::string advertising_id() const;
bool limit_ad_tracking() const;
#if defined(COBALT_ENABLE_EXTENDED_IFA)
std::string tracking_authorization_status() const;
script::HandlePromiseVoid RequestTrackingAuthorization(
script::EnvironmentSettings* environment_settings);
#endif // defined(COBALT_ENABLE_EXTENDED_IFA)

bool TriggerHelp() const;

Expand All @@ -55,10 +68,16 @@ class H5vccSystem : public script::Wrappable {
DEFINE_WRAPPABLE_TYPE(H5vccSystem);

private:
std::string video_container_size_;
#if SB_IS(EVERGREEN)
scoped_refptr<H5vccUpdater> updater_;
#endif
scoped_refptr<base::SequencedTaskRunner> const task_runner_;
const StarboardExtensionIfaApi* ifa_extension_;
#if defined(COBALT_ENABLE_EXTENDED_IFA)
void ReceiveTrackingAuthorizationComplete();
std::vector<std::unique_ptr<script::ValuePromiseVoid::Reference>>
request_tracking_authorization_promises_;
#endif // defined(COBALT_ENABLE_EXTENDED_IFA)
DISALLOW_COPY_AND_ASSIGN(H5vccSystem);
};

Expand Down
2 changes: 2 additions & 0 deletions cobalt/h5vcc/h5vcc_system.idl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ interface H5vccSystem {
readonly attribute DOMString version;
readonly attribute DOMString advertisingId;
readonly attribute boolean limitAdTracking;
[Conditional=COBALT_ENABLE_EXTENDED_IFA] readonly attribute DOMString trackingAuthorizationStatus;
[Conditional=COBALT_ENABLE_EXTENDED_IFA, CallWith=EnvironmentSettings, NewObject] Promise<void> requestTrackingAuthorization();
boolean triggerHelp();

// enum UserOnExitStrategy
Expand Down
1 change: 1 addition & 0 deletions cobalt/site/docs/reference/starboard/gn-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Book: /youtube/cobalt/_book.yaml
| **`cobalt_platform_dependencies`**<br><br> List of platform-specific targets that get compiled into cobalt.<br><br>The default value is `[]`. |
| **`cobalt_v8_emit_builtins_as_inline_asm`**<br><br> Some compiler can not compile with raw assembly(.S files) and v8 converts asm to inline assembly for these platforms.<br><br>The default value is `false`. |
| **`default_renderer_options_dependency`**<br><br> Override this value to adjust the default rasterizer setting for your platform.<br><br>The default value is `"//cobalt/renderer:default_options"`. |
| **`enable_extended_ifa_in_h5vcc`**<br><br> Set to true to enable extended IFA functionality in H5vccSystem.<br><br>The default value is `false`. |
| **`enable_in_app_dial`**<br><br> Enables or disables the DIAL server that runs inside Cobalt. Note: Only enable if there's no system-wide DIAL support.<br><br>The default value is `false`. |
| **`executable_configs`**<br><br> Target-specific configurations for executable targets.<br><br>The default value is `[]`. |
| **`final_executable_type`**<br><br> The target type for executable targets. Allows changing the target type on platforms where the native code may require an additional packaging step (ex. Android).<br><br>The default value is `"executable"`. |
Expand Down
3 changes: 3 additions & 0 deletions starboard/build/config/base_configuration.gni
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ declare_args() {
# all unused symbols and nplb fails to link.
# TODO: b/297808555 Remove this flag after nplb is fixed
sb_has_unused_symbol_issue = false

# Set to true to enable extended IFA functionality in H5vccSystem.
enable_extended_ifa_in_h5vcc = false
}

if (current_toolchain == starboard_toolchain &&
Expand Down
32 changes: 31 additions & 1 deletion starboard/extension/ifa.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ extern "C" {

#define kStarboardExtensionIfaName "dev.cobalt.extension.Ifa"

typedef void (*RequestTrackingAuthorizationCallback)(void* callback_context);

typedef struct StarboardExtensionIfaApi {
// Name should be the string |kCobaltExtensionIfaName|.
// This helps to validate that the extension API is correct.
Expand All @@ -46,9 +48,37 @@ typedef struct StarboardExtensionIfaApi {
// In Starboard 14 this the value is retrieved through the system
// property `kSbSystemPropertyLimitAdTracking` defined in
// `starboard/system.h`.

bool (*GetLimitAdTracking)(char* out_value, int value_length);

// The fields below this point were added in version 2 or later.

// Returns the the user's authorization status for using IFA in this app.
// Valid strings that can be returned are:
// * UNKNOWN - if the system isn't able to determine a status
// * NOT_DETERMINED - the user hasn't made a decision yet
// * RESTRICTED - the system doesn't allow the user a choice
// * AUTHORIZED - the user agreed to tracking
// * DENIED - the user declined tracking
// This is optional and only implemented on some platforms.
bool (*GetTrackingAuthorizationStatus)(char* out_value, int value_length);

// Registers the provided callback context and function to allow notification
// when |RequestTrackingAuthorization| completes.
// This is optional and only implemented on some platforms.
void (*RegisterTrackingAuthorizationCallback)(
void* callback_context,
RequestTrackingAuthorizationCallback callback);

// Unregisters any callback context and function set via
// |RegisterTrackingAuthorizationCallback|.
// This is optional and only implemented on some platforms.
void (*UnregisterTrackingAuthorizationCallback)();

// Asks the OS to request a user prompt to allow IFA in this app.
// If a callback is registered (via |RegisterTrackingAuthorizationCallback|),
// it will be called once the request completes.
// This is optional and only implemented on some platforms.
void (*RequestTrackingAuthorization)();
} CobaltExtensionIfaApi;

#ifdef __cplusplus
Expand Down

0 comments on commit f32fc3c

Please sign in to comment.