Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetAdRouter: Changed to call GetXifa/GetAdRouter instead of GetAdInitObject #387

Merged
merged 12 commits into from
Jan 30, 2024
188 changes: 110 additions & 78 deletions core/main/src/firebolt/handlers/advertising_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::{
service::apps::app_events::{AppEventDecorationError, AppEventDecorator, AppEvents},
utils::rpc_utils::rpc_add_event_listener_with_decorator,
};
use base64::encode;
use jsonrpsee::{
core::{async_trait, Error, RpcResult},
proc_macros::rpc,
Expand All @@ -28,8 +29,8 @@ use ripple_sdk::{
api::{
firebolt::{
fb_advertising::{
AdIdRequestParams, AdInitObjectRequestParams, AdvertisingFrameworkConfig,
AdvertisingRequest, AdvertisingResponse, GetAdConfig,
AdConfigRequestParams, AdConfigResponse, AdIdRequestParams,
AdvertisingFrameworkConfig, AdvertisingRequest, AdvertisingResponse, GetAdConfig,
},
fb_capabilities::{CapabilityRole, FireboltCap, RoleInfo},
fb_general::{ListenRequest, ListenerResponse},
Expand All @@ -40,7 +41,7 @@ use ripple_sdk::{
EVENT_ADVERTISING_SKIP_RESTRICTION_CHANGED,
},
},
log::error,
log::{debug, error},
};
use serde::{Deserialize, Serialize};
use serde_json::Value;
Expand All @@ -51,7 +52,10 @@ use crate::{
state::platform_state::PlatformState, utils::rpc_utils::rpc_err,
};

use super::{capabilities_rpc::is_permitted, privacy_rpc};
use super::{
capabilities_rpc::is_permitted,
privacy_rpc::{self, PrivacyImpl},
};

const ADVERTISING_APP_BUNDLE_ID_SUFFIX: &str = "Comcast";
//{"xifa":"00000000-0000-0000-0000-000000000000","xifaType":"sessionId","lmt":"0"}
Expand Down Expand Up @@ -97,7 +101,7 @@ pub struct SetSkipRestrictionRequest {
pub value: SkipRestriction,
}

#[derive(Debug, Deserialize, Clone)]
#[derive(Debug, Deserialize, Clone, Default)]
pub struct AdvertisingIdRPCRequest {
pub options: Option<ScopeOption>,
}
Expand Down Expand Up @@ -233,6 +237,17 @@ pub struct AdvertisingImpl {
pub state: PlatformState,
}

fn get_scope_option_map(options: &Option<ScopeOption>) -> HashMap<String, String> {
let mut scope_option_map = HashMap::new();
if let Some(scope_opt) = options {
if let Some(scope) = &scope_opt.scope {
scope_option_map.insert("type".to_string(), scope._type.as_string().to_string());
scope_option_map.insert("id".to_string(), scope.id.to_string());
}
}
scope_option_map
}

#[async_trait]
impl AdvertisingServer for AdvertisingImpl {
async fn reset_identifier(&self, _ctx: CallContext) -> RpcResult<()> {
Expand All @@ -255,14 +270,6 @@ impl AdvertisingServer for AdvertisingImpl {
request: AdvertisingIdRPCRequest,
) -> RpcResult<AdvertisingId> {
if let Some(session) = self.state.session_state.get_account_session() {
let mut scope_option_map = HashMap::new();
if let Some(scope_opt) = &request.options {
if let Some(scope) = &scope_opt.scope {
scope_option_map
.insert("type".to_string(), scope._type.as_string().to_string());
scope_option_map.insert("id".to_string(), scope.id.to_string());
}
}
let payload = AdvertisingRequest::GetAdIdObject(AdIdRequestParams {
privacy_data: privacy_rpc::get_allow_app_content_ad_targeting_settings(
&self.state,
Expand All @@ -272,7 +279,7 @@ impl AdvertisingServer for AdvertisingImpl {
.await,
app_id: ctx.app_id.to_owned(),
dist_session: session,
scope: scope_option_map,
scope: get_scope_option_map(&request.options),
});
let resp = self.state.get_client().send_extn_request(payload).await;

Expand All @@ -285,12 +292,12 @@ impl AdvertisingServer for AdvertisingImpl {
if let Some(AdvertisingResponse::AdIdObject(obj)) =
payload.payload.extract::<AdvertisingResponse>()
{
let ad_init_object = AdvertisingId {
let ad_id = AdvertisingId {
ifa: obj.ifa,
ifa_type: obj.ifa_type,
lmt: obj.lmt,
};
return Ok(ad_init_object);
return Ok(ad_id);
}
}

Expand All @@ -317,8 +324,9 @@ impl AdvertisingServer for AdvertisingImpl {
config: GetAdConfig,
) -> RpcResult<AdvertisingFrameworkConfig> {
let session = self.state.session_state.get_account_session();
let app_id = ctx.app_id.to_string();
let distributor_experience_id = self
let durable_app_id = ctx.app_id.to_string();
let environment = config.options.environment;
let distributor_app_id = self
.state
.get_device_manifest()
.get_distributor_experience_id();
Expand All @@ -330,76 +338,100 @@ impl AdvertisingServer for AdvertisingImpl {
.await
.unwrap_or(false);

let payload = AdvertisingRequest::GetAdInitObject(AdInitObjectRequestParams {
privacy_data: privacy_rpc::get_allow_app_content_ad_targeting_settings(
&self.state,
None,
&app_id,
)
.await,
environment: config.options.environment.to_string(),
durable_app_id: app_id,
app_version: "".to_string(),
distributor_app_id: distributor_experience_id,
device_ad_attributes: HashMap::new(),
coppa: config.options.coppa.unwrap_or(false),
authentication_entity: config.options.authentication_entity.unwrap_or_default(),
let ad_opt_out = PrivacyImpl::get_allow_app_content_ad_targeting(&self.state).await;

let mut privacy_data = privacy_rpc::get_allow_app_content_ad_targeting_settings(
&self.state,
None,
&durable_app_id,
)
.await;

privacy_data.insert("pdt".into(), "gdp:v1".into());

let coppa = match config.options.coppa {
Some(c) => c as u32,
None => 0,
};

let advertising_request = AdvertisingRequest::GetAdConfig(AdConfigRequestParams {
privacy_data: privacy_data.clone(),
durable_app_id: durable_app_id.clone(),
dist_session: session
.clone()
.ok_or_else(|| Error::Custom(String::from("no session available")))?,
scope: HashMap::new(),
environment: environment.to_string(),
scope: get_scope_option_map(&None),
pahearn73 marked this conversation as resolved.
Show resolved Hide resolved
});

match self.state.get_client().send_extn_request(payload).await {
Ok(payload) => match payload.payload.extract().unwrap() {
AdvertisingResponse::AdInitObject(obj) => {
let ad_init_object = AdvertisingFrameworkConfig {
ad_server_url: obj.ad_server_url,
ad_server_url_template: obj.ad_server_url_template,
ad_network_id: obj.ad_network_id,
ad_profile_id: obj.ad_profile_id,
ad_site_section_id: "".to_string(),
ad_opt_out: obj.ad_opt_out,
privacy_data: obj.privacy_data,
ifa: if ad_id_authorised {
obj.ifa
} else {
IFA_ZERO_BASE64.to_string()
},
ifa_value: if ad_id_authorised {
obj.ifa_value
} else {
let ifa_val_zero = obj
.ifa_value
.chars()
.map(|x| match x {
'-' => x,
_ => '0',
})
.collect();
ifa_val_zero
},
app_name: obj.app_name,
app_bundle_id: obj.app_bundle_id,
distributor_app_id: obj.distributor_app_id,
device_ad_attributes: obj.device_ad_attributes,
coppa: obj.coppa.to_string().parse::<u32>().unwrap_or(0),
authentication_entity: obj.authentication_entity,
};
Ok(ad_init_object)
debug!("config: advertising_request: {:?}", advertising_request);

let ad_config = match self
.state
.get_client()
.send_extn_request(advertising_request)
.await
{
Ok(message) => match message.payload.extract() {
Some(advertising_resp) => match advertising_resp {
AdvertisingResponse::AdConfig(resp) => resp,
_ => {
error!("config: Unexpected response payload, ad config not available");
AdConfigResponse::default()
}
},
None => {
error!("config: Ad config payload missing");
AdConfigResponse::default()
}
_ => Err(rpc_err(
"Device returned an invalid type for ad init object",
)),
},
Err(_e) => Err(jsonrpsee::core::Error::Custom(String::from(
"Failed to extract ad init object from response",
))),
}
Err(e) => {
error!("config: Could not get ad config: e={}", e);
AdConfigResponse::default()
}
};

let privacy_data_enc = encode(serde_json::to_string(&privacy_data).unwrap_or_default());

let ad_framework_config = AdvertisingFrameworkConfig {
ad_server_url: ad_config.ad_server_url,
ad_server_url_template: ad_config.ad_server_url_template,
ad_network_id: ad_config.ad_network_id,
ad_profile_id: ad_config.ad_profile_id,
ad_site_section_id: ad_config.ad_site_section_id,
ad_opt_out,
privacy_data: privacy_data_enc,
ifa: if ad_id_authorised {
ad_config.ifa
} else {
IFA_ZERO_BASE64.to_string()
},
ifa_value: if ad_id_authorised {
ad_config.ifa_value
} else {
let ifa_val_zero = ad_config
.ifa_value
.chars()
.map(|x| match x {
'-' => x,
_ => '0',
})
.collect();
ifa_val_zero
},
app_name: durable_app_id.clone(),
app_bundle_id: ad_config.app_bundle_id,
distributor_app_id,
device_ad_attributes: String::default(),
coppa,
authentication_entity: config.options.authentication_entity.unwrap_or_default(),
};

Ok(ad_framework_config)
}

async fn device_attributes(&self, ctx: CallContext) -> RpcResult<Value> {
let afc = self.config(ctx.clone(), Default::default()).await?;

let buff = base64::decode(afc.device_ad_attributes).unwrap_or_default();
match String::from_utf8(buff) {
Ok(mut b_string) => {
Expand Down
53 changes: 20 additions & 33 deletions core/sdk/src/api/firebolt/fb_advertising.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,58 +26,45 @@ use crate::{

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AdvertisingRequest {
GetAdInitObject(AdInitObjectRequestParams),
GetAdIdObject(AdIdRequestParams),
ResetAdIdentifier(AccountSession),
GetAdConfig(AdConfigRequestParams),
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AdInitObjectRequestParams {
pub struct AdIdRequestParams {
pub privacy_data: HashMap<String, String>,
pub environment: String,
pub durable_app_id: String,
pub app_version: String,
pub distributor_app_id: String,
pub device_ad_attributes: HashMap<String, String>,
pub coppa: bool,
pub authentication_entity: String,
pub app_id: String,
pub dist_session: AccountSession,
pub scope: HashMap<String, String>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AdInitObjectResponse {
pub ad_server_url: String,
pub ad_server_url_template: String,
pub ad_network_id: String,
pub ad_profile_id: String,
pub ad_site_section_id: String,
pub ad_opt_out: bool,
pub privacy_data: String,
pub ifa_value: String,
pub struct AdIdResponse {
pub ifa: String,
pub app_name: String,
pub app_bundle_id: String,
pub app_version: String,
pub distributor_app_id: String,
pub device_ad_attributes: String,
pub coppa: String,
pub authentication_entity: String,
pub ifa_type: String,
pub lmt: String,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AdIdRequestParams {
pub struct AdConfigRequestParams {
pub privacy_data: HashMap<String, String>,
pub app_id: String,
pub durable_app_id: String,
pub dist_session: AccountSession,
pub environment: String,
pub scope: HashMap<String, String>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AdIdResponse {
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct AdConfigResponse {
pub ad_server_url: String,
pub ad_server_url_template: String,
pub ad_network_id: String,
pub ad_profile_id: String,
pub ad_site_section_id: String,
pub app_bundle_id: String,
pub ifa: String,
pub ifa_type: String,
pub lmt: String,
pub ifa_value: String,
}

impl ExtnPayloadProvider for AdvertisingRequest {
Expand All @@ -101,11 +88,11 @@ impl ExtnPayloadProvider for AdvertisingRequest {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum AdvertisingResponse {
None,
AdInitObject(AdInitObjectResponse),
AdIdObject(AdIdResponse),
AdConfig(AdConfigResponse),
}

#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct AdvertisingFrameworkConfig {
pub ad_server_url: String,
Expand Down
Loading
Loading