From 976d7da4c16f9ddc87f0cd7c67cd2eefc9f260b1 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Mon, 27 Sep 2021 14:26:12 -0700 Subject: [PATCH] Add a realtime monitoring service. https://redmine.stoutner.com/issues/750 --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 21 ++- app/src/main/assets/en/changelog.html | 4 +- app/src/main/assets/en/contributors.html | 1 + app/src/main/assets/en/licenses.html | 8 +- app/src/main/assets/en/permissions.html | 8 + app/src/main/assets/es/changelog.html | 4 +- app/src/main/assets/es/contributors.html | 1 + app/src/main/assets/es/licenses.html | 8 +- app/src/main/assets/es/permissions.html | 8 + app/src/main/assets/fr/changelog.html | 4 +- app/src/main/assets/fr/contributors.html | 1 + app/src/main/assets/fr/licenses.html | 8 +- app/src/main/assets/fr/permissions.html | 8 + .../assets/images/insecure_notification.svg | 31 ++++ .../assets/images/secure_notification.svg | 31 ++++ app/src/main/assets/it/changelog.html | 4 +- app/src/main/assets/it/contributors.html | 1 + app/src/main/assets/it/licenses.html | 45 ++--- app/src/main/assets/it/permissions.html | 8 + app/src/main/assets/it/privacy_policy.html | 84 ++++----- .../activities/PrivacyCellActivity.kt | 25 ++- .../privacycell/fragments/SettingsFragment.kt | 53 +++++- .../receivers/OnBootCompletedReceiver.kt | 45 +++++ .../services/RealtimeMonitoringService.kt | 170 ++++++++++++++++++ .../res/drawable/insecure_notification.xml | 31 ++++ .../drawable/realtime_monitoring_disabled.xml | 31 ++++ .../drawable/realtime_monitoring_enabled.xml | 31 ++++ .../main/res/drawable/secure_notification.xml | 31 ++++ app/src/main/res/values/strings.xml | 20 +++ app/src/main/res/xml/preferences.xml | 38 +++- build.gradle | 2 +- 32 files changed, 669 insertions(+), 98 deletions(-) create mode 100644 app/src/main/assets/images/insecure_notification.svg create mode 100644 app/src/main/assets/images/secure_notification.svg create mode 100644 app/src/main/java/com/stoutner/privacycell/receivers/OnBootCompletedReceiver.kt create mode 100644 app/src/main/java/com/stoutner/privacycell/services/RealtimeMonitoringService.kt create mode 100644 app/src/main/res/drawable/insecure_notification.xml create mode 100644 app/src/main/res/drawable/realtime_monitoring_disabled.xml create mode 100644 app/src/main/res/drawable/realtime_monitoring_enabled.xml create mode 100644 app/src/main/res/drawable/secure_notification.xml diff --git a/app/build.gradle b/app/build.gradle index a6d9998..f49f3b4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,7 +55,7 @@ dependencies { implementation 'androidx.webkit:webkit:1.4.0' // Include the Kotlin standard libraries. This should be the same version number listed in project build.gradle. - implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30' + implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31' // Include the Google material library. implementation 'com.google.android.material:material:1.4.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a510530..4400b2c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,6 +27,12 @@ + + + + + + @@ -39,7 +45,7 @@ android:supportsRtl="true" android:theme="@style/Theme.PrivacyCell" > - + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/en/changelog.html b/app/src/main/assets/en/changelog.html index c29906d..6bd4d4d 100644 --- a/app/src/main/assets/en/changelog.html +++ b/app/src/main/assets/en/changelog.html @@ -27,8 +27,8 @@ -

1.2 (version code 3)

-

15 September 2021 - minimum API 30, target API 30.

+

1.2 (version code 3)

+

15 September 2021 - minimum API 30, target API 30.

  • Add the option to use a bottom app bar.
  • First full Spanish translation contributed by Jose A. León.
  • diff --git a/app/src/main/assets/en/contributors.html b/app/src/main/assets/en/contributors.html index 412a912..d3f91b1 100644 --- a/app/src/main/assets/en/contributors.html +++ b/app/src/main/assets/en/contributors.html @@ -32,6 +32,7 @@

    Translators

    Kévin L.: French
    + Bernhard G. Keller: German
    Francesco Buratti: Italian
    Jose A. León: Spanish diff --git a/app/src/main/assets/en/licenses.html b/app/src/main/assets/en/licenses.html index afd34e5..a370ba5 100644 --- a/app/src/main/assets/en/licenses.html +++ b/app/src/main/assets/en/licenses.html @@ -41,14 +41,14 @@ which are released under the Apache License 2.0. The full text of the license is below.

    Icons

    -

    is derived from security and 5g, +

    are derived from security and 5g, which are part of the Android Material icon set and are released under the Apache License 2.0. The full text of the license is below. Modifications copyright © 2016,2021 Soren Stoutner. - The resulting image is released under the GPLv3+ license.

    -

    is derived from security and do_not_disturb, + The resulting images are released under the GPLv3+ license.

    +

    are derived from security and do_not_disturb, which are part of the Android Material icon set and are released under the Apache License 2.0. Modifications copyright © 2016,2021 Soren Stoutner. - The resulting image is released under the GPLv3+ license.

    + The resulting images are released under the GPLv3+ license.

    The following icons come from the Android Material icon set, which is released under the Apache License 2.0. They are unchanged except for layout information like color and size. Some of them have been renamed to match their use in the code. The original icons and names are shown below.

    diff --git a/app/src/main/assets/en/permissions.html b/app/src/main/assets/en/permissions.html index b97caa5..f5483ba 100644 --- a/app/src/main/assets/en/permissions.html +++ b/app/src/main/assets/en/permissions.html @@ -32,5 +32,13 @@

    Read phone status and identity

    android.permission. READ_PHONE_STATE

    Required to determine which protocols are being used by the cell phone network.

    + +

    Run foreground service

    +

    android.permission. FOREGROUND_SERVICE

    +

    Allows Privacy Cell to display a realtime monitoring notification icon in the status bar.

    + +

    Run at startup

    +

    android.permission. RECEIVE_BOOT_COMPLETED

    +

    Allows Privacy Cell to enable the realtime monitoring service when the phone boots.

    \ No newline at end of file diff --git a/app/src/main/assets/es/changelog.html b/app/src/main/assets/es/changelog.html index f19c3cd..b557708 100644 --- a/app/src/main/assets/es/changelog.html +++ b/app/src/main/assets/es/changelog.html @@ -29,8 +29,8 @@ -

    1.2 (versión del código 3)

    -

    15 de septiembre de 2021 - API mínimo 30, API objetivo 30.

    +

    1.2 (versión del código 3)

    +

    15 de septiembre de 2021 - API mínimo 30, API objetivo 30.

    • Añadir la opción de utilizar una barra de app inferior.
    • Primera traducción completa al español aportada por José A. León.
    • diff --git a/app/src/main/assets/es/contributors.html b/app/src/main/assets/es/contributors.html index ed73096..a493f6c 100644 --- a/app/src/main/assets/es/contributors.html +++ b/app/src/main/assets/es/contributors.html @@ -35,6 +35,7 @@

      Traductores

      Jose A. León: Español
      Kévin L.: Francés
      + Bernhard G. Keller: Alemán
      Francesco Buratti: Italiano
      diff --git a/app/src/main/assets/es/licenses.html b/app/src/main/assets/es/licenses.html index 4687261..8eb61d5 100644 --- a/app/src/main/assets/es/licenses.html +++ b/app/src/main/assets/es/licenses.html @@ -43,14 +43,14 @@ que se liberan bajo la Licencia Apache 2.0. El texto completo de la licencia se muestra abajo.

      Iconos

      -

      deriva de security y 5g, +

      derivan de security y 5g, que son parte del set de iconos de Android Material y se liberan bajo la Licencia Apache 2.0. El texto completo de la licencia se muestra abajo. Copyright de modificaciones © 2016,2021 Soren Stoutner. - La imagen resultante se libera bajo la licencia GPLv3+.

      -

      deriva de security y do_not_disturb, + Las imágenes resultante se liberan bajo la licencia GPLv3+.

      +

      derivan de security y do_not_disturb, que son parte del set de iconos de Android Material y se liberan bajo la Licencia Apache 2.0. Copyright de modificaciones © 2016,2021 Soren Stoutner. - La imagen resultante se libera bajo la licencia GPLv3+.

      + Las imágenes resultantes se liberan bajo la licencia GPLv3+.

      Los siguientes iconos vienen del set de iconos de Android Material, que se liberan bajo la licencia Apache 2.0. No se han modificado, salvo la información sobre el diseño, como el color y el tamaño. Algunos de ellos han sido renombrados para que coincidan con su uso en el código. diff --git a/app/src/main/assets/es/permissions.html b/app/src/main/assets/es/permissions.html index 5eb59ae..83824ed 100644 --- a/app/src/main/assets/es/permissions.html +++ b/app/src/main/assets/es/permissions.html @@ -34,5 +34,13 @@

      Leer el estado del teléfono e identidad

      android.permission. READ_PHONE_STATE

      Requerido para determinar qué protocolos se están usando por la red del teléfono celular.

      + +

      Run foreground service

      +

      android.permission. FOREGROUND_SERVICE

      +

      Allows Privacy Cell to display a realtime monitoring notification icon in the status bar.

      + +

      Run at startup

      +

      android.permission. RECEIVE_BOOT_COMPLETED

      +

      Allows Privacy Cell to enable the realtime monitoring service when the phone boots.

      \ No newline at end of file diff --git a/app/src/main/assets/fr/changelog.html b/app/src/main/assets/fr/changelog.html index f7cbe9e..5fc0821 100644 --- a/app/src/main/assets/fr/changelog.html +++ b/app/src/main/assets/fr/changelog.html @@ -29,8 +29,8 @@ -

      1.2 (version de code 3)

      -

      15 Septembre 2021 - API minimum 30, API cible 30.

      +

      1.2 (version de code 3)

      +

      15 Septembre 2021 - API minimum 30, API cible 30.

      • Ajout d'une option permettant d'utiliser un barre d'application inférieure.
      • Traduction française partielle réalisée par Kévin L.
      • diff --git a/app/src/main/assets/fr/contributors.html b/app/src/main/assets/fr/contributors.html index 13eac13..0692484 100644 --- a/app/src/main/assets/fr/contributors.html +++ b/app/src/main/assets/fr/contributors.html @@ -34,6 +34,7 @@

        Traducteurs

        Kévin L. : Français
        + Bernhard G. Keller : Allemand
        Francesco Buratti : Italien
        Jose A. León : Espagnol diff --git a/app/src/main/assets/fr/licenses.html b/app/src/main/assets/fr/licenses.html index efb2483..cb7f10c 100644 --- a/app/src/main/assets/fr/licenses.html +++ b/app/src/main/assets/fr/licenses.html @@ -43,14 +43,14 @@ qui sont publiés sous la Licence Apache 2.0. Le texte intégral de la licence se trouve ci-dessous.

        Icônes

        -

        est dérivé de security et 5g, +

        sont dérivés de security et de 5g, qui font partie de l'ensemble d'icônes Android Material et sont publiés sous la Licence Apache 2.0. Le texte intégral de la licence est ci-dessous. Modifications copyright © 2016,2021 Soren Stoutner. - L'image qui en résulte est publiée sous la licence GPLv3+.

        -

        est dérivé de security et do_not_disturb, + Les images résultantes sont publiées sous la licence GPLv3+.

        +

        sont dérivés de security et de do_not_disturb, qui font partie de l'ensemble d'icônes Android Material icon set et sont publiés sous la Licence Apache 2.0. Modifications copyright © 2016,2021 Soren Stoutner. - L'image qui en résulte est publiée sous le label licence GPLv3+.

        + Les images résultantes sont publiées sous la licence GPLv3+.

        Les icônes suivantes proviennent de l'ensemble d'icônes Android Material, qui sont publiées sous la Licence Apache 2.0. Elles sont inchangés, à l'exception des informations de mise en page comme la couleur et la taille. Certaines d'entre elles ont été renommées pour correspondre à leur utilisation dans le code. Les icônes et les noms originaux sont présentés ci-dessous.

        diff --git a/app/src/main/assets/fr/permissions.html b/app/src/main/assets/fr/permissions.html index 6a26f55..bc6dd1b 100644 --- a/app/src/main/assets/fr/permissions.html +++ b/app/src/main/assets/fr/permissions.html @@ -34,5 +34,13 @@

        Lecture du statut et de l'identité du téléphone

        android.permission. READ_PHONE_STATE

        Nécessaire pour déterminer quels protocoles sont utilisés par le réseau de téléphonie mobile.

        + +

        Run foreground service

        +

        android.permission. FOREGROUND_SERVICE

        +

        Allows Privacy Cell to display a realtime monitoring notification icon in the status bar.

        + +

        Run at startup

        +

        android.permission. RECEIVE_BOOT_COMPLETED

        +

        Allows Privacy Cell to enable the realtime monitoring service when the phone boots.

        \ No newline at end of file diff --git a/app/src/main/assets/images/insecure_notification.svg b/app/src/main/assets/images/insecure_notification.svg new file mode 100644 index 0000000..3c62866 --- /dev/null +++ b/app/src/main/assets/images/insecure_notification.svg @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/app/src/main/assets/images/secure_notification.svg b/app/src/main/assets/images/secure_notification.svg new file mode 100644 index 0000000..bb32173 --- /dev/null +++ b/app/src/main/assets/images/secure_notification.svg @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/app/src/main/assets/it/changelog.html b/app/src/main/assets/it/changelog.html index d28a1b2..8b1390b 100644 --- a/app/src/main/assets/it/changelog.html +++ b/app/src/main/assets/it/changelog.html @@ -29,8 +29,8 @@ -

        1.2 (versione codice 3)

        -

        15 Settembre 2021 - minima API 30, target API 30.

        +

        1.2 (versione codice 3)

        +

        15 Settembre 2021 - minima API 30, target API 30.

        • Aggiunta l'opzione per avere la barra dell'app nella parte inferiore dello schermo.
        • Traduzione parziale in Italiano da parte di Francesco Buratti.
        • diff --git a/app/src/main/assets/it/contributors.html b/app/src/main/assets/it/contributors.html index 620bde7..88c5d4d 100644 --- a/app/src/main/assets/it/contributors.html +++ b/app/src/main/assets/it/contributors.html @@ -35,6 +35,7 @@

          Traduttori

          Francesco Buratti: Italiano
          Kévin L.: Francese
          + Bernhard G. Keller: Tedesco
          Jose A. León: Spagnolo
          diff --git a/app/src/main/assets/it/licenses.html b/app/src/main/assets/it/licenses.html index 43dbe86..3a00ff0 100644 --- a/app/src/main/assets/it/licenses.html +++ b/app/src/main/assets/it/licenses.html @@ -32,28 +32,29 @@

          Copyright

          Privacy Cell copyright © 2021 Soren Stoutner.

          -

          License

          -

          Privacy Cell is released under the GPLv3+ license. The full text of the license is below. - The source code is available from gitweb.stoutner.com.

          - -

          Libraries

          -

          Privacy Cell is built with the AndroidX Libraries, - the Kotlin libraries, - and code from the Google Material Maven repository, - which are released under the Apache License 2.0. The full text of the license is below.

          - -

          Icons

          -

          is derived from security and 5g, - which are part of the Android Material icon set and are released under the Apache License 2.0. - The full text of the license is below. Modifications copyright © 2016,2021 Soren Stoutner. - The resulting image is released under the GPLv3+ license.

          -

          is derived from security and do_not_disturb, - which are part of the Android Material icon set and are released under the Apache License 2.0. - Modifications copyright © 2016,2021 Soren Stoutner. - The resulting image is released under the GPLv3+ license.

          -

          The following icons come from the Android Material icon set, - which is released under the Apache License 2.0. - They are unchanged except for layout information like color and size. Some of them have been renamed to match their use in the code. The original icons and names are shown below.

          +

          Licenza

          +

          Privacy Cell è rilasciato con Licenza GPLv3+. Il testo completo è riportato di seguito. + Il codice sorgente è disponibile su gitweb.stoutner.com.

          + +

          Librerie

          +

          Privacy Cell è compilato con le Librerie AndroidX, + le Librerie Kotlin, + e codice tratto da Google Material Maven repository, + che sono rilasciati sotto Licenza Apache 2.0. Il testo completo della licenza è riportato di seguito.

          + +

          Icone

          +

          sono derivate da security e 5g, + che sono parte del set di icone Android Material e sono rilasciate sotto la Licenza Apache 2.0. + Il testo completo della licenza è riportato qui sotto. Il copyright delle modifiche © 2016,2021 appartiene a Soren Stoutner. + Le immagini risultanti sono rilasciate sotto la Licenza GPLv3+.

          +

          sono derivate da security e do_not_disturb, + che sono parte del set di icone Android Material e sono rilasciate sotto la Licenza Apache 2.0. + Il copyright delle modifiche © 2016,2021 appartiene a Soren Stoutner. + Le immagini risultanti sono rilasciate sotto la Licenza GPLv3+.

          +

          Le icone seguenti provengono dal set di icone Android Material, + che è rilasciato sotto la Licenza Apache 2.0. + Non sono state modificate ad eccezione delle informazioni del layout come il colore e le dimensioni. Alcune sono state rinominate per essere coerenti con il loro utilizzo nel codice. + Le icone originali e i loro nomi sono riportate di seguito.

          bug_report_rounded.

          call_to_action_rounded.

          chrome_reader_mode_rounded.

          diff --git a/app/src/main/assets/it/permissions.html b/app/src/main/assets/it/permissions.html index 575ab51..f904133 100644 --- a/app/src/main/assets/it/permissions.html +++ b/app/src/main/assets/it/permissions.html @@ -34,5 +34,13 @@

          Lettura dello stato e dell'identità del telefono

          android.permission. READ_PHONE_STATE

          Richiesta per determinare i protocolli utilizzati dalla rete.

          + +

          Run foreground service

          +

          android.permission. FOREGROUND_SERVICE

          +

          Allows Privacy Cell to display a realtime monitoring notification icon in the status bar.

          + +

          Run at startup

          +

          android.permission. RECEIVE_BOOT_COMPLETED

          +

          Allows Privacy Cell to enable the realtime monitoring service when the phone boots.

          \ No newline at end of file diff --git a/app/src/main/assets/it/privacy_policy.html b/app/src/main/assets/it/privacy_policy.html index 52a43f2..f2ba655 100644 --- a/app/src/main/assets/it/privacy_policy.html +++ b/app/src/main/assets/it/privacy_policy.html @@ -30,61 +30,61 @@

          Privacy Cell

          -

          Privacy Cell does not collect any user information.

          +

          Privacy Cell non raccoglie alcuna informazione dagli utenti.

          Google Play

          -

          Google Play has its own privacy policy. - Google provides anonymized summary installation information to developers, including the number of installs organized by the following categories.

          +

          Google Play ha una propria privacy policy. + Google fornisce agli sviluppatori informazioni anonime sulle installazioni, incluso il numero di installazioni, secondo le seguenti categorie.

            -
          • Android version (eg. Android 7.1)
          • -
          • Device (eg. Samsung Galaxy S6 [zeroflte])
          • -
          • Tablets (eg. Tablets 10" and above)
          • -
          • Country (eg. United States)
          • -
          • Language (eg. English [United States])
          • -
          • App version (eg. 14)
          • -
          • Carrier (eg. T-Mobile – US)
          • +
          • Versione Android (es. Android 7.1)
          • +
          • Dispositivo (es. Samsung Galaxy S6 [zeroflte])
          • +
          • Tablet (es. Tablet 10" o superiore)
          • +
          • Nazione (es. United States)
          • +
          • Lingua (es. English [United States])
          • +
          • Versione App (es. 14)
          • +
          • Vettore (es. T-Mobile - US)
          -

          Google Play Ratings

          -

          Google Play has its own privacy policy. - Google provides developers with anonymized summaries of the following information related to user ratings.

          +

          Ratings di Google Play

          +

          Google Play ha una propria privacy policy. + Google fornisce agli sviluppatori sintesi anonime delle seguenti informazioni collegate ai ratings degli utenti.

            -
          • Country (eg. United States)
          • -
          • Language (eg. English)
          • -
          • App version (eg. 14)
          • -
          • Android version (eg. 7.1)
          • -
          • Device (eg. Google Nexus 5X [bullhead])
          • -
          • Tablets (eg. Tablets 10" and above)
          • +
          • Nazione (es. United States)
          • +
          • Lingua (es. English)
          • +
          • Versione App (es. 14)
          • +
          • Versione Android (es. Android 7.1)
          • +
          • Dispositivo (es. Google Nexus 5X [bullhead])
          • +
          • Tablet (es. Tablets 10" o superiore)
          -

          Google Play Reviews

          -

          Google Play has its own privacy policy. - In addition to the name of the reviewer, the rating, and the text of the review (which are all available publicly), Google provides some or all of the following information to the developer.

          +

          Recensioni di Google Play

          +

          Google Play ha una propria privacy policy. + Oltre al nome del recensore, al rating, e al testo della recensione (i quali sono tutti pubblicamente disponibili), Google fornisce alcune o tutte le seguenti informazioni allo sviluppatore.

            -
          • Version code (eg. 7)
          • -
          • Version name (eg. 1.6)
          • -
          • Android version (eg. Android 5.1)
          • -
          • Device (eg. Galaxy S6 Edge+ [zenlte])
          • -
          • Manufacturer (eg. Samsung)
          • -
          • Device type (eg. Phone)
          • -
          • CPU make (eg. Samsung)
          • -
          • CPU model (eg. Exynos 7420)
          • -
          • Screen density (eg. 560 dpi)
          • -
          • Screen size (eg. 2560 x 1440)
          • -
          • RAM (eg. 4096 MB)
          • -
          • Native platform (eg. armeabi-v7a,armeabi,arm64v8a)
          • -
          • OpenGL ES version (eg. 3.1)
          • -
          • Device language (eg. English)
          • +
          • Codice Versione (es. 7)
          • +
          • Nome Versione (es. 1.6)
          • +
          • Versione Android (es. Android 5.1)
          • +
          • Dispositivo (es. Galaxy S6 Edge+ [zenlte])
          • +
          • Costruttore (es. Samsung)
          • +
          • Tipo di dispositivo (es. SmartPhone)
          • +
          • Produttore CPU (es. Samsung)
          • +
          • Modello CPU (es. Exynos 7420)
          • +
          • Risoluzione schermo (es. 560 dpi)
          • +
          • Dimensione Schermo (es. 2560 x 1440)
          • +
          • RAM (es. 4096 MB)
          • +
          • Piattaforma nativa (es. armeabi-v7a,armeabi,arm64v8a)
          • +
          • Versione OpenGL ES (es. 3.1)
          • +
          • Lingua del dispositivo (es. English)
          -

          Direct Communications

          -

          Users may choose to send direct communications to Stoutner, like email messages and comments on stoutner.com.

          +

          Comunicazioni Dirette

          +

          E' possibile inviare comunicazioni dirette a Stoutner, ad esempio email o commenti su stoutner.com.

          -

          Use of Information

          -

          Stoutner may use this information to assist in the development of Privacy Cell and communicate the status of the project to users. - Stoutner will never sell the information nor transfer it to any third party that would use it for advertising or marketing.

          +

          Uso delle informazioni

          +

          Stoutner si riserva di utilizzare queste informazioni per lo sviluppo di Privacy Cell e per comunicare lo stato del progetto agli utenti. + Stoutner non vendera' mai ne trasferira' le informazioni ad alcuna terza parte che possa utilizzarle per scopi pubblicitari o di marketing.


          -

          Revision 1.0, 23 August 2021

          +

          Revisione 1.0, 23 Agosto 2021

          \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCellActivity.kt b/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCellActivity.kt index 296a952..cd0e1a1 100644 --- a/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCellActivity.kt +++ b/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCellActivity.kt @@ -20,6 +20,7 @@ package com.stoutner.privacycell.activities import android.Manifest +import android.app.ActivityManager import android.content.Context import android.content.Intent import android.content.pm.PackageManager @@ -50,6 +51,7 @@ import com.google.android.material.navigation.NavigationView import com.stoutner.privacycell.R import com.stoutner.privacycell.dialogs.PhonePermissionDialog import com.stoutner.privacycell.dialogs.WebViewDialog +import com.stoutner.privacycell.services.RealtimeMonitoringService class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener { // Declare the class variables. @@ -79,7 +81,8 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem // Get a handle for the shared preferences. val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) - // Get the bottom app bar preference. + // Get the preferences. + val realtimeMonitoring = sharedPreferences.getBoolean(getString(R.string.realtime_monitoring_key), false) val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false) // Set the content view. @@ -147,6 +150,20 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem // Do nothing. } }) + + // Start the realtime monitoring service if it is enabled. + if (realtimeMonitoring) { + // Get a handle for the activity manager. + val activityManager: ActivityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + + // Get a list of the running service info. The deprecated `getRunningServices()` now only returns services stared by Privacy Cell, but that is all we want to know anyway. + val runningServiceInfoList: List = activityManager.getRunningServices(1) + + // Start the service if it is not already running. + if (runningServiceInfoList.isEmpty()) { + startService(Intent(this, RealtimeMonitoringService::class.java)) + } + } } override fun onPostCreate(savedInstanceState: Bundle?) { @@ -164,7 +181,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem // Check to see if the read phone state permission has been granted. These commands need to be run on every resume so that the listener gets reassigned as it is automatically paused. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted. // Populate Privacy Cell. - populatePrivacyCell() + populatePrivacyCell(this) } else { // The phone permission has not been granted. // Check if the user has previously denied the storage permission. if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) { // Show a dialog explaining the request first. @@ -311,7 +328,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem // Check to see if the read phone state permission was granted. If the dialog was canceled the grant results will be empty. if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // The read phone state permission was granted. // Populate Privacy Cell. - populatePrivacyCell() + populatePrivacyCell(this) } else { // The read phone state permission was denied. // Display the phone permission text on the main activity. stingrayTextView.text = getString(R.string.phone_permission_text) @@ -319,7 +336,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem } } - private fun populatePrivacyCell() { + private fun populatePrivacyCell(context: Context) { // Listen to changes in the cell network state. telephonyManager.listen(object : PhoneStateListener() { override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) { diff --git a/app/src/main/java/com/stoutner/privacycell/fragments/SettingsFragment.kt b/app/src/main/java/com/stoutner/privacycell/fragments/SettingsFragment.kt index 0cf6c6f..f23a116 100644 --- a/app/src/main/java/com/stoutner/privacycell/fragments/SettingsFragment.kt +++ b/app/src/main/java/com/stoutner/privacycell/fragments/SettingsFragment.kt @@ -24,17 +24,20 @@ import android.content.SharedPreferences import android.os.Bundle import android.os.Handler import android.os.Looper +import android.provider.Settings import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import com.stoutner.privacycell.R +import com.stoutner.privacycell.services.RealtimeMonitoringService class SettingsFragment : PreferenceFragmentCompat() { // Declare the class variables. private lateinit var sharedPreferenceChangeListener: SharedPreferences.OnSharedPreferenceChangeListener // Declare the class views. + private lateinit var realtimeMonitoringPreference: Preference private lateinit var bottomAppBarPreference: Preference override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { @@ -45,8 +48,36 @@ class SettingsFragment : PreferenceFragmentCompat() { val sharedPreferences = preferenceScreen.sharedPreferences // Get handles for the preferences. + realtimeMonitoringPreference = findPreference(getString(R.string.realtime_monitoring_key))!! + val secureNetworkNotificationPreference = findPreference(getString(R.string.secure_network_notification_key))!! + val insecureNetworkNotificationPreference = findPreference(getString(R.string.insecure_network_notification_key))!! bottomAppBarPreference = findPreference(getString(R.string.bottom_app_bar_key))!! + // Set the realtime monitoring preference icon. + if (sharedPreferences.getBoolean(getString(R.string.realtime_monitoring_key), false)) { + // Set the enabled icon. + realtimeMonitoringPreference.setIcon(R.drawable.realtime_monitoring_enabled) + } else { + // Set the disabled icon. + realtimeMonitoringPreference.setIcon(R.drawable.realtime_monitoring_disabled) + } + + // Set the notification preferences to depend on the realtime monitoring preference. + secureNetworkNotificationPreference.dependency = getString(R.string.realtime_monitoring_key) + insecureNetworkNotificationPreference.dependency = getString(R.string.realtime_monitoring_key) + + // Create the notification intents. + val secureNetworkNotificationIntent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) + .putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName) + .putExtra(Settings.EXTRA_CHANNEL_ID, RealtimeMonitoringService.SECURE_NETWORK) + val insecureNetworkNotificationIntent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) + .putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName) + .putExtra(Settings.EXTRA_CHANNEL_ID, RealtimeMonitoringService.INSECURE_NETWORK) + + // Set the notification preference intents. + secureNetworkNotificationPreference.intent = secureNetworkNotificationIntent + insecureNetworkNotificationPreference.intent = insecureNetworkNotificationIntent + // Set the bottom app bar preference icon. if (sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)) { // Set the enabled icon. @@ -88,7 +119,27 @@ class SettingsFragment : PreferenceFragmentCompat() { // Return the shared preference change listener. return SharedPreferences.OnSharedPreferenceChangeListener {sharedPreferences, key -> when (key) { - "bottom_app_bar" -> { + getString(R.string.realtime_monitoring_key) -> { + // Update the icon. + if (sharedPreferences.getBoolean(getString(R.string.realtime_monitoring_key), false)) { + // Set the enabled icon. + realtimeMonitoringPreference.setIcon(R.drawable.realtime_monitoring_enabled) + } else { + // Set the disabled icon. + realtimeMonitoringPreference.setIcon(R.drawable.realtime_monitoring_disabled) + } + + // Start or stop the service. + if (sharedPreferences.getBoolean(getString(R.string.realtime_monitoring_key), false)) { // Realtime monitoring has been enabled. + // Start the realtime monitoring service. + requireActivity().startService(Intent(context, RealtimeMonitoringService::class.java)) + } else { // Realtime monitoring has been disabled. + // Stop the realtime monitoring service. + requireActivity().stopService(Intent(context, RealtimeMonitoringService::class.java)) + } + } + + getString(R.string.bottom_app_bar_key) -> { // Update the icon. if (sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)) { // Set the enabled icon. diff --git a/app/src/main/java/com/stoutner/privacycell/receivers/OnBootCompletedReceiver.kt b/app/src/main/java/com/stoutner/privacycell/receivers/OnBootCompletedReceiver.kt new file mode 100644 index 0000000..54e23e9 --- /dev/null +++ b/app/src/main/java/com/stoutner/privacycell/receivers/OnBootCompletedReceiver.kt @@ -0,0 +1,45 @@ +/* + * Copyright © 2021 Soren Stoutner . + * + * This file is part of Privacy Cell . + * + * Privacy Cell 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 Cell 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 Cell. If not, see . + */ + +package com.stoutner.privacycell.receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import androidx.preference.PreferenceManager +import com.stoutner.privacycell.R +import com.stoutner.privacycell.services.RealtimeMonitoringService + +class OnBootCompletedReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + // Check to make sure the system ACTION_BOOT_COMPLETED initiated the receiver. + if (intent.action == Intent.ACTION_BOOT_COMPLETED) { + // Get a handle for the shared preferences. + val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) + + // Get the realtime monitoring preference. + val realtimeMonitoring = sharedPreferences.getBoolean(context.getString(R.string.realtime_monitoring_key), false) + + // Start the realtime monitoring service if it is enabled. + if (realtimeMonitoring) { + context.startForegroundService(Intent(context, RealtimeMonitoringService::class.java)) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacycell/services/RealtimeMonitoringService.kt b/app/src/main/java/com/stoutner/privacycell/services/RealtimeMonitoringService.kt new file mode 100644 index 0000000..dc5b494 --- /dev/null +++ b/app/src/main/java/com/stoutner/privacycell/services/RealtimeMonitoringService.kt @@ -0,0 +1,170 @@ +/* + * Copyright © 2021 Soren Stoutner . + * + * This file is part of Privacy Cell . + * + * Privacy Cell 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 Cell 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 Cell. If not, see . + */ + +package com.stoutner.privacycell.services + +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationChannelGroup +import android.app.NotificationManager +import android.app.PendingIntent +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.IBinder +import android.telephony.PhoneStateListener +import android.telephony.TelephonyDisplayInfo +import android.telephony.TelephonyManager + +import com.stoutner.privacycell.R +import com.stoutner.privacycell.activities.PrivacyCellActivity + +// Define the class constants. +const val REALTIME_MONITORING = "realtime_monitoring" +const val NOTIFICATION_ID = 1 + +class RealtimeMonitoringService : Service() { + companion object { + // Define the public constants. + const val SECURE_NETWORK = "secure_network" + const val INSECURE_NETWORK = "insecure_network" + } + + override fun onBind(intent: Intent?): IBinder? { + // Do nothing. + return null + } + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + // Get a handle for the notification manager. + val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + + // Create a notification channel group. + notificationManager.createNotificationChannelGroup(NotificationChannelGroup(REALTIME_MONITORING, getString(R.string.realtime_monitoring))) + + // Prepare the notification channels. + val secureNetworkChannel = NotificationChannel(SECURE_NETWORK, getString(R.string.secure_network_channel), NotificationManager.IMPORTANCE_DEFAULT) + val insecureNetworkChannel = NotificationChannel(INSECURE_NETWORK, getString(R.string.insecure_network_channel), NotificationManager.IMPORTANCE_DEFAULT) + + // Set the notification channel group. + secureNetworkChannel.group = REALTIME_MONITORING + insecureNetworkChannel.group = REALTIME_MONITORING + + // Disable the notification dots. + secureNetworkChannel.setShowBadge(false) + insecureNetworkChannel.setShowBadge(false) + + // Set the notifications to be public. + secureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC + insecureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC + + // Create the notification channels. + notificationManager.createNotificationChannel(secureNetworkChannel) + notificationManager.createNotificationChannel(insecureNetworkChannel) + + // Create a notification builder. + val notificationBuilder = Notification.Builder(this, INSECURE_NETWORK) + + // Create an intent to open Privacy Cell. + val privacyCellIntent = Intent(this, PrivacyCellActivity::class.java) + + // Create a pending intent from the Privacy Cell intent. + val privacyCellPendingIntent = PendingIntent.getActivity(this, 0, privacyCellIntent, PendingIntent.FLAG_IMMUTABLE) + + // Set the notification to open Privacy Cell. + notificationBuilder.setContentIntent(privacyCellPendingIntent) + + // Set the notification text. + notificationBuilder.setContentText(getString(R.string.unknown_network)) + + // Set the notification icon. + notificationBuilder.setSmallIcon(R.drawable.insecure_notification) + + // Set the color. + notificationBuilder.setColor(getColor(R.color.red_text)) + + // Start the foreground notification. + startForeground(NOTIFICATION_ID, notificationBuilder.build()) + + // Get a handle for the telephony manager and the context. + val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + + // Initialize the current status. + var currentStatus = "" + + // Listen for changes to the phone state. + telephonyManager.listen(object : PhoneStateListener() { + override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) { + // Populate the notification according to the network type. + if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) { // This is a secure 5G NR SA network. + // Only update the notification if the network status has changed. + if (currentStatus != SECURE_NETWORK) { + // Create a secure network notification builder. + val secureNetworkNotificationBuilder = Notification.Builder(applicationContext, SECURE_NETWORK) + + // Set the notification to open Privacy Cell. + secureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent) + + // Set the notification text. + secureNetworkNotificationBuilder.setContentText(getString(R.string.secure_network)) + + // Set the notification icon. + secureNetworkNotificationBuilder.setSmallIcon(R.drawable.secure_notification) + + // Set the color. + secureNetworkNotificationBuilder.setColor(getColor(R.color.blue_text)) + + // Update the notification. + notificationManager.notify(NOTIFICATION_ID, secureNetworkNotificationBuilder.build()) + + // Store the new network status. + currentStatus = SECURE_NETWORK + } + } else { // This is not a secure 5G NR SA network. + // Only update the notification if the network status has changed. + if (currentStatus !=INSECURE_NETWORK) { + // Create an insecure network notification builder. + val insecureNetworkNotificationBuilder = Notification.Builder(applicationContext, INSECURE_NETWORK) + + // Set the notification to open Privacy Cell. + insecureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent) + + // Set the notification text. + insecureNetworkNotificationBuilder.setContentText(getString(R.string.insecure_network)) + + // Set the notification icon. + insecureNetworkNotificationBuilder.setSmallIcon(R.drawable.insecure_notification) + + // Set the color. + insecureNetworkNotificationBuilder.setColor(getColor(R.color.red_text)) + + // Update the notification. + notificationManager.notify(NOTIFICATION_ID, insecureNetworkNotificationBuilder.build()) + + // Store the new network status. + currentStatus = INSECURE_NETWORK + } + } + } + }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) + + // Return a sticky service. + return START_STICKY + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/insecure_notification.xml b/app/src/main/res/drawable/insecure_notification.xml new file mode 100644 index 0000000..127b0f1 --- /dev/null +++ b/app/src/main/res/drawable/insecure_notification.xml @@ -0,0 +1,31 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/realtime_monitoring_disabled.xml b/app/src/main/res/drawable/realtime_monitoring_disabled.xml new file mode 100644 index 0000000..83b6e26 --- /dev/null +++ b/app/src/main/res/drawable/realtime_monitoring_disabled.xml @@ -0,0 +1,31 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/realtime_monitoring_enabled.xml b/app/src/main/res/drawable/realtime_monitoring_enabled.xml new file mode 100644 index 0000000..d255c8c --- /dev/null +++ b/app/src/main/res/drawable/realtime_monitoring_enabled.xml @@ -0,0 +1,31 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/secure_notification.xml b/app/src/main/res/drawable/secure_notification.xml new file mode 100644 index 0000000..ce61836 --- /dev/null +++ b/app/src/main/res/drawable/secure_notification.xml @@ -0,0 +1,31 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fdf38ee..060539f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,6 +52,12 @@ Donations + Monitoring + Realtime monitoring + Place an icon in the status bar that monitors the cell network. + Secure network notification + Insecure network notification + Interface Bottom app bar Move the app bar to the bottom of the screen. Changing this setting will restart Privacy Cell. @@ -117,6 +123,20 @@ Stingrays Close + + Secure + Insecure + You are connected to a secure network. + You are not connected to a secure network. + The security of the network is unknown. + Secure network + Insecure network + + monitoring + realtime_monitoring + secure_network_notification + insecure_network_notification + interface bottom_app_bar \ No newline at end of file diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index d31fafb..d41c3ca 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -18,10 +18,36 @@ You should have received a copy of the GNU General Public License along with Privacy Cell. If not, see . --> - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index a42d6c4..941d2e1 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.0.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.30" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files -- 2.43.0