Wait for the vm to stop before resize activity finishes
Bug: 401871090
Bug: 401875013
Test: start the VM, resize
Change-Id: Ic78b6c29a9aba9842734b03e19ed830094a533c7
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
index 7502415..80f403b 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
@@ -253,7 +253,7 @@
executorService.shutdown()
getSystemService<AccessibilityManager>(AccessibilityManager::class.java)
.removeAccessibilityStateChangeListener(this)
- stop(this)
+ stop(this, this)
super.onDestroy()
}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsDiskResizeActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsDiskResizeActivity.kt
index 8ea4b25..68da45f 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsDiskResizeActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsDiskResizeActivity.kt
@@ -31,6 +31,7 @@
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
+import com.android.virtualization.terminal.VmLauncherService.VmLauncherServiceCallback
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.util.Locale
import java.util.regex.Pattern
@@ -140,12 +141,32 @@
diskSizeMb = progressToMb(diskSizeSlider.progress)
buttons.isVisible = false
- // Restart terminal
- val intent = baseContext.packageManager.getLaunchIntentForPackage(baseContext.packageName)
- intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
- intent?.putExtra(MainActivity.KEY_DISK_SIZE, mbToBytes(diskSizeMb))
- finish()
- startActivity(intent)
+ // Note: we first stop the VM, and wait for it to fully stop. Then we (re) start the Main
+ // Activity with an extra argument specifying the new size. The actual resizing will be done
+ // there.
+ // TODO: show progress until the stop is confirmed
+ VmLauncherService.stop(
+ this,
+ object : VmLauncherServiceCallback {
+ override fun onVmStart() {}
+
+ override fun onTerminalAvailable(info: TerminalInfo) {}
+
+ override fun onVmStop() {
+ finish()
+
+ val intent =
+ baseContext.packageManager.getLaunchIntentForPackage(
+ baseContext.packageName
+ )!!
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ intent.putExtra(MainActivity.KEY_DISK_SIZE, mbToBytes(diskSizeMb))
+ startActivity(intent)
+ }
+
+ override fun onVmError() {}
+ },
+ )
}
fun updateSliderText(sizeMb: Long) {
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
index 2d7dde9..deccae5 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
@@ -69,10 +69,10 @@
// TODO: using lateinit for some fields to avoid null
private var virtualMachine: VirtualMachine? = null
- private var resultReceiver: ResultReceiver? = null
private var server: Server? = null
private var debianService: DebianServiceImpl? = null
private var portNotifier: PortNotifier? = null
+ private var runner: Runner? = null
interface VmLauncherServiceCallback {
fun onVmStart()
@@ -94,12 +94,22 @@
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
+ val resultReceiver =
+ intent.getParcelableExtra<ResultReceiver?>(
+ Intent.EXTRA_RESULT_RECEIVER,
+ ResultReceiver::class.java,
+ )
+
if (intent.action == ACTION_SHUTDOWN_VM) {
if (debianService != null && debianService!!.shutdownDebian()) {
// During shutdown, change the notification content to indicate that it's closing
val notification = createNotificationForTerminalClose()
getSystemService<NotificationManager?>(NotificationManager::class.java)
.notify(this.hashCode(), notification)
+ runner?.exitStatus?.thenAcceptAsync { success: Boolean ->
+ resultReceiver?.send(if (success) RESULT_STOP else RESULT_ERROR, null)
+ stopSelf()
+ }
} else {
// If there is no Debian service or it fails to shutdown, just stop the service.
stopSelf()
@@ -125,24 +135,18 @@
}
val config = configBuilder.build()
- val runner: Runner =
+ runner =
try {
create(this, config)
} catch (e: VirtualMachineException) {
throw RuntimeException("cannot create runner", e)
}
- virtualMachine = runner.vm
- resultReceiver =
- intent.getParcelableExtra<ResultReceiver?>(
- Intent.EXTRA_RESULT_RECEIVER,
- ResultReceiver::class.java,
- )
-
+ virtualMachine = runner!!.vm
val mbc = MemBalloonController(this, virtualMachine!!)
mbc.start()
- runner.exitStatus.thenAcceptAsync { success: Boolean ->
+ runner!!.exitStatus.thenAcceptAsync { success: Boolean ->
mbc.stop()
resultReceiver?.send(if (success) RESULT_STOP else RESULT_ERROR, null)
stopSelf()
@@ -462,9 +466,21 @@
return ResultReceiver.CREATOR.createFromParcel(parcel).also { parcel.recycle() }
}
- fun stop(context: Context) {
+ fun stop(context: Context, callback: VmLauncherServiceCallback?) {
val i = getMyIntent(context)
i.setAction(ACTION_SHUTDOWN_VM)
+ val resultReceiver: ResultReceiver =
+ object : ResultReceiver(Handler(Looper.myLooper()!!)) {
+ override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
+ if (callback == null) {
+ return
+ }
+ when (resultCode) {
+ RESULT_STOP -> callback.onVmStop()
+ }
+ }
+ }
+ i.putExtra(Intent.EXTRA_RESULT_RECEIVER, getResultReceiverForIntent(resultReceiver))
context.startService(i)
}
}