Merge "Bump Cuttlefish SHIPPING_API_LEVEL" into main
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index 79350c2..7baae38 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -710,15 +710,15 @@
guest_config.mouse_supported =
res_mouse_support.ok() && res_mouse_support.value() == "supported";
- auto res_custom_keyboard_config = GetAndroidInfoConfig(
- instance_android_info_txt, "custom_keyboard_config");
+ auto res_custom_keyboard_config =
+ GetAndroidInfoConfig(instance_android_info_txt, "custom_keyboard");
if (res_custom_keyboard_config.ok()) {
guest_config.custom_keyboard_config =
DefaultHostArtifactsPath(res_custom_keyboard_config.value());
}
- auto res_domkey_mapping_config = GetAndroidInfoConfig(
- instance_android_info_txt, "domkey_mapping_config");
+ auto res_domkey_mapping_config =
+ GetAndroidInfoConfig(instance_android_info_txt, "domkey_mapping");
if (res_domkey_mapping_config.ok()) {
guest_config.domkey_mapping_config =
DefaultHostArtifactsPath(res_domkey_mapping_config.value());
@@ -1985,7 +1985,7 @@
}
Result<void> SetDefaultFlagsForQemu(
- Arch target_arch,
+ const std::vector<GuestConfig>& guest_configs,
std::map<std::string, std::string>& name_to_default_value) {
auto instance_nums =
CF_EXPECT(InstanceNumsCalculator().FromGlobalGflags().Calculate());
@@ -1996,25 +1996,51 @@
CF_EXPECT(GET_FLAG_BOOL_VALUE(start_webrtc));
std::vector<std::string> system_image_dir =
CF_EXPECT(GET_FLAG_STR_VALUE(system_image_dir));
+ std::string curr_bootloader = "";
std::string curr_android_efi_loader = "";
+ std::string default_bootloader = "";
std::string default_android_efi_loader = "";
std::string default_start_webrtc = "";
for (int instance_index = 0; instance_index < instance_nums.size();
instance_index++) {
if (instance_index >= system_image_dir.size()) {
+ curr_bootloader = system_image_dir[0];
curr_android_efi_loader = system_image_dir[0];
} else {
+ curr_bootloader = system_image_dir[instance_index];
curr_android_efi_loader = system_image_dir[instance_index];
}
+ curr_bootloader += "/bootloader";
curr_android_efi_loader += "/android_efi_loader.efi";
+ // /bootloader isn't presented in the output folder by default and can be
+ // only fetched by --bootloader in fetch_cvd, so pick it only in case
+ // it's presented.
+ if (!FileExists(curr_bootloader)) {
+ // Fallback to default bootloader
+ curr_bootloader = DefaultHostArtifactsPath("etc/bootloader_");
+ if (guest_configs[instance_index].target_arch == Arch::Arm64) {
+ curr_bootloader += "aarch64";
+ } else {
+ curr_bootloader += "x86_64";
+ }
+ curr_bootloader += "/bootloader.qemu";
+ }
+
if (instance_index > 0) {
+ default_bootloader += ",";
default_android_efi_loader += ",";
default_start_webrtc += ",";
}
- default_android_efi_loader += curr_android_efi_loader;
+ default_bootloader += curr_bootloader;
+ // EFI loader isn't presented in the output folder by default and can be
+ // only fetched by --uefi_app_build in fetch_cvd, so pick it only in case
+ // it's presented.
+ if (FileExists(curr_android_efi_loader)) {
+ default_android_efi_loader += curr_android_efi_loader;
+ }
if (gpu_mode_vec[instance_index] == kGpuModeGuestSwiftshader &&
!start_webrtc_vec[instance_index]) {
// This makes WebRTC the default streamer unless the user requests
@@ -2031,29 +2057,11 @@
SetCommandLineOptionWithMode("start_webrtc", default_start_webrtc.c_str(),
SET_FLAGS_DEFAULT);
- std::string default_bootloader = DefaultHostArtifactsPath("etc/bootloader_");
- if (target_arch == Arch::Arm) {
- // Bootloader is unstable >512MB RAM on 32-bit ARM
- SetCommandLineOptionWithMode("memory_mb", "512", SET_FLAGS_VALUE);
- default_bootloader += "arm";
- } else if (target_arch == Arch::Arm64) {
- default_bootloader += "aarch64";
- } else if (target_arch == Arch::RiscV64) {
- default_bootloader += "riscv64";
- } else {
- default_bootloader += "x86_64";
- }
- default_bootloader += "/bootloader.qemu";
SetCommandLineOptionWithMode("bootloader", default_bootloader.c_str(),
SET_FLAGS_DEFAULT);
- // EFI loader isn't presented in the output folder by default and can be only
- // fetched by --uefi_app_build in fetch_cvd, so pick it only in case it's
- // presented.
- if (FileExists(default_android_efi_loader)) {
- SetCommandLineOptionWithMode("android_efi_loader",
- default_android_efi_loader.c_str(),
- SET_FLAGS_DEFAULT);
- }
+ SetCommandLineOptionWithMode("android_efi_loader",
+ default_android_efi_loader.c_str(),
+ SET_FLAGS_DEFAULT);
return {};
}
@@ -2076,43 +2084,50 @@
std::vector<std::string> system_image_dir =
CF_EXPECT(GET_FLAG_STR_VALUE(system_image_dir));
std::string curr_android_efi_loader = "";
- std::string cur_bootloader = "";
+ std::string curr_bootloader = "";
std::string default_android_efi_loader = "";
std::string default_bootloader = "";
std::string default_enable_sandbox_str = "";
for (int instance_index = 0; instance_index < instance_nums.size();
instance_index++) {
- if (guest_configs[instance_index].android_version_number == "11.0.0") {
- cur_bootloader = DefaultHostArtifactsPath("etc/bootloader_");
- if (guest_configs[instance_index].target_arch == Arch::Arm64) {
- cur_bootloader += "aarch64";
- } else {
- cur_bootloader += "x86_64";
- }
- cur_bootloader += "/bootloader.crosvm";
- } else {
- if (instance_index >= system_image_dir.size()) {
- cur_bootloader = system_image_dir[0];
- } else {
- cur_bootloader = system_image_dir[instance_index];
- }
- cur_bootloader += "/bootloader";
- }
if (instance_index >= system_image_dir.size()) {
+ curr_bootloader = system_image_dir[0];
curr_android_efi_loader = system_image_dir[0];
} else {
+ curr_bootloader = system_image_dir[instance_index];
curr_android_efi_loader = system_image_dir[instance_index];
}
+ curr_bootloader += "/bootloader";
curr_android_efi_loader += "/android_efi_loader.efi";
+ // /bootloader isn't presented in the output folder by default and can be
+ // only fetched by --bootloader in fetch_cvd, so pick it only in case
+ // it's presented.
+ if (!FileExists(curr_bootloader)) {
+ // Fallback to default bootloader
+ curr_bootloader = DefaultHostArtifactsPath("etc/bootloader_");
+ if (guest_configs[instance_index].target_arch == Arch::Arm64) {
+ curr_bootloader += "aarch64";
+ } else {
+ curr_bootloader += "x86_64";
+ }
+ curr_bootloader += "/bootloader.crosvm";
+ }
+
if (instance_index > 0) {
default_bootloader += ",";
default_android_efi_loader += ",";
default_enable_sandbox_str += ",";
default_start_webrtc += ",";
}
- default_bootloader += cur_bootloader;
- default_android_efi_loader += curr_android_efi_loader;
+
+ default_bootloader += curr_bootloader;
+ // EFI loader isn't presented in the output folder by default and can be
+ // only fetched by --uefi_app_build in fetch_cvd, so pick it only in case
+ // it's presented.
+ if (FileExists(curr_android_efi_loader)) {
+ default_android_efi_loader += curr_android_efi_loader;
+ }
default_enable_sandbox_str += fmt::format("{}", default_enable_sandbox);
if (!start_webrtc_vec[instance_index]) {
// This makes WebRTC the default streamer unless the user requests
@@ -2126,14 +2141,9 @@
}
SetCommandLineOptionWithMode("bootloader", default_bootloader.c_str(),
SET_FLAGS_DEFAULT);
- // EFI loader isn't presented in the output folder by default and can be only
- // fetched by --uefi_app_build in fetch_cvd, so pick it only in case it's
- // presented.
- if (FileExists(default_android_efi_loader)) {
- SetCommandLineOptionWithMode("android_efi_loader",
- default_android_efi_loader.c_str(),
- SET_FLAGS_DEFAULT);
- }
+ SetCommandLineOptionWithMode("android_efi_loader",
+ default_android_efi_loader.c_str(),
+ SET_FLAGS_DEFAULT);
// This is the 1st place to set "start_webrtc" flag value
SetCommandLineOptionWithMode("start_webrtc", default_start_webrtc.c_str(),
SET_FLAGS_DEFAULT);
@@ -2224,7 +2234,7 @@
auto name_to_default_value = CurrentFlagsToDefaultValue();
if (vmm == VmmMode::kQemu) {
- CF_EXPECT(SetDefaultFlagsForQemu(guest_configs[0].target_arch, name_to_default_value));
+ CF_EXPECT(SetDefaultFlagsForQemu(guest_configs, name_to_default_value));
} else if (vmm == VmmMode::kCrosvm) {
CF_EXPECT(SetDefaultFlagsForCrosvm(guest_configs, name_to_default_value));
} else if (vmm == VmmMode::kGem5) {
diff --git a/host/commands/casimir_control_server/Android.bp b/host/commands/casimir_control_server/Android.bp
index afaddb4..2caed5c 100644
--- a/host/commands/casimir_control_server/Android.bp
+++ b/host/commands/casimir_control_server/Android.bp
@@ -68,6 +68,7 @@
srcs: [
"casimir_controller.cpp",
"hex.cpp",
+ "crc.cpp",
"main.cpp",
],
cflags: [
diff --git a/host/commands/casimir_control_server/casimir_control.proto b/host/commands/casimir_control_server/casimir_control.proto
index a5434e9..4cc3ea4 100644
--- a/host/commands/casimir_control_server/casimir_control.proto
+++ b/host/commands/casimir_control_server/casimir_control.proto
@@ -23,6 +23,7 @@
rpc PollA (Void) returns (SenderId) {}
rpc SetRadioState(RadioState) returns (Void) {}
rpc SetPowerLevel(PowerLevel) returns (Void) {}
+ rpc SendBroadcast (SendBroadcastRequest) returns (SendBroadcastResponse) {}
rpc Init(Void) returns (Void) {}
rpc Close(Void) returns (Void) {}
}
@@ -49,4 +50,26 @@
message PowerLevel {
uint32 power_level = 1;
-}
\ No newline at end of file
+}
+
+message TransceiveConfiguration {
+ // A, B, F, V
+ optional string type = 1;
+ optional bool crc = 2;
+ // 0 to 8
+ optional uint32 bits = 3;
+ // 106, 212, 424, 848, 53, 26
+ optional uint32 bitrate = 4;
+ // value in microseconds
+ optional uint32 timeout = 5;
+ // 0 to 100
+ optional double power = 6;
+}
+
+message SendBroadcastRequest {
+ string data = 1;
+ optional TransceiveConfiguration configuration = 2;
+}
+
+message SendBroadcastResponse {
+}
diff --git a/host/commands/casimir_control_server/casimir_controller.cpp b/host/commands/casimir_control_server/casimir_controller.cpp
index fdf214f..e90887b 100644
--- a/host/commands/casimir_control_server/casimir_controller.cpp
+++ b/host/commands/casimir_control_server/casimir_controller.cpp
@@ -18,6 +18,9 @@
#include <chrono>
#include <cstdint>
+#include "host/commands/casimir_control_server/crc.h"
+
+#include "casimir_control.grpc.pb.h"
#include "casimir_controller.h"
namespace cuttlefish {
@@ -87,7 +90,11 @@
Result<uint16_t> CasimirController::SelectNfcA() {
PollCommandBuilder poll_command;
poll_command.technology_ = Technology::NFC_A;
+ poll_command.format_ = PollingFrameFormat::SHORT;
+ poll_command.bitrate_ = BitRate::BIT_RATE_106_KBIT_S;
poll_command.power_level_ = power_level;
+ // WUPA
+ poll_command.payload_ = std::vector<uint8_t>{0x52};
CF_EXPECT(Write(poll_command), "Failed to send NFC-A poll command");
auto res = CF_EXPECT(ReadRfPacket(10s), "Failed to get NFC-A poll response");
@@ -106,6 +113,7 @@
T4ATSelectCommandBuilder t4at_select_command;
t4at_select_command.sender_ = sender_id;
t4at_select_command.param_ = 0;
+ t4at_select_command.bitrate_ = BitRate::BIT_RATE_106_KBIT_S;
CF_EXPECT(Write(t4at_select_command), "Failed to send T4AT select command");
auto res = CF_EXPECT(ReadRfPacket(1s), "Failed to get T4AT response");
@@ -138,6 +146,7 @@
data_builder.receiver_ = receiver_id;
data_builder.technology_ = Technology::NFC_A;
data_builder.protocol_ = Protocol::ISO_DEP;
+ data_builder.bitrate_ = BitRate::BIT_RATE_106_KBIT_S;
CF_EXPECT(Write(data_builder), "Failed to send APDU bytes");
@@ -152,6 +161,83 @@
return CF_ERR("Invalid APDU response");
}
+Result<std::tuple<std::vector<uint8_t>, std::string, bool, uint32_t, uint32_t,
+ uint32_t, double>>
+CasimirController::SendBroadcast(std::vector<uint8_t> data, std::string type,
+ bool crc, uint8_t bits, uint32_t bitrate,
+ uint32_t timeout, double power) {
+ PollCommandBuilder poll_command;
+
+ if (type == "A") {
+ poll_command.technology_ = Technology::NFC_A;
+ if (crc) {
+ data = CF_EXPECT(WithCrc16A(data), "Could not append CRC16A");
+ }
+ } else if (type == "B") {
+ poll_command.technology_ = Technology::NFC_B;
+ if (crc) {
+ data = CF_EXPECT(WithCrc16B(data), "Could not append CRC16B");
+ }
+ if (bits != 8) {
+ return CF_ERR(
+ "Sending NFC-B data with != 8 bits in the last byte is unsupported");
+ }
+ } else if (type == "F") {
+ poll_command.technology_ = Technology::NFC_F;
+ if (!crc) {
+ // For NFC-F, CRC also assumes preamble
+ return CF_ERR("Sending NFC-F data without CRC is unsupported");
+ }
+ if (bits != 8) {
+ return CF_ERR(
+ "Sending NFC-F data with != 8 bits in the last byte is unsupported");
+ }
+ } else if (type == "V") {
+ poll_command.technology_ = Technology::NFC_V;
+ } else {
+ poll_command.technology_ = Technology::RAW;
+ }
+
+ if (bitrate == 106) {
+ poll_command.bitrate_ = BitRate::BIT_RATE_106_KBIT_S;
+ } else if (bitrate == 212) {
+ poll_command.bitrate_ = BitRate::BIT_RATE_212_KBIT_S;
+ } else if (bitrate == 424) {
+ poll_command.bitrate_ = BitRate::BIT_RATE_424_KBIT_S;
+ } else if (bitrate == 848) {
+ poll_command.bitrate_ = BitRate::BIT_RATE_848_KBIT_S;
+ } else if (bitrate == 1695) {
+ poll_command.bitrate_ = BitRate::BIT_RATE_1695_KBIT_S;
+ } else if (bitrate == 3390) {
+ poll_command.bitrate_ = BitRate::BIT_RATE_3390_KBIT_S;
+ } else if (bitrate == 6780) {
+ poll_command.bitrate_ = BitRate::BIT_RATE_6780_KBIT_S;
+ } else if (bitrate == 26) {
+ poll_command.bitrate_ = BitRate::BIT_RATE_26_KBIT_S;
+ } else {
+ return CF_ERR("Proper bitrate was not provided: " << bitrate);
+ }
+
+ poll_command.payload_ = std::move(data);
+
+ if (bits > 8) {
+ return CF_ERR("There can not be more than 8 bits in last byte: " << bits);
+ }
+ poll_command.format_ =
+ bits != 8 ? PollingFrameFormat::SHORT : PollingFrameFormat::LONG;
+
+ // Adjust range of values from 0-100 to 0-12
+ poll_command.power_level_ = static_cast<int>(std::round(power * 12 / 100));
+
+ CF_EXPECT(Write(poll_command), "Failed to send broadcast frame");
+
+ if (timeout != 0) {
+ ReadRfPacket(std::chrono::microseconds(timeout));
+ }
+
+ return std::make_tuple(data, type, crc, bits, bitrate, timeout, power);
+}
+
Result<void> CasimirController::Write(const RfPacketBuilder& rf_packet) {
std::vector<uint8_t> raw_bytes = rf_packet.SerializeToBytes();
uint16_t header_bytes_le = htole16(raw_bytes.size());
@@ -171,17 +257,21 @@
}
Result<std::shared_ptr<std::vector<uint8_t>>> CasimirController::ReadExact(
- size_t size, std::chrono::milliseconds timeout) {
+ size_t size, std::chrono::microseconds timeout) {
size_t total_read = 0;
auto out = std::make_shared<std::vector<uint8_t>>(size);
auto prev_time = std::chrono::steady_clock::now();
- while (timeout.count() > 0) {
+ while (
+ std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count() >
+ 0) {
PollSharedFd poll_fd = {
.fd = sock_,
.events = EPOLLIN,
.revents = 0,
};
- int res = sock_.Poll(&poll_fd, 1, timeout.count());
+ int res = sock_.Poll(
+ &poll_fd, 1,
+ std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count());
CF_EXPECT_GE(res, 0, "Failed to poll on the casimir socket");
CF_EXPECT_EQ(poll_fd.revents, EPOLLIN,
"Unexpected poll result for reading");
@@ -199,7 +289,7 @@
}
auto current_time = std::chrono::steady_clock::now();
- timeout -= std::chrono::duration_cast<std::chrono::milliseconds>(
+ timeout -= std::chrono::duration_cast<std::chrono::microseconds>(
current_time - prev_time);
}
@@ -209,7 +299,7 @@
// Note: Although rf_packets.h doesn't document nor include packet header,
// the header is necessary to know total packet size.
Result<std::shared_ptr<std::vector<uint8_t>>> CasimirController::ReadRfPacket(
- std::chrono::milliseconds timeout) {
+ std::chrono::microseconds timeout) {
auto start_time = std::chrono::steady_clock::now();
auto res = CF_EXPECT(ReadExact(sizeof(uint16_t), timeout),
@@ -218,7 +308,7 @@
int16_t packet_size = packet_size_slice.read_le<uint16_t>();
auto current_time = std::chrono::steady_clock::now();
- timeout -= std::chrono::duration_cast<std::chrono::milliseconds>(
+ timeout -= std::chrono::duration_cast<std::chrono::microseconds>(
current_time - start_time);
return CF_EXPECT(ReadExact(packet_size, timeout),
"Failed to read RF packet payload");
diff --git a/host/commands/casimir_control_server/casimir_controller.h b/host/commands/casimir_control_server/casimir_controller.h
index 3603cd7..6ca7781 100644
--- a/host/commands/casimir_control_server/casimir_controller.h
+++ b/host/commands/casimir_control_server/casimir_controller.h
@@ -38,6 +38,11 @@
Result<void> SetPowerLevel(uint32_t power_level);
+ Result<std::tuple<std::vector<uint8_t>, std::string, bool, uint32_t, uint32_t,
+ uint32_t, double>>
+ SendBroadcast(std::vector<uint8_t> data, std::string type, bool crc,
+ uint8_t bits, uint32_t bitrate, uint32_t timeout, double power);
+
/*
* Poll for NFC-A + ISO-DEP
*/
@@ -61,9 +66,9 @@
Result<void> Write(const RfPacketBuilder& rf_packet);
Result<std::shared_ptr<std::vector<uint8_t>>> ReadExact(
- size_t size, std::chrono::milliseconds timeout);
+ size_t size, std::chrono::microseconds timeout);
Result<std::shared_ptr<std::vector<uint8_t>>> ReadRfPacket(
- std::chrono::milliseconds timeout);
+ std::chrono::microseconds timeout);
SharedFD sock_;
uint8_t power_level;
diff --git a/host/commands/casimir_control_server/crc.cpp b/host/commands/casimir_control_server/crc.cpp
new file mode 100644
index 0000000..09939af
--- /dev/null
+++ b/host/commands/casimir_control_server/crc.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2023 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.
+ */
+
+#include "host/commands/casimir_control_server/crc.h"
+
+#include "common/libs/utils/result.h"
+
+namespace cuttlefish {
+
+namespace {
+static std::vector<uint8_t> Crc16(const std::vector<uint8_t>& data,
+ uint16_t initial, bool invert) {
+ uint16_t w_crc = initial;
+
+ for (uint8_t byte : data) {
+ byte ^= (w_crc & 0x00FF);
+ byte ^= (byte << 4) & 0xFF;
+ w_crc = (w_crc >> 8) ^ ((byte << 8) & 0xFFFF) ^ ((byte << 3) & 0xFFFF) ^
+ ((byte >> 4) & 0xFFFF);
+ }
+
+ if (invert) {
+ w_crc = ~w_crc;
+ }
+
+ return {static_cast<uint8_t>(w_crc & 0xFF),
+ static_cast<uint8_t>((w_crc >> 8) & 0xFF)};
+}
+
+static std::vector<uint8_t> Crc16A(const std::vector<uint8_t>& data) {
+ return Crc16(data, 0x6363, false);
+}
+
+static std::vector<uint8_t> Crc16B(const std::vector<uint8_t>& data) {
+ return Crc16(data, 0xFFFF, true);
+}
+} // namespace
+
+Result<std::vector<uint8_t>> WithCrc16A(const std::vector<uint8_t>& data) {
+ std::vector<uint8_t> newData = data;
+ std::vector<uint8_t> crc = Crc16A(newData);
+ newData.insert(newData.end(), crc.begin(), crc.end());
+ return newData;
+}
+
+Result<std::vector<uint8_t>> WithCrc16B(const std::vector<uint8_t>& data) {
+ std::vector<uint8_t> newData = data;
+ std::vector<uint8_t> crc = Crc16B(newData);
+ newData.insert(newData.end(), crc.begin(), crc.end());
+ return newData;
+}
+
+} // namespace cuttlefish
diff --git a/host/commands/casimir_control_server/crc.h b/host/commands/casimir_control_server/crc.h
new file mode 100644
index 0000000..da1e8fb
--- /dev/null
+++ b/host/commands/casimir_control_server/crc.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2023 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.
+ */
+
+#pragma once
+
+#include "common/libs/utils/result.h"
+
+namespace cuttlefish {
+
+Result<std::vector<uint8_t>> WithCrc16A(const std::vector<uint8_t>& data);
+Result<std::vector<uint8_t>> WithCrc16B(const std::vector<uint8_t>& data);
+
+} // namespace cuttlefish
diff --git a/host/commands/casimir_control_server/main.cpp b/host/commands/casimir_control_server/main.cpp
index 6a0f44a..4adcd2e 100644
--- a/host/commands/casimir_control_server/main.cpp
+++ b/host/commands/casimir_control_server/main.cpp
@@ -35,7 +35,10 @@
using casimircontrolserver::RadioState;
using casimircontrolserver::SendApduReply;
using casimircontrolserver::SendApduRequest;
+using casimircontrolserver::SendBroadcastRequest;
+using casimircontrolserver::SendBroadcastResponse;
using casimircontrolserver::SenderId;
+using casimircontrolserver::TransceiveConfiguration;
using casimircontrolserver::Void;
using cuttlefish::CasimirController;
@@ -218,6 +221,69 @@
return ResultToStatus(SendApduResult(request, response));
}
+ Result<void> SendBroadcastResult(const SendBroadcastRequest* request,
+ SendBroadcastResponse* response) {
+ // Default configuration values
+ TransceiveConfiguration requestConfig;
+ // Type A
+ requestConfig.set_type("A");
+ // CRC present
+ requestConfig.set_crc(true);
+ // 8 bits in last byte
+ requestConfig.set_bits(8);
+ // 106kbps
+ requestConfig.set_bitrate(106);
+ // No timeout, timeout immediately
+ requestConfig.clear_timeout();
+ // 100% output power
+ requestConfig.set_power(100);
+
+ // Overwrite defaults with provided configuration, if present
+ if (request->has_configuration()) {
+ auto config = request->configuration();
+ if (config.has_type()) {
+ requestConfig.set_type(config.type());
+ }
+ if (config.has_crc()) {
+ requestConfig.set_crc(config.crc());
+ }
+ if (config.has_bits()) {
+ requestConfig.set_bits(config.bits());
+ }
+ if (config.has_bitrate()) {
+ requestConfig.set_bitrate(config.bitrate());
+ }
+ if (config.has_timeout()) {
+ requestConfig.set_timeout(config.timeout());
+ }
+ if (config.has_power()) {
+ requestConfig.set_power(config.power());
+ }
+ }
+
+ if (!device_.has_value()) {
+ device_ = CF_EXPECT(ConnectToCasimir(), "Failed to connect with casimir");
+ CF_EXPECT(Unmute(), "failed to unmute the device");
+ }
+
+ std::vector<uint8_t> requestData =
+ CF_EXPECT(HexToBytes(request->data()),
+ "Failed to parse input. Must only contain [0-9a-fA-F]");
+
+ CF_EXPECT(device_->SendBroadcast(
+ requestData, requestConfig.type(), requestConfig.crc(),
+ requestConfig.bits(), requestConfig.bitrate(),
+ requestConfig.timeout(), requestConfig.power()),
+ "Failed to send broadcast data");
+
+ return {}; // Success
+ }
+
+ Status SendBroadcast(ServerContext*, const SendBroadcastRequest* request,
+ SendBroadcastResponse* response) override {
+ return ResultToStatus(SendBroadcastResult(request, response));
+ }
+
std::optional<CasimirController> device_;
bool is_radio_on_ = false;
};
diff --git a/host/commands/host_bugreport/main.cc b/host/commands/host_bugreport/main.cc
index f37d209..b4dcb4d 100644
--- a/host/commands/host_bugreport/main.cc
+++ b/host/commands/host_bugreport/main.cc
@@ -34,6 +34,7 @@
#include "ziparchive/zip_writer.h"
DEFINE_string(output, "host_bugreport.zip", "Where to write the output");
+DEFINE_bool(include_adb_bugreport, false, "Includes device's `adb bugreport`.");
namespace cuttlefish {
namespace {
@@ -188,7 +189,7 @@
}
}
- {
+ if (FLAGS_include_adb_bugreport) {
// TODO(b/359657254) Create the `adb bugreport` asynchronously.
std::string device_br_dir = TempDir() + "/cvd_dbrXXXXXX";
CF_EXPECTF(mkdtemp(device_br_dir.data()) != nullptr,
diff --git a/host/frontend/webrtc/html_client/client.html b/host/frontend/webrtc/html_client/client.html
index dfecac2..4614758 100644
--- a/host/frontend/webrtc/html_client/client.html
+++ b/host/frontend/webrtc/html_client/client.html
@@ -213,13 +213,13 @@
<div>
<div id='keyboard-prompt-text' class='keyboard-text'>
<div class='function-key-button'>
- <button id='shift-button' title='Shift' class='modal-button-highlight'>Shift</button>
- <button id='alt-button' title='Alt' class='modal-button-highlight'>Alt</button>
- <button id='ctrl-button' title='Ctrl' class='modal-button-highlight'>Ctrl</button>
+ <button id='shift-button' title='Shift' class='modal-button'>Shift</button>
+ <button id='alt-button' title='Alt' class='modal-button'>Alt</button>
+ <button id='ctrl-button' title='Ctrl' class='modal-button'>Ctrl</button>
</div>
<hr>
<div class='keyboard-button'>
- <button id='tab-button' title='Tab' class='modal-button-highlight'>Tab</button>
+ <button id='tab-button' title='Tab' class='modal-button'>Tab</button>
</div>
</div>
</div>
diff --git a/host/frontend/webrtc/html_client/js/keyboard.js b/host/frontend/webrtc/html_client/js/keyboard.js
index 3a3499e..4175205 100644
--- a/host/frontend/webrtc/html_client/js/keyboard.js
+++ b/host/frontend/webrtc/html_client/js/keyboard.js
@@ -25,7 +25,6 @@
dc.sendKeyEvent(keyCode, "keyup");
}
let button = document.getElementById(buttonName);
- button.disabled = false;
button.addEventListener('mousedown', onMouseDown);
button.addEventListener('mouseup', onMouseUp);
}
@@ -33,18 +32,21 @@
function processToggleButton(buttonName, keyCode, dc) {
let toggle = false;
function onMouseDown(evt) {
+ const kPrimaryButton = 1;
+ if ((evt.buttons & kPrimaryButton) == 0) {
+ return;
+ }
toggle = !toggle;
- if (toggle) dc.sendKeyEvent(keyCode, "keydown");
- else dc.sendKeyEvent(keyCode, "keyup");
+ if (toggle) {
+ dc.sendKeyEvent(keyCode, "keydown");
+ } else {
+ dc.sendKeyEvent(keyCode, "keyup");
+ }
this.classList.toggle('active');
}
- function onMouseUp(evt) {
- }
let button = document.getElementById(buttonName);
- button.disabled = false;
button.addEventListener('mousedown', onMouseDown);
- button.addEventListener('mouseup', onMouseUp);
}
function enableKeyboardRewriteButton(dc) {
diff --git a/host/frontend/webrtc/html_client/style.css b/host/frontend/webrtc/html_client/style.css
index 44d3aab..c485bc6 100644
--- a/host/frontend/webrtc/html_client/style.css
+++ b/host/frontend/webrtc/html_client/style.css
@@ -22,12 +22,14 @@
--alert-bg: #927836; /* dark yellow */
--info-bg: #007000; /* dark green */
--modal-bg: #5f6368ea; /* Semi-transparent Google grey 500 */
- --modal-button-bg: #e8eaed; /* Google grey 200 */
+ --modal-button-bg: #efefef; /* Google grey 200 */
--modal-button-shadow: #444444;
- --modal-button-fg: black;
+ --modal-button-fg: #434343;
--modal-button-border: black;
--modal-button-invalid-border: red;
--modal-button-highlight-bg: #f4cccc; /* light red */
+ --modal-button-toggled-bg: #d9ead3ff; /* light green */
+ --modal-button-toggled-color: #274e13; /* dark green */
--modal-padding: 20px;
--bt-label-fg: green;
--bt-label-invalid-fg: red;
@@ -50,12 +52,14 @@
--alert-bg: #f3ef9e; /* light yellow */
--info-bg: #a5d5a5; /* light green */
--modal-bg: #d9d9d9ea; /* Semi-transparent Google grey 200 */
- --modal-button-bg: #7b7b7b; /* Google grey 500 */
+ --modal-button-bg: #666666; /* Google grey 500 */
--modal-button-shadow: #666666;
- --modal-button-fg: #fafafa;
+ --modal-button-fg: #efefef;
--modal-button-border: #c4c4c4; /* Google grey 300 */
--modal-button-invalid-border: #c3413d; /*light red */
--modal-button-highlight-bg: #a05555; /* dark red-ish */
+ --modal-button-toggled-bg: #d9ead3ff; /* light green */
+ --modal-button-toggled-color: #274e13; /* dark green */
--bt-label-fg: green;
--bt-label-invalid-fg: #c3413d; /* light red */
--bt-action-bg: transparent;
@@ -182,7 +186,6 @@
background-color: transparent;
}
.modal-button, .modal-button-highlight {
- background: var(--modal-button-bg);
border-radius: 10px;
box-shadow: 1px 1px var(--modal-button-shadow);
padding: 10px 20px;
@@ -190,6 +193,17 @@
display: inline-block;
font: normal bold 14px/1 "Open Sans", sans-serif;
text-align: center;
+ cursor: pointer;
+}
+.modal-button {
+ background: var(--modal-button-bg);
+}
+.modal-button-highlight {
+ background: var(--modal-button-highlight-bg);
+}
+.modal-button.active, .modal-button-highlight.active {
+ background-color: var(--modal-button-toggled-bg);
+ color: var(--modal-button-toggled-color);
}
#bluetooth-wizard-mac:valid {
border: 2px solid var(--modal-button-border);
@@ -207,12 +221,6 @@
content: 'OK';
color: var(--bt-label-fg);
}
-.modal-button {
- background: var(--modal-button-bg);
-}
-.modal-button-highlight {
- background: var(--modal-button-highlight-bg);
-}
#device-details-modal span {
white-space: pre;
}
@@ -267,33 +275,6 @@
.location-button {
text-align: center;
}
-#shift-button {
- padding: 10px 20px;
- border: 1px solid #ccc;
- cursor: pointer;
-}
-#shift-button.active {
- background-color: #0000ff;
- color: white;
-}
-#ctrl-button {
- padding: 10px 20px;
- border: 1px solid #ccc;
- cursor: pointer;
-}
-#ctrl-button.active {
- background-color: #0000ff;
- color: white;
-}
-#alt-button {
- padding: 10px 20px;
- border: 1px solid #ccc;
- cursor: pointer;
-}
-#alt-button.active {
- background-color: #0000ff;
- color: white;
-}
.sensors{
position: sticky;
right: 0;
diff --git a/shared/BoardConfig.mk b/shared/BoardConfig.mk
index 3a1e535..01941d5 100644
--- a/shared/BoardConfig.mk
+++ b/shared/BoardConfig.mk
@@ -116,10 +116,7 @@
endif
endif
-# TODO(b/170639028): Back up TARGET_NO_BOOTLOADER
-__TARGET_NO_BOOTLOADER := $(TARGET_NO_BOOTLOADER)
include build/make/target/board/BoardConfigMainlineCommon.mk
-TARGET_NO_BOOTLOADER := $(__TARGET_NO_BOOTLOADER)
# For now modules are only blocked in second stage init.
# If a module ever needs to blocked in first stage init - add a new blocklist to
diff --git a/shared/auto/sepolicy/vhal/hal_vehicle_default.te b/shared/auto/sepolicy/vhal/hal_vehicle_default.te
index 545a76d..6b5b3aa 100644
--- a/shared/auto/sepolicy/vhal/hal_vehicle_default.te
+++ b/shared/auto/sepolicy/vhal/hal_vehicle_default.te
@@ -2,4 +2,7 @@
carwatchdog_client_domain(hal_vehicle_default)
binder_use(hal_vehicle_default)
+starting_at_board_api(202504, `
+typeattribute hal_vehicle_default unconstrained_vsock_violators;
+')
allow hal_vehicle_default self:vsock_socket { create connect getopt getattr read write shutdown };
diff --git a/shared/camera/sepolicy/hal_camera_default.te b/shared/camera/sepolicy/hal_camera_default.te
index 8783a44..0bc9ebd 100644
--- a/shared/camera/sepolicy/hal_camera_default.te
+++ b/shared/camera/sepolicy/hal_camera_default.te
@@ -10,6 +10,9 @@
hal_client_domain(hal_camera_default, hal_thermal)
# Vsocket camera
+starting_at_board_api(202504, `
+typeattribute hal_camera_default unconstrained_vsock_violators;
+')
allow hal_camera_default self:vsock_socket { accept bind create getopt listen read write };
set_prop(hal_camera_default, vendor_camera_prop)
diff --git a/shared/graphics/sepolicy/hal_graphics_composer_default.te b/shared/graphics/sepolicy/hal_graphics_composer_default.te
index 643c2d9..5626e72 100644
--- a/shared/graphics/sepolicy/hal_graphics_composer_default.te
+++ b/shared/graphics/sepolicy/hal_graphics_composer_default.te
@@ -7,6 +7,11 @@
allow hal_graphics_composer_default hal_graphics_mapper_service:service_manager find;
+# inherited from attribute hal_graphics_composer_server
+starting_at_board_api(202504, `
+typeattribute hal_graphics_composer_default unconstrained_vsock_violators;
+')
+
# Suppress warnings for drm_hwcomposer trying to read some vendor.hwc.*
# properties as Cuttlefish never configures these properties.
-dontaudit hal_graphics_composer_default default_prop:file read;
\ No newline at end of file
+dontaudit hal_graphics_composer_default default_prop:file read;
diff --git a/shared/sepolicy/product/private/tombstone_transmit.te b/shared/sepolicy/product/private/tombstone_transmit.te
index 289be52..6b0d8cf 100644
--- a/shared/sepolicy/product/private/tombstone_transmit.te
+++ b/shared/sepolicy/product/private/tombstone_transmit.te
@@ -9,4 +9,5 @@
allow tombstone_transmit self:capability net_admin;
r_dir_file(tombstone_transmit, tombstone_data_file)
+typeattribute tombstone_transmit unconstrained_vsock_violators;
allow tombstone_transmit self:{ vsock_socket } create_socket_perms_no_ioctl;
diff --git a/shared/sepolicy/system_ext/private/secure_storage_system.te b/shared/sepolicy/system_ext/private/secure_storage_system.te
index 4d7e653..8b85e09 100644
--- a/shared/sepolicy/system_ext/private/secure_storage_system.te
+++ b/shared/sepolicy/system_ext/private/secure_storage_system.te
@@ -28,6 +28,7 @@
#============= storageproxyd_system ==============
type storageproxyd_system, domain, coredomain;
+typeattribute storageproxyd_system unconstrained_vsock_violators;
type storageproxyd_system_exec, exec_type, system_file_type, file_type;
type secure_storage_persist_system_file, file_type, data_file_type, core_data_file_type;
type secure_storage_system_file, file_type, data_file_type, core_data_file_type;
diff --git a/shared/sepolicy/vendor/hal_light_cuttlefish.te b/shared/sepolicy/vendor/hal_light_cuttlefish.te
index e02f8e0..56ef539 100644
--- a/shared/sepolicy/vendor/hal_light_cuttlefish.te
+++ b/shared/sepolicy/vendor/hal_light_cuttlefish.te
@@ -4,4 +4,7 @@
type hal_light_cuttlefish_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(hal_light_cuttlefish)
+starting_at_board_api(202504, `
+typeattribute hal_light_cuttlefish unconstrained_vsock_violators;
+')
allow hal_light_cuttlefish self:{ socket vsock_socket } { create_socket_perms_no_ioctl listen accept };
diff --git a/shared/sepolicy/vendor/socket_vsock_proxy.te b/shared/sepolicy/vendor/socket_vsock_proxy.te
index 6f72963..65f5409 100644
--- a/shared/sepolicy/vendor/socket_vsock_proxy.te
+++ b/shared/sepolicy/vendor/socket_vsock_proxy.te
@@ -6,6 +6,9 @@
allow socket_vsock_proxy self:global_capability_class_set { net_admin net_raw };
allow socket_vsock_proxy self:{ socket vsock_socket } { create getopt read write getattr listen accept bind shutdown };
+starting_at_board_api(202504, `
+typeattribute socket_vsock_proxy unconstrained_vsock_violators;
+')
# TODO: socket returned by accept() has unlabeled context on it. Give it a
# specific label.
allow socket_vsock_proxy unlabeled:{ socket vsock_socket } { getopt read write shutdown };
diff --git a/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te b/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te
index 6e2958e..a1e52a3 100644
--- a/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te
+++ b/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te
@@ -10,5 +10,8 @@
get_prop(libcuttlefish_rild, vendor_modem_simulator_ports_prop)
+starting_at_board_api(202504, `
+typeattribute libcuttlefish_rild unconstrained_vsock_violators;
+')
allow libcuttlefish_rild self:{ socket vsock_socket } { create_socket_perms_no_ioctl getattr };
-allow libcuttlefish_rild su:{ socket udp_socket } { create_socket_perms_no_ioctl getattr };
\ No newline at end of file
+allow libcuttlefish_rild su:{ socket udp_socket } { create_socket_perms_no_ioctl getattr };
diff --git a/vsoc_arm/bootloader.mk b/vsoc_arm/bootloader.mk
index ce29443..aa9f9a6 100644
--- a/vsoc_arm/bootloader.mk
+++ b/vsoc_arm/bootloader.mk
@@ -14,7 +14,5 @@
# limitations under the License.
#
-TARGET_NO_BOOTLOADER := false
-# FIXME: Copying the QEMU bootloader for now, but this should be updated..
-BOARD_PREBUILT_BOOTLOADER := \
- device/google/cuttlefish_prebuilts/bootloader/crosvm_aarch64/u-boot.bin
+# May be booted using different bootloaders, so don't have the single one.
+TARGET_NO_BOOTLOADER := true
diff --git a/vsoc_arm64/bootloader.mk b/vsoc_arm64/bootloader.mk
index ce29443..aa9f9a6 100644
--- a/vsoc_arm64/bootloader.mk
+++ b/vsoc_arm64/bootloader.mk
@@ -14,7 +14,5 @@
# limitations under the License.
#
-TARGET_NO_BOOTLOADER := false
-# FIXME: Copying the QEMU bootloader for now, but this should be updated..
-BOARD_PREBUILT_BOOTLOADER := \
- device/google/cuttlefish_prebuilts/bootloader/crosvm_aarch64/u-boot.bin
+# May be booted using different bootloaders, so don't have the single one.
+TARGET_NO_BOOTLOADER := true
diff --git a/vsoc_arm_minidroid/bootloader.mk b/vsoc_arm_minidroid/bootloader.mk
index 959cd61..aa9f9a6 100644
--- a/vsoc_arm_minidroid/bootloader.mk
+++ b/vsoc_arm_minidroid/bootloader.mk
@@ -14,7 +14,5 @@
# limitations under the License.
#
-TARGET_NO_BOOTLOADER := false
-# FIXME: Copying the QEMU bootloader for now, but this should be updated..
-BOARD_PREBUILT_BOOTLOADER := \
- device/google/cuttlefish_prebuilts/bootloader/qemu_arm/u-boot.bin
+# May be booted using different bootloaders, so don't have the single one.
+TARGET_NO_BOOTLOADER := true
diff --git a/vsoc_riscv64/bootloader.mk b/vsoc_riscv64/bootloader.mk
index 427531b..4866ad3 100644
--- a/vsoc_riscv64/bootloader.mk
+++ b/vsoc_riscv64/bootloader.mk
@@ -14,7 +14,5 @@
# limitations under the License.
#
-TARGET_NO_BOOTLOADER := false
-# Only QEMU is supported for now
-BOARD_PREBUILT_BOOTLOADER := \
- device/google/cuttlefish_prebuilts/bootloader/qemu_riscv64/u-boot.bin
+# May be booted using different bootloaders, so don't have the single one.
+TARGET_NO_BOOTLOADER := true
diff --git a/vsoc_x86/go/aosp_cf.mk b/vsoc_x86/go/aosp_cf.mk
index 05bdc38..6dd038e 100644
--- a/vsoc_x86/go/aosp_cf.mk
+++ b/vsoc_x86/go/aosp_cf.mk
@@ -25,7 +25,6 @@
# These packages come from go_defaults.mk
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
system/apex/com.android.tethering.capex \
- system/app/PlatformCaptivePortalLogin/PlatformCaptivePortalLogin.apk \
system/etc/permissions/platform_privapp_allowlist_com.android.cellbroadcastservice.xml \
system/priv-app/CellBroadcastServiceModulePlatform/CellBroadcastServiceModulePlatform.apk \
diff --git a/vsoc_x86_64/bootloader.mk b/vsoc_x86_64/bootloader.mk
index 6294ca7..aa9f9a6 100644
--- a/vsoc_x86_64/bootloader.mk
+++ b/vsoc_x86_64/bootloader.mk
@@ -14,6 +14,5 @@
# limitations under the License.
#
-TARGET_NO_BOOTLOADER := false
-BOARD_PREBUILT_BOOTLOADER := \
- device/google/cuttlefish_prebuilts/bootloader/crosvm_x86_64/u-boot.rom
+# May be booted using different bootloaders, so don't have the single one.
+TARGET_NO_BOOTLOADER := true