Skip to content

Commit

Permalink
ads-identifier: Add most of the server side logic
Browse files Browse the repository at this point in the history
Except we don't persist, state is not shared accross apps and tracking is set to limited by default
  • Loading branch information
mar-v-in committed Aug 17, 2023
1 parent e6a443a commit e73704f
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 16 deletions.
4 changes: 4 additions & 0 deletions play-services-ads-identifier/core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,8 @@ android {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}

lintOptions {
disable 'MissingTranslation'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,134 @@
package org.microg.gms.ads.identifier

import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Binder
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import androidx.core.os.bundleOf
import com.google.android.gms.ads.identifier.internal.IAdvertisingIdService
import org.microg.gms.common.PackageUtils
import java.util.UUID

const val TAG = "AdvertisingId"
const val EMPTY_AD_ID = "00000000-0000-0000-0000-000000000000"

class AdvertisingIdService : Service() {
override fun onBind(intent: Intent): IBinder? {
return AdvertisingIdServiceImpl().asBinder()
return AdvertisingIdServiceImpl(this).asBinder()
}
}

class MemoryAdvertisingIdConfiguration(context: Context) : AdvertisingIdConfiguration(context) {
override val adTrackingLimitedPerApp: MutableMap<Int, Boolean> = hashMapOf()
override var adTrackingLimitedGlobally: Boolean = true
override var debugLogging: Boolean = false
override var adId: String = EMPTY_AD_ID
override var debugAdId: String = EMPTY_AD_ID

init {
resetAdvertisingId()
}
}

abstract class AdvertisingIdConfiguration(private val context: Context) {
abstract val adTrackingLimitedPerApp: MutableMap<Int, Boolean>
abstract var adTrackingLimitedGlobally: Boolean
abstract var debugLogging: Boolean
abstract var adId: String
abstract var debugAdId: String

fun isAdTrackingLimitedForApp(uid: Int): Boolean {
if (adTrackingLimitedGlobally) return true
return adTrackingLimitedPerApp[uid] ?: false
}

fun resetAdvertisingId(): String {
adId = UUID.randomUUID().toString()
debugAdId = UUID.randomUUID().toString().dropLast(12) + "10ca1ad1abe1"
return if (debugLogging) debugAdId else adId
}

fun getAdvertisingIdForApp(uid: Int): String {
if (isAdTrackingLimitedForApp(uid)) return EMPTY_AD_ID
try {
val packageNames = context.packageManager.getPackagesForUid(uid) ?: return EMPTY_AD_ID
for (packageName in packageNames) {
val applicationInfo = context.packageManager.getApplicationInfo(packageName, 0)
if (applicationInfo.targetSdkVersion > 33) {
if (context.packageManager.checkPermission("com.google.android.gms.permission.AD_ID", packageName) == PackageManager.PERMISSION_DENIED) {
throw SecurityException("Permission not granted")
}
}
}
} catch (e: Exception) {
Log.w(TAG, "Permission check failed", e)
return EMPTY_AD_ID
}
val adId = if (debugLogging) debugAdId else adId
return adId.ifEmpty { resetAdvertisingId() }
}
}

class AdvertisingIdServiceImpl : IAdvertisingIdService.Stub() {
class AdvertisingIdServiceImpl(private val context: Context) : IAdvertisingIdService.Stub() {
private val configuration = MemoryAdvertisingIdConfiguration(context)

override fun getAdvertisingId(): String {
return "00000000-0000-0000-0000-000000000000"
return configuration.getAdvertisingIdForApp(Binder.getCallingUid())
}

override fun isAdTrackingLimited(ignored: Boolean): Boolean {
return configuration.isAdTrackingLimitedForApp(Binder.getCallingUid())
}

override fun resetAdvertisingId(packageName: String): String {
PackageUtils.checkPackageUid(context, packageName, getCallingUid())
PackageUtils.assertExtendedAccess(context)
return configuration.resetAdvertisingId()
}

override fun setAdTrackingLimitedGlobally(packageName: String, limited: Boolean) {
PackageUtils.checkPackageUid(context, packageName, getCallingUid())
PackageUtils.assertExtendedAccess(context)
configuration.adTrackingLimitedGlobally = limited
}

override fun setDebugLoggingEnabled(packageName: String, enabled: Boolean): String {
PackageUtils.checkPackageUid(context, packageName, getCallingUid())
PackageUtils.assertExtendedAccess(context)
configuration.debugLogging = enabled
return advertisingId
}

override fun isDebugLoggingEnabled(): Boolean {
return configuration.debugLogging
}

override fun isAdTrackingLimitedGlobally(): Boolean {
PackageUtils.assertExtendedAccess(context)
return configuration.adTrackingLimitedGlobally
}

override fun setAdTrackingLimitedForApp(uid: Int, limited: Boolean) {
PackageUtils.assertExtendedAccess(context)
configuration.adTrackingLimitedPerApp[uid] = limited
}

override fun isAdTrackingLimited(defaultHint: Boolean): Boolean {
return true
override fun resetAdTrackingLimitedForApp(uid: Int) {
PackageUtils.assertExtendedAccess(context)
configuration.adTrackingLimitedPerApp.remove(uid)
}

override fun generateAdvertisingId(packageName: String): String {
return advertisingId // Ad tracking limited
override fun getAllAppsLimitedAdTrackingConfiguration(): Bundle {
PackageUtils.assertExtendedAccess(context)
return bundleOf(*configuration.adTrackingLimitedPerApp.map { it.key.toString() to it.value }.toTypedArray())
}

override fun setAdTrackingLimited(packageName: String, limited: Boolean) {
// Ignored, sorry :)
override fun getAdvertisingIdForApp(uid: Int): String {
PackageUtils.assertExtendedAccess(context)
return configuration.getAdvertisingIdForApp(uid)
}
}
11 changes: 11 additions & 0 deletions play-services-ads-identifier/core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ SPDX-FileCopyrightText: 2023 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->

<resources>
<string name="perm_ad_id_label">Advertising ID Permission</string>
<string name="perm_ad_id_description">Allows a publisher app to access a valid advertising ID directly or indirectly.</string>
<string name="perm_ad_id_notification_label">Advertising ID notification</string>
<string name="perm_ad_id_notification_description">Allows an app to receive a notification when the advertising ID or limit ad tracking preference of the user is updated.</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
package com.google.android.gms.ads.identifier.internal;

import android.os.Bundle;

interface IAdvertisingIdService {
String getAdvertisingId() = 0;
boolean isAdTrackingLimited(boolean defaultHint) = 1;
String generateAdvertisingId(String packageName) = 2;
void setAdTrackingLimited(String packageName, boolean limited) = 3;
boolean isAdTrackingLimited(boolean ignored) = 1;
String resetAdvertisingId(String packageName) = 2;
void setAdTrackingLimitedGlobally(String packageName, boolean limited) = 3;
String setDebugLoggingEnabled(String packageName, boolean enabled) = 4;
boolean isDebugLoggingEnabled() = 5;
boolean isAdTrackingLimitedGlobally() = 6;
void setAdTrackingLimitedForApp(int uid, boolean limited) = 7;
void resetAdTrackingLimitedForApp(int uid) = 8;
Bundle getAllAppsLimitedAdTrackingConfiguration() = 9; // Map packageName -> Boolean
String getAdvertisingIdForApp(int uid) = 10;
}
43 changes: 39 additions & 4 deletions play-services-core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2013-2019 microG Project Team
~
~ Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -59,6 +58,17 @@
android:label="@string/permission_service_writely_label"
android:protectionLevel="dangerous" />

<permission
android:name="com.google.android.gms.permission.AD_ID"
android:label="@string/perm_ad_id_label"
android:description="@string/perm_ad_id_description"
android:protectionLevel="normal" />
<permission
android:name="com.google.android.gms.permission.AD_ID_NOTIFICATION"
android:label="@string/perm_ad_id_notification_label"
android:description="@string/perm_ad_id_notification_description"
android:protectionLevel="normal" />

<permission
android:name="org.microg.gms.STATUS_BROADCAST"
android:label="@string/perm_status_broadcast_label"
Expand Down Expand Up @@ -161,8 +171,7 @@
</intent-filter>
</service>

<service
android:name="org.microg.gms.wearable.location.WearableLocationService">
<service android:name="org.microg.gms.wearable.location.WearableLocationService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
Expand Down Expand Up @@ -576,6 +585,32 @@
</intent-filter>
</service>

<!-- Help -->

<service
android:name="org.microg.gms.googlehelp.GoogleHelpService"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.googlehelp.service.GoogleHelpService.START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>

<activity
android:name="org.microg.gms.googlehelp.ui.GoogleHelpRedirectActivity"
android:process=":ui"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.googlehelp.HELP" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>

<!-- Other -->

<service
Expand Down

0 comments on commit e73704f

Please sign in to comment.