Skip to content

Commit

Permalink
Merge branch 'master' into fullscreen
Browse files Browse the repository at this point in the history
  • Loading branch information
corbinlc authored Oct 8, 2021
2 parents da38e9d + 9ffbc46 commit 4289ad1
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 34 deletions.
4 changes: 3 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ android {
minSdkVersion 21
targetSdkVersion 29
versionCode vcode
versionName "2.8.1"
versionName "2.8.2"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
Expand Down Expand Up @@ -312,4 +312,6 @@ dependencies {
}
androidTestUtil "androidx.test:orchestrator:$androidx_test_version"

implementation 'com.google.code.gson:gson:2.8.6'

}
39 changes: 34 additions & 5 deletions app/src/main/java/tech/ula/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.Uri
import android.net.wifi.WifiManager
import android.os.Build
import android.os.Bundle
import android.os.StatFs
import android.os.* // ktlint-disable no-wildcard-imports
import com.google.android.material.textfield.TextInputEditText
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.appcompat.app.AppCompatActivity
Expand All @@ -33,6 +31,7 @@ import androidx.navigation.Navigation
import androidx.navigation.findNavController
import androidx.navigation.ui.NavigationUI
import androidx.navigation.ui.NavigationUI.setupWithNavController
import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_main.* // ktlint-disable no-wildcard-imports
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -58,6 +57,7 @@ class MainActivity : AppCompatActivity(), SessionListFragment.SessionSelection,

private var progressBarIsVisible = false
private var currentFragmentDisplaysProgressDialog = false
private var autoStarted = false

private val logger = SentryLogger()
private val ulaFiles by lazy { UlaFiles(this, this.applicationInfo.nativeLibraryDir) }
Expand Down Expand Up @@ -142,6 +142,14 @@ class MainActivity : AppCompatActivity(), SessionListFragment.SessionSelection,
.get(MainActivityViewModel::class.java)
}

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
if (intent?.type.equals("settings"))
navController.navigate(R.id.settings_fragment)
else
autoStart()
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Expand Down Expand Up @@ -173,6 +181,10 @@ class MainActivity : AppCompatActivity(), SessionListFragment.SessionSelection,
}

viewModel.getState().observe(this, stateObserver)
if (intent?.type.equals("settings"))
navController.navigate(R.id.settings_fragment)
else
autoStart()
}

private fun setNavStartDestination() {
Expand Down Expand Up @@ -222,6 +234,18 @@ class MainActivity : AppCompatActivity(), SessionListFragment.SessionSelection,
return true
}

private fun autoStart() {
val prefs = getSharedPreferences("apps", Context.MODE_PRIVATE)
val json = prefs.getString("AutoApp", " ")
if (json != null)
if (json.compareTo(" ") != 0) {
val gson = Gson()
val autoApp = gson.fromJson(json, App::class.java)
autoStarted = true
appHasBeenSelected(autoApp, true)
}
}

override fun onStart() {
super.onStart()
LocalBroadcastManager.getInstance(this)
Expand Down Expand Up @@ -270,13 +294,13 @@ class MainActivity : AppCompatActivity(), SessionListFragment.SessionSelection,
unregisterReceiver(downloadBroadcastReceiver)
}

override fun appHasBeenSelected(app: App) {
override fun appHasBeenSelected(app: App, autoStart: Boolean) {
if (!PermissionHandler.permissionsAreGranted(this)) {
PermissionHandler.showPermissionsNecessaryDialog(this)
viewModel.waitForPermissions(appToContinue = app)
return
}
viewModel.submitAppSelection(app)
viewModel.submitAppSelection(app, autoStart)
}

override fun sessionHasBeenSelected(session: Session) {
Expand Down Expand Up @@ -341,6 +365,11 @@ class MainActivity : AppCompatActivity(), SessionListFragment.SessionSelection,
.putExtra("type", "start")
.putExtra("session", session)
startService(serviceIntent)
if (autoStarted) {
Handler(Looper.getMainLooper()).postDelayed({
finish()
}, 2000)
}
}

/*
Expand Down
12 changes: 11 additions & 1 deletion app/src/main/java/tech/ula/ui/AppDetailsFragment.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tech.ula.ui

import android.app.Activity
import android.content.Context
import android.os.Build
import android.os.Bundle
import androidx.fragment.app.Fragment
Expand Down Expand Up @@ -31,7 +32,7 @@ class AppDetailsFragment : Fragment() {
val sessionDao = UlaDatabase.getInstance(activityContext).sessionDao()
val appDetails = AppDetails(activityContext.filesDir.path, activityContext.resources)
val buildVersion = Build.VERSION.SDK_INT
val factory = AppDetailsViewmodelFactory(sessionDao, appDetails, buildVersion)
val factory = AppDetailsViewmodelFactory(sessionDao, appDetails, buildVersion, activityContext.getSharedPreferences("apps", Context.MODE_PRIVATE))
ViewModelProviders.of(this, factory)
.get(AppDetailsViewModel::class.java)
}
Expand All @@ -51,6 +52,7 @@ class AppDetailsFragment : Fragment() {
})
viewModel.submitEvent(AppDetailsEvent.SubmitApp(app))
setupPreferredServiceTypeRadioGroup()
setupAutoStartCheckbox()
}

private fun handleViewStateChange(viewState: AppDetailsViewState) {
Expand All @@ -63,6 +65,8 @@ class AppDetailsFragment : Fragment() {
if (viewState.selectedServiceTypeButton != null) {
apps_service_type_preferences.check(viewState.selectedServiceTypeButton)
}

checkbox_auto_start.setChecked(viewState.autoStartEnabled)
}

private fun handleEnableRadioButtons(viewState: AppDetailsViewState) {
Expand Down Expand Up @@ -95,4 +99,10 @@ class AppDetailsFragment : Fragment() {
viewModel.submitEvent(AppDetailsEvent.ServiceTypeChanged(checkedId, app))
}
}

private fun setupAutoStartCheckbox() {
checkbox_auto_start.setOnCheckedChangeListener { _, checked ->
viewModel.submitEvent(AppDetailsEvent.AutoStartChanged(checked, app))
}
}
}
4 changes: 2 additions & 2 deletions app/src/main/java/tech/ula/ui/AppsListFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import tech.ula.viewmodel.AppsListViewModelFactory
class AppsListFragment : Fragment(), AppsListAdapter.AppsClickHandler {

interface AppSelection {
fun appHasBeenSelected(app: App)
fun appHasBeenSelected(app: App, autoStart: Boolean)
}

private val doOnAppSelection: AppSelection by lazy {
Expand Down Expand Up @@ -108,7 +108,7 @@ class AppsListFragment : Fragment(), AppsListAdapter.AppsClickHandler {
}

override fun onClick(app: App) {
doOnAppSelection.appHasBeenSelected(app)
doOnAppSelection.appHasBeenSelected(app, false)
}

override fun createContextMenu(menu: Menu) {
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/tech/ula/ui/SettingsFragment.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package tech.ula.ui

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
Expand All @@ -26,6 +27,16 @@ class SettingsFragment : PreferenceFragmentCompat() {
prootDebugLogger.deleteLogs()
true
}

val clearAutoStartPreference: Preference = findPreference("pref_clear_auto_start")!!
clearAutoStartPreference.setOnPreferenceClickListener {
val prefs = activity!!.getSharedPreferences("apps", Context.MODE_PRIVATE)
with(prefs.edit()) {
remove("AutoApp")
apply()
true
}
}
}

override fun setDivider(divider: Drawable?) {
Expand Down
14 changes: 10 additions & 4 deletions app/src/main/java/tech/ula/utils/NotificationConstructor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,18 @@ class NotificationConstructor(val context: Context) {

fun buildPersistentServiceNotification(): Notification {
val sessionListIntent = Intent(context, MainActivity::class.java)
sessionListIntent.type = "sessionList"
val pendingSessionListIntent = PendingIntent
.getActivity(context, 0, sessionListIntent, 0)

val stopSessionsIntent = Intent(context, ServerService::class.java).putExtra("type", "stopAll")
val stopSessionsPendingIntent = PendingIntent.getService(context, 0,
stopSessionsIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val stopSessionsPendingIntent = PendingIntent
.getService(context, 0, stopSessionsIntent, PendingIntent.FLAG_UPDATE_CURRENT)

val settingsIntent = Intent(context, MainActivity::class.java)
settingsIntent.type = "settings"
val settingsPendingIntent = PendingIntent
.getActivity(context, 0, settingsIntent, 0)

val builder = NotificationCompat.Builder(context, serviceNotificationChannelId)
.setSmallIcon(R.drawable.ic_stat_icon)
Expand All @@ -57,8 +63,8 @@ class NotificationConstructor(val context: Context) {
.setGroupSummary(true)
.setAutoCancel(false)
.setContentIntent(pendingSessionListIntent)
.addAction(R.drawable.ic_stat_icon, "Stop Sessions",
stopSessionsPendingIntent)
.addAction(0, "Stop Sessions", stopSessionsPendingIntent)
.addAction(0, "Settings", settingsPendingIntent)

return builder.build()
}
Expand Down
43 changes: 38 additions & 5 deletions app/src/main/java/tech/ula/viewmodel/AppDetailsViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package tech.ula.viewmodel

import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
import androidx.annotation.IdRes
import androidx.annotation.StringRes
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.google.gson.Gson
import kotlinx.coroutines.* // ktlint-disable no-wildcard-imports
import tech.ula.R
import tech.ula.model.daos.SessionDao
Expand All @@ -25,15 +27,17 @@ data class AppDetailsViewState(
val xsdlEnabled: Boolean,
val describeStateHintEnabled: Boolean,
@StringRes val describeStateText: Int?,
@IdRes val selectedServiceTypeButton: Int?
@IdRes val selectedServiceTypeButton: Int?,
val autoStartEnabled: Boolean
)

sealed class AppDetailsEvent {
data class SubmitApp(val app: App) : AppDetailsEvent()
data class ServiceTypeChanged(@IdRes val selectedButton: Int, val app: App) : AppDetailsEvent()
data class AutoStartChanged(val autoStartEnabled: Boolean, val app: App) : AppDetailsEvent()
}

class AppDetailsViewModel(private val sessionDao: SessionDao, private val appDetails: AppDetails, private val buildVersion: Int) : ViewModel(), CoroutineScope {
class AppDetailsViewModel(private val sessionDao: SessionDao, private val appDetails: AppDetails, private val buildVersion: Int, private val prefs: SharedPreferences) : ViewModel(), CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
Expand All @@ -44,6 +48,7 @@ class AppDetailsViewModel(private val sessionDao: SessionDao, private val appDet
return@launch when (event) {
is AppDetailsEvent.SubmitApp -> constructView(event.app)
is AppDetailsEvent.ServiceTypeChanged -> handleServiceTypeChanged(event)
is AppDetailsEvent.AutoStartChanged -> handleAutoStartChanged(event)
}
}

Expand Down Expand Up @@ -79,6 +84,16 @@ class AppDetailsViewModel(private val sessionDao: SessionDao, private val appDet
else -> null
}

var autoAppEnabled = false
val gson = Gson()
val json = prefs.getString("AutoApp", " ")
if (json != null)
if (json.compareTo(" ") != 0) {
val autoApp = gson.fromJson(json, App::class.java)
if (autoApp.name.compareTo(appTitle) == 0)
autoAppEnabled = true
}

return AppDetailsViewState(
appIconUri,
appTitle,
Expand All @@ -88,7 +103,8 @@ class AppDetailsViewModel(private val sessionDao: SessionDao, private val appDet
xsdlEnabled,
describeStateHintEnabled,
describeStateText,
selectedServiceTypeButton
selectedServiceTypeButton,
autoAppEnabled
)
}

Expand All @@ -113,6 +129,23 @@ class AppDetailsViewModel(private val sessionDao: SessionDao, private val appDet
}
}

private fun handleAutoStartChanged(event: AppDetailsEvent.AutoStartChanged) {
this.launch {
if (event.autoStartEnabled)
with(prefs.edit()) {
val gson = Gson()
val json = gson.toJson(event.app)
putString("AutoApp", json)
apply()
}
else
with(prefs.edit()) {
remove("AutoApp")
apply()
}
}
}

private fun getStateHintEnabled(appSession: Session?): Boolean {
return !radioButtonsShouldBeEnabled(appSession)
}
Expand Down Expand Up @@ -141,9 +174,9 @@ class AppDetailsViewModel(private val sessionDao: SessionDao, private val appDet
}
}

class AppDetailsViewmodelFactory(private val sessionDao: SessionDao, private val appDetails: AppDetails, private val buildVersion: Int) : ViewModelProvider.NewInstanceFactory() {
class AppDetailsViewmodelFactory(private val sessionDao: SessionDao, private val appDetails: AppDetails, private val buildVersion: Int, private val prefs: SharedPreferences) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return AppDetailsViewModel(sessionDao, appDetails, buildVersion) as T
return AppDetailsViewModel(sessionDao, appDetails, buildVersion, prefs) as T
}
}
4 changes: 2 additions & 2 deletions app/src/main/java/tech/ula/viewmodel/MainActivityViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ class MainActivityViewModel(
}
}

fun submitAppSelection(app: App) {
if (!selectionsCanBeMade()) return
fun submitAppSelection(app: App, autoStart: Boolean) {
if (!autoStart && !selectionsCanBeMade()) return
lastSelectedApp = app
submitAppsStartupEvent(AppSelected(app))
}
Expand Down
13 changes: 12 additions & 1 deletion app/src/main/res/layout/frag_app_details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,18 @@
android:textAlignment="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_describe_state" />
app:layout_constraintTop_toBottomOf="@id/text_describe_state"
app:layout_constraintBottom_toTopOf="@id/checkbox_auto_start" />

<CheckBox android:id="@+id/checkbox_auto_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="@string/auto_start_checkbox"
android:textAlignment="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_xsdl_version_supported_description"/>

</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
3 changes: 3 additions & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@
<!-- Advanced options -->
<string name="desc_import_backups_should_use_same_settings">Bitte gleich ausfüllen: \n\n\u2022 Nutzername \n\u2022 Passwort \n\u2022 VNC-Passwort \n\u2022 Distribution \n\n wie beim Backup, um einen reibungslosen Ablauf sicherzustellen</string>

<string name="pref_clear_auto_start_title">Autostart Einstellungen löschen</string>
<string name="pref_clear_auto_start_summary">Keine App mehr automatisch starten, bis wieder aktiviert wird.</string>
<string name="auto_start_checkbox">Autostart aktivieren</string>
<string name="pref_custom_scaling_enabled_title">Benuterdefinierten Skalierfaktor verwenden</string>
<string name="pref_custom_scaling_enabled_summary">Erlaubt das Einstellen eines benutzerdefinierten Skalierfaktors, um die Display Auflösung der VNC Sitzung zu verringern.</string>
<string name="pref_scaling_title">Skalierfaktor festlegen</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@
<string name="pref_app_category">App Preferences</string>
<string name="pref_default_landing_page_title">Default Landing Page</string>
<string name="pref_default_landing_page_message">Select the page you would like to open the app with.</string>
<string name="pref_clear_auto_start_title">Clear Auto Start Settings</string>
<string name="pref_clear_auto_start_summary">Stops any app from auto starting until enabled again.</string>
<string name="pref_custom_scaling_enabled_title">Use Custom Graphical Scaling Factor</string>
<string name="pref_custom_scaling_enabled_summary">Allows specifying a custom scaling factor to decrease the resolution of the VNC session.</string>
<string name="pref_scaling_title">Set Custom Scaling Factor</string>
Expand Down Expand Up @@ -285,5 +287,6 @@

<!-- Advanced options -->
<string name="desc_import_backups_should_use_same_settings">Fill out the same: \n\n\u2022 username \n\u2022 password \n\u2022 VNC password \n\u2022 distribution \n\n as the backup to ensure smooth functionality</string>
<string name="auto_start_checkbox">Enable Auto Start</string>

</resources>
Loading

0 comments on commit 4289ad1

Please sign in to comment.