Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit d1fa239

Browse files
committed
fix: reload JDK distributions when returning from terminal to onboarding activity
1 parent 9e16f89 commit d1fa239

File tree

8 files changed

+193
-74
lines changed

8 files changed

+193
-74
lines changed

app/src/main/java/com/itsaky/androidide/activities/OnboardingActivity.kt

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package com.itsaky.androidide.activities
1919

2020
import android.content.Intent
2121
import android.os.Bundle
22+
import android.util.Log
23+
import androidx.activity.result.contract.ActivityResultContracts
2224
import androidx.core.content.ContextCompat
2325
import androidx.fragment.app.Fragment
2426
import com.github.appintro.AppIntro2
@@ -32,18 +34,42 @@ import com.itsaky.androidide.fragments.onboarding.IdeSetupConfigurationFragment
3234
import com.itsaky.androidide.fragments.onboarding.OnboardingInfoFragment
3335
import com.itsaky.androidide.fragments.onboarding.PermissionsFragment
3436
import com.itsaky.androidide.fragments.onboarding.StatisticsFragment
37+
import com.itsaky.androidide.models.JdkDistribution
3538
import com.itsaky.androidide.preferences.internal.prefManager
3639
import com.itsaky.androidide.preferences.internal.statConsentDialogShown
40+
import com.itsaky.androidide.tasks.launchAsyncWithProgress
3741
import com.itsaky.androidide.ui.themes.IThemeManager
3842
import com.itsaky.androidide.utils.Environment
3943
import com.termux.shared.android.PackageUtils
4044
import com.termux.shared.markdown.MarkdownUtils
4145
import com.termux.shared.termux.TermuxConstants
46+
import kotlinx.coroutines.CoroutineName
47+
import kotlinx.coroutines.CoroutineScope
48+
import kotlinx.coroutines.Dispatchers
49+
import kotlinx.coroutines.Job
50+
import kotlinx.coroutines.cancel
51+
import kotlinx.coroutines.withContext
4252

4353
class OnboardingActivity : AppIntro2() {
4454

55+
private val terminalActivityCallback = registerForActivityResult(
56+
ActivityResultContracts.StartActivityForResult()) {
57+
Log.d(TAG, "TerminalActivity: resultCode=${it.resultCode}")
58+
if (!isFinishing) {
59+
reloadJdkDistInfo {
60+
tryNavigateToMainIfSetupIsCompleted()
61+
}
62+
}
63+
}
64+
65+
private val activityScope =
66+
CoroutineScope(Dispatchers.Main + CoroutineName("OnboardingActivity"))
67+
68+
private var listJdkInstallationsJob: Job? = null
69+
4570
companion object {
4671

72+
private const val TAG = "OnboardingActivity"
4773
private const val KEY_ARCHCONFIG_WARNING_IS_SHOWN = "ide.archConfig.experimentalWarning.isShown"
4874
}
4975

@@ -52,9 +78,8 @@ class OnboardingActivity : AppIntro2() {
5278

5379
super.onCreate(savedInstanceState)
5480

55-
if (isSetupDone()) {
56-
openActivity(MainActivity::class.java)
57-
finish()
81+
if (tryNavigateToMainIfSetupIsCompleted()) {
82+
return
5883
}
5984

6085
setSwipeLock(true)
@@ -110,12 +135,16 @@ class OnboardingActivity : AppIntro2() {
110135

111136
override fun onResume() {
112137
super.onResume()
113-
if (isSetupDone()) {
114-
openActivity(MainActivity::class.java)
115-
finish()
138+
reloadJdkDistInfo {
139+
tryNavigateToMainIfSetupIsCompleted()
116140
}
117141
}
118142

143+
override fun onDestroy() {
144+
super.onDestroy()
145+
activityScope.cancel("Activity is being destroyed")
146+
}
147+
119148
override fun onNextPressed(currentFragment: Fragment?) {
120149
(currentFragment as? StatisticsFragment?)?.updateStatOptInStatus()
121150
}
@@ -129,31 +158,58 @@ class OnboardingActivity : AppIntro2() {
129158
}
130159

131160
if (!checkToolsIsInstalled() && currentFragment is IdeSetupConfigurationFragment) {
132-
val intenet = Intent(this, TerminalActivity::class.java)
161+
val intent = Intent(this, TerminalActivity::class.java)
133162
if (currentFragment.isAutoInstall()) {
134-
intenet.putExtra(TerminalActivity.EXTRA_ONBOARDING_RUN_IDESETUP, true)
135-
intenet.putExtra(TerminalActivity.EXTRA_ONBOARDING_RUN_IDESETUP_ARGS,
163+
intent.putExtra(TerminalActivity.EXTRA_ONBOARDING_RUN_IDESETUP, true)
164+
intent.putExtra(TerminalActivity.EXTRA_ONBOARDING_RUN_IDESETUP_ARGS,
136165
currentFragment.buildIdeSetupArguments())
137166
}
138-
startActivity(intenet)
167+
terminalActivityCallback.launch(intent)
139168
return
140169
}
141170

142-
openActivity(MainActivity::class.java)
143-
}
144-
145-
private fun openActivity(cls: Class<*>) {
146-
startActivity(Intent(this, cls))
171+
tryNavigateToMainIfSetupIsCompleted()
147172
}
148173

149174
private fun checkToolsIsInstalled(): Boolean {
150175
return IJdkDistributionProvider.getInstance().installedDistributions.isNotEmpty()
151176
&& Environment.ANDROID_HOME.exists()
152177
}
153178

154-
private fun isSetupDone() =
155-
(checkToolsIsInstalled() && statConsentDialogShown && PermissionsFragment.areAllPermissionsGranted(
156-
this))
179+
private fun isSetupCompleted(): Boolean {
180+
return checkToolsIsInstalled()
181+
&& statConsentDialogShown
182+
&& PermissionsFragment.areAllPermissionsGranted(this)
183+
}
184+
185+
private fun tryNavigateToMainIfSetupIsCompleted(): Boolean {
186+
if (isSetupCompleted()) {
187+
startActivity(Intent(this, MainActivity::class.java))
188+
finish()
189+
return true
190+
}
191+
192+
return false
193+
}
194+
195+
private inline fun reloadJdkDistInfo(crossinline distConsumer: (List<JdkDistribution>) -> Unit) {
196+
listJdkInstallationsJob?.cancel("Reloading JDK distributions")
197+
198+
listJdkInstallationsJob = activityScope.launchAsyncWithProgress(Dispatchers.Default,
199+
configureFlashbar = { builder, _ ->
200+
builder.message(string.please_wait)
201+
}) { _, _ ->
202+
val distributionProvider = IJdkDistributionProvider.getInstance()
203+
distributionProvider.loadDistributions()
204+
withContext(Dispatchers.Main) {
205+
distConsumer(distributionProvider.installedDistributions)
206+
}
207+
}.also {
208+
it?.invokeOnCompletion {
209+
listJdkInstallationsJob = null
210+
}
211+
}
212+
}
157213

158214
private fun isInstalledOnSdCard(): Boolean {
159215
// noinspection SdCardPath

app/src/main/java/com/itsaky/androidide/app/configuration/JdkDistributionProviderImpl.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,17 @@ class JdkDistributionProviderImpl : IJdkDistributionProvider {
3636
private val log = ILogger.newInstance("JdkDistributionProviderImpl")
3737
}
3838

39-
override val installedDistributions: List<JdkDistribution> by lazy {
40-
JdkUtils.findJavaInstallations().also { distributions ->
39+
private var _installedDistributions: List<JdkDistribution>? = null
40+
41+
override val installedDistributions: List<JdkDistribution>
42+
get() = _installedDistributions ?: emptyList()
43+
44+
override fun loadDistributions() {
45+
_installedDistributions = doLoadDistributions()
46+
}
47+
48+
private fun doLoadDistributions(): List<JdkDistribution> {
49+
return JdkUtils.findJavaInstallations().also { distributions ->
4150

4251
// set the default value for the 'javaHome' preference
4352
if (javaHome.isBlank() && distributions.isNotEmpty()) {

common/src/main/java/com/itsaky/androidide/app/configuration/IJdkDistributionProvider.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package com.itsaky.androidide.app.configuration
1919

20+
import androidx.annotation.WorkerThread
2021
import com.itsaky.androidide.models.JdkDistribution
2122
import com.itsaky.androidide.utils.ServiceLoader
2223

@@ -32,6 +33,13 @@ interface IJdkDistributionProvider {
3233
*/
3334
val installedDistributions: List<JdkDistribution>
3435

36+
/**
37+
* Reloads the installed JDK distributions. This function is synchronous and should not be called
38+
* on the UI thread.
39+
*/
40+
@WorkerThread
41+
fun loadDistributions()
42+
3543
/**
3644
* Get the [JdkDistribution] instance for the given java version.
3745
*

common/src/main/java/com/itsaky/androidide/managers/ToolsManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public static void init(@NonNull BaseApplication app, Runnable onFinish) {
5353

5454
CompletableFuture.runAsync(() -> {
5555
// Load installed JDK distributions
56-
IJdkDistributionProvider.getInstance().getInstalledDistributions();
56+
IJdkDistributionProvider.getInstance().loadDistributions();
5757

5858
writeNoMediaFile();
5959
extractAapt2();

termux/termux-app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ import android.view.View
2626
import android.widget.Button
2727
import androidx.core.content.ContextCompat
2828
import androidx.core.view.WindowCompat
29+
import com.itsaky.androidide.terminal.IdeTerminalSessionClient
2930
import com.itsaky.androidide.terminal.IdesetupSession
3031
import com.itsaky.androidide.utils.Environment
3132
import com.itsaky.androidide.utils.ILogger
3233
import com.itsaky.androidide.utils.flashError
3334
import com.termux.R
3435
import com.termux.app.TermuxActivity
36+
import com.termux.app.terminal.TermuxTerminalSessionActivityClient
3537
import com.termux.shared.termux.shell.command.runner.terminal.TermuxSession
3638

3739
/**
@@ -70,6 +72,10 @@ class TerminalActivity : TermuxActivity() {
7072
KEY_TERMINAL_CAN_ADD_SESSIONS, true) ?: true
7173
}
7274

75+
override fun onCreateTerminalSessionClient(): TermuxTerminalSessionActivityClient {
76+
return IdeTerminalSessionClient(this)
77+
}
78+
7379
override fun onSaveInstanceState(savedInstanceState: Bundle) {
7480
super.onSaveInstanceState(savedInstanceState)
7581
savedInstanceState.putBoolean(KEY_TERMINAL_CAN_ADD_SESSIONS, canAddNewSessions)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* This file is part of AndroidIDE.
3+
*
4+
* AndroidIDE is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* AndroidIDE is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.itsaky.androidide.terminal
19+
20+
import com.itsaky.androidide.activities.TerminalActivity
21+
import com.termux.app.terminal.TermuxTerminalSessionActivityClient
22+
import com.termux.terminal.TerminalSession
23+
import com.termux.terminal.TerminalSessionClient
24+
25+
/**
26+
* [TerminalSessionClient] delegate for AndroidIDE.
27+
*
28+
* @author Akash Yadav
29+
*/
30+
class IdeTerminalSessionClient(
31+
activity: TerminalActivity
32+
) : TermuxTerminalSessionActivityClient(activity) {
33+
34+
override fun onSessionFinished(finishedSession: TerminalSession) {
35+
val termuxSession = mActivity?.termuxService?.getTermuxSessionForTerminalSession(
36+
finishedSession)
37+
if (termuxSession != null && termuxSession is IdesetupSession) {
38+
// if the finished session was performing tools installation
39+
// then set the result code for the installation process
40+
mActivity.setResult(finishedSession.exitStatus)
41+
}
42+
43+
super.onSessionFinished(finishedSession)
44+
}
45+
}

0 commit comments

Comments
 (0)