From 578979a47d905469cfc5c7cdc748fe9b539437e2 Mon Sep 17 00:00:00 2001 From: Soren Stoutner <soren@stoutner.com> Date: Fri, 20 Aug 2021 13:06:18 -0700 Subject: [PATCH] Populate the permissions menu entry. --- app/build.gradle | 1 + app/src/main/assets/css/theme.css | 50 ++++++++++++ app/src/main/assets/en/permissions.html | 36 +++++++++ .../privacycell/activities/PrivacyCell.kt | 49 ++++++++---- .../privacycell/dialogs/PermissionsDialog.kt | 78 +++++++++++++++++++ .../dialogs/PhonePermissionDialog.kt | 2 +- app/src/main/res/drawable/permissions.xml | 29 +++++++ .../main/res/layout/permissions_dialog.xml | 34 ++++++++ .../res/menu/navigation_menu_top_appbar.xml | 2 +- app/src/main/res/values/strings.xml | 3 + 10 files changed, 266 insertions(+), 18 deletions(-) create mode 100644 app/src/main/assets/css/theme.css create mode 100644 app/src/main/assets/en/permissions.html create mode 100644 app/src/main/java/com/stoutner/privacycell/dialogs/PermissionsDialog.kt create mode 100644 app/src/main/res/drawable/permissions.xml create mode 100644 app/src/main/res/layout/permissions_dialog.xml diff --git a/app/build.gradle b/app/build.gradle index 14a34a2..5ddfaba 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -51,6 +51,7 @@ dependencies { // Include the following AndroidX libraries. implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' + 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.21' diff --git a/app/src/main/assets/css/theme.css b/app/src/main/assets/css/theme.css new file mode 100644 index 0000000..2ccd34c --- /dev/null +++ b/app/src/main/assets/css/theme.css @@ -0,0 +1,50 @@ +/* + * Copyright © 2021 Soren Stoutner <soren@stoutner.com>. + * + * This file is part of Privacy Cell <https://www.stoutner.com/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 Browser. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Dark colors. */ +@media (prefers-color-scheme: dark) { + body { + color: #C1C1C1; /* Gray 350 */ + background-color: #424242; /* Gray 800 */ + } +} + +/* Hyperlinks. */ +a { + color: #1976D2; /* Blue 700 */ + text-decoration: none; +} + +@media (prefers-color-scheme: dark) { + a { + color: #5785C5; /* Violet 700 */ + } +} + + +/* Headers. */ +h3 { + color: #0D47A1; /* Blue 900 */ +} + +@media (prefers-color-scheme: dark) { + h3 { + color: #8AB4F8; /* Violet 500 */ + } +} \ No newline at end of file diff --git a/app/src/main/assets/en/permissions.html b/app/src/main/assets/en/permissions.html new file mode 100644 index 0000000..5207e2e --- /dev/null +++ b/app/src/main/assets/en/permissions.html @@ -0,0 +1,36 @@ +<!-- + Copyright © 2021 Soren Stoutner <soren@stoutner.com>. + + This file is part of Privacy Cell <https://www.stoutner.com/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 Browser. If not, see <http://www.gnu.org/licenses/>. --> + +<html> + <head> + <meta charset="UTF-8"> + + <link rel="stylesheet" href="../css/theme.css"> + + <!-- Setting the color scheme instructs the WebView to respect `prefers-color-scheme` @media CSS. --> + <meta name="color-scheme" content="light dark"> + </head> + + <body> + <p>Privacy Cell uses the following permission.</p> + + <h3>Phone</h3> + <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">READ_PHONE_STATE</a></p> + <p>Required to determine which protocols are being used by the cell phone network.</p> + </body> +</html> \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCell.kt b/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCell.kt index 8f482b0..a886347 100644 --- a/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCell.kt +++ b/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCell.kt @@ -38,12 +38,13 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.widget.Toolbar import androidx.core.app.ActivityCompat +import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout -import androidx.fragment.app.DialogFragment import com.google.android.material.navigation.NavigationView import com.stoutner.privacycell.R +import com.stoutner.privacycell.dialogs.PermissionsDialog import com.stoutner.privacycell.dialogs.PhonePermissionDialog class PrivacyCell : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener { @@ -53,14 +54,15 @@ class PrivacyCell : AppCompatActivity(), NavigationView.OnNavigationItemSelected private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle // Declare the views. - lateinit var secureFromStingrayImageView: ImageView - lateinit var secureFromStingrayTextView: TextView - lateinit var voiceNetworkTextView: TextView - lateinit var voiceNetworkDetailsTextView: TextView - lateinit var dataNetworkTextView: TextView - lateinit var dataNetworkDetailsTextView: TextView - lateinit var additionalNetworkInfoTextView: TextView - lateinit var additionalNetworkInfoDetailsTextView: TextView + private lateinit var drawerLayout: DrawerLayout + private lateinit var secureFromStingrayImageView: ImageView + private lateinit var secureFromStingrayTextView: TextView + private lateinit var voiceNetworkTextView: TextView + private lateinit var voiceNetworkDetailsTextView: TextView + private lateinit var dataNetworkTextView: TextView + private lateinit var dataNetworkDetailsTextView: TextView + private lateinit var additionalNetworkInfoTextView: TextView + private lateinit var additionalNetworkInfoDetailsTextView: TextView override fun onCreate(savedInstanceState: Bundle?) { // Run the default commands. @@ -70,7 +72,7 @@ class PrivacyCell : AppCompatActivity(), NavigationView.OnNavigationItemSelected setContentView(R.layout.privacy_cell_drawerlayout) // Get handles for the views. - val drawerLayout = findViewById<DrawerLayout>(R.id.drawerlayout) + drawerLayout = findViewById(R.id.drawerlayout) val toolbar = findViewById<Toolbar>(R.id.toolbar) secureFromStingrayImageView = findViewById(R.id.secure_from_stingray_imageview) secureFromStingrayTextView = findViewById(R.id.secure_from_stingray_textview) @@ -147,7 +149,7 @@ class PrivacyCell : AppCompatActivity(), NavigationView.OnNavigationItemSelected // Check to see if a phone permission dialog is already displayed. This happens if the app is restarted when the dialog is shown. if (supportFragmentManager.findFragmentByTag(getString(R.string.phone_permission)) == null) { // No dialog is currently shown. // Instantiate the phone permission dialog fragment. - val phonePermissionDialogFragment: DialogFragment = PhonePermissionDialog() + val phonePermissionDialogFragment = PhonePermissionDialog() // Show the phone permission alert dialog. The permission will be requested when the dialog is closed. phonePermissionDialogFragment.show(supportFragmentManager, getString(R.string.phone_permission)) @@ -159,6 +161,26 @@ class PrivacyCell : AppCompatActivity(), NavigationView.OnNavigationItemSelected } } + override fun onNavigationItemSelected(menuItem: MenuItem) : Boolean { + // Get the menu item ID. + val menuItemId = menuItem.itemId + + // Run the commands that correspond to the selected menu item. + if (menuItemId == R.id.permissions) { // Permissions. + // Instantiate the permissions dialog fragment. + val permissionsDialogFragment = PermissionsDialog() + + // Show the permissions alert dialog. + permissionsDialogFragment.show(supportFragmentManager, getString(R.string.phone_permission)) + } + + // Close the navigation drawer. + drawerLayout.closeDrawer(GravityCompat.START) + + // Consume the click. + return true + } + override fun onCloseStoragePermissionDialog() { // Request the read phone state permission. There is only one permission request in the app, so it has a request code of 0. ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0) @@ -269,9 +291,4 @@ class PrivacyCell : AppCompatActivity(), NavigationView.OnNavigationItemSelected else -> arrayOf(getString(R.string.error), "") } } - - override fun onNavigationItemSelected(menuItem: MenuItem) : Boolean { - // TODO. - return true - } } \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacycell/dialogs/PermissionsDialog.kt b/app/src/main/java/com/stoutner/privacycell/dialogs/PermissionsDialog.kt new file mode 100644 index 0000000..8cf799e --- /dev/null +++ b/app/src/main/java/com/stoutner/privacycell/dialogs/PermissionsDialog.kt @@ -0,0 +1,78 @@ +/* + * Copyright © 2021 Soren Stoutner <soren@stoutner.com>. + * + * This file is part of Privacy Cell <https://www.stoutner.com/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 Browser. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.stoutner.privacycell.dialogs + +import android.app.Dialog +import android.content.res.Configuration +import android.os.Bundle +import android.webkit.WebView + +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import androidx.webkit.WebSettingsCompat +import androidx.webkit.WebViewFeature + +import com.stoutner.privacycell.R + +class PermissionsDialog : DialogFragment() { + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + // Use a builder to create the alert dialog. + val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.Theme_PrivacyCellAlertDialog) + + // Set the icon. + dialogBuilder.setIcon(R.drawable.permissions) + + // Set the title. + dialogBuilder.setTitle(R.string.permissions) + + // Set the view. + dialogBuilder.setView(R.layout.permissions_dialog) + + // Set a listener on the close button. Using `null` as the listener closes the dialog without doing anything else. + dialogBuilder.setNegativeButton(R.string.close, null) + + // Create an alert dialog from the builder. + val alertDialog = dialogBuilder.create() + + // The alert dialog needs to be shown before the contents can be modified. + alertDialog.show() + + // Get a handle for the WebView. + val webView = alertDialog.findViewById<WebView>(R.id.webview)!! + + // Get the current theme status. + val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK + + // Check to see if the app is in night mode. + if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { // The app is in night mode. + // Apply the dark WebView theme. + WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON) + } + + // Create a WebView asset loader. TODO. + // val webViewAssetLoader = WebViewAssetLoader.Builder().addPathHandler("/assets/", WebViewAssetLoader.AssetsPathHandler(requireContext())).build() + + // Load the WebView data. + webView.loadUrl("file:///android_asset/en/permissions.html") + + // Return the alert dialog. + return alertDialog + } +} \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacycell/dialogs/PhonePermissionDialog.kt b/app/src/main/java/com/stoutner/privacycell/dialogs/PhonePermissionDialog.kt index f6a0d38..df5fa9f 100644 --- a/app/src/main/java/com/stoutner/privacycell/dialogs/PhonePermissionDialog.kt +++ b/app/src/main/java/com/stoutner/privacycell/dialogs/PhonePermissionDialog.kt @@ -48,7 +48,7 @@ class PhonePermissionDialog : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { // Use a builder to create the alert dialog. - val dialogBuilder: AlertDialog.Builder = AlertDialog.Builder(requireContext(), R.style.Theme_PrivacyCellAlertDialog) + val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.Theme_PrivacyCellAlertDialog) // Set the icon. dialogBuilder.setIcon(R.drawable.phone_permission) diff --git a/app/src/main/res/drawable/permissions.xml b/app/src/main/res/drawable/permissions.xml new file mode 100644 index 0000000..7862822 --- /dev/null +++ b/app/src/main/res/drawable/permissions.xml @@ -0,0 +1,29 @@ +<!-- This file comes from the Android Material icon set, where it is called `fact_check`. It is released under the Apache License 2.0. --> + +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:width="24dp" + android:viewportHeight="24" + android:viewportWidth="24" > + + <path + android:fillColor="@color/icon" + android:pathData="M20,3H4C2.9,3 2,3.9 2,5v14c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V5C22,3.9 21.1,3 20,3zM20,19H4V5h16V19z" /> + + <path + android:fillColor="@color/icon" + android:pathData="M19.41,10.42l-1.42,-1.42l-3.17,3.17l-1.41,-1.42l-1.41,1.41l2.82,2.84z" /> + + <path + android:fillColor="@color/icon" + android:pathData="M5,7h5v2h-5z" /> + + <path + android:fillColor="@color/icon" + android:pathData="M5,11h5v2h-5z" /> + + <path + android:fillColor="@color/icon" + android:pathData="M5,15h5v2h-5z" /> +</vector> diff --git a/app/src/main/res/layout/permissions_dialog.xml b/app/src/main/res/layout/permissions_dialog.xml new file mode 100644 index 0000000..0c20a55 --- /dev/null +++ b/app/src/main/res/layout/permissions_dialog.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + Copyright © 2021 Soren Stoutner <soren@stoutner.com>. + + This file is part of Privacy Cell <https://www.stoutner.com/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 Browser. If not, see <http://www.gnu.org/licenses/>. --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:orientation="vertical" + android:paddingTop="10dp" + android:paddingStart="5dp" + android:paddingEnd="5dp" > + + <WebView + android:id="@+id/webview" + android:layout_height="wrap_content" + android:layout_width="wrap_content" /> +</LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/menu/navigation_menu_top_appbar.xml b/app/src/main/res/menu/navigation_menu_top_appbar.xml index bd33b0c..b4b9e73 100644 --- a/app/src/main/res/menu/navigation_menu_top_appbar.xml +++ b/app/src/main/res/menu/navigation_menu_top_appbar.xml @@ -22,7 +22,7 @@ <item android:id="@+id/permissions" android:title="@string/permissions" - android:icon="@drawable/secure_5g_nr_sa" + android:icon="@drawable/permissions" android:orderInCategory="10" /> <item diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a330355..57739c9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -101,4 +101,7 @@ <string name="phone_permission">Phone Permission</string> <string name="phone_permission_text">Privacy Cell needs the Read Phone State permission to determine the safety level of your cell connection.</string> <string name="ok">OK</string> + + <!-- Dialogs. --> + <string name="close">Close</string> </resources> \ No newline at end of file -- 2.47.2