// 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'
--- /dev/null
+/*
+ * 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
--- /dev/null
+<!--
+ 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
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 {
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.
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)
// 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))
}
}
+ 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)
else -> arrayOf(getString(R.string.error), "")
}
}
-
- override fun onNavigationItemSelected(menuItem: MenuItem) : Boolean {
- // TODO.
- return true
- }
}
\ No newline at end of file
--- /dev/null
+/*
+ * 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
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)
--- /dev/null
+<!-- 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>
--- /dev/null
+<?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
<item
android:id="@+id/permissions"
android:title="@string/permissions"
- android:icon="@drawable/secure_5g_nr_sa"
+ android:icon="@drawable/permissions"
android:orderInCategory="10" />
<item
<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