Implement a billing system for in-app purchases in your application, by using Samsung Checkout through the DPI service APIs and the purchase API and GUI.
Prerequisites
To implement in-app purchases:
Before you start implementing Samsung Checkout in your application, start registering your application at the Samsung Apps TV Seller Office. You do not need to complete the registration with your source code at this point. To be able to use the DPI portal, you need to proceed to the second step of the App Registration Page and set the "Billing" field to "Use" and the "Samsung Checkout on TV" field to "Yes". You can save the registration at this point and return to it later when your source code is complete. For more information, see the Samsung Checkout DPI Portal guide.
To access the device and user information, and use the methods of the Tizen.TV.Service.Billing and Tizen.TV.Service.Sso namespaces, the application has to request permission by adding the following privileges to the "tizen-manifest.xml" file:
using Tizen.TV.Service.Sso;
string uniqueId = "abc";// Set an unique id that you can identify your user. "abc" is a one of the example for Unique custom id. you can assign id managed by your service
Retrieve the country code:
using Tizen.TV;
string country = Environment.SmartHubConfig.Country;
Retrieve the server type:
using Tizen.TV;
SmartHubConfig.ServerType tvServerType = Environment.SmartHubConfig.Server;
The check value is used by the DPI service to verify Purchase List and Products List API requests. It is a Base64 hash generated by applying the HMAC SHA256 algorithm on a concatenated string of parameters using the DPI security key.
The application can also use the check value to verify that API response data from the DPI server is legitimate. To ensure the data integrity of requests and responses in real time, generate and verify the check value for API requests and responses during runtime.
NoteThe DPI security key is used only by Samsung Smart TV applications for Samsung Checkout features. Do not expose this key. You can use a key management server for greater security.
To generate the check value, the following 2 items are used as parameters:
Concatenation of the required parameters
For example, "12345"+"123"+"US"+"2"+"1" is concatenated to "12345123US21".
The required parameters vary depending on the API.
DPI security key
The DPI security key is issued at the DPI portal.
To generate the HMAC SHA256 hash:
using System;
using System.Security.Cryptography;
private string GetCheckValue(string strMsg, string strKey)
{
var encoding = new System.Text.ASCIIEncoding();
byte[] byteKey = encoding.GetBytes(strKey);
byte[] dataToHmac = encoding.GetBytes(strMsg);
HMACSHA256 hmac = new HMACSHA256(byteKey);
return Convert.ToBase64String(hmac.ComputeHash(dataToHmac));
}
Requesting User Purchases
The Purchase List API requests the list of purchased items for a specific user, usually the currently logged-in user. The API response identifies whether purchased products have been applied or have been refunded.
NoteFor subscription products, the default value of the "AppliedStatus" parameter is "true", but the "CancelStatus" parameter does not indicate the refund status in purchase history. Instead, it indicates the cancellation status for the next subscription cycle. The "SubsStatus" and "SubsEndTime" parameters detail the subscription expiration status.
To call the Purchase List API, use the GetPurchaseList() method:
using System;
using System.Security.Cryptography;
using Tizen.TV.Service.Billing;
using Tizen.TV.Service.Sso;
using Tizen.TV;
public void Request_Purchase_list()
{
BillingPlugin pIBilling = new BillingPlugin();
pIBilling.RequestAPIEventHandler += new BillingRequestAPICallbackEventHandler(RequestPurchaseListCallbackEvent);
string strAppId = "**********"; // Your application ID
string strUniqueCustomID = "abc"; // Unique customer ID. "abc" is a one of the example for Unique custom id. you can assign id managed by your service
string strCountryCode = Environment.SmartHubConfig.Country;
string strItemType = "2";
string strSecurityKey = "**********"; // Your security key issued by DPI portal
int iPageNumber = 1;
string strCheckValue = GetCheckValue(strAppId + strUniqueCustomID + strCountryCode + strItemType + iPageNumber, strSecurityKey);
bool bRet = pIBilling.GetPurchaseList(strAppId, strUniqueCustomID, strCountryCode, iPageNumber, strCheckValue, servertype);
if (bRet)
{
// API call success
}
else
{
// API call fail
}
}
private string GetCheckValue(string strMsg, string strKey)
{
var encoding = new System.Text.ASCIIEncoding();
byte[] byteKey = encoding.GetBytes(strKey);
byte[] dataToHmac = encoding.GetBytes(strMsg);
HMACSHA256 hmac = new HMACSHA256(byteKey);
return Convert.ToBase64String(hmac.ComputeHash(dataToHmac));
}
private void RequestPurchaseListCallbackEvent(object sender, BillingRequestAPICallbackEventArgs e)
{
// Do something
}
The following tables describe the Purchase List API parameters. The response data is in JSON format.
Purchase List API request parameters:
Parameter
Type
Mandatory
Description
"AppID"
String
True
Application ID
"CustomID"
Unique Customer ID Same value as the "OrderCustomID" parameter for the BuyItem() method.
"CountryCode"
Country code The country code must be retrieved from the TV.
"PageNumber"
Number
Requested page number Range: 1~N Each purchase record page has up to 100 entries. To receive the complete purchase record, post Purchase List API requests while increasing the "PageNumber" value, until "EOF" is returned in the "CPResult" parameter.
For subscription products, indicates the cancellation status for the next subscription cycle.
"AppliedStatus"
Product application status:
"true": Applied
"false": Not applied
For subscription products, the default value is "true".
"AppliedTime"
String
False
Time product applied, in 14-digit UTC time
"LimitEndTime"
Limited period product end time, in 14-digit UTC time For limited period products only. "LimitEndTime" = "AppliedTime" + "Period"
"RemainTime"
Limited period product time remaining, in seconds For limited period products only. "RemainTime" = "LimitEndTime" – request time
"SubscriptionInfo"
JSON
Subscription information Mandatory for subscription products.
"SubscriptionId"
String
True
Subscription ID
"SubsStartTime"
Subscription start time, in 14-digit UTC time
"SubsEndTime"
Subscription expiry time, in 14-digit UTC time
"SubsStatus"
Subscription status:
"00": Active
"01": Subscription expired
"02": Canceled by buyer
"03": Canceled for payment failure
"04": Canceled by CP
"05": Canceled by admin
Table 2. Purchase List API response parameters
Requesting Products for Sale
The Products List API requests product information from the DPI server. When the API is in "show" status, it returns the information for the products on sale. This API is generally used to generate a list of buyable products in the application.
To call the Products List API, use the GetProductsList() method:
using System;
using System.Security.Cryptography;
using Tizen.TV.Service.Billing;
using Tizen.TV;
public void Request_product_list()
{
BillingPlugin pIBilling = new BillingPlugin();
pIBilling.RequestAPIEventHandler += new BillingRequestAPICallbackEventHandler(RequestProductListCallbackEvent);
string strAppId = "**********"; // Your application ID
string strCountryCode = Environment.SmartHubConfig.Country;
string strSecurityKey = "**********"; // Your security key issued by DPI portal
string strCheckValue = GetCheckValue(strAppId + strCountryCode, strSecurityKey);
int iPageSize = 100;
int iPageNumber = 1;
bool bRet = pIBilling.GetProductsList(strAppId, strCountryCode, iPageSize, iPageNumber, strCheckValue, servertype);
if (bRet)
{
// API call success
}
else
{
// API call fail
}
}
private string GetCheckValue(string strMsg, string strKey)
{
var encoding = new System.Text.ASCIIEncoding();
byte[] byteKey = encoding.GetBytes(strKey);
byte[] dataToHmac = encoding.GetBytes(strMsg);
HMACSHA256 hmac = new HMACSHA256(byteKey);
return Convert.ToBase64String(hmac.ComputeHash(dataToHmac));
}
private void RequestProductListCallbackEvent(object sender, BillingRequestAPICallbackEventArgs e)
{
// Do something after parsing e.Result
JObject ProductListObj = JObject.Parse(e.Result);
JArray jArray = JArray.Parse(ProductListObj.GetValue("ItemDetails").ToString());
ProductInfos = jArray.Select(p => new ProductInfo
{
ItemType = (string)p["ItemType"],
Price = (string)p["Price"],
ItemTitle = (string)p["ItemTitle"],
ItemID = (string)p["ItemID"],
CurrencyID = (string)p["CurrencyID"]
}).ToList();
}
The following tables describe the Products List API parameters. The response data is in JSON format.
Products List API request parameters:
Parameter
Type
Mandatory
Description
"AppID"
String
True
Application ID
"CountryCode"
Country code The country code must be retrieved from the TV.
"PageSize"
Number
False
Requested page size Range: 1~N (maximum 100) Number of products retrieved per page.
"PageNumber"
Requested page number Range: 1~N Each purchase record page has a number of entries equal to the "PageSize" value. To receive the complete purchase record, post Purchase List API requests while increasing the "PageNumber" value, until "EOF" is returned in the "CPResult" parameter.
"CheckValue"
String
True
Security check value Required parameters: "AppID" + "CountryCode"
Subscription information Mandatory for subscription products.
"PaymentCyclePeriod"
String
True
Subscription payment period:
"D": Days
"W": Weeks
"M": Months
"PaymentCycleFrq"
Number
Payment cycle frequency
"PaymentCycle"
Number of payment cycles
Table 4. Products List API response parameters
Verifying Purchases
The Verify Purchase API checks whether a purchase, corresponding to the requested "InvoiceID", was successful.
To call the Verify Purchase API, use the VerifyInvoice() method:
using System;
using Tizen.TV.Service.Billing;
using Tizen.TV.Service.Sso;
using Tizen.TV;
public void Request_Verify_Purchase(string strInvoiceID)
{
BillingPlugin pIBilling = new BillingPlugin();
pIBilling.RequestAPIEventHandler += new BillingRequestAPICallbackEventHandler(RequestVerifyInvoiceCallbackEvent);
string strAppId = "**********"; // Your application ID
strUniqueCustomID = "abc"; // Unique customer ID. "abc" is a one of the example for Unique custom id. you can assign id managed by your service
// strInvoiceID = issued by GetPurchaseList
string strCountryCode = Environment.SmartHubConfig.Country;
bool bRet = pIBilling.VerifyInvoice(m_strAppId, strUniqueCustomID, strInvoiceID, strCountryCode, servertype);
if (bRet)
{
// API call success
}
else
{
// API call fail
}
}
private void RequestVerifyInvoiceCallbackEvent(object sender, BillingRequestAPICallbackEventArgs e)
{
// Do something
}
The following tables describe the Verify Purchase API parameters. The response data is in JSON format.
Verify Purchase API request parameters:
Parameter
Type
Mandatory
Description
"AppID"
String
True
Application ID
"InvoiceID"
Invoice ID
"CustomID"
Unique Customer ID Same value as the "OrderCustomID" parameter for the BuyItem() method.
"CountryCode"
Country code The country code must be retrieved from the TV.
Other message corresponding to the "CPStatus" error code
"AppID"
True
Requested application ID
"InvoiceID"
Requested invoice ID
Table 6. Verify Purchase API response parameters
Applying Products
The Apply Product API supports product management to help guarantee secure sales of your products. Normally, the DPI service is notified that the purchased product has been successfully applied. The Apply Product API is used in situations where purchase result delivery to the application encounters issues and is not successful. For example, if the network connection is interrupted, the application can fail to receive the "payment complete" message, even though the payment was completed. In this situation, the product is not applied to the application. You can check for unapplied products using the "AppliedStatus" parameter of the Purchase List API response and apply the product at that time.
For subscription products, the product is considered applied at the time of purchase and the "AppliedStatus" is set to "true" by default. Consequently, it is not necessary to check whether a subscription product purchase corresponding to the requested "InvoiceID" was successful.
NoteTo avoid applying the same product more than once in error, after 3 failed attempts to request the Apply Product API, wait until the network is reconnected before trying again.
To call the Apply Product API, use the ApplyInvoice() method:
using System;
using Tizen.TV.Service.Billing;
using Tizen.TV.Service.Sso;
using Tizen.TV;
public void Request_Apply_Purchase(string strInvoiceID)
{
BillingPlugin pIBilling = new BillingPlugin();
pIBilling.RequestAPIEventHandler += new BillingRequestAPICallbackEventHandler(RequestApplyInvoiceCallbackEvent);
string strAppId = "**********"; // Your application ID
string strUniqueCustomID = "abc"; // Unique customer ID. "abc" is a one of the example for Unique custom id. you can assign id managed by your service
// strInvoiceID = issued by GetPurchaseList
string strCountryCode = Environment.SmartHubConfig.Country;
bool bRet = pIBilling.ApplyInvoice(strAppId, strUniqueCustomID, strInvoiceID, strCountryCode, servertype); if (bRet)
{
// API call success
}
else
{
// API call fail
}
}
private void RequestApplyInvoiceCallbackEvent(object sender, BillingRequestAPICallbackEventArgs e)
{
// Do something
}
The following tables describe the Apply Product API parameters. The response data is in JSON format.
Apply Product API request parameters:
Parameter
Type
Mandatory
Description
"AppID"
String
True
Application ID
"InvoiceID"
Invoice ID
"CustomID"
Unique Customer ID Same value as the "OrderCustomID" parameter for the BuyItem() method.
"CountryCode"
Country code The country code must be retrieved from the TV.
Other message corresponding to the "CPStatus" error code
"AppliedTime"
True
Time product applied, in 14-digit UTC time, for example, "20140314175900"
Table 8. Apply Product API response parameters
Canceling Subscriptions
You can only use the Subscription Cancel API with subscription products, to request canceling the subscription. The DPI server returns the subscription expiry time and the current subscription status.
To call the Subscription Cancel API, use the CancelSubscription() method:
using System;
using Tizen.TV.Service.Billing;
using Tizen.TV.Service.Sso;
using Tizen.TV;
public void Request_Cancel_Subscription(string strSubscriptionID)
{
BillingPlugin pIBilling = new BillingPlugin();
pIBilling.RequestAPIEventHandler += new BillingRequestAPICallbackEventHandler(RequestCancelSubscriptionCallbackEvent);
string strAppId = "**********"; // Your application ID
string strUniqueCustomID = "abc"; // Unique customer ID. "abc" is a one of the example for Unique custom id. you can assign id managed by your service
// strSubscriptionID = issued by GetPurchaseList
string strCountryCode = Environment.SmartHubConfig.Country;
bool bRet = pIBilling.CancelSubscription(strAppId, strUniqueCustomID, strSubscriptionID, strCountryCode, servertype); if (bRet)
{
// API call success
}
else
{
// API call fail
}
}
private void RequestCancelSubscriptionCallbackEvent(object sender, BillingRequestAPICallbackEventArgs e)
{
// Do something
}
The following tables describe the Subscription Cancel API parameters. The response data is in JSON format.
Subscription Cancel API request parameters:
Parameter
Type
Mandatory
Description
"AppID"
String
True
Application ID
"SubscriptionID"
Subscription ID
"CustomID"
Unique Customer ID Same value as the "OrderCustomID" parameter for the BuyItem() method.
"CountryCode"
Country code The country code must be retrieved from the TV.
"ServerType"
Possible values:
"DEV": Staging zone
"PRD": Operating zone
Table 9. Subscription Cancel API request parameters
Other message corresponding to the "CPStatus" error code
"InvoiceID"
True
Invoice ID
"SubsCancelTime"
False
Time subscription canceled, in 14-digit UTC time, for example, "20140314175900"
"SubsStatus"
Subscription status:
"00": Active
"01": Subscription expired
"02": Canceled by buyer
"03": Canceled for payment failure
"04": Canceled by CP
"05": Canceled by admin
Table 10. Subscription Cancel API response parameters
DPI Result Codes
The following table lists result codes and messages that are returned by the DPI service.
Result Code
Result Message
Description
100000
"SUCCESS"
Additional messages:
"hasNext:TRUE": Product list or purchase history has further pages
"EOF": Last page of the product list or purchase history
"Your Invoice Not Found": No purchase history exists
400111
"AppID not correct"
Requested application ID does not exist
Table 11. DPI result codes and messages
For explanations of additional DPI result codes, at the DPI portal, go to "Help > Error Code".
Purchase API and GUI
When the user wants to make a purchase, authenticate the user and show the common purchase GUI with the BuyItem() method of the Tizen.TV.Service.Billing namespace.
ImportantWhen the BuyItem() method is called, the common purchase GUI is shown in the application automatically. Do not change the purchase GUI appearance until the purchase transaction is complete and the application receives the response.
You can customize the product image in Samsung Checkout by providing the URI to an image on your own content server.
Default image
Product image
Table 12. Display your own product image
To show the common purchase GUI, call the BuyItem() method:
using System.Text;
using System.IO;
using Newtonsoft.Json;
using Tizen.TV.Service.Billing;
using Tizen.TV.Service.Sso;
using Tizen.TV;
public void Request_Buy_Item()
{
BillingPlugin pIBilling = new BillingPlugin();
pIBilling.BuyItemEventHandler += new BillingClientClosedEventHandler(BuyItemCallbackEvent);
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
string appId = "**********"; // Your application ID
string uniqueCustomID = "abc"; // Unique customer ID. "abc" is a one of the example for Unique custom id. you can assign id managed by your service
BillingRequestServerType servertype = GetBillingServerType();
using (JsonWriter writer = new JsonTextWriter(sw))
{
writer.Formatting = Formatting.Indented;
writer.WriteStartObject();
writer.WritePropertyName("OrderTotal");
writer.WriteValue(price); // Issued by GetProductList
writer.WritePropertyName("OrderItemID");
writer.WriteValue(itemID); // Issued by GetProductList
writer.WritePropertyName("OrderTitle");
writer.WriteValue(itemTitle); // Issued by GetProductList
writer.WritePropertyName("OrderCurrencyID");
writer.WriteValue(currencyID); // Issued by GetProductList
writer.WritePropertyName("OrderCustomID");
writer.WriteValue(uniqueCustomID);
writer.WriteEndObject();
}
bool bRet = pIBilling.BuyItem(appId, servertype, sb.ToString());
if (bRet)
{
// API call success
}
else
{
// API call fail
}
}
private void BuyItemCallbackEvent(object sender, BillingClientClosedEventArgs e)
{
// Do something
}
private BillingRequestServerType GetBillingServerType()
{
var tvServerType = Environment.SmartHubConfig.Server;
BillingRequestServerType serverType;
switch (tvServerType)
{
case SmartHubConfig.ServerType.Operating:
serverType = BillingRequestServerType.Prd;
break;
case SmartHubConfig.ServerType.Developement:
serverType = BillingRequestServerType.Dev;
break;
default:
serverType = BillingRequestServerType.Prd;
break;
}
return serverType;
}
The BuyItem() method request and response data are in JSON format:
BuyItem() method request parameters:
Parameter
Type
Mandatory
Description
"AppID"
String
True
Application ID
"PaymentServer"
Possible values:
"DEV": Staging zone
"DUMMY": Staging zone with dummy payment
"PRD": Operating zone
"PaymentDetails"
JSON
Payment details
OrderItemID"
String
True
Purchase item ID, for example, "DP123400000000" "ItemID" issued by the Products List API.
"OrderTitle"
Purchase item title "ItemTitle" issued by the Products List API. The length must not exceed 100 characters.
"OrderTotal"
Total purchase price "Price" issued by the Products List API. When converting the number to string type, pay attention to the unit separators.
"OrderCurrencyID"
Purchase currency unit "CurrencyID" issued by the Products List API.
"OrderID"
False
Management ID for purchases managed by third-party applications
"OrderCustomID"
True
Unique customer ID
"OrderItemPath"
False
Item image URI The image must be in JPEG, JPG, or PNG format.
"DynmcProductID"
True (dynamic products only)
Unique ID for dynamic product from a third-party application
"DynmcProductInfo"
Dynamic product item type, such as rental or permanent purchase
"DynmcShareCategory"
Dynamic product share category
"DynmcTaxCategory"
Dynamic product tax category
"StltAppId"
False
Settlement application ID For Samsung internal use only. Do not use.
Table 13. BuyItem() method request parameters
BuyItem() method response parameters:
Parameter
Type
Mandatory
Description
"payResult"
String
True
Possible values:
“SUCCESS”
“FAILED”
“CANCEL”: Canceled by the user
"payDetail"
JSON
False
Payment details
"InvoiceID"
String
False
Purchased Invoice ID, for example, "DO1904US000007153", this value is only available when payResult is "SUCCESS" otherwise, you will not get any value for "InvoiceID"
Table 14. buyItem() response parameters
Note
"InvoiceID" in payDetail is available since Tizen 5.0
The “Dynamic Product” type is also supported on Samsung Checkout.
For more information on offering dynamic products in your application, contact a Samsung representative by going to "Samsung Apps TV Seller Office > Support" and creating a "1:1 Q&A" support ticket.
Country and Currency Codes
The following table lists countries with their corresponding country code, currency, and currency code.
Country Name
Country Code
Currency
Currency Code
Aland Islands
AX
Euro
EUR
Argentina
AR
Argentine peso
ARS
Australia
AU
Australian dollar
AUD
Austria
AT
Euro
EUR
Belgium
BE
Euro
EUR
Brazil
BR
Brazilian real
BRL
Bulgaria
BG
Bulgarian lev
BGN
Canada
CA
Canadian dollar
CAD
Chile
CL
Chilean peso
CLP
Colombia
CO
Colombian peso
COP
Croatia
HR
Croatian kuna
HRK
Czech Republic
CZ
Czech koruna
CZK
Denmark
DK
Danish krone
DKK
Estonia
EE
Euro
EUR
Faroe Islands
FO
Danish krone
DKK
Finland
FI
Euro
EUR
France
FR
Euro
EUR
Germany
DE
Euro
EUR
Greece
GR
Euro
EUR
Greenland
GL
Danish krone
DKK
Guatemala
GT
Guatemalan quetzal
GTQ
Guernsey
GG
British pound
GBP
Hong Kong
HK
Hong Kong dollar
HKD
Hungary
HU
Hungarian forint
HUF
India
IN
Indian rupee
INR
Indonesia
ID
Indonesian rupiah
IDR
Ireland
IE
Euro
EUR
Isle of Man
IM
British pound
GBP
Israel
IL
Israeli shekel
ILS
Italy
IT
Euro
EUR
Jersey
JE
British pound
GBP
Jordan
JO
Jordanian dinar
JOD
Kazakhstan
KZ
Kazakhstani tenge
KZT
Korea, Republic of
KR
South Korean won
KRW
Latvia
LV
Euro
EUR
Lithuania
LT
Euro
EUR
Luxembourg
LU
Euro
EUR
Malaysia
MY
Malaysian ringgit
MYR
Mexico
MX
Mexican peso
MXN
Netherlands
NL
Euro
EUR
New Zealand
NZ
New Zealand dollar
NZD
Norway
NO
Norwegian krone
NOK
Panama
PA
US dollar
USD
Peru
PE
Peruvian sol
PEN
Philippines
PH
Philippine peso
PHP
Poland
PL
Polish zloty
PLN
Portugal
PT
Euro
EUR
Romania
RO
Euro
EUR
Russia
RU
Russian ruble
RUB
Saudi Arabia
SA
Saudi riyal
SAR
Singapore
SG
Singapore dollar
SGD
Slovakia
SK
Euro
EUR
Slovenia
SI
Euro
EUR
South Africa
ZA
South African rand
ZAR
Spain
ES
Euro
EUR
Sweden
SE
Swedish krona
SEK
Switzerland
CH
Swiss franc
CHF
Taiwan
TW
New Taiwan dollar
TWD
Thailand
TH
Thai baht
THB
Turkey
TR
Turkish lira
TRY
United Arab Emirates
AE
Emiriti dirham
AED
Ukraine
UA
Ukrainian hryvnia
UAH
United Kingdom
GB
British pound
GBP
United States of America
US
US dollar
USD
Vietnam
VN
Vietnamese dong
VND
Table 15. Country and currency codes
Manage Your Cookies
We use cookies to improve your experience on our website and to show you relevant
advertising. Manage you settings for our cookies below.
Essential Cookies
These cookies are essential as they enable you to move around the website. This
category cannot be disabled.
Company
Domain
Samsung Electronics
.samsungdeveloperconference.com
Analytical/Performance Cookies
These cookies collect information about how you use our website. for example which
pages you visit most often. All information these cookies collect is used to improve
how the website works.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Functionality Cookies
These cookies allow our website to remember choices you make (such as your user name, language or the region your are in) and
tailor the website to provide enhanced features and content for you.
Company
Domain
LinkedIn
.ads.linkedin.com, .linkedin.com
Advertising Cookies
These cookies gather information about your browser habits. They remember that
you've visited our website and share this information with other organizations such
as advertisers.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Preferences Submitted
You have successfully updated your cookie preferences.