Merge "Enable mod keyboard in a11y env as well" into main
diff --git a/android/TerminalApp/AndroidManifest.xml b/android/TerminalApp/AndroidManifest.xml
index dad07ee..a9d6e9d 100644
--- a/android/TerminalApp/AndroidManifest.xml
+++ b/android/TerminalApp/AndroidManifest.xml
@@ -83,10 +83,6 @@
<property
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="Run VM instances" />
- <intent-filter>
- <action android:name="android.virtualization.START_VM_LAUNCHER_SERVICE" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
</service>
</application>
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java b/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java
index 01d2afa..fa5c382 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java
@@ -16,6 +16,8 @@
package com.android.virtualization.terminal;
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
import android.content.Context;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
@@ -37,8 +39,6 @@
import java.security.cert.X509Certificate;
public class CertificateUtils {
- private static final String TAG = "CertificateUtils";
-
private static final String ALIAS = "ttyd";
public static KeyStore.PrivateKeyEntry createOrGetKey() {
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/DebianServiceImpl.java b/android/TerminalApp/java/com/android/virtualization/terminal/DebianServiceImpl.java
index 1b2ce8c..93b0b0c 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/DebianServiceImpl.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/DebianServiceImpl.java
@@ -16,6 +16,8 @@
package com.android.virtualization.terminal;
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
@@ -37,7 +39,11 @@
import java.util.Set;
final class DebianServiceImpl extends DebianServiceGrpc.DebianServiceImplBase {
- public static final String TAG = "DebianService";
+ private static final String PREFERENCE_FILE_KEY =
+ "com.android.virtualization.terminal.PREFERENCE_FILE_KEY";
+ private static final String PREFERENCE_FORWARDING_PORTS = "PREFERENCE_FORWARDING_PORTS";
+ private static final String PREFERENCE_FORWARDING_PORT_IS_ENABLED_PREFIX =
+ "PREFERENCE_FORWARDING_PORT_IS_ENABLED_";
private final Context mContext;
private final SharedPreferences mSharedPref;
@@ -66,7 +72,7 @@
public void reportVmActivePorts(
ReportVmActivePortsRequest request,
StreamObserver<ReportVmActivePortsResponse> responseObserver) {
- Log.d(DebianServiceImpl.TAG, "reportVmActivePorts: " + request.toString());
+ Log.d(TAG, "reportVmActivePorts: " + request.toString());
Set<String> prevPorts =
mSharedPref.getStringSet(mPreferenceForwardingPorts, Collections.emptySet());
@@ -93,7 +99,7 @@
@Override
public void reportVmIpAddr(
IpAddr request, StreamObserver<ReportVmIpAddrResponse> responseObserver) {
- Log.d(DebianServiceImpl.TAG, "reportVmIpAddr: " + request.toString());
+ Log.d(TAG, "reportVmIpAddr: " + request.toString());
mCallback.onIpAddressAvailable(request.getAddr());
ReportVmIpAddrResponse reply = ReportVmIpAddrResponse.newBuilder().setSuccess(true).build();
responseObserver.onNext(reply);
@@ -103,7 +109,7 @@
@Override
public void openForwardingRequestQueue(
QueueOpeningRequest request, StreamObserver<ForwardingRequestItem> responseObserver) {
- Log.d(DebianServiceImpl.TAG, "OpenForwardingRequestQueue");
+ Log.d(TAG, "OpenForwardingRequestQueue");
mPortForwardingListener =
new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
@@ -144,7 +150,7 @@
private static native void terminateForwarderHost();
void killForwarderHost() {
- Log.d(DebianServiceImpl.TAG, "Stopping port forwarding");
+ Log.d(TAG, "Stopping port forwarding");
if (mPortForwardingListener != null) {
mSharedPref.unregisterOnSharedPreferenceChangeListener(mPortForwardingListener);
terminateForwarderHost();
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallUtils.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstallUtils.java
index b17e636..71f2a2d 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallUtils.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallUtils.java
@@ -15,6 +15,8 @@
*/
package com.android.virtualization.terminal;
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
import android.content.Context;
import android.os.Environment;
import android.os.FileUtils;
@@ -38,8 +40,6 @@
import java.util.function.Function;
public class InstallUtils {
- private static final String TAG = InstallUtils.class.getSimpleName();
-
private static final String VM_CONFIG_FILENAME = "vm_config.json";
private static final String COMPRESSED_PAYLOAD_FILENAME = "images.tar.gz";
private static final String ROOTFS_FILENAME = "root_part";
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
index 45da73c..52ef3d4 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
@@ -16,6 +16,8 @@
package com.android.virtualization.terminal;
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
import android.annotation.MainThread;
import android.content.ComponentName;
import android.content.Context;
@@ -42,8 +44,6 @@
import java.lang.ref.WeakReference;
public class InstallerActivity extends BaseActivity {
- private static final String TAG = "LinuxInstaller";
-
private static final long ESTIMATED_IMG_SIZE_BYTES = FileUtils.parseSize("550MB");
private CheckBox mWaitForWifiCheckbox;
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java
index 5d4c4ad..6fd3b5c 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java
@@ -16,6 +16,8 @@
package com.android.virtualization.terminal;
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
@@ -55,8 +57,6 @@
import java.util.concurrent.Executors;
public class InstallerService extends Service {
- private static final String TAG = "InstallerService";
-
private static final int NOTIFICATION_ID = 1313; // any unique number among notifications
private static final String IMAGE_URL =
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
index 15bc29c..bc5d037 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
@@ -76,7 +76,7 @@
import java.util.Map;
public class MainActivity extends BaseActivity
- implements VmLauncherServices.VmLauncherServiceCallback, AccessibilityStateChangeListener {
+ implements VmLauncherService.VmLauncherServiceCallback, AccessibilityStateChangeListener {
static final String TAG = "VmTerminalApp";
private static final String VM_ADDR = "192.168.0.2";
private static final int TTYD_PORT = 7681;
@@ -427,7 +427,7 @@
@Override
protected void onDestroy() {
getSystemService(AccessibilityManager.class).removeAccessibilityStateChangeListener(this);
- VmLauncherServices.stopVmLauncherService(this);
+ VmLauncherService.stop(this);
super.onDestroy();
}
@@ -539,7 +539,7 @@
Intent stopIntent = new Intent();
stopIntent.setClass(this, VmLauncherService.class);
- stopIntent.setAction(VmLauncherServices.ACTION_STOP_VM_LAUNCHER_SERVICE);
+ stopIntent.setAction(VmLauncherService.ACTION_STOP_VM_LAUNCHER_SERVICE);
PendingIntent stopPendingIntent =
PendingIntent.getService(
this,
@@ -577,7 +577,7 @@
.build();
android.os.Trace.beginAsyncSection("executeTerminal", 0);
- VmLauncherServices.startVmLauncherService(this, this, notification);
+ VmLauncherService.run(this, this, notification);
connectToTerminalService();
}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java b/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java
index a2247b1..4094025 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java
@@ -16,6 +16,8 @@
package com.android.virtualization.terminal;
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
import android.content.Context;
import android.system.virtualmachine.VirtualMachine;
import android.system.virtualmachine.VirtualMachineCallback;
@@ -30,7 +32,6 @@
/** Utility class for creating a VM and waiting for it to finish. */
class Runner {
- private static final String TAG = Runner.class.getSimpleName();
private final VirtualMachine mVirtualMachine;
private final Callback mCallback;
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt
index 32df273..1b39ff0 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt
@@ -28,9 +28,9 @@
import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import com.android.virtualization.terminal.MainActivity.TAG
class SettingsPortForwardingActivity : AppCompatActivity() {
- val TAG: String = "VmTerminalApp"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.settings_port_forwarding)
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsRecoveryActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsRecoveryActivity.kt
index ef76e03..e291b57 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsRecoveryActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsRecoveryActivity.kt
@@ -22,6 +22,7 @@
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
+import com.android.virtualization.terminal.MainActivity.TAG
import com.google.android.material.card.MaterialCardView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
@@ -30,8 +31,6 @@
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
-const val TAG: String = "VmTerminalApp"
-
class SettingsRecoveryActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -123,4 +122,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
index 1c00c8d..cd1f65b 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
@@ -16,6 +16,8 @@
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;
@@ -27,7 +29,10 @@
import android.content.SharedPreferences;
import android.graphics.drawable.Icon;
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;
@@ -52,14 +57,19 @@
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.util.HashSet;
+import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class VmLauncherService extends Service implements DebianServiceImpl.DebianServiceCallback {
- public static final String EXTRA_NOTIFICATION = "EXTRA_NOTIFICATION";
- static final String TAG = "VmLauncherService";
+ 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;
@@ -74,19 +84,71 @@
private DebianServiceImpl mDebianService;
private PortForwardingRequestReceiver mPortForwardingReceiver;
+ private static Intent getMyIntent(Context context) {
+ return new Intent(context.getApplicationContext(), VmLauncherService.class);
+ }
+
+ public interface VmLauncherServiceCallback {
+ void onVmStart();
+
+ void onVmStop();
+
+ void onVmError();
+
+ void onIpAddrAvailable(String ipAddr);
+ }
+
+ 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;
+ case RESULT_IPADDR:
+ callback.onIpAddrAvailable(resultData.getString(KEY_VM_IP_ADDR));
+ 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;
}
- private void startForeground(Notification notification) {
- startForeground(this.hashCode(), notification);
- }
-
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- if (Objects.equals(
- intent.getAction(), VmLauncherServices.ACTION_STOP_VM_LAUNCHER_SERVICE)) {
+ if (Objects.equals(intent.getAction(), ACTION_STOP_VM_LAUNCHER_SERVICE)) {
stopSelf();
return START_NOT_STICKY;
}
@@ -136,7 +198,7 @@
Notification notification =
intent.getParcelableExtra(EXTRA_NOTIFICATION, Notification.class);
- startForeground(notification);
+ startForeground(this.hashCode(), notification);
mResultReceiver.send(RESULT_START, null);
@@ -149,27 +211,6 @@
return START_NOT_STICKY;
}
- @Override
- public void onDestroy() {
- unregisterReceiver(mPortForwardingReceiver);
- 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 startDebianServer() {
ServerInterceptor interceptor =
new ServerInterceptor() {
@@ -224,6 +265,40 @@
});
}
+ @Override
+ public void onIpAddressAvailable(String ipAddr) {
+ android.os.Trace.endAsyncSection("debianBoot", 0);
+ Bundle b = new Bundle();
+ b.putString(VmLauncherService.KEY_VM_IP_ADDR, ipAddr);
+ mResultReceiver.send(VmLauncherService.RESULT_IPADDR, b);
+ }
+
+ public static void stop(Context context) {
+ Intent i = getMyIntent(context);
+ context.stopService(i);
+ }
+
+ @Override
+ public void onDestroy() {
+ unregisterReceiver(mPortForwardingReceiver);
+ 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();
@@ -234,14 +309,6 @@
}
@Override
- public void onIpAddressAvailable(String ipAddr) {
- android.os.Trace.endAsyncSection("debianBoot", 0);
- Bundle b = new Bundle();
- b.putString(VmLauncherService.KEY_VM_IP_ADDR, ipAddr);
- mResultReceiver.send(VmLauncherService.RESULT_IPADDR, b);
- }
-
- @Override
public void onActivePortsChanged(Set<String> oldPorts, Set<String> newPorts) {
Set<String> union = new HashSet<>(oldPorts);
union.addAll(newPorts);
@@ -262,7 +329,7 @@
private PendingIntent getPortForwardingPendingIntent(int port, boolean enabled) {
Intent intent = new Intent(PortForwardingRequestReceiver.ACTION_PORT_FORWARDING);
intent.setPackage(getPackageName());
- intent.setIdentifier(String.format("%d_%b", port, enabled));
+ intent.setIdentifier(String.format(Locale.ROOT, "%d_%b", port, enabled));
intent.putExtra(PortForwardingRequestReceiver.KEY_PORT, port);
intent.putExtra(PortForwardingRequestReceiver.KEY_ENABLED, enabled);
return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
@@ -308,7 +375,7 @@
getSystemService(NotificationManager.class).cancel(TAG, port);
}
- private final class PortForwardingRequestReceiver extends BroadcastReceiver {
+ private static final class PortForwardingRequestReceiver extends BroadcastReceiver {
private static final String ACTION_PORT_FORWARDING =
"android.virtualization.PORT_FORWARDING";
private static final String KEY_PORT = "port";
@@ -335,7 +402,7 @@
enabled);
editor.apply();
- context.getSystemService(NotificationManager.class).cancel(VmLauncherService.TAG, port);
+ context.getSystemService(NotificationManager.class).cancel(TAG, port);
}
}
}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherServices.java b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherServices.java
deleted file mode 100644
index d6c6786..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherServices.java
+++ /dev/null
@@ -1,122 +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.app.Notification;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-import java.util.List;
-
-public class VmLauncherServices {
- private static final String TAG = "VmLauncherServices";
-
- 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 static final int RESULT_IPADDR = 3;
- private static final String KEY_VM_IP_ADDR = "ip_addr";
-
- private static Intent buildVmLauncherServiceIntent(Context context) {
- Intent i = new Intent();
- i.setAction(ACTION_START_VM_LAUNCHER_SERVICE);
-
- Intent intent = new Intent(ACTION_START_VM_LAUNCHER_SERVICE);
- PackageManager pm = context.getPackageManager();
- List<ResolveInfo> resolveInfos =
- pm.queryIntentServices(intent, PackageManager.MATCH_DEFAULT_ONLY);
- if (resolveInfos == null || resolveInfos.size() != 1) {
- Log.e(TAG, "cannot find a service to handle ACTION_START_VM_LAUNCHER_SERVICE");
- return null;
- }
- String packageName = resolveInfos.get(0).serviceInfo.packageName;
-
- i.setPackage(packageName);
- return i;
- }
-
- public static void stopVmLauncherService(Context context) {
- Intent i = buildVmLauncherServiceIntent(context);
- context.stopService(i);
- }
-
- public static void startVmLauncherService(
- Context context, VmLauncherServiceCallback callback, Notification notification) {
- Intent i = buildVmLauncherServiceIntent(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;
- case RESULT_IPADDR:
- callback.onIpAddrAvailable(resultData.getString(KEY_VM_IP_ADDR));
- return;
- }
- }
- };
- i.putExtra(Intent.EXTRA_RESULT_RECEIVER, getResultReceiverForIntent(resultReceiver));
- i.putExtra(VmLauncherService.EXTRA_NOTIFICATION, notification);
- context.startForegroundService(i);
- }
-
- public interface VmLauncherServiceCallback {
- void onVmStart();
-
- void onVmStop();
-
- void onVmError();
-
- void onIpAddrAvailable(String ipAddr);
- }
-
- 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;
- }
-}
diff --git a/docs/custom_vm.md b/docs/custom_vm.md
index 9a9ede4..eaff2a4 100644
--- a/docs/custom_vm.md
+++ b/docs/custom_vm.md
@@ -24,3 +24,22 @@
The `vm` command also has other subcommands for debugging; run
`/apex/com.android.virt/bin/vm help` for details.
+
+# Terminal app
+## Graphical environment (Wayland, VNC)
+By installing Wayland compositor and VNC backend, you can enable graphical environment.
+One of the options is `sway`, `wayvnc` and `xwayland`(if necessary).
+
+```
+sudo apt install sway wayvnc xwayland
+WLR_BACKENDS=headless WLR_LIBINPUT_NO_DEVICES=1 sway
+WAYLAND_DISPLAY=wayland-1 wayvnc 0.0.0.0 # or use port forwarding
+```
+
+And then, connect to 192.168.0.2:5900(or localhost:5900) with arbitrary VNC client.
+Or, `novnc`(https://github.com/novnc/noVNC/releases). For `novnc` you need to install
+`novnc`, and run `<novnc_path>/utils/novnc_proxy`, and then connect to `http://192.168.0.2:6080/vnc.html`
+(or `localhost:6080` if port forwarding is enabled.)
+
+`weston` with VNC backend might be another option, but it isn't available in
+Debian package repository for bookworm.
\ No newline at end of file
diff --git a/guest/forwarder_guest_launcher/src/main.rs b/guest/forwarder_guest_launcher/src/main.rs
index 0bb3b4d..1da37b4 100644
--- a/guest/forwarder_guest_launcher/src/main.rs
+++ b/guest/forwarder_guest_launcher/src/main.rs
@@ -36,6 +36,7 @@
const NON_PREVILEGED_PORT_RANGE_START: i32 = 1024;
const TCPSTATES_IP_4: i8 = 4;
+const TCPSTATES_STATE_CLOSE: &str = "CLOSE";
const TCPSTATES_STATE_LISTEN: &str = "LISTEN";
#[derive(Debug, Deserialize)]
@@ -43,7 +44,7 @@
struct TcpStateRow {
ip: i8,
lport: i32,
- oldstate: String,
+ rport: i32,
newstate: String,
}
@@ -142,14 +143,17 @@
if row.lport < NON_PREVILEGED_PORT_RANGE_START {
continue;
}
- match (row.oldstate.as_str(), row.newstate.as_str()) {
- (_, TCPSTATES_STATE_LISTEN) => {
+ if row.rport > 0 {
+ continue;
+ }
+ match row.newstate.as_str() {
+ TCPSTATES_STATE_LISTEN => {
listening_ports.insert(row.lport);
}
- (TCPSTATES_STATE_LISTEN, _) => {
+ TCPSTATES_STATE_CLOSE => {
listening_ports.remove(&row.lport);
}
- (_, _) => continue,
+ _ => continue,
}
send_active_ports_report(listening_ports.clone(), &mut client).await?;
}