Merge changes I35375ad2,I0fe5cd43 into main

* changes:
  Add test to verify page size of Microdroid VM
  Reland Add microdroid_16k
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt
index 7119225..a1509ad 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt
@@ -19,6 +19,7 @@
 import android.app.Notification
 import android.app.NotificationManager
 import android.app.PendingIntent
+import android.content.Context
 import android.content.Intent
 import android.content.pm.PackageManager
 import android.graphics.drawable.Icon
@@ -34,14 +35,29 @@
         super.onCreate(savedInstanceState)
         setContentView(R.layout.settings_port_forwarding)
 
-        val settingsPortForwardingItems = arrayOf(
-            SettingsPortForwardingItem(8080, true),
-            SettingsPortForwardingItem(443, false),
-            SettingsPortForwardingItem(80, false)
+        val settingsPortForwardingItems = ArrayList<SettingsPortForwardingItem>()
+
+        val sharedPref = this.getSharedPreferences(
+            getString(R.string.preference_file_key), Context.MODE_PRIVATE
         )
 
+        val ports =
+            sharedPref.getStringSet(
+                getString(R.string.preference_forwarding_ports),
+                HashSet<String>()
+            )
+
+        for (port in ports!!) {
+            val enabled =
+                sharedPref.getBoolean(
+                    getString(R.string.preference_forwarding_port_is_enabled) + port,
+                    false
+                )
+            settingsPortForwardingItems.add(SettingsPortForwardingItem(port.toInt(), enabled));
+        }
+
         val settingsPortForwardingAdapter =
-            SettingsPortForwardingAdapter(settingsPortForwardingItems)
+            SettingsPortForwardingAdapter(settingsPortForwardingItems, this)
 
         val recyclerView: RecyclerView = findViewById(R.id.settings_port_forwarding_recycler_view)
         recyclerView.layoutManager = LinearLayoutManager(this)
@@ -59,7 +75,12 @@
                 .setChannelId(TAG)
                 .setSmallIcon(R.drawable.ic_launcher_foreground)
                 .setContentTitle(resources.getString(R.string.settings_port_forwarding_notification_title))
-                .setContentText(resources.getString(R.string.settings_port_forwarding_notification_content, settingsPortForwardingItems[0].port))
+                .setContentText(
+                    resources.getString(
+                        R.string.settings_port_forwarding_notification_content,
+                        8080
+                    )
+                )
                 .addAction(
                     Notification.Action.Builder(
                         Icon.createWithResource(resources, R.drawable.ic_launcher_foreground),
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingAdapter.kt b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingAdapter.kt
index 1fa38e3..904f7f6 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingAdapter.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingAdapter.kt
@@ -15,6 +15,8 @@
  */
 package com.android.virtualization.terminal
 
+import android.content.Context
+import android.content.SharedPreferences
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -22,7 +24,10 @@
 import androidx.recyclerview.widget.RecyclerView
 import com.google.android.material.materialswitch.MaterialSwitch
 
-class SettingsPortForwardingAdapter(private val dataSet: Array<SettingsPortForwardingItem>) :
+class SettingsPortForwardingAdapter(
+    private val dataSet: ArrayList<SettingsPortForwardingItem>,
+    private val context: Context
+) :
     RecyclerView.Adapter<SettingsPortForwardingAdapter.ViewHolder>() {
 
     class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
@@ -40,6 +45,17 @@
     override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
         viewHolder.port.text = dataSet[position].port.toString()
         viewHolder.enabledSwitch.isChecked = dataSet[position].enabled
+        viewHolder.enabledSwitch.setOnCheckedChangeListener { _, isChecked ->
+            val sharedPref: SharedPreferences = context.getSharedPreferences(
+                context.getString(R.string.preference_file_key), Context.MODE_PRIVATE
+            )
+            val editor = sharedPref.edit()
+            editor.putBoolean(
+                context.getString(R.string.preference_forwarding_port_is_enabled) + viewHolder.port.text,
+                isChecked
+            )
+            editor.apply()
+        }
     }
 
     override fun getItemCount() = dataSet.size
diff --git a/android/TerminalApp/res/values/config.xml b/android/TerminalApp/res/values/config.xml
index 055abb7..9d2456c 100644
--- a/android/TerminalApp/res/values/config.xml
+++ b/android/TerminalApp/res/values/config.xml
@@ -18,4 +18,6 @@
     <string name="preference_file_key" translatable="false">com.android.virtualization.terminal.PREFERENCE_FILE_KEY</string>
     <string name="preference_disk_size_key" translatable="false">PREFERENCE_DISK_SIZE_KEY</string>
     <string name="preference_min_disk_size_key" translatable="false">PREFERENCE_MIN_DISK_SIZE_KEY</string>
+    <string name="preference_forwarding_ports" translatable="false">PREFERENCE_FORWARDING_PORTS</string>
+    <string name="preference_forwarding_port_is_enabled" translatable="false">PREFERENCE_FORWARDING_PORT_IS_ENABLED_</string>
 </resources>
\ No newline at end of file
diff --git a/tests/Terminal/Android.bp b/tests/Terminal/Android.bp
index 745a47c..2a52068 100644
--- a/tests/Terminal/Android.bp
+++ b/tests/Terminal/Android.bp
@@ -15,6 +15,7 @@
         "androidx.test.core",
         "androidx.test.ext.junit",
         "junit",
+        "MicrodroidTestHelper",
     ],
     platform_apis: true,
     test_suites: ["device-tests"],
diff --git a/tests/Terminal/src/com/android/virtualization/terminal/TerminalAppTest.java b/tests/Terminal/src/com/android/virtualization/terminal/TerminalAppTest.java
index 64ef79f..6400438 100644
--- a/tests/Terminal/src/com/android/virtualization/terminal/TerminalAppTest.java
+++ b/tests/Terminal/src/com/android/virtualization/terminal/TerminalAppTest.java
@@ -21,10 +21,12 @@
 import android.app.Instrumentation;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Bundle;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.microdroid.test.common.MetricsProcessor;
 import com.android.virtualization.vmlauncher.InstallUtils;
 
 import org.junit.After;
@@ -32,10 +34,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
 @RunWith(AndroidJUnit4.class)
 public class TerminalAppTest {
     private Instrumentation mInstr;
     private Context mTargetContext;
+    private final MetricsProcessor mMetricsProc = new MetricsProcessor("avf_perf/terminal/");
 
     @Before
     public void setup() {
@@ -65,9 +72,21 @@
         Intent intent = new Intent(mTargetContext, MainActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
+        long start = System.currentTimeMillis();
         if (mInstr.startActivitySync(intent) instanceof MainActivity activity) {
             assertTrue("Failed to boot in 30s", activity.waitForBootCompleted(BOOT_TIMEOUT_MILLIS));
         }
+        long delay = System.currentTimeMillis() - start;
+
+        // TODO: measure multiple times?
+        List<Long> measurements = new ArrayList<>();
+        measurements.add(delay);
+        Map<String, Double> stats = mMetricsProc.computeStats(measurements, "boot", "ms");
+        Bundle bundle = new Bundle();
+        for (Map.Entry<String, Double> entry : stats.entrySet()) {
+            bundle.putDouble(entry.getKey(), entry.getValue());
+        }
+        mInstr.sendStatus(0, bundle);
     }
 
     @After