Merge "Delete cutf hwcomposer" into sc-dev
diff --git a/common/libs/utils/subprocess.cpp b/common/libs/utils/subprocess.cpp
index 089b2e4..c9d676a 100644
--- a/common/libs/utils/subprocess.cpp
+++ b/common/libs/utils/subprocess.cpp
@@ -157,14 +157,6 @@
}
return true;
}
-Command::ParameterBuilder::~ParameterBuilder() { Build(); }
-void Command::ParameterBuilder::Build() {
- auto param = stream_.str();
- stream_ = std::stringstream();
- if (param.size()) {
- cmd_->AddParameter(param);
- }
-}
Command::~Command() {
// Close all inherited file descriptors
diff --git a/common/libs/utils/subprocess.h b/common/libs/utils/subprocess.h
index 7d2c0f7..0eb2bcc 100644
--- a/common/libs/utils/subprocess.h
+++ b/common/libs/utils/subprocess.h
@@ -119,25 +119,6 @@
}
public:
- class ParameterBuilder {
- public:
- ParameterBuilder(Command* cmd) : cmd_(cmd){};
- ParameterBuilder(ParameterBuilder&& builder) = default;
- ~ParameterBuilder();
-
- template <typename T>
- ParameterBuilder& operator<<(T t) {
- cmd_->BuildParameter(&stream_, t);
- return *this;
- }
-
- void Build();
-
- private:
- Command* cmd_;
- std::stringstream stream_;
- };
-
// Constructs a command object from the path to an executable binary and an
// optional subprocess stopper. When not provided, stopper defaults to sending
// SIGKILL to the subprocess.
@@ -190,8 +171,6 @@
return false;
}
- ParameterBuilder GetParameterBuilder() { return ParameterBuilder(this); }
-
// Redirects the standard IO of the command.
bool RedirectStdIO(Subprocess::StdIOChannel channel, SharedFD shared_fd);
bool RedirectStdIO(Subprocess::StdIOChannel subprocess_channel,
diff --git a/guest/hals/keymint/remote/remote_keymint_device.cpp b/guest/hals/keymint/remote/remote_keymint_device.cpp
index fbf2568..c9171c8 100644
--- a/guest/hals/keymint/remote/remote_keymint_device.cpp
+++ b/guest/hals/keymint/remote/remote_keymint_device.cpp
@@ -407,6 +407,12 @@
return kmError2ScopedAStatus(response.error);
}
+ScopedAStatus RemoteKeyMintDevice::convertStorageKeyToEphemeral(
+ const std::vector<uint8_t>& /* storageKeyBlob */,
+ std::vector<uint8_t>* /* ephemeralKeyBlob */) {
+ return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
+}
+
ScopedAStatus RemoteKeyMintDevice::performOperation(
const vector<uint8_t>& /* request */, vector<uint8_t>* /* response */) {
return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
diff --git a/guest/hals/keymint/remote/remote_keymint_device.h b/guest/hals/keymint/remote/remote_keymint_device.h
index c4e840e..7f289b4 100644
--- a/guest/hals/keymint/remote/remote_keymint_device.h
+++ b/guest/hals/keymint/remote/remote_keymint_device.h
@@ -73,6 +73,10 @@
const optional<TimeStampToken>& timestampToken) override;
ScopedAStatus earlyBootEnded() override;
+ ScopedAStatus convertStorageKeyToEphemeral(
+ const std::vector<uint8_t>& storageKeyBlob,
+ std::vector<uint8_t>* ephemeralKeyBlob) override;
+
ScopedAStatus performOperation(const vector<uint8_t>& request,
vector<uint8_t>* response) override;
diff --git a/guest/hals/ril/reference-libril/ril.h b/guest/hals/ril/reference-libril/ril.h
index 8942bcc..586de42 100644
--- a/guest/hals/ril/reference-libril/ril.h
+++ b/guest/hals/ril/reference-libril/ril.h
@@ -7537,7 +7537,14 @@
*/
#define RIL_REQUEST_GET_SLICING_CONFIG 169
-#define RIL_REQUEST_LAST RIL_REQUEST_GET_SLICING_CONFIG
+#define RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS 170
+
+#define RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY 171
+
+#define RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORDS 172
+
+
+#define RIL_REQUEST_LAST RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORDS
/***********************************************************************/
diff --git a/guest/hals/ril/reference-libril/ril_commands.h b/guest/hals/ril/reference-libril/ril_commands.h
index 4cb950b..81629b0 100644
--- a/guest/hals/ril/reference-libril/ril_commands.h
+++ b/guest/hals/ril/reference-libril/ril_commands.h
@@ -183,5 +183,7 @@
{RIL_REQUEST_SET_DATA_THROTTLING, radio_1_6::setDataThrottlingResponse},
{RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS, radio_1_6::getSystemSelectionChannelsResponse},
{RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP, radio_1_6::getAllowedNetworkTypesBitmapResponse},
- {RIL_REQUEST_GET_SLICING_CONFIG, radio_1_6::getSlicingConfigResponse}
-
+ {RIL_REQUEST_GET_SLICING_CONFIG, radio_1_6::getSlicingConfigResponse},
+ {RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS, radio_1_6::getSimPhonebookRecordsResponse},
+ {RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY, radio_1_6::getSimPhonebookCapacityResponse},
+ {RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORDS, radio_1_6::updateSimPhonebookRecordsResponse}
diff --git a/guest/hals/ril/reference-libril/ril_service.cpp b/guest/hals/ril/reference-libril/ril_service.cpp
index 635d48f..848d4dd 100644
--- a/guest/hals/ril/reference-libril/ril_service.cpp
+++ b/guest/hals/ril/reference-libril/ril_service.cpp
@@ -646,6 +646,11 @@
Return<void> setCarrierInfoForImsiEncryption_1_6(
int32_t serial,
const ::android::hardware::radio::V1_6::ImsiEncryptionInfo& imsiEncryptionInfo);
+ Return<void> getSimPhonebookRecords(int32_t serial);
+ Return<void> getSimPhonebookCapacity(int32_t serial);
+ Return<void> updateSimPhonebookRecords(
+ int32_t serial,
+ const ::android::hardware::radio::V1_6::PhonebookRecordInfo& recordInfo);
};
struct OemHookImpl : public IOemHook {
@@ -4696,6 +4701,34 @@
return Void();
}
+
+Return<void> RadioImpl_1_6::getSimPhonebookRecords(int32_t serial) {
+#if VDBG
+ RLOGD("getSimPhonebookRecords: serial %d", serial);
+#endif
+ dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS);
+ return Void();
+}
+
+Return<void> RadioImpl_1_6::getSimPhonebookCapacity(int32_t serial) {
+#if VDBG
+ RLOGD("getSimPhonebookCapacity: serial %d", serial);
+#endif
+ dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY);
+ return Void();
+}
+
+Return<void> RadioImpl_1_6::updateSimPhonebookRecords(
+ int32_t serial,
+ const ::android::hardware::radio::V1_6::PhonebookRecordInfo& recordInfo) {
+#if VDBG
+ RLOGD("updateSimPhonebookRecords: serial %d", serial);
+#endif
+ dispatchVoid(serial, mSlotId, RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORDS);
+ return Void();
+}
+
+
// OEM hook methods:
Return<void> OemHookImpl::setResponseFunctions(
const ::android::sp<IOemHookResponse>& oemHookResponseParam,
@@ -10303,6 +10336,31 @@
return 0;
}
+
+int radio_1_6::getSimPhonebookRecordsResponse(int slotId, int responseType, int serial,
+ RIL_Errno e, void *response, size_t responseLen) {
+#if VDBG
+ RLOGD("getSimPhonebookRecordsResponse: serial %d", serial);
+#endif
+ return 0;
+}
+
+int radio_1_6::getSimPhonebookCapacityResponse(int slotId, int responseType, int serial,
+ RIL_Errno e, void *response, size_t responseLen) {
+#if VDBG
+ RLOGD("getSimPhonebookRecordsResponse: serial %d", serial);
+#endif
+ return 0;
+}
+
+int radio_1_6::updateSimPhonebookRecordsResponse(int slotId, int responseType, int serial,
+ RIL_Errno e, void *response, size_t responseLen) {
+#if VDBG
+ RLOGD("getSimPhonebookRecordsResponse: serial %d", serial);
+#endif
+ return 0;
+}
+
/***************************************************************************************************
* INDICATION FUNCTIONS
* The below function handle unsolicited messages coming from the Radio
diff --git a/guest/hals/ril/reference-libril/ril_service.h b/guest/hals/ril/reference-libril/ril_service.h
index 85bd091..30c7b69 100644
--- a/guest/hals/ril/reference-libril/ril_service.h
+++ b/guest/hals/ril/reference-libril/ril_service.h
@@ -821,6 +821,15 @@
int getSlicingConfigResponse(int slotId, int responseType, int serial,
RIL_Errno e, void *response, size_t responseLen);
+int getSimPhonebookRecordsResponse(int slotId, int responseType, int serial,
+ RIL_Errno e, void *response, size_t responseLen);
+
+int getSimPhonebookCapacityResponse(int slotId, int responseType, int serial,
+ RIL_Errno e, void *response, size_t responseLen);
+
+int updateSimPhonebookRecordsResponse(int slotId, int responseType, int serial,
+ RIL_Errno e, void *response, size_t responseLen);
+
pthread_rwlock_t * getRadioServiceRwlock(int slotId);
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index d285d84..bfb856b 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -704,9 +704,8 @@
instance.set_device_title(FLAGS_device_title);
if (FLAGS_protected_vm) {
- instance.set_virtual_disk_paths({
- const_instance.PerInstancePath("composite.img")
- });
+ instance.set_virtual_disk_paths(
+ {const_instance.PerInstancePath("os_composite.img")});
} else {
std::vector<std::string> virtual_disk_paths = {
const_instance.PerInstancePath("overlay.img"),
diff --git a/host/commands/run_cvd/launch.cc b/host/commands/run_cvd/launch.cc
index a2432e1..1599fe0 100644
--- a/host/commands/run_cvd/launch.cc
+++ b/host/commands/run_cvd/launch.cc
@@ -155,8 +155,7 @@
std::vector<SharedFD> ret;
if (number_of_event_pipes > 0) {
- auto param_builder = command.GetParameterBuilder();
- param_builder << "-subscriber_fds=";
+ command.AddParameter("-subscriber_fds=");
for (unsigned int i = 0; i < number_of_event_pipes; ++i) {
SharedFD event_pipe_write_end, event_pipe_read_end;
if (!SharedFD::Pipe(&event_pipe_read_end, &event_pipe_write_end)) {
@@ -164,12 +163,11 @@
std::exit(RunnerExitCodes::kPipeIOError);
}
if (i > 0) {
- param_builder << ",";
+ command.AppendToLastParameter(",");
}
- param_builder << event_pipe_write_end;
+ command.AppendToLastParameter(event_pipe_write_end);
ret.push_back(event_pipe_read_end);
}
- param_builder.Build();
}
process_monitor->AddCommand(std::move(command));
@@ -434,8 +432,7 @@
auto instance = config.ForDefaultInstance();
auto ports = instance.modem_simulator_ports();
- auto param_builder = cmd.GetParameterBuilder();
- param_builder << "-server_fds=";
+ cmd.AddParameter("-server_fds=");
for (int i = 0; i < instance_number; ++i) {
auto pos = ports.find(',');
auto temp = (pos != std::string::npos) ? ports.substr(0, pos - 1) : ports;
@@ -449,11 +446,10 @@
std::exit(RunnerExitCodes::kModemSimulatorServerError);
}
if (i > 0) {
- param_builder << ",";
+ cmd.AppendToLastParameter(",");
}
- param_builder << socket;
+ cmd.AppendToLastParameter(socket);
}
- param_builder.Build();
process_monitor->AddCommand(std::move(cmd));
}
diff --git a/host/frontend/webrtc/connection_observer.cpp b/host/frontend/webrtc/connection_observer.cpp
index 3be8fa4..a8613e6 100644
--- a/host/frontend/webrtc/connection_observer.cpp
+++ b/host/frontend/webrtc/connection_observer.cpp
@@ -236,42 +236,62 @@
LOG(ERROR) << "Received invalid JSON object over control channel: " << errorMessage;
return;
}
- auto result =
- webrtc_streaming::ValidationResult::ValidateJsonObject(evt, "command",
- {{"command", Json::ValueType::stringValue},
- {"state", Json::ValueType::stringValue}});
+
+ auto result = webrtc_streaming::ValidationResult::ValidateJsonObject(
+ evt, "command",
+ /*required_fields=*/{{"command", Json::ValueType::stringValue}},
+ /*optional_fields=*/
+ {
+ {"button_state", Json::ValueType::stringValue},
+ {"lid_switch_open", Json::ValueType::booleanValue},
+ {"hinge_angle_value", Json::ValueType::intValue},
+ });
if (!result.ok()) {
LOG(ERROR) << result.error();
return;
}
auto command = evt["command"].asString();
- auto state = evt["state"].asString();
- LOG(VERBOSE) << "Control command: " << command << " (" << state << ")";
+ if (command == "device_state") {
+ if (evt.isMember("lid_switch_open")) {
+ // InputManagerService treats a value of 0 as open and 1 as closed, so
+ // invert the lid_switch_open value that is sent to the input device.
+ OnSwitchEvent(SW_LID, !evt["lid_switch_open"].asBool());
+ }
+ // TODO(b/181157794) Propagate hinge angle sensor data.
+ if (evt.isMember("hinge_angle_value")) {
+ LOG(WARNING) << "Hinge angle sensor is not yet implemented.";
+ }
+ return;
+ }
+
+ auto button_state = evt["button_state"].asString();
+ LOG(VERBOSE) << "Control command: " << command << " (" << button_state
+ << ")";
if (command == "power") {
- OnKeyboardEvent(KEY_POWER, state == "down");
+ OnKeyboardEvent(KEY_POWER, button_state == "down");
} else if (command == "home") {
- OnKeyboardEvent(KEY_HOMEPAGE, state == "down");
+ OnKeyboardEvent(KEY_HOMEPAGE, button_state == "down");
} else if (command == "menu") {
- OnKeyboardEvent(KEY_MENU, state == "down");
+ OnKeyboardEvent(KEY_MENU, button_state == "down");
} else if (command == "volumemute") {
- OnKeyboardEvent(KEY_MUTE, state == "down");
+ OnKeyboardEvent(KEY_MUTE, button_state == "down");
} else if (command == "volumedown") {
- OnKeyboardEvent(KEY_VOLUMEDOWN, state == "down");
+ OnKeyboardEvent(KEY_VOLUMEDOWN, button_state == "down");
} else if (command == "volumeup") {
- OnKeyboardEvent(KEY_VOLUMEUP, state == "down");
+ OnKeyboardEvent(KEY_VOLUMEUP, button_state == "down");
} else if (commands_to_custom_action_servers_.find(command) !=
commands_to_custom_action_servers_.end()) {
// Simple protocol for commands forwarded to action servers:
// - Always 128 bytes
- // - Format: command:state
+ // - Format: command:button_state
// - Example: my_button:down
- std::string action_server_message = command + ":" + state;
+ std::string action_server_message = command + ":" + button_state;
cuttlefish::WriteAll(commands_to_custom_action_servers_[command],
action_server_message.c_str(), 128);
} else {
- LOG(WARNING) << "Unsupported control command: " << command << " (" << state << ")";
- // TODO(b/163081337): Handle custom commands.
+ LOG(WARNING) << "Unsupported control command: " << command << " ("
+ << button_state << ")";
}
}
diff --git a/host/frontend/webrtc/lib/streamer.cpp b/host/frontend/webrtc/lib/streamer.cpp
index 31ec7fe..255ee88 100644
--- a/host/frontend/webrtc/lib/streamer.cpp
+++ b/host/frontend/webrtc/lib/streamer.cpp
@@ -55,6 +55,9 @@
constexpr auto kControlPanelButtonTitle = "title";
constexpr auto kControlPanelButtonIconName = "icon_name";
constexpr auto kControlPanelButtonShellCommand = "shell_command";
+constexpr auto kControlPanelButtonDeviceStates = "device_states";
+constexpr auto kControlPanelButtonLidSwitchOpen = "lid_switch_open";
+constexpr auto kControlPanelButtonHingeAngleValue = "hinge_angle_value";
constexpr auto kCustomControlPanelButtonsField = "custom_control_panel_buttons";
void SendJson(WsConnection* ws_conn, const Json::Value& data) {
@@ -99,6 +102,7 @@
std::string title;
std::string icon_name;
std::optional<std::string> shell_command;
+ std::vector<DeviceState> device_states;
};
// TODO (jemoreira): move to a place in common with the signaling server
@@ -231,12 +235,30 @@
impl_->hardware_.emplace(key, value);
}
-void Streamer::AddCustomControlPanelButton(
+void Streamer::AddCustomControlPanelButton(const std::string& command,
+ const std::string& title,
+ const std::string& icon_name) {
+ ControlPanelButtonDescriptor button = {
+ .command = command, .title = title, .icon_name = icon_name};
+ impl_->custom_control_panel_buttons_.push_back(button);
+}
+
+void Streamer::AddCustomControlPanelButtonWithShellCommand(
+ const std::string& command, const std::string& title,
+ const std::string& icon_name, const std::string& shell_command) {
+ ControlPanelButtonDescriptor button = {
+ .command = command, .title = title, .icon_name = icon_name};
+ button.shell_command = shell_command;
+ impl_->custom_control_panel_buttons_.push_back(button);
+}
+
+void Streamer::AddCustomControlPanelButtonWithDeviceStates(
const std::string& command, const std::string& title,
const std::string& icon_name,
- const std::optional<std::string>& shell_command) {
- ControlPanelButtonDescriptor button = {command, title, icon_name,
- shell_command};
+ const std::vector<DeviceState>& device_states) {
+ ControlPanelButtonDescriptor button = {
+ .command = command, .title = title, .icon_name = icon_name};
+ button.device_states = device_states;
impl_->custom_control_panel_buttons_.push_back(button);
}
@@ -327,6 +349,21 @@
button_entry[kControlPanelButtonIconName] = button.icon_name;
if (button.shell_command) {
button_entry[kControlPanelButtonShellCommand] = *(button.shell_command);
+ } else if (!button.device_states.empty()) {
+ Json::Value device_states(Json::arrayValue);
+ for (const DeviceState& device_state : button.device_states) {
+ Json::Value device_state_entry;
+ if (device_state.lid_switch_open) {
+ device_state_entry[kControlPanelButtonLidSwitchOpen] =
+ *device_state.lid_switch_open;
+ }
+ if (device_state.hinge_angle_value) {
+ device_state_entry[kControlPanelButtonHingeAngleValue] =
+ *device_state.hinge_angle_value;
+ }
+ device_states.append(device_state_entry);
+ }
+ button_entry[kControlPanelButtonDeviceStates] = device_states;
}
custom_control_panel_buttons.append(button_entry);
}
diff --git a/host/frontend/webrtc/lib/streamer.h b/host/frontend/webrtc/lib/streamer.h
index c9ff382..115d5cb 100644
--- a/host/frontend/webrtc/lib/streamer.h
+++ b/host/frontend/webrtc/lib/streamer.h
@@ -24,6 +24,8 @@
#include <utility>
#include <vector>
+#include "host/libs/config/custom_actions.h"
+
#include "host/frontend/webrtc/lib/audio_sink.h"
#include "host/frontend/webrtc/lib/connection_observer.h"
#include "host/frontend/webrtc/lib/local_recorder.h"
@@ -91,12 +93,16 @@
std::shared_ptr<AudioSink> AddAudioStream(const std::string& label);
// Add a custom button to the control panel.
- // If this button should be handled by an action server, use nullopt (the
- // default) for shell_command.
- void AddCustomControlPanelButton(
+ void AddCustomControlPanelButton(const std::string& command,
+ const std::string& title,
+ const std::string& icon_name);
+ void AddCustomControlPanelButtonWithShellCommand(
+ const std::string& command, const std::string& title,
+ const std::string& icon_name, const std::string& shell_command);
+ void AddCustomControlPanelButtonWithDeviceStates(
const std::string& command, const std::string& title,
const std::string& icon_name,
- const std::optional<std::string>& shell_command = std::nullopt);
+ const std::vector<DeviceState>& device_states);
// Register with the operator.
void Register(std::weak_ptr<OperatorObserver> operator_observer);
diff --git a/host/frontend/webrtc/lib/utils.cpp b/host/frontend/webrtc/lib/utils.cpp
index 117492d..78460c3 100644
--- a/host/frontend/webrtc/lib/utils.cpp
+++ b/host/frontend/webrtc/lib/utils.cpp
@@ -23,23 +23,47 @@
namespace cuttlefish {
namespace webrtc_streaming {
+namespace {
+
+std::string ValidateField(const Json::Value &obj, const std::string &type,
+ const std::string &field_name,
+ const Json::ValueType &field_type, bool required) {
+ if (!obj.isMember(field_name) && !required) {
+ return "";
+ }
+ if (!(obj.isMember(field_name) &&
+ obj[field_name].isConvertibleTo(field_type))) {
+ std::string error_msg = "Expected a field named '";
+ error_msg += field_name + "' of type '";
+ error_msg += std::to_string(field_type);
+ error_msg += "'";
+ if (!type.empty()) {
+ error_msg += " in message of type '" + type + "'";
+ }
+ error_msg += ".";
+ return error_msg;
+ }
+ return "";
+}
+
+} // namespace
+
ValidationResult ValidationResult::ValidateJsonObject(
const Json::Value &obj, const std::string &type,
- const std::map<std::string, Json::ValueType> &fields) {
- for (const auto &field_spec : fields) {
- const auto &field_name = field_spec.first;
- auto field_type = field_spec.second;
- if (!(obj.isMember(field_name) &&
- obj[field_name].isConvertibleTo(field_type))) {
- std::string error_msg = "Expected a field named '";
- error_msg += field_name + "' of type '";
- error_msg += std::to_string(field_type);
- error_msg += "'";
- if (!type.empty()) {
- error_msg += " in message of type '" + type + "'";
- }
- error_msg += ".";
- return {error_msg};
+ const std::map<std::string, Json::ValueType> &required_fields,
+ const std::map<std::string, Json::ValueType> &optional_fields) {
+ for (const auto &field_spec : required_fields) {
+ auto result =
+ ValidateField(obj, type, field_spec.first, field_spec.second, true);
+ if (!result.empty()) {
+ return {result};
+ }
+ }
+ for (const auto &field_spec : optional_fields) {
+ auto result =
+ ValidateField(obj, type, field_spec.first, field_spec.second, false);
+ if (!result.empty()) {
+ return {result};
}
}
return {};
diff --git a/host/frontend/webrtc/lib/utils.h b/host/frontend/webrtc/lib/utils.h
index 1208551..169221c 100644
--- a/host/frontend/webrtc/lib/utils.h
+++ b/host/frontend/webrtc/lib/utils.h
@@ -32,8 +32,9 @@
// Helper method to ensure a json object has the required fields convertible
// to the appropriate types.
static ValidationResult ValidateJsonObject(
- const Json::Value &obj, const std::string &type,
- const std::map<std::string, Json::ValueType> &fields);
+ const Json::Value &obj, const std::string &type,
+ const std::map<std::string, Json::ValueType> &required_fields,
+ const std::map<std::string, Json::ValueType> &optional_fields = {});
bool ok() const { return !error_.has_value(); }
std::string error() const { return error_.value_or(""); }
diff --git a/host/frontend/webrtc/main.cpp b/host/frontend/webrtc/main.cpp
index d6021a2..297c8a6 100644
--- a/host/frontend/webrtc/main.cpp
+++ b/host/frontend/webrtc/main.cpp
@@ -271,11 +271,10 @@
<< *(custom_action.shell_command);
}
const auto button = custom_action.buttons[0];
- streamer->AddCustomControlPanelButton(button.command, button.title,
- button.icon_name,
- custom_action.shell_command);
- }
- if (custom_action.server) {
+ streamer->AddCustomControlPanelButtonWithShellCommand(
+ button.command, button.title, button.icon_name,
+ *(custom_action.shell_command));
+ } else if (custom_action.server) {
if (action_server_fds.find(*(custom_action.server)) !=
action_server_fds.end()) {
LOG(INFO) << "Connecting to custom action server "
@@ -302,6 +301,15 @@
LOG(ERROR) << "Custom action server not provided as command line flag: "
<< *(custom_action.server);
}
+ } else if (!custom_action.device_states.empty()) {
+ if (custom_action.buttons.size() != 1) {
+ LOG(FATAL)
+ << "Expected exactly one button for custom action device states.";
+ }
+ const auto button = custom_action.buttons[0];
+ streamer->AddCustomControlPanelButtonWithDeviceStates(
+ button.command, button.title, button.icon_name,
+ custom_action.device_states);
}
}
diff --git a/host/frontend/webrtc_operator/assets/js/app.js b/host/frontend/webrtc_operator/assets/js/app.js
index 5ca5fb7..903ed5a 100644
--- a/host/frontend/webrtc_operator/assets/js/app.js
+++ b/host/frontend/webrtc_operator/assets/js/app.js
@@ -251,6 +251,11 @@
e => onCustomShellButton(button.shell_command, e),
'control_panel_custom_buttons');
buttons[button.command].adb = true;
+ } else if (button.device_states) {
+ // This button corresponds to variable hardware device state(s).
+ createControlPanelButton(button.command, button.title, button.icon_name,
+ getCustomDeviceStateButtonCb(button.device_states),
+ 'control_panel_custom_buttons');
} else {
// This button's command is handled by custom action server.
createControlPanelButton(button.command, button.title, button.icon_name,
@@ -267,11 +272,11 @@
// connected long after the device boots up.
deviceConnection.sendControlMessage(JSON.stringify({
command: 'home',
- state: 'down',
+ button_state: 'down',
}));
deviceConnection.sendControlMessage(JSON.stringify({
command: 'home',
- state: 'up',
+ button_state: 'up',
}));
// Show the error message and disable buttons when the WebRTC connection fails.
deviceConnection.onConnectionStateChange(state => {
@@ -329,7 +334,7 @@
}
deviceConnection.sendControlMessage(JSON.stringify({
command: e.target.dataset.command,
- state: e.type == 'mousedown' ? "down" : "up",
+ button_state: e.type == 'mousedown' ? "down" : "up",
}));
}
@@ -343,6 +348,7 @@
(currentRotation == 0 ? 'landscape' : 'portrait'))
}
}
+
function onCustomShellButton(shell_command, e) {
// Attempt to init adb again, in case the initial connection failed.
// This succeeds immediately if already connected.
@@ -352,6 +358,26 @@
}
}
+ function getCustomDeviceStateButtonCb(device_states) {
+ let states = device_states;
+ let index = 0;
+ return e => {
+ if (e.type == 'mousedown') {
+ // Reset any overridden device state.
+ adbShell('cmd device_state state reset');
+ // Send a device_state message for the current state.
+ let message = {
+ command: 'device_state',
+ ...states[index],
+ };
+ deviceConnection.sendControlMessage(JSON.stringify(message));
+ console.log(JSON.stringify(message));
+ // Cycle to the next state.
+ index = (index + 1) % states.length;
+ }
+ }
+ }
+
function startMouseTracking() {
if (window.PointerEvent) {
deviceScreen.addEventListener('pointerdown', onStartDrag);
diff --git a/host/libs/config/custom_actions.cpp b/host/libs/config/custom_actions.cpp
index 2c78eba..1cc2e06 100644
--- a/host/libs/config/custom_actions.cpp
+++ b/host/libs/config/custom_actions.cpp
@@ -29,6 +29,9 @@
const char* kCustomActionShellCommand = "shell_command";
const char* kCustomActionServer = "server";
+const char* kCustomActionDeviceStates = "device_states";
+const char* kCustomActionDeviceStateLidSwitchOpen = "lid_switch_open";
+const char* kCustomActionDeviceStateHingeAngleValue = "hinge_angle_value";
const char* kCustomActionButton = "button";
const char* kCustomActionButtons = "buttons";
const char* kCustomActionButtonCommand = "command";
@@ -39,11 +42,15 @@
CustomActionConfig::CustomActionConfig(const Json::Value& dictionary) {
+ if (dictionary.isMember(kCustomActionShellCommand) +
+ dictionary.isMember(kCustomActionServer) +
+ dictionary.isMember(kCustomActionDeviceStates) !=
+ 1) {
+ LOG(FATAL) << "Custom action must contain exactly one of shell_command, "
+ << "server, or device_states";
+ return;
+ }
if (dictionary.isMember(kCustomActionShellCommand)) {
- if (dictionary.isMember(kCustomActionServer)) {
- LOG(ERROR) << "Custom action contains both shell command and action server.";
- return;
- }
// Shell command with one button.
Json::Value button_entry = dictionary[kCustomActionButton];
buttons = {{button_entry[kCustomActionButtonCommand].asString(),
@@ -60,8 +67,29 @@
buttons.push_back(button);
}
server = dictionary[kCustomActionServer].asString();
+ } else if (dictionary.isMember(kCustomActionDeviceStates)) {
+ // Device state(s) with one button.
+ // Each button press cycles to the next state, then repeats to the first.
+ Json::Value button_entry = dictionary[kCustomActionButton];
+ buttons = {{button_entry[kCustomActionButtonCommand].asString(),
+ button_entry[kCustomActionButtonTitle].asString(),
+ button_entry[kCustomActionButtonIconName].asString()}};
+ for (const Json::Value& device_state_entry :
+ dictionary[kCustomActionDeviceStates]) {
+ DeviceState state;
+ if (device_state_entry.isMember(kCustomActionDeviceStateLidSwitchOpen)) {
+ state.lid_switch_open =
+ device_state_entry[kCustomActionDeviceStateLidSwitchOpen].asBool();
+ }
+ if (device_state_entry.isMember(
+ kCustomActionDeviceStateHingeAngleValue)) {
+ state.hinge_angle_value =
+ device_state_entry[kCustomActionDeviceStateHingeAngleValue].asInt();
+ }
+ device_states.push_back(state);
+ }
} else {
- LOG(ERROR) << "Unknown custom action format.";
+ LOG(FATAL) << "Unknown custom action type.";
}
}
@@ -88,8 +116,30 @@
button_entry[kCustomActionButtonIconName] = button.icon_name;
custom_action[kCustomActionButtons].append(button_entry);
}
+ } else if (!device_states.empty()) {
+ // Device state(s) with one button.
+ custom_action[kCustomActionDeviceStates] = Json::Value(Json::arrayValue);
+ for (const auto& device_state : device_states) {
+ Json::Value device_state_entry;
+ if (device_state.lid_switch_open) {
+ device_state_entry[kCustomActionDeviceStateLidSwitchOpen] =
+ *device_state.lid_switch_open;
+ }
+ if (device_state.hinge_angle_value) {
+ device_state_entry[kCustomActionDeviceStateHingeAngleValue] =
+ *device_state.hinge_angle_value;
+ }
+ custom_action[kCustomActionDeviceStates].append(device_state_entry);
+ }
+ custom_action[kCustomActionButton] = Json::Value();
+ custom_action[kCustomActionButton][kCustomActionButtonCommand] =
+ buttons[0].command;
+ custom_action[kCustomActionButton][kCustomActionButtonTitle] =
+ buttons[0].title;
+ custom_action[kCustomActionButton][kCustomActionButtonIconName] =
+ buttons[0].icon_name;
} else {
- LOG(ERROR) << "Unknown custom action type.";
+ LOG(FATAL) << "Unknown custom action type.";
}
return custom_action;
}
diff --git a/host/libs/config/custom_actions.h b/host/libs/config/custom_actions.h
index 51e73ba..6279401 100644
--- a/host/libs/config/custom_actions.h
+++ b/host/libs/config/custom_actions.h
@@ -29,6 +29,11 @@
std::string icon_name;
};
+struct DeviceState {
+ std::optional<bool> lid_switch_open;
+ std::optional<int> hinge_angle_value;
+};
+
struct CustomActionConfig {
CustomActionConfig(const Json::Value&);
Json::Value ToJson() const;
@@ -36,6 +41,7 @@
std::vector<ControlPanelButton> buttons;
std::optional<std::string> shell_command;
std::optional<std::string> server;
+ std::vector<DeviceState> device_states;
};
} // namespace cuttlefish
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index 89cc84d..e2ec717 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -110,7 +110,7 @@
"androidboot.cpuvulkan.version=" + std::to_string(VK_API_VERSION_1_1),
"androidboot.hardware.gralloc=minigbm",
"androidboot.hardware.hwcomposer=ranchu",
- "androidboot.hardware.egl=swiftshader",
+ "androidboot.hardware.egl=angle",
"androidboot.hardware.vulkan=pastel",
};
}
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index 9eea793..ed61c69 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -100,11 +100,11 @@
// with properities lead to non-deterministic behavior while loading the
// HALs.
return {
- "androidboot.cpuvulkan.version=" + std::to_string(VK_API_VERSION_1_1),
- "androidboot.hardware.gralloc=minigbm",
- "androidboot.hardware.hwcomposer=cutf",
- "androidboot.hardware.egl=swiftshader",
- "androidboot.hardware.vulkan=pastel",
+ "androidboot.cpuvulkan.version=" + std::to_string(VK_API_VERSION_1_1),
+ "androidboot.hardware.gralloc=minigbm",
+ "androidboot.hardware.hwcomposer=ranchu",
+ "androidboot.hardware.egl=swiftshader",
+ "androidboot.hardware.vulkan=pastel",
};
}
diff --git a/shared/config/config_foldable.json b/shared/config/config_foldable.json
index f8cee39..7a1e731 100644
--- a/shared/config/config_foldable.json
+++ b/shared/config/config_foldable.json
@@ -4,13 +4,29 @@
"dpi" : 386,
"memory_mb" : 4096,
"custom_actions" : [
- {
- "shell_command":"dumpsys device_state | grep mCommittedState | grep OPENED && cmd device_state state 0 || cmd device_state state 2",
- "button":{
- "command":"fold",
- "title":"Fold/Unfold",
- "icon_name":"chrome_reader_mode"
- }
- }
+ {
+ "device_states": [
+ {
+ "lid_switch_open": false
+ }
+ ],
+ "button":{
+ "command":"device_state_closed",
+ "title":"Device State Closed",
+ "icon_name":"smartphone"
+ }
+ },
+ {
+ "device_states": [
+ {
+ "lid_switch_open": true
+ }
+ ],
+ "button":{
+ "command":"device_state_opened",
+ "title":"Device State Opened",
+ "icon_name":"tablet"
+ }
+ }
]
}
diff --git a/shared/config/config_phone.json b/shared/config/config_phone.json
index 3a0ee64..69ad977 100644
--- a/shared/config/config_phone.json
+++ b/shared/config/config_phone.json
@@ -1,6 +1,6 @@
{
"x_res" : 720,
"y_res" : 1280,
- "dpi" : 240,
+ "dpi" : 320,
"memory_mb" : 2048
}
diff --git a/shared/config/config_tablet.json b/shared/config/config_tablet.json
index 87bc145..832d637 100644
--- a/shared/config/config_tablet.json
+++ b/shared/config/config_tablet.json
@@ -1,6 +1,6 @@
{
"x_res" : 2560,
"y_res" : 1800,
- "dpi" : 240,
+ "dpi" : 320,
"memory_mb" : 4096
}
diff --git a/shared/device.mk b/shared/device.mk
index 212e372..7f97e5b 100644
--- a/shared/device.mk
+++ b/shared/device.mk
@@ -465,7 +465,7 @@
# Gatekeeper
#
ifeq ($(LOCAL_GATEKEEPER_PRODUCT_PACKAGE),)
- LOCAL_GATEKEEPER_PRODUCT_PACKAGE := [email protected]
+ LOCAL_GATEKEEPER_PRODUCT_PACKAGE := [email protected]
endif
PRODUCT_PACKAGES += \
$(LOCAL_GATEKEEPER_PRODUCT_PACKAGE)
@@ -520,7 +520,7 @@
# Keymaster HAL
#
ifeq ($(LOCAL_KEYMASTER_PRODUCT_PACKAGE),)
- LOCAL_KEYMASTER_PRODUCT_PACKAGE := [email protected]
+ LOCAL_KEYMASTER_PRODUCT_PACKAGE := [email protected]
endif
PRODUCT_PACKAGES += \
$(LOCAL_KEYMASTER_PRODUCT_PACKAGE)
@@ -532,7 +532,7 @@
LOCAL_KEYMINT_PRODUCT_PACKAGE := android.hardware.security.keymint-service
endif
# PRODUCT_PACKAGES += \
- $(LOCAL_KEYMINT_PRODUCT_PACKAGE)
+# $(LOCAL_KEYMINT_PRODUCT_PACKAGE)
#
# Power HAL
@@ -559,7 +559,8 @@
android.hardware.neuralnetworks-service-sample-float-fast \
android.hardware.neuralnetworks-service-sample-float-slow \
android.hardware.neuralnetworks-service-sample-minimal \
- android.hardware.neuralnetworks-service-sample-quant
+ android.hardware.neuralnetworks-service-sample-quant \
+ android.hardware.neuralnetworks-shim-service-sample
#
# USB
diff --git a/shared/foldable/device_state_configuration.xml b/shared/foldable/device_state_configuration.xml
index d2c7bf3..b32eced 100644
--- a/shared/foldable/device_state_configuration.xml
+++ b/shared/foldable/device_state_configuration.xml
@@ -8,7 +8,15 @@
</lid-switch>
</conditions>
</device-state>
- <!-- TODO(b/181583265): Add state 1 for HALF_OPENED using hinge sensor. -->
+ <device-state>
+ <!-- TODO(b/181583265): Use the hinge sensor for HALF_OPENED state.
+ Currently using an identifier of 3 so that this state never takes
+ precedence over the lower-identifier-value CLOSED and OPENED states,
+ until a hinge sensor is available. -->
+ <identifier>3</identifier>
+ <name>HALF_OPENED</name>
+ <conditions></conditions>
+ </device-state>
<device-state>
<identifier>2</identifier>
<name>OPENED</name>
diff --git a/shared/foldable/overlay/frameworks/base/core/res/res/values/config.xml b/shared/foldable/overlay/frameworks/base/core/res/res/values/config.xml
index bbcd179..2c540e1 100644
--- a/shared/foldable/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/shared/foldable/overlay/frameworks/base/core/res/res/values/config.xml
@@ -20,6 +20,14 @@
<!-- Indicate the display area rect for foldable devices in folded state. -->
<!-- left and right bounds come from: (open_width/2) +/- (folded_width)/2 -->
<string name="config_foldedArea">476 0 1292 2208</string>
+ <!-- WindowsManager JetPack display features -->
+ <string name="config_display_features" translatable="false">fold-[884,0,884,2208]</string>
+ <!-- Map of System DeviceState supplied by DeviceStateManager to WM Jetpack posture. -->
+ <string-array name="config_device_state_postures" translatable="false">
+ <item>0:1</item> <!-- CLOSED : STATE_FLAT -->
+ <item>3:2</item> <!-- HALF_OPENED : STATE_HALF_OPENED -->
+ <item>2:3</item> <!-- OPENED : STATE_FLIPPED -->
+ </string-array>
<!-- The device states (supplied by DeviceStateManager) that should be treated as folded by the
display fold controller. -->
<integer-array name="config_foldedDeviceStates" translatable="false">
diff --git a/shared/sepolicy/vendor/file_contexts b/shared/sepolicy/vendor/file_contexts
index 8259407..d64fb17 100644
--- a/shared/sepolicy/vendor/file_contexts
+++ b/shared/sepolicy/vendor/file_contexts
@@ -76,6 +76,7 @@
/vendor/bin/hw/android\.hardware\.health\.storage-service\.cuttlefish u:object_r:hal_health_storage_default_exec:s0
/vendor/bin/hw/android\.hardware\.lights-service\.example u:object_r:hal_light_default_exec:s0
/vendor/bin/hw/android\.hardware\.neuralnetworks@1\.3-service-sample-.* u:object_r:hal_neuralnetworks_sample_exec:s0
+/vendor/bin/hw/android\.hardware\.neuralnetworks-shim-service-sample u:object_r:hal_neuralnetworks_sample_exec:s0
/vendor/bin/hw/android\.hardware\.neuralnetworks-service-sample-.* u:object_r:hal_neuralnetworks_sample_exec:s0
/vendor/bin/hw/android\.hardware\.vibrator@1\.x-service\.example u:object_r:hal_vibrator_default_exec:s0
/vendor/bin/setup_wifi u:object_r:setup_wifi_exec:s0
diff --git a/shared/sepolicy/vendor/service_contexts b/shared/sepolicy/vendor/service_contexts
index 7b8a515..d20d026 100644
--- a/shared/sepolicy/vendor/service_contexts
+++ b/shared/sepolicy/vendor/service_contexts
@@ -3,6 +3,7 @@
android.hardware.neuralnetworks.IDevice/nnapi-sample_float_slow u:object_r:hal_neuralnetworks_service:s0
android.hardware.neuralnetworks.IDevice/nnapi-sample_minimal u:object_r:hal_neuralnetworks_service:s0
android.hardware.neuralnetworks.IDevice/nnapi-sample_quant u:object_r:hal_neuralnetworks_service:s0
+android.hardware.neuralnetworks.IDevice/nnapi-sample_sl_shim u:object_r:hal_neuralnetworks_service:s0
# Binder service mappings
gce u:object_r:gce_service:s0
diff --git a/shared/tv/device.mk b/shared/tv/device.mk
index 4ab5928..2faccff 100644
--- a/shared/tv/device.mk
+++ b/shared/tv/device.mk
@@ -32,6 +32,9 @@
# HDMI CEC HAL
PRODUCT_PACKAGES += [email protected]
+# Setup HDMI CEC as Playback Device
+PRODUCT_PROPERTY_OVERRIDES += ro.hdmi.device_type=4
+
# Tuner HAL
PRODUCT_PACKAGES += [email protected]
diff --git a/tests/hal/hal_implementation_test.cpp b/tests/hal/hal_implementation_test.cpp
index 74bbd68..c389f53 100644
--- a/tests/hal/hal_implementation_test.cpp
+++ b/tests/hal/hal_implementation_test.cpp
@@ -102,11 +102,6 @@
"android.hardware.common.fmq.",
"android.hardware.graphics.common.",
- // Temporarily add the keystore2 interface. The service implementation is
- // in full swing but we cannot register the service by default just yet.
- // b/170144267
- "android.system.keystore2.",
-
// These KeyMaster types are in an AIDL types-only HAL because they're used
// by the Identity Credential AIDL HAL. Remove this when fully porting
// KeyMaster to AIDL.
diff --git a/tools/upload_via_ssh.py b/tools/upload_via_ssh.py
index a31aaf9..5359473 100755
--- a/tools/upload_via_ssh.py
+++ b/tools/upload_via_ssh.py
@@ -12,7 +12,7 @@
dir = os.getcwd()
try:
os.chdir(args.image_dir)
- images = glob.glob('*.img')
+ images = glob.glob('*.img') + ["bootloader"]
if len(images) == 0:
raise OSError('File not found: ' + args.image_dir + '/*.img')
subprocess.check_call(