Get consent for ads to comply with the GDPR. https://redmine.stoutner.com/issues/278
authorSoren Stoutner <soren@stoutner.com>
Tue, 22 May 2018 20:53:34 +0000 (13:53 -0700)
committerSoren Stoutner <soren@stoutner.com>
Tue, 22 May 2018 20:53:34 +0000 (13:53 -0700)
38 files changed:
.idea/dictionaries/soren.xml
app/build.gradle
app/src/free/assets/de/about_privacy_policy_dark.html
app/src/free/assets/de/about_privacy_policy_light.html
app/src/free/assets/en/about_privacy_policy_dark.html
app/src/free/assets/en/about_privacy_policy_light.html
app/src/free/assets/es/about_privacy_policy_dark.html
app/src/free/assets/es/about_privacy_policy_light.html
app/src/free/assets/it/about_privacy_policy_dark.html
app/src/free/assets/it/about_privacy_policy_light.html
app/src/free/assets/ru/about_privacy_policy_dark.html
app/src/free/assets/ru/about_privacy_policy_light.html
app/src/free/java/com/stoutner/privacybrowser/BannerAd.java [deleted file]
app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java [new file with mode: 0644]
app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java [new file with mode: 0644]
app/src/free/res/values/strings.xml
app/src/main/assets/de/guide_tracking_ids_dark.html
app/src/main/assets/de/guide_tracking_ids_light.html
app/src/main/assets/de/images/advertising_id.png [deleted file]
app/src/main/assets/en/guide_tracking_ids_dark.html
app/src/main/assets/en/guide_tracking_ids_light.html
app/src/main/assets/en/images/advertising_id.png [deleted file]
app/src/main/assets/es/guide_tracking_ids_dark.html
app/src/main/assets/es/guide_tracking_ids_light.html
app/src/main/assets/es/images/advertising_id.png [deleted file]
app/src/main/assets/it/guide_tracking_ids_dark.html
app/src/main/assets/it/guide_tracking_ids_light.html
app/src/main/assets/it/images/advertising_id.png [deleted file]
app/src/main/assets/ru/guide_tracking_ids_dark.html
app/src/main/assets/ru/guide_tracking_ids_light.html
app/src/main/assets/ru/images/advertising_id.png [deleted file]
app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java
app/src/main/res/menu/webview_options_menu.xml
app/src/main/res/values/strings.xml
app/src/standard/java/com/stoutner/privacybrowser/BannerAd.java [deleted file]
app/src/standard/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java [new file with mode: 0644]
app/src/standard/java/com/stoutner/privacybrowser/helpers/AdHelper.java [new file with mode: 0644]

index 26e198d..57f6549 100644 (file)
@@ -63,6 +63,7 @@
       <w>fontsize</w>
       <w>framelayout</w>
       <w>freitas</w>
+      <w>gdpr</w>
       <w>gerlach</w>
       <w>gitweb</w>
       <w>googleplay</w>
       <w>referer</w>
       <w>refreshlayout</w>
       <w>relativelayout</w>
+      <w>remarketing</w>
       <w>requery</w>
       <w>roadmap</w>
       <w>robinlinus</w>
index 85c0ba7..fdd6ec3 100644 (file)
@@ -67,11 +67,10 @@ android {
 dependencies {
     implementation fileTree(include: ['*.jar'], dir: 'libs')
     implementation 'com.android.support:design:27.0.2'
-    // Only compile `com.google.firebase:firebase-ads` for the free flavor.
+
+    // Only compile Firebase ads for the free flavor.
     freeImplementation 'com.google.firebase:firebase-ads:15.0.1'
-}
 
-// Google's documentation says the following line is required for `firebase-ads` but things work correctly without it.
-// I have no interest in applying the Google Mobile Services plugin in the standard flavor if I don't have to.
-// I suspect that in the free flavor `firebase-ads` applies it even when not specified.  <https://firebase.google.com/docs/admob/android/quick-start>.
-// apply plugin: 'com.google.gms.google-services'
\ No newline at end of file
+    // Only compile the consent library for the free flavor.  It is used to comply with the GDPR in Europe.
+    freeImplementation 'com.google.android.ads.consent:consent-library:1.0.0'
+}
\ No newline at end of file
index 3570de8..5fb1977 100644 (file)
@@ -78,8 +78,8 @@
 
         <h3>Advertisements</h3>
         <p>Privacy Browser Free displays a banner ad across the bottom of the screen using Google's AdMob network, which has its <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
-            Note that unless you have <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">opted out of interest-based ads</a>,
-            the advertiser will receive a copy of your unique device advertising ID, which allows them to track your device across apps.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob reports <em>anonymized summaries</em> of the following information to developers.</p>
         <ul>
             <li><item>Total impressions</item></li>
@@ -98,6 +98,6 @@
             <strong class="red">Stoutner will never sell this information nor transfer it to any third party that would use it for advertising or marketing.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Revision 1.5, 11 January 2018</em></p>
+        <p style="text-align: center;"><em>Revision 1.6, 22. Mai 2018</em></p>
     </body>
 </html>
\ No newline at end of file
index 55b9f04..64766e7 100644 (file)
@@ -78,8 +78,8 @@
 
         <h3>Advertisements</h3>
         <p>Privacy Browser Free displays a banner ad across the bottom of the screen using Google's AdMob network, which has its <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
-            Note that unless you have <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">opted out of interest-based ads</a>,
-            the advertiser will receive a copy of your unique device advertising ID, which allows them to track your device across apps.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob reports <em>anonymized summaries</em> of the following information to developers.</p>
         <ul>
             <li><item>Total impressions</item></li>
@@ -98,6 +98,6 @@
             <strong class="red">Stoutner will never sell this information nor transfer it to any third party that would use it for advertising or marketing.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Revision 1.5, 11 January 2018</em></p>
+        <p style="text-align: center;"><em>Revision 1.6, 22. Mai 2018</em></p>
     </body>
 </html>
\ No newline at end of file
index 3570de8..ba65e85 100644 (file)
 
 
         <h3>Advertisements</h3>
-        <p>Privacy Browser Free displays a banner ad across the bottom of the screen using Google's AdMob network, which has its <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
-            Note that unless you have <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">opted out of interest-based ads</a>,
-            the advertiser will receive a copy of your unique device advertising ID, which allows them to track your device across apps.
+        <p>Privacy Browser Free displays a banner ad across the bottom of the screen using Google's AdMob network,
+            which has its <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob reports <em>anonymized summaries</em> of the following information to developers.</p>
         <ul>
             <li><item>Total impressions</item></li>
@@ -98,6 +99,6 @@
             <strong class="red">Stoutner will never sell this information nor transfer it to any third party that would use it for advertising or marketing.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Revision 1.5, 11 January 2018</em></p>
+        <p style="text-align: center;"><em>Revision 1.6, 22 May 2018</em></p>
     </body>
 </html>
\ No newline at end of file
index ff0cbdc..a5a17aa 100644 (file)
 
 
         <h3>Advertisements</h3>
-        <p>Privacy Browser Free displays a banner ad across the bottom of the screen using Google's AdMob network, which has its <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
-            Note that unless you have <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">opted out of interest-based ads</a>,
-            the advertiser will receive a copy of your unique device advertising ID, which allows them to track your device across apps.
+        <p>Privacy Browser Free displays a banner ad across the bottom of the screen using Google's AdMob network,
+            which has its <a href="https://www.google.com/intl/en/policies/privacy/">own privacy policy</a>.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob reports <em>anonymized summaries</em> of the following information to developers.</p>
         <ul>
             <li><item>Total impressions</item></li>
@@ -98,6 +99,6 @@
             <strong class="red">Stoutner will never sell this information nor transfer it to any third party that would use it for advertising or marketing.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Revision 1.4, 11 January 2018</em></p>
+        <p style="text-align: center;"><em>Revision 1.6, 22 May 2018</em></p>
     </body>
 </html>
\ No newline at end of file
index dad0eb3..e4d4b2a 100644 (file)
@@ -59,7 +59,8 @@
 
         <h3>Comentarios de Google Play</h3>
         <p>Google Play tiene su <a href="https://www.google.com/intl/en/policies/privacy/">propia política de privacidad</a>.
-            Además del nombre del comentador, la calificación y el texto del comentario (las cuales están disponibles públicamente), Google proporciona alguna o toda la siguiente información al desarrollador.</p>
+            Además del nombre del comentador, la calificación y el texto del comentario (las cuales están disponibles públicamente),
+            Google proporciona alguna o toda la siguiente información al desarrollador.</p>
         <ul>
             <li><item>Código de versión</item> (p.ej. 7)</li>
             <li><item>Nombre de versión</item> (p.ej. 1.6)</li>
 
 
         <h3>Anuncios</h3>
-        <p>Navegador Privado Gratuito muestra un banner plubicitario en la parte inferior de la pantalla mediante la red AdMob de Google, que tiene su <a href="https://www.google.com/intl/en/policies/privacy/">propia política de privacidad</a>.
-            Tenga en cuenta que, a menos que haya <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">desactivado los anuncios basados en intereses</a>,
-            el anunciante recibirá una copia del ID de publicidad único de su dispositivo, que les permite rastrear su dispositivo a través de las aplicaciones.
+        <p>Navegador Privado Gratuito muestra un banner plubicitario en la parte inferior de la pantalla mediante la red AdMob de Google,
+            que tiene su <a href="https://www.google.com/intl/en/policies/privacy/">propia política de privacidad</a>.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob reporta <em>resúmenes anónimos</em> de la siguiente información a los desarrolladores.</p>
         <ul>
             <li><item>Impresiones totales</item></li>
             <strong class="red">Stoutner nunca vendrá la información ni la transferirá a ninguna tercera parte que la pudiera usar para publicidad o marketing.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Revisión 1.5, 11 de enero de 2018</em></p>
+        <p style="text-align: center;"><em>Revisión 1.6, 22 de mayo de 2018</em></p>
     </body>
 </html>
\ No newline at end of file
index 6c0cd95..ba5bf0e 100644 (file)
@@ -59,7 +59,8 @@
 
         <h3>Comentarios de Google Play</h3>
         <p>Google Play tiene su <a href="https://www.google.com/intl/en/policies/privacy/">propia política de privacidad</a>.
-            Además del nombre del comentador, la calificación y el texto del comentario (las cuales están disponibles públicamente), Google proporciona alguna o toda la siguiente información al desarrollador.</p>
+            Además del nombre del comentador, la calificación y el texto del comentario (las cuales están disponibles públicamente),
+            Google proporciona alguna o toda la siguiente información al desarrollador.</p>
         <ul>
             <li><item>Código de versión</item> (p.ej. 7)</li>
             <li><item>Nombre de versión</item> (p.ej. 1.6)</li>
 
 
         <h3>Anuncios</h3>
-        <p>Navegador Privado Gratuito muestra un banner plubicitario en la parte inferior de la pantalla mediante la red AdMob de Google, que tiene su <a href="https://www.google.com/intl/en/policies/privacy/">propia política de privacidad</a>.
-            Tenga en cuenta que, a menos que haya <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">desactivado los anuncios basados en intereses</a>,
-            el anunciante recibirá una copia del ID de publicidad único de su dispositivo, que les permite rastrear su dispositivo a través de las aplicaciones.
+        <p>Navegador Privado Gratuito muestra un banner plubicitario en la parte inferior de la pantalla mediante la red AdMob de Google,
+            que tiene su <a href="https://www.google.com/intl/en/policies/privacy/">propia política de privacidad</a>.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob reporta <em>resúmenes anónimos</em> de la siguiente información a los desarrolladores.</p>
         <ul>
             <li><item>Impresiones totales</item></li>
             <strong class="red">Stoutner nunca vendrá la información ni la transferirá a ninguna tercera parte que la pudiera usar para publicidad o marketing.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Revisión 1.5, 11 de enero de 2018</em></p>
+        <p style="text-align: center;"><em>Revisión 1.6, 22 de mayo de 2018</em></p>
     </body>
 </html>
\ No newline at end of file
index f6f780d..b5c4128 100644 (file)
@@ -81,8 +81,8 @@
         <h3>Annunci</h3>
         <p>Privacy Browser Free mostra un banner pubblicitario nella parte inferiore dello schermo utilizzando la Google's AdMob network,
             che ha una propria <a href="https://www.google.com/intl/en/policies/privacy/">privacy policy</a>.
-            Si precisa che a meno che non siano stati <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">disattivati gli annunci personalizzati</a>,
-            l'inserzionista riceverà l'indicazione dell'advertising ID univoco del dispositivo, il quale permette il tracciamento dello stesso tramite le app.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob fornisce agli sviluppatori <em>sintesi anonime</em> delle seguenti informazioni.</p>
         <ul>
             <li><item>Numero totale di visualizzazioni</item></li>
             <strong class="red">Stoutner non rivenderà o comunque non trasferirà mai nessuna informazione a terze parti che potrebbero utilizzarle a scopi pubblicitari o di marketing.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Revisione 1.5, 11 Gennaio 2018</em></p>
+        <p style="text-align: center;"><em>Revisione 1.6, 22 Maggio 2018</em></p>
     </body>
 </html>
\ No newline at end of file
index 50ca4ed..7beb79d 100644 (file)
@@ -81,8 +81,8 @@
         <h3>Annunci</h3>
         <p>Privacy Browser Free mostra un banner pubblicitario nella parte inferiore dello schermo utilizzando la Google's AdMob network,
             che ha una propria <a href="https://www.google.com/intl/en/policies/privacy/">privacy policy</a>.
-            Si precisa che a meno che non siano stati <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">disattivati gli annunci personalizzati</a>,
-            l'inserzionista riceverà l'indicazione dell'advertising ID univoco del dispositivo, il quale permette il tracciamento dello stesso tramite le app.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob fornisce agli sviluppatori <em>sintesi anonime</em> delle seguenti informazioni.</p>
         <ul>
             <li><item>Numero totale di visualizzazioni</item></li>
             <strong class="red">Stoutner non rivenderà o comunque non trasferirà mai nessuna informazione a terze parti che potrebbero utilizzarle a scopi pubblicitari o di marketing.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Revisione 1.5, 11 Gennaio 2018</em></p>
+        <p style="text-align: center;"><em>Revisione 1.6, 22 Maggio 2018</em></p>
     </body>
 </html>
\ No newline at end of file
index a3ad28b..c3ed91f 100644 (file)
 
 
         <h3>Реклама</h3>
-        <p>Privacy Browser Free отображает рекламный баннер в нижней части экрана с помощью сети Google AdMob, которая имеет <a href="https://www.google.com/intl/en/policies/privacy/">собственную политику конфиденциальности</a>.
-            Обратите внимание, что если вы <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">не отказались от рекламы на основе интересов</a>,
-            рекламодатель получит копию уникального рекламного идентификатора устройства, который позволит ему отслеживать ваше устройство в различных приложениях.
+        <p>Privacy Browser Free отображает рекламный баннер в нижней части экрана с помощью сети Google AdMob,
+            которая имеет <a href="https://www.google.com/intl/en/policies/privacy/">собственную политику конфиденциальности</a>.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob отправляет <em>анонимные отчеты</em> разработчикам, содержащие следующую информацию.</p>
         <ul>
             <li><item>Всего показов</item></li>
@@ -98,6 +99,6 @@
             <strong class="red">Stoutner никогда не будет продавать эту информацию и передавать ее какой-либо третьей стороне, которая будет использовать ее для рекламы или маркетинга.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Ревизия 1.5, 11 января 2018</em></p>
+        <p style="text-align: center;"><em>Ревизия 1.6, 22 мая 2018 года</em></p>
     </body>
 </html>
\ No newline at end of file
index 413bf53..182ee07 100644 (file)
 
 
         <h3>Реклама</h3>
-        <p>Privacy Browser Free отображает рекламный баннер в нижней части экрана с помощью сети Google AdMob, которая имеет <a href="https://www.google.com/intl/en/policies/privacy/">собственную политику конфиденциальности</a>.
-            Обратите внимание, что если вы <a href="http://www.techrepublic.com/article/pro-tip-how-to-opt-out-of-interest-based-ads-on-your-android-phone/">не отказались от рекламы на основе интересов</a>,
-            рекламодатель получит копию уникального рекламного идентификатора устройства, который позволит ему отслеживать ваше устройство в различных приложениях.
+        <p>Privacy Browser Free отображает рекламный баннер в нижней части экрана с помощью сети Google AdMob,
+            которая имеет <a href="https://www.google.com/intl/en/policies/privacy/">собственную политику конфиденциальности</a>.
+            These ads are set to be non-personalized and the user is flagged as being under the age of consent,
+            which removes all <a href="https://developers.google.com/admob/android/eu-consent#collect_consent">tracking and remarketing</a>.
             AdMob отправляет <em>анонимные отчеты</em> разработчикам, содержащие следующую информацию.</p>
         <ul>
             <li><item>Всего показов</item></li>
@@ -98,6 +99,6 @@
             <strong class="red">Stoutner никогда не будет продавать эту информацию и передавать ее какой-либо третьей стороне, которая будет использовать ее для рекламы или маркетинга.</strong></p>
 
         <hr />
-        <p style="text-align: center;"><em>Ревизия 1.5, 11 января 2018</em></p>
+        <p style="text-align: center;"><em>Ревизия 1.6, 22 мая 2018 года</em></p>
     </body>
 </html>
\ No newline at end of file
diff --git a/app/src/free/java/com/stoutner/privacybrowser/BannerAd.java b/app/src/free/java/com/stoutner/privacybrowser/BannerAd.java
deleted file mode 100644 (file)
index c9263c2..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
- *
- * Privacy Browser 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.
- *
- * Privacy Browser 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 Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.stoutner.privacybrowser;
-
-import android.content.Context;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-import android.widget.RelativeLayout;
-
-import com.google.android.gms.ads.AdRequest;
-import com.google.android.gms.ads.AdSize;
-import com.google.android.gms.ads.AdView;
-
-public class BannerAd extends AppCompatActivity{
-    public static void requestAd(View view) {
-        // Cast view to an AdView.
-        AdView adView = (AdView) view;
-
-        // Load an ad.
-        AdRequest adRequest = new AdRequest.Builder().build();
-        adView.loadAd(adRequest);
-    }
-
-    public static void reloadAfterRotate (View view, Context applicationContext, String ad_id) {
-        // Cast `view` to an `AdView`.
-        AdView adView = (AdView) view;
-
-        // Save the layout parameters.
-        RelativeLayout.LayoutParams adViewLayoutParameters = (RelativeLayout.LayoutParams) adView.getLayoutParams();
-
-        // Remove the `AdView`.
-        RelativeLayout adViewParentLayout = (RelativeLayout) adView.getParent();
-        adViewParentLayout.removeView(adView);
-
-        // Setup the new `AdView`.
-        adView = new AdView(applicationContext);
-        adView.setAdSize(AdSize.SMART_BANNER);
-        adView.setAdUnitId(ad_id);
-        adView.setId(R.id.adview);
-        adView.setLayoutParams(adViewLayoutParameters);
-
-        // Display the new `AdView`.
-        adViewParentLayout.addView(adView);
-
-        // Request a new ad.
-        AdRequest adRequest = new AdRequest.Builder().build();
-        adView.loadAd(adRequest);
-    }
-
-    public static void hideAd(View view) {
-        // Cast `view` to an `AdView`.
-        AdView adView = (AdView) view;
-
-        // Hide the ad.
-        adView.setVisibility(View.GONE);
-    }
-
-    public static void showAd(View view) {
-        // Cast `view` to an `AdView`.
-        AdView adView = (AdView) view;
-
-        // Show the ad.
-        adView.setVisibility(View.VISIBLE);
-    }
-
-    public static void pauseAd(View view) {
-        // Cast `view` to an `AdView`.
-        AdView adView = (AdView) view;
-
-        // Pause the `AdView`.
-        adView.pause();
-    }
-
-    public static void resumeAd(View view) {
-        // Cast `view` to an `AdView`.
-        AdView adView = (AdView) view;
-
-        // Resume the `AdView`.
-        adView.resume();
-    }
-}
\ No newline at end of file
diff --git a/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java b/app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java
new file mode 100644 (file)
index 0000000..6b771d6
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser 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.
+ *
+ * Privacy Browser 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 Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.dialogs;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Build;
+import android.os.Bundle;
+
+import com.google.ads.consent.ConsentInformation;
+import com.google.ads.consent.ConsentStatus;
+import com.stoutner.privacybrowser.R;
+import com.stoutner.privacybrowser.activities.MainWebViewActivity;
+import com.stoutner.privacybrowser.helpers.AdHelper;
+
+public class AdConsentDialog extends DialogFragment {
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // Use a builder to create the alert dialog.
+        AlertDialog.Builder dialogBuilder;
+
+        // Set the style and the icon according to the theme.
+        if (MainWebViewActivity.darkTheme) {
+            dialogBuilder = new AlertDialog.Builder(getActivity(), R.style.PrivacyBrowserAlertDialogDark);
+            dialogBuilder.setIcon(R.drawable.block_ads_enabled_dark);
+        } else {
+            dialogBuilder = new AlertDialog.Builder(getActivity(), R.style.PrivacyBrowserAlertDialogLight);
+            dialogBuilder.setIcon(R.drawable.block_ads_enabled_light);
+        }
+
+        // Set the title.
+        dialogBuilder.setTitle(R.string.ad_consent);
+
+        // Set the text.
+        dialogBuilder.setMessage(R.string.ad_consent_text);
+
+        // Get a handle for the consent information.
+        ConsentInformation consentInformation = ConsentInformation.getInstance(getActivity().getApplicationContext());
+
+        // Configure the close button.
+        dialogBuilder.setNegativeButton(R.string.close_browser, (DialogInterface dialog, int which) -> {
+            // Set the consent status to Unknown.
+            consentInformation.setConsentStatus(ConsentStatus.UNKNOWN);
+
+            // Close the browser.  `finishAndRemoveTask` also removes Privacy Browser from the recent app list.
+            if (Build.VERSION.SDK_INT >= 21) {
+                getActivity().finishAndRemoveTask();
+            } else {
+                getActivity().finish();
+            }
+
+            // Remove the terminated program from RAM.  The status code is `0`.
+            System.exit(0);
+        });
+
+        // Configure the accept button.
+        dialogBuilder.setPositiveButton(R.string.accept_ads, (DialogInterface dialog, int which) -> {
+            // Set the consent status to Non-Personalized.
+            consentInformation.setConsentStatus(ConsentStatus.NON_PERSONALIZED);
+
+            // Indicate the user is under age, which disables personalized advertising and remarketing.  https://developers.google.com/admob/android/eu-consent
+            consentInformation.setTagForUnderAgeOfConsent(true);
+
+            // Load an ad.
+            AdHelper.loadAd(getActivity().findViewById(R.id.adview), getActivity().getApplicationContext(), getString(R.string.ad_id));
+        });
+
+        // Return the alert dialog.
+        return dialogBuilder.create();
+    }
+
+    // Close Privacy Browser Free if the dialog is cancelled without selecting a button (by tapping on the background).
+    @Override
+    public void onCancel(DialogInterface dialogInterface) {
+        // Set the consent status to Unknown.
+        ConsentInformation.getInstance(getActivity().getApplicationContext()).setConsentStatus(ConsentStatus.UNKNOWN);
+
+        // Close the browser.  `finishAndRemoveTask` also removes Privacy Browser from the recent app list.
+        if (Build.VERSION.SDK_INT >= 21) {
+            getActivity().finishAndRemoveTask();
+        } else {
+            getActivity().finish();
+        }
+
+        // Remove the terminated program from RAM.  The status code is `0`.
+        System.exit(0);
+    }
+}
\ No newline at end of file
diff --git a/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java b/app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java
new file mode 100644 (file)
index 0000000..a4f5b03
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser 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.
+ *
+ * Privacy Browser 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 Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.helpers;
+
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.RelativeLayout;
+
+import com.google.ads.consent.ConsentInfoUpdateListener;
+import com.google.ads.consent.ConsentInformation;
+import com.google.ads.consent.ConsentStatus;
+import com.google.ads.mediation.admob.AdMobAdapter;
+import com.google.android.gms.ads.AdRequest;
+import com.google.android.gms.ads.AdSize;
+import com.google.android.gms.ads.AdView;
+import com.google.android.gms.ads.MobileAds;
+import com.stoutner.privacybrowser.R;
+import com.stoutner.privacybrowser.dialogs.AdConsentDialog;
+
+public class AdHelper {
+    private static boolean initialized;
+
+    public static void initializeAds (View view, Context applicationContext, FragmentManager fragmentManager, String adId) {
+        if (!initialized) {  // This is the first run.
+            // Initialize mobile ads.
+            MobileAds.initialize(applicationContext, adId);
+
+            // Store the publisher ID in a string array.
+            String[] publisherIds = {"pub-5962503714887045"};
+
+            // Check to see if consent is needed in Europe to comply with the GDPR.
+            ConsentInformation consentInformation = ConsentInformation.getInstance(applicationContext);
+            consentInformation.requestConsentInfoUpdate(publisherIds, new ConsentInfoUpdateListener() {
+                @Override
+                public void onConsentInfoUpdated(ConsentStatus consentStatus) {
+                    if (consentStatus == ConsentStatus.UNKNOWN) {  // The user has not yet consented to ads.
+                        // Display the ad consent dialog.
+                        DialogFragment adConsentDialogFragment = new AdConsentDialog();
+                        adConsentDialogFragment.show(fragmentManager, "Ad Consent");
+                    } else {  // The user has consented to ads.
+                        // Indicate the user is under age, which disables personalized advertising and remarketing.  https://developers.google.com/admob/android/eu-consent
+                        consentInformation.setTagForUnderAgeOfConsent(true);
+
+                        // Load an ad.
+                        loadAd(view, applicationContext, adId);
+                    }
+                }
+
+                @Override
+                public void onFailedToUpdateConsentInfo(String reason) {  // The user is not in Europe.
+                    // Indicate the user is under age, which disables personalized advertising and remarketing.  https://developers.google.com/admob/android/eu-consent
+                    consentInformation.setTagForUnderAgeOfConsent(true);
+
+                    // Load an ad.
+                    loadAd(view, applicationContext, adId);
+                }
+            });
+
+            // Set the initialized variable to true so this section doesn't run again.
+            initialized = true;
+        } else {  // Ads have previously been initialized.
+            // Load an ad.
+            loadAd(view, applicationContext, adId);
+        }
+    }
+
+    public static void loadAd (View view, Context applicationContext, String adId) {
+        // Cast the generic view to an AdView.
+        AdView adView = (AdView) view;
+
+        // Save the layout parameters.  They are used when programatically recreating the add below.
+        RelativeLayout.LayoutParams adViewLayoutParameters = (RelativeLayout.LayoutParams) adView.getLayoutParams();
+
+        // Remove the AdView.
+        RelativeLayout adViewParentLayout = (RelativeLayout) adView.getParent();
+        adViewParentLayout.removeView(adView);
+
+        // Setup the new AdView.  This is necessary because the size of the banner ad can change on rotate.
+        adView = new AdView(applicationContext);
+        adView.setAdSize(AdSize.SMART_BANNER);
+        adView.setAdUnitId(adId);
+        adView.setId(R.id.adview);
+        adView.setLayoutParams(adViewLayoutParameters);
+
+        // Display the new AdView.
+        adViewParentLayout.addView(adView);
+
+        // Only request non-personalized ads.
+        Bundle adSettingsBundle = new Bundle();
+        adSettingsBundle.putString("npa", "1");
+
+        // Request a new ad.
+        AdRequest adRequest = new AdRequest.Builder().addNetworkExtrasBundle(AdMobAdapter.class, adSettingsBundle).build();
+        adView.loadAd(adRequest);
+    }
+
+    public static void hideAd(View view) {
+        // Cast the generic view to an AdView.
+        AdView adView = (AdView) view;
+
+        // Hide the ad.
+        adView.setVisibility(View.GONE);
+    }
+
+    public static void pauseAd(View view) {
+        // Cast The generic view to an AdView.
+        AdView adView = (AdView) view;
+
+        // Pause the AdView.
+        adView.pause();
+    }
+
+    public static void resumeAd(View view) {
+        // Cast the generic view to an AdView.
+        AdView adView = (AdView) view;
+
+        // Resume the AdView.
+        adView.resume();
+    }
+}
\ No newline at end of file
index 6a5db00..35b8896 100644 (file)
     <!-- Activities. -->
     <string name="privacy_browser">Privacy Browser Free</string>
 
-    <!-- Ad control. -->
+    <!-- Ad Control. -->
     <string name="ad_id" translatable="false">ca-app-pub-5962503714887045/2738552414</string>
+
+    <!-- Test Ad Control.
+    <string name="ad_id" translatable="false">ca-app-pub-3940256099942544/6300978111</string>
+    -->
+
+    <!-- Ad Consent. -->
+    <string name="ad_consent_text">Privacy Browser Free displays a banner ad on the bottom of the screen.
+        These ads come from Google’s set of commonly used providers and are configured to be non-personalized and non-tracking.
+        The standard version of Privacy Browser does not contain ads.</string>
+    <string name="close_browser">Close Browser</string>
+    <string name="accept_ads">Accept Ads</string>
 </resources>
\ No newline at end of file
index afe3bea..9f02c1c 100644 (file)
     </head>
 
     <body>
-        <h3><img class="title" src="../shared_images/ic_location_off_blue_dark.png"> Werbung</h3>
+        <h3><img class="title" src="../shared_images/ic_location_off_blue_dark.png"> Do Not Track</h3>
 
-        <p>Privacy Browser Free beinhaltet eine Bannerwerbung unten auf dem Bildschirm, welcher von Googles
-            AdMob-Netzwerk befüllt wird. Standardmäßig stellt Google die <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">Werbe-ID</a>
-            des Geräts den Werbungen über dieses Netzwerk zur Verfügung. Das ermöglicht werbenden Firmen, ein Profil von
-            dem Gerät anzulegen, welches zeigt welche Apps installiert sind  (welche auch Werbungen zeigen), wie oft sie genutzt werden und an welchen Werbungen der Nutzer interessiert ist.</p>
+        <p>A few years ago the W3C (World Wide Web Consortium) created a mechanism for browsers to inform web servers that they would not like to be tracked.
+            This is accomplished by including a <a href="https://en.wikipedia.org/wiki/Do_Not_Track">DNT (Do Not Track) header</a> with web requests.</p>
 
-        <p>Benutzer können diese Werbe-ID deaktivieren in <strong>Einstellungen</strong>, <strong>Google</strong>, <strong>Werbung</strong>.</p>
-
-        <img class="center" src="images/advertising_id.png">
-
-        <p>Der Zweck der kostenlosen Version von Privacy Browser ist es, Nutzern zu ermöglichen, die Features der App zu testen. Die Standardversion kann in den bekannten App-Stores
-            gekauft oder kostenlos von
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a> bezogen werden.</p>
+        <p>The DNT header doesn't really provide any privacy because most web servers ignore it. For example, Yahoo, Google, Microsoft, and Facebook all ignore at least some DNT headers.</p>
     </body>
 </html>
\ No newline at end of file
index e917d27..09b98a8 100644 (file)
     </head>
 
     <body>
-        <h3><img class="title" src="../shared_images/ic_location_off_blue_light.png"> Werbung</h3>
+        <h3><img class="title" src="../shared_images/ic_location_off_blue_light.png"> Do Not Track</h3>
 
-        <p>Privacy Browser Free beinhaltet eine Bannerwerbung unten auf dem Bildschirm, welcher von Googles
-            AdMob-Netzwerk befüllt wird. Standardmäßig stellt Google die <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">Werbe-ID</a>
-            des Geräts den Werbungen über dieses Netzwerk zur Verfügung. Das ermöglicht werbenden Firmen, ein Profil von
-            dem Gerät anzulegen, welches zeigt welche Apps installiert sind  (welche auch Werbungen zeigen), wie oft sie genutzt werden und an welchen Werbungen der Nutzer interessiert ist.</p>
+        <p>A few years ago the W3C (World Wide Web Consortium) created a mechanism for browsers to inform web servers that they would not like to be tracked.
+            This is accomplished by including a <a href="https://en.wikipedia.org/wiki/Do_Not_Track">DNT (Do Not Track) header</a> with web requests.</p>
 
-        <p>Benutzer können diese Werbe-ID deaktivieren in <strong>Einstellungen</strong>, <strong>Google</strong>, <strong>Werbung</strong>.</p>
-
-        <img class="center" src="images/advertising_id.png">
-
-        <p>Der Zweck der kostenlosen Version von Privacy Browser ist es, Nutzern zu ermöglichen, die Features der App zu testen. Die Standardversion kann in den bekannten App-Stores
-            gekauft oder kostenlos von
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a> bezogen werden.</p>
+        <p>The DNT header doesn't really provide any privacy because most web servers ignore it. For example, Yahoo, Google, Microsoft, and Facebook all ignore at least some DNT headers.</p>
     </body>
 </html>
\ No newline at end of file
diff --git a/app/src/main/assets/de/images/advertising_id.png b/app/src/main/assets/de/images/advertising_id.png
deleted file mode 100644 (file)
index 5b4978e..0000000
Binary files a/app/src/main/assets/de/images/advertising_id.png and /dev/null differ
index 9ad2dd0..60697c1 100644 (file)
         <p>A few years ago the W3C (World Wide Web Consortium) created a mechanism for browsers to inform web servers that they would not like to be tracked.
             This is accomplished by including a <a href="https://en.wikipedia.org/wiki/Do_Not_Track">DNT (Do Not Track) header</a> with web requests.</p>
 
-        <p>The DNT header doesn't really provide much privacy because most web servers ignore it. For example, Yahoo, Google, Microsoft, and Facebook all ignore at least some DNT headers.</p>
-
-
-        <h3>Advertisements</h3>
-
-        <p>Privacy Browser Free includes a banner advertisement across the bottom of the screen that is populated by Google’s AdMob network.
-            By default, Google provides the <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">advertising ID</a> of the device to the ads displayed through this network.
-            This allows advertising companies to build a profile of the device that show which apps are installed (that display ads), how often they are used, and which ads the user is interested in.</p>
-
-        <p>Users can choose to disable the advertising ID in <strong>Settings</strong>, <strong>Google</strong>, <strong>Ads</strong>.</p>
-
-        <img class="center" src="images/advertising_id.png">
-
-        <p>The purpose of the free version of Privacy Browser is to allow people to test the features of the app. The standard version can be purchased on the major app stores or downloaded for free from
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a>.</p>
+        <p>The DNT header doesn't really provide any privacy because most web servers ignore it. For example, Yahoo, Google, Microsoft, and Facebook all ignore at least some DNT headers.</p>
     </body>
 </html>
\ No newline at end of file
index 4a5d4e9..51b0e89 100644 (file)
     </head>
 
     <body>
-    <h3><img class="title" src="../shared_images/ic_location_off_blue_light.png"> Do Not Track</h3>
+        <h3><img class="title" src="../shared_images/ic_location_off_blue_light.png"> Do Not Track</h3>
 
         <p>A few years ago the W3C (World Wide Web Consortium) created a mechanism for browsers to inform web servers that they would not like to be tracked.
             This is accomplished by including a <a href="https://en.wikipedia.org/wiki/Do_Not_Track">DNT (Do Not Track) header</a> with web requests.</p>
 
-        <p>The DNT header doesn't really provide much privacy because most web servers ignore it. For example, Yahoo, Google, Microsoft, and Facebook all ignore at least some DNT headers.</p>
-
-
-        <h3>Advertisements</h3>
-
-        <p>Privacy Browser Free includes a banner advertisement across the bottom of the screen that is populated by Google’s AdMob network.
-            By default, Google provides the <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">advertising ID</a> of the device to the ads displayed through this network.
-            This allows advertising companies to build a profile of the device that show which apps are installed (that display ads), how often they are used, and which ads the user is interested in.</p>
-
-        <p>Users can choose to disable the advertising ID in <strong>Settings</strong>, <strong>Google</strong>, <strong>Ads</strong>.</p>
-
-        <img class="center" src="images/advertising_id.png">
-
-        <p>The purpose of the free version of Privacy Browser is to allow people to test the features of the app. The standard version can be purchased on the major app stores or downloaded for free from
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a>.</p>
+        <p>The DNT header doesn't really provide any privacy because most web servers ignore it. For example, Yahoo, Google, Microsoft, and Facebook all ignore at least some DNT headers.</p>
     </body>
 </html>
\ No newline at end of file
diff --git a/app/src/main/assets/en/images/advertising_id.png b/app/src/main/assets/en/images/advertising_id.png
deleted file mode 100644 (file)
index 2d811f3..0000000
Binary files a/app/src/main/assets/en/images/advertising_id.png and /dev/null differ
index 127f793..a00544e 100644 (file)
 
         <p>El encabezado DNT no provee realmente de mucha privacidad porque la mayoría de servidores web lo ignoran. Por ejemplo, Yahoo, Google, Microsoft y Facebook,
             todos ellos ignoran al menos algunos encabezados DNT.</p>
-
-
-        <h3>Anuncios</h3>
-
-        <p>Navegador Privado Gratuito incluye un anuncio de banner en la parte inferior de la pantalla que está poblado por la red AdMob de Google.
-            Por defecto, Google proporciona el <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">ID publicitario</a>
-            del dispositivo a los anuncios que se muestran a través de esta red.
-            Esto permite a las compañías publicitarias construir un perfil del dispositivo que muestre qué aplicaciones están instaladas (que muestran anuncios),
-            la frecuencia con la que se utilizan y los anuncios en los que está interesado el usuario.</p>
-
-        <p>Los usuarios pueden elegir deshabilitar el ID publicitario en <strong>Configuración</strong>, <strong>Google</strong>, <strong>Anuncios</strong>.</p>
-
-        <img class="center" src="images/advertising_id.png">
-
-        <p>El propósito de la versión gratuta de Navegador Privado es la de permitir a la gente probar las características de la aplicación.
-            La versión estándar se puede comprar en las principales tiendas de aplicaciones o descargarse gratuitamente de
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a>.
     </body>
 </html>
\ No newline at end of file
index 17cd9ac..0739b34 100644 (file)
 
         <p>El encabezado DNT no provee realmente de mucha privacidad porque la mayoría de servidores web lo ignoran. Por ejemplo, Yahoo, Google, Microsoft y Facebook,
             todos ellos ignoran al menos algunos encabezados DNT.</p>
-
-
-        <h3>Anuncios</h3>
-
-        <p>Navegador Privado Gratuito incluye un anuncio de banner en la parte inferior de la pantalla que está poblado por la red AdMob de Google.
-            Por defecto, Google proporciona el <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">ID publicitario</a>
-            del dispositivo a los anuncios que se muestran a través de esta red.
-            Esto permite a las compañías publicitarias construir un perfil del dispositivo que muestre qué aplicaciones están instaladas (que muestran anuncios),
-            la frecuencia con la que se utilizan y los anuncios en los que está interesado el usuario.</p>
-
-        <p>Los usuarios pueden elegir deshabilitar el ID publicitario en <strong>Configuración</strong>, <strong>Google</strong>, <strong>Anuncios</strong>.</p>
-
-        <img class="center" src="images/advertising_id.png">
-
-        <p>El propósito de la versión gratuta de Navegador Privado es la de permitir a la gente probar las características de la aplicación.
-            La versión estándar se puede comprar en las principales tiendas de aplicaciones o descargarse gratuitamente de
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a>.
     </body>
 </html>
\ No newline at end of file
diff --git a/app/src/main/assets/es/images/advertising_id.png b/app/src/main/assets/es/images/advertising_id.png
deleted file mode 100644 (file)
index b4c2282..0000000
Binary files a/app/src/main/assets/es/images/advertising_id.png and /dev/null differ
index cdcad6a..391d47a 100644 (file)
 
         <p>L'header DNT in realtà non garantisce nessuna privacy dal momento che la maggior parte dei web server lo ignora, come ad esempio Yahoo, Google, Microsoft e Facebook,
             che ignorano tutti almeno alcuni degli header DNT.</p>
-
-
-        <h3>Annunci</h3>
-
-        <p>Privacy Browser Free mostra nella parte inferiore dello schermo un banner pubblicitario che è popolato attraverso la Google’s AdMob network.
-            Di default Google fornisce la <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">advertising ID</a> del dispositivo agli annunci mostrati.
-            Questa pratica permette alle compagnie pubblicitarie la creazione di un profilo del dispositivo che mostri quali app sono installate (quelle che mostrano l'annuncio),
-            la loro frequenza di utilizzo, gli annunci che interessano all'utente.</p>
-
-        <p>Gli utenti possono scegliere di disattivare la advertising ID in <strong>Impostazioni</strong>, <strong>Google</strong>, <strong>Annunci</strong>.</p>
-
-        <img class="center" src="images/advertising_id.png">
-
-        <p>Lo scopo della versione free di Privacy Browser è quello di permettere agli utenti di provare la app e le sue funzionalità.
-            La versione standard può essere acquistata su tutti i principali app stores o scaricata gratuitamente da
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a>.</p>
     </body>
 </html>
\ No newline at end of file
index 5e4801f..3734e65 100644 (file)
 
         <p>L'header DNT in realtà non garantisce nessuna privacy dal momento che la maggior parte dei web server lo ignora, come ad esempio Yahoo, Google, Microsoft e Facebook,
             che ignorano tutti almeno alcuni degli header DNT.</p>
-
-
-        <h3>Annunci</h3>
-
-        <p>Privacy Browser Free mostra nella parte inferiore dello schermo un banner pubblicitario che è popolato attraverso la Google’s AdMob network.
-            Di default Google fornisce la <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=en">advertising ID</a> del dispositivo agli annunci mostrati.
-            Questa pratica permette alle compagnie pubblicitarie la creazione di un profilo del dispositivo che mostri quali app sono installate (quelle che mostrano l'annuncio),
-            la loro frequenza di utilizzo, gli annunci che interessano all'utente.</p>
-
-        <p>Gli utenti possono scegliere di disattivare la advertising ID in <strong>Impostazioni</strong>, <strong>Google</strong>, <strong>Annunci</strong>.</p>
-
-        <img class="center" src="images/advertising_id.png">
-
-        <p>Lo scopo della versione free di Privacy Browser è quello di permettere agli utenti di provare la app e le sue funzionalità.
-            La versione standard può essere acquistata su tutti i principali app stores o scaricata gratuitamente da
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a>.</p>
     </body>
 </html>
\ No newline at end of file
diff --git a/app/src/main/assets/it/images/advertising_id.png b/app/src/main/assets/it/images/advertising_id.png
deleted file mode 100644 (file)
index c0a6669..0000000
Binary files a/app/src/main/assets/it/images/advertising_id.png and /dev/null differ
index f6ef72b..ed8c2b0 100644 (file)
 
         <p>Заголовок DNT на самом деле не обеспечивает большую конфиденциальность, поскольку большинство веб-серверов его игнорируют.
             Например, Yahoo, Google, Microsoft и Facebook игнорируют, по крайней мере, некоторые заголовки DNT.</p>
-
-
-        <h3>Реклама</h3>
-
-        <p>Privacy Browser Free включает баннерную рекламу в нижней части экрана от сети Google AdMob.
-            По умолчанию Google предоставляет <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=ru">рекламный идентификатор</a>
-            устройства для рекламы, отображаемой от этой сети.
-            Это позволяет рекламным компаниям создавать профиль устройства, который отображает, какие приложения установлены (для показа рекламы),
-            как часто они используются и какая реклама интересна пользователю.</p>
-
-        <p>Пользователи могут отключить рекламный идентификатор в <strong>Настройках</strong>, <strong>Google</strong>, <strong>Реклама</strong>.</p>
-
-        <img class="center21" src="images/advertising_id.png">
-
-        <p>Цель бесплатной версии Privacy Browser - позволить пользователям протестировать функции приложения. Стандартную версию можно приобрести в основных магазинах приложений или загрузить бесплатно из
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a>.</p>
     </body>
 </html>
\ No newline at end of file
index b92ac03..3b23acb 100644 (file)
 
         <p>Заголовок DNT на самом деле не обеспечивает большую конфиденциальность, поскольку большинство веб-серверов его игнорируют.
             Например, Yahoo, Google, Microsoft и Facebook игнорируют, по крайней мере, некоторые заголовки DNT.</p>
-
-
-        <h3>Реклама</h3>
-
-        <p>Privacy Browser Free включает баннерную рекламу в нижней части экрана от сети Google AdMob.
-            По умолчанию Google предоставляет <a href="https://support.google.com/googleplay/android-developer/answer/6048248?hl=ru">рекламный идентификатор</a>
-            устройства для рекламы, отображаемой от этой сети.
-            Это позволяет рекламным компаниям создавать профиль устройства, который отображает, какие приложения установлены (для показа рекламы),
-            как часто они используются и какая реклама интересна пользователю.</p>
-
-        <p>Пользователи могут отключить рекламный идентификатор в <strong>Настройках</strong>, <strong>Google</strong>, <strong>Реклама</strong>.</p>
-
-        <img class="center21" src="images/advertising_id.png">
-
-        <p>Цель бесплатной версии Privacy Browser - позволить пользователям протестировать функции приложения. Стандартную версию можно приобрести в основных магазинах приложений или загрузить бесплатно из
-            <a href="https://f-droid.org/repository/browse/?fdfilter=privacy+browser&fdid=com.stoutner.privacybrowser.standard">F-Droid</a>.</p>
     </body>
 </html>
\ No newline at end of file
diff --git a/app/src/main/assets/ru/images/advertising_id.png b/app/src/main/assets/ru/images/advertising_id.png
deleted file mode 100644 (file)
index 0302924..0000000
Binary files a/app/src/main/assets/ru/images/advertising_id.png and /dev/null differ
index e76e3e8..6e29667 100644 (file)
@@ -108,9 +108,9 @@ import android.widget.RadioButton;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
-import com.stoutner.privacybrowser.BannerAd;
 import com.stoutner.privacybrowser.BuildConfig;
 import com.stoutner.privacybrowser.R;
+import com.stoutner.privacybrowser.dialogs.AdConsentDialog;
 import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog;
 import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog;
 import com.stoutner.privacybrowser.dialogs.CreateHomeScreenShortcutDialog;
@@ -122,6 +122,7 @@ import com.stoutner.privacybrowser.dialogs.HttpAuthenticationDialog;
 import com.stoutner.privacybrowser.dialogs.PinnedSslCertificateMismatchDialog;
 import com.stoutner.privacybrowser.dialogs.UrlHistoryDialog;
 import com.stoutner.privacybrowser.dialogs.ViewSslCertificateDialog;
+import com.stoutner.privacybrowser.helpers.AdHelper;
 import com.stoutner.privacybrowser.helpers.BlockListHelper;
 import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
 import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper;
@@ -369,9 +370,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     private ForegroundColorSpan initialGrayColorSpan;
     private ForegroundColorSpan finalGrayColorSpan;
 
-    // `adView` is used in `onCreate()` and `onConfigurationChanged()`.
-    private View adView;
-
     // `sslErrorHandler` is used in `onCreate()`, `onSslErrorCancel()`, and `onSslErrorProceed`.
     private SslErrorHandler sslErrorHandler;
 
@@ -604,9 +602,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                         // Hide the `appBar`.
                         appBar.hide();
 
-                        // Hide the `BannerAd` in the free flavor.
+                        // Hide the banner ad in the free flavor.
                         if (BuildConfig.FLAVOR.contentEquals("free")) {
-                            BannerAd.hideAd(adView);
+                            // The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
+                            AdHelper.hideAd(findViewById(R.id.adview));
                         }
 
                         // Modify the system bars.
@@ -641,11 +640,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
                         // Show the `BannerAd` in the free flavor.
                         if (BuildConfig.FLAVOR.contentEquals("free")) {
-                            // Reload the ad.  Because the screen may have rotated, we need to use `reloadAfterRotate`.
-                            BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
-
-                            // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`.
-                            adView = findViewById(R.id.adview);
+                            // Reload the ad.  The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
+                            AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_id));
                         }
 
                         // Remove the translucent navigation bar flag if it is set.
@@ -928,7 +924,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             public void onShowCustomView(View view, CustomViewCallback callback) {
                 // Pause the ad if this is the free flavor.
                 if (BuildConfig.FLAVOR.contentEquals("free")) {
-                    BannerAd.pauseAd(adView);
+                    // The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
+                    AdHelper.pauseAd(findViewById(R.id.adview));
                 }
 
                 // Remove the translucent overlays.
@@ -966,11 +963,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
                 // Show the ad if this is the free flavor.
                 if (BuildConfig.FLAVOR.contentEquals("free")) {
-                    // Reload the ad.  Because the screen may have rotated, we need to use `reloadAfterRotate`.
-                    BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
-
-                    // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`.
-                    adView = findViewById(R.id.adview);
+                    // Reload the ad.  The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
+                    AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_id));
                 }
             }
 
@@ -1071,9 +1065,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         // Initialize `inFullScreenBrowsingMode`, which is always false at this point because Privacy Browser never starts in full screen browsing mode.
         inFullScreenBrowsingMode = false;
 
-        // Initialize AdView for the free flavor.
-        adView = findViewById(R.id.adview);
-
         // Initialize the privacy settings variables.
         javaScriptEnabled = false;
         firstPartyCookiesEnabled = false;
@@ -1549,7 +1540,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
         // Resume the adView for the free flavor.
         if (BuildConfig.FLAVOR.contentEquals("free")) {
-            BannerAd.resumeAd(adView);
+            // The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
+            AdHelper.resumeAd(findViewById(R.id.adview));
         }
     }
 
@@ -1563,7 +1555,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
         // Pause the adView or it will continue to consume resources in the background on the free flavor.
         if (BuildConfig.FLAVOR.contentEquals("free")) {
-            BannerAd.pauseAd(adView);
+            // The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
+            AdHelper.pauseAd(findViewById(R.id.adview));
         }
 
         super.onPause();
@@ -1621,6 +1614,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         MenuItem fontSizeMenuItem = menu.findItem(R.id.font_size);
         MenuItem displayImagesMenuItem = menu.findItem(R.id.display_images);
         MenuItem refreshMenuItem = menu.findItem(R.id.refresh);
+        MenuItem adConsentMenuItem = menu.findItem(R.id.ad_consent);
 
         // Set the text for the domain menu item.
         if (domainSettingsApplied) {
@@ -1726,9 +1720,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         fontSizeMenuItem.setTitle(fontSizeTitle);
         selectedFontSizeMenuItem.setChecked(true);
 
-        // Only show `Refresh` if `swipeToRefresh` is disabled.
+        // Only show Refresh if `swipeToRefresh` is disabled.
         refreshMenuItem.setVisible(!swipeToRefreshEnabled);
 
+        // Only show Ad Consent if this is the free flavor.
+        adConsentMenuItem.setVisible(BuildConfig.FLAVOR.contentEquals("free"));
+
         // Run all the other default commands.
         super.onPrepareOptionsMenu(menu);
 
@@ -1828,7 +1825,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 // Display a `Snackbar`.
                 if (firstPartyCookiesEnabled) {  // First-party cookies are enabled.
                     Snackbar.make(findViewById(R.id.main_webview), R.string.first_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
-                } else if (javaScriptEnabled){  // JavaScript is still enabled.
+                } else if (javaScriptEnabled) {  // JavaScript is still enabled.
                     Snackbar.make(findViewById(R.id.main_webview), R.string.first_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
                 } else {  // Privacy mode.
                     Snackbar.make(findViewById(R.id.main_webview), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
@@ -2110,6 +2107,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 mainWebView.reload();
                 return true;
 
+            case R.id.ad_consent:
+                // Display the ad consent dialog.
+                DialogFragment adConsentDialogFragment = new AdConsentDialog();
+                adConsentDialogFragment.show(getFragmentManager(), getString(R.string.ad_consent));
+                return true;
+
             default:
                 // Don't consume the event.
                 return super.onOptionsItemSelected(menuItem);
@@ -2339,11 +2342,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
         // Reload the ad for the free flavor if we are not in full screen mode.
         if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
-            // Reload the ad.
-            BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
-
-            // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`.
-            adView = findViewById(R.id.adview);
+            // Reload the ad.  The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
+            AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_id));
         }
 
         // `invalidateOptionsMenu` should recalculate the number of action buttons from the menu to display on the app bar, but it doesn't because of the this bug:
@@ -3263,11 +3263,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
             // Show the `BannerAd` in the free flavor.
             if (BuildConfig.FLAVOR.contentEquals("free")) {
-                // Reload the ad.  Because the screen may have rotated, we need to use `reloadAfterRotate`.
-                BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
-
-                // Reinitialize the `adView` variable, as the `View` will have been removed and re-added by `BannerAd.reloadAfterRotate()`.
-                adView = findViewById(R.id.adview);
+                // Initialize the ad.  The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
+                AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getFragmentManager(), getString(R.string.ad_id));
             }
 
             // Remove the translucent navigation bar flag if it is set.
index d75cf6c..712e216 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -75,6 +75,7 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment {
         void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId);
     }
 
+    @Override
     public void onAttach(Context context) {
         // Run the default commands.
         super.onAttach(context);
@@ -108,6 +109,9 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment {
         // Run the default commands.
         super.onCreate(savedInstanceState);
 
+        // Remove the incorrect lint warning below that `getInt()` might be null.
+        assert getArguments() != null;
+
         // Store the bookmark database ID in the class variable.
         bookmarkDatabaseId = getArguments().getInt("Database ID");
     }
@@ -137,6 +141,9 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment {
         // Set the title.
         dialogBuilder.setTitle(R.string.edit_bookmark);
 
+        // Remove the incorrect lint warning below that `getLayoutInflater()` might be null.
+        assert getActivity() != null;
+
         // Set the view.  The parent view is `null` because it will be assigned by `AlertDialog`.
         dialogBuilder.setView(getActivity().getLayoutInflater().inflate(R.layout.edit_bookmark_databaseview_dialog, null));
 
@@ -210,6 +217,9 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment {
         // Combine `matrixCursor` and `foldersCursor`.
         MergeCursor foldersMergeCursor = new MergeCursor(new Cursor[]{matrixCursor, foldersCursor});
 
+        // Remove the incorrect lint warning below that `getContext()` might be null.
+        assert getContext() != null;
+
         // Create a `ResourceCursorAdapter` for the `Spinner`.  `0` specifies no flags.;
         ResourceCursorAdapter foldersCursorAdapter = new ResourceCursorAdapter(getContext(), R.layout.edit_bookmark_databaseview_spinner_item, foldersMergeCursor, 0) {
             @Override
index a468a00..72b9fd6 100644 (file)
         android:title="@string/refresh"
         android:orderInCategory="150"
         app:showAsAction="never" />
+
+    <item
+        android:id="@+id/ad_consent"
+        android:title="@string/ad_consent"
+        android:orderInCategory="160"
+        app:showAsAction="never" />
 </menu>
\ No newline at end of file
index dd6b75f..257e285 100644 (file)
     <string name="contributors">Contributors</string>
     <string name="links">Links</string>
 
-    <!-- Ad Control. -->
-    <string name="ad_id" translatable="false">Null</string>  <!-- There are no ads in the standard flavor, but this string must exist because it is referenced in the code. -->
+    <!-- Ad Control. There are no ads in the standard flavor, but these strings must exist because they are referenced in the code. -->
+    <string name="ad_id" translatable="false">Null</string>
+    <string name="ad_consent">Ad Consent</string>
 </resources>
diff --git a/app/src/standard/java/com/stoutner/privacybrowser/BannerAd.java b/app/src/standard/java/com/stoutner/privacybrowser/BannerAd.java
deleted file mode 100644 (file)
index 32b0378..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
- *
- * Privacy Browser 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.
- *
- * Privacy Browser 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 Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.stoutner.privacybrowser;
-
-import android.content.Context;
-import android.view.View;
-
-public class BannerAd {
-    public static void requestAd(View view) {
-        // Do nothing because this is the standard flavor.
-    }
-
-    public static void reloadAfterRotate(View view, Context applicationContext, String ad_id) {
-        // Do nothing because this is the standard flavor.
-    }
-
-    public static void hideAd(View view) {
-        // Do nothing because this is the standard flavor.
-    }
-
-    public static void showAd(View view) {
-        // Do nothing because this is the standard flavor.
-    }
-
-    public static void pauseAd(View view) {
-        // Do nothing because this is the standard flavor.
-    }
-
-    public static void resumeAd(View view) {
-        // Do nothing because this is the standard flavor.
-    }
-}
\ No newline at end of file
diff --git a/app/src/standard/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java b/app/src/standard/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java
new file mode 100644 (file)
index 0000000..c029d71
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser 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.
+ *
+ * Privacy Browser 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 Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.dialogs;
+
+import android.app.DialogFragment;
+
+public class AdConsentDialog extends DialogFragment {
+    // Do nothing because this is the standard flavor.
+}
\ No newline at end of file
diff --git a/app/src/standard/java/com/stoutner/privacybrowser/helpers/AdHelper.java b/app/src/standard/java/com/stoutner/privacybrowser/helpers/AdHelper.java
new file mode 100644 (file)
index 0000000..068d272
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser 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.
+ *
+ * Privacy Browser 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 Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.helpers;
+
+import android.app.FragmentManager;
+import android.content.Context;
+import android.view.View;
+
+@SuppressWarnings("unused")
+public class AdHelper {
+    public static void initializeAds(View view, Context applicationContext, FragmentManager fragmentManager, String ad_id) {
+        // Do nothing because this is the standard flavor.
+    }
+
+    public static void loadAd(View view, Context applicationContext, String ad_id) {
+        // Do nothing because this is the standard flavor.
+    }
+
+    public static void hideAd(View view) {
+        // Do nothing because this is the standard flavor.
+    }
+
+    public static void pauseAd(View view) {
+        // Do nothing because this is the standard flavor.
+    }
+
+    public static void resumeAd(View view) {
+        // Do nothing because this is the standard flavor.
+    }
+}
\ No newline at end of file