diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.java b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.java
deleted file mode 100644
index 0ffc093..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.java
+++ /dev/null
@@ -1,313 +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.content.Context;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.view.View.AccessibilityDelegate;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import android.view.accessibility.AccessibilityNodeProvider;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.webkit.WebView;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-
-public class TerminalView extends WebView
-        implements AccessibilityStateChangeListener, TouchExplorationStateChangeListener {
-    // Maximum length of texts the talk back announcements can be. This value is somewhat
-    // arbitrarily set. We may want to adjust this in the future.
-    private static final int TEXT_TOO_LONG_TO_ANNOUNCE = 200;
-
-    private final String CTRL_KEY_HANDLER;
-    private final String ENABLE_CTRL_KEY;
-    private final String TOUCH_TO_MOUSE_HANDLER;
-
-    private final AccessibilityManager mA11yManager;
-
-    public TerminalView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        mA11yManager = context.getSystemService(AccessibilityManager.class);
-        mA11yManager.addTouchExplorationStateChangeListener(this);
-        mA11yManager.addAccessibilityStateChangeListener(this);
-        adjustToA11yStateChange();
-        try {
-            CTRL_KEY_HANDLER = readAssetAsString(context, "js/ctrl_key_handler.js");
-            ENABLE_CTRL_KEY = readAssetAsString(context, "js/enable_ctrl_key.js");
-            TOUCH_TO_MOUSE_HANDLER = readAssetAsString(context, "js/touch_to_mouse_handler.js");
-        } catch (IOException e) {
-            // It cannot happen
-            throw new IllegalArgumentException("cannot read code from asset", e);
-        }
-    }
-
-    private String readAssetAsString(Context context, String filePath) throws IOException {
-        try (InputStream is = context.getAssets().open(filePath)) {
-            return new String(is.readAllBytes());
-        }
-    }
-
-    public void mapTouchToMouseEvent() {
-        this.evaluateJavascript(TOUCH_TO_MOUSE_HANDLER, null);
-    }
-
-    public void mapCtrlKey() {
-        this.evaluateJavascript(CTRL_KEY_HANDLER, null);
-    }
-
-    public void enableCtrlKey() {
-        this.evaluateJavascript(ENABLE_CTRL_KEY, null);
-    }
-
-    @Override
-    public void onAccessibilityStateChanged(boolean enabled) {
-        Log.d(TAG, "accessibility " + enabled);
-        adjustToA11yStateChange();
-    }
-
-    @Override
-    public void onTouchExplorationStateChanged(boolean enabled) {
-        Log.d(TAG, "touch exploration " + enabled);
-        adjustToA11yStateChange();
-    }
-
-    private void adjustToA11yStateChange() {
-        if (!mA11yManager.isEnabled()) {
-            setFocusable(true);
-            return;
-        }
-
-        // When accessibility is on, the webview itself doesn't have to be focusable. The (virtual)
-        // edittext will be focusable to accept inputs. However, the webview has to be focusable for
-        // an accessibility purpose so that users can read the contents in it or scroll the view.
-        setFocusable(false);
-        setFocusableInTouchMode(true);
-    }
-
-    // AccessibilityEvents for WebView are sent directly from WebContentsAccessibilityImpl to the
-    // parent of WebView, without going through WebView. So, there's no WebView methods we can
-    // override to intercept the event handling process. To work around this, we attach an
-    // AccessibilityDelegate to the parent view where the events are sent to. And to guarantee that
-    // the parent view exists, wait until the WebView is attached to the window by when the parent
-    // must exist.
-    private final AccessibilityDelegate mA11yEventFilter =
-            new AccessibilityDelegate() {
-                @Override
-                public boolean onRequestSendAccessibilityEvent(
-                        ViewGroup host, View child, AccessibilityEvent e) {
-                    // We filter only the a11y events from the WebView
-                    if (child != TerminalView.this) {
-                        return super.onRequestSendAccessibilityEvent(host, child, e);
-                    }
-                    final int eventType = e.getEventType();
-                    switch (e.getEventType()) {
-                            // Skip reading texts that are too long. Right now, ttyd emits entire
-                            // text on the terminal to the live region, which is very annoying to
-                            // screen reader users.
-                        case AccessibilityEvent.TYPE_ANNOUNCEMENT:
-                            CharSequence text = e.getText().get(0); // there always is a text
-                            if (text.length() >= TEXT_TOO_LONG_TO_ANNOUNCE) {
-                                Log.i(TAG, "Announcement skipped because it's too long: " + text);
-                                return false;
-                            }
-                            break;
-                    }
-                    return super.onRequestSendAccessibilityEvent(host, child, e);
-                }
-            };
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (mA11yManager.isEnabled()) {
-            View parent = (View) getParent();
-            parent.setAccessibilityDelegate(mA11yEventFilter);
-        }
-    }
-
-    private final AccessibilityNodeProvider mA11yNodeProvider =
-            new AccessibilityNodeProvider() {
-
-                /** Returns the original NodeProvider that WebView implements. */
-                private AccessibilityNodeProvider getParent() {
-                    return TerminalView.super.getAccessibilityNodeProvider();
-                }
-
-                /** Convenience method for reading a string resource. */
-                private String getString(int resId) {
-                    return TerminalView.this.getContext().getResources().getString(resId);
-                }
-
-                /** Checks if NodeInfo renders an empty line in the terminal. */
-                private boolean isEmptyLine(AccessibilityNodeInfo info) {
-                    final CharSequence text = info.getText();
-                    // Node with no text is not consiered a line. ttyd emits at least one character,
-                    // which usually is NBSP.
-                    if (text == null) {
-                        return false;
-                    }
-                    for (int i = 0; i < text.length(); i++) {
-                        char c = text.charAt(i);
-                        // Note: don't use Characters.isWhitespace as it doesn't recognize NBSP as a
-                        // whitespace.
-                        if (!TextUtils.isWhitespace(c)) {
-                            return false;
-                        }
-                    }
-                    return true;
-                }
-
-                @Override
-                public AccessibilityNodeInfo createAccessibilityNodeInfo(int id) {
-                    AccessibilityNodeInfo info = getParent().createAccessibilityNodeInfo(id);
-                    if (info == null) {
-                        return null;
-                    }
-
-                    final String className = info.getClassName().toString();
-
-                    // By default all views except the cursor is not click-able. Other views are
-                    // read-only. This ensures that user is not navigated to non-clickable elements
-                    // when using switches.
-                    if (!"android.widget.EditText".equals(className)) {
-                        info.removeAction(AccessibilityAction.ACTION_CLICK);
-                    }
-
-                    switch (className) {
-                        case "android.webkit.WebView":
-                            // There are two NodeInfo objects of class name WebView. The one is the
-                            // real WebView whose ID is View.NO_ID as it's at the root of the
-                            // virtual view hierarchy. The second one is a virtual view for the
-                            // iframe. The latter one's text is set to the command that we give to
-                            // ttyd, which is "login -f droid ...". This is an impl detail which
-                            // doesn't have to be announced.  Replace the text with "Terminal
-                            // display".
-                            if (id != View.NO_ID) {
-                                info.setText(null);
-                                info.setContentDescription(getString(R.string.terminal_display));
-                                // b/376827536
-                                info.setHintText(getString(R.string.double_tap_to_edit_text));
-                            }
-
-                            // These two lines below are to prevent this WebView element from being
-                            // fousable by the screen reader, while allowing any other element in
-                            // the WebView to be focusable by the reader. In our case, the EditText
-                            // is a117_focusable.
-                            info.setScreenReaderFocusable(false);
-                            info.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
-                            break;
-                        case "android.view.View":
-                            // Empty line was announced as "space" (via the NBSP character).
-                            // Localize the spoken text.
-                            if (isEmptyLine(info)) {
-                                info.setContentDescription(getString(R.string.empty_line));
-                                // b/376827536
-                                info.setHintText(getString(R.string.double_tap_to_edit_text));
-                            }
-                            break;
-                        case "android.widget.TextView":
-                            // There are several TextViews in the terminal, and one of them is an
-                            // invisible TextView which seems to be from the <div
-                            // class="live-region"> tag. Interestingly, its text is often populated
-                            // with the entire text on the screen. Silence this by forcibly setting
-                            // the text to null. Note that this TextView is identified by having a
-                            // zero width. This certainly is not elegant, but I couldn't find other
-                            // options.
-                            Rect rect = new Rect();
-                            info.getBoundsInScreen(rect);
-                            if (rect.width() == 0) {
-                                info.setText(null);
-                                info.setContentDescription(getString(R.string.empty_line));
-                            }
-                            info.setScreenReaderFocusable(false);
-                            break;
-                        case "android.widget.EditText":
-                            // This EditText is for the <textarea> accepting user input; the cursor.
-                            // ttyd name it as "Terminal input" but it's not i18n'ed. Override it
-                            // here for better i18n.
-                            info.setText(null);
-                            info.setHintText(getString(R.string.double_tap_to_edit_text));
-                            info.setContentDescription(getString(R.string.terminal_input));
-                            info.setScreenReaderFocusable(true);
-                            info.addAction(AccessibilityAction.ACTION_FOCUS);
-                            break;
-                    }
-                    return info;
-                }
-
-                @Override
-                public boolean performAction(int id, int action, Bundle arguments) {
-                    return getParent().performAction(id, action, arguments);
-                }
-
-                @Override
-                public void addExtraDataToAccessibilityNodeInfo(
-                        int virtualViewId,
-                        AccessibilityNodeInfo info,
-                        String extraDataKey,
-                        Bundle arguments) {
-                    getParent()
-                            .addExtraDataToAccessibilityNodeInfo(
-                                    virtualViewId, info, extraDataKey, arguments);
-                }
-
-                @Override
-                public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(
-                        String text, int virtualViewId) {
-                    return getParent().findAccessibilityNodeInfosByText(text, virtualViewId);
-                }
-
-                @Override
-                public AccessibilityNodeInfo findFocus(int focus) {
-                    return getParent().findFocus(focus);
-                }
-            };
-
-    @Override
-    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
-        AccessibilityNodeProvider p = super.getAccessibilityNodeProvider();
-        if (p != null && mA11yManager.isEnabled()) {
-            return mA11yNodeProvider;
-        }
-        return p;
-    }
-
-    @Override
-    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
-        InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
-        if (outAttrs != null) {
-            outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
-        }
-        return inputConnection;
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.kt b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.kt
new file mode 100644
index 0000000..18a39fa
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.kt
@@ -0,0 +1,283 @@
+/*
+ * 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.content.Context
+import android.graphics.Rect
+import android.os.Bundle
+import android.text.InputType
+import android.text.TextUtils
+import android.util.AttributeSet
+import android.util.Log
+import android.view.View
+import android.view.ViewGroup
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityManager
+import android.view.accessibility.AccessibilityNodeInfo
+import android.view.accessibility.AccessibilityNodeProvider
+import android.view.inputmethod.EditorInfo
+import android.view.inputmethod.InputConnection
+import android.webkit.WebView
+import com.android.virtualization.terminal.MainActivity.TAG
+import java.io.IOException
+
+class TerminalView(context: Context, attrs: AttributeSet?) :
+    WebView(context, attrs),
+    AccessibilityManager.AccessibilityStateChangeListener,
+    AccessibilityManager.TouchExplorationStateChangeListener {
+    private val ctrlKeyHandler: String = readAssetAsString(context, "js/ctrl_key_handler.js")
+    private val enableCtrlKey: String = readAssetAsString(context, "js/enable_ctrl_key.js")
+    private val touchToMouseHandler: String =
+        readAssetAsString(context, "js/touch_to_mouse_handler.js")
+    private val a11yManager =
+        context.getSystemService<AccessibilityManager>(AccessibilityManager::class.java).also {
+            it.addTouchExplorationStateChangeListener(this)
+            it.addAccessibilityStateChangeListener(this)
+        }
+
+    @Throws(IOException::class)
+    private fun readAssetAsString(context: Context, filePath: String): String {
+        return String(context.assets.open(filePath).readAllBytes())
+    }
+
+    fun mapTouchToMouseEvent() {
+        this.evaluateJavascript(touchToMouseHandler, null)
+    }
+
+    fun mapCtrlKey() {
+        this.evaluateJavascript(ctrlKeyHandler, null)
+    }
+
+    fun enableCtrlKey() {
+        this.evaluateJavascript(enableCtrlKey, null)
+    }
+
+    override fun onAccessibilityStateChanged(enabled: Boolean) {
+        Log.d(TAG, "accessibility $enabled")
+        adjustToA11yStateChange()
+    }
+
+    override fun onTouchExplorationStateChanged(enabled: Boolean) {
+        Log.d(TAG, "touch exploration $enabled")
+        adjustToA11yStateChange()
+    }
+
+    private fun adjustToA11yStateChange() {
+        if (!a11yManager.isEnabled) {
+            setFocusable(true)
+            return
+        }
+
+        // When accessibility is on, the webview itself doesn't have to be focusable. The (virtual)
+        // edittext will be focusable to accept inputs. However, the webview has to be focusable for
+        // an accessibility purpose so that users can read the contents in it or scroll the view.
+        setFocusable(false)
+        setFocusableInTouchMode(true)
+    }
+
+    // AccessibilityEvents for WebView are sent directly from WebContentsAccessibilityImpl to the
+    // parent of WebView, without going through WebView. So, there's no WebView methods we can
+    // override to intercept the event handling process. To work around this, we attach an
+    // AccessibilityDelegate to the parent view where the events are sent to. And to guarantee that
+    // the parent view exists, wait until the WebView is attached to the window by when the parent
+    // must exist.
+    private val mA11yEventFilter: AccessibilityDelegate =
+        object : AccessibilityDelegate() {
+            override fun onRequestSendAccessibilityEvent(
+                host: ViewGroup,
+                child: View,
+                e: AccessibilityEvent,
+            ): Boolean {
+                // We filter only the a11y events from the WebView
+                if (child !== this@TerminalView) {
+                    return super.onRequestSendAccessibilityEvent(host, child, e)
+                }
+                when (e.eventType) {
+                    AccessibilityEvent.TYPE_ANNOUNCEMENT -> {
+                        val text = e.text[0] // there always is a text
+                        if (text.length >= TEXT_TOO_LONG_TO_ANNOUNCE) {
+                            Log.i(TAG, "Announcement skipped because it's too long: $text")
+                            return false
+                        }
+                    }
+                }
+                return super.onRequestSendAccessibilityEvent(host, child, e)
+            }
+        }
+
+    override fun onAttachedToWindow() {
+        super.onAttachedToWindow()
+        if (a11yManager.isEnabled) {
+            val parent = getParent() as View
+            parent.setAccessibilityDelegate(mA11yEventFilter)
+        }
+    }
+
+    private val mA11yNodeProvider: AccessibilityNodeProvider =
+        object : AccessibilityNodeProvider() {
+            /** Returns the original NodeProvider that WebView implements. */
+            private fun getParent(): AccessibilityNodeProvider? {
+                return super@TerminalView.getAccessibilityNodeProvider()
+            }
+
+            /** Convenience method for reading a string resource. */
+            private fun getString(resId: Int): String {
+                return this@TerminalView.context.getResources().getString(resId)
+            }
+
+            /** Checks if NodeInfo renders an empty line in the terminal. */
+            private fun isEmptyLine(info: AccessibilityNodeInfo): Boolean {
+                // Node with no text is not considered a line. ttyd emits at least one character,
+                // which usually is NBSP.
+                // Note: don't use Characters.isWhitespace as it doesn't recognize NBSP as a
+                // whitespace.
+                return (info.getText()?.all { TextUtils.isWhitespace(it.code) }) == true
+            }
+
+            override fun createAccessibilityNodeInfo(id: Int): AccessibilityNodeInfo? {
+                val info: AccessibilityNodeInfo? = getParent()?.createAccessibilityNodeInfo(id)
+                if (info == null) {
+                    return null
+                }
+
+                val className = info.className.toString()
+
+                // By default all views except the cursor is not click-able. Other views are
+                // read-only. This ensures that user is not navigated to non-clickable elements
+                // when using switches.
+                if ("android.widget.EditText" != className) {
+                    info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK)
+                }
+
+                when (className) {
+                    "android.webkit.WebView" -> {
+                        // There are two NodeInfo objects of class name WebView. The one is the
+                        // real WebView whose ID is View.NO_ID as it's at the root of the
+                        // virtual view hierarchy. The second one is a virtual view for the
+                        // iframe. The latter one's text is set to the command that we give to
+                        // ttyd, which is "login -f droid ...". This is an impl detail which
+                        // doesn't have to be announced.  Replace the text with "Terminal
+                        // display".
+                        if (id != NO_ID) {
+                            info.setText(null)
+                            info.setContentDescription(getString(R.string.terminal_display))
+                            // b/376827536
+                            info.setHintText(getString(R.string.double_tap_to_edit_text))
+                        }
+
+                        // These two lines below are to prevent this WebView element from being
+                        // focusable by the screen reader, while allowing any other element in
+                        // the WebView to be focusable by the reader. In our case, the EditText
+                        // is a117_focusable.
+                        info.isScreenReaderFocusable = false
+                        info.addAction(
+                            AccessibilityNodeInfo.AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS
+                        )
+                    }
+
+                    "android.view.View" ->
+                        // Empty line was announced as "space" (via the NBSP character).
+                        // Localize the spoken text.
+                        if (isEmptyLine(info)) {
+                            info.setContentDescription(getString(R.string.empty_line))
+                            // b/376827536
+                            info.setHintText(getString(R.string.double_tap_to_edit_text))
+                        }
+
+                    "android.widget.TextView" -> {
+                        // There are several TextViews in the terminal, and one of them is an
+                        // invisible TextView which seems to be from the <div
+                        // class="live-region"> tag. Interestingly, its text is often populated
+                        // with the entire text on the screen. Silence this by forcibly setting
+                        // the text to null. Note that this TextView is identified by having a
+                        // zero width. This certainly is not elegant, but I couldn't find other
+                        // options.
+                        val rect = Rect()
+                        info.getBoundsInScreen(rect)
+                        if (rect.width() == 0) {
+                            info.setText(null)
+                            info.setContentDescription(getString(R.string.empty_line))
+                        }
+                        info.isScreenReaderFocusable = false
+                    }
+
+                    "android.widget.EditText" -> {
+                        // This EditText is for the <textarea> accepting user input; the cursor.
+                        // ttyd name it as "Terminal input" but it's not i18n'ed. Override it
+                        // here for better i18n.
+                        info.setText(null)
+                        info.setHintText(getString(R.string.double_tap_to_edit_text))
+                        info.setContentDescription(getString(R.string.terminal_input))
+                        info.isScreenReaderFocusable = true
+                        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_FOCUS)
+                    }
+                }
+                return info
+            }
+
+            override fun performAction(id: Int, action: Int, arguments: Bundle?): Boolean {
+                return getParent()?.performAction(id, action, arguments) == true
+            }
+
+            override fun addExtraDataToAccessibilityNodeInfo(
+                virtualViewId: Int,
+                info: AccessibilityNodeInfo?,
+                extraDataKey: String?,
+                arguments: Bundle?,
+            ) {
+                getParent()
+                    ?.addExtraDataToAccessibilityNodeInfo(
+                        virtualViewId,
+                        info,
+                        extraDataKey,
+                        arguments,
+                    )
+            }
+
+            override fun findAccessibilityNodeInfosByText(
+                text: String?,
+                virtualViewId: Int,
+            ): MutableList<AccessibilityNodeInfo?>? {
+                return getParent()?.findAccessibilityNodeInfosByText(text, virtualViewId)
+            }
+
+            override fun findFocus(focus: Int): AccessibilityNodeInfo? {
+                return getParent()?.findFocus(focus)
+            }
+        }
+
+    override fun getAccessibilityNodeProvider(): AccessibilityNodeProvider? {
+        val p = super.getAccessibilityNodeProvider()
+        if (p != null && a11yManager.isEnabled) {
+            return mA11yNodeProvider
+        }
+        return p
+    }
+
+    override fun onCreateInputConnection(outAttrs: EditorInfo?): InputConnection? {
+        val inputConnection = super.onCreateInputConnection(outAttrs)
+        if (outAttrs != null) {
+            outAttrs.inputType = outAttrs.inputType or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
+        }
+        return inputConnection
+    }
+
+    companion object {
+        // Maximum length of texts the talk back announcements can be. This value is somewhat
+        // arbitrarily set. We may want to adjust this in the future.
+        private const val TEXT_TOO_LONG_TO_ANNOUNCE = 200
+    }
+}
