296a95290ffbe6e1d4836dfcb842afb992ea85f8
[PrivacyCell.git] / app / src / main / java / com / stoutner / privacycell / activities / PrivacyCellActivity.kt
1 /*
2  * Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
5  *
6  * Privacy Cell is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Cell is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Cell.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacycell.activities
21
22 import android.Manifest
23 import android.content.Context
24 import android.content.Intent
25 import android.content.pm.PackageManager
26 import android.net.Uri
27 import android.os.Bundle
28 import android.telephony.PhoneStateListener
29 import android.telephony.ServiceState
30 import android.telephony.TelephonyDisplayInfo
31 import android.telephony.TelephonyManager
32 import android.view.MenuItem
33 import android.view.View
34 import android.widget.ImageView
35 import android.widget.LinearLayout
36 import android.widget.TextView
37
38 import androidx.appcompat.app.ActionBar
39 import androidx.appcompat.app.ActionBarDrawerToggle
40 import androidx.appcompat.app.AppCompatActivity
41 import androidx.appcompat.content.res.AppCompatResources
42 import androidx.appcompat.widget.Toolbar
43 import androidx.core.app.ActivityCompat
44 import androidx.core.view.GravityCompat
45 import androidx.drawerlayout.widget.DrawerLayout
46 import androidx.preference.PreferenceManager
47
48 import com.google.android.material.navigation.NavigationView
49
50 import com.stoutner.privacycell.R
51 import com.stoutner.privacycell.dialogs.PhonePermissionDialog
52 import com.stoutner.privacycell.dialogs.WebViewDialog
53
54 class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener {
55     // Declare the class variables.
56     private lateinit var context: Context
57     private lateinit var telephonyManager: TelephonyManager
58     private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
59
60     // Declare the views.
61     private lateinit var drawerLayout: DrawerLayout
62     private lateinit var stingrayLinearLayout: LinearLayout
63     private lateinit var stingrayImageView: ImageView
64     private lateinit var stingrayTextView: TextView
65     private lateinit var voiceNetworkLinearLayout: LinearLayout
66     private lateinit var voiceNetworkTextView: TextView
67     private lateinit var voiceNetworkDetailsTextView: TextView
68     private lateinit var dataNetworkLinearLayout: LinearLayout
69     private lateinit var dataNetworkTextView: TextView
70     private lateinit var dataNetworkDetailsTextView: TextView
71     private lateinit var additionalNetworkInfoLinearLayout: LinearLayout
72     private lateinit var additionalNetworkInfoTextView: TextView
73     private lateinit var additionalNetworkInfoDetailsTextView: TextView
74
75     override fun onCreate(savedInstanceState: Bundle?) {
76         // Run the default commands.
77         super.onCreate(savedInstanceState)
78
79         // Get a handle for the shared preferences.
80         val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
81
82         // Get the bottom app bar preference.
83         val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)
84
85         // Set the content view.
86         if (bottomAppBar) {
87             setContentView(R.layout.privacy_cell_bottom_appbar)
88         } else {
89             setContentView(R.layout.privacy_cell_top_appbar)
90         }
91
92         // Get handles for the views.
93         drawerLayout = findViewById(R.id.drawerlayout)
94         val toolbar = findViewById<Toolbar>(R.id.toolbar)
95         stingrayLinearLayout = findViewById(R.id.stingray_linearlayout)
96         stingrayImageView = findViewById(R.id.stingray_imageview)
97         stingrayTextView = findViewById(R.id.stingray_textview)
98         voiceNetworkLinearLayout = findViewById(R.id.voice_network_linearlayout)
99         voiceNetworkTextView = findViewById(R.id.voice_network)
100         voiceNetworkDetailsTextView = findViewById(R.id.voice_network_details)
101         dataNetworkLinearLayout = findViewById(R.id.data_network_linearlayout)
102         dataNetworkTextView = findViewById(R.id.data_network)
103         dataNetworkDetailsTextView = findViewById(R.id.data_network_details)
104         additionalNetworkInfoLinearLayout = findViewById(R.id.additional_network_info_linearlayout)
105         additionalNetworkInfoTextView = findViewById(R.id.additional_network_info)
106         additionalNetworkInfoDetailsTextView = findViewById(R.id.additional_network_info_details)
107         val navigationView = findViewById<NavigationView>(R.id.navigationview)
108
109         // Get handles for the context and the telephony manager.
110         context = this
111         telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
112
113         // Set the support action bar.
114         setSupportActionBar(toolbar)
115
116         // Get a handle for the action bar.
117         val actionBar = supportActionBar!!
118
119         // Set a custom view on the action bar.
120         actionBar.setCustomView(R.layout.app_bar_textview)
121
122         // Display the custom view.
123         actionBar.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
124
125         // Define a hamburger icon at the start of the app bar.  It will be populated in `onPostCreate()`.
126         actionBarDrawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer)
127
128         // Listen for touches on the navigation menu.
129         navigationView.setNavigationItemSelectedListener(this)
130
131         // Add a drawer listener.
132         drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
133             override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
134                 // Do nothing.
135             }
136
137             override fun onDrawerOpened(drawerView: View) {
138                 // Do nothing.
139             }
140
141             override fun onDrawerClosed(drawerView: View) {
142                 // Reset the drawer icon when the drawer is closed.  Otherwise, it is an arrow if the drawer is open when the app is restarted.
143                 actionBarDrawerToggle.syncState()
144             }
145
146             override fun onDrawerStateChanged(newState: Int) {
147                 // Do nothing.
148             }
149         })
150     }
151
152     override fun onPostCreate(savedInstanceState: Bundle?) {
153         // Run the default commands.
154         super.onPostCreate(savedInstanceState)
155
156         // Sync the state of the DrawerToggle after the default `onRestoreInstanceState()` has finished.  This creates the navigation drawer icon.
157         actionBarDrawerToggle.syncState()
158     }
159
160     override fun onResume() {
161         // Run the default commands.
162         super.onResume()
163
164         // Check to see if the read phone state permission has been granted.  These commands need to be run on every resume so that the listener gets reassigned as it is automatically paused.
165         if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {  // The storage permission has been granted.
166             // Populate Privacy Cell.
167             populatePrivacyCell()
168         } else {  // The phone permission has not been granted.
169             // Check if the user has previously denied the storage permission.
170             if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) {  // Show a dialog explaining the request first.
171                 // Check to see if a phone permission dialog is already displayed.  This happens if the app is restarted when the dialog is shown.
172                 if (supportFragmentManager.findFragmentByTag(getString(R.string.phone_permission)) == null) {  // No dialog is currently shown.
173                     // Instantiate the phone permission dialog fragment.
174                     val phonePermissionDialogFragment = PhonePermissionDialog()
175
176                     // Show the phone permission alert dialog.  The permission will be requested when the dialog is closed.
177                     phonePermissionDialogFragment.show(supportFragmentManager, getString(R.string.phone_permission))
178                 }
179             } else {  // Show the permission request directly.
180                 // Request the read phone state permission.  There is only one permission request in the app, so it has a request code of 0.
181                 ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
182             }
183         }
184     }
185
186     override fun onNavigationItemSelected(menuItem: MenuItem) : Boolean {
187         // Run the commands that correspond to the selected menu item.
188         when (menuItem.itemId) {
189             R.id.settings -> {  // Settings.
190                 // Create an intent to load the Settings activity.
191                 val settingsIntent = Intent(this, SettingsActivity::class.java)
192
193                 // Make it so.
194                 startActivity(settingsIntent)
195             }
196
197             R.id.permissions -> {  // Permissions.
198                 // Instantiate the permissions dialog fragment.
199                 val permissionsDialogFragment = WebViewDialog().type(WebViewDialog.PERMISSIONS)
200
201                 // Show the alert dialog.
202                 permissionsDialogFragment.show(supportFragmentManager, getString(R.string.permissions))
203             }
204
205             R.id.privacy_policy -> {  // Privacy Policy.
206                 // Instantiate the privacy policy dialog fragment.
207                 val privacyPolicyDialogFragment = WebViewDialog().type(WebViewDialog.PRIVACY_POLICY)
208
209                 // Show the alert dialog.
210                 privacyPolicyDialogFragment.show(supportFragmentManager, getString(R.string.privacy_policy))
211             }
212
213             R.id.changelog -> {  // Changelog.
214                 // Instantiate the changelog dialog fragment.
215                 val changelogDialogFragment = WebViewDialog().type(WebViewDialog.CHANGELOG)
216
217                 // Show the alert dialog.
218                 changelogDialogFragment.show(supportFragmentManager, getString(R.string.changelog))
219             }
220
221             R.id.licenses -> {  // Licenses.
222                 // Instantiate the licenses dialog fragment.
223                 val licensesDialogFragment = WebViewDialog().type(WebViewDialog.LICENSES)
224
225                 // Show the alert dialog.
226                 licensesDialogFragment.show(supportFragmentManager, getString(R.string.licenses))
227             }
228
229             R.id.contributors -> {  // Contributors.
230                 // Instantiate the contributors dialog fragment.
231                 val contributorsDialogFragment = WebViewDialog().type(WebViewDialog.CONTRIBUTORS)
232
233                 // Show the alert dialog.
234                 contributorsDialogFragment.show(supportFragmentManager, getString(R.string.contributors))
235             }
236
237             R.id.news -> {  // News.
238                 // Create a news URL intent.
239                 val newsUrlIntent = Intent(Intent.ACTION_VIEW)
240
241                 // Add the URL to the intent.
242                 newsUrlIntent.data = Uri.parse("https://www.stoutner.com/category/privacy-cell/")
243
244                 // Make it so.
245                 startActivity(newsUrlIntent)
246             }
247
248             R.id.roadmap -> {  // Roadmap.
249                 // Create a roadmap URL intent.
250                 val roadmapUrlIntent = Intent(Intent.ACTION_VIEW)
251
252                 // Add the URL to the intent.
253                 roadmapUrlIntent.data = Uri.parse("https://www.stoutner.com/category/privacy-cell-roadmap/")
254
255                 // Make it so.
256                 startActivity(roadmapUrlIntent)
257             }
258
259             R.id.bug_tracker -> {  // Bug tracker.
260                 // Create a bug tracker URL intent.
261                 val bugTrackerUrlIntent = Intent(Intent.ACTION_VIEW)
262
263                 // Add the URL to the intent.
264                 bugTrackerUrlIntent.data = Uri.parse("https://redmine.stoutner.com/projects/privacy-cell/issues")
265
266                 // Make it so.
267                 startActivity(bugTrackerUrlIntent)
268             }
269
270             R.id.forum -> {  // Forum.
271                 // Create a forum URL intent.
272                 val forumUrlIntent = Intent(Intent.ACTION_VIEW)
273
274                 // Add the URL to the intent.
275                 forumUrlIntent.data = Uri.parse("https://redmine.stoutner.com/projects/privacy-cell/boards")
276
277                 // Make it so.
278                 startActivity(forumUrlIntent)
279             }
280
281             R.id.donations -> {  // Donations.
282                 // Create a donations URL intent.
283                 val donationsUrlIntent = Intent(Intent.ACTION_VIEW)
284
285                 // Add the URL to the intent.
286                 donationsUrlIntent.data = Uri.parse("https://www.stoutner.com/donations/")
287
288                 // Make it so.
289                 startActivity(donationsUrlIntent)
290             }
291         }
292
293         // Close the navigation drawer.
294         drawerLayout.closeDrawer(GravityCompat.START)
295
296         // Consume the click.
297         return true
298     }
299
300     override fun onCloseStoragePermissionDialog() {
301         // Request the read phone state permission.  There is only one permission request in the app, so it has a request code of 0.
302         ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
303     }
304
305     override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
306         // Run the default commands.
307         super.onRequestPermissionsResult(requestCode, permissions, grantResults)
308
309         //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).
310         if (grantResults.isNotEmpty()) {
311             // Check to see if the read phone state permission was granted.  If the dialog was canceled the grant results will be empty.
312             if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {  // The read phone state permission was granted.
313                 // Populate Privacy Cell.
314                 populatePrivacyCell()
315             } else {  // The read phone state permission was denied.
316                 // Display the phone permission text on the main activity.
317                 stingrayTextView.text = getString(R.string.phone_permission_text)
318             }
319         }
320     }
321
322     private fun populatePrivacyCell() {
323         // Listen to changes in the cell network state.
324         telephonyManager.listen(object : PhoneStateListener() {
325             override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
326                 // Populate the stingray security information.  <https://source.android.com/devices/tech/connect/acts-5g-testing>
327                 if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) {  // This is a secure 5G NR SA network.
328                     // Populate the image view.
329                     stingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.secure_5g_nr_sa))
330
331                     // Set the text.
332                     stingrayTextView.text = getString(R.string.secure_from_stingray)
333
334                     // Set the text color.
335                     stingrayTextView.setTextColor(getColor(R.color.blue_text))
336                 } else {  // This is not a secure 5G NR SA network.
337                     // Populate the image view.
338                     stingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.not_secure))
339
340                     // Set the text.
341                     stingrayTextView.text = getString(R.string.not_secure_from_stingray)
342
343                     // Set the text color.
344                     stingrayTextView.setTextColor(getColor(R.color.red_text))
345                 }
346
347                 // Get the strings that correspond to the network information.
348                 val dataNetworkType = getNetworkType(telephonyDisplayInfo.networkType)
349                 val additionalNetworkInfo = getAdditionalNetworkInfo(telephonyDisplayInfo.overrideNetworkType)
350
351                 // Populate the data network text views.
352                 dataNetworkTextView.text = getString(R.string.data_network, dataNetworkType[0])
353                 dataNetworkDetailsTextView.text = dataNetworkType[1]
354                 additionalNetworkInfoTextView.text = getString(R.string.additional_network_info, additionalNetworkInfo[0])
355                 additionalNetworkInfoDetailsTextView.text = additionalNetworkInfo[1]
356
357                 // Set the stingray click listener.
358                 stingrayLinearLayout.setOnClickListener {
359                     // Instantiate the stingray dialog fragment.
360                     val stingrayDialogFragment = WebViewDialog().type(WebViewDialog.STINGRAY)
361
362                     // Show the alert dialog.
363                     stingrayDialogFragment.show(supportFragmentManager, getString(R.string.stingrays))
364                 }
365
366                 // Set the data network click listener.
367                 dataNetworkLinearLayout.setOnClickListener {
368                     // Instantiate the data network dialog fragment according to the network type.
369                     val dataNetworkDialogFragment = when (telephonyDisplayInfo.networkType) {
370                         TelephonyManager.NETWORK_TYPE_UNKNOWN -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
371                         TelephonyManager.NETWORK_TYPE_GPRS -> WebViewDialog().type(WebViewDialog.NETWORK_GPRS)
372                         TelephonyManager.NETWORK_TYPE_EDGE -> WebViewDialog().type(WebViewDialog.NETWORK_EDGE)
373                         TelephonyManager.NETWORK_TYPE_UMTS -> WebViewDialog().type(WebViewDialog.NETWORK_UMTS)
374                         TelephonyManager.NETWORK_TYPE_CDMA -> WebViewDialog().type(WebViewDialog.NETWORK_CDMA)
375                         TelephonyManager.NETWORK_TYPE_EVDO_0 -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_0)
376                         TelephonyManager.NETWORK_TYPE_EVDO_A -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_A)
377                         TelephonyManager.NETWORK_TYPE_1xRTT -> WebViewDialog().type(WebViewDialog.NETWORK_1xRTT)
378                         TelephonyManager.NETWORK_TYPE_HSDPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSDPA)
379                         TelephonyManager.NETWORK_TYPE_HSUPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSUPA)
380                         TelephonyManager.NETWORK_TYPE_HSPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSPA)
381                         TelephonyManager.NETWORK_TYPE_IDEN -> WebViewDialog().type(WebViewDialog.NETWORK_IDEN)
382                         TelephonyManager.NETWORK_TYPE_EVDO_B -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_B)
383                         TelephonyManager.NETWORK_TYPE_LTE -> WebViewDialog().type(WebViewDialog.NETWORK_LTE)
384                         TelephonyManager.NETWORK_TYPE_EHRPD -> WebViewDialog().type(WebViewDialog.NETWORK_EHRPD)
385                         TelephonyManager.NETWORK_TYPE_HSPAP -> WebViewDialog().type(WebViewDialog.NETWORK_HSPAP)
386                         TelephonyManager.NETWORK_TYPE_GSM -> WebViewDialog().type(WebViewDialog.NETWORK_GSM)
387                         TelephonyManager.NETWORK_TYPE_TD_SCDMA -> WebViewDialog().type(WebViewDialog.NETWORK_TD_SCDMA)
388                         TelephonyManager.NETWORK_TYPE_IWLAN -> WebViewDialog().type(WebViewDialog.NETWORK_IWLAN)
389                         TelephonyManager.NETWORK_TYPE_NR -> WebViewDialog().type(WebViewDialog.NETWORK_NR)
390                         else -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
391                     }
392
393                     // Show the alert dialog.
394                     dataNetworkDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
395                 }
396
397                 // Set the additional network info click listener.
398                 additionalNetworkInfoLinearLayout.setOnClickListener {
399                     // Instantiate the initial network info dialog fragment according to the network type.
400                     val additionalNetworkInfoDialogFragment = when (telephonyDisplayInfo.overrideNetworkType) {
401                         TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NONE)
402                         TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_LTE_CA)
403                         TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_LTE_ADVANCED_PRO)
404                         TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA)
405                         TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA_MMWAVE)
406                         else -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA_MMWAVE)
407                     }
408
409                     // Show the alert dialog.
410                     additionalNetworkInfoDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
411                 }
412             }
413
414             override fun onServiceStateChanged(serviceState: ServiceState) {
415                 // 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).
416                 val networkRegistrationInfo = serviceState.networkRegistrationInfoList[1]
417
418                 // Get the voice network type.
419                 val voiceNetworkType = getNetworkType(networkRegistrationInfo.accessNetworkTechnology)
420
421                 // Populate the voice network text views.
422                 voiceNetworkTextView.text = getString(R.string.voice_network, voiceNetworkType[0])
423                 voiceNetworkDetailsTextView.text = voiceNetworkType[1]
424
425                 // Set the voice network click listener.
426                 voiceNetworkLinearLayout.setOnClickListener {
427                     // Instantiate the voice network dialog fragment according to the network type.
428                     val voiceNetworkDialogFragment = when (networkRegistrationInfo.accessNetworkTechnology) {
429                         TelephonyManager.NETWORK_TYPE_UNKNOWN -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
430                         TelephonyManager.NETWORK_TYPE_GPRS -> WebViewDialog().type(WebViewDialog.NETWORK_GPRS)
431                         TelephonyManager.NETWORK_TYPE_EDGE -> WebViewDialog().type(WebViewDialog.NETWORK_EDGE)
432                         TelephonyManager.NETWORK_TYPE_UMTS -> WebViewDialog().type(WebViewDialog.NETWORK_UMTS)
433                         TelephonyManager.NETWORK_TYPE_CDMA -> WebViewDialog().type(WebViewDialog.NETWORK_CDMA)
434                         TelephonyManager.NETWORK_TYPE_EVDO_0 -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_0)
435                         TelephonyManager.NETWORK_TYPE_EVDO_A -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_A)
436                         TelephonyManager.NETWORK_TYPE_1xRTT -> WebViewDialog().type(WebViewDialog.NETWORK_1xRTT)
437                         TelephonyManager.NETWORK_TYPE_HSDPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSDPA)
438                         TelephonyManager.NETWORK_TYPE_HSUPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSUPA)
439                         TelephonyManager.NETWORK_TYPE_HSPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSPA)
440                         TelephonyManager.NETWORK_TYPE_IDEN -> WebViewDialog().type(WebViewDialog.NETWORK_IDEN)
441                         TelephonyManager.NETWORK_TYPE_EVDO_B -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_B)
442                         TelephonyManager.NETWORK_TYPE_LTE -> WebViewDialog().type(WebViewDialog.NETWORK_LTE)
443                         TelephonyManager.NETWORK_TYPE_EHRPD -> WebViewDialog().type(WebViewDialog.NETWORK_EHRPD)
444                         TelephonyManager.NETWORK_TYPE_HSPAP -> WebViewDialog().type(WebViewDialog.NETWORK_HSPAP)
445                         TelephonyManager.NETWORK_TYPE_GSM -> WebViewDialog().type(WebViewDialog.NETWORK_GSM)
446                         TelephonyManager.NETWORK_TYPE_TD_SCDMA -> WebViewDialog().type(WebViewDialog.NETWORK_TD_SCDMA)
447                         TelephonyManager.NETWORK_TYPE_IWLAN -> WebViewDialog().type(WebViewDialog.NETWORK_IWLAN)
448                         TelephonyManager.NETWORK_TYPE_NR -> WebViewDialog().type(WebViewDialog.NETWORK_NR)
449                         else -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
450                     }
451
452                     // Show the alert dialog.
453                     voiceNetworkDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
454                 }
455             }
456         }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED or PhoneStateListener.LISTEN_SERVICE_STATE)
457     }
458
459     private fun getNetworkType(networkType: Int) : Array<String> {
460         // Return the string that corresponds to the network type.
461         return when(networkType) {
462             TelephonyManager.NETWORK_TYPE_UNKNOWN -> arrayOf(getString(R.string.unknown), "")
463             TelephonyManager.NETWORK_TYPE_GPRS -> arrayOf(getString(R.string.gprs), getString(R.string.gprs_detail))
464             TelephonyManager.NETWORK_TYPE_EDGE -> arrayOf(getString(R.string.edge), getString(R.string.edge_detail))
465             TelephonyManager.NETWORK_TYPE_UMTS -> arrayOf(getString(R.string.umts), getString(R.string.umts_detail))
466             TelephonyManager.NETWORK_TYPE_CDMA -> arrayOf(getString(R.string.cdma), getString(R.string.cdma_detail))
467             TelephonyManager.NETWORK_TYPE_EVDO_0 -> arrayOf(getString(R.string.evdo_0), getString(R.string.evdo_0_detail))
468             TelephonyManager.NETWORK_TYPE_EVDO_A -> arrayOf(getString(R.string.evdo_a), getString(R.string.evdo_a_detail))
469             TelephonyManager.NETWORK_TYPE_1xRTT -> arrayOf(getString(R.string.rtt), getString(R.string.rtt_detail))
470             TelephonyManager.NETWORK_TYPE_HSDPA -> arrayOf(getString(R.string.hsdpa), getString(R.string.hsdpa_detail))
471             TelephonyManager.NETWORK_TYPE_HSUPA -> arrayOf(getString(R.string.hsupa), getString(R.string.hsupa_detail))
472             TelephonyManager.NETWORK_TYPE_HSPA -> arrayOf(getString(R.string.hspa), getString(R.string.hspa_detail))
473             TelephonyManager.NETWORK_TYPE_IDEN -> arrayOf(getString(R.string.iden), getString(R.string.iden_detail))
474             TelephonyManager.NETWORK_TYPE_EVDO_B -> arrayOf(getString(R.string.evdo_b), getString(R.string.evdo_b_detail))
475             TelephonyManager.NETWORK_TYPE_LTE -> arrayOf(getString(R.string.lte), getString(R.string.lte_detail))
476             TelephonyManager.NETWORK_TYPE_EHRPD -> arrayOf(getString(R.string.ehrpd), getString(R.string.ehrpd_detail))
477             TelephonyManager.NETWORK_TYPE_HSPAP -> arrayOf(getString(R.string.hspap), getString(R.string.hspap_detail))
478             TelephonyManager.NETWORK_TYPE_GSM -> arrayOf(getString(R.string.gsm), getString(R.string.gsm_detail))
479             TelephonyManager.NETWORK_TYPE_TD_SCDMA -> arrayOf(getString(R.string.td_scdma), getString(R.string.td_scdma_detail))
480             TelephonyManager.NETWORK_TYPE_IWLAN -> arrayOf(getString(R.string.iwlan), getString(R.string.iwlan_detail))
481             TelephonyManager.NETWORK_TYPE_NR -> arrayOf(getString(R.string.nr), getString(R.string.nr_detail))
482             else -> arrayOf(getString(R.string.error), "")
483         }
484     }
485
486     private fun getAdditionalNetworkInfo(overrideNetworkType: Int) : Array<String> {
487         // Return the string that corresponds to the override network type.
488         return when(overrideNetworkType) {
489             TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> arrayOf(getString(R.string.none), "")
490             TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> arrayOf(getString(R.string.lte_ca), getString(R.string.lte_ca_detail))
491             TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> arrayOf(getString(R.string.lte_advanced_pro), getString(R.string.lte_advanced_pro_detail))
492             TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> arrayOf(getString(R.string.nr_nsa), getString(R.string.nr_nsa_detail))
493             TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> arrayOf(getString(R.string.nr_nsa_mmwave), getString(R.string.nr_nsa_mmwave_detail))
494             else -> arrayOf(getString(R.string.error), "")
495         }
496     }
497 }