/* * Copyright 2021-2022 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.dialogs import android.app.Dialog import android.content.Intent import android.os.Bundle import android.webkit.WebResourceRequest import android.webkit.WebResourceResponse import android.webkit.WebView import android.webkit.WebViewClient import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import androidx.webkit.WebViewAssetLoader 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 const val LICENSES = 3 const val CONTRIBUTORS = 4 const val STINGRAY = 5 const val ANTIQUATED_NETWORK = 6 const val NETWORK_UNKNOWN = 7 const val NETWORK_GPRS = 8 const val NETWORK_EDGE = 9 const val NETWORK_UMTS = 10 const val NETWORK_CDMA = 11 const val NETWORK_EVDO_0 = 12 const val NETWORK_EVDO_A = 13 const val NETWORK_1xRTT = 14 const val NETWORK_HSDPA = 15 const val NETWORK_HSUPA = 16 const val NETWORK_HSPA = 17 const val NETWORK_IDEN = 18 const val NETWORK_EVDO_B = 19 const val NETWORK_LTE = 20 const val NETWORK_EHRPD = 21 const val NETWORK_HSPAP = 22 const val NETWORK_GSM = 23 const val NETWORK_TD_SCDMA = 24 const val NETWORK_IWLAN = 25 const val NETWORK_NR = 26 const val OVERRIDE_NETWORK_NONE = 27 const val OVERRIDE_NETWORK_LTE_CA = 28 const val OVERRIDE_NETWORK_LTE_ADVANCED_PRO = 29 const val OVERRIDE_NETWORK_NR_NSA = 30 const val OVERRIDE_NETWORK_NR_NSA_MMWAVE = 31 // Can be removed once the minimum API >= 31. const val OVERRIDE_NETWORK_NR_ADVANCED = 32 } // 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) } LICENSES -> { // Set the icon. dialogBuilder.setIcon(R.drawable.licenses) // Set the title. dialogBuilder.setTitle(R.string.licenses) } CONTRIBUTORS -> { // Set the icon. dialogBuilder.setIcon(R.drawable.contributors) // Set the tile. dialogBuilder.setTitle(R.string.contributors) } STINGRAY -> { // Set the icon. dialogBuilder.setIcon(R.drawable.secure) // Set the tile. dialogBuilder.setTitle(R.string.stingrays) } ANTIQUATED_NETWORK -> { // Set the icon. dialogBuilder.setIcon(R.drawable.antiquated) // Set the title. dialogBuilder.setTitle(R.string.antiquated_network_title) } NETWORK_UNKNOWN -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.unknown) } NETWORK_GPRS -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.gprs) } NETWORK_EDGE -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.edge) } NETWORK_UMTS -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.umts) } NETWORK_CDMA -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.cdma) } NETWORK_EVDO_0 -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.evdo_0) } NETWORK_EVDO_A -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.evdo_a) } NETWORK_1xRTT -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.rtt) } NETWORK_HSDPA -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.hsdpa) } NETWORK_HSUPA -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.hsupa) } NETWORK_HSPA -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.hspa) } NETWORK_IDEN -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.iden) } NETWORK_EVDO_B -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.evdo_b) } NETWORK_LTE -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.lte) } NETWORK_EHRPD -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.ehrpd) } NETWORK_HSPAP -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.hspap) } NETWORK_GSM -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.gsm) } NETWORK_TD_SCDMA -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.td_scdma) } NETWORK_IWLAN -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.iwlan) } NETWORK_NR -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.nr) } OVERRIDE_NETWORK_NONE -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.none) } OVERRIDE_NETWORK_LTE_CA -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.lte_ca) } OVERRIDE_NETWORK_LTE_ADVANCED_PRO -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.lte_advanced_pro) } OVERRIDE_NETWORK_NR_NSA -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.nr_nsa) } OVERRIDE_NETWORK_NR_NSA_MMWAVE -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.nr_nsa_mmwave) } OVERRIDE_NETWORK_NR_ADVANCED -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) // Set the title. dialogBuilder.setTitle(R.string.nr_advanced) } } // 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)!! // Create a WebView asset loader. val webViewAssetLoader = WebViewAssetLoader.Builder().addPathHandler("/assets/", WebViewAssetLoader.AssetsPathHandler(requireContext())).build() // Set a WebView client. webView.webViewClient = object : WebViewClient() { // Send external links to a web browser. override fun shouldOverrideUrlLoading(view: WebView, webResourceRequest: WebResourceRequest): Boolean { // Create an intent to view the URL. val urlIntent = Intent(Intent.ACTION_VIEW) // Add the URL to the intent. urlIntent.data = webResourceRequest.url // Make it so. startActivity(urlIntent) // Consume the click. return true } // Process asset requests with the asset loader. override fun shouldInterceptRequest(webView: WebView, webResourceRequest: WebResourceRequest): WebResourceResponse? { // This allows using the `appassets.androidplatform.net` URL, which handles the loading of SVG files, which otherwise is prevented by the CORS policy. return webViewAssetLoader.shouldInterceptRequest(webResourceRequest.url) } } // Load the WebView data according to the dialog type. when (dialogType) { PERMISSIONS -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/permissions.html") PRIVACY_POLICY -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/privacy_policy.html") CHANGELOG -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/changelog.html") LICENSES -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/licenses.html") CONTRIBUTORS -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/contributors.html") STINGRAY -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/stingrays.html") ANTIQUATED_NETWORK -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/antiquated_network.html") NETWORK_UNKNOWN -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_unknown.html") NETWORK_GPRS -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_gprs.html") NETWORK_EDGE -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_edge.html") NETWORK_UMTS -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_umts.html") NETWORK_CDMA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_cdma.html") NETWORK_EVDO_0 -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_evdo_0.html") NETWORK_EVDO_A -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_evdo_a.html") NETWORK_1xRTT -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_1xrtt.html") NETWORK_HSDPA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_hsdpa.html") NETWORK_HSUPA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_hsupa.html") NETWORK_HSPA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_hspa.html") NETWORK_IDEN -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_iden.html") NETWORK_EVDO_B -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_evdo_b.html") NETWORK_LTE -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_lte.html") NETWORK_EHRPD -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_ehrpd.html") NETWORK_HSPAP -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_hspap.html") NETWORK_GSM -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_gsm.html") NETWORK_TD_SCDMA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_td_scdma.html") NETWORK_IWLAN -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_iwlan.html") NETWORK_NR -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_nr.html") OVERRIDE_NETWORK_NONE -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/override_network_none.html") OVERRIDE_NETWORK_LTE_CA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/override_network_lte_ca.html") OVERRIDE_NETWORK_LTE_ADVANCED_PRO -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/override_network_lte_advanced_pro.html") OVERRIDE_NETWORK_NR_NSA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/override_network_nr_nsa.html") // The item below can be removed once the minimum API >= 31. OVERRIDE_NETWORK_NR_NSA_MMWAVE -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/override_network_nr_nsa_mmwave.html") OVERRIDE_NETWORK_NR_ADVANCED -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/override_network_nr_advanced.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) } }