feat: add android codex remote control actions

This commit is contained in:
AI Bot
2026-06-04 17:26:19 +08:00
parent 025e749618
commit 6f143ea6f9
7 changed files with 176 additions and 3 deletions

View File

@@ -58,6 +58,23 @@ public class BossApiClientDeviceModeTest {
);
}
@Test
public void queueCodexRemoteControlWritesConfirmedActionBody() throws Exception {
RecordingConnection connection = new RecordingConnection(
new URL("https://boss.hyzq.net/api/v1/devices/device-1/codex-remote-control")
);
RecordingBossApiClient apiClient = new RecordingBossApiClient(connection);
apiClient.queueCodexRemoteControl("device-1", "start", "APP 设备详情页确认启动");
assertEquals("/api/v1/devices/device-1/codex-remote-control", apiClient.lastPath);
assertEquals("POST", connection.requestMethodValue);
assertEquals(
"{\"action\":\"start\",\"confirmed\":true,\"reason\":\"APP 设备详情页确认启动\"}",
connection.requestBody()
);
}
private static final class RecordingBossApiClient extends BossApiClient {
private final RecordingConnection connection;
private String lastPath = "";

View File

@@ -76,6 +76,31 @@ public class DeviceDetailActivityTest {
assertTrue(viewTreeContainsText(content, "未连接"));
}
@Test
public void renderDeviceShowsCodexRemoteControlActions() throws Exception {
TestDeviceDetailActivity activity = Robolectric
.buildActivity(
TestDeviceDetailActivity.class,
new Intent()
.putExtra(DeviceDetailActivity.EXTRA_DEVICE_ID, "device-1")
.putExtra(DeviceDetailActivity.EXTRA_DEVICE_NAME, "Mac Studio")
)
.setup()
.get();
ReflectionHelpers.callInstanceMethod(
activity,
"renderDevice",
ReflectionHelpers.ClassParameter.from(JSONObject.class, buildDevicePayload())
);
View content = activity.findViewById(R.id.screen_content);
assertTrue(viewTreeContainsText(content, "Codex 远程控制"));
assertTrue(viewTreeContainsText(content, "启动远控"));
assertTrue(viewTreeContainsText(content, "停止远控"));
assertTrue(viewTreeContainsText(content, "默认走 Codex Computer Use"));
}
@Test
public void renderDeviceShowsCodexAppServerProtocolAndCollaborationSummary() throws Exception {
TestDeviceDetailActivity activity = Robolectric
@@ -228,6 +253,43 @@ public class DeviceDetailActivityTest {
assertEquals("allow_always", apiClient.lastPayload.optString("conflictDecision"));
}
@Test
public void codexRemoteControlConfirmDialogQueuesStartAction() throws Exception {
TestDeviceDetailActivity activity = Robolectric
.buildActivity(
TestDeviceDetailActivity.class,
new Intent()
.putExtra(DeviceDetailActivity.EXTRA_DEVICE_ID, "device-1")
.putExtra(DeviceDetailActivity.EXTRA_DEVICE_NAME, "Mac Studio")
)
.setup()
.get();
RecordingBossApiClient apiClient = new RecordingBossApiClient(
activity.getSharedPreferences("test-boss-api", Context.MODE_PRIVATE),
"https://boss.hyzq.net"
);
ReflectionHelpers.setField(activity, "apiClient", apiClient);
ReflectionHelpers.setField(activity, "executor", new DirectExecutorService());
ReflectionHelpers.callInstanceMethod(
activity,
"showCodexRemoteControlConfirmDialog",
ReflectionHelpers.ClassParameter.from(String.class, "start")
);
android.app.Dialog latestDialog = ShadowDialog.getLatestDialog();
assertTrue(latestDialog instanceof AlertDialog);
AlertDialog dialog = (AlertDialog) latestDialog;
dialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
Shadows.shadowOf(activity.getMainLooper()).idle();
assertEquals(1, apiClient.queueCodexRemoteControlCalls);
assertEquals("device-1", apiClient.lastCodexRemoteControlDeviceId);
assertEquals("start", apiClient.lastCodexRemoteControlAction);
assertEquals("APP 设备详情页确认启动 Codex 远控", apiClient.lastCodexRemoteControlReason);
}
@Test
public void matchingDevicesUpdatedEventTriggersReload() throws Exception {
TestDeviceDetailActivity activity = Robolectric
@@ -462,6 +524,10 @@ public class DeviceDetailActivityTest {
private int updateDeviceCalls;
private String lastDeviceId;
private JSONObject lastPayload;
private int queueCodexRemoteControlCalls;
private String lastCodexRemoteControlDeviceId;
private String lastCodexRemoteControlAction;
private String lastCodexRemoteControlReason;
RecordingBossApiClient(android.content.SharedPreferences prefs, String baseUrl) {
super(prefs, baseUrl);
@@ -478,6 +544,19 @@ public class DeviceDetailActivityTest {
throw new RuntimeException(error);
}
}
@Override
public ApiResponse queueCodexRemoteControl(String deviceId, String action, String reason) {
queueCodexRemoteControlCalls += 1;
lastCodexRemoteControlDeviceId = deviceId;
lastCodexRemoteControlAction = action;
lastCodexRemoteControlReason = reason;
try {
return new ApiResponse(200, new JSONObject().put("ok", true));
} catch (Exception error) {
throw new RuntimeException(error);
}
}
}
private static final class DirectExecutorService extends AbstractExecutorService {