diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
index e84250b..31c9a91 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
@@ -142,7 +142,7 @@
         private const val HOST_URL = "https://dl.google.com/android/ferrochrome/$BUILD_TAG"
 
         @JvmStatic
-        fun getSdcardPathForTesting(): Path? {
+        fun getSdcardPathForTesting(): Path {
             return Environment.getExternalStoragePublicDirectory(DIR_IN_SDCARD).toPath()
         }
 
@@ -151,7 +151,7 @@
          */
         @JvmStatic
         fun fromSdCard(): ImageArchive {
-            return ImageArchive(getSdcardPathForTesting()!!.resolve(ARCHIVE_NAME))
+            return ImageArchive(getSdcardPathForTesting().resolve(ARCHIVE_NAME))
         }
 
         /**
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Runner.kt b/android/TerminalApp/java/com/android/virtualization/terminal/Runner.kt
index 86dadbe..897e182 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/Runner.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/Runner.kt
@@ -32,7 +32,7 @@
     val exitStatus = callback.finishedSuccessfully
 
     private class Callback : VirtualMachineCallback {
-        val finishedSuccessfully: CompletableFuture<Boolean?> = CompletableFuture<Boolean?>()
+        val finishedSuccessfully: CompletableFuture<Boolean> = CompletableFuture<Boolean>()
 
         override fun onPayloadStarted(vm: VirtualMachine) {
             // This event is only from Microdroid-based VM. Custom VM shouldn't emit this.
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
deleted file mode 100644
index 09b58d3..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.virtualization.terminal;
-
-import static com.android.virtualization.terminal.MainActivity.TAG;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Icon;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.ResultReceiver;
-import android.system.virtualmachine.VirtualMachine;
-import android.system.virtualmachine.VirtualMachineConfig;
-import android.system.virtualmachine.VirtualMachineCustomImageConfig;
-import android.system.virtualmachine.VirtualMachineCustomImageConfig.Disk;
-import android.system.virtualmachine.VirtualMachineException;
-import android.util.Log;
-import android.widget.Toast;
-
-import io.grpc.Grpc;
-import io.grpc.InsecureServerCredentials;
-import io.grpc.Metadata;
-import io.grpc.Server;
-import io.grpc.ServerCall;
-import io.grpc.ServerCallHandler;
-import io.grpc.ServerInterceptor;
-import io.grpc.Status;
-import io.grpc.okhttp.OkHttpServerBuilder;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Objects;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-public class VmLauncherService extends Service {
-    private static final String EXTRA_NOTIFICATION = "EXTRA_NOTIFICATION";
-    private static final String ACTION_START_VM_LAUNCHER_SERVICE =
-            "android.virtualization.START_VM_LAUNCHER_SERVICE";
-
-    public static final String ACTION_STOP_VM_LAUNCHER_SERVICE =
-            "android.virtualization.STOP_VM_LAUNCHER_SERVICE";
-
-    private static final int RESULT_START = 0;
-    private static final int RESULT_STOP = 1;
-    private static final int RESULT_ERROR = 2;
-
-    private ExecutorService mExecutorService;
-    private VirtualMachine mVirtualMachine;
-    private ResultReceiver mResultReceiver;
-    private Server mServer;
-    private DebianServiceImpl mDebianService;
-    private PortNotifier mPortNotifier;
-
-    private static Intent getMyIntent(Context context) {
-        return new Intent(context.getApplicationContext(), VmLauncherService.class);
-    }
-
-    public interface VmLauncherServiceCallback {
-        void onVmStart();
-
-        void onVmStop();
-
-        void onVmError();
-    }
-
-    public static void run(
-            Context context, VmLauncherServiceCallback callback, Notification notification) {
-        Intent i = getMyIntent(context);
-        if (i == null) {
-            return;
-        }
-        ResultReceiver resultReceiver =
-                new ResultReceiver(new Handler(Looper.myLooper())) {
-                    @Override
-                    protected void onReceiveResult(int resultCode, Bundle resultData) {
-                        if (callback == null) {
-                            return;
-                        }
-                        switch (resultCode) {
-                            case RESULT_START:
-                                callback.onVmStart();
-                                return;
-                            case RESULT_STOP:
-                                callback.onVmStop();
-                                return;
-                            case RESULT_ERROR:
-                                callback.onVmError();
-                                return;
-                        }
-                    }
-                };
-        i.putExtra(Intent.EXTRA_RESULT_RECEIVER, getResultReceiverForIntent(resultReceiver));
-        i.putExtra(VmLauncherService.EXTRA_NOTIFICATION, notification);
-        context.startForegroundService(i);
-    }
-
-    private static ResultReceiver getResultReceiverForIntent(ResultReceiver r) {
-        Parcel parcel = Parcel.obtain();
-        r.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        r = ResultReceiver.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-        return r;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (Objects.equals(intent.getAction(), ACTION_STOP_VM_LAUNCHER_SERVICE)) {
-
-            if (mDebianService != null && mDebianService.shutdownDebian()) {
-                // During shutdown, change the notification content to indicate that it's closing
-                Notification notification = createNotificationForTerminalClose();
-                getSystemService(NotificationManager.class).notify(this.hashCode(), notification);
-            } else {
-                // If there is no Debian service or it fails to shutdown, just stop the service.
-                stopSelf();
-            }
-            return START_NOT_STICKY;
-        }
-        if (mVirtualMachine != null) {
-            Log.d(TAG, "VM instance is already started");
-            return START_NOT_STICKY;
-        }
-        mExecutorService =
-                Executors.newCachedThreadPool(new TerminalThreadFactory(getApplicationContext()));
-
-        InstalledImage image = InstalledImage.getDefault(this);
-        ConfigJson json = ConfigJson.from(this, image.getConfigPath());
-        VirtualMachineConfig.Builder configBuilder = json.toConfigBuilder(this);
-        VirtualMachineCustomImageConfig.Builder customImageConfigBuilder =
-                json.toCustomImageConfigBuilder(this);
-        if (overrideConfigIfNecessary(customImageConfigBuilder)) {
-            configBuilder.setCustomImageConfig(customImageConfigBuilder.build());
-        }
-        VirtualMachineConfig config = configBuilder.build();
-
-        Runner runner;
-        try {
-            android.os.Trace.beginSection("vmCreate");
-            runner = Runner.create(this, config);
-            android.os.Trace.endSection();
-            android.os.Trace.beginAsyncSection("debianBoot", 0);
-        } catch (VirtualMachineException e) {
-            throw new RuntimeException("cannot create runner", e);
-        }
-        mVirtualMachine = runner.getVm();
-        mResultReceiver =
-                intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER, ResultReceiver.class);
-
-        runner.getExitStatus()
-                .thenAcceptAsync(
-                        success -> {
-                            if (mResultReceiver != null) {
-                                mResultReceiver.send(success ? RESULT_STOP : RESULT_ERROR, null);
-                            }
-                            stopSelf();
-                        });
-        Path logPath = getFileStreamPath(mVirtualMachine.getName() + ".log").toPath();
-        Logger.setup(mVirtualMachine, logPath, mExecutorService);
-
-        Notification notification =
-                intent.getParcelableExtra(EXTRA_NOTIFICATION, Notification.class);
-
-        startForeground(this.hashCode(), notification);
-
-        mResultReceiver.send(RESULT_START, null);
-
-        mPortNotifier = new PortNotifier(this);
-
-        // TODO: dedup this part
-        NsdManager nsdManager = getSystemService(NsdManager.class);
-        NsdServiceInfo info = new NsdServiceInfo();
-        info.setServiceType("_http._tcp");
-        info.setServiceName("ttyd");
-        nsdManager.registerServiceInfoCallback(
-                info,
-                mExecutorService,
-                new NsdManager.ServiceInfoCallback() {
-                    @Override
-                    public void onServiceInfoCallbackRegistrationFailed(int errorCode) {}
-
-                    @Override
-                    public void onServiceInfoCallbackUnregistered() {}
-
-                    @Override
-                    public void onServiceLost() {}
-
-                    @Override
-                    public void onServiceUpdated(NsdServiceInfo info) {
-                        nsdManager.unregisterServiceInfoCallback(this);
-                        Log.i(TAG, "Service found: " + info.toString());
-                        String ipAddress = info.getHostAddresses().get(0).getHostAddress();
-                        startDebianServer(ipAddress);
-                    }
-                });
-
-        return START_NOT_STICKY;
-    }
-
-    private Notification createNotificationForTerminalClose() {
-        Intent stopIntent = new Intent();
-        stopIntent.setClass(this, VmLauncherService.class);
-        stopIntent.setAction(VmLauncherService.ACTION_STOP_VM_LAUNCHER_SERVICE);
-        PendingIntent stopPendingIntent =
-                PendingIntent.getService(
-                        this,
-                        0,
-                        stopIntent,
-                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
-        Icon icon = Icon.createWithResource(getResources(), R.drawable.ic_launcher_foreground);
-        String stopActionText =
-                getResources().getString(R.string.service_notification_force_quit_action);
-        String stopNotificationTitle =
-                getResources().getString(R.string.service_notification_close_title);
-        return new Notification.Builder(this, this.getPackageName())
-                .setSmallIcon(R.drawable.ic_launcher_foreground)
-                .setContentTitle(stopNotificationTitle)
-                .setOngoing(true)
-                .setSilent(true)
-                .addAction(
-                        new Notification.Action.Builder(icon, stopActionText, stopPendingIntent)
-                                .build())
-                .build();
-    }
-
-    private boolean overrideConfigIfNecessary(VirtualMachineCustomImageConfig.Builder builder) {
-        boolean changed = false;
-        // TODO: check if ANGLE is enabled for the app.
-        if (Files.exists(ImageArchive.getSdcardPathForTesting().resolve("virglrenderer"))) {
-            builder.setGpuConfig(
-                    new VirtualMachineCustomImageConfig.GpuConfig.Builder()
-                            .setBackend("virglrenderer")
-                            .setRendererUseEgl(true)
-                            .setRendererUseGles(true)
-                            .setRendererUseGlx(false)
-                            .setRendererUseSurfaceless(true)
-                            .setRendererUseVulkan(false)
-                            .setContextTypes(new String[] {"virgl2"})
-                            .build());
-            Toast.makeText(this, R.string.virgl_enabled, Toast.LENGTH_SHORT).show();
-            changed = true;
-        }
-
-        InstalledImage image = InstalledImage.getDefault(this);
-        if (image.hasBackup()) {
-            Path backup = image.getBackupFile();
-            builder.addDisk(Disk.RWDisk(backup.toString()));
-            changed = true;
-        }
-        return changed;
-    }
-
-    private void startDebianServer(String ipAddress) {
-        ServerInterceptor interceptor =
-                new ServerInterceptor() {
-                    @Override
-                    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
-                            ServerCall<ReqT, RespT> call,
-                            Metadata headers,
-                            ServerCallHandler<ReqT, RespT> next) {
-                        InetSocketAddress remoteAddr =
-                                (InetSocketAddress)
-                                        call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
-
-                        if (remoteAddr != null
-                                && Objects.equals(
-                                        remoteAddr.getAddress().getHostAddress(), ipAddress)) {
-                            // Allow the request only if it is from VM
-                            return next.startCall(call, headers);
-                        }
-                        Log.d(TAG, "blocked grpc request from " + remoteAddr);
-                        call.close(Status.Code.PERMISSION_DENIED.toStatus(), new Metadata());
-                        return new ServerCall.Listener<ReqT>() {};
-                    }
-                };
-        try {
-            // TODO(b/372666638): gRPC for java doesn't support vsock for now.
-            int port = 0;
-            mDebianService = new DebianServiceImpl(this);
-            mServer =
-                    OkHttpServerBuilder.forPort(port, InsecureServerCredentials.create())
-                            .intercept(interceptor)
-                            .addService(mDebianService)
-                            .build()
-                            .start();
-        } catch (IOException e) {
-            Log.d(TAG, "grpc server error", e);
-            return;
-        }
-
-        mExecutorService.execute(
-                () -> {
-                    // TODO(b/373533555): we can use mDNS for that.
-                    String debianServicePortFileName = "debian_service_port";
-                    File debianServicePortFile = new File(getFilesDir(), debianServicePortFileName);
-                    try (FileOutputStream writer = new FileOutputStream(debianServicePortFile)) {
-                        writer.write(String.valueOf(mServer.getPort()).getBytes());
-                    } catch (IOException e) {
-                        Log.d(TAG, "cannot write grpc port number", e);
-                    }
-                });
-    }
-
-    public static void stop(Context context) {
-        Intent i = getMyIntent(context);
-        i.setAction(VmLauncherService.ACTION_STOP_VM_LAUNCHER_SERVICE);
-        context.startService(i);
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mPortNotifier != null) {
-            mPortNotifier.stop();
-        }
-        getSystemService(NotificationManager.class).cancelAll();
-        stopDebianServer();
-        if (mVirtualMachine != null) {
-            if (mVirtualMachine.getStatus() == VirtualMachine.STATUS_RUNNING) {
-                try {
-                    mVirtualMachine.stop();
-                    stopForeground(STOP_FOREGROUND_REMOVE);
-                } catch (VirtualMachineException e) {
-                    Log.e(TAG, "failed to stop a VM instance", e);
-                }
-            }
-            mExecutorService.shutdownNow();
-            mExecutorService = null;
-            mVirtualMachine = null;
-        }
-        super.onDestroy();
-    }
-
-    private void stopDebianServer() {
-        if (mDebianService != null) {
-            mDebianService.killForwarderHost();
-        }
-        if (mServer != null) {
-            mServer.shutdown();
-        }
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
new file mode 100644
index 0000000..2796b86
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.virtualization.terminal
+
+import android.app.Notification
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.app.Service
+import android.content.Context
+import android.content.Intent
+import android.graphics.drawable.Icon
+import android.net.nsd.NsdManager
+import android.net.nsd.NsdServiceInfo
+import android.os.Bundle
+import android.os.Handler
+import android.os.IBinder
+import android.os.Looper
+import android.os.Parcel
+import android.os.ResultReceiver
+import android.os.Trace
+import android.system.virtualmachine.VirtualMachine
+import android.system.virtualmachine.VirtualMachineCustomImageConfig
+import android.system.virtualmachine.VirtualMachineException
+import android.util.Log
+import android.widget.Toast
+import com.android.virtualization.terminal.MainActivity.TAG
+import com.android.virtualization.terminal.Runner.Companion.create
+import com.android.virtualization.terminal.VmLauncherService.VmLauncherServiceCallback
+import io.grpc.Grpc
+import io.grpc.InsecureServerCredentials
+import io.grpc.Metadata
+import io.grpc.Server
+import io.grpc.ServerCall
+import io.grpc.ServerCallHandler
+import io.grpc.ServerInterceptor
+import io.grpc.Status
+import io.grpc.okhttp.OkHttpServerBuilder
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.lang.RuntimeException
+import java.net.InetSocketAddress
+import java.net.SocketAddress
+import java.nio.file.Files
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
+
+class VmLauncherService : Service() {
+    // TODO: using lateinit for some fields to avoid null
+    private var mExecutorService: ExecutorService? = null
+    private var mVirtualMachine: VirtualMachine? = null
+    private var mResultReceiver: ResultReceiver? = null
+    private var mServer: Server? = null
+    private var mDebianService: DebianServiceImpl? = null
+    private var mPortNotifier: PortNotifier? = null
+
+    interface VmLauncherServiceCallback {
+        fun onVmStart()
+
+        fun onVmStop()
+
+        fun onVmError()
+    }
+
+    override fun onBind(intent: Intent?): IBinder? {
+        return null
+    }
+
+    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
+        if (intent.action == ACTION_STOP_VM_LAUNCHER_SERVICE) {
+            if (mDebianService != null && mDebianService!!.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)
+            } else {
+                // If there is no Debian service or it fails to shutdown, just stop the service.
+                stopSelf()
+            }
+            return START_NOT_STICKY
+        }
+        if (mVirtualMachine != null) {
+            Log.d(TAG, "VM instance is already started")
+            return START_NOT_STICKY
+        }
+        mExecutorService = Executors.newCachedThreadPool(TerminalThreadFactory(applicationContext))
+
+        val image = InstalledImage.getDefault(this)
+        val json = ConfigJson.from(this, image.configPath)
+        val configBuilder = json.toConfigBuilder(this)
+        val customImageConfigBuilder = json.toCustomImageConfigBuilder(this)
+        if (overrideConfigIfNecessary(customImageConfigBuilder)) {
+            configBuilder.setCustomImageConfig(customImageConfigBuilder.build())
+        }
+        val config = configBuilder.build()
+
+        Trace.beginSection("vmCreate")
+        val runner: Runner =
+            try {
+                create(this, config)
+            } catch (e: VirtualMachineException) {
+                throw RuntimeException("cannot create runner", e)
+            }
+        Trace.endSection()
+        Trace.beginAsyncSection("debianBoot", 0)
+
+        mVirtualMachine = runner.vm
+        mResultReceiver =
+            intent.getParcelableExtra<ResultReceiver?>(
+                Intent.EXTRA_RESULT_RECEIVER,
+                ResultReceiver::class.java,
+            )
+
+        runner.exitStatus.thenAcceptAsync { success: Boolean ->
+            mResultReceiver?.send(if (success) RESULT_STOP else RESULT_ERROR, null)
+            stopSelf()
+        }
+        val logPath = getFileStreamPath(mVirtualMachine!!.name + ".log").toPath()
+        Logger.setup(mVirtualMachine!!, logPath, mExecutorService!!)
+
+        val notification =
+            intent.getParcelableExtra<Notification?>(EXTRA_NOTIFICATION, Notification::class.java)
+
+        startForeground(this.hashCode(), notification)
+
+        mResultReceiver!!.send(RESULT_START, null)
+
+        mPortNotifier = PortNotifier(this)
+
+        // TODO: dedup this part
+        val nsdManager = getSystemService<NsdManager?>(NsdManager::class.java)
+        val info = NsdServiceInfo()
+        info.serviceType = "_http._tcp"
+        info.serviceName = "ttyd"
+        nsdManager.registerServiceInfoCallback(
+            info,
+            mExecutorService!!,
+            object : NsdManager.ServiceInfoCallback {
+                override fun onServiceInfoCallbackRegistrationFailed(errorCode: Int) {}
+
+                override fun onServiceInfoCallbackUnregistered() {}
+
+                override fun onServiceLost() {}
+
+                override fun onServiceUpdated(info: NsdServiceInfo) {
+                    nsdManager.unregisterServiceInfoCallback(this)
+                    Log.i(TAG, "Service found: $info")
+                    startDebianServer(info.hostAddresses[0].hostAddress)
+                }
+            },
+        )
+
+        return START_NOT_STICKY
+    }
+
+    private fun createNotificationForTerminalClose(): Notification {
+        val stopIntent = Intent()
+        stopIntent.setClass(this, VmLauncherService::class.java)
+        stopIntent.setAction(ACTION_STOP_VM_LAUNCHER_SERVICE)
+        val stopPendingIntent =
+            PendingIntent.getService(
+                this,
+                0,
+                stopIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
+            )
+        val icon = Icon.createWithResource(resources, R.drawable.ic_launcher_foreground)
+        val stopActionText: String? =
+            resources.getString(R.string.service_notification_force_quit_action)
+        val stopNotificationTitle: String? =
+            resources.getString(R.string.service_notification_close_title)
+        return Notification.Builder(this, this.packageName)
+            .setSmallIcon(R.drawable.ic_launcher_foreground)
+            .setContentTitle(stopNotificationTitle)
+            .setOngoing(true)
+            .setSilent(true)
+            .addAction(Notification.Action.Builder(icon, stopActionText, stopPendingIntent).build())
+            .build()
+    }
+
+    private fun overrideConfigIfNecessary(
+        builder: VirtualMachineCustomImageConfig.Builder
+    ): Boolean {
+        var changed = false
+        // TODO: check if ANGLE is enabled for the app.
+        if (Files.exists(ImageArchive.getSdcardPathForTesting().resolve("virglrenderer"))) {
+            builder.setGpuConfig(
+                VirtualMachineCustomImageConfig.GpuConfig.Builder()
+                    .setBackend("virglrenderer")
+                    .setRendererUseEgl(true)
+                    .setRendererUseGles(true)
+                    .setRendererUseGlx(false)
+                    .setRendererUseSurfaceless(true)
+                    .setRendererUseVulkan(false)
+                    .setContextTypes(arrayOf<String>("virgl2"))
+                    .build()
+            )
+            Toast.makeText(this, R.string.virgl_enabled, Toast.LENGTH_SHORT).show()
+            changed = true
+        }
+
+        val image = InstalledImage.getDefault(this)
+        if (image.hasBackup()) {
+            val backup = image.backupFile
+            builder.addDisk(VirtualMachineCustomImageConfig.Disk.RWDisk(backup.toString()))
+            changed = true
+        }
+        return changed
+    }
+
+    private fun startDebianServer(ipAddress: String?) {
+        val interceptor: ServerInterceptor =
+            object : ServerInterceptor {
+                override fun <ReqT, RespT> interceptCall(
+                    call: ServerCall<ReqT?, RespT?>,
+                    headers: Metadata?,
+                    next: ServerCallHandler<ReqT?, RespT?>,
+                ): ServerCall.Listener<ReqT?>? {
+                    val remoteAddr =
+                        call.attributes.get<SocketAddress?>(Grpc.TRANSPORT_ATTR_REMOTE_ADDR)
+                            as InetSocketAddress?
+
+                    if (remoteAddr?.address?.hostAddress == ipAddress) {
+                        // Allow the request only if it is from VM
+                        return next.startCall(call, headers)
+                    }
+                    Log.d(TAG, "blocked grpc request from $remoteAddr")
+                    call.close(Status.Code.PERMISSION_DENIED.toStatus(), Metadata())
+                    return object : ServerCall.Listener<ReqT?>() {}
+                }
+            }
+        try {
+            // TODO(b/372666638): gRPC for java doesn't support vsock for now.
+            val port = 0
+            mDebianService = DebianServiceImpl(this)
+            mServer =
+                OkHttpServerBuilder.forPort(port, InsecureServerCredentials.create())
+                    .intercept(interceptor)
+                    .addService(mDebianService)
+                    .build()
+                    .start()
+        } catch (e: IOException) {
+            Log.d(TAG, "grpc server error", e)
+            return
+        }
+
+        mExecutorService!!.execute(
+            Runnable {
+                // TODO(b/373533555): we can use mDNS for that.
+                val debianServicePortFile = File(filesDir, "debian_service_port")
+                try {
+                    FileOutputStream(debianServicePortFile).use { writer ->
+                        writer.write(mServer!!.port.toString().toByteArray())
+                    }
+                } catch (e: IOException) {
+                    Log.d(TAG, "cannot write grpc port number", e)
+                }
+            }
+        )
+    }
+
+    override fun onDestroy() {
+        mPortNotifier?.stop()
+        getSystemService<NotificationManager?>(NotificationManager::class.java).cancelAll()
+        stopDebianServer()
+        if (mVirtualMachine != null) {
+            if (mVirtualMachine!!.getStatus() == VirtualMachine.STATUS_RUNNING) {
+                try {
+                    mVirtualMachine!!.stop()
+                    stopForeground(STOP_FOREGROUND_REMOVE)
+                } catch (e: VirtualMachineException) {
+                    Log.e(TAG, "failed to stop a VM instance", e)
+                }
+            }
+            mExecutorService?.shutdownNow()
+            mExecutorService = null
+            mVirtualMachine = null
+        }
+        super.onDestroy()
+    }
+
+    private fun stopDebianServer() {
+        mDebianService?.killForwarderHost()
+        mServer?.shutdown()
+    }
+
+    companion object {
+        private const val EXTRA_NOTIFICATION = "EXTRA_NOTIFICATION"
+        private const val ACTION_START_VM_LAUNCHER_SERVICE =
+            "android.virtualization.START_VM_LAUNCHER_SERVICE"
+
+        const val ACTION_STOP_VM_LAUNCHER_SERVICE: String =
+            "android.virtualization.STOP_VM_LAUNCHER_SERVICE"
+
+        private const val RESULT_START = 0
+        private const val RESULT_STOP = 1
+        private const val RESULT_ERROR = 2
+
+        private fun getMyIntent(context: Context): Intent {
+            return Intent(context.getApplicationContext(), VmLauncherService::class.java)
+        }
+
+        @JvmStatic
+        fun run(
+            context: Context,
+            callback: VmLauncherServiceCallback?,
+            notification: Notification?,
+        ) {
+            val i = getMyIntent(context)
+            val resultReceiver: ResultReceiver =
+                object : ResultReceiver(Handler(Looper.myLooper()!!)) {
+                    override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
+                        if (callback == null) {
+                            return
+                        }
+                        when (resultCode) {
+                            RESULT_START -> callback.onVmStart()
+                            RESULT_STOP -> callback.onVmStop()
+                            RESULT_ERROR -> callback.onVmError()
+                        }
+                    }
+                }
+            i.putExtra(Intent.EXTRA_RESULT_RECEIVER, getResultReceiverForIntent(resultReceiver))
+            i.putExtra(EXTRA_NOTIFICATION, notification)
+            context.startForegroundService(i)
+        }
+
+        private fun getResultReceiverForIntent(r: ResultReceiver): ResultReceiver {
+            val parcel = Parcel.obtain()
+            r.writeToParcel(parcel, 0)
+            parcel.setDataPosition(0)
+            return ResultReceiver.CREATOR.createFromParcel(parcel).also { parcel.recycle() }
+        }
+
+        @JvmStatic
+        fun stop(context: Context) {
+            val i = getMyIntent(context)
+            i.setAction(ACTION_STOP_VM_LAUNCHER_SERVICE)
+            context.startService(i)
+        }
+    }
+}
