h3 {
color: #8AB4F8; /* Violet 500 */
}
+}
+
+/* Red bold text */
+strong.red {
+ color: #B71C1C; /* Red 900. */
+}
+
+@media (prefers-color-scheme: dark) {
+ strong.red {
+ color: #FC684E; /* Salmon. */
+ }
+}
+
+/* Blue bold text */
+strong.blue {
+ color: #1565C0; /* Blue 800. */
+}
+
+
+/* List items. */
+item {
+ color: #1565C0; /* Blue 800. */
+ font-weight: bold;
}
\ 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>
+ <h3>1.0 (version code 1)</h3>
+ <p>28 August 2021 - minimum API 30, target API 30</p>
+ <ul>
+ <li>Initial release.</li>
+ </ul>
+ </body>
+</html>
\ No newline at end of file
<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><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission. 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
--- /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>
+ <h3>Privacy Cell</h3>
+ <p><strong class="red">Privacy Cell does not collect any user information.</strong></p>
+
+ <h3>Google Play</h3>
+ <p>Google Play has its <a href="https://policies.google.com/privacy">own privacy policy</a>.
+ Google provides anonymized summary installation information to developers, including the number of installs organized by the following categories.</p>
+ <ul>
+ <li><item>Android version</item> (eg. Android 7.1)</li>
+ <li><item>Device</item> (eg. Samsung Galaxy S6 [zeroflte])</li>
+ <li><item>Tablets</item> (eg. Tablets 10? and above)</li>
+ <li><item>Country</item> (eg. United States)</li>
+ <li><item>Language</item> (eg. English [United States])</li>
+ <li><item>App version</item> (eg. 14)</li>
+ <li><item>Carrier </item>(eg. T-Mobile – US)</li>
+ </ul>
+
+ <h3>Google Play Ratings</h3>
+ <p>Google Play has its <a href="https://policies.google.com/privacy">own privacy policy</a>.
+ Google provides developers with anonymized summaries of the following information related to user ratings.</p>
+ <ul>
+ <li><item>Country</item> (eg. United States)</li>
+ <li><item>Language</item> (eg. English)</li>
+ <li><item>App version</item> (eg. 14)</li>
+ <li><item>Android version</item> (eg. 7.1)</li>
+ <li><item>Device</item> (eg. Google Nexus 5X [bullhead])</li>
+ <li><item>Tablets</item> (eg. Tablets 10? and above)</li>
+ </ul>
+
+ <h3>Google Play Reviews</h3>
+ <p>Google Play has its <a href="https://policies.google.com/privacy">own privacy policy</a>.
+ 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.</p>
+ <ul>
+ <li><item>Version code</item> (eg. 7)</li>
+ <li><item>Version name</item> (eg. 1.6)</li>
+ <li><item>Android version</item> (eg. Android 5.1)</li>
+ <li><item>Device </item>(eg. Galaxy S6 Edge+ [zenlte])</li>
+ <li><item>Manufacturer</item> (eg. Samsung)</li>
+ <li><item>Device type</item> (eg. Phone)</li>
+ <li><item>CPU make</item> (eg. Samsung)</li>
+ <li><item>CPU model</item> (eg. Exynos 7420)</li>
+ <li><item>Screen density</item> (eg. 560 dpi)</li>
+ <li><item>Screen size</item> (eg. 2560 x 1440)</li>
+ <li><item>RAM</item> (eg. 4096 MB)</li>
+ <li><item>Native platform</item> (eg. armeabi-v7a,armeabi,arm64v8a)</li>
+ <li><item>OpenGL ES version</item> (eg. 3.1)</li>
+ <li><item>Device language</item> (eg. English)</li>
+ </ul>
+
+ <h3>Direct Communications</h3>
+ <p>Users may choose to send direct communications to Stoutner, like email messages and comments on <a href="https://www.stoutner.com/">stoutner.com</a>.</p>
+
+ <h3>Use of Information</h3>
+ <p><strong class="blue">Stoutner may use this information to assist in the development of Privacy Cell and communicate the status of the project to users.</strong>
+ <strong class="red">Stoutner will never sell the 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.0, 23 August 2021</em></p>
+ </body>
+</html>
\ No newline at end of file
import com.google.android.material.navigation.NavigationView
import com.stoutner.privacycell.R
-import com.stoutner.privacycell.dialogs.PermissionsDialog
import com.stoutner.privacycell.dialogs.PhonePermissionDialog
+import com.stoutner.privacycell.dialogs.WebViewDialog
class PrivacyCell : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener {
// Declare the class variables.
// Run the commands that correspond to the selected menu item.
if (menuItemId == R.id.permissions) { // Permissions.
// Instantiate the permissions dialog fragment.
- val permissionsDialogFragment = PermissionsDialog()
+ val permissionsDialogFragment = WebViewDialog().type(WebViewDialog.PERMISSIONS)
// Show the permissions alert dialog.
- permissionsDialogFragment.show(supportFragmentManager, getString(R.string.phone_permission))
+ permissionsDialogFragment.show(supportFragmentManager, getString(R.string.permissions))
+ } else if (menuItemId == R.id.privacy_policy) { // Privacy Policy.
+ // Instantiate the privacy policy dialog fragment.
+ val privacyPolicyDialogFragment = WebViewDialog().type(WebViewDialog.PRIVACY_POLICY)
+
+ // Show the privacy policy alert dialog.
+ privacyPolicyDialogFragment.show(supportFragmentManager, getString(R.string.privacy_policy))
+ } else if (menuItemId == R.id.changelog) { // Changelog.
+ // Instantiate the changelog dialog fragment.
+ val changelogDialogFragment = WebViewDialog().type(WebViewDialog.CHANGELOG)
+
+ // Show the changelog alert dialog.
+ changelogDialogFragment.show(supportFragmentManager, getString(R.string.changelog))
}
// Close the navigation drawer.
+++ /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
--- /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
+
+// Define the class constants.
+private const val DIALOG_TYPE = "dialog_type"
+private const val SCROLL_Y = "scroll_y"
+
+class WebViewDialog : DialogFragment() {
+ companion object {
+ // Define the public constants.
+ const val PERMISSIONS = 0
+ const val PRIVACY_POLICY = 1
+ const val CHANGELOG = 2
+ }
+
+ // Define the class views.
+ private lateinit var webView: WebView
+
+ // Populate the WebView dialog type.
+ fun type(dialogType: Int): WebViewDialog {
+ // Create an arguments bundle.
+ val argumentsBundle = Bundle()
+
+ // Add the dialog type to the bundle.
+ argumentsBundle.putInt(DIALOG_TYPE, dialogType)
+
+ // Create a new instance of the WebView dialog.
+ val webViewDialog = WebViewDialog()
+
+ // Add the arguments bundle to the new dialog.
+ webViewDialog.arguments = argumentsBundle
+
+ // Return the new dialog.
+ return webViewDialog
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ // Get the dialog type from the arguments bundle.
+ val dialogType = requireArguments().getInt(DIALOG_TYPE)
+
+ // Use a builder to create the alert dialog.
+ val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.Theme_PrivacyCellAlertDialog)
+
+ // Set the icon and the title according to the dialog type.
+ when (dialogType) {
+ PERMISSIONS -> {
+ // Set the icon.
+ dialogBuilder.setIcon(R.drawable.permissions)
+
+ // Set the title.
+ dialogBuilder.setTitle(R.string.permissions)
+ }
+
+ PRIVACY_POLICY -> {
+ // Set the icon.
+ dialogBuilder.setIcon(R.drawable.privacy_policy)
+
+ // Set the title.
+ dialogBuilder.setTitle(R.string.privacy_policy)
+ }
+
+ CHANGELOG -> {
+ // Set the icon.
+ dialogBuilder.setIcon(R.drawable.changelog)
+
+ // Set the title.
+ dialogBuilder.setTitle(R.string.changelog)
+ }
+ }
+
+ // Set the view.
+ dialogBuilder.setView(R.layout.webview_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.
+ webView = alertDialog.findViewById(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 according to the dialog type.
+ when (dialogType) {
+ PERMISSIONS -> webView.loadUrl("file:///android_asset/en/permissions.html")
+ PRIVACY_POLICY -> webView.loadUrl("file:///android_asset/en/privacy_policy.html")
+ CHANGELOG -> webView.loadUrl("file:///android_asset/en/changelog.html")
+ }
+
+ // Scroll the WebView if the saved instance state is not null.
+ if (savedInstanceState != null) {
+ webView.post {
+ webView.scrollY = savedInstanceState.getInt(SCROLL_Y)
+ }
+ }
+
+ // Return the alert dialog.
+ return alertDialog
+ }
+
+ override fun onSaveInstanceState(savedInstanceState: Bundle) {
+ // Run the default commands.
+ super.onSaveInstanceState(savedInstanceState)
+
+ // Save the scroll position.
+ savedInstanceState.putInt(SCROLL_Y, webView.scrollY)
+ }
+}
\ No newline at end of file
--- /dev/null
+<!-- This file comes from the Android Material icon set, where it is called `format_list_bulleted`. 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"
+ android:autoMirrored="true" >
+
+ <path
+ android:fillColor="@color/icon" android:pathData="M4,10.5c-0.83,0 -1.5,0.67 -1.5,1.5s0.67,1.5 1.5,1.5 1.5,-0.67 1.5,-1.5 -0.67,-1.5 -1.5,-1.5zM4,4.5c-0.83,0 -1.5,0.67 -1.5,1.5S3.17,7.5 4,7.5 5.5,6.83 5.5,6 4.83,4.5 4,4.5zM4,16.5c-0.83,0 -1.5,0.68 -1.5,1.5s0.68,1.5 1.5,1.5 1.5,-0.68 1.5,-1.5 -0.67,-1.5 -1.5,-1.5zM8,19h12c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L8,17c-0.55,0 -1,0.45 -1,1s0.45,1 1,1zM8,13h12c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L8,11c-0.55,0 -1,0.45 -1,1s0.45,1 1,1zM7,6c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L8,5c-0.55,0 -1,0.45 -1,1z" />
+</vector>
\ No newline at end of file
--- /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="M21,5l-9,-4L3,5v6c0,5.55 3.84,10.74 9,12c2.3,-0.56 4.33,-1.9 5.88,-3.71l-3.12,-3.12c-1.94,1.29 -4.58,1.07 -6.29,-0.64c-1.95,-1.95 -1.95,-5.12 0,-7.07c1.95,-1.95 5.12,-1.95 7.07,0c1.71,1.71 1.92,4.35 0.64,6.29l2.9,2.9C20.29,15.69 21,13.38 21,11V5z" />
+
+ <path
+ android:fillColor="@color/icon"
+ android:pathData="M12,12m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0" />
+</vector>
\ No newline at end of file
+++ /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
--- /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/privacy_policy"
android:title="@string/privacy_policy"
- android:icon="@drawable/secure_5g_nr_sa"
+ android:icon="@drawable/privacy_policy"
android:orderInCategory="20" />
<item
android:id="@+id/changelog"
android:title="@string/changelog"
- android:icon="@drawable/secure_5g_nr_sa"
+ android:icon="@drawable/changelog"
android:orderInCategory="30" />
<item