Merge "[dice] Move open-dice Rust wrapper tests to presubmit" into main
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
index 1abba85..83c6b4c 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
@@ -29,11 +29,13 @@
 import android.os.RemoteException;
 import android.text.format.Formatter;
 import android.util.Log;
+import android.view.KeyEvent;
 import android.view.View;
 import android.widget.CheckBox;
 import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.virtualization.vmlauncher.InstallUtils;
 
 import com.google.android.material.progressindicator.LinearProgressIndicator;
 import com.google.android.material.snackbar.Snackbar;
@@ -45,7 +47,6 @@
     private static final String TAG = "LinuxInstaller";
 
     private static final long ESTIMATED_IMG_SIZE_BYTES = FileUtils.parseSize("350MB");
-    static final String EXTRA_AUTO_DOWNLOAD = "auto_download";
 
     private ExecutorService mExecutorService;
     private CheckBox mWaitForWifiCheckbox;
@@ -80,17 +81,25 @@
                     requestInstall();
                 });
 
-        if (getIntent().getBooleanExtra(EXTRA_AUTO_DOWNLOAD, false)) {
-            Log.i(TAG, "Auto downloading");
-            requestInstall();
-        }
-
         Intent intent = new Intent(this, InstallerService.class);
         mInstallerServiceConnection = new InstallerServiceConnection(this);
         if (!bindService(intent, mInstallerServiceConnection, Context.BIND_AUTO_CREATE)) {
             handleCriticalError(new Exception("Failed to connect to installer service"));
         }
+    }
 
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        if (Build.isDebuggable() && InstallUtils.payloadFromExternalStorageExists()) {
+            Snackbar.make(
+                            findViewById(android.R.id.content),
+                            "Auto installing",
+                            Snackbar.LENGTH_LONG)
+                    .show();
+            requestInstall();
+        }
     }
 
     @Override
@@ -103,6 +112,15 @@
         super.onDestroy();
     }
 
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BUTTON_START) {
+            requestInstall();
+            return true;
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+
     @VisibleForTesting
     public boolean waitForInstallCompleted(long timeoutMillis) {
         return mInstallCompleted.block(timeoutMillis);
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java
index b785416..f97f16f 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java
@@ -17,8 +17,6 @@
 package com.android.virtualization.terminal;
 
 import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Intent;
@@ -122,16 +120,21 @@
     }
 
     private void requestInstall() {
-        Log.i(TAG, "Installing..");
+        synchronized (mLock) {
+            if (mIsInstalling) {
+                Log.i(TAG, "already installing..");
+                return;
+            } else {
+                Log.i(TAG, "installing..");
+                mIsInstalling = true;
+            }
+        }
 
         // Make service to be long running, even after unbind() when InstallerActivity is destroyed
         // The service will still be destroyed if task is remove.
         startService(new Intent(this, InstallerService.class));
         startForeground(
                 NOTIFICATION_ID, mNotification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
-        synchronized (mLock) {
-            mIsInstalling = true;
-        }
 
         mExecutorService.execute(
                 () -> {
diff --git a/android/TerminalApp/res/layout/settings_disk_resize.xml b/android/TerminalApp/res/layout/settings_disk_resize.xml
index 6c8c2c1..d80f4f9 100644
--- a/android/TerminalApp/res/layout/settings_disk_resize.xml
+++ b/android/TerminalApp/res/layout/settings_disk_resize.xml
@@ -64,9 +64,11 @@
             android:id="@+id/settings_disk_resize_cancel_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:maxWidth="150sp"
+            android:hyphenationFrequency="normal"
             android:text="@string/settings_disk_resize_resize_cancel"
             android:visibility="invisible"
-            android:layout_marginVertical="48dp"
+            android:layout_marginTop="48dp"
             android:layout_marginHorizontal="8dp"
             app:layout_constraintTop_toTopOf="@+id/settings_disk_resize_disk_size_slider"
             app:layout_constraintBottom_toBottomOf="parent"
@@ -76,10 +78,13 @@
             android:id="@+id/settings_disk_resize_resize_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:maxWidth="150sp"
+            android:hyphenationFrequency="normal"
             android:text="@string/settings_disk_resize_resize_restart_vm_to_apply"
             android:visibility="invisible"
+            android:layout_marginTop="48dp"
             app:layout_constraintTop_toTopOf="@+id/settings_disk_resize_disk_size_slider"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toEndOf="parent" />
     </androidx.constraintlayout.widget.ConstraintLayout>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/android/TerminalApp/res/values/strings.xml b/android/TerminalApp/res/values/strings.xml
index 3448388..c89fcfa 100644
--- a/android/TerminalApp/res/values/strings.xml
+++ b/android/TerminalApp/res/values/strings.xml
@@ -61,10 +61,10 @@
     <string name="settings_disk_resize_resize_gb_assigned_format"><xliff:g id="assigned_size" example="10GB">%1$s</xliff:g> assigned</string>
     <!-- Settings menu option description format of the maximum resizable disk size. [CHAR LIMIT=none] -->
     <string name="settings_disk_resize_resize_gb_max_format"><xliff:g id="max_size" example="256GB">%1$s</xliff:g> max</string>
-    <!-- Settings menu button to cancel disk resize. [CHAR LIMIT=32] -->
+    <!-- Settings menu button to cancel disk resize. [CHAR LIMIT=16] -->
     <string name="settings_disk_resize_resize_cancel">Cancel</string>
-    <!-- Settings menu button to apply change that requires to restart VM (abbrev of virtual machine). [CHAR LIMIT=64] -->
-    <string name="settings_disk_resize_resize_restart_vm_to_apply">Restart VM to apply</string>
+    <!-- Settings menu button to apply change that requires to restart Terminal app. [CHAR LIMIT=20] -->
+    <string name="settings_disk_resize_resize_restart_vm_to_apply">Restart to apply</string>
 
     <!-- Settings menu title for 'port forwarding' [CHAR LIMIT=none] -->
     <string name="settings_port_forwarding_title">Port Forwarding</string>
@@ -96,12 +96,12 @@
     <!-- Dialog button cancel for resetting the terminal [CHAR LIMIT=16] -->
     <string name="settings_recovery_reset_dialog_cancel">Cancel</string>
 
-    <!-- Notification action button for settings [CHAR LIMIT=none] -->
+    <!-- Notification action button for settings [CHAR LIMIT=20] -->
     <string name="service_notification_settings">Settings</string>
     <!-- Notification title for foreground service notification [CHAR LIMIT=none] -->
     <string name="service_notification_title">Terminal is running</string>
     <!-- Notification content for foreground service notification [CHAR LIMIT=none] -->
     <string name="service_notification_content">Click to open the terminal</string>
-    <!-- Notification action button for closing the virtual machine [CHAR LIMIT=none] -->
+    <!-- Notification action button for closing the virtual machine [CHAR LIMIT=20] -->
     <string name="service_notification_quit_action">Close</string>
 </resources>
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 4538248..1cae344 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -567,9 +567,11 @@
         let config = config.as_ref();
         *is_protected = config.protectedVm;
 
-        check_tee_service_permission(&caller_secontext, &config.teeServices)
-            .with_log()
-            .or_binder_exception(ExceptionCode::SECURITY)?;
+        if !config.teeServices.is_empty() {
+            check_tee_service_permission(&caller_secontext, &config.teeServices)
+                .with_log()
+                .or_binder_exception(ExceptionCode::SECURITY)?;
+        }
 
         // Check if partition images are labeled incorrectly. This is to prevent random images
         // which are not protected by the Android Verified Boot (e.g. bits downloaded by apps) from
diff --git a/android/virtmgr/src/selinux.rs b/android/virtmgr/src/selinux.rs
index a8c895f..719c9a9 100644
--- a/android/virtmgr/src/selinux.rs
+++ b/android/virtmgr/src/selinux.rs
@@ -246,6 +246,7 @@
     use super::*;
 
     #[test]
+    #[ignore = "disabling test while investigating b/379087641"]
     fn test_check_tee_service_permission_has_permission() -> Result<()> {
         if cfg!(not(tee_services_allowlist)) {
             // Skip test on release configurations without tee_services_allowlist feature enabled.
@@ -258,6 +259,7 @@
     }
 
     #[test]
+    #[ignore = "disabling test while investigating b/379087641"]
     fn test_check_tee_service_permission_invalid_tee_service() -> Result<()> {
         if cfg!(not(tee_services_allowlist)) {
             // Skip test on release configurations without tee_services_allowlist feature enabled.
diff --git a/build/debian/kokoro/gcp_ubuntu_docker/aarch64/build.sh b/build/debian/kokoro/gcp_ubuntu_docker/aarch64/build.sh
index 7a1523a..130e691 100644
--- a/build/debian/kokoro/gcp_ubuntu_docker/aarch64/build.sh
+++ b/build/debian/kokoro/gcp_ubuntu_docker/aarch64/build.sh
@@ -5,8 +5,7 @@
 cd "${KOKORO_ARTIFACTS_DIR}/git/avf/build/debian/"
 sudo losetup -D
 grep vmx /proc/cpuinfo || true
-sudo ./build.sh
+sudo ./build.sh -r
 sudo mv images.tar.gz ${KOKORO_ARTIFACTS_DIR} || true
-
 mkdir -p ${KOKORO_ARTIFACTS_DIR}/logs
 sudo cp -r /var/log/fai/* ${KOKORO_ARTIFACTS_DIR}/logs || true
diff --git a/build/debian/kokoro/gcp_ubuntu_docker/x86_64/build.sh b/build/debian/kokoro/gcp_ubuntu_docker/x86_64/build.sh
index 66e3d64..50ded7b 100644
--- a/build/debian/kokoro/gcp_ubuntu_docker/x86_64/build.sh
+++ b/build/debian/kokoro/gcp_ubuntu_docker/x86_64/build.sh
@@ -5,7 +5,7 @@
 cd "${KOKORO_ARTIFACTS_DIR}/git/avf/build/debian/"
 sudo losetup -D
 grep vmx /proc/cpuinfo || true
-sudo ./build.sh -a x86_64
+sudo ./build.sh -a x86_64 -r
 sudo mv images.tar.gz ${KOKORO_ARTIFACTS_DIR} || true
 
 mkdir -p ${KOKORO_ARTIFACTS_DIR}/logs
diff --git a/guest/forwarder_guest_launcher/src/main.rs b/guest/forwarder_guest_launcher/src/main.rs
index 0e06c66..c3fdd7e 100644
--- a/guest/forwarder_guest_launcher/src/main.rs
+++ b/guest/forwarder_guest_launcher/src/main.rs
@@ -110,8 +110,12 @@
 async fn report_active_ports(
     mut client: DebianServiceClient<Channel>,
 ) -> Result<(), Box<dyn std::error::Error>> {
-    let mut cmd =
-        Command::new("/usr/sbin/tcpstates-bpfcc").arg("-s").stdout(Stdio::piped()).spawn()?;
+    let mut cmd = Command::new("python3")
+        .arg("-u")
+        .arg("/usr/sbin/tcpstates-bpfcc")
+        .arg("-s")
+        .stdout(Stdio::piped())
+        .spawn()?;
     let stdout = cmd.stdout.take().context("Failed to get stdout of tcpstates")?;
     let mut csv_reader = AsyncReader::from_reader(BufReader::new(stdout));
     let header = csv_reader.headers().await?.clone();
@@ -134,6 +138,9 @@
         if row.ip != TCPSTATES_IP_4 {
             continue;
         }
+        if row.lport < NON_PREVILEGED_PORT_RANGE_START {
+            continue;
+        }
         match (row.oldstate.as_str(), row.newstate.as_str()) {
             (_, TCPSTATES_STATE_LISTEN) => {
                 listening_ports.insert(row.lport);
diff --git a/guest/microdroid_manager/src/main.rs b/guest/microdroid_manager/src/main.rs
index fa089fa..c5fa864 100644
--- a/guest/microdroid_manager/src/main.rs
+++ b/guest/microdroid_manager/src/main.rs
@@ -669,7 +669,9 @@
         });
     }
 
-    command.stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::null());
+    if !is_debuggable()? {
+        command.stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::null());
+    }
 
     info!("notifying payload started");
     service.notifyPayloadStarted()?;
diff --git a/guest/trusty/security_vm/launcher/Android.bp b/guest/trusty/security_vm/launcher/Android.bp
index e482e02..ef32740 100644
--- a/guest/trusty/security_vm/launcher/Android.bp
+++ b/guest/trusty/security_vm/launcher/Android.bp
@@ -40,12 +40,15 @@
 // python -c "import hashlib; print(hashlib.sha256(b'trusty_security_vm_salt').hexdigest())"
 trusty_security_vm_salt = "75a71e967c1a1e0f805cca20465e7acf83e6a04e567a67c426d8b5a94f8d61c5"
 
+TRUSTY_SECURITY_VM_VERSION = 1
+
 avb_add_hash_footer {
     name: "trusty_security_vm_signed",
     filename: "trusty_security_vm_signed",
     partition_name: "boot",
     private_key: ":trusty_vm_sign_key",
     salt: trusty_security_vm_salt,
+    rollback_index: TRUSTY_SECURITY_VM_VERSION,
     src: ":empty_file",
     enabled: false,
     arch: {
diff --git a/tests/Terminal/src/com/android/virtualization/terminal/TerminalAppTest.java b/tests/Terminal/src/com/android/virtualization/terminal/TerminalAppTest.java
index 6400438..fd07973 100644
--- a/tests/Terminal/src/com/android/virtualization/terminal/TerminalAppTest.java
+++ b/tests/Terminal/src/com/android/virtualization/terminal/TerminalAppTest.java
@@ -56,7 +56,6 @@
 
         Intent intent = new Intent(mTargetContext, InstallerActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.putExtra(InstallerActivity.EXTRA_AUTO_DOWNLOAD, true);
 
         if (mInstr.startActivitySync(intent) instanceof InstallerActivity activity) {
             assertTrue(