<!-- Support Chromebooks that don't have a touch screen. -->
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
- <!-- App data is automatically backed up to Google cloud servers unless `android:allowBackup="false"` and `android:fullBackupContent="false"` is set. TODO round icon and theme name. -->
+ <!-- App data is automatically backed up to Google cloud servers unless `android:allowBackup="false"` and `android:fullBackupContent="false"` is set. -->
<application
android:label="@string/privacy_cell"
android:icon="@mipmap/privacy_cell"
import android.content.pm.PackageManager
import android.os.Bundle
import android.telephony.PhoneStateListener
+import android.telephony.ServiceState
import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.app.ActivityCompat
+import androidx.fragment.app.DialogFragment
import com.stoutner.privacycell.R
+import com.stoutner.privacycell.dialogs.PhonePermissionDialog
+
+class PrivacyCell : AppCompatActivity(), PhonePermissionDialog.StoragePermissionDialogListener {
+ // Declare the class variables.
+ private lateinit var context: Context
+ private lateinit var telephonyManager: TelephonyManager
+
+ // 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
-class PrivacyCell : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Run the default commands.
super.onCreate(savedInstanceState)
// Set the content view.
- setContentView(R.layout.privacy_cell_linearlayout)
+ setContentView(R.layout.privacy_cell_scrollview)
// Get handles for the views.
- val secureFromStingrayImageView = findViewById<ImageView>(R.id.secure_from_stingray_imageview)
- val secureFromStingrayTextView = findViewById<TextView>(R.id.secure_from_stingray_textview)
- val voiceNetworkTextView = findViewById<TextView>(R.id.voice_network)
- val voiceNetworkDetailsTextView = findViewById<TextView>(R.id.voice_network_details)
- val dataNetworkTextView = findViewById<TextView>(R.id.data_network)
- val dataNetworkDetailsTextView = findViewById<TextView>(R.id.data_network_details)
- val additionalNetworkInfoTextView = findViewById<TextView>(R.id.additional_network_info)
- val additionalNetworkInfoDetailsTextView = findViewById<TextView>(R.id.additional_network_info_details)
-
- // TODO.
- if (ActivityCompat.checkSelfPermission(
- this,
- Manifest.permission.READ_PHONE_STATE
- ) != PackageManager.PERMISSION_GRANTED
- ) {
- // TODO: Consider calling
- // ActivityCompat#requestPermissions
- // here to request the missing permissions, and then overriding
- // public void onRequestPermissionsResult(int requestCode, String[] permissions,
- // int[] grantResults)
- // to handle the case where the user grants the permission. See the documentation
- // for ActivityCompat#requestPermissions for more details.
- return
+ secureFromStingrayImageView = findViewById(R.id.secure_from_stingray_imageview)
+ secureFromStingrayTextView = findViewById(R.id.secure_from_stingray_textview)
+ voiceNetworkTextView = findViewById(R.id.voice_network)
+ voiceNetworkDetailsTextView = findViewById(R.id.voice_network_details)
+ dataNetworkTextView = findViewById(R.id.data_network)
+ dataNetworkDetailsTextView = findViewById(R.id.data_network_details)
+ additionalNetworkInfoTextView = findViewById(R.id.additional_network_info)
+ additionalNetworkInfoDetailsTextView = findViewById(R.id.additional_network_info_details)
+
+ // Get handles for the context and the telephony manager.
+ context = this
+ telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
+
+ // Check to see if the read phone state permission has been granted.
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted.
+ // Populate Privacy Cell.
+ populatePrivacyCell()
+ } 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.
+ // 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()
+
+ // Show the phone permission alert dialog. The permission will be requested when the dialog is closed.
+ phonePermissionDialogFragment.show(supportFragmentManager, getString(R.string.phone_permission))
+ }
+ } else { // Show the permission request directly.
+ // 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)
+ }
}
+ }
- // Get a handle for the the telephone Manager and the context.
- val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
- val context: Context = this
-
- // Get the voice network type.
- val voiceNetworkType = getNetworkType(telephonyManager.voiceNetworkType)
+ 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)
+ }
- // Populate the voice network text views.
- voiceNetworkTextView.text = getString(R.string.voice_network, voiceNetworkType[0])
- voiceNetworkDetailsTextView.text = voiceNetworkType[1]
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
+ // Run the default commands.
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+
+ //Only process the results if they exist (this method is triggered when a dialog is presented the first time for an app, but no grant results are included).
+ if (grantResults.isNotEmpty()) {
+ // 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()
+ } else { // The read phone state permission was denied.
+ // Display the phone permission text on the main activity.
+ secureFromStingrayTextView.text = getString(R.string.phone_permission_text)
+ }
+ }
+ }
+ private fun populatePrivacyCell() {
// Listen to changes in the cell network state.
telephonyManager.listen(object : PhoneStateListener() {
- override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {// Populate the secure from stingray text view. <https://source.android.com/devices/tech/connect/acts-5g-testing>
- // Populate the stingray security information.
+ override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
+ // Populate the stingray security information. <https://source.android.com/devices/tech/connect/acts-5g-testing>
if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) { // This is a secure 5G NR SA network.
// Populate the image view.
secureFromStingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.secure_5g_nr_sa))
secureFromStingrayTextView.text = getString(R.string.secure_from_stingray)
// Set the text color.
- secureFromStingrayTextView.setTextColor(getColor(R.color.blue_700))
+ secureFromStingrayTextView.setTextColor(getColor(R.color.blue_text))
} else { // This is not a secure 5G NR SA network.
// Populate the image view.
secureFromStingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.not_secure))
secureFromStingrayTextView.text = getString(R.string.not_secure_from_stingray)
// Set the text color.
- secureFromStingrayTextView.setTextColor(getColor(R.color.red_700))
+ secureFromStingrayTextView.setTextColor(getColor(R.color.red_text))
- // Get the strings that correspond to the network information.
- val dataNetworkType = getNetworkType(telephonyDisplayInfo.networkType)
- val additionalNetworkInfo = getAdditionalNetworkInfo(telephonyDisplayInfo.overrideNetworkType)
+ // Get the strings that correspond to the network information.
+ val dataNetworkType = getNetworkType(telephonyDisplayInfo.networkType)
+ val additionalNetworkInfo = getAdditionalNetworkInfo(telephonyDisplayInfo.overrideNetworkType)
- // Populate the data network text views.
- dataNetworkTextView.text = getString(R.string.data_network, dataNetworkType[0])
- dataNetworkDetailsTextView.text = dataNetworkType[1]
- additionalNetworkInfoTextView.text = getString(R.string.additional_network_info, additionalNetworkInfo[0])
- additionalNetworkInfoDetailsTextView.text = additionalNetworkInfo[1]
+ // Populate the data network text views.
+ dataNetworkTextView.text = getString(R.string.data_network, dataNetworkType[0])
+ dataNetworkDetailsTextView.text = dataNetworkType[1]
+ additionalNetworkInfoTextView.text = getString(R.string.additional_network_info, additionalNetworkInfo[0])
+ additionalNetworkInfoDetailsTextView.text = additionalNetworkInfo[1]
}
}
- }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
+
+ override fun onServiceStateChanged(serviceState: ServiceState) {
+ // Get the network registration info for the voice network, which is the second of the three entries (the first appears to be Wi-Fi and the third appears to be the cell data network).
+ val networkRegistrationInfo = serviceState.networkRegistrationInfoList[1]
+
+ // Get the voice network type.
+ val voiceNetworkType = getNetworkType(networkRegistrationInfo.accessNetworkTechnology)
+
+ // Populate the voice network text views.
+ voiceNetworkTextView.text = getString(R.string.voice_network, voiceNetworkType[0])
+ voiceNetworkDetailsTextView.text = voiceNetworkType[1]
+ }
+ }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED or PhoneStateListener.LISTEN_SERVICE_STATE)
}
private fun getNetworkType(networkType: Int) : Array<String> {
// Return the string that corresponds to the network type.
return when(networkType) {
- TelephonyManager.NETWORK_TYPE_UNKNOWN -> arrayOf(getString(R.string.unknown), getString(R.string.unknown))
+ TelephonyManager.NETWORK_TYPE_UNKNOWN -> arrayOf(getString(R.string.unknown), "")
TelephonyManager.NETWORK_TYPE_GPRS -> arrayOf(getString(R.string.gprs), getString(R.string.gprs_detal))
TelephonyManager.NETWORK_TYPE_EDGE -> arrayOf(getString(R.string.edge), getString(R.string.edge_detail))
TelephonyManager.NETWORK_TYPE_UMTS -> arrayOf(getString(R.string.umts), getString(R.string.umts_detail))
TelephonyManager.NETWORK_TYPE_TD_SCDMA -> arrayOf(getString(R.string.td_scdma), getString(R.string.td_scdma_detail))
TelephonyManager.NETWORK_TYPE_IWLAN -> arrayOf(getString(R.string.iwlan), getString(R.string.iwlan_detail))
TelephonyManager.NETWORK_TYPE_NR -> arrayOf(getString(R.string.nr), getString(R.string.nr_detail))
- else -> arrayOf(getString(R.string.error), getString(R.string.error))
+ else -> arrayOf(getString(R.string.error), "")
}
}
--- /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.Context
+import android.content.DialogInterface
+import android.os.Bundle
+
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.DialogFragment
+
+import com.stoutner.privacycell.R
+
+class PhonePermissionDialog : DialogFragment() {
+ // Declare the listener.
+ private lateinit var storagePermissionDialogListener: StoragePermissionDialogListener
+
+ // The public interface is used to send information back to the parent activity.
+ interface StoragePermissionDialogListener {
+ fun onCloseStoragePermissionDialog()
+ }
+
+ override fun onAttach(context: Context) {
+ // Run the default commands.
+ super.onAttach(context)
+
+ // Get a handle for the listener from the launching context.
+ storagePermissionDialogListener = context as StoragePermissionDialogListener
+ }
+
+ 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)
+
+ // Set the icon.
+ dialogBuilder.setIcon(R.drawable.phone_permission)
+
+ // Set the title.
+ dialogBuilder.setTitle(R.string.phone_permission)
+
+ // Set the text.
+ dialogBuilder.setMessage(R.string.phone_permission_text)
+
+ // Set the close button listener.
+ dialogBuilder.setNegativeButton(R.string.ok) { _: DialogInterface, _: Int ->
+ // Call the storage permission dialog listener.
+ storagePermissionDialogListener.onCloseStoragePermissionDialog()
+ }
+
+ // Return the alert dialog.
+ return dialogBuilder.create()
+ }
+}
\ No newline at end of file
--- /dev/null
+<!-- This file comes from the Android Material icon set, where it is called `phone_android`. 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="M16,1L8,1C6.34,1 5,2.34 5,4v16c0,1.66 1.34,3 3,3h8c1.66,0 3,-1.34 3,-3L19,4c0,-1.66 -1.34,-3 -3,-3zM14,21h-4v-1h4v1zM17.25,18L6.75,18L6.75,4h10.5v14z" />
+</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/>. -->
-
-<ScrollView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_height="match_parent"
- android:layout_width="wrap_content" >
-
- <LinearLayout
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:orientation="vertical"
- android:padding="15dp" >
-
- <!-- Secure from stingray. -->
- <ImageView
- android:id="@+id/secure_from_stingray_imageview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- tools:ignore="ContentDescription" />
-
- <TextView
- android:id="@+id/secure_from_stingray_textview"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:layout_marginTop="10dp"
- android:textSize="20sp"
- android:textStyle="bold" />
-
- <!-- Voice network. -->
- <TextView
- android:id="@+id/voice_network"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:layout_marginTop="30dp"
- android:textColor="@color/blue_700"
- android:textSize="18sp"
- android:textStyle="bold" />
-
- <TextView
- android:id="@+id/voice_network_details"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:layout_marginBottom="10dp" />
-
- <!-- Data network. -->
- <TextView
- android:id="@+id/data_network"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:textColor="@color/blue_700"
- android:textSize="18sp"
- android:textStyle="bold" />
-
- <TextView
- android:id="@+id/data_network_details"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:layout_marginBottom="10dp" />
-
- <!-- Additional network info. -->
- <TextView
- android:id="@+id/additional_network_info"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:textColor="@color/blue_700"
- android:textSize="18sp"
- android:textStyle="bold" />
-
- <TextView
- android:id="@+id/additional_network_info_details"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center" />
- </LinearLayout>
-</ScrollView>
\ 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/>. -->
+
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content" >
+
+ <LinearLayout
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:orientation="vertical"
+ android:padding="15dp" >
+
+ <!-- Secure from stingray. -->
+ <ImageView
+ android:id="@+id/secure_from_stingray_imageview"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ tools:ignore="ContentDescription" />
+
+ <!-- The text color primary is only displayed if the read phone state permission is not granted. -->
+ <TextView
+ android:id="@+id/secure_from_stingray_textview"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:layout_marginTop="10dp"
+ android:textColor="?android:textColorPrimary"
+ android:textSize="20sp"
+ android:textStyle="bold" />
+
+ <!-- Voice network. -->
+ <TextView
+ android:id="@+id/voice_network"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:layout_marginTop="30dp"
+ android:textColor="@color/blue_text"
+ android:textSize="18sp"
+ android:textStyle="bold" />
+
+ <TextView
+ android:id="@+id/voice_network_details"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:layout_marginBottom="10dp" />
+
+ <!-- Data network. -->
+ <TextView
+ android:id="@+id/data_network"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:textColor="@color/blue_text"
+ android:textSize="18sp"
+ android:textStyle="bold" />
+
+ <TextView
+ android:id="@+id/data_network_details"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:layout_marginBottom="10dp" />
+
+ <!-- Additional network info. -->
+ <TextView
+ android:id="@+id/additional_network_info"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:textColor="@color/blue_text"
+ android:textSize="18sp"
+ android:textStyle="bold" />
+
+ <TextView
+ android:id="@+id/additional_network_info_details"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center" />
+ </LinearLayout>
+</ScrollView>
\ 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/>. -->
+
+<resources>
+ <!-- Nicknamed colors. -->
+ <color name="blue_text">@color/violet_500</color>
+ <color name="icon">@color/violet_500</color>
+ <color name="red_text">@color/salmon</color>
+
+ <!-- Raw colors. -->
+ <color name="black">#FF000000</color>
+ <color name="blue_500">#FF2196F3</color>
+ <color name="blue_700">#FF1976D2</color>
+ <color name="blue_900">#FF0D47A1</color>
+ <color name="red_600">#FFE53935</color>
+ <color name="red_700">#FFD32F2F</color>
+ <color name="salmon">#FFFC684E</color>
+ <color name="soft_red">#FFC73625</color>
+ <color name="violet_500">#FF8AB4F8</color>
+ <color name="white">#FFFFFFFF</color>
+</resources>
\ No newline at end of file
You should have received a copy of the GNU General Public License
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
-<resources xmlns:tools="http://schemas.android.com/tools">
+<resources>
<style name="Theme.PrivacyCell" parent="Theme.AppCompat.DayNight">
<!-- Main items. -->
<item name="android:navigationBarColor">?android:attr/colorBackground</item>
<item name="android:windowLightNavigationBar">false</item>
<item name="android:windowLightStatusBar">false</item>
</style>
+
+ <style name="Theme.PrivacyCellAlertDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert">
+ <!-- Colors. -->
+ <item name="colorAccent">@color/violet_500</item>
+ </style>
</resources>
\ No newline at end of file
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
<resources>
+ <!-- Nicknamed colors. -->
+ <color name="blue_text">@color/blue_700</color>
+ <color name="icon">@color/blue_700</color>
+ <color name="red_text">@color/red_700</color>
+
+ <!-- Raw colors. -->
<color name="black">#FF000000</color>
<color name="blue_500">#FF2196F3</color>
<color name="blue_700">#FF1976D2</color>
<color name="blue_900">#FF0D47A1</color>
<color name="red_600">#FFE53935</color>
<color name="red_700">#FFD32F2F</color>
+ <color name="salmon">#FFFC684E</color>
+ <color name="soft_red">#FFC73625</color>
+ <color name="violet_500">#FF8AB4F8</color>
<color name="white">#FFFFFFFF</color>
</resources>
\ No newline at end of file
<string name="lte_nr_nsa_mmwave_detail">Long Term Evolution New Radio Non-Standalone millimeter Wave</string>
<!-- Stingray. -->
+ <!-- The `\n\n` code inserts a line break and should be maintained in translations. -->
<string name="secure_from_stingray">Your device is connected to a standalone 5G network.\n\nIt is secure from stingray IMSI man-in-the-middle attacks.</string>
<string name="not_secure_from_stingray">Your device is not connected to a standalone 5G network.\n\nIt is not secure from stingray IMSI man-in-the-middle attacks.</string>
+
+ <!-- Phone permission dialog. -->
+ <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>
</resources>
\ No newline at end of file
You should have received a copy of the GNU General Public License
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
-<resources xmlns:tools="http://schemas.android.com/tools">
+<resources>
<style name="Theme.PrivacyCell" parent="Theme.AppCompat.DayNight">
<!-- Main items. -->
<item name="android:navigationBarColor">?android:attr/colorBackground</item>
<item name="android:windowLightNavigationBar">true</item>
<item name="android:windowLightStatusBar">true</item>
</style>
+
+ <style name="Theme.PrivacyCellAlertDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert">
+ <!-- Colors. -->
+ <item name="colorAccent">@color/blue_700</item>
+ </style>
</resources>
\ No newline at end of file