diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.java b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.java
deleted file mode 100644
index 0d70ab9..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.java
+++ /dev/null
@@ -1,146 +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.Notification.Action;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.drawable.Icon;
-
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-
-/**
- * PortNotifier is responsible for posting a notification when a new open port is detected. User can
- * enable or disable forwarding of the port in notification panel.
- */
-class PortNotifier {
-    private static final String ACTION_PORT_FORWARDING = "android.virtualization.PORT_FORWARDING";
-    private static final String KEY_PORT = "port";
-    private static final String KEY_ENABLED = "enabled";
-
-    private final Context mContext;
-    private final NotificationManager mNotificationManager;
-    private final BroadcastReceiver mReceiver;
-    private final PortsStateManager mPortsStateManager;
-    private final PortsStateManager.Listener mPortsStateListener;
-
-    public PortNotifier(Context context) {
-        mContext = context;
-        mNotificationManager = mContext.getSystemService(NotificationManager.class);
-        mReceiver = new PortForwardingRequestReceiver();
-
-        mPortsStateManager = PortsStateManager.getInstance(mContext);
-        mPortsStateListener =
-                new PortsStateManager.Listener() {
-                    @Override
-                    public void onPortsStateUpdated(
-                            Set<Integer> oldActivePorts, Set<Integer> newActivePorts) {
-                        Set<Integer> union = new HashSet<>(oldActivePorts);
-                        union.addAll(newActivePorts);
-                        for (int port : union) {
-                            if (!oldActivePorts.contains(port)) {
-                                showNotificationFor(port);
-                            } else if (!newActivePorts.contains(port)) {
-                                discardNotificationFor(port);
-                            }
-                        }
-                    }
-                };
-        mPortsStateManager.registerListener(mPortsStateListener);
-
-        IntentFilter intentFilter = new IntentFilter(ACTION_PORT_FORWARDING);
-        mContext.registerReceiver(mReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED);
-    }
-
-    public void stop() {
-        mPortsStateManager.unregisterListener(mPortsStateListener);
-        mContext.unregisterReceiver(mReceiver);
-    }
-
-    private String getString(int resId) {
-        return mContext.getString(resId);
-    }
-
-    private PendingIntent getPendingIntentFor(int port, boolean enabled) {
-        Intent intent = new Intent(ACTION_PORT_FORWARDING);
-        intent.setPackage(mContext.getPackageName());
-        intent.setIdentifier(String.format(Locale.ROOT, "%d_%b", port, enabled));
-        intent.putExtra(KEY_PORT, port);
-        intent.putExtra(KEY_ENABLED, enabled);
-        return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE);
-    }
-
-    private void showNotificationFor(int port) {
-        Intent tapIntent = new Intent(mContext, SettingsPortForwardingActivity.class);
-        tapIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        PendingIntent tapPendingIntent =
-                PendingIntent.getActivity(mContext, 0, tapIntent, PendingIntent.FLAG_IMMUTABLE);
-
-        String title = getString(R.string.settings_port_forwarding_notification_title);
-        String content =
-                mContext.getString(R.string.settings_port_forwarding_notification_content, port);
-        String acceptText = getString(R.string.settings_port_forwarding_notification_accept);
-        String denyText = getString(R.string.settings_port_forwarding_notification_deny);
-        Icon icon = Icon.createWithResource(mContext, R.drawable.ic_launcher_foreground);
-
-        Action acceptAction =
-                new Action.Builder(icon, acceptText, getPendingIntentFor(port, true /* enabled */))
-                        .build();
-        Action denyAction =
-                new Action.Builder(icon, denyText, getPendingIntentFor(port, false /* enabled */))
-                        .build();
-        Notification notification =
-                new Notification.Builder(mContext, mContext.getPackageName())
-                        .setSmallIcon(R.drawable.ic_launcher_foreground)
-                        .setContentTitle(title)
-                        .setContentText(content)
-                        .setContentIntent(tapPendingIntent)
-                        .addAction(acceptAction)
-                        .addAction(denyAction)
-                        .build();
-        mNotificationManager.notify(TAG, port, notification);
-    }
-
-    private void discardNotificationFor(int port) {
-        mNotificationManager.cancel(TAG, port);
-    }
-
-    private final class PortForwardingRequestReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (ACTION_PORT_FORWARDING.equals(intent.getAction())) {
-                performActionPortForwarding(context, intent);
-            }
-        }
-
-        private void performActionPortForwarding(Context context, Intent intent) {
-            int port = intent.getIntExtra(KEY_PORT, 0);
-            boolean enabled = intent.getBooleanExtra(KEY_ENABLED, false);
-            mPortsStateManager.updateEnabledPort(port, enabled);
-            discardNotificationFor(port);
-        }
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt
new file mode 100644
index 0000000..ed6e02e
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt
@@ -0,0 +1,139 @@
+/*
+ * 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.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.graphics.drawable.Icon
+import java.util.HashSet
+import java.util.Locale
+
+/**
+ * PortNotifier is responsible for posting a notification when a new open port is detected. User can
+ * enable or disable forwarding of the port in notification panel.
+ */
+internal class PortNotifier(val context: Context) {
+    private val notificationManager: NotificationManager =
+        context.getSystemService<NotificationManager?>(NotificationManager::class.java)
+    private val receiver: BroadcastReceiver =
+        PortForwardingRequestReceiver().also {
+            val intentFilter = IntentFilter(ACTION_PORT_FORWARDING)
+            context.registerReceiver(it, intentFilter, Context.RECEIVER_NOT_EXPORTED)
+        }
+    private val portsStateListener: PortsStateManager.Listener =
+        object : PortsStateManager.Listener {
+            override fun onPortsStateUpdated(oldActivePorts: Set<Int>, newActivePorts: Set<Int>) {
+                val union: MutableSet<Int> = HashSet<Int>(oldActivePorts)
+                union.addAll(newActivePorts)
+                for (port in union) {
+                    if (!oldActivePorts.contains(port)) {
+                        showNotificationFor(port)
+                    } else if (!newActivePorts.contains(port)) {
+                        discardNotificationFor(port)
+                    }
+                }
+            }
+        }
+    private val portsStateManager: PortsStateManager =
+        PortsStateManager.getInstance(context).also { it.registerListener(portsStateListener) }
+
+    fun stop() {
+        portsStateManager.unregisterListener(portsStateListener)
+        context.unregisterReceiver(receiver)
+    }
+
+    private fun getString(resId: Int): String {
+        return context.getString(resId)
+    }
+
+    private fun getPendingIntentFor(port: Int, enabled: Boolean): PendingIntent? {
+        val intent = Intent(ACTION_PORT_FORWARDING)
+        intent.setPackage(context.getPackageName())
+        intent.setIdentifier(String.format(Locale.ROOT, "%d_%b", port, enabled))
+        intent.putExtra(KEY_PORT, port)
+        intent.putExtra(KEY_ENABLED, enabled)
+        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+    }
+
+    private fun showNotificationFor(port: Int) {
+        val tapIntent = Intent(context, SettingsPortForwardingActivity::class.java)
+        tapIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
+        val tapPendingIntent =
+            PendingIntent.getActivity(context, 0, tapIntent, PendingIntent.FLAG_IMMUTABLE)
+
+        val title = getString(R.string.settings_port_forwarding_notification_title)
+        val content =
+            context.getString(R.string.settings_port_forwarding_notification_content, port)
+        val acceptText = getString(R.string.settings_port_forwarding_notification_accept)
+        val denyText = getString(R.string.settings_port_forwarding_notification_deny)
+        val icon = Icon.createWithResource(context, R.drawable.ic_launcher_foreground)
+
+        val acceptAction: Notification.Action =
+            Notification.Action.Builder(
+                    icon,
+                    acceptText,
+                    getPendingIntentFor(port, true /* enabled */),
+                )
+                .build()
+        val denyAction: Notification.Action =
+            Notification.Action.Builder(
+                    icon,
+                    denyText,
+                    getPendingIntentFor(port, false /* enabled */),
+                )
+                .build()
+        val notification: Notification =
+            Notification.Builder(context, context.getPackageName())
+                .setSmallIcon(R.drawable.ic_launcher_foreground)
+                .setContentTitle(title)
+                .setContentText(content)
+                .setContentIntent(tapPendingIntent)
+                .addAction(acceptAction)
+                .addAction(denyAction)
+                .build()
+        notificationManager.notify(MainActivity.TAG, port, notification)
+    }
+
+    private fun discardNotificationFor(port: Int) {
+        notificationManager.cancel(MainActivity.TAG, port)
+    }
+
+    private inner class PortForwardingRequestReceiver : BroadcastReceiver() {
+        override fun onReceive(context: Context?, intent: Intent) {
+            if (ACTION_PORT_FORWARDING == intent.action) {
+                performActionPortForwarding(intent)
+            }
+        }
+
+        fun performActionPortForwarding(intent: Intent) {
+            val port = intent.getIntExtra(KEY_PORT, 0)
+            val enabled = intent.getBooleanExtra(KEY_ENABLED, false)
+            portsStateManager.updateEnabledPort(port, enabled)
+            discardNotificationFor(port)
+        }
+    }
+
+    companion object {
+        private const val ACTION_PORT_FORWARDING = "android.virtualization.PORT_FORWARDING"
+        private const val KEY_PORT = "port"
+        private const val KEY_ENABLED = "enabled"
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.java b/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.java
deleted file mode 100644
index 5321d89..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.java
+++ /dev/null
@@ -1,158 +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 android.content.Context;
-import android.content.SharedPreferences;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * PortsStateManager is responsible for communicating with shared preferences and managing state of
- * ports.
- */
-public class PortsStateManager {
-    private static final String PREFS_NAME = ".PORTS";
-    private static final int FLAG_ENABLED = 1;
-
-    private static PortsStateManager mInstance;
-    private final Object mLock = new Object();
-
-    private final SharedPreferences mSharedPref;
-
-    @GuardedBy("mLock")
-    private Set<Integer> mActivePorts;
-
-    @GuardedBy("mLock")
-    private final Set<Integer> mEnabledPorts;
-
-    @GuardedBy("mLock")
-    private final Set<Listener> mListeners;
-
-    private PortsStateManager(SharedPreferences sharedPref) {
-        mSharedPref = sharedPref;
-        mEnabledPorts =
-                mSharedPref.getAll().entrySet().stream()
-                        .filter(entry -> entry.getValue() instanceof Integer)
-                        .filter(entry -> ((int) entry.getValue() & FLAG_ENABLED) == FLAG_ENABLED)
-                        .map(entry -> entry.getKey())
-                        .filter(
-                                key -> {
-                                    try {
-                                        Integer.parseInt(key);
-                                        return true;
-                                    } catch (NumberFormatException e) {
-                                        return false;
-                                    }
-                                })
-                        .map(Integer::parseInt)
-                        .collect(Collectors.toSet());
-        mActivePorts = new HashSet<>();
-        mListeners = new HashSet<>();
-    }
-
-    static synchronized PortsStateManager getInstance(Context context) {
-        if (mInstance == null) {
-            SharedPreferences sharedPref =
-                    context.getSharedPreferences(
-                            context.getPackageName() + PREFS_NAME, Context.MODE_PRIVATE);
-            mInstance = new PortsStateManager(sharedPref);
-        }
-        return mInstance;
-    }
-
-    Set<Integer> getActivePorts() {
-        synchronized (mLock) {
-            return new HashSet<>(mActivePorts);
-        }
-    }
-
-    Set<Integer> getEnabledPorts() {
-        synchronized (mLock) {
-            return new HashSet<>(mEnabledPorts);
-        }
-    }
-
-    void updateActivePorts(Set<Integer> ports) {
-        Set<Integer> oldPorts;
-        synchronized (mLock) {
-            oldPorts = mActivePorts;
-            mActivePorts = ports;
-        }
-        notifyPortsStateUpdated(oldPorts, ports);
-    }
-
-    void updateEnabledPort(int port, boolean enabled) {
-        Set<Integer> activePorts;
-        synchronized (mLock) {
-            SharedPreferences.Editor editor = mSharedPref.edit();
-            editor.putInt(String.valueOf(port), enabled ? FLAG_ENABLED : 0);
-            editor.apply();
-            if (enabled) {
-                mEnabledPorts.add(port);
-            } else {
-                mEnabledPorts.remove(port);
-            }
-            activePorts = mActivePorts;
-        }
-        notifyPortsStateUpdated(activePorts, activePorts);
-    }
-
-    void clearEnabledPorts() {
-        Set<Integer> activePorts;
-        synchronized (mLock) {
-            SharedPreferences.Editor editor = mSharedPref.edit();
-            editor.clear();
-            editor.apply();
-            mEnabledPorts.clear();
-            activePorts = mActivePorts;
-        }
-        notifyPortsStateUpdated(activePorts, activePorts);
-    }
-
-    void registerListener(Listener listener) {
-        synchronized (mLock) {
-            mListeners.add(listener);
-        }
-    }
-
-    void unregisterListener(Listener listener) {
-        synchronized (mLock) {
-            mListeners.remove(listener);
-        }
-    }
-
-    private void notifyPortsStateUpdated(Set<Integer> oldActivePorts, Set<Integer> newActivePorts) {
-        Set<Listener> listeners;
-        synchronized (mLock) {
-            listeners = new HashSet<>(mListeners);
-        }
-        for (Listener listener : listeners) {
-            listener.onPortsStateUpdated(
-                    new HashSet<>(oldActivePorts), new HashSet<>(newActivePorts));
-        }
-    }
-
-    interface Listener {
-        default void onPortsStateUpdated(
-                Set<Integer> oldActivePorts, Set<Integer> newActivePorts) {}
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.kt b/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.kt
new file mode 100644
index 0000000..736176a
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.kt
@@ -0,0 +1,137 @@
+/*
+ * 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.content.SharedPreferences
+import com.android.internal.annotations.GuardedBy
+import java.util.HashSet
+
+/**
+ * PortsStateManager is responsible for communicating with shared preferences and managing state of
+ * ports.
+ */
+class PortsStateManager private constructor(private val sharedPref: SharedPreferences) {
+    private val lock = Any()
+
+    @GuardedBy("lock") private var activePorts: MutableSet<Int> = hashSetOf()
+
+    @GuardedBy("lock")
+    private val enabledPorts: MutableSet<Int> =
+        sharedPref
+            .getAll()
+            .entries
+            .filterIsInstance<MutableMap.MutableEntry<String, Int>>()
+            .filter { it.value and FLAG_ENABLED == FLAG_ENABLED }
+            .map { it.key.toIntOrNull() }
+            .filterNotNull()
+            .toMutableSet()
+
+    @GuardedBy("lock") private val listeners: MutableSet<Listener> = hashSetOf()
+
+    fun getActivePorts(): MutableSet<Int> {
+        synchronized(lock) {
+            return HashSet<Int>(activePorts)
+        }
+    }
+
+    fun getEnabledPorts(): MutableSet<Int> {
+        synchronized(lock) {
+            return HashSet<Int>(enabledPorts)
+        }
+    }
+
+    fun updateActivePorts(ports: MutableSet<Int>) {
+        var oldPorts: MutableSet<Int>
+        synchronized(lock) {
+            oldPorts = activePorts
+            activePorts = ports
+        }
+        notifyPortsStateUpdated(oldPorts, ports)
+    }
+
+    fun updateEnabledPort(port: Int, enabled: Boolean) {
+        var activePorts: MutableSet<Int>
+        synchronized(lock) {
+            val editor = sharedPref.edit()
+            editor.putInt(port.toString(), if (enabled) FLAG_ENABLED else 0)
+            editor.apply()
+            if (enabled) {
+                enabledPorts.add(port)
+            } else {
+                enabledPorts.remove(port)
+            }
+            activePorts = this@PortsStateManager.activePorts
+        }
+        notifyPortsStateUpdated(activePorts, activePorts)
+    }
+
+    fun clearEnabledPorts() {
+        var activePorts: MutableSet<Int>
+        synchronized(lock) {
+            val editor = sharedPref.edit()
+            editor.clear()
+            editor.apply()
+            enabledPorts.clear()
+            activePorts = this@PortsStateManager.activePorts
+        }
+        notifyPortsStateUpdated(activePorts, activePorts)
+    }
+
+    fun registerListener(listener: Listener) {
+        synchronized(lock) { listeners.add(listener) }
+    }
+
+    fun unregisterListener(listener: Listener) {
+        synchronized(lock) { listeners.remove(listener) }
+    }
+
+    private fun notifyPortsStateUpdated(
+        oldActivePorts: MutableSet<Int>,
+        newActivePorts: MutableSet<Int>,
+    ) {
+        var listeners: MutableSet<Listener>
+        synchronized(lock) { listeners = HashSet<Listener>(this@PortsStateManager.listeners) }
+        for (listener in listeners) {
+            listener.onPortsStateUpdated(HashSet<Int>(oldActivePorts), HashSet<Int>(newActivePorts))
+        }
+    }
+
+    interface Listener {
+        fun onPortsStateUpdated(oldActivePorts: Set<Int>, newActivePorts: Set<Int>) {}
+    }
+
+    companion object {
+        private const val PREFS_NAME = ".PORTS"
+        private const val FLAG_ENABLED = 1
+
+        private var instance: PortsStateManager? = null
+
+        @JvmStatic
+        @Synchronized
+        fun getInstance(context: Context): PortsStateManager {
+            if (instance == null) {
+                val sharedPref =
+                    context.getSharedPreferences(
+                        context.getPackageName() + PREFS_NAME,
+                        Context.MODE_PRIVATE,
+                    )
+                instance = PortsStateManager(sharedPref)
+            }
+            return instance!!
+        }
+    }
+}
