[automerger skipped] SIGKILL crosvm since `crosvm stop` may be slow am: 004598c980 am: 60e7dced74 -s ours
am skip reason: Merged-In Iec376c1bb02c98dd32ff869c708cace40ad86ff9 with SHA-1 91041ad910 is already in history
Original change: https://googleplex-android-review.googlesource.com/c/device/google/cuttlefish/+/23746824
Change-Id: I271346fc6d4b9da32beccd3c6ec3f330ce33f02c
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/Android.mk b/Android.mk
index 78b607f..fe6abb5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -27,8 +27,8 @@
$(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,wpa_supplicant.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
$(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,init.cutf_cvm.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
$(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,bt_vhci_forwarder.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,fstab.f2fs,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
-$(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,fstab.ext4,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
+$(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,fstab.cf.f2fs.cts,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
+$(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,fstab.cf.ext4.cts,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
$(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,init.rc,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
$(eval $(call declare-copy-files-license-metadata,device/google/cuttlefish,audio_policy.conf,SPDX-license-identifier-Apache-2.0,notice,build/soong/licenses/LICENSE,))
diff --git a/AndroidProducts.mk b/AndroidProducts.mk
index d345316..d990da1 100644
--- a/AndroidProducts.mk
+++ b/AndroidProducts.mk
@@ -28,6 +28,7 @@
aosp_cf_x86_64_tv:$(LOCAL_DIR)/vsoc_x86_64/tv/aosp_cf.mk \
aosp_cf_x86_64_foldable:$(LOCAL_DIR)/vsoc_x86_64/phone/aosp_cf_foldable.mk \
aosp_cf_x86_64_only_phone:$(LOCAL_DIR)/vsoc_x86_64_only/phone/aosp_cf.mk \
+ aosp_cf_x86_64_only_phone_hsum:$(LOCAL_DIR)/vsoc_x86_64_only/phone/aosp_cf_hsum.mk \
aosp_cf_x86_64_slim:$(LOCAL_DIR)/vsoc_x86_64_only/slim/aosp_cf.mk \
aosp_cf_x86_auto:$(LOCAL_DIR)/vsoc_x86/auto/aosp_cf.mk \
aosp_cf_x86_pasan:$(LOCAL_DIR)/vsoc_x86/pasan/aosp_cf.mk \
@@ -40,6 +41,7 @@
COMMON_LUNCH_CHOICES := \
aosp_cf_arm64_auto-userdebug \
aosp_cf_arm64_phone-userdebug \
+ aosp_cf_x86_64_only_phone_hsum-userdebug \
aosp_cf_x86_64_pc-userdebug \
aosp_cf_x86_64_phone-userdebug \
aosp_cf_x86_64_foldable-userdebug \
diff --git a/default-permissions.xml b/default-permissions.xml
index 48b0f17..2d5020a 100644
--- a/default-permissions.xml
+++ b/default-permissions.xml
@@ -133,4 +133,9 @@
<!-- Notifications -->
<permission name="android.permission.POST_NOTIFICATIONS" fixed="false"/>
</exception>
+ <exception
+ package="com.google.android.euicc">
+ <!-- Notifications -->
+ <permission name="android.permission.POST_NOTIFICATIONS" fixed="false"/>
+ </exception>
</exceptions>
diff --git a/guest/commands/bt_vhci_forwarder/main.cpp b/guest/commands/bt_vhci_forwarder/main.cpp
index 2f1aab2..d1bb588 100644
--- a/guest/commands/bt_vhci_forwarder/main.cpp
+++ b/guest/commands/bt_vhci_forwarder/main.cpp
@@ -128,6 +128,9 @@
send(vhci_fd, HCI_ISODATA_PKT, raw_iso.data(), raw_iso.size());
},
[]() { LOG(INFO) << "HCI socket device disconnected"; });
+
+ bool before_first_command = true;
+
while (true) {
int ret = TEMP_FAILURE_RETRY(poll(fds, 2, -1));
if (ret < 0) {
@@ -141,6 +144,7 @@
if (c < 0) {
PLOG(ERROR) << "vhci to virtio-console failed";
}
+ before_first_command = false;
}
if (fds[1].revents & POLLHUP) {
LOG(ERROR) << "PollHUP";
@@ -148,6 +152,16 @@
continue;
}
if (fds[1].revents & (POLLIN | POLLERR)) {
+ if (before_first_command) {
+ // Drop any data left in the virtio-console from a previous reset.
+ ssize_t bytes = TEMP_FAILURE_RETRY(read(virtio_fd, buf, kBufferSize));
+ if (bytes < 0) {
+ LOG(ERROR) << "virtio_fd ready, but read failed " << strerror(errno);
+ } else {
+ LOG(INFO) << "Discarding " << bytes << " bytes from virtio_fd.";
+ }
+ continue;
+ }
// 'virtio-console to vhci' depends on H4Packetizer because vhci expects
// full packet, but the data from virtio-console could be partial.
h4.OnDataReady(virtio_fd);
diff --git a/guest/commands/setup_wifi/main.cpp b/guest/commands/setup_wifi/main.cpp
index 4a91442..2727fb4 100644
--- a/guest/commands/setup_wifi/main.cpp
+++ b/guest/commands/setup_wifi/main.cpp
@@ -33,6 +33,7 @@
#include "common/libs/net/network_interface_manager.h"
DEFINE_string(mac_prefix, "", "mac prefix to use for wlan0");
+DEFINE_string(interface, "eth2", "interface to create wlan wrapper on");
static std::array<unsigned char, 6> prefix_to_mac(
const std::string& mac_prefix) {
@@ -138,9 +139,9 @@
gflags::ParseCommandLineFlags(&argc, &argv, true);
- int renamed_eth2 = RenameNetwork("eth2", "buried_eth2");
- if (renamed_eth2 != 0) {
- return renamed_eth2;
+ int renamed_if = RenameNetwork(FLAGS_interface, "buried_" + FLAGS_interface);
+ if (renamed_if != 0) {
+ return renamed_if;
}
- return CreateWifiWrapper("buried_eth2", "wlan0");
+ return CreateWifiWrapper("buried_" + FLAGS_interface, "wlan0");
}
diff --git a/guest/commands/setup_wifi/setup_wifi.rc b/guest/commands/setup_wifi/setup_wifi.rc
index a2f1eb5..993e957 100644
--- a/guest/commands/setup_wifi/setup_wifi.rc
+++ b/guest/commands/setup_wifi/setup_wifi.rc
@@ -1,2 +1,2 @@
-service setup_wifi /vendor/bin/setup_wifi
+service setup_wifi /vendor/bin/setup_wifi --interface=${ro.vendor.virtwifi.port}
oneshot
diff --git a/guest/hals/audio/effects/manifest.xml b/guest/hals/audio/effects/manifest.xml
new file mode 100644
index 0000000..6b4e832
--- /dev/null
+++ b/guest/hals/audio/effects/manifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2022, 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.
+** limitations under the License.
+*/
+-->
+
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.audio.effect</name>
+ <transport>hwbinder</transport>
+ <version>7.0</version>
+ <interface>
+ <name>IEffectsFactory</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/guest/hals/keymint/remote/remote_keymint_operation.cpp b/guest/hals/keymint/remote/remote_keymint_operation.cpp
index b88715a..aa05035 100644
--- a/guest/hals/keymint/remote/remote_keymint_operation.cpp
+++ b/guest/hals/keymint/remote/remote_keymint_operation.cpp
@@ -50,13 +50,17 @@
}
ScopedAStatus RemoteKeyMintOperation::updateAad(
- const vector<uint8_t>& input,
- const optional<HardwareAuthToken>& /* authToken */,
+ const vector<uint8_t>& input, const optional<HardwareAuthToken>& authToken,
const optional<TimeStampToken>& /* timestampToken */) {
UpdateOperationRequest request(impl_.message_version());
request.op_handle = opHandle_;
request.additional_params.push_back(TAG_ASSOCIATED_DATA, input.data(),
input.size());
+ if (authToken) {
+ auto tokenAsVec(authToken2AidlVec(*authToken));
+ request.additional_params.push_back(keymaster::TAG_AUTH_TOKEN,
+ tokenAsVec.data(), tokenAsVec.size());
+ }
UpdateOperationResponse response(impl_.message_version());
impl_.UpdateOperation(request, &response);
@@ -65,8 +69,7 @@
}
ScopedAStatus RemoteKeyMintOperation::update(
- const vector<uint8_t>& input,
- const optional<HardwareAuthToken>& /* authToken */,
+ const vector<uint8_t>& input, const optional<HardwareAuthToken>& authToken,
const optional<TimeStampToken>&
/* timestampToken */,
vector<uint8_t>* output) {
@@ -75,6 +78,11 @@
UpdateOperationRequest request(impl_.message_version());
request.op_handle = opHandle_;
request.input.Reinitialize(input.data(), input.size());
+ if (authToken) {
+ auto tokenAsVec(authToken2AidlVec(*authToken));
+ request.additional_params.push_back(keymaster::TAG_AUTH_TOKEN,
+ tokenAsVec.data(), tokenAsVec.size());
+ }
UpdateOperationResponse response(impl_.message_version());
impl_.UpdateOperation(request, &response);
@@ -92,7 +100,7 @@
ScopedAStatus RemoteKeyMintOperation::finish(
const optional<vector<uint8_t>>& input, //
const optional<vector<uint8_t>>& signature, //
- const optional<HardwareAuthToken>& /* authToken */,
+ const optional<HardwareAuthToken>& authToken,
const optional<TimeStampToken>& /* timestampToken */,
const optional<vector<uint8_t>>& /* confirmationToken */,
vector<uint8_t>* output) {
@@ -104,8 +112,14 @@
FinishOperationRequest request(impl_.message_version());
request.op_handle = opHandle_;
if (input) request.input.Reinitialize(input->data(), input->size());
- if (signature)
+ if (signature) {
request.signature.Reinitialize(signature->data(), signature->size());
+ }
+ if (authToken) {
+ auto tokenAsVec(authToken2AidlVec(*authToken));
+ request.additional_params.push_back(keymaster::TAG_AUTH_TOKEN,
+ tokenAsVec.data(), tokenAsVec.size());
+ }
FinishOperationResponse response(impl_.message_version());
impl_.FinishOperation(request, &response);
diff --git a/host/commands/assemble_cvd/disk_flags.cc b/host/commands/assemble_cvd/disk_flags.cc
index c06d7d7..ce7d569 100644
--- a/host/commands/assemble_cvd/disk_flags.cc
+++ b/host/commands/assemble_cvd/disk_flags.cc
@@ -80,7 +80,7 @@
DEFINE_string(otheros_root_image, "",
"Location of cuttlefish otheros root filesystem image.");
-DEFINE_int32(blank_metadata_image_mb, 16,
+DEFINE_int32(blank_metadata_image_mb, 64,
"The size of the blank metadata image to generate, MB.");
DEFINE_int32(blank_sdcard_image_mb, 2048,
"If enabled, the size of the blank sdcard image to generate, MB.");
@@ -677,7 +677,8 @@
private:
std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
Result<void> ResultSetup() override {
- if (FileExists(FLAGS_metadata_image)) {
+ if (FileExists(FLAGS_metadata_image) &&
+ FileSize(FLAGS_metadata_image) == FLAGS_blank_metadata_image_mb << 20) {
return {};
}
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index 08c2b68..a68a475 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -597,15 +597,6 @@
}
}
- // The device needs to avoid having both hwcomposer2.4 and hwcomposer3
- // services running at the same time so warn the user to manually build
- // in drm_hwcomposer when needed.
- if (tmp_config_obj.hwcomposer() == kHwComposerAuto) {
- LOG(WARNING) << "In order to run with --hwcomposer=drm. Please make sure "
- "Cuttlefish was built with "
- "TARGET_ENABLE_DRMHWCOMPOSER=true.";
- }
-
tmp_config_obj.set_enable_gpu_udmabuf(FLAGS_enable_gpu_udmabuf);
tmp_config_obj.set_enable_gpu_angle(FLAGS_enable_gpu_angle);
@@ -768,7 +759,7 @@
const auto vsock_guest_cid = FLAGS_vsock_guest_cid + num - GetInstance();
instance.set_vsock_guest_cid(vsock_guest_cid);
auto calc_vsock_port = [vsock_guest_cid](const int base_port) {
- // a base (vsock) port is like 9200 for modem_simulator, etc
+ // a base (vsock) port is like 9600 for modem_simulator, etc
return cuttlefish::GetVsockServerPort(base_port, vsock_guest_cid);
};
instance.set_session_id(iface_config.mobile_tap.session_id);
@@ -891,10 +882,10 @@
if (modem_simulator_count > 0) {
std::stringstream modem_ports;
for (auto index {0}; index < modem_simulator_count - 1; index++) {
- auto port = 9200 + (modem_simulator_count * (num - 1)) + index;
+ auto port = 9600 + (modem_simulator_count * (num - 1)) + index;
modem_ports << calc_vsock_port(port) << ",";
}
- auto port = 9200 + (modem_simulator_count * (num - 1)) +
+ auto port = 9600 + (modem_simulator_count * (num - 1)) +
modem_simulator_count - 1;
modem_ports << calc_vsock_port(port);
instance.set_modem_simulator_ports(modem_ports.str());
diff --git a/host/commands/modem_simulator/call_service.cpp b/host/commands/modem_simulator/call_service.cpp
index 674c153..7e40870 100644
--- a/host/commands/modem_simulator/call_service.cpp
+++ b/host/commands/modem_simulator/call_service.cpp
@@ -37,7 +37,6 @@
auto instance = nvram_config->ForInstance(service_id_);
in_emergency_mode_ = instance.emergency_mode();
- last_active_call_index_ = 1;
mute_on_ = false;
}
@@ -216,7 +215,7 @@
call_status.is_mobile_terminated = false;
call_status.call_state = CallStatus::CALL_STATE_DIALING;
call_status.remote_client = remote_client;
- int index = last_active_call_index_++;
+ auto index = FindFreeCallIndex();
auto call_token = std::make_pair(index, call_status.number);
call_status.timeout_serial = thread_looper_->Post(
@@ -232,7 +231,7 @@
CallStatus call_status(number);
call_status.is_mobile_terminated = false;
call_status.call_state = CallStatus::CALL_STATE_DIALING;
- auto index = last_active_call_index_++;
+ auto index = FindFreeCallIndex();
active_calls_[index] = call_status;
if (emergency_number) {
@@ -707,7 +706,7 @@
call_status.remote_client = client.client_fd;
call_status.call_state = CallStatus::CALL_STATE_INCOMING;
- auto index = last_active_call_index_++;
+ auto index = FindFreeCallIndex();
active_calls_[index] = call_status;
break;
}
diff --git a/host/commands/modem_simulator/call_service.h b/host/commands/modem_simulator/call_service.h
index 1870372..f57eb05 100644
--- a/host/commands/modem_simulator/call_service.h
+++ b/host/commands/modem_simulator/call_service.h
@@ -42,6 +42,13 @@
void HandleCancelUssd(const Client& client, const std::string& command);
void HandleEmergencyMode(const Client& client, const std::string& command);
void HandleRemoteCall(const Client& client, const std::string& command);
+ int FindFreeCallIndex() const {
+ for (int index = 1; true; index++) {
+ if (active_calls_.find(index) == active_calls_.end()) {
+ return index;
+ }
+ }
+ }
private:
void InitializeServiceState();
@@ -141,7 +148,6 @@
// private data members
SimService* sim_service_;
NetworkService* network_service_;
- int32_t last_active_call_index_;
std::map<int, CallStatus> active_calls_;
bool in_emergency_mode_;
bool mute_on_;
diff --git a/host/frontend/webrtc/client/js/cf_webrtc.js b/host/frontend/webrtc/client/js/cf_webrtc.js
index 5c91383..073ea36 100644
--- a/host/frontend/webrtc/client/js/cf_webrtc.js
+++ b/host/frontend/webrtc/client/js/cf_webrtc.js
@@ -422,7 +422,7 @@
this.#pc.addIceCandidate(iceCandidate);
}
- ConnectDevice(pc) {
+ ConnectDevice(pc, infraConfig) {
this.#pc = pc;
console.debug('ConnectDevice');
// ICE candidates will be generated when we add the offer. Adding it here
@@ -432,7 +432,8 @@
this.#pc.addEventListener('icecandidate', evt => {
if (evt.candidate) this.#sendIceCandidate(evt.candidate);
});
- this.#serverConnector.sendToDevice({type: 'request-offer'});
+ this.#serverConnector.sendToDevice(
+ {type: 'request-offer', ice_servers: infraConfig.ice_servers});
}
async renegotiateConnection() {
@@ -445,10 +446,7 @@
}
function createPeerConnection(infra_config) {
- let pc_config = {iceServers: []};
- for (const stun of infra_config.ice_servers) {
- pc_config.iceServers.push({urls: 'stun:' + stun});
- }
+ let pc_config = {iceServers: infra_config.ice_servers};
let pc = new RTCPeerConnection(pc_config);
pc.addEventListener('icecandidate', evt => {
@@ -470,12 +468,6 @@
let infraConfig = requestRet.infraConfig;
console.debug('Device available:');
console.debug(deviceInfo);
- let pc_config = {iceServers: []};
- if (infraConfig.ice_servers && infraConfig.ice_servers.length > 0) {
- for (const server of infraConfig.ice_servers) {
- pc_config.iceServers.push(server);
- }
- }
let pc = createPeerConnection(infraConfig);
let control = new Controller(serverConnector);
@@ -491,6 +483,6 @@
reject(evt);
}
});
- control.ConnectDevice(pc);
+ control.ConnectDevice(pc, infraConfig);
});
}
diff --git a/host/frontend/webrtc/lib/client_handler.cpp b/host/frontend/webrtc/lib/client_handler.cpp
index 9be1ca0..94aa175 100644
--- a/host/frontend/webrtc/lib/client_handler.cpp
+++ b/host/frontend/webrtc/lib/client_handler.cpp
@@ -457,22 +457,65 @@
msg_data + msg.size());
}
+std::vector<webrtc::PeerConnectionInterface::IceServer>
+ClientHandler::ParseIceServersMessage(const Json::Value &message) {
+ std::vector<webrtc::PeerConnectionInterface::IceServer> ret;
+ if (!message.isMember("ice_servers") || !message["ice_servers"].isArray()) {
+ // Log as verbose since the ice_servers field is optional in some messages
+ LOG(VERBOSE) << "ice_servers field not present in json object or not an array";
+ return ret;
+ }
+ auto& servers = message["ice_servers"];
+ for (const auto& server: servers) {
+ webrtc::PeerConnectionInterface::IceServer ice_server;
+ if (!server.isMember("urls") || !server["urls"].isArray()) {
+ // The urls field is required
+ LOG(WARNING)
+ << "ICE server specification missing urls field or not an array: "
+ << server.toStyledString();
+ continue;
+ }
+ auto urls = server["urls"];
+ for (int url_idx = 0; url_idx < urls.size(); url_idx++) {
+ auto url = urls[url_idx];
+ if (!url.isString()) {
+ LOG(WARNING) << "Non string 'urls' field in ice server: "
+ << url.toStyledString();
+ continue;
+ }
+ ice_server.urls.push_back(url.asString());
+ }
+ if (server.isMember("credential") && server["credential"].isString()) {
+ ice_server.password = server["credential"].asString();
+ }
+ if (server.isMember("username") && server["username"].isString()) {
+ ice_server.username = server["username"].asString();
+ }
+ ret.push_back(ice_server);
+ }
+ return ret;
+}
+
std::shared_ptr<ClientHandler> ClientHandler::Create(
int client_id, std::shared_ptr<ConnectionObserver> observer,
+ PeerConnectionBuilder &connection_builder,
std::function<void(const Json::Value &)> send_to_client_cb,
std::function<void(bool)> on_connection_changed_cb) {
- return std::shared_ptr<ClientHandler>(new ClientHandler(
- client_id, observer, send_to_client_cb, on_connection_changed_cb));
+ return std::shared_ptr<ClientHandler>(
+ new ClientHandler(client_id, observer, connection_builder,
+ send_to_client_cb, on_connection_changed_cb));
}
ClientHandler::ClientHandler(
int client_id, std::shared_ptr<ConnectionObserver> observer,
+ PeerConnectionBuilder &connection_builder,
std::function<void(const Json::Value &)> send_to_client_cb,
std::function<void(bool)> on_connection_changed_cb)
: client_id_(client_id),
observer_(observer),
send_to_client_(send_to_client_cb),
on_connection_changed_cb_(on_connection_changed_cb),
+ connection_builder_(connection_builder),
camera_track_(new ClientVideoTrackImpl()) {}
ClientHandler::~ClientHandler() {
@@ -481,54 +524,37 @@
}
}
-bool ClientHandler::SetPeerConnection(
- rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection) {
- peer_connection_ = peer_connection;
-
- // libwebrtc configures the video encoder with a start bitrate of just 300kbs
- // which causes it to drop the first 4 frames it receives. Any value over 2Mbs
- // will be capped at 2Mbs when passed to the encoder by the peer_connection
- // object, so we pass the maximum possible value here.
- webrtc::BitrateSettings bitrate_settings;
- bitrate_settings.start_bitrate_bps = 2000000; // 2Mbs
- peer_connection_->SetBitrate(bitrate_settings);
- // At least one data channel needs to be created on the side that makes the
- // SDP offer (the device) for data channels to be enabled at all.
- // This channel is meant to carry control commands from the client.
- auto control_channel = peer_connection_->CreateDataChannel(
- "device-control", nullptr /* config */);
- if (!control_channel) {
- LOG(ERROR) << "Failed to create control data channel";
- return false;
- }
- control_handler_.reset(new ControlChannelHandler(control_channel, observer_));
- return true;
-}
-
bool ClientHandler::AddDisplay(
rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track,
const std::string &label) {
- // Send each track as part of a different stream with the label as id
- auto err_or_sender =
- peer_connection_->AddTrack(video_track, {label} /* stream_id */);
- if (!err_or_sender.ok()) {
- LOG(ERROR) << "Failed to add video track to the peer connection";
- return false;
+ displays_.emplace_back(video_track, label);
+ if (peer_connection_) {
+ // Send each track as part of a different stream with the label as id
+ auto err_or_sender =
+ peer_connection_->AddTrack(video_track, {label} /* stream_id */);
+ if (!err_or_sender.ok()) {
+ LOG(ERROR) << "Failed to add video track to the peer connection";
+ return false;
+ }
+ // TODO (b/154138394): use the returned sender (err_or_sender.value()) to
+ // remove the display from the connection.
}
- // TODO (b/154138394): use the returned sender (err_or_sender.value()) to
- // remove the display from the connection.
return true;
}
bool ClientHandler::AddAudio(
rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track,
const std::string &label) {
- // Send each track as part of a different stream with the label as id
- auto err_or_sender =
- peer_connection_->AddTrack(audio_track, {label} /* stream_id */);
- if (!err_or_sender.ok()) {
- LOG(ERROR) << "Failed to add video track to the peer connection";
- return false;
+ // Store the audio track for when the peer connection is created
+ audio_streams_.emplace_back(audio_track, label);
+ if (peer_connection_) {
+ // Send each track as part of a different stream with the label as id
+ auto err_or_sender =
+ peer_connection_->AddTrack(audio_track, {label} /* stream_id */);
+ if (!err_or_sender.ok()) {
+ LOG(ERROR) << "Failed to add video track to the peer connection";
+ return false;
+ }
}
return true;
}
@@ -558,6 +584,56 @@
pending_ice_candidates_.clear();
}
+bool ClientHandler::BuildPeerConnection(const Json::Value &message) {
+ auto ice_servers = ParseIceServersMessage(message);
+ peer_connection_ = connection_builder_.Build(this, ice_servers);
+ if (!peer_connection_) {
+ return false;
+ }
+
+ // Re-add the video and audio tracks after the peer connection has been
+ // created
+ decltype(displays_) tmp_displays;
+ tmp_displays.swap(displays_);
+ for (auto &pair : tmp_displays) {
+ auto &video_track = pair.first;
+ auto &label = pair.second;
+ if (!AddDisplay(video_track, label)) {
+ return false;
+ }
+ }
+ decltype(audio_streams_) tmp_audio_streams;
+ tmp_audio_streams.swap(audio_streams_);
+ for (auto &pair : tmp_audio_streams) {
+ auto &audio_track = pair.first;
+ auto &label = pair.second;
+ if (!AddAudio(audio_track, label)) {
+ return false;
+ }
+ }
+
+ // libwebrtc configures the video encoder with a start bitrate of just 300kbs
+ // which causes it to drop the first 4 frames it receives. Any value over 2Mbs
+ // will be capped at 2Mbs when passed to the encoder by the peer_connection
+ // object, so we pass the maximum possible value here.
+ webrtc::BitrateSettings bitrate_settings;
+ bitrate_settings.start_bitrate_bps = 2000000; // 2Mbs
+ peer_connection_->SetBitrate(bitrate_settings);
+
+ // At least one data channel needs to be created on the side that makes the
+ // SDP offer (the device) for data channels to be enabled at all.
+ // This channel is meant to carry control commands from the client.
+ auto control_channel = peer_connection_->CreateDataChannel(
+ "device-control", nullptr /* config */);
+ if (!control_channel) {
+ LOG(ERROR) << "Failed to create control data channel";
+ return false;
+ }
+ control_handler_.reset(new ControlChannelHandler(control_channel, observer_));
+
+ return true;
+}
+
void ClientHandler::OnCreateSDPSuccess(
webrtc::SessionDescriptionInterface *desc) {
std::string offer_str;
@@ -607,9 +683,15 @@
}
auto type = message["type"].asString();
if (type == "request-offer") {
- // Can't check for state being different that kNew because renegotiation can
- // start in any state after the answer is returned.
- if (state_ == State::kCreatingOffer) {
+ if (state_ == State::kNew) {
+ // The peer connection must be created on the first request-offer
+ if (!BuildPeerConnection(message)) {
+ LogAndReplyError("Failed to create peer connection");
+ return;
+ }
+ // Renegotiation can start in any state after the answer is returned, not
+ // just kNew.
+ } else if (state_ == State::kCreatingOffer) {
// An offer has been requested already
LogAndReplyError("Multiple requests for offer received from single client");
return;
diff --git a/host/frontend/webrtc/lib/client_handler.h b/host/frontend/webrtc/lib/client_handler.h
index ea58552..2617e64 100644
--- a/host/frontend/webrtc/lib/client_handler.h
+++ b/host/frontend/webrtc/lib/client_handler.h
@@ -42,19 +42,24 @@
class ClientVideoTrackInterface;
class ClientVideoTrackImpl;
+class PeerConnectionBuilder;
class ClientHandler : public webrtc::PeerConnectionObserver,
public std::enable_shared_from_this<ClientHandler> {
public:
+ // Checks if the message contains an "ice_servers" array field and parses it
+ // into a vector of webrtc ICE servers. Returns an empty vector if the field
+ // isn't present.
+ static std::vector<webrtc::PeerConnectionInterface::IceServer>
+ ParseIceServersMessage(const Json::Value& message);
+
static std::shared_ptr<ClientHandler> Create(
int client_id, std::shared_ptr<ConnectionObserver> observer,
+ PeerConnectionBuilder& connection_builder,
std::function<void(const Json::Value&)> send_client_cb,
std::function<void(bool)> on_connection_changed_cb);
~ClientHandler() override;
- bool SetPeerConnection(
- rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection);
-
bool AddDisplay(rtc::scoped_refptr<webrtc::VideoTrackInterface> track,
const std::string& label);
@@ -113,6 +118,7 @@
kFailed,
};
ClientHandler(int client_id, std::shared_ptr<ConnectionObserver> observer,
+ PeerConnectionBuilder& connection_builder,
std::function<void(const Json::Value&)> send_client_cb,
std::function<void(bool)> on_connection_changed_cb);
@@ -121,12 +127,14 @@
void LogAndReplyError(const std::string& error_msg) const;
void AddPendingIceCandidates();
+ bool BuildPeerConnection(const Json::Value& message);
int client_id_;
State state_ = State::kNew;
std::shared_ptr<ConnectionObserver> observer_;
std::function<void(const Json::Value&)> send_to_client_;
std::function<void(bool)> on_connection_changed_cb_;
+ PeerConnectionBuilder& connection_builder_;
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
std::vector<rtc::scoped_refptr<webrtc::DataChannelInterface>> data_channels_;
std::unique_ptr<InputChannelHandler> input_handler_;
@@ -138,6 +146,12 @@
bool remote_description_added_ = false;
std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
pending_ice_candidates_;
+ std::vector<
+ std::pair<rtc::scoped_refptr<webrtc::VideoTrackInterface>, std::string>>
+ displays_;
+ std::vector<
+ std::pair<rtc::scoped_refptr<webrtc::AudioTrackInterface>, std::string>>
+ audio_streams_;
};
class ClientVideoTrackInterface {
@@ -148,5 +162,14 @@
const rtc::VideoSinkWants& wants) = 0;
};
+class PeerConnectionBuilder {
+ public:
+ virtual ~PeerConnectionBuilder() = default;
+ virtual rtc::scoped_refptr<webrtc::PeerConnectionInterface> Build(
+ webrtc::PeerConnectionObserver* observer,
+ const std::vector<webrtc::PeerConnectionInterface::IceServer>&
+ per_connection_servers) = 0;
+};
+
} // namespace webrtc_streaming
} // namespace cuttlefish
diff --git a/host/frontend/webrtc/lib/streamer.cpp b/host/frontend/webrtc/lib/streamer.cpp
index 088b25b..9dd8fea 100644
--- a/host/frontend/webrtc/lib/streamer.cpp
+++ b/host/frontend/webrtc/lib/streamer.cpp
@@ -136,6 +136,7 @@
class Streamer::Impl : public ServerConnectionObserver,
+ public PeerConnectionBuilder,
public std::enable_shared_from_this<ServerConnectionObserver> {
public:
std::shared_ptr<ClientHandler> CreateClientHandler(int client_id);
@@ -155,6 +156,12 @@
void HandleConfigMessage(const Json::Value& msg);
void HandleClientMessage(const Json::Value& server_message);
+ // PeerConnectionBuilder
+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> Build(
+ webrtc::PeerConnectionObserver* observer,
+ const std::vector<webrtc::PeerConnectionInterface::IceServer>&
+ per_connection_servers) override;
+
// All accesses to these variables happen from the signal_thread, so there is
// no need for extra synchronization mechanisms (mutex)
StreamerConfig config_;
@@ -474,39 +481,8 @@
void Streamer::Impl::HandleConfigMessage(const Json::Value& server_message) {
CHECK(signal_thread_->IsCurrent())
<< __FUNCTION__ << " called from the wrong thread";
- if (server_message.isMember("ice_servers") &&
- server_message["ice_servers"].isArray()) {
- auto servers = server_message["ice_servers"];
- operator_config_.servers.clear();
- for (int server_idx = 0; server_idx < servers.size(); server_idx++) {
- auto server = servers[server_idx];
- webrtc::PeerConnectionInterface::IceServer ice_server;
- if (!server.isMember("urls") || !server["urls"].isArray()) {
- // The urls field is required
- LOG(WARNING)
- << "Invalid ICE server specification obtained from server: "
- << server.toStyledString();
- continue;
- }
- auto urls = server["urls"];
- for (int url_idx = 0; url_idx < urls.size(); url_idx++) {
- auto url = urls[url_idx];
- if (!url.isString()) {
- LOG(WARNING) << "Non string 'urls' field in ice server: "
- << url.toStyledString();
- continue;
- }
- ice_server.urls.push_back(url.asString());
- if (server.isMember("credential") && server["credential"].isString()) {
- ice_server.password = server["credential"].asString();
- }
- if (server.isMember("username") && server["username"].isString()) {
- ice_server.username = server["username"].asString();
- }
- operator_config_.servers.push_back(ice_server);
- }
- }
- }
+ operator_config_.servers =
+ ClientHandler::ParseIceServersMessage(server_message);
}
void Streamer::Impl::HandleClientMessage(const Json::Value& server_message) {
@@ -598,7 +574,7 @@
auto observer = connection_observer_factory_->CreateObserver();
auto client_handler = ClientHandler::Create(
- client_id, observer,
+ client_id, observer, *this,
[this, client_id](const Json::Value& msg) {
SendMessageToClient(client_id, msg);
},
@@ -610,28 +586,6 @@
}
});
- webrtc::PeerConnectionInterface::RTCConfiguration config;
- config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
- config.enable_dtls_srtp = true;
- config.servers.insert(config.servers.end(), operator_config_.servers.begin(),
- operator_config_.servers.end());
- webrtc::PeerConnectionDependencies dependencies(client_handler.get());
- // PortRangeSocketFactory's super class' constructor needs to be called on the
- // network thread or have it as a parameter
- dependencies.packet_socket_factory.reset(new PortRangeSocketFactory(
- network_thread_.get(), config_.udp_port_range, config_.tcp_port_range));
- auto peer_connection = peer_connection_factory_->CreatePeerConnection(
- config, std::move(dependencies));
-
- if (!peer_connection) {
- LOG(ERROR) << "Failed to create peer connection";
- return nullptr;
- }
-
- if (!client_handler->SetPeerConnection(std::move(peer_connection))) {
- return nullptr;
- }
-
for (auto& entry : displays_) {
auto& label = entry.first;
auto& video_source = entry.second.source;
@@ -652,6 +606,32 @@
return client_handler;
}
+rtc::scoped_refptr<webrtc::PeerConnectionInterface> Streamer::Impl::Build(
+ webrtc::PeerConnectionObserver* observer,
+ const std::vector<webrtc::PeerConnectionInterface::IceServer>&
+ per_connection_servers) {
+ webrtc::PeerConnectionInterface::RTCConfiguration config;
+ config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
+ config.enable_dtls_srtp = true;
+ config.servers.insert(config.servers.end(), operator_config_.servers.begin(),
+ operator_config_.servers.end());
+ config.servers.insert(config.servers.end(), per_connection_servers.begin(),
+ per_connection_servers.end());
+ webrtc::PeerConnectionDependencies dependencies(observer);
+ // PortRangeSocketFactory's super class' constructor needs to be called on the
+ // network thread or have it as a parameter
+ dependencies.packet_socket_factory.reset(new PortRangeSocketFactory(
+ network_thread_.get(), config_.udp_port_range, config_.tcp_port_range));
+ auto peer_connection = peer_connection_factory_->CreatePeerConnection(
+ config, std::move(dependencies));
+
+ if (!peer_connection) {
+ LOG(ERROR) << "Failed to create peer connection";
+ return nullptr;
+ }
+ return peer_connection;
+}
+
void Streamer::Impl::SendMessageToClient(int client_id,
const Json::Value& msg) {
LOG(VERBOSE) << "Sending to client: " << msg.toStyledString();
diff --git a/host/libs/config/bootconfig_args.cpp b/host/libs/config/bootconfig_args.cpp
index 00673f6..d8ef114 100644
--- a/host/libs/config/bootconfig_args.cpp
+++ b/host/libs/config/bootconfig_args.cpp
@@ -154,8 +154,8 @@
instance.modem_simulator_ports()));
}
- bootconfig_args.push_back(concat("androidboot.fstab_suffix=",
- config.userdata_format()));
+ std::string fstab_suffix = fmt::format("cf.{}.{}", config.userdata_format(), "cts");
+ bootconfig_args.push_back(concat("androidboot.fstab_suffix=", fstab_suffix));
bootconfig_args.push_back(
concat("androidboot.wifi_mac_prefix=", instance.wifi_mac_prefix()));
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index 68609a3..1adb55b 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -77,9 +77,11 @@
return {
"androidboot.cpuvulkan.version=0",
"androidboot.hardware.gralloc=minigbm",
- "androidboot.hardware.hwcomposer=drm",
+ "androidboot.hardware.hwcomposer=ranchu",
+ "androidboot.hardware.hwcomposer.mode=client",
"androidboot.hardware.egl=mesa",
- };
+ // No "hardware" Vulkan support, yet
+ "androidboot.opengles.version=196608"}; // OpenGL ES 3.0
}
if (config.gpu_mode() == kGpuModeGfxStream) {
std::string gles_impl = config.enable_gpu_angle() ? "angle" : "emulation";
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index adedf04..4efb053 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -131,21 +131,23 @@
// with properities lead to non-deterministic behavior while loading the
// HALs.
return {
- "androidboot.cpuvulkan.version=" + std::to_string(VK_API_VERSION_1_1),
+ "androidboot.cpuvulkan.version=" + std::to_string(VK_API_VERSION_1_2),
"androidboot.hardware.gralloc=minigbm",
"androidboot.hardware.hwcomposer=" + config.hwcomposer(),
"androidboot.hardware.egl=angle",
"androidboot.hardware.vulkan=pastel",
- };
+ "androidboot.opengles.version=196609"}; // OpenGL ES 3.1
}
if (config.gpu_mode() == kGpuModeDrmVirgl) {
return {
"androidboot.cpuvulkan.version=0",
"androidboot.hardware.gralloc=minigbm",
- "androidboot.hardware.hwcomposer=drm",
+ "androidboot.hardware.hwcomposer=ranchu",
+ "androidboot.hardware.hwcomposer.mode=client",
"androidboot.hardware.egl=mesa",
- };
+ // No "hardware" Vulkan support, yet
+ "androidboot.opengles.version=196608"}; // OpenGL ES 3.0
}
return {};
diff --git a/shared/BoardConfig.mk b/shared/BoardConfig.mk
index b59b39c..6e1b95c 100644
--- a/shared/BoardConfig.mk
+++ b/shared/BoardConfig.mk
@@ -23,7 +23,9 @@
include build/make/target/board/BoardConfigMainlineCommon.mk
TARGET_NO_BOOTLOADER := $(__TARGET_NO_BOOTLOADER)
+ifndef TARGET_BOOTLOADER_BOARD_NAME
TARGET_BOOTLOADER_BOARD_NAME := cutf
+endif
BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE := $(TARGET_RO_FILE_SYSTEM_TYPE)
@@ -204,7 +206,7 @@
TARGET_RECOVERY_PIXEL_FORMAT := ABGR_8888
TARGET_RECOVERY_UI_LIB := librecovery_ui_cuttlefish
-TARGET_RECOVERY_FSTAB ?= device/google/cuttlefish/shared/config/fstab.f2fs
+TARGET_RECOVERY_FSTAB_GENRULE := gen_fstab_cf_f2fs_cts
BOARD_SUPER_PARTITION_SIZE := 7516192768 # 7GiB
BOARD_SUPER_PARTITION_GROUPS := google_system_dynamic_partitions google_vendor_dynamic_partitions
diff --git a/shared/auto/device_vendor.mk b/shared/auto/device_vendor.mk
index 277eaa3..a03044e 100644
--- a/shared/auto/device_vendor.mk
+++ b/shared/auto/device_vendor.mk
@@ -115,6 +115,7 @@
ENABLE_MOCK_EVSHAL ?= true
ENABLE_CAREVSSERVICE_SAMPLE ?= true
ENABLE_SAMPLE_EVS_APP ?= true
+ENABLE_CARTELEMETRY_SERVICE ?= true
ifeq ($(ENABLE_MOCK_EVSHAL), true)
CUSTOMIZE_EVS_SERVICE_PARAMETER := true
@@ -130,6 +131,9 @@
PRODUCT_COPY_FILES += \
device/google/cuttlefish/shared/auto/evs/evs_app_config.json:$(TARGET_COPY_OUT_SYSTEM)/etc/automotive/evs/config_override.json
BOARD_SEPOLICY_DIRS += packages/services/Car/cpp/evs/apps/sepolicy/private
+ifeq ($(ENABLE_CARTELEMETRY_SERVICE), true)
+BOARD_SEPOLICY_DIRS += packages/services/Car/cpp/evs/apps/sepolicy/cartelemetry
+endif
endif
BOARD_IS_AUTOMOTIVE := true
diff --git a/shared/auto/overlay/frameworks/base/core/res/res/values/config.xml b/shared/auto/overlay/frameworks/base/core/res/res/values/config.xml
index bf07d05..7eaea59 100644
--- a/shared/auto/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/shared/auto/overlay/frameworks/base/core/res/res/values/config.xml
@@ -34,4 +34,11 @@
Handle volume keys directly in CarAudioService without passing them to the foreground app
-->
<bool name="config_handleVolumeKeysInWindowManager">true</bool>
+
+ <!-- Controls if local secondary displays should be private or not. Value specified in the array
+ represents physical port address of each display and display in this list will be marked
+ as private. {@see android.view.Display#FLAG_PRIVATE} -->
+ <integer-array translatable="false" name="config_localPrivateDisplayPorts">
+ <item>1</item> <!-- ClusterDisplay -->
+ </integer-array>
</resources>
diff --git a/shared/auto/preinstalled-packages-product-car-cuttlefish.xml b/shared/auto/preinstalled-packages-product-car-cuttlefish.xml
index 9f22200..0aca16b 100644
--- a/shared/auto/preinstalled-packages-product-car-cuttlefish.xml
+++ b/shared/auto/preinstalled-packages-product-car-cuttlefish.xml
@@ -94,10 +94,6 @@
<install-in-user-type package="com.android.cameraextensions">
<install-in user-type="SYSTEM" />
<install-in user-type="FULL" />
- </install-in-user-type>
- <install-in-user-type package="com.android.car.messenger">
- <install-in user-type="FULL" />
- <install-in user-type="SYSTEM" />
</install-in-user-type>
<install-in-user-type package="com.android.apps.tag">
<install-in user-type="FULL" />
@@ -124,9 +120,6 @@
<install-in-user-type package="com.android.car.datacenter">
<install-in user-type="FULL" />
</install-in-user-type>
- <install-in-user-type package="com.android.car.dialer">
- <install-in user-type="FULL" />
- </install-in-user-type>
<install-in-user-type package="com.android.car.goldilocks">
<install-in user-type="FULL" />
</install-in-user-type>
diff --git a/shared/config/Android.bp b/shared/config/Android.bp
index f2d94e4..40c3f93 100644
--- a/shared/config/Android.bp
+++ b/shared/config/Android.bp
@@ -89,3 +89,33 @@
name: "[email protected]",
srcs: ["[email protected]"]
}
+
+genrule {
+ name: "gen_fstab_cf_f2fs_cts",
+ srcs: ["fstab.in"],
+ out: ["fstab.cf.f2fs.cts"],
+ tool_files: [ "sed.f2fs" ],
+ cmd: "sed -f $(location sed.f2fs) $(in) > $(out)",
+}
+
+genrule {
+ name: "gen_fstab_cf_ext4_cts",
+ srcs: ["fstab.in"],
+ out: ["fstab.cf.ext4.cts"],
+ tool_files: [ "sed.ext4" ],
+ cmd: "sed -f $(location sed.ext4) $(in) > $(out)",
+}
+
+prebuilt_etc {
+ name: "fstab.cf.f2fs.cts",
+ src: ":gen_fstab_cf_f2fs_cts",
+ vendor: true,
+ vendor_ramdisk_available: true,
+}
+
+prebuilt_etc {
+ name: "fstab.cf.ext4.cts",
+ src: ":gen_fstab_cf_ext4_cts",
+ vendor: true,
+ vendor_ramdisk_available: true,
+}
diff --git a/shared/config/fstab.f2fs b/shared/config/fstab.f2fs
deleted file mode 100644
index 41162ed..0000000
--- a/shared/config/fstab.f2fs
+++ /dev/null
@@ -1,30 +0,0 @@
-# Non-dynamic, boot critical partitions
-/dev/block/by-name/boot /boot emmc defaults recoveryonly,slotselect,first_stage_mount,avb=boot
-/dev/block/by-name/init_boot /init_boot emmc defaults recoveryonly,slotselect,first_stage_mount,avb=init_boot
-/dev/block/by-name/vendor_boot /vendor_boot emmc defaults recoveryonly,slotselect
-system /system erofs ro wait,logical,first_stage_mount,slotselect,avb=vbmeta_system,avb_keys=/avb
-system /system ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb=vbmeta_system,avb_keys=/avb
-# Add all non-dynamic partitions except system, after this comment
-/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,inlinecrypt,reserve_root=32768 latemount,wait,check,quota,formattable,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,fscompress,keydirectory=/metadata/vold/metadata_encryption,checkpoint=fs
-/dev/block/by-name/metadata /metadata ext4 nodev,noatime,nosuid,errors=panic wait,formattable,first_stage_mount,check
-/dev/block/by-name/misc /misc emmc defaults defaults
-# Add all dynamic partitions except system, after this comment
-odm /odm erofs ro wait,logical,first_stage_mount,slotselect,avb
-odm /odm ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb
-product /product erofs ro wait,logical,first_stage_mount,slotselect,avb
-product /product ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb
-system_ext /system_ext erofs ro wait,logical,first_stage_mount,slotselect,avb=vbmeta_system
-system_ext /system_ext ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb=vbmeta_system
-vendor /vendor erofs ro wait,logical,first_stage_mount,slotselect,avb=vbmeta
-vendor /vendor ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb=vbmeta
-vendor_dlkm /vendor_dlkm erofs ro wait,logical,first_stage_mount,slotselect,avb
-vendor_dlkm /vendor_dlkm ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb
-odm_dlkm /odm_dlkm erofs ro wait,logical,first_stage_mount,slotselect,avb
-odm_dlkm /odm_dlkm ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb
-system_dlkm /system_dlkm erofs ro wait,logical,first_stage_mount,slotselect,avb=vbmeta
-system_dlkm /system_dlkm ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb=vbmeta
-# ZRAM, SD-Card and virtiofs shares
-/dev/block/zram0 none swap defaults zramsize=75%
-/dev/block/vdc1 /sdcard vfat defaults recoveryonly
-/devices/*/block/vdc auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
-shared /mnt/vendor/shared virtiofs nosuid,nodev,noatime nofail
diff --git a/shared/config/fstab.ext4 b/shared/config/fstab.in
similarity index 86%
rename from shared/config/fstab.ext4
rename to shared/config/fstab.in
index 4d3fe9b..d9b3c13 100644
--- a/shared/config/fstab.ext4
+++ b/shared/config/fstab.in
@@ -5,8 +5,8 @@
system /system erofs ro wait,logical,first_stage_mount,slotselect,avb=vbmeta_system,avb_keys=/avb
system /system ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb=vbmeta_system,avb_keys=/avb
# Add all non-dynamic partitions except system, after this comment
-/dev/block/by-name/userdata /data ext4 nodev,noatime,nosuid,errors=panic latemount,wait,check,quota,formattable,fileencryption=aes-256-xts:aes-256-cts,keydirectory=/metadata/vold/metadata_encryption,checkpoint=block
-/dev/block/by-name/metadata /metadata ext4 nodev,noatime,nosuid,errors=panic wait,formattable,first_stage_mount,check
+/dev/block/by-name/userdata /data @userdata_fs_type@ nodev,noatime,nosuid,@userdata_mount_flags@ latemount,wait,check,quota,formattable,keydirectory=/metadata/vold/metadata_encryption,@userdata_fsmgr_flags@
+/dev/block/by-name/metadata /metadata f2fs nodev,noatime,nosuid wait,check,formattable,first_stage_mount
/dev/block/by-name/misc /misc emmc defaults defaults
# Add all dynamic partitions except system, after this comment
odm /odm erofs ro wait,logical,first_stage_mount,slotselect,avb
diff --git a/shared/config/init.vendor.rc b/shared/config/init.vendor.rc
index 8861ca3..83a52c4 100644
--- a/shared/config/init.vendor.rc
+++ b/shared/config/init.vendor.rc
@@ -6,6 +6,7 @@
setprop debug.sf.vsync_reactor_ignore_present_fences true
setprop ro.hardware.gralloc ${ro.boot.hardware.gralloc}
setprop ro.hardware.hwcomposer ${ro.boot.hardware.hwcomposer}
+ setprop ro.vendor.hwcomposer.display_finder_mode ${ro.boot.hardware.hwcomposer.display_finder_mode}
setprop ro.vendor.hwcomposer.mode ${ro.boot.hardware.hwcomposer.mode}
setprop ro.hardware.vulkan ${ro.boot.hardware.vulkan}
setprop ro.cpuvulkan.version ${ro.boot.cpuvulkan.version}
@@ -54,7 +55,7 @@
# set RLIMIT_MEMLOCK to 64MB
setrlimit 8 67108864 67108864
-on post-fs-data
+on post-fs-data && property:ro.vendor.disable_rename_eth0=
# works around framework netiface enumeration issue
# TODO(b/202731768): Add this `start rename_eth0` command to the init.rc for rename_netiface
start rename_eth0
diff --git a/shared/config/manifest.xml b/shared/config/manifest.xml
index 126557f..893dbfa 100644
--- a/shared/config/manifest.xml
+++ b/shared/config/manifest.xml
@@ -18,15 +18,6 @@
-->
<manifest version="1.0" type="device" target-level="7">
<hal format="hidl">
- <name>android.hardware.audio.effect</name>
- <transport>hwbinder</transport>
- <version>7.0</version>
- <interface>
- <name>IEffectsFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
<name>android.hardware.authsecret</name>
<transport>hwbinder</transport>
<version>1.0</version>
diff --git a/shared/config/sed.ext4 b/shared/config/sed.ext4
new file mode 100644
index 0000000..af302aa
--- /dev/null
+++ b/shared/config/sed.ext4
@@ -0,0 +1,3 @@
+s/@userdata_fs_type@/ext4/
+s/@userdata_mount_flags@/errors=panic/
+s/@userdata_fsmgr_flags@/fileencryption=aes-256-xts:aes-256-cts,checkpoint=block/
diff --git a/shared/config/sed.f2fs b/shared/config/sed.f2fs
new file mode 100644
index 0000000..eab04e8
--- /dev/null
+++ b/shared/config/sed.f2fs
@@ -0,0 +1,3 @@
+s/@userdata_fs_type@/f2fs/
+s/@userdata_mount_flags@/inlinecrypt,reserve_root=32768/
+s/@userdata_fsmgr_flags@/fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,fscompress,checkpoint=fs/
diff --git a/shared/device.mk b/shared/device.mk
index 04dedbd..b67eeff 100644
--- a/shared/device.mk
+++ b/shared/device.mk
@@ -66,7 +66,6 @@
AB_OTA_UPDATER := true
AB_OTA_PARTITIONS += \
boot \
- init_boot \
odm \
odm_dlkm \
product \
@@ -79,6 +78,11 @@
vendor_boot \
vendor_dlkm \
+TARGET_USES_INITBOOT ?= true
+ifeq ($(TARGET_USES_INITBOOT),true)
+AB_OTA_PARTITIONS += init_boot
+endif
+
# Enable Virtual A/B
$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz
@@ -339,13 +343,11 @@
device/google/cuttlefish/shared/config/input/Crosvm_Virtio_Multitouch_Touchscreen_3.idc:$(TARGET_COPY_OUT_VENDOR)/usr/idc/Crosvm_Virtio_Multitouch_Touchscreen_3.idc
endif
-PRODUCT_COPY_FILES += \
- device/google/cuttlefish/shared/config/fstab.f2fs:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.f2fs \
- device/google/cuttlefish/shared/config/fstab.f2fs:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.f2fs \
- device/google/cuttlefish/shared/config/fstab.f2fs:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.f2fs \
- device/google/cuttlefish/shared/config/fstab.ext4:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.ext4 \
- device/google/cuttlefish/shared/config/fstab.ext4:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.ext4 \
- device/google/cuttlefish/shared/config/fstab.ext4:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.ext4
+PRODUCT_PACKAGES += \
+ fstab.cf.f2fs.cts \
+ fstab.cf.f2fs.cts.vendor_ramdisk \
+ fstab.cf.ext4.cts \
+ fstab.cf.ext4.cts.vendor_ramdisk \
ifeq ($(TARGET_VULKAN_SUPPORT),true)
ifneq ($(LOCAL_PREFER_VENDOR_APEX),true)
@@ -403,7 +405,6 @@
ifeq ($(TARGET_ENABLE_DRMHWCOMPOSER),true)
DEVICE_MANIFEST_FILE += \
device/google/cuttlefish/shared/config/[email protected]
-
PRODUCT_PACKAGES += \
[email protected] \
hwcomposer.drm
@@ -468,6 +469,8 @@
android.hardware.audio.service \
[email protected] \
[email protected]
+DEVICE_MANIFEST_FILE += \
+ device/google/cuttlefish/guest/hals/audio/effects/manifest.xml
endif
ifndef LOCAL_AUDIO_PRODUCT_COPY_FILES
@@ -767,6 +770,12 @@
PRODUCT_COPY_FILES += \
device/google/cuttlefish/shared/config/wpa_supplicant.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/wpa_supplicant.rc
+# VirtWifi interface configuration
+ifeq ($(DEVICE_VIRTWIFI_PORT),)
+ DEVICE_VIRTWIFI_PORT := eth2
+endif
+PRODUCT_VENDOR_PROPERTIES += ro.vendor.virtwifi.port=${DEVICE_VIRTWIFI_PORT}
+
# WLAN driver configuration files
ifndef LOCAL_WPA_SUPPLICANT_OVERLAY
LOCAL_WPA_SUPPLICANT_OVERLAY := $(LOCAL_PATH)/config/wpa_supplicant_overlay.conf
@@ -825,19 +834,11 @@
# Enable GPU-intensive background blur support on Cuttlefish when requested by apps
PRODUCT_VENDOR_PROPERTIES += \
- ro.surface_flinger.supports_background_blur 1
+ ro.surface_flinger.supports_background_blur=1
-# Set support one-handed mode
-PRODUCT_PRODUCT_PROPERTIES += \
- ro.support_one_handed_mode=true
-
-# Set one_handed_mode screen translate offset percentage
-PRODUCT_PRODUCT_PROPERTIES += \
- persist.debug.one_handed_offset_percentage=50
-
-# Set one_handed_mode translate animation duration milliseconds
-PRODUCT_PRODUCT_PROPERTIES += \
- persist.debug.one_handed_translate_animation_duration=300
+# Disable GPU-intensive background blur for widget picker
+PRODUCT_SYSTEM_PROPERTIES += \
+ ro.launcher.depth.widget=0
# Vendor Dlkm Locader
PRODUCT_PACKAGES += \
diff --git a/shared/foldable/device_state_configuration.xml b/shared/foldable/device_state_configuration.xml
index 9618b11..877a583 100644
--- a/shared/foldable/device_state_configuration.xml
+++ b/shared/foldable/device_state_configuration.xml
@@ -34,4 +34,11 @@
</lid-switch>
</conditions>
</device-state>
+ <device-state>
+ <identifier>3</identifier>
+ <name>REAR_DISPLAY_MODE</name>
+ <flags>
+ <flag>FLAG_EMULATED_ONLY</flag>
+ </flags>
+ </device-state>
</device-state-config>
diff --git a/shared/foldable/display_layout_configuration.xml b/shared/foldable/display_layout_configuration.xml
index 54b76b1..2c50e76 100644
--- a/shared/foldable/display_layout_configuration.xml
+++ b/shared/foldable/display_layout_configuration.xml
@@ -38,4 +38,17 @@
<address>4619827551948147201</address>
</display>
</layout>
+
+ <layout>
+ <!-- REAR_DISPLAY_MODE: display0 disabled, display1 enabled -->
+ <state>3</state>
+
+ <display enabled="false">
+ <address>4619827259835644672</address>
+ </display>
+
+ <display enabled="true" defaultDisplay="true">
+ <address>4619827551948147201</address>
+ </display>
+ </layout>
</layouts>
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 b0b42ab..8186c97 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
@@ -24,6 +24,7 @@
<item>0:1</item> <!-- CLOSED : STATE_FLAT -->
<item>1:2</item> <!-- HALF_OPENED : STATE_HALF_OPENED -->
<item>2:3</item> <!-- OPENED : STATE_FLIPPED -->
+ <item>3:1</item> <!-- REAR_DISPLAY: STATE_FLAT -->
</string-array>
<!-- The device states (supplied by DeviceStateManager) that should be treated as folded by the
display fold controller. -->
@@ -41,4 +42,13 @@
<bool name="config_supportsSplitScreenMultiWindow">true</bool>
<!-- Radius of the software rounded corners. -->
<dimen name="rounded_corner_radius">34px</dimen>
+
+ <!-- List of the labels of requestable device state config values -->
+ <string-array name="config_deviceStatesAvailableForAppRequests">
+ <item>config_deviceStateRearDisplay</item>
+ </string-array>
+
+ <!-- Device state that corresponds to rear display mode, feature provided
+ through Jetpack WindowManager -->
+ <integer name="config_deviceStateRearDisplay">3</integer>
</resources>
diff --git a/shared/overlays/core/res/values/config.xml b/shared/overlays/core/res/values/config.xml
new file mode 100644
index 0000000..bfcec6c
--- /dev/null
+++ b/shared/overlays/core/res/values/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show the "Adaptive Brightness" toggle. -->
+ <bool name="config_automatic_brightness_available">true</bool>
+</resources>
\ No newline at end of file
diff --git a/shared/permissions/cuttlefish_excluded_hardware.xml b/shared/permissions/cuttlefish_excluded_hardware.xml
index c3d03d5..3fba9f6 100644
--- a/shared/permissions/cuttlefish_excluded_hardware.xml
+++ b/shared/permissions/cuttlefish_excluded_hardware.xml
@@ -15,5 +15,4 @@
-->
<permissions>
<unavailable-feature name="android.software.print" />
- <unavailable-feature name="android.software.voice_recognizers" />
</permissions>
diff --git a/shared/sepolicy/vendor/e2fs.te b/shared/sepolicy/vendor/e2fs.te
new file mode 100644
index 0000000..54af273
--- /dev/null
+++ b/shared/sepolicy/vendor/e2fs.te
@@ -0,0 +1,3 @@
+# make_f2fs wants to read /sys/devices/*/block/*
+allow e2fs sysfs_devices_block:dir search;
+allow e2fs sysfs_devices_block:file r_file_perms;
diff --git a/shared/sepolicy/vendor/genfs_contexts b/shared/sepolicy/vendor/genfs_contexts
index 542db04..cbbd88f 100644
--- a/shared/sepolicy/vendor/genfs_contexts
+++ b/shared/sepolicy/vendor/genfs_contexts
@@ -65,7 +65,7 @@
# qemu (arm64)
cf_pci_block_device(/devices/platform/4010000000.pcie/pci0000:00, 0xa, 9)
-cf_pci_gpu_device(/devices/platform/4010000000.pcie/pci0000:00, 0x2)
+cf_pci_gpu_device(/devices/platform/4010000000.pcie/pci0000:00, 0x1)
## find /sys/devices/platform/* -type d -name 'rtc[0-9]' | sed 's,/rtc[0-9],,'
genfscon sysfs /devices/platform/9010000.pl031/rtc u:object_r:sysfs_rtc:s0
## find /sys/devices/platform/* -type d -name 'wakeup[0-9]'
@@ -73,7 +73,7 @@
# qemu (arm)
cf_pci_block_device(/devices/platform/3f000000.pcie/pci0000:00, 0xa, 9)
-cf_pci_gpu_device(/devices/platform/3f000000.pcie/pci0000:00, 0x2)
+cf_pci_gpu_device(/devices/platform/3f000000.pcie/pci0000:00, 0x1)
genfscon sysfs /devices/platform/rtc-test.1/wakeup/wakeup2 u:object_r:sysfs_wakeup:s0
genfscon sysfs /devices/platform/rtc-test.2/wakeup/wakeup3 u:object_r:sysfs_wakeup:s0
diff --git a/shared/sepolicy/vendor/property_contexts b/shared/sepolicy/vendor/property_contexts
index 9b98ed1..235b35a 100644
--- a/shared/sepolicy/vendor/property_contexts
+++ b/shared/sepolicy/vendor/property_contexts
@@ -14,6 +14,7 @@
ro.vendor.boot_security_patch u:object_r:vendor_boot_security_patch_level_prop:s0
vendor.bt.rootcanal_mac_address u:object_r:vendor_bt_rootcanal_prop:s0
vendor.bt.rootcanal_test_console u:object_r:vendor_bt_rootcanal_prop:s0
+ro.vendor.hwcomposer.display_finder_mode u:object_r:vendor_hwcomposer_prop:s0 exact string
ro.vendor.hwcomposer.mode u:object_r:vendor_hwcomposer_prop:s0 exact string
ro.vendor.hwcomposer.pmem u:object_r:vendor_hwcomposer_prop:s0 exact string
vendor.wlan.firmware.version u:object_r:vendor_wlan_versions_prop:s0 exact string
diff --git a/vsoc_x86_64/phone/OWNERS b/vsoc_x86_64/phone/OWNERS
new file mode 100644
index 0000000..e0d597b
--- /dev/null
+++ b/vsoc_x86_64/phone/OWNERS
@@ -0,0 +1 @@
+per-file *hsum*.mk = file:platform/frameworks/base:/MULTIUSER_OWNERS
diff --git a/vsoc_x86_64_only/phone/aosp_cf_hsum.mk b/vsoc_x86_64_only/phone/aosp_cf_hsum.mk
new file mode 100644
index 0000000..3abca8c
--- /dev/null
+++ b/vsoc_x86_64_only/phone/aosp_cf_hsum.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2022 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.
+#
+
+# Inherit mostly from aosp_cf_x86_64_phone
+$(call inherit-product, device/google/cuttlefish/vsoc_x86_64_only/phone/aosp_cf.mk)
+PRODUCT_NAME := aosp_cf_x86_64_only_phone_hsum
+PRODUCT_MODEL := Cuttlefish x86_64 phone 64-bit only Headless System User Mode
+
+# Set Headless System User Mode
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES = \
+ ro.fw.mu.headless_system_user=true
+
+# TODO(b/204071542): add package allow-list; something like
+# PRODUCT_COPY_FILES += \
+# device/google/cuttlefish/SOME_PATH/preinstalled-packages.xml:$(TARGET_COPY_OUT_PRODUCT)/etc/sysconfig/preinstalled-packages-cf_phone.xml