From 062b755f5b5856040917f4845c74563b279b424f Mon Sep 17 00:00:00 2001 From: Felix Bechstein Date: Tue, 22 May 2018 21:26:23 +0200 Subject: [PATCH] get consent for EEA ad requests --- CHANGELOG.md | 3 + PRIVACY.md | 2 +- SMSdroid/build.gradle | 11 +- .../ub0r/android/smsdroid/ConsentManager.java | 126 ++++++++++++++++++ .../smsdroid/ConversationListActivity.java | 10 +- .../android/smsdroid/MessageListActivity.java | 7 +- 6 files changed, 146 insertions(+), 13 deletions(-) create mode 100644 SMSdroid/src/main/java/de/ub0r/android/smsdroid/ConsentManager.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 08d1276..96c5bea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changes +## 1.7.3 +* GDPR compliance + ## 1.7.2 * bug fixes diff --git a/PRIVACY.md b/PRIVACY.md index 23e2afb..3780961 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -1,6 +1,6 @@ # SMSdroid Privacy Policy -This Privacy Policy was last modified on 19.09.2015. +This Privacy Policy was last modified on 22.05.2018. ub0r.de / Felix Bechstein ("us", "we", or "our") operates the SMSdroid App (the "App"). This page informs you of our policies regarding the collection, diff --git a/SMSdroid/build.gradle b/SMSdroid/build.gradle index cd6e966..2c0ed1a 100644 --- a/SMSdroid/build.gradle +++ b/SMSdroid/build.gradle @@ -18,12 +18,12 @@ repositories { } android { - compileSdkVersion 25 + compileSdkVersion 26 buildToolsVersion '27.0.3' defaultConfig { minSdkVersion 14 - targetSdkVersion 25 + targetSdkVersion 26 versionCode 141720000 versionName "1.7.2" } @@ -67,9 +67,10 @@ android { } dependencies { - implementation 'com.android.support:support-v4:25.4.0' - implementation 'com.android.support:appcompat-v7:25.4.0' - implementation 'com.google.android.gms:play-services-ads:10.2.6' + implementation 'com.android.support:support-v4:26.1.0' + implementation 'com.android.support:appcompat-v7:26.1.0' + implementation 'com.google.android.gms:play-services-ads:15.0.1' implementation 'de.ub0r.android.lib:lib:1.1.1' implementation 'de.ub0r.android.logg0r:logg0r:2.0.0' + implementation 'com.google.android.ads.consent:consent-library:1.0.1' } diff --git a/SMSdroid/src/main/java/de/ub0r/android/smsdroid/ConsentManager.java b/SMSdroid/src/main/java/de/ub0r/android/smsdroid/ConsentManager.java new file mode 100644 index 0000000..1692882 --- /dev/null +++ b/SMSdroid/src/main/java/de/ub0r/android/smsdroid/ConsentManager.java @@ -0,0 +1,126 @@ +package de.ub0r.android.smsdroid; + +import android.app.Activity; +import android.content.Intent; + +import com.google.ads.consent.ConsentForm; +import com.google.ads.consent.ConsentFormListener; +import com.google.ads.consent.ConsentInfoUpdateListener; +import com.google.ads.consent.ConsentInformation; +import com.google.ads.consent.ConsentStatus; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Calendar; + +import de.ub0r.android.lib.DonationHelper; +import de.ub0r.android.logg0r.Log; + +public class ConsentManager { + + private static final String TAG = "ConsentManager"; + private static final String ADMOB_PUBLISHER_ID = "pub-1948477123608376"; + private static final String PRIVACY_URL = "https://github.com/felixb/smsdroid/blob/master/PRIVACY.md"; + + private final Activity mActivity; + private ConsentForm mForm; + + public ConsentManager(final Activity activity) { + mActivity = activity; + + } + + public void updateConsent() { + if (!DonationHelper.hideAds(mActivity)) { + ConsentInformation consentInformation = ConsentInformation.getInstance(mActivity); + String[] publisherIds = {ADMOB_PUBLISHER_ID}; + consentInformation.requestConsentInfoUpdate(publisherIds, new ConsentInfoUpdateListener() { + @Override + public void onConsentInfoUpdated(final ConsentStatus consentStatus) { + Log.i(TAG, "updated consent status: ", consentStatus.toString()); + checkConsentForAds(); + } + + @Override + public void onFailedToUpdateConsentInfo(final String errorDescription) { + Log.e(TAG, "failed to update consent info: ", errorDescription); + } + }); + } + } + + public boolean showAds() { + return !DonationHelper.hideAds(mActivity) && checkConsentForAds(); + } + + private boolean checkConsentForAds() { + final ConsentInformation consentInformation = ConsentInformation.getInstance(mActivity); + if (!consentInformation.isRequestLocationInEeaOrUnknown()) { + // user is outside EEA + Log.d(TAG, "User is outseide EEA"); + return true; + } + + final Calendar now = Calendar.getInstance(); + final Calendar gdprDeadline = Calendar.getInstance(); + gdprDeadline.set(2018, 5, 25, 0, 0, 0); + + if (now.before(gdprDeadline)) { + Log.d(TAG, "Before GDPR deadline"); + return true; + } + + if (ConsentStatus.UNKNOWN.equals(consentInformation.getConsentStatus())) { + Log.d(TAG, "Need to ask for consent"); + // we need to ask for consent + askForConsent(); + return false; + } + + return true; + } + + private void askForConsent() { + URL privacyUrl = null; + try { + privacyUrl = new URL(PRIVACY_URL); + } catch (MalformedURLException e) { + Log.e(TAG, "Error parsing privacy url", e); + mActivity.finish(); + } + mForm = new ConsentForm.Builder(mActivity, privacyUrl) + .withListener(new ConsentFormListener() { + @Override + public void onConsentFormLoaded() { + Log.d(TAG, "onConsentFormLoaded"); + mForm.show(); + } + + @Override + public void onConsentFormOpened() { + Log.d(TAG, "onConsentFormOpened"); + } + + @Override + public void onConsentFormClosed(final ConsentStatus consentStatus, final Boolean userPrefersAdFree) { + Log.d(TAG, "onConsentFormClosed(", consentStatus, userPrefersAdFree, ")"); + if (userPrefersAdFree) { + Intent i = new Intent(Intent.ACTION_VIEW, DonationHelper.DONATOR_URI); + mActivity.startActivity(i); + } else if (ConsentStatus.UNKNOWN.equals(consentStatus)) { + mActivity.finish(); + } + } + + @Override + public void onConsentFormError(final String errorDescription) { + Log.e(TAG, "error showing consent form: ", errorDescription); + } + }) + .withPersonalizedAdsOption() + .withAdFreeOption() + .build(); + mForm.load(); + mForm.show(); + } +} diff --git a/SMSdroid/src/main/java/de/ub0r/android/smsdroid/ConversationListActivity.java b/SMSdroid/src/main/java/de/ub0r/android/smsdroid/ConversationListActivity.java index b3d9ebf..61c2012 100644 --- a/SMSdroid/src/main/java/de/ub0r/android/smsdroid/ConversationListActivity.java +++ b/SMSdroid/src/main/java/de/ub0r/android/smsdroid/ConversationListActivity.java @@ -1,18 +1,18 @@ /* * Copyright (C) 2009-2015 Felix Bechstein - * + * * This file is part of SMSdroid. - * + * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 3 of the License, or (at your option) any later * version. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. - * + * * You should have received a copy of the GNU General Public License along with * this program; If not, see . */ @@ -282,6 +282,8 @@ public void onCreate(final Bundle savedInstanceState) { setContentView(R.layout.conversationlist); } + new ConsentManager(this).updateConsent(); + // debug info showRows(this); diff --git a/SMSdroid/src/main/java/de/ub0r/android/smsdroid/MessageListActivity.java b/SMSdroid/src/main/java/de/ub0r/android/smsdroid/MessageListActivity.java index 83862b6..d3d49d1 100644 --- a/SMSdroid/src/main/java/de/ub0r/android/smsdroid/MessageListActivity.java +++ b/SMSdroid/src/main/java/de/ub0r/android/smsdroid/MessageListActivity.java @@ -62,7 +62,6 @@ import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdView; -import de.ub0r.android.lib.DonationHelper; import de.ub0r.android.lib.Utils; import de.ub0r.android.lib.apis.Contact; import de.ub0r.android.lib.apis.ContactsWrapper; @@ -285,9 +284,11 @@ public final void onCreate(final Bundle savedInstanceState) { longItemClickDialog[WHICH_VIEW_DETAILS] = getString(R.string.view_details_); longItemClickDialog[WHICH_DELETE] = getString(R.string.delete_message_); - mAdView = (AdView) findViewById(R.id.ads); + mAdView = findViewById(R.id.ads); mAdView.setVisibility(View.GONE); - if (!DonationHelper.hideAds(this)) { + ConsentManager cm = new ConsentManager(this); + cm.updateConsent(); + if (cm.showAds()) { mAdView.loadAd(new AdRequest.Builder().build()); mAdView.setAdListener(new AdListener() { @Override