Skip to content

Commit

Permalink
Display API logs in separate activity
Browse files Browse the repository at this point in the history
  • Loading branch information
dzolnai committed Oct 20, 2023
1 parent bee7cfe commit ad47336
Show file tree
Hide file tree
Showing 15 changed files with 209 additions and 28 deletions.
6 changes: 6 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
android:name="de.blinkt.openvpn.OpenVPNTileService"
android:icon="@drawable/logo_black"
android:label="@string/qs_title"
android:exported="true"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
android:value="true"
tools:replace="android:icon">
Expand Down Expand Up @@ -153,6 +154,11 @@

</activity>

<activity android:name=".ApiLogsActivity"
android:launchMode="singleTask"
android:exported="false"
android:theme="@style/AppTheme.NoActionBar" />

<activity
android:name=".LicenseActivity"
android:launchMode="singleTask"
Expand Down
28 changes: 28 additions & 0 deletions app/src/main/java/nl/eduvpn/app/ApiLogsActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package nl.eduvpn.app

import android.os.Bundle
import androidx.activity.viewModels
import nl.eduvpn.app.base.BaseActivity
import nl.eduvpn.app.databinding.ActivityApiLogsBinding
import nl.eduvpn.app.viewmodel.ApiLogsViewModel
import nl.eduvpn.app.viewmodel.ViewModelFactory
import javax.inject.Inject

class ApiLogsActivity : BaseActivity<ActivityApiLogsBinding>() {

override val layout = R.layout.activity_api_logs

@Inject
protected lateinit var viewModelFactory: ViewModelFactory

private val viewModel by viewModels<ApiLogsViewModel> { viewModelFactory }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
EduVPNApplication.get(this).component().inject(this)
}

override fun onResume() {
super.onResume()
binding.logContents.text = viewModel.getLogFileContents()
}
}
2 changes: 1 addition & 1 deletion app/src/main/java/nl/eduvpn/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}

fun selectCountry(cookie: Int? = null) {
viewModel.getCountryList(this, cookie)
viewModel.getCountryList(cookie)
}

private fun openLink(oAuthUrl: String) {
Expand Down
24 changes: 15 additions & 9 deletions app/src/main/java/nl/eduvpn/app/fragment/SettingsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import de.blinkt.openvpn.activities.LogWindow
import nl.eduvpn.app.ApiLogsActivity
import nl.eduvpn.app.BuildConfig
import nl.eduvpn.app.EduVPNApplication
import nl.eduvpn.app.LicenseActivity
Expand All @@ -32,25 +35,23 @@ import nl.eduvpn.app.databinding.FragmentSettingsBinding
import nl.eduvpn.app.entity.Settings
import nl.eduvpn.app.service.HistoryService
import nl.eduvpn.app.service.PreferencesService
import nl.eduvpn.app.viewmodel.SettingsViewModel
import javax.inject.Inject

/**
* Fragment which displays the available settings to the user.
* Created by Daniel Zolnai on 2016-10-22.
*/
class SettingsFragment : BaseFragment<FragmentSettingsBinding>() {
@Inject
lateinit var preferencesService: PreferencesService

@Inject
lateinit var historyService: HistoryService
val viewModel by viewModels<SettingsViewModel>{ viewModelFactory }

override val layout = R.layout.fragment_settings

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
EduVPNApplication.get(view.context).component().inject(this)
val originalSettings = preferencesService.getAppSettings()
val originalSettings = viewModel.appSettings
binding.useCustomTabsSwitch.isChecked = originalSettings.useCustomTabs()
binding.forceTcpSwitch.isChecked = originalSettings.forceTcp()
binding.useCustomTabsSwitch.setOnClickListener { saveSettings() }
Expand All @@ -64,25 +65,30 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding>() {
)
}
binding.resetDataButton.setOnClickListener { onResetDataClicked() }
binding.viewLogButton.setOnClickListener {
binding.viewOpenvpnLogsButton.setOnClickListener {
val intent = Intent(activity, LogWindow::class.java)
startActivity(intent)
}
binding.viewApiLogsButton.setOnClickListener {
val intent = Intent(activity, ApiLogsActivity::class.java)
startActivity(intent)
}
binding.viewApiLogsContainer.isVisible = viewModel.apiLogFile != null
if (!BuildConfig.API_DISCOVERY_ENABLED) {
binding.resetDataSeparator.visibility = View.GONE
binding.resetAppDataContainer.visibility = View.GONE
}
}

private fun onResetDataClicked() {
if (historyService.addedServers?.hasServers() == true) {
if (viewModel.hasAddedServers) {
val resetDataDialog = AlertDialog.Builder(requireContext())
.setTitle(R.string.reset_data_dialog_title)
.setMessage(R.string.reset_data_dialog_message)
.setPositiveButton(R.string.reset_data_dialog_yes) { dialog: DialogInterface, _: Int ->
dialog.dismiss()
try {
historyService.removeOrganizationData()
viewModel.removeOrganizationData()
} catch (ex: Exception) {
AlertDialog.Builder(requireContext())
.setTitle(R.string.unexpected_error)
Expand All @@ -109,6 +115,6 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding>() {
private fun saveSettings() {
val useCustomTabs = binding.useCustomTabsSwitch.isChecked
val forceTcp = binding.forceTcpSwitch.isChecked
preferencesService.storeAppSettings(Settings(useCustomTabs, forceTcp))
viewModel.storeAppSettings(Settings(useCustomTabs, forceTcp))
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/nl/eduvpn/app/inject/EduVPNComponent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package nl.eduvpn.app.inject

import dagger.Component
import nl.eduvpn.app.ApiLogsActivity
import nl.eduvpn.app.CertExpiredBroadcastReceiver
import nl.eduvpn.app.DisconnectVPNBroadcastReceiver
import nl.eduvpn.app.EduVPNApplication
Expand All @@ -41,6 +42,7 @@ interface EduVPNComponent {

fun inject(organizationSelectionFragment: OrganizationSelectionFragment)
fun inject(mainActivity: MainActivity)
fun inject(apiLogsActivity: ApiLogsActivity)
fun inject(connectionStatusFragment: ConnectionStatusFragment)
fun inject(homeFragment: ProfileSelectionFragment)
fun inject(settingsFragment: SettingsFragment)
Expand Down
17 changes: 14 additions & 3 deletions app/src/main/java/nl/eduvpn/app/inject/ViewModelModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package nl.eduvpn.app.inject

import android.view.View
import androidx.lifecycle.ViewModel
import dagger.Binds
import dagger.Module
Expand Down Expand Up @@ -45,15 +46,25 @@ interface ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(ProfileSelectionViewModel::class)
fun bindProfileSelectionViewModel(profileSelectionViewModel: ProfileSelectionViewModel) : ViewModel
fun bindProfileSelectionViewModel(profileSelectionViewModel: ProfileSelectionViewModel): ViewModel

@Binds
@IntoMap
@ViewModelKey(AddServerViewModel::class)
fun bindAddServerViewModel(addServerViewModel: AddServerViewModel) : ViewModel
fun bindAddServerViewModel(addServerViewModel: AddServerViewModel): ViewModel

@Binds
@IntoMap
@ViewModelKey(MainViewModel::class)
fun bindMainViewModel(mainViewModel: MainViewModel) : ViewModel
fun bindMainViewModel(mainViewModel: MainViewModel): ViewModel

@Binds
@IntoMap
@ViewModelKey(SettingsViewModel::class)
fun bindSettingsViewModel(settingsViewModel: SettingsViewModel): ViewModel

@Binds
@IntoMap
@ViewModelKey(ApiLogsViewModel::class)
fun bindApiLogsViewModel(apiLogsViewModel: ApiLogsViewModel): ViewModel
}
9 changes: 9 additions & 0 deletions app/src/main/java/nl/eduvpn/app/service/BackendService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -310,5 +310,14 @@ class BackendService(
pendingOAuthCookie = null
}
}

fun getLogFile() : File? {
val configDirectory = File(context.cacheDir, DIRECTORY_BACKEND_CONFIG_FILES)
val configFile = File(configDirectory, "log")
if (configFile.exists()) {
return configFile
}
return null
}
}

17 changes: 17 additions & 0 deletions app/src/main/java/nl/eduvpn/app/viewmodel/ApiLogsViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package nl.eduvpn.app.viewmodel

import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.ViewModel
import nl.eduvpn.app.entity.Settings
import nl.eduvpn.app.service.BackendService
import nl.eduvpn.app.service.HistoryService
import nl.eduvpn.app.service.PreferencesService
import javax.inject.Inject

class ApiLogsViewModel @Inject constructor(
private val backendService: BackendService
) : ViewModel() {
fun getLogFileContents() : String {
return backendService.getLogFile()!!.readLines().joinToString("\n")
}
}
4 changes: 1 addition & 3 deletions app/src/main/java/nl/eduvpn/app/viewmodel/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ package nl.eduvpn.app.viewmodel

import android.content.Context
import android.net.Uri
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.wireguard.config.Config
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import nl.eduvpn.app.MainActivity
import nl.eduvpn.app.R
import nl.eduvpn.app.entity.AuthorizationType
Expand Down Expand Up @@ -114,7 +112,7 @@ class MainViewModel @Inject constructor(
}

fun useCustomTabs() = preferencesService.getAppSettings().useCustomTabs()
fun getCountryList(activity: MainActivity, cookie: Int? = null) {
fun getCountryList(cookie: Int? = null) {
viewModelScope.launch(Dispatchers.IO) {
try {
val allInstances = organizationService.fetchServerList().serverList
Expand Down
30 changes: 30 additions & 0 deletions app/src/main/java/nl/eduvpn/app/viewmodel/SettingsViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package nl.eduvpn.app.viewmodel

import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.ViewModel
import nl.eduvpn.app.entity.Settings
import nl.eduvpn.app.service.BackendService
import nl.eduvpn.app.service.HistoryService
import nl.eduvpn.app.service.PreferencesService
import javax.inject.Inject

class SettingsViewModel @Inject constructor(
private val historyService: HistoryService,
private val preferencesService: PreferencesService,
private val backendService: BackendService
) : ViewModel() {

val appSettings get() = preferencesService.getAppSettings()

val apiLogFile get() = backendService.getLogFile()

val hasAddedServers get() = historyService.addedServers?.hasServers() == true

fun removeOrganizationData() {
historyService.removeOrganizationData()
}

fun storeAppSettings(appSettings: Settings) {
preferencesService.storeAppSettings(appSettings)
}
}
48 changes: 48 additions & 0 deletions app/src/main/res/layout/activity_api_logs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of eduVPN.
~
~ eduVPN 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.
~
~ eduVPN 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 eduVPN. If not, see <http://www.gnu.org/licenses/>.
~
-->
<layout>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".LicenseActivity">

<ScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/actionbar_size"
android:background="@color/backgroundColor">

<TextView
android:id="@+id/log_contents"
android:layout_width="match_parent"
android:fontFamily="monospace"
android:textStyle="bold"
tools:text="@tools:sample/lorem/random"
android:layout_height="wrap_content"/>

</ScrollView>

<include
android:id="@+id/toolbar"
layout="@layout/include_toolbar" />
</RelativeLayout>
</layout>
Loading

0 comments on commit ad47336

Please sign in to comment.