Project Flight is a sample project that combines the privacy-preserving APIs of the Privacy Sandbox on Android to demonstrate how they can be used together in end-to-end customer journeys.
Project Flight includes five components:
- Publisher app
- A sample app that represents a publisher in the advertising flow. This example publisher is a news app that shows an ad when the user scrolls through the content.
- Advertiser app
- A sample app that represents the advertiser in the advertising flow. This example advertiser is a travel app, selling experiences such as flights and hotels to various destinations.
- SSP module
- This module represents an SSP SDK in the advertising flow. This module calls
registerSource()
for measurement, and runs ad selection from the Publisher app based on the Custom Audiences joined by the user.
- This module represents an SSP SDK in the advertising flow. This module calls
- MMP module
- This MMP represents an MMP SDK in the advertising flow. The module registers triggers for measurement and handles joining custom audiences inside of the advertiser app.
- Firebase hosting specs
- To represent the ad tech backend in the advertising flow, these files can be used to run a local server and store the static files with Firebase Hosting.
System requirements:
- Android Studio Giraffe | 2022.3.1 RC 1 or higher
- Gradle 8.1 or higher
- An emulator or physical Pixel device running an API 34-ext12 or higher system image with Play Store enabled.
To use the functionality of the Protected Audiences and Attribution Reporting APIs, you need to have server endpoints set up to receive calls from the Flight client apps. There are existing resources for setting up Protected Audience servers and Attribution Reporting servers using Open API specs or mock servers. Project Flight demonstrates how to use Firebase for hosting the server.
To set up your Firebase server, there are two different configuration options provided in the "Firebase-Backend" folder: The first option only uses the Firebase "Hosting" functionality, and the second has "Functions" enabled. The difference between these two is that by using the hosting-only setup (inside the "Without-Functions" folder) you can deploy the full Firebase server without having to upgrade to a Blaze pay-as-you-go plan for Firebase. However, you also will be unable to view the body of aggregate and event reports sent to server endpoints with this setup. The "Functions-Enabled" folder contains a Firebase server configuration which uses the Firebase Functions product, enabling the report content to be viewed in full by calling a function to log the body on receipt.
Note: the Firebase Blaze plan is pay-as-you-go, and setup using the "Functions-Enabled" configuration will still be free so long as Firebase monthly usage limits are adhered to. Learn more about billing plans.
- To begin, follow the instructions for Getting Started with Firebase
Hosting. When given the option to select a local directory for
your firebase project, select either the "Without-Functions" or
"Functions-Enabled" folder inside of the
Firebase-Backend
directory of the repository you've just cloned. - Once you have your Firebase project set up and your desired configuration designated as your local reference for that project, deploy your server according to the instructions on that doc. You should now have your server endpoints for Attribution and Protected Audiences available to be called from the client app. For support in using Firebase Functions, documentation is available from the Firebase team to help with getting started and expanding the available functionality.
- Replace the
topLevelDomain
variables inside of the project code to match the URL you've now created for your Firebase project. This variable is present in two places:- Inside of the SspSdKImpl.kt file in the
SspSdk
project. - Inside of the MmpSdkImpl.kt file in the
MmpSdk
project. - If you want to point to a different server for Attribution (such as one
that has already been set up and enrolled for testing the measurement
sample app, you can do so by replacing the following variables:
registerSourceUrl
inside of SspSdkImpl.ktregisterTriggerUrl
inside of MmpSdkImpl.kt
- Inside of the SspSdKImpl.kt file in the
- To monitor calls being sent to the Firebase server, go to https://console.cloud.google.com/logs/ and select your project. If you are using the "Without-Functions" version of the setup, when receiving event and aggregate reports you will not be able to view the content of the reports, but you will still see the calls being sent to the reporting endpoints on the server.
Open up the AdvertiserApp or PublisherApp projects in Android Studio and start your emulator. Follow these instructions to set up your emulator to run the project.
First, toggle the Privacy Sandbox APIs to "On" in Settings. You can navigate to the correct screen with this command:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity
Next, set permissions. These permissions should be set every time you run the project, even if you have set them before. To set these permissions, run the following commands:
adb shell device_config set_sync_disabled_for_tests persistent
adb shell device_config put adservices ppapi_app_signature_allow_list \"\*\"
adb shell device_config put adservices ppapi_app_allow_list \"\*\"
adb shell device_config put adservices adservice_system_service_enabled true
adb shell device_config put adservices adservice_enabled true
adb shell device_config put adservices adservice_enable_status true
adb shell device_config put adservices global_kill_switch false
adb shell device_config put adservices measurement_kill_switch false
adb shell device_config put adservices fledge_js_isolate_enforce_max_heap_size false
adb shell device_config put adservices fledge_custom_audience_service_kill_switch false
adb shell device_config put adservices fledge_select_ads_kill_switch false
adb shell device_config put adservices adid_kill_switch false
adb shell device_config put adservices fledge_register_ad_beacon_enabled true
adb shell device_config put adservices fledge_measurement_report_and_register_event_api_enabled true
You can copy and paste the entire block of commands above into your terminal and they will each execute in turn.
For local testing of this project, we recommend turning off enrollment. You can turn off enrollment for Protected Audience and Attribution Reporting APIs with these commands:
adb shell device_config put adservices disable_fledge_enrollment_check true
adb shell device_config put adservices disable_measurement_enrollment_check true
If you have run these commands and are getting enrollment-related errors, make sure you have at least the API 34-ext12 system image installed on Android Studio. You can check for this by opening Tools > SDK Manager, and looking at the "API Level" column to find an Android SDK Platform and Google Play System Image at least at the API 34-ext12 level. Check the boxes next to the Android SDK Platform and Google Play System Image and then click the "Apply" button at the bottom right corner of the SDK manager. Then try creating a new emulator with at least API 34-ext12 and running the project setup steps again.
For production testing, you must enroll your site URL
to use Protected Audiences (e.g. https://example.com
) and your source and
trigger URLs to use Attribution Reporting (e.g.
https://example.com/register_source
). Read the enrollment
documentation to begin the enrollment process.
- Open the AdvertiserApp project.
- Click either "Athens", "Berlin", or "Cairo" to add you to a custom audience for the given location. (Clicking Delhi will not add you to a custom audience.)
- Open the PublisherApp project
- See the ad for the place you chose appear
-
Make sure an ad is showing by following the steps in the prior "Select and show an Ad" section. You can't attribute an ad that isn't shown.
-
Open PublisherApp, and click on the ad that is shown. You will see a toast appear that indicates if the source registration was successful.
-
Open AdvertiserApp, and navigate to a product detail page (e.g. click the button that says "Athens")
-
Click the "Book Now" button. You will see a toast appear that will indicate if the trigger registration was successful.
-
Run the job to record the source and trigger registrations on device
adb shell cmd jobscheduler run -f com.google.android.adservices.api 20
-
Force the AttributionJobService
adb shell cmd jobscheduler run -f com.google.android.adservices.api 5
-
On your device, open the time and date settings. Disable automatic time and date. Then, set the date to three days forward.
-
Force the ReportingJobService to send Event Level and Aggregate reports
adb shell cmd jobscheduler run -f com.google.android.adservices.api 3
adb shell cmd jobscheduler run -f com.google.android.adservices.api 7
-
Check the server logs to verify receipt of Event Level and Aggregate reports. Note: If you are using the "Functions" Firebase setup, you will be able to see the content of the reports in the logs. If you are using "Without-Functions," you will be able to verify receipt of the reports, but not be able to see their contents.
To help with debugging, you can enable more verbose logging for the Privacy Sandbox modules with the following commands:
adb shell setprop log.tag.adservices VERBOSE
adb shell setprop log.tag.adservices.fledge VERBOSE
adb shell setprop log.tag.adservices.measurement VERBOSE
You can then filter logcat by adservices
to see Privacy Sandbox related issues.